[PATCH 7/8] ntdll: Add a get_cpuinfo() for each architecture

James Eder jimportal at gmail.com
Sat Oct 20 19:40:49 CDT 2012


This was split apart from the next patch in the series to make the diffs
readable. If it's preferred, I can have git squash them back together.  It
feels like a lot for a single commit but I'm at a loss to see a better way
due to the over lap of each OS more or less doing the same thing but
differently on x86.
---
 dlls/ntdll/nt.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index fe450c1..31bae2f 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -811,6 +811,14 @@ NTSTATUS WINAPI NtSetIntervalProfile(
 
 static  SYSTEM_CPU_INFORMATION cached_sci;
 
+/*******************************************************************************
+ * Architecture specific feature detection for CPUs
+ *
+ * This a set of mutually exclusive #if define()s each providing its own get_cpuinfo() to be called
+ * from fill_cpu_info();
+ */
+#if defined(__i386__) || defined(__x86_64__)
+
 #define AUTH	0x68747541	/* "Auth" */
 #define ENTI	0x69746e65	/* "enti" */
 #define CAMD	0x444d4163	/* "cAMD" */
@@ -911,6 +919,12 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
 {
     unsigned int regs[4], regs2[4];
 
+#if defined(__i386__)
+    info->Architecture = PROCESSOR_ARCHITECTURE_INTEL;
+#elif defined(__x86_64__)
+    info->Architecture = PROCESSOR_ARCHITECTURE_AMD64;
+#endif
+
     /* We're at least a 386 */
     info->FeatureSet = CPU_FEATURE_VME | CPU_FEATURE_X86 | CPU_FEATURE_PGE;
     info->Level = 3;
@@ -1000,6 +1014,102 @@ static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
     }
 }
 
+#elif defined(__powerpc__) || defined(__ppc__)
+
+static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
+{
+#ifdef __APPLE__
+    size_t valSize;
+    int value;
+
+    valSize = sizeof(value);
+    if (sysctlbyname("hw.optional.floatingpoint", &value, &valSize, NULL, 0) == 0)
+        user_shared_data->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = !value;
+
+    valSize = sizeof(value);
+    if (sysctlbyname("hw.cpusubtype", &value, &valSize, NULL, 0) == 0)
+    {
+        switch (value)
+        {
+            case CPU_SUBTYPE_POWERPC_601:
+            case CPU_SUBTYPE_POWERPC_602:       info->Level = 1;   break;
+            case CPU_SUBTYPE_POWERPC_603:       info->Level = 3;   break;
+            case CPU_SUBTYPE_POWERPC_603e:
+            case CPU_SUBTYPE_POWERPC_603ev:     info->Level = 6;   break;
+            case CPU_SUBTYPE_POWERPC_604:       info->Level = 4;   break;
+            case CPU_SUBTYPE_POWERPC_604e:      info->Level = 9;   break;
+            case CPU_SUBTYPE_POWERPC_620:       info->Level = 20;  break;
+            case CPU_SUBTYPE_POWERPC_750:       /* G3/G4 derive from 603 so ... */
+            case CPU_SUBTYPE_POWERPC_7400:
+            case CPU_SUBTYPE_POWERPC_7450:      info->Level = 6;   break;
+            case CPU_SUBTYPE_POWERPC_970:       info->Level = 9;
+                /* :o) user_shared_data->ProcessorFeatures[PF_ALTIVEC_INSTRUCTIONS_AVAILABLE] ;-) */
+                break;
+            default: break;
+        }
+    }
+#else
+    FIXME("CPU Feature detection not implemented.\n");
+#endif
+    info->Architecture = PROCESSOR_ARCHITECTURE_PPC;
+}
+
+#elif defined(__arm__)
+
+static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
+{
+#ifdef linux
+    char line[512];
+    char *s, *value;
+    FILE *f = fopen("/proc/cpuinfo", "r");
+    if (f)
+    {
+        while (fgets(line, sizeof(line), f) != NULL)
+        {
+            /* NOTE: the ':' is the only character we can rely on */
+            if (!(value = strchr(line,':')))
+                continue;
+            /* terminate the valuename */
+            s = value - 1;
+            while ((s >= line) && isspace(*s)) s--;
+            *(s + 1) = '\0';
+            /* and strip leading spaces from value */
+            value += 1;
+            while (isspace(*value)) value++;
+            if ((s = strchr(value,'\n')))
+                *s='\0';
+            if (!strcasecmp(line, "CPU architecture"))
+            {
+                if (isdigit(value[0]))
+                    info->Level = atoi(value);
+                continue;
+            }
+            if (!strcasecmp(line, "features"))
+            {
+                if (strstr(value, "vfpv3"))
+                    user_shared_data->ProcessorFeatures[PF_ARM_VFP_32_REGISTERS_AVAILABLE] = TRUE;
+                if (strstr(value, "neon"))
+                    user_shared_data->ProcessorFeatures[PF_ARM_NEON_INSTRUCTIONS_AVAILABLE] = TRUE;
+                continue;
+            }
+        }
+        fclose(f);
+    }
+#else
+    FIXME("CPU Feature detection not implemented.\n");
+#endif
+    info->Architecture = PROCESSOR_ARCHITECTURE_ARM;
+}
+
+#elif defined(__sparc__)
+
+static inline void get_cpuinfo(SYSTEM_CPU_INFORMATION* info)
+{
+    info->Architecture = PROCESSOR_ARCHITECTURE_SPARC;
+}
+
+#endif /* End architecture specific feature detection for CPUs */
+
 /******************************************************************
  *		fill_cpu_info
  *
-- 
1.7.12.4




More information about the wine-patches mailing list