|
@@ -143,6 +143,18 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {}
|
|
|
#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
|
|
|
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
|
|
|
|
|
|
+static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
|
|
|
+ unsigned int *ecx, unsigned int *edx)
|
|
|
+{
|
|
|
+ /* ecx is often an input as well as an output. */
|
|
|
+ __asm__("cpuid"
|
|
|
+ : "=a" (*eax),
|
|
|
+ "=b" (*ebx),
|
|
|
+ "=c" (*ecx),
|
|
|
+ "=d" (*edx)
|
|
|
+ : "0" (*eax), "2" (*ecx));
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Generic CPUID function
|
|
|
* clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
|
|
@@ -150,24 +162,18 @@ static inline void detect_ht(struct cpuinfo_x86 *c) {}
|
|
|
*/
|
|
|
static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
|
|
|
{
|
|
|
- __asm__("cpuid"
|
|
|
- : "=a" (*eax),
|
|
|
- "=b" (*ebx),
|
|
|
- "=c" (*ecx),
|
|
|
- "=d" (*edx)
|
|
|
- : "0" (op), "c"(0));
|
|
|
+ *eax = op;
|
|
|
+ *ecx = 0;
|
|
|
+ __cpuid(eax, ebx, ecx, edx);
|
|
|
}
|
|
|
|
|
|
/* Some CPUID calls want 'count' to be placed in ecx */
|
|
|
static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
|
|
|
- int *edx)
|
|
|
+ int *edx)
|
|
|
{
|
|
|
- __asm__("cpuid"
|
|
|
- : "=a" (*eax),
|
|
|
- "=b" (*ebx),
|
|
|
- "=c" (*ecx),
|
|
|
- "=d" (*edx)
|
|
|
- : "0" (op), "c" (count));
|
|
|
+ *eax = op;
|
|
|
+ *ecx = count;
|
|
|
+ __cpuid(eax, ebx, ecx, edx);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -175,42 +181,30 @@ static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
|
|
|
*/
|
|
|
static inline unsigned int cpuid_eax(unsigned int op)
|
|
|
{
|
|
|
- unsigned int eax;
|
|
|
+ unsigned int eax, ebx, ecx, edx;
|
|
|
|
|
|
- __asm__("cpuid"
|
|
|
- : "=a" (eax)
|
|
|
- : "0" (op)
|
|
|
- : "bx", "cx", "dx");
|
|
|
+ cpuid(op, &eax, &ebx, &ecx, &edx);
|
|
|
return eax;
|
|
|
}
|
|
|
static inline unsigned int cpuid_ebx(unsigned int op)
|
|
|
{
|
|
|
- unsigned int eax, ebx;
|
|
|
+ unsigned int eax, ebx, ecx, edx;
|
|
|
|
|
|
- __asm__("cpuid"
|
|
|
- : "=a" (eax), "=b" (ebx)
|
|
|
- : "0" (op)
|
|
|
- : "cx", "dx" );
|
|
|
+ cpuid(op, &eax, &ebx, &ecx, &edx);
|
|
|
return ebx;
|
|
|
}
|
|
|
static inline unsigned int cpuid_ecx(unsigned int op)
|
|
|
{
|
|
|
- unsigned int eax, ecx;
|
|
|
+ unsigned int eax, ebx, ecx, edx;
|
|
|
|
|
|
- __asm__("cpuid"
|
|
|
- : "=a" (eax), "=c" (ecx)
|
|
|
- : "0" (op)
|
|
|
- : "bx", "dx" );
|
|
|
+ cpuid(op, &eax, &ebx, &ecx, &edx);
|
|
|
return ecx;
|
|
|
}
|
|
|
static inline unsigned int cpuid_edx(unsigned int op)
|
|
|
{
|
|
|
- unsigned int eax, edx;
|
|
|
+ unsigned int eax, ebx, ecx, edx;
|
|
|
|
|
|
- __asm__("cpuid"
|
|
|
- : "=a" (eax), "=d" (edx)
|
|
|
- : "0" (op)
|
|
|
- : "bx", "cx");
|
|
|
+ cpuid(op, &eax, &ebx, &ecx, &edx);
|
|
|
return edx;
|
|
|
}
|
|
|
|