This patch has been sent to upstream vgabios maillist, but there is no response. Since it is useful for windows8 resolution, I resend it to qemu maillist for review.
Signed-off-by: Bo Yang <boy...@suse.com> --- vbe.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 files changed, 38 insertions(+), 4 deletions(-) diff --git a/vbe.c b/vbe.c index 1fab2f9..eb9150c 100644 --- a/vbe.c +++ b/vbe.c @@ -754,6 +754,29 @@ lmulul: ret ASM_END +ASM_START +_size64: + push bp + mov bp, sp + push dx + +; multiply bbp by yres first as results fit in 16bits +; then multiply by xres + mov ax, 8[bp] + mul word 6[bp] + mul word 4[bp] +; divide by 2^19 ceiling result + add ax, #0xffff + adc dx, #7 + mov ax, dx + shr ax, #3 + + pop dx + pop bp + ret +ASM_END + + /** Function 00h - Return VBE Controller Information * * Input: @@ -857,7 +880,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI; do { - size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; + Bit16u size_64k = size64(cur_info->info.XResolution, cur_info->info.YResolution, cur_info->info.BitsPerPixel); if ((cur_info->info.XResolution <= dispi_get_max_xres()) && (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && @@ -917,14 +940,25 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; if (cur_info != 0) { + Bit16u max_bpp = dispi_get_max_bpp(); + Bit16u size_64k; + Bit16u totalMemory; + + outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + totalMemory = inw(VBE_DISPI_IOPORT_DATA); #ifdef DEBUG printf("VBE found mode %x\n",CX); #endif memsetb(ss, &info, 0, sizeof(ModeInfoBlock)); memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); - if (using_lfb) { - info.NumberOfBanks = 1; - } + size_64k = size64(info.XResolution, info.YResolution, info.BitsPerPixel); + if ((info.XResolution > dispi_get_max_xres()) || + (info.BitsPerPixel > max_bpp) || + (size_64k > totalMemory)) + info.ModeAttributes &= ~VBE_MODE_ATTRIBUTE_SUPPORTED; + + /* Windows 8 require this to be 1! */ + info.NumberOfBanks = 1; #ifdef PCI_VID lfb_addr = pci_get_lfb_addr(PCI_VID); #else -- 1.6.0.2