[arch][x86] Read full 32bit apic id from x2apic msr if available (#465)

This commit is contained in:
little fairy
2025-09-22 12:04:00 +08:00
committed by GitHub
parent a1be045514
commit d0eb5c464e
3 changed files with 37 additions and 9 deletions

View File

@@ -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);

View File

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

View File

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