faster Cirrus VGA VRAM access
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1114 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
6d46bf8ae3
commit
8926b517e9
@ -692,6 +692,8 @@ int cpu_register_io_memory(int io_index,
|
|||||||
CPUReadMemoryFunc **mem_read,
|
CPUReadMemoryFunc **mem_read,
|
||||||
CPUWriteMemoryFunc **mem_write,
|
CPUWriteMemoryFunc **mem_write,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
|
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
|
||||||
|
CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
|
||||||
|
|
||||||
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
|
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
|
||||||
int len, int is_write);
|
int len, int is_write);
|
||||||
|
10
exec.c
10
exec.c
@ -1977,6 +1977,16 @@ int cpu_register_io_memory(int io_index,
|
|||||||
return io_index << IO_MEM_SHIFT;
|
return io_index << IO_MEM_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
|
||||||
|
{
|
||||||
|
return io_mem_write[io_index >> IO_MEM_SHIFT];
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
|
||||||
|
{
|
||||||
|
return io_mem_read[io_index >> IO_MEM_SHIFT];
|
||||||
|
}
|
||||||
|
|
||||||
/* physical memory access (slow version, mainly for debug) */
|
/* physical memory access (slow version, mainly for debug) */
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
|
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
|
||||||
|
@ -259,9 +259,6 @@ typedef struct CirrusVGAState {
|
|||||||
uint8_t *cirrus_srcptr;
|
uint8_t *cirrus_srcptr;
|
||||||
uint8_t *cirrus_srcptr_end;
|
uint8_t *cirrus_srcptr_end;
|
||||||
uint32_t cirrus_srccounter;
|
uint32_t cirrus_srccounter;
|
||||||
uint8_t *cirrus_dstptr;
|
|
||||||
uint8_t *cirrus_dstptr_end;
|
|
||||||
uint32_t cirrus_dstcounter;
|
|
||||||
/* hwcursor display state */
|
/* hwcursor display state */
|
||||||
int last_hw_cursor_size;
|
int last_hw_cursor_size;
|
||||||
int last_hw_cursor_x;
|
int last_hw_cursor_x;
|
||||||
@ -269,6 +266,7 @@ typedef struct CirrusVGAState {
|
|||||||
int last_hw_cursor_y_start;
|
int last_hw_cursor_y_start;
|
||||||
int last_hw_cursor_y_end;
|
int last_hw_cursor_y_end;
|
||||||
int real_vram_size; /* XXX: suppress that */
|
int real_vram_size; /* XXX: suppress that */
|
||||||
|
CPUWriteMemoryFunc **cirrus_linear_write;
|
||||||
} CirrusVGAState;
|
} CirrusVGAState;
|
||||||
|
|
||||||
typedef struct PCICirrusVGAState {
|
typedef struct PCICirrusVGAState {
|
||||||
@ -285,7 +283,8 @@ static uint8_t rop_to_index[256];
|
|||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
|
|
||||||
static void cirrus_bitblt_reset(CirrusVGAState * s);
|
static void cirrus_bitblt_reset(CirrusVGAState *s);
|
||||||
|
static void cirrus_update_memory_access(CirrusVGAState *s);
|
||||||
|
|
||||||
/***************************************
|
/***************************************
|
||||||
*
|
*
|
||||||
@ -711,9 +710,7 @@ static void cirrus_bitblt_reset(CirrusVGAState * s)
|
|||||||
s->cirrus_srcptr = &s->cirrus_bltbuf[0];
|
s->cirrus_srcptr = &s->cirrus_bltbuf[0];
|
||||||
s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
|
s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
|
||||||
s->cirrus_srccounter = 0;
|
s->cirrus_srccounter = 0;
|
||||||
s->cirrus_dstptr = &s->cirrus_bltbuf[0];
|
cirrus_update_memory_access(s);
|
||||||
s->cirrus_dstptr_end = &s->cirrus_bltbuf[0];
|
|
||||||
s->cirrus_dstcounter = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
|
static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
|
||||||
@ -746,6 +743,7 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
|
|||||||
}
|
}
|
||||||
s->cirrus_srcptr = s->cirrus_bltbuf;
|
s->cirrus_srcptr = s->cirrus_bltbuf;
|
||||||
s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
|
s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
|
||||||
|
cirrus_update_memory_access(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1199,7 +1197,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
|
|||||||
case 0x14: // Scratch Register 2
|
case 0x14: // Scratch Register 2
|
||||||
case 0x15: // Scratch Register 3
|
case 0x15: // Scratch Register 3
|
||||||
case 0x16: // Performance Tuning Register
|
case 0x16: // Performance Tuning Register
|
||||||
case 0x17: // Configuration Readback and Extended Control
|
|
||||||
case 0x18: // Signature Generator Control
|
case 0x18: // Signature Generator Control
|
||||||
case 0x19: // Signature Generator Result
|
case 0x19: // Signature Generator Result
|
||||||
case 0x1a: // Signature Generator Result
|
case 0x1a: // Signature Generator Result
|
||||||
@ -1214,6 +1211,10 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
|
|||||||
reg_index, reg_value);
|
reg_index, reg_value);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case 0x17: // Configuration Readback and Extended Control
|
||||||
|
s->sr[reg_index] = reg_value;
|
||||||
|
cirrus_update_memory_access(s);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG_CIRRUS
|
#ifdef DEBUG_CIRRUS
|
||||||
printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,
|
printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,
|
||||||
@ -1348,13 +1349,19 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
|
|||||||
return CIRRUS_HOOK_NOT_HANDLED;
|
return CIRRUS_HOOK_NOT_HANDLED;
|
||||||
case 0x05: // Standard VGA, Cirrus extended mode
|
case 0x05: // Standard VGA, Cirrus extended mode
|
||||||
s->gr[reg_index] = reg_value & 0x7f;
|
s->gr[reg_index] = reg_value & 0x7f;
|
||||||
|
cirrus_update_memory_access(s);
|
||||||
break;
|
break;
|
||||||
case 0x09: // bank offset #0
|
case 0x09: // bank offset #0
|
||||||
case 0x0A: // bank offset #1
|
case 0x0A: // bank offset #1
|
||||||
|
s->gr[reg_index] = reg_value;
|
||||||
|
cirrus_update_bank_ptr(s, 0);
|
||||||
|
cirrus_update_bank_ptr(s, 1);
|
||||||
|
break;
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
s->gr[reg_index] = reg_value;
|
s->gr[reg_index] = reg_value;
|
||||||
cirrus_update_bank_ptr(s, 0);
|
cirrus_update_bank_ptr(s, 0);
|
||||||
cirrus_update_bank_ptr(s, 1);
|
cirrus_update_bank_ptr(s, 1);
|
||||||
|
cirrus_update_memory_access(s);
|
||||||
break;
|
break;
|
||||||
case 0x10: // BGCOLOR 0x0000ff00
|
case 0x10: // BGCOLOR 0x0000ff00
|
||||||
case 0x11: // FGCOLOR 0x0000ff00
|
case 0x11: // FGCOLOR 0x0000ff00
|
||||||
@ -2304,6 +2311,36 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
|
|||||||
cirrus_linear_writel,
|
cirrus_linear_writel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void cirrus_linear_mem_writeb(void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
CirrusVGAState *s = (CirrusVGAState *) opaque;
|
||||||
|
|
||||||
|
addr &= s->cirrus_addr_mask;
|
||||||
|
*(s->vram_ptr + addr) = val;
|
||||||
|
cpu_physical_memory_set_dirty(s->vram_offset + addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
CirrusVGAState *s = (CirrusVGAState *) opaque;
|
||||||
|
|
||||||
|
addr &= s->cirrus_addr_mask;
|
||||||
|
cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val);
|
||||||
|
cpu_physical_memory_set_dirty(s->vram_offset + addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
CirrusVGAState *s = (CirrusVGAState *) opaque;
|
||||||
|
|
||||||
|
addr &= s->cirrus_addr_mask;
|
||||||
|
cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val);
|
||||||
|
cpu_physical_memory_set_dirty(s->vram_offset + addr);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************
|
/***************************************
|
||||||
*
|
*
|
||||||
* system to screen memory access
|
* system to screen memory access
|
||||||
@ -2405,6 +2442,37 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
|
|||||||
cirrus_linear_bitblt_writel,
|
cirrus_linear_bitblt_writel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Compute the memory access functions */
|
||||||
|
static void cirrus_update_memory_access(CirrusVGAState *s)
|
||||||
|
{
|
||||||
|
unsigned mode;
|
||||||
|
|
||||||
|
if ((s->sr[0x17] & 0x44) == 0x44) {
|
||||||
|
goto generic_io;
|
||||||
|
} else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
|
||||||
|
goto generic_io;
|
||||||
|
} else {
|
||||||
|
if ((s->gr[0x0B] & 0x14) == 0x14) {
|
||||||
|
goto generic_io;
|
||||||
|
} else if (s->gr[0x0B] & 0x02) {
|
||||||
|
goto generic_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = s->gr[0x05] & 0x7;
|
||||||
|
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
|
||||||
|
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
|
||||||
|
s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
|
||||||
|
s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
|
||||||
|
} else {
|
||||||
|
generic_io:
|
||||||
|
s->cirrus_linear_write[0] = cirrus_linear_writeb;
|
||||||
|
s->cirrus_linear_write[1] = cirrus_linear_writew;
|
||||||
|
s->cirrus_linear_write[2] = cirrus_linear_writel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* I/O ports */
|
/* I/O ports */
|
||||||
|
|
||||||
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
|
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
|
||||||
@ -2933,6 +3001,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
|
|||||||
s->cirrus_linear_io_addr =
|
s->cirrus_linear_io_addr =
|
||||||
cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
|
cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
|
||||||
s);
|
s);
|
||||||
|
s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
|
||||||
|
|
||||||
/* I/O handler for LFB */
|
/* I/O handler for LFB */
|
||||||
s->cirrus_linear_bitblt_io_addr =
|
s->cirrus_linear_bitblt_io_addr =
|
||||||
cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
|
cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user