summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2006-02-20 18:29:19 +0000
committerPeter Jones <pjones@redhat.com>2006-02-20 18:29:19 +0000
commita59ee15e854b5c18dae58f102ba4b440081faf34 (patch)
tree86505de83b5e12328bde87e34cc425c8130d7b59
parentaaf7756f394fae7f4f20481e767c4c6ed7161564 (diff)
downloadanaconda-a59ee15e854b5c18dae58f102ba4b440081faf34.tar.gz
anaconda-a59ee15e854b5c18dae58f102ba4b440081faf34.tar.xz
anaconda-a59ee15e854b5c18dae58f102ba4b440081faf34.zip
- set ecx to 0 on all cpuid calls (fixes need for wierd eax-reading workaround)
- use common code for individual register cpuid calls - fix amd64 cores-per-package call to properly use ecx nod edx.
-rw-r--r--isys/smp.c100
1 files changed, 41 insertions, 59 deletions
diff --git a/isys/smp.c b/isys/smp.c
index 0090968be..19e6bd29a 100644
--- a/isys/smp.c
+++ b/isys/smp.c
@@ -556,76 +556,58 @@ static int intelDetectSMP(void)
#if defined(__i386__) || defined(__x86_64__)
#if defined(__x86_64__)
-u_int32_t recursive_cpuid_eax(u_int32_t op, int cycle)
+static inline void
+cpuid_count(u_int32_t *eax, u_int32_t *ebx, u_int32_t *ecx, u_int32_t *edx)
{
- 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");
- out0 = eax;
- if (cycle != 0) {
- out1 = recursive_cpuid_eax(saved_op, 0);
- return out1 > out0 ? out1 : out0;
- }
- return out0;
-}
-
-#define cpuid_eax(x) recursive_cpuid_eax(x, 1)
-
-u_int32_t cpuid_ebx(u_int32_t op)
-{
- u_int32_t eax, ebx;
__asm__("cpuid"
- : "=a" (eax), "=b" (ebx)
- : "0" (op)
- : "cx", "dx");
- return ebx;
+ : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "0" (*eax), "c" (*ecx));
}
-u_int32_t cpuid_edx(u_int32_t op)
+#elif defined(__i386__)
+static inline void
+cpuid_count(u_int32_t *eax, u_int32_t *ebx, u_int32_t *ecx, u_int32_t *edx)
{
- u_int32_t eax, edx;
- __asm__("cpuid"
- : "=a" (eax), "=d" (edx)
- : "0" (op)
- : "bx", "cx");
- return edx;
+ __asm__("pushl %%ebx ; cpuid ;"
+ "movl %%eax,%[eax] ; movl %%ebx,%[ebx] ;"
+ "movl %%ecx,%[ecx] ; movl %%edx,%[edx] ;"
+ "popl %%ebx"
+ : [eax] "=a" (*eax), [ebx] "=g" (*ebx),
+ [ecx] "=g" (*ecx), [edx] "=g" (*edx)
+ : "0" (*eax), "c" (*ecx));
}
-#elif defined(__i386__)
-static inline u_int32_t cpuid_eax(u_int32_t fn)
+#endif
+
+static inline u_int32_t
+cpuid_eax(u_int32_t op)
{
- u_int32_t eax, ebx;
- __asm__("pushl %%ebx; cpuid; movl %%eax,%[out]; popl %%ebx"
- : [out] "=a" (eax), "=g" (ebx)
- : "0" (fn)
- : "cx", "dx");
+ u_int32_t eax = op, ebx = 0, ecx = 0, edx = 0;
+ cpuid_count(&eax, &ebx, &ecx, &edx);
return eax;
}
-static inline u_int32_t cpuid_ebx(u_int32_t fn)
+
+static inline u_int32_t
+cpuid_ebx(u_int32_t op)
{
- u_int32_t eax, ebx;
- __asm__("pushl %%ebx; cpuid; movl %%ebx,%[out]; popl %%ebx"
- : "=a" (eax), [out] "=g" (ebx)
- : "0" (fn)
- : "cx", "dx");
+ u_int32_t eax = op, ebx = 0, ecx = 0, edx = 0;
+ cpuid_count(&eax, &ebx, &ecx, &edx);
return ebx;
}
-static inline u_int32_t cpuid_edx(u_int32_t fn)
+
+static inline u_int32_t
+cpuid_ecx(u_int32_t op)
{
- u_int32_t eax, ebx, edx;
- __asm__("pushl %%ebx; cpuid; movl %%edx,%[out]; popl %%ebx"
- : "=a" (eax), "=g" (ebx), [out] "=g" (edx)
- : "0" (fn)
- : "cx");
+ u_int32_t eax = op, ebx = 0, ecx = 0, edx = 0;
+ cpuid_count(&eax, &ebx, &ecx, &edx);
+ return ecx;
+}
+
+static inline u_int32_t
+cpuid_edx(u_int32_t op)
+{
+ u_int32_t eax = op, ebx = 0, ecx = 0, edx = 0;
+ cpuid_count(&eax, &ebx, &ecx, &edx);
return edx;
}
-#endif
typedef enum {
VENDOR_UNKNOWN,
@@ -688,10 +670,10 @@ int detectCoresPerPackage(void)
break;
}
case VENDOR_AMD: {
- u_int32_t edx = 0;
+ u_int32_t ecx = 0;
- edx = cpuid_edx(0x80000008);
- cores_per_package = (edx & 0xff) + 1;
+ ecx = cpuid_ecx(0x80000008);
+ cores_per_package = (ecx & 0xff) + 1;
break;
}
case VENDOR_OTHER: