diff --git a/include/minix/type.h b/include/minix/type.h index 7e8c9ff16..5cf9bcef9 100644 --- a/include/minix/type.h +++ b/include/minix/type.h @@ -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 diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index fbc9b14e7..14cf4e661 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -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 diff --git a/kernel/arch/i386/include/archconst.h b/kernel/arch/i386/include/archconst.h index d66f19275..2019e9c68 100644 --- a/kernel/arch/i386/include/archconst.h +++ b/kernel/arch/i386/include/archconst.h @@ -153,6 +153,10 @@ #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