[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Vgabios-developers] [Xen-devel] [Qemu-devel] Cirrus VGA slow screen
From: |
Gonglei (Arei) |
Subject: |
Re: [Vgabios-developers] [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show blank screen last 13s or so for windows XP guest |
Date: |
Sat, 17 Aug 2013 09:04:29 +0000 |
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 <address@hidden>
# 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 <address@hidden>
Signed-off-by: Gary Grebus <address@hidden>
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;
> 'address@hidden'; 'address@hidden'; 'Anthony Liguori';
> Huangweidong (Hardware); 'address@hidden'; '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
>
- Re: [Vgabios-developers] [Xen-devel] [Qemu-devel] Cirrus VGA slow screen update, show blank screen last 13s or so for windows XP guest,
Gonglei (Arei) <=