diff mbox

[Xen-devel] Cirrus VGA slow screen update, show blank screen last 13s or so for windows XP guest

Message ID 33183CC9F5247A488A2544077AF19020815935E0@SZXEMA503-MBS.china.huawei.com
State New
Headers show

Commit Message

Gonglei (Arei) Aug. 17, 2013, 9:04 a.m. UTC
Hi,
The fundamental reason is traditional qemu-dm and upstream qemu using a different vgabios-cirrus.bin,
qemu-dm is using xen-4.1.2/tools/firmware/vgabios/ VGABIOS-lgpl-latest.cirrus.bin, 
but upstream qemu is using qemu-1.2.2/pc-bios/vgabios-cirrus.bin

the pivotal patch is :

# HG changeset patch
# User Keir Fraser <keir@xensource.com>
# Date 1193391667 -3600
# Node ID d31f63db5f1e88deadc5461adda07b77c22873d7
# Parent  413107fa49a50e5c61ac390dc1870d8995b2a012

x86, hvm: Allow Cirrus VGA BIOS to clear framebuffer with minimal PIO writes.

Signed-off-by: Ben Guthro <bguthro@virtualron.com>

Signed-off-by: Gary Grebus <ggrebus@virtualiron.com>



By replacing the vgabios-cirrus.bin, the windows XP guest screen updating is fast with upstream qemu.

And I test the latest vgabios-0.7a come from 
http://www.nongnu.org/vgabios/#DOWNLOAD
but the problem of blank screen remain.

Best Regards!
-Gonglei
 

> -----Original Message-----

> From: Gonglei (Arei)

> Sent: Friday, August 16, 2013 5:10 PM

> To: Gonglei (Arei); 'Pasi Kärkkäinen'

> Cc: 'Gerd Hoffmann'; 'Andreas Färber'; Hanweidong; Luonengjun;

> 'qemu-devel@nongnu.org'; 'xen-devel@lists.xen.org'; 'Anthony Liguori';

> Huangweidong (Hardware); 'Ian.Jackson@eu.citrix.com'; 'Anthony Liguori';

> Yanqiangjun; Yangxiaowei

> Subject: RE: [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show

> blank screen last 13s or so for windows XP guest

> 

> Hi, all

> I compared the traditional qemu-dm and upstream qemu,

> and I found the upstream qemu will create the expansion ROM at f3000000,

> but qemu-dm don't.

> the details as below (by "lspci -vnnn"):

> 

> 1) traditional qemu-dm:

> 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]

> (prog-if 00 [VGA controller])

> 	Subsystem: XenSource, Inc. Device [5853:0001]

> 	Flags: bus master, fast devsel, latency 0, IRQ 11

> 	Memory at f0000000 (32-bit, prefetchable) [size=32M]

> 	Memory at f3000000 (32-bit, non-prefetchable) [size=4K]

> 	Kernel modules: cirrusfb

> 

> 2) upstream qemu:

> 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]

> (prog-if 00 [VGA controller])

> 	Subsystem: XenSource, Inc. Device [5853:0001]

> 	Physical Slot: 2

> 	Flags: bus master, fast devsel, latency 0, IRQ 11

> 	Memory at f0000000 (32-bit, prefetchable) [size=32M]

> 	Memory at f3020000 (32-bit, non-prefetchable) [size=4K]

> 	Expansion ROM at f3000000 [disabled] [size=64K]

> 	Kernel modules: cirrusfb

> 

> I tried to simply delete the expansion ROM at function pci_add_option_rom,

> such as

> 

>   //pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);

> 

> but the VNC viewer only can see black screen, but RDP works well.

> Any ideas about the cirrus's expansion ROM?

> Slow screen refresh has any relationship with cirrus's expansion ROM?

> Thank you in advance!

> 

> BTW, I added some log in stdvga.c(xen-4.1.2/xen/arch/x86/hvm):

> static int stdvga_intercept_mmio(ioreq_t *p)

