[arch][x86] Read full 32bit apic id from x2apic msr if available (#465)
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
// local apic
|
||||
void lapic_init(void);
|
||||
uint32_t lapic_get_id_from_hardware(void);
|
||||
status_t lapic_timer_init(bool invariant_tsc_supported);
|
||||
void lapic_eoi(unsigned int vector);
|
||||
void lapic_send_init_ipi(uint32_t apic_id, bool level);
|
||||
|
||||
@@ -285,9 +285,20 @@ static void lapic_init_percpu(uint level) {
|
||||
register_int_handler_msi(LAPIC_INT_GENERIC, &lapic_generic_handler, NULL, false);
|
||||
register_int_handler_msi(LAPIC_INT_RESCHEDULE, &lapic_reschedule_handler, NULL, false);
|
||||
}
|
||||
|
||||
LK_INIT_HOOK_FLAGS(lapic_init_percpu, lapic_init_percpu, LK_INIT_LEVEL_VM, LK_INIT_FLAG_SECONDARY_CPUS);
|
||||
|
||||
uint32_t lapic_get_id_from_hardware(void) {
|
||||
if (!lapic_present) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lapic_x2apic) {
|
||||
return (uint32_t)read_msr(0x802);
|
||||
} else {
|
||||
return lapic_read(LAPIC_ID) >> 24;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t lapic_read_current_tick(void) {
|
||||
if (!lapic_present) {
|
||||
return 0;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <arch/arch_ops.h>
|
||||
#include <sys/types.h>
|
||||
#include <arch/x86/lapic.h>
|
||||
#include <arch/x86/feature.h>
|
||||
|
||||
#define LOCAL_TRACE 0
|
||||
|
||||
@@ -86,20 +87,35 @@ status_t arch_mp_send_ipi(mp_cpu_mask_t target, mp_ipi_t ipi) {
|
||||
|
||||
void arch_mp_init_percpu(void) {}
|
||||
|
||||
/*
|
||||
* Move to lapic.c
|
||||
*
|
||||
uint32_t x86_get_apic_id_from_hardware(void) {
|
||||
// read the apic id out of cpuid leaf 1, which should be present if SMP is enabled.
|
||||
uint32_t apic_id, unused;
|
||||
cpuid(0x1, &unused, &apic_id, &unused, &unused);
|
||||
uint32_t unused = 0, ecx = 0;
|
||||
cpuid(0x1, &unused, &unused, &ecx, &unused);
|
||||
|
||||
apic_id >>= 24;
|
||||
if (ecx & (1u << 21)) {
|
||||
// read full 32bit apic id from x2apic msr if available
|
||||
return (uint32_t)read_msr(0x802);
|
||||
} else {
|
||||
// read the apic id out of cpuid leaf 1, which should be present if SMP is enabled.
|
||||
uint32_t apic_id;
|
||||
cpuid(0x1, &unused, &apic_id, &unused, &unused);
|
||||
|
||||
// TODO: read full 32bit apic id from x2apic msr if available
|
||||
|
||||
return apic_id;
|
||||
apic_id >>= 24;
|
||||
return apic_id;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void x86_secondary_entry(uint cpu_num) {
|
||||
uint32_t apic_id = x86_get_apic_id_from_hardware();
|
||||
if (x86_feature_test(X86_FEATURE_X2APIC)) {
|
||||
uint64_t apic_base = read_msr(X86_MSR_IA32_APIC_BASE);
|
||||
apic_base |= (1u << 10);
|
||||
write_msr(X86_MSR_IA32_APIC_BASE, apic_base);
|
||||
}
|
||||
|
||||
uint32_t apic_id = lapic_get_id_from_hardware();
|
||||
x86_configure_percpu_early(cpu_num, apic_id);
|
||||
|
||||
x86_early_init_percpu();
|
||||
|
||||
Reference in New Issue
Block a user