From c9bfb13cdb2e57a71554715052afd30a74fd5fce Mon Sep 17 00:00:00 2001 From: Tomas Hruby Date: Tue, 26 Oct 2010 21:07:27 +0000 Subject: [PATCH] Kernel keeps information about each cpu - kernel maintains a cpu_info array which contains various information about each cpu as filled when each cpu boots - the information contains idetification, features etc. --- include/minix/type.h | 5 +++-- kernel/arch/i386/apic.c | 1 + kernel/arch/i386/arch_clock.c | 1 + kernel/arch/i386/arch_smp.c | 2 ++ kernel/arch/i386/arch_system.c | 29 ++++++++++++++--------------- kernel/arch/i386/arch_watchdog.c | 13 +++++++------ kernel/glo.h | 2 ++ kernel/main.c | 2 ++ kernel/proto.h | 1 + 9 files changed, 33 insertions(+), 23 deletions(-) diff --git a/include/minix/type.h b/include/minix/type.h index 5cf9bcef9..e66936d70 100644 --- a/include/minix/type.h +++ b/include/minix/type.h @@ -120,11 +120,13 @@ struct loadinfo { clock_t last_clock; }; -struct cpu_type { +struct cpu_info { u8_t vendor; u8_t family; u8_t model; u8_t stepping; + u32_t freq; /* in MHz */ + u32_t flags[2]; }; struct machine { @@ -138,7 +140,6 @@ 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/apic.c b/kernel/arch/i386/apic.c index bc8b8a3fe..4bd617bf2 100644 --- a/kernel/arch/i386/apic.c +++ b/kernel/arch/i386/apic.c @@ -496,6 +496,7 @@ PRIVATE void apic_calibrate_clocks(unsigned cpu) lapic_bus_freq[cpuid] / 1000000)); cpu_freq = mul64(div64u64(tsc_delta, PROBE_TICKS - 1), make64(system_hz, 0)); cpu_set_freq(cpuid, cpu_freq); + cpu_info[cpuid].freq = div64u(cpu_freq, 1000000); BOOT_VERBOSE(cpu_print_freq(cpuid)); } diff --git a/kernel/arch/i386/arch_clock.c b/kernel/arch/i386/arch_clock.c index cc6ec35ec..2f6ff1eef 100644 --- a/kernel/arch/i386/arch_clock.c +++ b/kernel/arch/i386/arch_clock.c @@ -115,6 +115,7 @@ PRIVATE void estimate_cpu_freq(void) cpu_freq = mul64(div64u64(tsc_delta, PROBE_TICKS - 1), make64(system_hz, 0)); cpu_set_freq(cpuid, cpu_freq); + cpu_info[cpuid].freq = div64u(cpu_freq, 1000000); BOOT_VERBOSE(cpu_print_freq(cpuid)); } diff --git a/kernel/arch/i386/arch_smp.c b/kernel/arch/i386/arch_smp.c index 936ed3fe3..d9c2977aa 100644 --- a/kernel/arch/i386/arch_smp.c +++ b/kernel/arch/i386/arch_smp.c @@ -238,6 +238,8 @@ PRIVATE void ap_finish_booting(void) printf("CPU %d paging is on\n", cpu); + cpu_identify(); + lapic_enable(cpu); fpu_init(); diff --git a/kernel/arch/i386/arch_system.c b/kernel/arch/i386/arch_system.c index 14cf4e661..5b005c5c8 100644 --- a/kernel/arch/i386/arch_system.c +++ b/kernel/arch/i386/arch_system.c @@ -304,23 +304,22 @@ PUBLIC void restore_fpu(struct proc *pr) } } -PRIVATE void cpu_identify(void) +PUBLIC void cpu_identify(void) { u32_t eax, ebx, ecx, edx; + unsigned cpu = cpuid; 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"); + cpu_info[cpu].vendor = CPU_VENDOR_INTEL; } 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"); + cpu_info[cpu].vendor = CPU_VENDOR_AMD; } else - machine.cpu_type.vendor = CPU_VENDOR_UNKNOWN; + cpu_info[cpu].vendor = CPU_VENDOR_UNKNOWN; if (eax == 0) return; @@ -328,19 +327,19 @@ PRIVATE void cpu_identify(void) 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; + cpu_info[cpu].family = (eax >> 8) & 0xf; + if (cpu_info[cpu].family == 0xf) + cpu_info[cpu].family += (eax >> 20) & 0xff; + cpu_info[cpu].model = (eax >> 4) & 0xf; + if (cpu_info[cpu].model == 0xf || cpu_info[cpu].model == 0x6) + cpu_info[cpu].model += ((eax >> 16) & 0xf) << 4 ; + cpu_info[cpu].stepping = eax & 0xf; + cpu_info[cpu].flags[0] = ecx; + cpu_info[cpu].flags[1] = edx; } 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/arch_watchdog.c b/kernel/arch/i386/arch_watchdog.c index b91d5bd65..56861a11d 100644 --- a/kernel/arch/i386/arch_watchdog.c +++ b/kernel/arch/i386/arch_watchdog.c @@ -60,13 +60,14 @@ PRIVATE void intel_arch_watchdog_reinit(const unsigned cpu) PUBLIC int arch_watchdog_init(void) { u32_t eax, ebx, ecx, edx; + unsigned cpu = cpuid; if (!lapic_addr) { printf("ERROR : Cannot use NMI watchdog if APIC is not enabled\n"); return -1; } - if (machine.cpu_type.vendor == CPU_VENDOR_INTEL) { + if (cpu_info[cpu].vendor == CPU_VENDOR_INTEL) { eax = 0xA; _cpuid(&eax, &ebx, &ecx, &edx); @@ -81,11 +82,11 @@ PUBLIC int arch_watchdog_init(void) return -1; watchdog = &intel_arch_watchdog; - } else if (machine.cpu_type.vendor == CPU_VENDOR_AMD) { - if (machine.cpu_type.family != 6 && - machine.cpu_type.family != 15 && - machine.cpu_type.family != 16 && - machine.cpu_type.family != 17) + } else if (cpu_info[cpu].vendor == CPU_VENDOR_AMD) { + if (cpu_info[cpu].family != 6 && + cpu_info[cpu].family != 15 && + cpu_info[cpu].family != 16 && + cpu_info[cpu].family != 17) return -1; else watchdog = &amd_watchdog; diff --git a/kernel/glo.h b/kernel/glo.h index 7fb548d4d..d3d76babf 100644 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -79,6 +79,8 @@ extern struct segdesc_s gdt[]; /* global descriptor table */ EXTERN volatile int serial_debug_active; +EXTERN struct cpu_info cpu_info[CONFIG_MAX_CPUS]; + /* BKL stats */ EXTERN u64_t kernel_ticks[CONFIG_MAX_CPUS]; EXTERN u64_t bkl_ticks[CONFIG_MAX_CPUS]; diff --git a/kernel/main.c b/kernel/main.c index 1576502df..91a92566b 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -40,6 +40,8 @@ PUBLIC void bsp_finish_booting(void) #endif /* SPROFILE */ cprof_procs_no = 0; /* init nr of hash table slots used */ + cpu_identify(); + vm_running = 0; krandom.random_sources = RANDOM_SOURCES; krandom.random_elements = RANDOM_ELEMENTS; diff --git a/kernel/proto.h b/kernel/proto.h index b040c8a52..0a628ab04 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -184,6 +184,7 @@ _PROTOTYPE( vir_bytes alloc_remote_segment, (u32_t *, segframe_t *, _PROTOTYPE( int intr_init, (int, int) ); _PROTOTYPE( void halt_cpu, (void) ); _PROTOTYPE( void arch_init, (void) ); +_PROTOTYPE( void cpu_identify, (void) ); /* arch dependent FPU initialization per CPU */ _PROTOTYPE( void fpu_init, (void) ); /* returns true if pfu is present and initialized */ -- 2.44.0