summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2006-02-17 22:12:46 +0000
committerPeter Jones <pjones@redhat.com>2006-02-17 22:12:46 +0000
commit0fd2d39e599daadb1d0c83e76330311386993f1e (patch)
tree823b76e1ee1707d21d1407e9536570be94367c9f
parent11ea0628531de160667c4a250e6fd7fdb1ccc765 (diff)
downloadanaconda-0fd2d39e599daadb1d0c83e76330311386993f1e.tar.gz
anaconda-0fd2d39e599daadb1d0c83e76330311386993f1e.tar.xz
anaconda-0fd2d39e599daadb1d0c83e76330311386993f1e.zip
- make eax fn 4 probing on x86_64 work
-rw-r--r--isys/smp.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/isys/smp.c b/isys/smp.c
index cc0504140..0090968be 100644
--- a/isys/smp.c
+++ b/isys/smp.c
@@ -556,17 +556,29 @@ static int intelDetectSMP(void)
#if defined(__i386__) || defined(__x86_64__)
#if defined(__x86_64__)
-/* seems not to work */
-u_int32_t cpuid_eax(u_int32_t op)
+u_int32_t recursive_cpuid_eax(u_int32_t op, int cycle)
{
- u_int32_t eax=op, out;
- __asm__("cpuid; movl %%eax,%[out]"
- : [in] "=a" (eax), [out] "=g" (out)
+ u_int32_t saved_op=op, eax=op;
+ u_int32_t out0, out1;
+
+ /* just doing this once doesn't work on some SDP hardware. doing it twice
+ with a function call that has the output as an argument and manipulates
+ the variable in some way seems to do it... -- pj
+ */
+ __asm__("cpuid"
+ : "=a" (eax)
: "0" (op)
: "bx", "cx", "dx");
- return eax;
+ out0 = eax;
+ if (cycle != 0) {
+ out1 = recursive_cpuid_eax(saved_op, 0);
+ return out1 > out0 ? out1 : out0;
+ }
+ return out0;
}
-/* seems to work? */
+
+#define cpuid_eax(x) recursive_cpuid_eax(x, 1)
+
u_int32_t cpuid_ebx(u_int32_t op)
{
u_int32_t eax, ebx;
@@ -576,21 +588,16 @@ u_int32_t cpuid_ebx(u_int32_t op)
: "cx", "dx");
return ebx;
}
-/* seems not to work */
u_int32_t cpuid_edx(u_int32_t op)
{
- u_int32_t eax, edx, out;
- __asm__("cpuid; movl %%edx,%[out]"
- : "=a" (eax), "=d" (edx), [out] "=g" (out)
+ u_int32_t eax, edx;
+ __asm__("cpuid"
+ : "=a" (eax), "=d" (edx)
: "0" (op)
: "bx", "cx");
- printf("eax: %x\n", eax);
- printf("edx: %x\n", edx);
- printf("out: %x\n", out);
return edx;
}
#elif defined(__i386__)
-/* this one works */
static inline u_int32_t cpuid_eax(u_int32_t fn)
{
u_int32_t eax, ebx;
@@ -600,7 +607,6 @@ static inline u_int32_t cpuid_eax(u_int32_t fn)
: "cx", "dx");
return eax;
}
-/* this one works */
static inline u_int32_t cpuid_ebx(u_int32_t fn)
{
u_int32_t eax, ebx;
@@ -610,7 +616,6 @@ static inline u_int32_t cpuid_ebx(u_int32_t fn)
: "cx", "dx");
return ebx;
}
-/* no idea */
static inline u_int32_t cpuid_edx(u_int32_t fn)
{
u_int32_t eax, ebx, edx;