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.
This commit is contained in:
parent
9e01a83636
commit
c9bfb13cdb
9 changed files with 33 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue