summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2012-01-09 22:00:30 -0800
committerStefan Reinauer <stefan.reinauer@coreboot.org>2012-03-30 17:47:02 +0200
commit689e31d18b0fdefdef2d3b2947355e07b496ce77 (patch)
tree26700bd43ee6b79ad5d5c9436959bbdfd82ce3d9
parent5d3438de41368acc89d80af7b8d235d0d1b19b60 (diff)
downloadcoreboot-689e31d18b0fdefdef2d3b2947355e07b496ce77.tar.xz
Make cpuid functions usable when compiled with PIC
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>
-rw-r--r--src/arch/x86/include/arch/cpu.h57
1 files changed, 45 insertions, 12 deletions
diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h
index 2dfcd72e95..891e62bbcb 100644
--- a/src/arch/x86/include/arch/cpu.h
+++ b/src/arch/x86/include/arch/cpu.h
@@ -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;
}