]> git.ipfire.org Git - thirdparty/ipxe.git/commit
[vesafb] Work around data corruption bug in bochs/qemu VBE implementation
authorMichael Brown <mcb30@ipxe.org>
Fri, 6 Dec 2013 02:37:36 +0000 (02:37 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 6 Dec 2013 02:54:13 +0000 (02:54 +0000)
commit54c5d08df14aa72e3494d4708041aee5f1a8861b
tree6d99a10e54c1e7567fe5fdabb07a9b736f1365ef
parent99c679696a3184ca9ab3f6a04b0bd633ae0055ad
[vesafb] Work around data corruption bug in bochs/qemu VBE implementation

The vgabios used by bochs and qemu (and other virtualisation products)
has a bug in its implementation of INT 10,4f00 which causes the high
16 bits of %ebx and %edx to become corrupted.

The vgabios code uses a "pushaw"/"popaw" pair to preserve the low 16
bits of all non-segment registers.  The vgabios code is compiled using
bcc, which generates 8086-compatible code and so never touches the
high 16 bits of the 32-bit registers.  However, the function
vbe_biosfn_return_controller_information() includes the line:

    size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution *
cur_info->info.XResolution *
cur_info->info.BitsPerPixel) >> 19;

which generates an implicit call to the "lmulul" function.  This
function is implemented in vbe.c as:

    ; 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

which modifies %eax, %ebx, and %edx (as a result of the "mul"
instruction, which places its result into %edx:%eax).

Work around this problem by marking %ebx and %edx as being clobbered
by the call to INT 10,4f00.  (%eax is already used as an output
register, so does not need to be on the clobber list.)

Reported-by: Oliver Rath <rath@mglug.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/interface/pcbios/vesafb.c