> {

>     struct domain *d = current->domain;

>     struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;

>     int buf = 0, rc;

>     static int count_1 = 0;

>     static int count_2 = 0;

> 

>     if ( p->size > 8 )

>     {

>         gdprintk(XENLOG_WARNING, "invalid mmio size %d\n", (int)p->size);

>         return X86EMUL_UNHANDLEABLE;

>     }

> 

>     spin_lock(&s->lock);

> 

>     if ( s->stdvga && s->cache )

>     {

>         switch ( p->type )

>         {

>         case IOREQ_TYPE_COPY:

>             buf = mmio_move(s, p);

>             count_1++;

>             if (count_1 % 1000 == 0)

>                 gdprintk(XENLOG_WARNING, " =uvp= enter mmio_move,

> count_1=%d\n", count_1);

>             if ( !buf )

>                 s->cache = 0;

>             break;

>         default:

>             gdprintk(XENLOG_WARNING, "unsupported mmio request

> type:%d "

>                      "addr:0x%04x data:0x%04x size:%d count:%d

> state:%d "

>                      "isptr:%d dir:%d df:%d\n",

>                      p->type, (int)p->addr, (int)p->data, (int)p->size,

>                      (int)p->count, p->state,

>                      p->data_is_ptr, p->dir, p->df);

>             s->cache = 0;

>         }

>     }

>     else

>     {

>         buf = (p->dir == IOREQ_WRITE);

>         count_2++;

>         if (count_2 % 5000 == 0)

>             gdprintk(XENLOG_WARNING, " >>> vga mmio count_2=%d\n",

> count_2);

>     }

> 

>     rc = (buf && hvm_buffered_io_send(p));

> 

>     spin_unlock(&s->lock);

> 

>     return rc ? X86EMUL_OKAY : X86EMUL_UNHANDLEABLE;

> }

> 

> and I got the below result with upstream qemu and tranditional qemu-dm:

> 

>  1) traditional qemu-dm:

> (XEN) stdvga.c:152:d2 entering stdvga and caching modes

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=460000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=461000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=462000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=463000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=464000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=465000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=466000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=467000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=468000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=469000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=470000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=471000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=472000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=473000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=474000

> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=475000

> (XEN) stdvga.c:156:d2 leaving stdvga

> 

>  2) upstream qemu:

> (XEN) stdvga.c:152:d1 entering stdvga and caching modes

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=233000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=234000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=235000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=236000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=237000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=238000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=239000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=240000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=241000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=242000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=243000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=244000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=245000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=246000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=247000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=248000

> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=249000

> (XEN) stdvga.c:156:d1 leaving stdvga

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8400000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8405000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8410000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8415000

>   ... ... //Omit some similar

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12570000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12575000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12580000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12585000

> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12590000

> 

> Upstream qemu has lot's of MMIO access Memory region 0xa0000~0xc0000

> than traditional qemu-dm.

> 

> Best Regards!

> 

> -Gonglei

>

Comments

Konrad Rzeszutek Wilk Aug. 20, 2013, 7:45 p.m. UTC | #1
On Sat, Aug 17, 2013 at 09:04:29AM +0000, Gonglei (Arei) wrote:
> Hi,
> The fundamental reason is traditional qemu-dm and upstream qemu using a different vgabios-cirrus.bin,
> qemu-dm is using xen-4.1.2/tools/firmware/vgabios/ VGABIOS-lgpl-latest.cirrus.bin, 
> but upstream qemu is using qemu-1.2.2/pc-bios/vgabios-cirrus.bin
> 
> the pivotal patch is :
> 
> # HG changeset patch
> # User Keir Fraser <keir@xensource.com>
> # Date 1193391667 -3600
> # Node ID d31f63db5f1e88deadc5461adda07b77c22873d7
> # Parent  413107fa49a50e5c61ac390dc1870d8995b2a012
> 
> x86, hvm: Allow Cirrus VGA BIOS to clear framebuffer with minimal PIO writes.
> 
> Signed-off-by: Ben Guthro <bguthro@virtualron.com>
> Signed-off-by: Gary Grebus <ggrebus@virtualiron.com>

Ben's new address is <benjamin.guthro@citrix.com>. CC-ing him here.

