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:
Tomas Hruby 2010-10-26 21:07:27 +00:00
parent 9e01a83636
commit c9bfb13cdb
9 changed files with 33 additions and 23 deletions

View 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

View 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));
}

View 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));
}

View 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();

View 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

View 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;

View 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];

View 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;

View 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 */