Konrad Rzeszutek Wilk
2013-Aug-20 19:45 UTC
Re: [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@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_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel