Index: /trunk/src/emx/testcase/cpuid.c
===================================================================
--- /trunk/src/emx/testcase/cpuid.c	(revision 2291)
+++ /trunk/src/emx/testcase/cpuid.c	(revision 2292)
@@ -26,44 +26,153 @@
 
 #include <stdio.h>
+#include <stdint.h>
 
-#define BIT(n) (1 << n)
+/**
+ * Checks if the current CPU supports CPUID.
+ *
+ * @returns 1 if CPUID is supported, 0 if it doesn't.
+ */
+static inline int HasCpuId(void)
+{
+    int         fRet = 0;
+    uint32_t    u1;
+    uint32_t    u2;
+    __asm__ ("pushf\n\t"
+             "pop   %1\n\t"
+             "mov   %1, %2\n\t"
+             "xorl  $0x200000, %1\n\t"
+             "push  %1\n\t"
+             "popf\n\t"
+             "pushf\n\t"
+             "pop   %1\n\t"
+             "cmpl  %1, %2\n\t"
+             "setne %0\n\t"
+             "push  %2\n\t"
+             "popf\n\t"
+             : "=m" (fRet), "=r" (u1), "=r" (u2));
+    return fRet;
+}
+
+
+#define BIT(n)  (1 << n)
+#define CPUID(n) do {   __asm__ __volatile__ ("cpuid" : "=a" (eax), "=d" (edx), "=c" (ecx), "=b" (ebx) : "0" (n)); \
+                        printf("%#010x: edx=%08x ecx=%08x eax=%08x ebx=%08x\n", (n), edx, ecx, eax, ebx); } while (0)
+#define CPUIDSZ(n, psz) \
+    do {   __asm__ __volatile__ ("cpuid" : "=a" (eax), "=d" (edx), "=c" (ecx), "=b" (ebx) : "0" (n)); \
+            ((uint32_t *)(psz))[0] = eax; ((uint32_t *)(psz))[1] = ebx; \
+            ((uint32_t *)(psz))[2] = ecx; ((uint32_t *)(psz))[3] = edx; } while (0)
 int main()
 {
-    unsigned  eax, edx, ecx, ebx;
-    __asm__ ("cpuid" : "=a" (eax), "=d" (edx), "=c" (ecx), "=b" (ebx) : "0" (1));
-    printf("1: edx=%#x ecx=%#x eax=%#x ebx=%#x\n", edx, ecx, eax, ebx);
-    if (edx & BIT(0))   printf("FPU ");
-    if (edx & BIT(1))   printf("VME ");
-    if (edx & BIT(2))   printf("DE ");
-    if (edx & BIT(3))   printf("PSE ");
-    if (edx & BIT(4))   printf("TSC ");
-    if (edx & BIT(5))   printf("MSR ");
-    if (edx & BIT(6))   printf("PAE ");
-    if (edx & BIT(7))   printf("MCE ");
-    if (edx & BIT(8))   printf("CX8 ");
-    if (edx & BIT(9))   printf("APIC ");
-    if (edx & BIT(10))  printf("10 ");
-    if (edx & BIT(11))  printf("SEP ");
-    if (edx & BIT(12))  printf("MTRR ");
-    if (edx & BIT(13))  printf("PGE ");
-    if (edx & BIT(14))  printf("MCA ");
-    if (edx & BIT(15))  printf("CMOV ");
-    if (edx & BIT(16))  printf("PAT ");
-    if (edx & BIT(17))  printf("PSE36 ");
-    if (edx & BIT(18))  printf("PSN ");
-    if (edx & BIT(19))  printf("CLFSH ");
-    if (edx & BIT(20))  printf("20 ");
-    if (edx & BIT(21))  printf("DS ");
-    if (edx & BIT(22))  printf("ACPI ");
-    if (edx & BIT(23))  printf("MMX ");
-    if (edx & BIT(24))  printf("FXSR ");
-    if (edx & BIT(25))  printf("SSE ");
-    if (edx & BIT(26))  printf("SSE2 ");
-    if (edx & BIT(27))  printf("SS ");
-    if (edx & BIT(28))  printf("28 ");
-    if (edx & BIT(29))  printf("29 ");
-    if (edx & BIT(30))  printf("30 ");
-    if (edx & BIT(31))  printf("31 ");
-    printf("\n");
+    enum {  MANU_AMD, MANU_INTEL, MANU_OTHER }
+                enmManufacturer = MANU_OTHER;
+    unsigned    c;
+    uint32_t    eax, edx, ecx, ebx;
+
+    if (!HasCpuId())
+    {
+        printf("This processor doesn't support the CPUID instruction!\n");
+        return 0;
+    }
+
+    CPUID(0);
+    c = eax;
+    printf("Name:           %.4s%.4s%.4s\n"
+           "Supports:       0-%u\n", &ebx, &edx, &ecx, eax);
+    if (edx == 0x69746e65 && ecx == 0x444d4163 && ebx == 0x68747541)
+        enmManufacturer = MANU_AMD;
+    else if (edx == 0x6c65746e && ecx == 0x49656e69 && ebx == 0x756e6547)
+        enmManufacturer = MANU_INTEL;
+
+    if (c >= 1)
+    {
+        CPUID(1);
+        printf("Family:         %d\n"
+               "Model:          %d\n"
+               "Stepping:       %d\n", 
+               (eax >> 8) & 7, (eax >> 4) & 7, eax & 7);
+        printf("Features:      ");
+        if (edx & BIT(0))   printf(" FPU");
+        if (edx & BIT(1))   printf(" VME");
+        if (edx & BIT(2))   printf(" DE");
+        if (edx & BIT(3))   printf(" PSE");
+        if (edx & BIT(4))   printf(" TSC");
+        if (edx & BIT(5))   printf(" MSR");
+        if (edx & BIT(6))   printf(" PAE");
+        if (edx & BIT(7))   printf(" MCE");
+        if (edx & BIT(8))   printf(" CX8");
+        if (edx & BIT(9))   printf(" APIC");
+        if (edx & BIT(10))  printf(" 10");
+        if (edx & BIT(11))  printf(" SEP");
+        if (edx & BIT(12))  printf(" MTRR");
+        if (edx & BIT(13))  printf(" PGE");
+        if (edx & BIT(14))  printf(" MCA");
+        if (edx & BIT(15))  printf(" CMOV");
+        if (edx & BIT(16))  printf(" PAT");
+        if (edx & BIT(17))  printf(" PSE36");
+        if (edx & BIT(18))  printf(" PSN");
+        if (edx & BIT(19))  printf(" CLFSH");
+        if (edx & BIT(20))  printf(" 20");
+        if (edx & BIT(21))  printf(" DS");
+        if (edx & BIT(22))  printf(" ACPI");
+        if (edx & BIT(23))  printf(" MMX");
+        if (edx & BIT(24))  printf(" FXSR");
+        if (edx & BIT(25))  printf(" SSE");
+        if (edx & BIT(26))  printf(" SSE2");
+        if (edx & BIT(27))  printf(" SS");
+        if (edx & BIT(28))  printf(" 28");
+        if (edx & BIT(29))  printf(" 29");
+        if (edx & BIT(30))  printf(" 30");
+        if (edx & BIT(31))  printf(" 31");
+        printf("\n");
+    }
+
+    //CPUID(2);
+
+    /*
+     * AMD
+     */
+    if (enmManufacturer == MANU_AMD)
+    {
+        CPUID(0x80000000);
+        c = eax;
+        printf("AMD Name:       %.4s%.4s%.4s\n"
+               "AMD Supports:   0x80000000-%#010x\n", &ebx, &edx, &ecx, eax);
+
+        if (c >= 0x80000001)
+        {
+            CPUID(0x80000001);
+            printf("AMD Family:     %d\n"
+                   "AMD Model:      %d\n"
+                   "AMD Stepping:   %d\n", 
+                   (eax >> 8) & 7, (eax >> 4) & 7, eax & 7);
+        }
+
+        char szString[4*4*3+1] = {0};
+        if (c >= 0x80000002)
+            CPUIDSZ(0x80000002, &szString[0]);
+        if (c >= 0x80000003)
+            CPUIDSZ(0x80000003, &szString[16]);
+        if (c >= 0x80000004)
+            CPUIDSZ(0x80000004, &szString[32]);
+        if (c >= 0x80000002)
+            printf("AMD Model:      %s\n", szString);
+
+        if (c >= 0x80000005)
+        {
+            CPUID(0x80000005);
+        }
+        if (c >= 0x80000006)
+        {
+            CPUID(0x80000006);
+        }
+        if (c >= 0x80000007)
+        {
+            CPUID(0x80000007);
+        }
+        if (c >= 0x80000008)
+        {
+            CPUID(0x80000008);
+        }
+    }
 
     return 0;
