]> xenbits.xensource.com Git - xen.git/commitdiff
x86, hvm: Allow Cirrus VGA BIOS to clear framebuffer with minimal PIO writes.
authorKeir Fraser <keir@xensource.com>
Fri, 26 Oct 2007 09:41:07 +0000 (10:41 +0100)
committerKeir Fraser <keir@xensource.com>
Fri, 26 Oct 2007 09:41:07 +0000 (10:41 +0100)
Signed-off-by: Ben Guthro <bguthro@virtualron.com>
Signed-off-by: Gary Grebus <ggrebus@virtualiron.com>
tools/firmware/vgabios/clext.c
tools/ioemu/hw/cirrus_vga.c

index 1eb3c69734d34cd7cc531c75a2e7297a6714abd7..97ae080b2cdb63aa363a023bb263ce693594f2af 100644 (file)
@@ -1489,14 +1489,26 @@ cirrus_clear_vram_1:
   mov dx, #0x3ce
   out dx, ax
   push ax
-  mov cx, #0xa000
-  mov es, cx
-  xor di, di
+
+;; Windows Vista appears to be emulating this sequence as part of changing 
+;; screen resolution, but it generates 4096 writes per iteration.
+;; Instead, use a magic register sequence to write the whole bank.
+;;mov cx, #0xa000
+;;mov es, cx
+;;xor di, di
+;;mov ax, si
+;;mov cx, #8192
+;;cld
+;;rep
+;;    stosw
   mov ax, si
-  mov cx, #8192
-  cld
-  rep
-      stosw
+  shl ax, #8
+  mov al, #0xfe
+  out dx, ax   ;; Low byte of value to be written to the bank
+  mov ax, si
+  mov al, #0xff  
+  out dx, ax    ;; High byte and trigger the write
+
   pop ax
   inc ah
   cmp ah, bl
index 2fd162636250b1d6f6094f21b4886dd3a72c6a1d..8a637c57fd266c9dc1b731e919f442437990d117 100644 (file)
@@ -294,6 +294,7 @@ void *shared_vram;
 
 static void cirrus_bitblt_reset(CirrusVGAState *s);
 static void cirrus_update_memory_access(CirrusVGAState *s);
+static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val);
 
 /***************************************
  *
@@ -1497,6 +1498,17 @@ cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
     case 0x31:                 // BLT STATUS/START
        cirrus_write_bitblt(s, reg_value);
        break;
+
+       // Extension to allow BIOS to clear 16K VRAM bank in one operation
+    case 0xFE:
+       s->gr[reg_index] = reg_value;  // Lower byte of value to be written
+       break;
+    case 0xFF: {
+       target_phys_addr_t addr;
+       for (addr = 0xa0000; addr < 0xa4000; addr += 2)
+           cirrus_vga_mem_writew(s, addr, (reg_value << 8) | s->gr[0xFE]);
+       }
+       break;
     default:
 #ifdef DEBUG_CIRRUS
        printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,