Make cpuid functions usable when compiled with PIC
authorDuncan Laurie <dlaurie@chromium.org>
Tue, 10 Jan 2012 06:00:30 +0000 (22:00 -0800)
committerStefan Reinauer <stefan.reinauer@coreboot.org>
Fri, 30 Mar 2012 15:47:02 +0000 (17:47 +0200)
This avoids using EBX and instead uses EDI where possible,
and ESI when necessary to get the EBX value out.

This allows me to enable -fpic for SMM TSEG code.

Also add a new CPUID extended function to query with ECX set.

Change-Id: I10dbded3f3ad98a39ba7b53da59af6ca3145e2e5
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Reviewed-on: http://review.coreboot.org/764
Tested-by: build bot (Jenkins)
Reviewed-by: Mathias Krause <minipli@googlemail.com>
src/arch/x86/include/arch/cpu.h

index 2dfcd72e95f0cc6cca27a7cb397ac4d280530ceb..891e62bbcb98e00ddef393c9f4c0e76bd8245378 100644 (file)
@@ -36,12 +36,36 @@ static inline struct cpuid_result cpuid(int op)
 {
        struct cpuid_result result;
        asm volatile(
-               "cpuid"
+               "mov %%ebx, %%edi;"
+               "cpuid;"
+               "mov %%ebx, %%esi;"
+               "mov %%edi, %%ebx;"
                : "=a" (result.eax),
-                 "=b" (result.ebx),
+                 "=S" (result.ebx),
                  "=c" (result.ecx),
                  "=d" (result.edx)
-               : "0" (op));
+               : "0" (op)
+               : "edi");
+       return result;
+}
+
+/*
+ * Generic Extended CPUID function
+ */
+static inline struct cpuid_result cpuid_ext(int op, unsigned ecx)
+{
+       struct cpuid_result result;
+       asm volatile(
+               "mov %%ebx, %%edi;"
+               "cpuid;"
+               "mov %%ebx, %%esi;"
+               "mov %%edi, %%ebx;"
+               : "=a" (result.eax),
+                 "=S" (result.ebx),
+                 "=c" (result.ecx),
+                 "=d" (result.edx)
+               : "0" (op), "2" (ecx)
+               : "edi");
        return result;
 }
 
@@ -52,10 +76,12 @@ static inline unsigned int cpuid_eax(unsigned int op)
 {
        unsigned int eax;
 
-       __asm__("cpuid"
+       __asm__("mov %%ebx, %%edi;"
+               "cpuid;"
+               "mov %%edi, %%ebx;"
                : "=a" (eax)
                : "0" (op)
-               : "ebx", "ecx", "edx");
+               : "ecx", "edx", "edi");
        return eax;
 }
 
@@ -63,10 +89,13 @@ static inline unsigned int cpuid_ebx(unsigned int op)
 {
        unsigned int eax, ebx;
 
-       __asm__("cpuid"
-               : "=a" (eax), "=b" (ebx)
+       __asm__("mov %%ebx, %%edi;"
+               "cpuid;"
+               "mov %%edi, %%ebx;"
+               "mov %%edi, %%esi;"
+               : "=a" (eax), "=S" (ebx)
                : "0" (op)
-               : "ecx", "edx" );
+               : "ecx", "edx", "edi");
        return ebx;
 }
 
@@ -74,10 +103,12 @@ static inline unsigned int cpuid_ecx(unsigned int op)
 {
        unsigned int eax, ecx;
 
-       __asm__("cpuid"
+       __asm__("mov %%ebx, %%edi;"
+               "cpuid;"
+               "mov %%edi, %%ebx;"
                : "=a" (eax), "=c" (ecx)
                : "0" (op)
-               : "ebx", "edx" );
+               : "edx", "edi");
        return ecx;
 }
 
@@ -85,10 +116,12 @@ static inline unsigned int cpuid_edx(unsigned int op)
 {
        unsigned int eax, edx;
 
-       __asm__("cpuid"
+       __asm__("mov %%ebx, %%edi;"
+               "cpuid;"
+               "mov %%edi, %%ebx;"
                : "=a" (eax), "=d" (edx)
                : "0" (op)
-               : "ebx", "ecx");
+               : "ecx", "edi");
        return edx;
 }