> 
> diff -r 413107fa49a5 -r d31f63db5f1e tools/firmware/vgabios/clext.c
> --- a/tools/firmware/vgabios/clext.c	Fri Oct 26 10:33:12 2007 +0100
> +++ b/tools/firmware/vgabios/clext.c	Fri Oct 26 10:41:07 2007 +0100
> @@ -1489,14 +1489,26 @@
>    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
> diff -r 413107fa49a5 -r d31f63db5f1e tools/ioemu/hw/cirrus_vga.c
> --- a/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:33:12 2007 +0100
> +++ b/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:41:07 2007 +0100
> @@ -294,6 +294,7 @@
>  
>  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 @@
>      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,
> 
> By replacing the vgabios-cirrus.bin, the windows XP guest screen updating is fast with upstream qemu.
> 
> And I test the latest vgabios-0.7a come from 
> http://www.nongnu.org/vgabios/#DOWNLOAD
> but the problem of blank screen remain.
> 
> Best Regards!
> -Gonglei
>  
> 
> > -----Original Message-----
> > From: Gonglei (Arei)
> > Sent: Friday, August 16, 2013 5:10 PM
> > To: Gonglei (Arei); 'Pasi Kärkkäinen'
> > Cc: 'Gerd Hoffmann'; 'Andreas Färber'; Hanweidong; Luonengjun;
> > 'qemu-devel@nongnu.org'; 'xen-devel@lists.xen.org'; 'Anthony Liguori';
> > Huangweidong (Hardware); 'Ian.Jackson@eu.citrix.com'; 'Anthony Liguori';
> > Yanqiangjun; Yangxiaowei
> > Subject: RE: [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show
> > blank screen last 13s or so for windows XP guest
> > 
> > Hi, all
> > I compared the traditional qemu-dm and upstream qemu,
> > and I found the upstream qemu will create the expansion ROM at f3000000,
> > but qemu-dm don't.
> > the details as below (by "lspci -vnnn"):
> > 
> > 1) traditional qemu-dm:
> > 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]
> > (prog-if 00 [VGA controller])
> > 	Subsystem: XenSource, Inc. Device [5853:0001]
> > 	Flags: bus master, fast devsel, latency 0, IRQ 11
> > 	Memory at f0000000 (32-bit, prefetchable) [size=32M]
> > 	Memory at f3000000 (32-bit, non-prefetchable) [size=4K]
> > 	Kernel modules: cirrusfb
> > 
> > 2) upstream qemu:
> > 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]
> > (prog-if 00 [VGA controller])
> > 	Subsystem: XenSource, Inc. Device [5853:0001]
> > 	Physical Slot: 2
> > 	Flags: bus master, fast devsel, latency 0, IRQ 11
> > 	Memory at f0000000 (32-bit, prefetchable) [size=32M]
> > 	Memory at f3020000 (32-bit, non-prefetchable) [size=4K]
> > 	Expansion ROM at f3000000 [disabled] [size=64K]
> > 	Kernel modules: cirrusfb
> > 
> > I tried to simply delete the expansion ROM at function pci_add_option_rom,
> > such as
> > 
> >   //pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
> > 
> > but the VNC viewer only can see black screen, but RDP works well.
> > Any ideas about the cirrus's expansion ROM?
> > Slow screen refresh has any relationship with cirrus's expansion ROM?
> > Thank you in advance!
> > 
> > BTW, I added some log in stdvga.c(xen-4.1.2/xen/arch/x86/hvm):
> > static int stdvga_intercept_mmio(ioreq_t *p)
> > {
> >     struct domain *d = current->domain;
> >     struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;
> >     int buf = 0, rc;
> >     static int count_1 = 0;
> >     static int count_2 = 0;
> > 
> >     if ( p->size > 8 )
> >     {
> >         gdprintk(XENLOG_WARNING, "invalid mmio size %d\n", (int)p->size);
> >         return X86EMUL_UNHANDLEABLE;
> >     }
> > 
> >     spin_lock(&s->lock);
> > 
> >     if ( s->stdvga && s->cache )
> >     {
> >         switch ( p->type )
> >         {
> >         case IOREQ_TYPE_COPY:
> >             buf = mmio_move(s, p);
> >             count_1++;
> >             if (count_1 % 1000 == 0)
> >                 gdprintk(XENLOG_WARNING, " =uvp= enter mmio_move,
> > count_1=%d\n", count_1);
> >             if ( !buf )
> >                 s->cache = 0;
> >             break;
> >         default:
> >             gdprintk(XENLOG_WARNING, "unsupported mmio request
> > type:%d "
> >                      "addr:0x%04x data:0x%04x size:%d count:%d
> > state:%d "
> >                      "isptr:%d dir:%d df:%d\n",
> >                      p->type, (int)p->addr, (int)p->data, (int)p->size,
> >                      (int)p->count, p->state,
> >                      p->data_is_ptr, p->dir, p->df);
> >             s->cache = 0;
> >         }
> >     }
> >     else
> >     {
> >         buf = (p->dir == IOREQ_WRITE);
> >         count_2++;
> >         if (count_2 % 5000 == 0)
> >             gdprintk(XENLOG_WARNING, " >>> vga mmio count_2=%d\n",
> > count_2);
> >     }
> > 
> >     rc = (buf && hvm_buffered_io_send(p));
> > 
> >     spin_unlock(&s->lock);
> > 
> >     return rc ? X86EMUL_OKAY : X86EMUL_UNHANDLEABLE;
> > }
> > 
> > and I got the below result with upstream qemu and tranditional qemu-dm:
> > 
> >  1) traditional qemu-dm:
> > (XEN) stdvga.c:152:d2 entering stdvga and caching modes
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=460000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=461000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=462000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=463000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=464000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=465000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=466000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=467000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=468000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=469000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=470000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=471000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=472000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=473000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=474000
> > (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=475000
> > (XEN) stdvga.c:156:d2 leaving stdvga
> > 
> >  2) upstream qemu:
> > (XEN) stdvga.c:152:d1 entering stdvga and caching modes
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=233000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=234000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=235000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=236000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=237000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=238000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=239000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=240000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=241000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=242000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=243000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=244000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=245000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=246000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=247000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=248000
> > (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=249000
> > (XEN) stdvga.c:156:d1 leaving stdvga
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8400000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8405000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8410000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8415000
> >   ... ... //Omit some similar
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12570000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12575000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12580000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12585000
> > (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12590000
> > 
> > Upstream qemu has lot's of MMIO access Memory region 0xa0000~0xc0000
> > than traditional qemu-dm.
> > 
> > Best Regards!
> > 
> > -Gonglei
> > 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
Ben Guthro Aug. 21, 2013, 12:02 a.m. UTC | #2
On Aug 20, 2013, at 3:45 PM, Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 wrote:

> On Sat, Aug 17, 2013 at 09:04:29AM +0000, Gonglei (Arei) wrote:

>> Hi,

>> The fundamental reason is traditional qemu-dm and upstream qemu using a different vgabios-cirrus.bin,

>> qemu-dm is using xen-4.1.2/tools/firmware/vgabios/ VGABIOS-lgpl-latest.cirrus.bin, 

>> but upstream qemu is using qemu-1.2.2/pc-bios/vgabios-cirrus.bin

>> 

>> the pivotal patch is :

>> 

>> # HG changeset patch

>> # User Keir Fraser <keir@xensource.com>

>> # Date 1193391667 -3600

>> # Node ID d31f63db5f1e88deadc5461adda07b77c22873d7

>> # Parent  413107fa49a50e5c61ac390dc1870d8995b2a012

>> 

>> x86, hvm: Allow Cirrus VGA BIOS to clear framebuffer with minimal PIO writes.

>> 

>> Signed-off-by: Ben Guthro <bguthro@virtualron.com>

>> Signed-off-by: Gary Grebus <ggrebus@virtualiron.com>

> 

> Ben's new address is <benjamin.guthro@citrix.com>. CC-ing him here.


FWIW, I took Gary's patch, and made it apply to unstable, at that time.
He was the primary developer, in that case.

That's how I recall it, anyhow...from 6 years ago.

I don't have Gary's new contact info.

Regards,
Ben

> 

>> 

>> diff -r 413107fa49a5 -r d31f63db5f1e tools/firmware/vgabios/clext.c

>> --- a/tools/firmware/vgabios/clext.c	Fri Oct 26 10:33:12 2007 +0100

>> +++ b/tools/firmware/vgabios/clext.c	Fri Oct 26 10:41:07 2007 +0100

>> @@ -1489,14 +1489,26 @@

>>   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

>> diff -r 413107fa49a5 -r d31f63db5f1e tools/ioemu/hw/cirrus_vga.c

>> --- a/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:33:12 2007 +0100

>> +++ b/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:41:07 2007 +0100

>> @@ -294,6 +294,7 @@

>> 

>> 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 @@

>>     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,

>> 

>> By replacing the vgabios-cirrus.bin, the windows XP guest screen updating is fast with upstream qemu.

>> 

>> And I test the latest vgabios-0.7a come from 

>> http://www.nongnu.org/vgabios/#DOWNLOAD

>> but the problem of blank screen remain.

>> 

>> Best Regards!

>> -Gonglei

>> 

>> 

>>> -----Original Message-----

>>> From: Gonglei (Arei)

>>> Sent: Friday, August 16, 2013 5:10 PM

>>> To: Gonglei (Arei); 'Pasi Kärkkäinen'

>>> Cc: 'Gerd Hoffmann'; 'Andreas Färber'; Hanweidong; Luonengjun;

>>> 'qemu-devel@nongnu.org'; 'xen-devel@lists.xen.org'; 'Anthony Liguori';

>>> Huangweidong (Hardware); 'Ian.Jackson@eu.citrix.com'; 'Anthony Liguori';

>>> Yanqiangjun; Yangxiaowei

>>> Subject: RE: [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show

>>> blank screen last 13s or so for windows XP guest

>>> 

>>> Hi, all

>>> I compared the traditional qemu-dm and upstream qemu,

>>> and I found the upstream qemu will create the expansion ROM at f3000000,

>>> but qemu-dm don't.

>>> the details as below (by "lspci -vnnn"):

>>> 

>>> 1) traditional qemu-dm:

>>> 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]

>>> (prog-if 00 [VGA controller])

>>> 	Subsystem: XenSource, Inc. Device [5853:0001]

>>> 	Flags: bus master, fast devsel, latency 0, IRQ 11

>>> 	Memory at f0000000 (32-bit, prefetchable) [size=32M]

>>> 	Memory at f3000000 (32-bit, non-prefetchable) [size=4K]

>>> 	Kernel modules: cirrusfb

>>> 

>>> 2) upstream qemu:

