]> Zhao Yanbai Git Server - minix.git/commitdiff
Kernel keeps information about each cpu
authorTomas Hruby <tom@minix3.org>
Tue, 26 Oct 2010 21:07:27 +0000 (21:07 +0000)
committerTomas Hruby <tom@minix3.org>
Tue, 26 Oct 2010 21:07:27 +0000 (21:07 +0000)
- 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
kernel/arch/i386/apic.c
kernel/arch/i386/arch_clock.c
kernel/arch/i386/arch_smp.c
kernel/arch/i386/arch_system.c
kernel/arch/i386/arch_watchdog.c
kernel/glo.h
kernel/main.c
kernel/proto.h

index 5cf9bcef91f0d5902841c9250d5fcc21c09203c3..e66936d705f6899d756ef9d8ad7ef051db4b7a94 100644 (file)
@@ -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
index bc8b8a3fe45c3932b1cc28971e3bf2b2fc6b298f..4bd617bf289b13517b0ede2b1aaa5cf566a41977 100644 (file)
@@ -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));
 }
 
index cc6ec35ecb277eb4cc8238c442e746ee36e59f1f..2f6ff1eef5dc45e905d9967f4decb4ac4ce53a52 100644 (file)
@@ -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));
 }
 
index 936ed3fe3d048ebb34afb66f639b7e19e7888c8a..d9c2977aae52bdedac47d2c4466b15b63ce211dd 100644 (file)
@@ -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();
 
index 14cf4e6614857ca1a206f8d77a5e6a0648ddeda0..5b005c5c80366b808b16ee7699ce0155ebcbd151 100644 (file)
@@ -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
index b91d5bd6542b682d8cb24f920907c2c164d7e535..56861a11d45739ccb6b86934a7794fecdd856ae2 100644 (file)
@@ -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;
index 7fb548d4d9d76e83ca2c473cd89611b73e91d104..d3d76babf2ce1131b859c1304d45b5dd92d9c452 100644 (file)
@@ -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];
index 1576502dfb92954690ed5b3e071e6a688c11722b..91a92566bf76d4d654e399bdccd1cf9f61902295 100644 (file)
@@ -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;
index b040c8a52f9b7ba2034f140c4c060e4b12e267d6..0a628ab049771f7ac5c4faa1752185581e842ac4 100644 (file)
@@ -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 */