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>
This commit is contained in:
Duncan Laurie 2012-01-09 22:00:30 -08:00 committed by Stefan Reinauer
parent 5d3438de41
commit 689e31d18b
1 changed files with 45 additions and 12 deletions

View File

@ -36,12 +36,36 @@ static inline struct cpuid_result cpuid(int op)
{ {
struct cpuid_result result; struct cpuid_result result;
asm volatile( asm volatile(
"cpuid" "mov %%ebx, %%edi;"
"cpuid;"
"mov %%ebx, %%esi;"
"mov %%edi, %%ebx;"
: "=a" (result.eax), : "=a" (result.eax),
"=b" (result.ebx), "=S" (result.ebx),
"=c" (result.ecx), "=c" (result.ecx),
"=d" (result.edx) "=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; return result;
} }
@ -52,10 +76,12 @@ static inline unsigned int cpuid_eax(unsigned int op)
{ {
unsigned int eax; unsigned int eax;
__asm__("cpuid" __asm__("mov %%ebx, %%edi;"
"cpuid;"
"mov %%edi, %%ebx;"
: "=a" (eax) : "=a" (eax)
: "0" (op) : "0" (op)
: "ebx", "ecx", "edx"); : "ecx", "edx", "edi");
return eax; return eax;
} }
@ -63,10 +89,13 @@ static inline unsigned int cpuid_ebx(unsigned int op)
{ {
unsigned int eax, ebx; unsigned int eax, ebx;
__asm__("cpuid" __asm__("mov %%ebx, %%edi;"
: "=a" (eax), "=b" (ebx) "cpuid;"
"mov %%edi, %%ebx;"
"mov %%edi, %%esi;"
: "=a" (eax), "=S" (ebx)
: "0" (op) : "0" (op)
: "ecx", "edx" ); : "ecx", "edx", "edi");
return ebx; return ebx;
} }
@ -74,10 +103,12 @@ static inline unsigned int cpuid_ecx(unsigned int op)
{ {
unsigned int eax, ecx; unsigned int eax, ecx;
__asm__("cpuid" __asm__("mov %%ebx, %%edi;"
"cpuid;"
"mov %%edi, %%ebx;"
: "=a" (eax), "=c" (ecx) : "=a" (eax), "=c" (ecx)
: "0" (op) : "0" (op)
: "ebx", "edx" ); : "edx", "edi");
return ecx; return ecx;
} }
@ -85,10 +116,12 @@ static inline unsigned int cpuid_edx(unsigned int op)
{ {
unsigned int eax, edx; unsigned int eax, edx;
__asm__("cpuid" __asm__("mov %%ebx, %%edi;"
"cpuid;"
"mov %%edi, %%ebx;"
: "=a" (eax), "=d" (edx) : "=a" (eax), "=d" (edx)
: "0" (op) : "0" (op)
: "ebx", "ecx"); : "ecx", "edi");
return edx; return edx;
} }