mirror of https://github.com/ipxe/ipxe.git
[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>pull/17/head
parent
99c679696a
commit
54c5d08df1
|
@ -171,7 +171,7 @@ static int vesafb_mode_list ( uint16_t **mode_numbers ) {
|
|||
: "=a" ( status )
|
||||
: "a" ( VBE_CONTROLLER_INFO ),
|
||||
"D" ( __from_data16 ( controller ) )
|
||||
: "memory" );
|
||||
: "memory", "ebx", "edx" );
|
||||
if ( ( rc = vesafb_rc ( status ) ) != 0 ) {
|
||||
DBGC ( &vbe_buf, "VESAFB could not get controller information: "
|
||||
"[%04x] %s\n", status, strerror ( rc ) );
|
||||
|
|
Loading…
Reference in New Issue