]> Zhao Yanbai Git Server - minix.git/commitdiff
CPU type detection
authorTomas Hruby <tom@minix3.org>
Thu, 23 Sep 2010 14:42:19 +0000 (14:42 +0000)
committerTomas Hruby <tom@minix3.org>
Thu, 23 Sep 2010 14:42:19 +0000 (14:42 +0000)
- sometimes the system needs to know precisely on what type of cpu is
  running. The cpu type id detected during arch specific
  initialization and kept in the machine structure for later use.

- as a side-effect the information is exported to userland

include/minix/type.h
kernel/arch/i386/arch_system.c
kernel/arch/i386/include/archconst.h

index 7e8c9ff16b40d234eadce852a66839ef2f98113d..5cf9bcef91f0d5902841c9250d5fcc21c09203c3 100644 (file)
@@ -120,6 +120,13 @@ struct loadinfo {
   clock_t last_clock;
 };
 
+struct cpu_type {
+       u8_t    vendor;
+       u8_t    family;
+       u8_t    model;
+       u8_t    stepping;
+};
+
 struct machine {
   int pc_at;
   int ps_mca;
@@ -131,6 +138,7 @@ struct machine {
   int vdu_vga;
   int apic_enabled; /* does the kernel use APIC or not? */
   phys_bytes   acpi_rsdp; /* where is the acpi RSDP */
+  struct cpu_type      cpu_type;
 };
 
 struct io_range
index fbc9b14e787d09e371bd510ee61197f7dd95c445..14cf4e6614857ca1a206f8d77a5e6a0648ddeda0 100644 (file)
@@ -304,8 +304,43 @@ PUBLIC void restore_fpu(struct proc *pr)
        }
 }
 
+PRIVATE void cpu_identify(void)
+{
+       u32_t eax, ebx, ecx, edx;
+       
+       eax = 0;
+       _cpuid(&eax, &ebx, &ecx, &edx);
+
+       if (ebx == INTEL_CPUID_GEN_EBX && ecx == INTEL_CPUID_GEN_ECX &&
+                       edx == INTEL_CPUID_GEN_EDX) {
+               machine.cpu_type.vendor = CPU_VENDOR_INTEL;
+               printf("Genuine Intel found\n");
+       } else if (ebx == AMD_CPUID_GEN_EBX && ecx == AMD_CPUID_GEN_ECX &&
+                       edx == AMD_CPUID_GEN_EDX) {
+               machine.cpu_type.vendor = CPU_VENDOR_AMD;
+               printf("Authentic AMD found\n");
+       } else
+               machine.cpu_type.vendor = CPU_VENDOR_UNKNOWN;
+
+       if (eax == 0) 
+               return;
+
+       eax = 1;
+       _cpuid(&eax, &ebx, &ecx, &edx);
+
+       machine.cpu_type.family = (eax >> 8) & 0xf;
+       if (machine.cpu_type.family == 0xf)
+               machine.cpu_type.family += (eax >> 20) & 0xff;
+       machine.cpu_type.model = (eax >> 4) & 0xf;
+       if (machine.cpu_type.model == 0xf || machine.cpu_type.model == 0x6)
+               machine.cpu_type.model += ((eax >> 16) & 0xf) << 4 ;
+       machine.cpu_type.stepping = eax & 0xf;
+}
+
 PUBLIC void arch_init(void)
 {
+       cpu_identify();
+
 #ifdef CONFIG_APIC
        /*
         * this is setting kernel segments to cover most of the phys memory. The
index d66f19275524507b7945b07aac197ed99b69c2ff..2019e9c68070009a1b0ca1f05ec3dad7895d3262 100644 (file)
 #define AMD_CPUID_GEN_EDX      0x69746e65 /* ASCII value of "enti" */
 #define AMD_CPUID_GEN_ECX      0x444d4163 /* ASCII value of "cAMD" */
 
+#define CPU_VENDOR_INTEL       0
+#define CPU_VENDOR_AMD         2
+#define CPU_VENDOR_UNKNOWN     0xff
+
 /* fpu context should be saved in 16-byte aligned memory */
 #define FPUALIGN               16