>>> 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]

>>> (prog-if 00 [VGA controller])

>>> 	Subsystem: XenSource, Inc. Device [5853:0001]

>>> 	Physical Slot: 2

>>> 	Flags: bus master, fast devsel, latency 0, IRQ 11

>>> 	Memory at f0000000 (32-bit, prefetchable) [size=32M]

>>> 	Memory at f3020000 (32-bit, non-prefetchable) [size=4K]

>>> 	Expansion ROM at f3000000 [disabled] [size=64K]

>>> 	Kernel modules: cirrusfb

>>> 

>>> I tried to simply delete the expansion ROM at function pci_add_option_rom,

>>> such as

>>> 

>>>  //pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);

>>> 

>>> but the VNC viewer only can see black screen, but RDP works well.

>>> Any ideas about the cirrus's expansion ROM?

>>> Slow screen refresh has any relationship with cirrus's expansion ROM?

>>> Thank you in advance!

>>> 

>>> BTW, I added some log in stdvga.c(xen-4.1.2/xen/arch/x86/hvm):

>>> static int stdvga_intercept_mmio(ioreq_t *p)

>>> {

>>>    struct domain *d = current->domain;

>>>    struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;

>>>    int buf = 0, rc;

>>>    static int count_1 = 0;

>>>    static int count_2 = 0;

>>> 

>>>    if ( p->size > 8 )

>>>    {

>>>        gdprintk(XENLOG_WARNING, "invalid mmio size %d\n", (int)p->size);

>>>        return X86EMUL_UNHANDLEABLE;

>>>    }

>>> 

>>>    spin_lock(&s->lock);

>>> 

>>>    if ( s->stdvga && s->cache )

>>>    {

>>>        switch ( p->type )

>>>        {

>>>        case IOREQ_TYPE_COPY:

>>>            buf = mmio_move(s, p);

>>>            count_1++;

>>>            if (count_1 % 1000 == 0)

>>>                gdprintk(XENLOG_WARNING, " =uvp= enter mmio_move,

>>> count_1=%d\n", count_1);

>>>            if ( !buf )

>>>                s->cache = 0;

>>>            break;

>>>        default:

>>>            gdprintk(XENLOG_WARNING, "unsupported mmio request

>>> type:%d "

>>>                     "addr:0x%04x data:0x%04x size:%d count:%d

>>> state:%d "

>>>                     "isptr:%d dir:%d df:%d\n",

>>>                     p->type, (int)p->addr, (int)p->data, (int)p->size,

>>>                     (int)p->count, p->state,

>>>                     p->data_is_ptr, p->dir, p->df);

>>>            s->cache = 0;

>>>        }

>>>    }

>>>    else

>>>    {

>>>        buf = (p->dir == IOREQ_WRITE);

>>>        count_2++;

>>>        if (count_2 % 5000 == 0)

>>>            gdprintk(XENLOG_WARNING, " >>> vga mmio count_2=%d\n",

>>> count_2);

>>>    }

>>> 

>>>    rc = (buf && hvm_buffered_io_send(p));

>>> 

>>>    spin_unlock(&s->lock);

>>> 

>>>    return rc ? X86EMUL_OKAY : X86EMUL_UNHANDLEABLE;

>>> }

>>> 

>>> and I got the below result with upstream qemu and tranditional qemu-dm:

>>> 

>>> 1) traditional qemu-dm:

