[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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@xxxxxxxxxxxxx>
> # 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@xxxxxxxxxxxxxx>
> Signed-off-by: Gary Grebus <ggrebus@xxxxxxxxxxxxxxx>

Ben's new address is <benjamin.guthro@xxxxxxxxxx>. 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@xxxxxxxxxx'; 'xen-devel@xxxxxxxxxxxxx'; 'Anthony Liguori';
> > Huangweidong (Hardware); 'Ian.Jackson@xxxxxxxxxxxxx'; '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@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.