[Xorg-driver-geode] [RFC PATCH] X86EMU: handle CPUID instruction
Bart Trojanowski
bart at symbio-technologies.com
Sat Feb 2 19:10:16 PST 2008
Please consider this patch as a work in progress.
I have updated the patch to handle the CPUID on a non x86 system. Thank
you to the CC'ed for setting me straight on that one.
Values returned by function 1 (EAX==1) for non x86 systems still needs a
bit of cleanup. Currently I am returning values from the GeodeLX, but I
would like to return the values from a 486DX2, which Martin Eric
(Q-FUNK) will get for me tomorrow.
Also, Stephane Marchesin (marcheu) suggested that I mask out the MTRR
support if I do go out to fetch the CPUID from the hardware.
If the above two changes are made, would this approach be accepted?
-Bart
Rest of the commit follows...
--
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 in one of
two ways:
1) if ran on __i386__ then it calls the CPUID instruction directly.
2) if ran elsewhere it returns a canned set of values for function 1.
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 | 62 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 61 insertions(+), 1 deletions(-)
diff --git a/hw/xfree86/x86emu/ops2.c b/hw/xfree86/x86emu/ops2.c
index 68e73ab..f91b3d7 100644
--- a/hw/xfree86/x86emu/ops2.c
+++ b/hw/xfree86/x86emu/ops2.c
@@ -333,6 +333,66 @@ 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();
+#ifdef __i386__
+ // 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
+#else // not __i386__
+ switch (M.x86.R_EAX) {
+ case 0:
+ M.x86.R_EAX = 1; // maximum function number we support
+ M.x86.R_EBX = 0x68747541;
+ M.x86.R_ECX = 0x444d4163;
+ M.x86.R_EDX = 0x69746e65;
+ break;
+ case 1:
+ M.x86.R_EAX = 0x000005a2; // copied from GeodeLX
+ M.x86.R_EBX = 0x00000400;
+ M.x86.R_ECX = 0x00000000;
+ M.x86.R_EDX = 0x0088a93d;
+ break;
+ case 0x80000000:
+ M.x86.R_EAX = 0; // don't support extended features
+ M.x86.R_EBX = 0;
+ M.x86.R_ECX = 0;
+ M.x86.R_EDX = 0;
+ break;
+ default:
+ DECODE_PRINTF("ILLEGAL CPUID FUNCTION\n");
+ TRACE_REGS();
+ printk("%04x:%04x: ILLEGAL CPUID FUNCTION!\n",
+ M.x86.R_CS, M.x86.R_IP-3, M.x86.R_EAX);
+ HALT_SYS();
+ }
+#endif
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
REMARKS:
Handles opcode 0x0f,0xa3
****************************************************************************/
@@ -2739,7 +2799,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.3.7.1150.g149d432
More information about the Xorg-driver-geode
mailing list