[Xorg-driver-geode] [PATCH] X86EMU: handle CPUID instruction (passthrough)

Bart Trojanowski bart at symbio-technologies.com
Sat Feb 2 09:40:30 PST 2008


This bug is tracked here:
https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-amd/+bug/180742

After trying to switch from X to VT (or just quit) the video-amd driver
attempts to issue INT 10/0 to go to mode 3 (VGA).  The emulator, running
the BIOS code, would then spit out:

        c000:0282: A2 ILLEGAL EXTENDED X86 OPCODE!

The opcode was 0F A2, or CPUID; it was not implemented in the emulator.
This simple patch, against 1.3.0.0, handles the CPUID instruction by
getting the values from the real hardware (Geode LX in this case).

This fix allows the video-amd driver to switch back to console mode,
with the GSW BIOS.

Thanks to Symbio Technologies for funding my work, and ThinCan for
providing hardware :)

Signed-off-by: Bart Trojanowski <bart at jukie.net>
---
 hw/xfree86/x86emu/ops2.c |   33 ++++++++++++++++++++++++++++++++-
 1 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/hw/xfree86/x86emu/ops2.c b/hw/xfree86/x86emu/ops2.c
index 68e73ab..19190e7 100644
--- a/hw/xfree86/x86emu/ops2.c
+++ b/hw/xfree86/x86emu/ops2.c
@@ -333,6 +333,37 @@ static void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
 }
 
 /****************************************************************************
+REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
+Handles opcode 0x0f,0xa2
+****************************************************************************/
+static void x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("CPUID\n");
+    TRACE_AND_STEP();
+    // see this link for reference...
+    // http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
+#ifdef __PIC__
+    __asm__ __volatile__ ("pushl %%ebx      \n\t"
+		          "cpuid            \n\t"
+		          "movl %%ebx, %1   \n\t"
+		          "popl %%ebx       \n\t"
+                          : "=a" (M.x86.R_EAX), "=r" (M.x86.R_EBX),
+                            "=c" (M.x86.R_ECX), "=d" (M.x86.R_EDX)
+                          : "a" (M.x86.R_EAX), "c" (M.x86.R_ECX)
+                          : "cc");
+#else
+    __asm__ __volatile__ ("cpuid"
+                          : "=a" (M.x86.R_EAX), "=b" (M.x86.R_EBX),
+                            "=c" (M.x86.R_ECX), "=d" (M.x86.R_EDX)
+                          : "a" (M.x86.R_EAX), "c" (M.x86.R_ECX)
+                          : "cc");
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
 REMARKS:
 Handles opcode 0x0f,0xa3
 ****************************************************************************/
@@ -2739,7 +2770,7 @@ void (*x86emu_optab2[256])(u8) =
 
 /*  0xa0 */ x86emuOp2_push_FS,
 /*  0xa1 */ x86emuOp2_pop_FS,
-/*  0xa2 */ x86emuOp2_illegal_op,
+/*  0xa2 */ x86emuOp2_cpuid,
 /*  0xa3 */ x86emuOp2_bt_R,
 /*  0xa4 */ x86emuOp2_shld_IMM,
 /*  0xa5 */ x86emuOp2_shld_CL,
-- 
1.5.2.5



More information about the Xorg-driver-geode mailing list