There are a could of patch to vgabios code that - make some optimizations - fix a overflow computing frame buffer size - make Windows 8 suport greater resolutions - fix some informations returned from interrupt Frediano Ziglio (7): vgabios: Output to Qemu debug port instead of using Bochs one vgabios: Does not define cur_mode if not required vgabios: Fix size computation overflow vgabios: Report mode not supported getting mode informations vgabios: Reduce stack usage getting mode informations vgabios: Check if mode is currently supported as vesa specifications vgabios: Make Windows 8 support greater resolutions tools/firmware/vgabios/vbe.c | 69 +++++++++++++++++++++++++++++--------- tools/firmware/vgabios/vgabios.c | 6 ++-- 2 files changed, 56 insertions(+), 19 deletions(-) -- 1.7.5.4
Frediano Ziglio
2012-May-04 12:36 UTC
[PATCH 1/7] vgabios: Output to Qemu debug port instead of using Bochs one
Bios was outputing into port 0xe9 while Qemu use 0x12 Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vgabios.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/firmware/vgabios/vgabios.c b/tools/firmware/vgabios/vgabios.c index a9dbe00..e0b1ed9 100644 --- a/tools/firmware/vgabios/vgabios.c +++ b/tools/firmware/vgabios/vgabios.c @@ -3811,9 +3811,9 @@ void printf(s) for (i=0; i<format_width; i++) { nibble = (arg >> (4 * digit)) & 0x000f; if (nibble <= 9) - outb(0xe9, nibble + ''0''); + outb(0x12, nibble + ''0''); else - outb(0xe9, (nibble - 10) + ''A''); + outb(0x12, (nibble - 10) + ''A''); digit--; } in_format = 0; @@ -3823,7 +3823,7 @@ void printf(s) // } } else { - outb(0xe9, c); + outb(0x12, c); } s ++; } -- 1.7.5.4
Frediano Ziglio
2012-May-04 12:36 UTC
[PATCH 2/7] vgabios: Does not define cur_mode if not required
Declare and use cur_mode only if debug is enabled Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vbe.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c index 3fc786d..3d42216 100644 --- a/tools/firmware/vgabios/vbe.c +++ b/tools/firmware/vgabios/vbe.c @@ -761,7 +761,9 @@ Bit16u *AX;Bit16u ES;Bit16u DI; Bit16u status; Bit16u result; Bit16u vbe2_info; +#ifdef DEBUG Bit16u cur_mode=0; +#endif Bit16u cur_ptr=34; ModeInfoListItem *cur_info=&mode_info_list; @@ -849,9 +851,9 @@ Bit16u *AX;Bit16u ES;Bit16u DI; (cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel <= vbe_info_block.TotalMemory << 19 )) { #ifdef DEBUG printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); + cur_mode++; #endif write_word(ES, DI + cur_ptr, cur_info->mode); - cur_mode++; cur_ptr+=2; } else { #ifdef DEBUG -- 1.7.5.4
Remove an overflow computing width x height x bit which does not fit into a 16 bits. I wrote a routine to multiple these value and get the size required for framebuffer in segment unit (64k). Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vbe.c | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-) diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c index 3d42216..35d9866 100644 --- a/tools/firmware/vgabios/vbe.c +++ b/tools/firmware/vgabios/vbe.c @@ -742,6 +742,29 @@ no_vbe_flag: jmp _display_string 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: @@ -846,9 +869,12 @@ Bit16u *AX;Bit16u ES;Bit16u DI; do { + Bit16u size_64k = size64(cur_info->info.XResolution, cur_info->info.YResolution, cur_info->info.BitsPerPixel); + Bit16u max_bpp = dispi_get_max_bpp(); + if ((cur_info->info.XResolution <= dispi_get_max_xres()) && - (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && - (cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel <= vbe_info_block.TotalMemory << 19 )) { + (cur_info->info.BitsPerPixel <= max_bpp) && + (size_64k <= vbe_info_block.TotalMemory)) { #ifdef DEBUG printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); cur_mode++; -- 1.7.5.4
Frediano Ziglio
2012-May-04 12:36 UTC
[PATCH 4/7] vgabios: Report mode not supported getting mode informations
If you try to get mode information for an unsupported mode interrupt should return error but not that the function is not supported. Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vbe.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c index 35d9866..fff314e 100644 --- a/tools/firmware/vgabios/vbe.c +++ b/tools/firmware/vgabios/vbe.c @@ -911,7 +911,8 @@ Bit16u *AX;Bit16u ES;Bit16u DI; void vbe_biosfn_return_mode_information(AX, CX, ES, DI) Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; { - Bit16u result=0x0100; + // error by default is 0x014f which means supported but error + Bit16u result=0x014f; Bit16u ss=get_SS(); ModeInfoBlock info; ModeInfoListItem *cur_info; @@ -955,7 +956,6 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; #ifdef DEBUG printf("VBE *NOT* found mode %x\n",CX); #endif - result = 0x100; } if (result == 0x4f) -- 1.7.5.4
Frediano Ziglio
2012-May-04 12:36 UTC
[PATCH 5/7] vgabios: Reduce stack usage getting mode informations
Informations are stored in a structure that is smaller than final one. Previous code copy this structure to stack extending with zeroes then update it and copy to caller while now the not-extended version is copied into stack and then is extended during copy reducing stack usage. Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vbe.c | 13 +++++-------- 1 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c index fff314e..0b8b736 100644 --- a/tools/firmware/vgabios/vbe.c +++ b/tools/firmware/vgabios/vbe.c @@ -914,9 +914,9 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; // error by default is 0x014f which means supported but error Bit16u result=0x014f; Bit16u ss=get_SS(); - ModeInfoBlock info; ModeInfoListItem *cur_info; Boolean using_lfb; + ModeInfoBlockCompact info; #ifdef DEBUG printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX); @@ -933,7 +933,6 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; #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; @@ -950,6 +949,10 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; info.PhysBasePtr |= inw(VBE_DISPI_IOPORT_DATA); #endif result = 0x4f; + + // copy updates in mode_info_block back + memsetb(ES, DI, 0, sizeof(ModeInfoBlock)); + memcpyb(ES, DI, ss, &info, sizeof(info)); } else { @@ -957,12 +960,6 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; printf("VBE *NOT* found mode %x\n",CX); #endif } - - if (result == 0x4f) - { - // copy updates in mode_info_block back - memcpyb(ES, DI, ss, &info, sizeof(info)); - } write_word(ss, AX, result); } -- 1.7.5.4
Frediano Ziglio
2012-May-04 12:36 UTC
[PATCH 6/7] vgabios: Check if mode is currently supported as vesa specifications
Vesa specification require that mode information return if a given mode is supported or not so test if we can support it checking required memory and set correctly supported bit. Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vbe.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c index 0b8b736..a7b06b9 100644 --- a/tools/firmware/vgabios/vbe.c +++ b/tools/firmware/vgabios/vbe.c @@ -930,10 +930,22 @@ 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 memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); + 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; + if (using_lfb) { info.NumberOfBanks = 1; } -- 1.7.5.4
Frediano Ziglio
2012-May-04 12:36 UTC
[PATCH 7/7] vgabios: Make Windows 8 support greater resolutions
Apparently Windows 8 refuse to use any mode if has more than one page. Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> --- tools/firmware/vgabios/vbe.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c index a7b06b9..9131721 100644 --- a/tools/firmware/vgabios/vbe.c +++ b/tools/firmware/vgabios/vbe.c @@ -946,9 +946,9 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; (size_64k > totalMemory)) info.ModeAttributes &= ~VBE_MODE_ATTRIBUTE_SUPPORTED; - if (using_lfb) { - info.NumberOfBanks = 1; - } + /* Windows 8 require this to be 1! */ + info.NumberOfBanks = 1; + if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) { info.WinFuncPtr = 0xC0000000UL; *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall); -- 1.7.5.4
Ian Campbell
2012-May-04 14:04 UTC
Re: [PATCH 1/7] vgabios: Output to Qemu debug port instead of using Bochs one
On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote:> Bios was outputing into port 0xe9 while Qemu use 0x120xe9 is also the Xen HVM debug port (see hvm_print_line), don''t be confused by the fact that it happens to be the same as the bochs port. Ian.> Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> > --- > tools/firmware/vgabios/vgabios.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/tools/firmware/vgabios/vgabios.c b/tools/firmware/vgabios/vgabios.c > index a9dbe00..e0b1ed9 100644 > --- a/tools/firmware/vgabios/vgabios.c > +++ b/tools/firmware/vgabios/vgabios.c > @@ -3811,9 +3811,9 @@ void printf(s) > for (i=0; i<format_width; i++) { > nibble = (arg >> (4 * digit)) & 0x000f; > if (nibble <= 9) > - outb(0xe9, nibble + ''0''); > + outb(0x12, nibble + ''0''); > else > - outb(0xe9, (nibble - 10) + ''A''); > + outb(0x12, (nibble - 10) + ''A''); > digit--; > } > in_format = 0; > @@ -3823,7 +3823,7 @@ void printf(s) > // } > } > else { > - outb(0xe9, c); > + outb(0x12, c); > } > s ++; > }
On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote:> Remove an overflow computing width x height x bit which does > not fit into a 16 bits. I wrote a routine to multiple these value > and get the size required for framebuffer in segment unit (64k).Couldn''t this be done in C using a suitably wide temporary variable?> > Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> > --- > tools/firmware/vgabios/vbe.c | 30 ++++++++++++++++++++++++++++-- > 1 files changed, 28 insertions(+), 2 deletions(-) > > diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c > index 3d42216..35d9866 100644 > --- a/tools/firmware/vgabios/vbe.c > +++ b/tools/firmware/vgabios/vbe.c > @@ -742,6 +742,29 @@ no_vbe_flag: > jmp _display_string > 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: > @@ -846,9 +869,12 @@ Bit16u *AX;Bit16u ES;Bit16u DI; > > do > { > + Bit16u size_64k = size64(cur_info->info.XResolution, cur_info->info.YResolution, cur_info->info.BitsPerPixel); > + Bit16u max_bpp = dispi_get_max_bpp(); > + > if ((cur_info->info.XResolution <= dispi_get_max_xres()) && > - (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && > - (cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel <= vbe_info_block.TotalMemory << 19 )) { > + (cur_info->info.BitsPerPixel <= max_bpp) && > + (size_64k <= vbe_info_block.TotalMemory)) { > #ifdef DEBUG > printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); > cur_mode++;
Frediano Ziglio
2012-May-04 14:18 UTC
Re: [PATCH 3/7] vgabios: Fix size computation overflow
On Fri, 2012-05-04 at 15:12 +0100, Ian Campbell wrote:> On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote: > > Remove an overflow computing width x height x bit which does > > not fit into a 16 bits. I wrote a routine to multiple these value > > and get the size required for framebuffer in segment unit (64k). > > Couldn''t this be done in C using a suitably wide temporary variable? >I''d like :( BCC compiler used need some function which are not linked by BIOS. Personally I would switch to something more clever like OpenWatcom but mainly I wrote some small asm. I think bochs code fix the issue providing a asm function used by compiler but seems more hacky than my function. Frediano> > > > Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> > > --- > > tools/firmware/vgabios/vbe.c | 30 ++++++++++++++++++++++++++++-- > > 1 files changed, 28 insertions(+), 2 deletions(-) > > > > diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c > > index 3d42216..35d9866 100644 > > --- a/tools/firmware/vgabios/vbe.c > > +++ b/tools/firmware/vgabios/vbe.c > > @@ -742,6 +742,29 @@ no_vbe_flag: > > jmp _display_string > > 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: > > @@ -846,9 +869,12 @@ Bit16u *AX;Bit16u ES;Bit16u DI; > > > > do > > { > > + Bit16u size_64k = size64(cur_info->info.XResolution, cur_info->info.YResolution, cur_info->info.BitsPerPixel); > > + Bit16u max_bpp = dispi_get_max_bpp(); > > + > > if ((cur_info->info.XResolution <= dispi_get_max_xres()) && > > - (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && > > - (cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel <= vbe_info_block.TotalMemory << 19 )) { > > + (cur_info->info.BitsPerPixel <= max_bpp) && > > + (size_64k <= vbe_info_block.TotalMemory)) { > > #ifdef DEBUG > > printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); > > cur_mode++; > >
Ian Campbell
2012-May-04 14:18 UTC
Re: [PATCH 4/7] vgabios: Report mode not supported getting mode informations
On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote:> If you try to get mode information for an unsupported mode > interrupt should return error but not that the function is not > supported. > > Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> > --- > tools/firmware/vgabios/vbe.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c > index 35d9866..fff314e 100644 > --- a/tools/firmware/vgabios/vbe.c > +++ b/tools/firmware/vgabios/vbe.c > @@ -911,7 +911,8 @@ Bit16u *AX;Bit16u ES;Bit16u DI; > void vbe_biosfn_return_mode_information(AX, CX, ES, DI) > Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; > { > - Bit16u result=0x0100; > + // error by default is 0x014f which means supported but error > + Bit16u result=0x014f;Something odd has happened to the whitepace here. Otherwise: Acked-by: Ian Campbell <ian.campbell@citrix.com>> Bit16u ss=get_SS(); > ModeInfoBlock info; > ModeInfoListItem *cur_info; > @@ -955,7 +956,6 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; > #ifdef DEBUG > printf("VBE *NOT* found mode %x\n",CX); > #endif > - result = 0x100; > } > > if (result == 0x4f)
Ian Campbell
2012-May-04 14:19 UTC
Re: [PATCH 7/7] vgabios: Make Windows 8 support greater resolutions
On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote:> Apparently Windows 8 refuse to use any mode if has more than one page.What about OSes other than Windows 8? Did you test with any of them?> > Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> > --- > tools/firmware/vgabios/vbe.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/tools/firmware/vgabios/vbe.c b/tools/firmware/vgabios/vbe.c > index a7b06b9..9131721 100644 > --- a/tools/firmware/vgabios/vbe.c > +++ b/tools/firmware/vgabios/vbe.c > @@ -946,9 +946,9 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; > (size_64k > totalMemory)) > info.ModeAttributes &= ~VBE_MODE_ATTRIBUTE_SUPPORTED; > > - if (using_lfb) { > - info.NumberOfBanks = 1; > - } > + /* Windows 8 require this to be 1! */ > + info.NumberOfBanks = 1; > + > if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) { > info.WinFuncPtr = 0xC0000000UL; > *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall);
On Fri, 2012-05-04 at 15:18 +0100, Frediano Ziglio wrote:> On Fri, 2012-05-04 at 15:12 +0100, Ian Campbell wrote: > > On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote: > > > Remove an overflow computing width x height x bit which does > > > not fit into a 16 bits. I wrote a routine to multiple these value > > > and get the size required for framebuffer in segment unit (64k). > > > > Couldn''t this be done in C using a suitably wide temporary variable? > > > > I''d like :( > > BCC compiler used need some function which are not linked by BIOS.In which case Acked-by: Ian Campbell <ian.campbell@citrix.com>
Frediano Ziglio
2012-May-04 14:45 UTC
Re: [PATCH 3/7] vgabios: Fix size computation overflow
On Fri, 2012-05-04 at 15:26 +0100, Ian Campbell wrote:> On Fri, 2012-05-04 at 15:18 +0100, Frediano Ziglio wrote: > > On Fri, 2012-05-04 at 15:12 +0100, Ian Campbell wrote: > > > On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote: > > > > Remove an overflow computing width x height x bit which does > > > > not fit into a 16 bits. I wrote a routine to multiple these value > > > > and get the size required for framebuffer in segment unit (64k). > > > > > > Couldn''t this be done in C using a suitably wide temporary variable? > > > > > > > I''d like :( > > > > BCC compiler used need some function which are not linked by BIOS. > > In which case > > Acked-by: Ian Campbell <ian.campbell@citrix.com> > >In current vgabios (from Bochs not Xen copy) size is computed using size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; If you try to use this code you get an undefined call to lmulul. Bochs code (still in vbe.c) provide this internal function with this asm code: ; helper function for memory size calculation lmulul: and eax, #0x0000FFFF shl ebx, #16 or eax, ebx SEG SS mul eax, dword ptr [di] mov ebx, eax shr ebx, #16 ret Note also that Bochs line have some problems - it multiply Xres by Xres intead of Xres by Yref - it does not take into account ceiling division Frediano
Frediano Ziglio
2012-May-04 14:47 UTC
Re: [PATCH 3/7] vgabios: Fix size computation overflow
On Fri, 2012-05-04 at 15:26 +0100, Ian Campbell wrote:> On Fri, 2012-05-04 at 15:18 +0100, Frediano Ziglio wrote: > > On Fri, 2012-05-04 at 15:12 +0100, Ian Campbell wrote: > > > On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote: > > > > Remove an overflow computing width x height x bit which does > > > > not fit into a 16 bits. I wrote a routine to multiple these value > > > > and get the size required for framebuffer in segment unit (64k). > > > > > > Couldn''t this be done in C using a suitably wide temporary variable? > > > > > > > I''d like :( > > > > BCC compiler used need some function which are not linked by BIOS. > > In which case > > Acked-by: Ian Campbell <ian.campbell@citrix.com> > >In current vgabios (from Bochs not Xen copy) size is computed using size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; If you try to use this code you get an undefined call to lmulul. Bochs code (still in vbe.c) provide this internal function with this asm code: ; helper function for memory size calculation lmulul: and eax, #0x0000FFFF shl ebx, #16 or eax, ebx SEG SS mul eax, dword ptr [di] mov ebx, eax shr ebx, #16 ret Note also that Bochs line have some problems - it multiply Xres by Xres intead of Xres by Yref - it does not take into account ceiling division Frediano
Frediano Ziglio
2012-May-04 14:48 UTC
Re: [PATCH 3/7] vgabios: Fix size computation overflow
On Fri, 2012-05-04 at 15:26 +0100, Ian Campbell wrote:> On Fri, 2012-05-04 at 15:18 +0100, Frediano Ziglio wrote: > > On Fri, 2012-05-04 at 15:12 +0100, Ian Campbell wrote: > > > On Fri, 2012-05-04 at 13:36 +0100, Frediano Ziglio wrote: > > > > Remove an overflow computing width x height x bit which does > > > > not fit into a 16 bits. I wrote a routine to multiple these value > > > > and get the size required for framebuffer in segment unit (64k). > > > > > > Couldn''t this be done in C using a suitably wide temporary variable? > > > > > > > I''d like :( > > > > BCC compiler used need some function which are not linked by BIOS. > > In which case > > Acked-by: Ian Campbell <ian.campbell@citrix.com> > >In current vgabios (from Bochs not Xen copy) size is computed using size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; If you try to use this code you get an undefined call to lmulul. Bochs code (still in vbe.c) provide this internal function with this asm code: ; helper function for memory size calculation lmulul: and eax, #0x0000FFFF shl ebx, #16 or eax, ebx SEG SS mul eax, dword ptr [di] mov ebx, eax shr ebx, #16 ret Note also that Bochs line have some problems - it multiply Xres by Xres intead of Xres by Yref - it does not take into account ceiling division Frediano