Commit 8926b517e9ebe20a4348f445e9d0c7f11029eb57

Authored by bellard
1 parent 6d46bf8a

faster Cirrus VGA VRAM access


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1114 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
... ... @@ -692,6 +692,8 @@ int cpu_register_io_memory(int io_index,
692 692 CPUReadMemoryFunc **mem_read,
693 693 CPUWriteMemoryFunc **mem_write,
694 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 698 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
697 699 int len, int is_write);
... ...
... ... @@ -1977,6 +1977,16 @@ int cpu_register_io_memory(int io_index,
1977 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 1990 /* physical memory access (slow version, mainly for debug) */
1981 1991 #if defined(CONFIG_USER_ONLY)
1982 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 259 uint8_t *cirrus_srcptr;
260 260 uint8_t *cirrus_srcptr_end;
261 261 uint32_t cirrus_srccounter;
262   - uint8_t *cirrus_dstptr;
263   - uint8_t *cirrus_dstptr_end;
264   - uint32_t cirrus_dstcounter;
265 262 /* hwcursor display state */
266 263 int last_hw_cursor_size;
267 264 int last_hw_cursor_x;
... ... @@ -269,6 +266,7 @@ typedef struct CirrusVGAState {
269 266 int last_hw_cursor_y_start;
270 267 int last_hw_cursor_y_end;
271 268 int real_vram_size; /* XXX: suppress that */
  269 + CPUWriteMemoryFunc **cirrus_linear_write;
272 270 } CirrusVGAState;
273 271  
274 272 typedef struct PCICirrusVGAState {
... ... @@ -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 710 s->cirrus_srcptr = &s->cirrus_bltbuf[0];
712 711 s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
713 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 716 static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
... ... @@ -746,6 +743,7 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
746 743 }
747 744 s->cirrus_srcptr = s->cirrus_bltbuf;
748 745 s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
  746 + cirrus_update_memory_access(s);
749 747 return 1;
750 748 }
751 749  
... ... @@ -1199,7 +1197,6 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1199 1197 case 0x14: // Scratch Register 2
1200 1198 case 0x15: // Scratch Register 3
1201 1199 case 0x16: // Performance Tuning Register
1202   - case 0x17: // Configuration Readback and Extended Control
1203 1200 case 0x18: // Signature Generator Control
1204 1201 case 0x19: // Signature Generator Result
1205 1202 case 0x1a: // Signature Generator Result
... ... @@ -1214,6 +1211,10 @@ cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
1214 1211 reg_index, reg_value);
1215 1212 #endif
1216 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 1218 default:
1218 1219 #ifdef DEBUG_CIRRUS
1219 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 1349 return CIRRUS_HOOK_NOT_HANDLED;
1349 1350 case 0x05: // Standard VGA, Cirrus extended mode
1350 1351 s->gr[reg_index] = reg_value & 0x7f;
  1352 + cirrus_update_memory_access(s);
1351 1353 break;
1352 1354 case 0x09: // bank offset #0
1353 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 1360 case 0x0B:
1355 1361 s->gr[reg_index] = reg_value;
1356 1362 cirrus_update_bank_ptr(s, 0);
1357 1363 cirrus_update_bank_ptr(s, 1);
  1364 + cirrus_update_memory_access(s);
1358 1365 break;
1359 1366 case 0x10: // BGCOLOR 0x0000ff00
1360 1367 case 0x11: // FGCOLOR 0x0000ff00
... ... @@ -2304,6 +2311,36 @@ static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
2304 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 2346 * system to screen memory access
... ... @@ -2405,6 +2442,37 @@ static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
2405 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 2476 /* I/O ports */
2409 2477  
2410 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 3001 s->cirrus_linear_io_addr =
2934 3002 cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
2935 3003 s);
  3004 + s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
  3005 +
2936 3006 /* I/O handler for LFB */
2937 3007 s->cirrus_linear_bitblt_io_addr =
2938 3008 cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
... ...