Commit 8926b517e9ebe20a4348f445e9d0c7f11029eb57
1 parent
6d46bf8a
faster Cirrus VGA VRAM access
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1114 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
90 additions
and
8 deletions
cpu-all.h
| @@ -692,6 +692,8 @@ int cpu_register_io_memory(int io_index, | @@ -692,6 +692,8 @@ int cpu_register_io_memory(int io_index, | ||
| 692 | CPUReadMemoryFunc **mem_read, | 692 | CPUReadMemoryFunc **mem_read, |
| 693 | CPUWriteMemoryFunc **mem_write, | 693 | CPUWriteMemoryFunc **mem_write, |
| 694 | void *opaque); | 694 | void *opaque); |
| 695 | +CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index); | ||
| 696 | +CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index); | ||
| 695 | 697 | ||
| 696 | void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, | 698 | void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, |
| 697 | int len, int is_write); | 699 | int len, int is_write); |
exec.c
| @@ -1977,6 +1977,16 @@ int cpu_register_io_memory(int io_index, | @@ -1977,6 +1977,16 @@ int cpu_register_io_memory(int io_index, | ||
| 1977 | return io_index << IO_MEM_SHIFT; | 1977 | return io_index << IO_MEM_SHIFT; |
| 1978 | } | 1978 | } |
| 1979 | 1979 | ||
| 1980 | +CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index) | ||
| 1981 | +{ | ||
| 1982 | + return io_mem_write[io_index >> IO_MEM_SHIFT]; | ||
| 1983 | +} | ||
| 1984 | + | ||
| 1985 | +CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index) | ||
| 1986 | +{ | ||
| 1987 | + return io_mem_read[io_index >> IO_MEM_SHIFT]; | ||
| 1988 | +} | ||
| 1989 | + | ||
| 1980 | /* physical memory access (slow version, mainly for debug) */ | 1990 | /* physical memory access (slow version, mainly for debug) */ |
| 1981 | #if defined(CONFIG_USER_ONLY) | 1991 | #if defined(CONFIG_USER_ONLY) |
| 1982 | void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, | 1992 | void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, |
hw/cirrus_vga.c
| @@ -259,9 +259,6 @@ typedef struct CirrusVGAState { | @@ -259,9 +259,6 @@ typedef struct CirrusVGAState { | ||
| 259 | uint8_t *cirrus_srcptr; | 259 | uint8_t *cirrus_srcptr; |
| 260 | uint8_t *cirrus_srcptr_end; | 260 | uint8_t *cirrus_srcptr_end; |
| 261 | uint32_t cirrus_srccounter; | 261 | uint32_t cirrus_srccounter; |
| 262 | - uint8_t *cirrus_dstptr; | ||
| 263 | - uint8_t *cirrus_dstptr_end; | ||
| 264 | - uint32_t cirrus_dstcounter; | ||
| 265 | /* hwcursor display state */ | 262 | /* hwcursor display state */ |
| 266 | int last_hw_cursor_size; | 263 | int last_hw_cursor_size; |
| 267 | int last_hw_cursor_x; | 264 | int last_hw_cursor_x; |
| @@ -269,6 +266,7 @@ typedef struct CirrusVGAState { | @@ -269,6 +266,7 @@ typedef struct CirrusVGAState { | ||
| 269 | int last_hw_cursor_y_start; | 266 | int last_hw_cursor_y_start; |
| 270 | int last_hw_cursor_y_end; | 267 | int last_hw_cursor_y_end; |
| 271 | int real_vram_size; /* XXX: suppress that */ | 268 | int real_vram_size; /* XXX: suppress that */ |
| 269 | + CPUWriteMemoryFunc **cirrus_linear_write; | ||
| 272 | } CirrusVGAState; | 270 | } CirrusVGAState; |
| 273 | 271 | ||
| 274 | typedef struct PCICirrusVGAState { | 272 | typedef struct PCICirrusVGAState { |
| @@ -285,7 +283,8 @@ static uint8_t rop_to_index[256]; | @@ -285,7 +283,8 @@ static uint8_t rop_to_index[256]; | ||
| 285 | ***************************************/ | 283 | ***************************************/ |
| 286 | 284 | ||
| 287 | 285 | ||
| 288 | -static void cirrus_bitblt_reset(CirrusVGAState * s); | 286 | +static void cirrus_bitblt_reset(CirrusVGAState *s); |
| 287 | +static void cirrus_update_memory_access(CirrusVGAState *s); | ||
| 289 | 288 | ||
| 290 | /*************************************** | 289 | /*************************************** |
| 291 | * | 290 | * |
| @@ -711,9 +710,7 @@ static void cirrus_bitblt_reset(CirrusVGAState * s) | @@ -711,9 +710,7 @@ static void cirrus_bitblt_reset(CirrusVGAState * s) | ||
| 711 | s->cirrus_srcptr = &s->cirrus_bltbuf[0]; | 710 | s->cirrus_srcptr = &s->cirrus_bltbuf[0]; |
| 712 | s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; | 711 | s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; |
| 713 | s->cirrus_srccounter = 0; | 712 | s->cirrus_srccounter = 0; |
| 714 | - s->cirrus_dstptr = &s->cirrus_bltbuf[0]; | ||
| 715 | - s->cirrus_dstptr_end = &s->cirrus_bltbuf[0]; | ||
| 716 | - s->cirrus_dstcounter = 0; | 713 | + cirrus_update_memory_access(s); |
| 717 | } | 714 | } |
| 718 | 715 | ||
| 719 | static int cirrus_bitblt_cputovideo(CirrusVGAState * s) | 716 | static int cirrus_bitblt_cputovideo(CirrusVGAState * s) |
| @@ -746,6 +743,7 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) | @@ -746,6 +743,7 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) | ||
| 746 | } | 743 | } |
| 747 | s->cirrus_srcptr = s->cirrus_bltbuf; | 744 | s->cirrus_srcptr = s->cirrus_bltbuf; |
| 748 | s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; | 745 | s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; |
| 746 | + cirrus_update_memory_access(s); | ||
| 749 | return 1; | 747 | return 1; |
| 750 | } | 748 | } |
| 751 | 749 | ||
| @@ -1199,7 +1197,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) | @@ -1199,7 +1197,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) | ||
| 1199 | case 0x14: // Scratch Register 2 | 1197 | case 0x14: // Scratch Register 2 |
| 1200 | case 0x15: // Scratch Register 3 | 1198 | case 0x15: // Scratch Register 3 |
| 1201 | case 0x16: // Performance Tuning Register | 1199 | case 0x16: // Performance Tuning Register |
| 1202 | - case 0x17: // Configuration Readback and Extended Control | ||
| 1203 | case 0x18: // Signature Generator Control | 1200 | case 0x18: // Signature Generator Control |
| 1204 | case 0x19: // Signature Generator Result | 1201 | case 0x19: // Signature Generator Result |
| 1205 | case 0x1a: // Signature Generator Result | 1202 | case 0x1a: // Signature Generator Result |
| @@ -1214,6 +1211,10 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) | @@ -1214,6 +1211,10 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value) | ||
| 1214 | reg_index, reg_value); | 1211 | reg_index, reg_value); |
| 1215 | #endif | 1212 | #endif |
| 1216 | break; | 1213 | break; |
| 1214 | + case 0x17: // Configuration Readback and Extended Control | ||
| 1215 | + s->sr[reg_index] = reg_value; | ||
| 1216 | + cirrus_update_memory_access(s); | ||
| 1217 | + break; | ||
| 1217 | default: | 1218 | default: |
| 1218 | #ifdef DEBUG_CIRRUS | 1219 | #ifdef DEBUG_CIRRUS |
| 1219 | printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index, | 1220 | 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) | @@ -1348,13 +1349,19 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value) | ||
| 1348 | return CIRRUS_HOOK_NOT_HANDLED; | 1349 | return CIRRUS_HOOK_NOT_HANDLED; |
| 1349 | case 0x05: // Standard VGA, Cirrus extended mode | 1350 | case 0x05: // Standard VGA, Cirrus extended mode |
| 1350 | s->gr[reg_index] = reg_value & 0x7f; | 1351 | s->gr[reg_index] = reg_value & 0x7f; |
| 1352 | + cirrus_update_memory_access(s); | ||
| 1351 | break; | 1353 | break; |
| 1352 | case 0x09: // bank offset #0 | 1354 | case 0x09: // bank offset #0 |
| 1353 | case 0x0A: // bank offset #1 | 1355 | case 0x0A: // bank offset #1 |
| 1356 | + s->gr[reg_index] = reg_value; | ||
| 1357 | + cirrus_update_bank_ptr(s, 0); | ||
| 1358 | + cirrus_update_bank_ptr(s, 1); | ||
| 1359 | + break; | ||
| 1354 | case 0x0B: | 1360 | case 0x0B: |
| 1355 | s->gr[reg_index] = reg_value; | 1361 | s->gr[reg_index] = reg_value; |
| 1356 | cirrus_update_bank_ptr(s, 0); | 1362 | cirrus_update_bank_ptr(s, 0); |
| 1357 | cirrus_update_bank_ptr(s, 1); | 1363 | cirrus_update_bank_ptr(s, 1); |
| 1364 | + cirrus_update_memory_access(s); | ||
| 1358 | break; | 1365 | break; |
| 1359 | case 0x10: // BGCOLOR 0x0000ff00 | 1366 | case 0x10: // BGCOLOR 0x0000ff00 |
| 1360 | case 0x11: // FGCOLOR 0x0000ff00 | 1367 | case 0x11: // FGCOLOR 0x0000ff00 |
| @@ -2304,6 +2311,36 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = { | @@ -2304,6 +2311,36 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = { | ||
| 2304 | cirrus_linear_writel, | 2311 | cirrus_linear_writel, |
| 2305 | }; | 2312 | }; |
| 2306 | 2313 | ||
| 2314 | +static void cirrus_linear_mem_writeb(void *opaque, target_phys_addr_t addr, | ||
| 2315 | + uint32_t val) | ||
| 2316 | +{ | ||
| 2317 | + CirrusVGAState *s = (CirrusVGAState *) opaque; | ||
| 2318 | + | ||
| 2319 | + addr &= s->cirrus_addr_mask; | ||
| 2320 | + *(s->vram_ptr + addr) = val; | ||
| 2321 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); | ||
| 2322 | +} | ||
| 2323 | + | ||
| 2324 | +static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr, | ||
| 2325 | + uint32_t val) | ||
| 2326 | +{ | ||
| 2327 | + CirrusVGAState *s = (CirrusVGAState *) opaque; | ||
| 2328 | + | ||
| 2329 | + addr &= s->cirrus_addr_mask; | ||
| 2330 | + cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val); | ||
| 2331 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); | ||
| 2332 | +} | ||
| 2333 | + | ||
| 2334 | +static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr, | ||
| 2335 | + uint32_t val) | ||
| 2336 | +{ | ||
| 2337 | + CirrusVGAState *s = (CirrusVGAState *) opaque; | ||
| 2338 | + | ||
| 2339 | + addr &= s->cirrus_addr_mask; | ||
| 2340 | + cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val); | ||
| 2341 | + cpu_physical_memory_set_dirty(s->vram_offset + addr); | ||
| 2342 | +} | ||
| 2343 | + | ||
| 2307 | /*************************************** | 2344 | /*************************************** |
| 2308 | * | 2345 | * |
| 2309 | * system to screen memory access | 2346 | * system to screen memory access |
| @@ -2405,6 +2442,37 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = { | @@ -2405,6 +2442,37 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = { | ||
| 2405 | cirrus_linear_bitblt_writel, | 2442 | cirrus_linear_bitblt_writel, |
| 2406 | }; | 2443 | }; |
| 2407 | 2444 | ||
| 2445 | +/* Compute the memory access functions */ | ||
| 2446 | +static void cirrus_update_memory_access(CirrusVGAState *s) | ||
| 2447 | +{ | ||
| 2448 | + unsigned mode; | ||
| 2449 | + | ||
| 2450 | + if ((s->sr[0x17] & 0x44) == 0x44) { | ||
| 2451 | + goto generic_io; | ||
| 2452 | + } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) { | ||
| 2453 | + goto generic_io; | ||
| 2454 | + } else { | ||
| 2455 | + if ((s->gr[0x0B] & 0x14) == 0x14) { | ||
| 2456 | + goto generic_io; | ||
| 2457 | + } else if (s->gr[0x0B] & 0x02) { | ||
| 2458 | + goto generic_io; | ||
| 2459 | + } | ||
| 2460 | + | ||
| 2461 | + mode = s->gr[0x05] & 0x7; | ||
| 2462 | + if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) { | ||
| 2463 | + s->cirrus_linear_write[0] = cirrus_linear_mem_writeb; | ||
| 2464 | + s->cirrus_linear_write[1] = cirrus_linear_mem_writew; | ||
| 2465 | + s->cirrus_linear_write[2] = cirrus_linear_mem_writel; | ||
| 2466 | + } else { | ||
| 2467 | + generic_io: | ||
| 2468 | + s->cirrus_linear_write[0] = cirrus_linear_writeb; | ||
| 2469 | + s->cirrus_linear_write[1] = cirrus_linear_writew; | ||
| 2470 | + s->cirrus_linear_write[2] = cirrus_linear_writel; | ||
| 2471 | + } | ||
| 2472 | + } | ||
| 2473 | +} | ||
| 2474 | + | ||
| 2475 | + | ||
| 2408 | /* I/O ports */ | 2476 | /* I/O ports */ |
| 2409 | 2477 | ||
| 2410 | static uint32_t vga_ioport_read(void *opaque, uint32_t addr) | 2478 | 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) | @@ -2933,6 +3001,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) | ||
| 2933 | s->cirrus_linear_io_addr = | 3001 | s->cirrus_linear_io_addr = |
| 2934 | cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, | 3002 | cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, |
| 2935 | s); | 3003 | s); |
| 3004 | + s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr); | ||
| 3005 | + | ||
| 2936 | /* I/O handler for LFB */ | 3006 | /* I/O handler for LFB */ |
| 2937 | s->cirrus_linear_bitblt_io_addr = | 3007 | s->cirrus_linear_bitblt_io_addr = |
| 2938 | cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write, | 3008 | cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write, |