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
@ -120,11 +120,13 @@ struct loadinfo {
|
|||||||
clock_t last_clock;
|
clock_t last_clock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cpu_type {
|
struct cpu_info {
|
||||||
u8_t vendor;
|
u8_t vendor;
|
||||||
u8_t family;
|
u8_t family;
|
||||||
u8_t model;
|
u8_t model;
|
||||||
u8_t stepping;
|
u8_t stepping;
|
||||||
|
u32_t freq; /* in MHz */
|
||||||
|
u32_t flags[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct machine {
|
struct machine {
|
||||||
@ -138,7 +140,6 @@ struct machine {
|
|||||||
int vdu_vga;
|
int vdu_vga;
|
||||||
int apic_enabled; /* does the kernel use APIC or not? */
|
int apic_enabled; /* does the kernel use APIC or not? */
|
||||||
phys_bytes acpi_rsdp; /* where is the acpi RSDP */
|
phys_bytes acpi_rsdp; /* where is the acpi RSDP */
|
||||||
struct cpu_type cpu_type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct io_range
|
struct io_range
|
||||||
|
@ -496,6 +496,7 @@ PRIVATE void apic_calibrate_clocks(unsigned cpu)
|
|||||||
lapic_bus_freq[cpuid] / 1000000));
|
lapic_bus_freq[cpuid] / 1000000));
|
||||||
cpu_freq = mul64(div64u64(tsc_delta, PROBE_TICKS - 1), make64(system_hz, 0));
|
cpu_freq = mul64(div64u64(tsc_delta, PROBE_TICKS - 1), make64(system_hz, 0));
|
||||||
cpu_set_freq(cpuid, cpu_freq);
|
cpu_set_freq(cpuid, cpu_freq);
|
||||||
|
cpu_info[cpuid].freq = div64u(cpu_freq, 1000000);
|
||||||
BOOT_VERBOSE(cpu_print_freq(cpuid));
|
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_freq = mul64(div64u64(tsc_delta, PROBE_TICKS - 1), make64(system_hz, 0));
|
||||||
cpu_set_freq(cpuid, cpu_freq);
|
cpu_set_freq(cpuid, cpu_freq);
|
||||||
|
cpu_info[cpuid].freq = div64u(cpu_freq, 1000000);
|
||||||
BOOT_VERBOSE(cpu_print_freq(cpuid));
|
BOOT_VERBOSE(cpu_print_freq(cpuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +238,8 @@ PRIVATE void ap_finish_booting(void)
|
|||||||
|
|
||||||
printf("CPU %d paging is on\n", cpu);
|
printf("CPU %d paging is on\n", cpu);
|
||||||
|
|
||||||
|
cpu_identify();
|
||||||
|
|
||||||
lapic_enable(cpu);
|
lapic_enable(cpu);
|
||||||
fpu_init();
|
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;
|
u32_t eax, ebx, ecx, edx;
|
||||||
|
unsigned cpu = cpuid;
|
||||||
|
|
||||||
eax = 0;
|
eax = 0;
|
||||||
_cpuid(&eax, &ebx, &ecx, &edx);
|
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
if (ebx == INTEL_CPUID_GEN_EBX && ecx == INTEL_CPUID_GEN_ECX &&
|
if (ebx == INTEL_CPUID_GEN_EBX && ecx == INTEL_CPUID_GEN_ECX &&
|
||||||
edx == INTEL_CPUID_GEN_EDX) {
|
edx == INTEL_CPUID_GEN_EDX) {
|
||||||
machine.cpu_type.vendor = CPU_VENDOR_INTEL;
|
cpu_info[cpu].vendor = CPU_VENDOR_INTEL;
|
||||||
printf("Genuine Intel found\n");
|
|
||||||
} else if (ebx == AMD_CPUID_GEN_EBX && ecx == AMD_CPUID_GEN_ECX &&
|
} else if (ebx == AMD_CPUID_GEN_EBX && ecx == AMD_CPUID_GEN_ECX &&
|
||||||
edx == AMD_CPUID_GEN_EDX) {
|
edx == AMD_CPUID_GEN_EDX) {
|
||||||
machine.cpu_type.vendor = CPU_VENDOR_AMD;
|
cpu_info[cpu].vendor = CPU_VENDOR_AMD;
|
||||||
printf("Authentic AMD found\n");
|
|
||||||
} else
|
} else
|
||||||
machine.cpu_type.vendor = CPU_VENDOR_UNKNOWN;
|
cpu_info[cpu].vendor = CPU_VENDOR_UNKNOWN;
|
||||||
|
|
||||||
if (eax == 0)
|
if (eax == 0)
|
||||||
return;
|
return;
|
||||||
@ -328,19 +327,19 @@ PRIVATE void cpu_identify(void)
|
|||||||
eax = 1;
|
eax = 1;
|
||||||
_cpuid(&eax, &ebx, &ecx, &edx);
|
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
machine.cpu_type.family = (eax >> 8) & 0xf;
|
cpu_info[cpu].family = (eax >> 8) & 0xf;
|
||||||
if (machine.cpu_type.family == 0xf)
|
if (cpu_info[cpu].family == 0xf)
|
||||||
machine.cpu_type.family += (eax >> 20) & 0xff;
|
cpu_info[cpu].family += (eax >> 20) & 0xff;
|
||||||
machine.cpu_type.model = (eax >> 4) & 0xf;
|
cpu_info[cpu].model = (eax >> 4) & 0xf;
|
||||||
if (machine.cpu_type.model == 0xf || machine.cpu_type.model == 0x6)
|
if (cpu_info[cpu].model == 0xf || cpu_info[cpu].model == 0x6)
|
||||||
machine.cpu_type.model += ((eax >> 16) & 0xf) << 4 ;
|
cpu_info[cpu].model += ((eax >> 16) & 0xf) << 4 ;
|
||||||
machine.cpu_type.stepping = eax & 0xf;
|
cpu_info[cpu].stepping = eax & 0xf;
|
||||||
|
cpu_info[cpu].flags[0] = ecx;
|
||||||
|
cpu_info[cpu].flags[1] = edx;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUBLIC void arch_init(void)
|
PUBLIC void arch_init(void)
|
||||||
{
|
{
|
||||||
cpu_identify();
|
|
||||||
|
|
||||||
#ifdef CONFIG_APIC
|
#ifdef CONFIG_APIC
|
||||||
/*
|
/*
|
||||||
* this is setting kernel segments to cover most of the phys memory. The
|
* 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)
|
PUBLIC int arch_watchdog_init(void)
|
||||||
{
|
{
|
||||||
u32_t eax, ebx, ecx, edx;
|
u32_t eax, ebx, ecx, edx;
|
||||||
|
unsigned cpu = cpuid;
|
||||||
|
|
||||||
if (!lapic_addr) {
|
if (!lapic_addr) {
|
||||||
printf("ERROR : Cannot use NMI watchdog if APIC is not enabled\n");
|
printf("ERROR : Cannot use NMI watchdog if APIC is not enabled\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (machine.cpu_type.vendor == CPU_VENDOR_INTEL) {
|
if (cpu_info[cpu].vendor == CPU_VENDOR_INTEL) {
|
||||||
eax = 0xA;
|
eax = 0xA;
|
||||||
|
|
||||||
_cpuid(&eax, &ebx, &ecx, &edx);
|
_cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
@ -81,11 +82,11 @@ PUBLIC int arch_watchdog_init(void)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
watchdog = &intel_arch_watchdog;
|
watchdog = &intel_arch_watchdog;
|
||||||
} else if (machine.cpu_type.vendor == CPU_VENDOR_AMD) {
|
} else if (cpu_info[cpu].vendor == CPU_VENDOR_AMD) {
|
||||||
if (machine.cpu_type.family != 6 &&
|
if (cpu_info[cpu].family != 6 &&
|
||||||
machine.cpu_type.family != 15 &&
|
cpu_info[cpu].family != 15 &&
|
||||||
machine.cpu_type.family != 16 &&
|
cpu_info[cpu].family != 16 &&
|
||||||
machine.cpu_type.family != 17)
|
cpu_info[cpu].family != 17)
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
watchdog = &amd_watchdog;
|
watchdog = &amd_watchdog;
|
||||||
|
@ -79,6 +79,8 @@ extern struct segdesc_s gdt[]; /* global descriptor table */
|
|||||||
|
|
||||||
EXTERN volatile int serial_debug_active;
|
EXTERN volatile int serial_debug_active;
|
||||||
|
|
||||||
|
EXTERN struct cpu_info cpu_info[CONFIG_MAX_CPUS];
|
||||||
|
|
||||||
/* BKL stats */
|
/* BKL stats */
|
||||||
EXTERN u64_t kernel_ticks[CONFIG_MAX_CPUS];
|
EXTERN u64_t kernel_ticks[CONFIG_MAX_CPUS];
|
||||||
EXTERN u64_t bkl_ticks[CONFIG_MAX_CPUS];
|
EXTERN u64_t bkl_ticks[CONFIG_MAX_CPUS];
|
||||||
|
@ -40,6 +40,8 @@ PUBLIC void bsp_finish_booting(void)
|
|||||||
#endif /* SPROFILE */
|
#endif /* SPROFILE */
|
||||||
cprof_procs_no = 0; /* init nr of hash table slots used */
|
cprof_procs_no = 0; /* init nr of hash table slots used */
|
||||||
|
|
||||||
|
cpu_identify();
|
||||||
|
|
||||||
vm_running = 0;
|
vm_running = 0;
|
||||||
krandom.random_sources = RANDOM_SOURCES;
|
krandom.random_sources = RANDOM_SOURCES;
|
||||||
krandom.random_elements = RANDOM_ELEMENTS;
|
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( int intr_init, (int, int) );
|
||||||
_PROTOTYPE( void halt_cpu, (void) );
|
_PROTOTYPE( void halt_cpu, (void) );
|
||||||
_PROTOTYPE( void arch_init, (void) );
|
_PROTOTYPE( void arch_init, (void) );
|
||||||
|
_PROTOTYPE( void cpu_identify, (void) );
|
||||||
/* arch dependent FPU initialization per CPU */
|
/* arch dependent FPU initialization per CPU */
|
||||||
_PROTOTYPE( void fpu_init, (void) );
|
_PROTOTYPE( void fpu_init, (void) );
|
||||||
/* returns true if pfu is present and initialized */
|
/* returns true if pfu is present and initialized */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user