>>> (XEN) stdvga.c:152:d2 entering stdvga and caching modes

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=460000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=461000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=462000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=463000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=464000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=465000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=466000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=467000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=468000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=469000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=470000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=471000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=472000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=473000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=474000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=475000

>>> (XEN) stdvga.c:156:d2 leaving stdvga

>>> 

>>> 2) upstream qemu:

>>> (XEN) stdvga.c:152:d1 entering stdvga and caching modes

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=233000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=234000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=235000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=236000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=237000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=238000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=239000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=240000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=241000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=242000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=243000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=244000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=245000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=246000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=247000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=248000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=249000

>>> (XEN) stdvga.c:156:d1 leaving stdvga

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8400000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8405000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8410000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8415000

>>>  ... ... //Omit some similar

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12570000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12575000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12580000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12585000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12590000

>>> 

>>> Upstream qemu has lot's of MMIO access Memory region 0xa0000~0xc0000

>>> than traditional qemu-dm.

>>> 

>>> Best Regards!

>>> 

>>> -Gonglei

>>> 

>> _______________________________________________

>> Xen-devel mailing list

>> Xen-devel@lists.xen.org

>> http://lists.xen.org/xen-devel
Gonglei (Arei) Aug. 27, 2013, 3:08 p.m. UTC | #3
Hi all.
  I got another trouble after I using that patch, which windows 2003 32bit guest VNC display wasn't normal,
please see the attached. In addition, windows 2003 64bit guest had a normal display.
I couldn't understand it, anyone can help me? Thanks you in advance.

The patch is:
http://xen.1045712.n5.nabble.com/PATCH-QEMU-Clear-bios-framebuffer-with-minimal-writes-td2511735.html

Best Regards,
-Gonglei

> -----Original Message-----

> Subject: Re: [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show

> blank screen last 13s or so for windows XP guest

> 

> 

> On Aug 20, 2013, at 3:45 PM, Konrad Rzeszutek Wilk

> <konrad.wilk@oracle.com>

>  wrote:

> 

> > On Sat, Aug 17, 2013 at 09:04:29AM +0000, Gonglei (Arei) wrote:

> >> Hi,

> >> The fundamental reason is traditional qemu-dm and upstream qemu using a

> different vgabios-cirrus.bin,

> >> qemu-dm is using xen-4.1.2/tools/firmware/vgabios/

> VGABIOS-lgpl-latest.cirrus.bin,

> >> but upstream qemu is using qemu-1.2.2/pc-bios/vgabios-cirrus.bin

> >>

> >> the pivotal patch is :

> >>

> >> # HG changeset patch

> >> # User Keir Fraser <keir@xensource.com>

> >> # Date 1193391667 -3600

> >> # Node ID d31f63db5f1e88deadc5461adda07b77c22873d7

> >> # Parent  413107fa49a50e5c61ac390dc1870d8995b2a012

> >>

> >> x86, hvm: Allow Cirrus VGA BIOS to clear framebuffer with minimal PIO

> writes.

> >>

> >> Signed-off-by: Ben Guthro <bguthro@virtualron.com>

> >> Signed-off-by: Gary Grebus <ggrebus@virtualiron.com>

> >

> > Ben's new address is <benjamin.guthro@citrix.com>. CC-ing him here.

> 

> FWIW, I took Gary's patch, and made it apply to unstable, at that time.

> He was the primary developer, in that case.

> 

> That's how I recall it, anyhow...from 6 years ago.

> 

> I don't have Gary's new contact info.

> 

> Regards,

> Ben

> 

> >

> >>

> >> diff -r 413107fa49a5 -r d31f63db5f1e tools/firmware/vgabios/clext.c

> >> --- a/tools/firmware/vgabios/clext.c	Fri Oct 26 10:33:12 2007 +0100

> >> +++ b/tools/firmware/vgabios/clext.c	Fri Oct 26 10:41:07 2007 +0100

> >> @@ -1489,14 +1489,26 @@

> >>   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

> >> diff -r 413107fa49a5 -r d31f63db5f1e tools/ioemu/hw/cirrus_vga.c

> >> --- a/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:33:12 2007 +0100

> >> +++ b/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:41:07 2007 +0100

> >> @@ -294,6 +294,7 @@

> >>

> >> 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 @@

> >>     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,

> >>

> >> By replacing the vgabios-cirrus.bin, the windows XP guest screen updating is

> fast with upstream qemu.

> >>

> >> And I test the latest vgabios-0.7a come from

> >> http://www.nongnu.org/vgabios/#DOWNLOAD

> >> but the problem of blank screen remain.

> >>

>> Best Regards!

>> -Gonglei

>> 

>> 

>>> -----Original Message-----

>>> From: Gonglei (Arei)

>>> Sent: Friday, August 16, 2013 5:10 PM

>>> To: Gonglei (Arei); 'Pasi Kärkkäinen'

>>> Cc: 'Gerd Hoffmann'; 'Andreas Färber'; Hanweidong; Luonengjun;

>>> 'qemu-devel@nongnu.org'; 'xen-devel@lists.xen.org'; 'Anthony Liguori';

>>> Huangweidong (Hardware); 'Ian.Jackson@eu.citrix.com'; 'Anthony Liguori';

>>> Yanqiangjun; Yangxiaowei

>>> Subject: RE: [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show

>>> blank screen last 13s or so for windows XP guest

>>> 

>>> Hi, all

>>> I compared the traditional qemu-dm and upstream qemu,

>>> and I found the upstream qemu will create the expansion ROM at f3000000,

>>> but qemu-dm don't.

>>> the details as below (by "lspci -vnnn"):

>>> 

>>> 1) traditional qemu-dm:

>>> 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]

>>> (prog-if 00 [VGA controller])

>>> 	Subsystem: XenSource, Inc. Device [5853:0001]

>>> 	Flags: bus master, fast devsel, latency 0, IRQ 11

>>> 	Memory at f0000000 (32-bit, prefetchable) [size=32M]

>>> 	Memory at f3000000 (32-bit, non-prefetchable) [size=4K]

>>> 	Kernel modules: cirrusfb

>>> 

>>> 2) upstream qemu:

>>> 00:02.0 VGA compatible controller [0300]: Cirrus Logic GD 5446 [1013:00b8]

>>> (prog-if 00 [VGA controller])

>>> 	Subsystem: XenSource, Inc. Device [5853:0001]

>>> 	Physical Slot: 2

>>> 	Flags: bus master, fast devsel, latency 0, IRQ 11

>>> 	Memory at f0000000 (32-bit, prefetchable) [size=32M]

>>> 	Memory at f3020000 (32-bit, non-prefetchable) [size=4K]

>>> 	Expansion ROM at f3000000 [disabled] [size=64K]

>>> 	Kernel modules: cirrusfb

>>> 

>>> I tried to simply delete the expansion ROM at function pci_add_option_rom,

>>> such as

>>> 

>>>  //pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);

>>> 

>>> but the VNC viewer only can see black screen, but RDP works well.

>>> Any ideas about the cirrus's expansion ROM?

>>> Slow screen refresh has any relationship with cirrus's expansion ROM?

>>> Thank you in advance!

>>> 

>>> BTW, I added some log in stdvga.c(xen-4.1.2/xen/arch/x86/hvm):

>>> static int stdvga_intercept_mmio(ioreq_t *p)

>>> {

>>>    struct domain *d = current->domain;

>>>    struct hvm_hw_stdvga *s = &d->arch.hvm_domain.stdvga;

>>>    int buf = 0, rc;

>>>    static int count_1 = 0;

>>>    static int count_2 = 0;

>>> 

>>>    if ( p->size > 8 )

>>>    {

>>>        gdprintk(XENLOG_WARNING, "invalid mmio size %d\n", (int)p->size);

>>>        return X86EMUL_UNHANDLEABLE;

>>>    }

>>> 

>>>    spin_lock(&s->lock);

>>> 

>>>    if ( s->stdvga && s->cache )

>>>    {

>>>        switch ( p->type )

>>>        {

>>>        case IOREQ_TYPE_COPY:

>>>            buf = mmio_move(s, p);

>>>            count_1++;

>>>            if (count_1 % 1000 == 0)

>>>                gdprintk(XENLOG_WARNING, " =uvp= enter mmio_move,

>>> count_1=%d\n", count_1);

>>>            if ( !buf )

>>>                s->cache = 0;

>>>            break;

>>>        default:

>>>            gdprintk(XENLOG_WARNING, "unsupported mmio request

>>> type:%d "

>>>                     "addr:0x%04x data:0x%04x size:%d count:%d

>>> state:%d "

>>>                     "isptr:%d dir:%d df:%d\n",

>>>                     p->type, (int)p->addr, (int)p->data, (int)p->size,

>>>                     (int)p->count, p->state,

>>>                     p->data_is_ptr, p->dir, p->df);

>>>            s->cache = 0;

>>>        }

>>>    }

>>>    else

>>>    {

>>>        buf = (p->dir == IOREQ_WRITE);

>>>        count_2++;

>>>        if (count_2 % 5000 == 0)

>>>            gdprintk(XENLOG_WARNING, " >>> vga mmio count_2=%d\n",

>>> count_2);

>>>    }

>>> 

>>>    rc = (buf && hvm_buffered_io_send(p));

>>> 

>>>    spin_unlock(&s->lock);

>>> 

>>>    return rc ? X86EMUL_OKAY : X86EMUL_UNHANDLEABLE;

>>> }

>>> 

>>> and I got the below result with upstream qemu and tranditional qemu-dm:

>>> 

>>> 1) traditional qemu-dm:

>>> (XEN) stdvga.c:152:d2 entering stdvga and caching modes

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=460000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=461000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=462000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=463000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=464000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=465000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=466000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=467000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=468000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=469000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=470000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=471000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=472000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=473000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=474000

>>> (XEN) stdvga.c:577:d2  =uvp= enter mmio_move, count_1=475000

>>> (XEN) stdvga.c:156:d2 leaving stdvga

>>> 

>>> 2) upstream qemu:

>>> (XEN) stdvga.c:152:d1 entering stdvga and caching modes

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=233000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=234000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=235000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=236000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=237000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=238000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=239000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=240000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=241000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=242000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=243000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=244000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=245000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=246000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=247000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=248000

>>> (XEN) stdvga.c:577:d1  =uvp= enter mmio_move, count_1=249000

>>> (XEN) stdvga.c:156:d1 leaving stdvga

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8400000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8405000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8410000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=8415000

>>>  ... ... //Omit some similar

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12570000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12575000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12580000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12585000

>>> (XEN) stdvga.c:596:d1  >>> vga mmio count_2=12590000

>>> 

>>> Upstream qemu has lot's of MMIO access Memory region 0xa0000~0xc0000

>>> than traditional qemu-dm.

>>> 

>>> Best Regards!

>>> 

>>> -Gonglei

>>> 

>> _______________________________________________

>> Xen-devel mailing list

>> Xen-devel@lists.xen.org

>> http://lists.xen.org/xen-devel
diff mbox

Patch

diff -r 413107fa49a5 -r d31f63db5f1e tools/firmware/vgabios/clext.c
--- a/tools/firmware/vgabios/clext.c	Fri Oct 26 10:33:12 2007 +0100
+++ b/tools/firmware/vgabios/clext.c	Fri Oct 26 10:41:07 2007 +0100
@@ -1489,14 +1489,26 @@ 
   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
diff -r 413107fa49a5 -r d31f63db5f1e tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:33:12 2007 +0100
+++ b/tools/ioemu/hw/cirrus_vga.c	Fri Oct 26 10:41:07 2007 +0100
@@ -294,6 +294,7 @@ 
 
 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 @@ 
     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,