[arch][x86][lapic] a little bit of restructuring of some recent lapic code
Functionally equivalent, but refactor two copies of local apic initialization code into a shared routine.
This commit is contained in:
@@ -178,6 +178,7 @@ main_lk:
|
|||||||
call setup_idt
|
call setup_idt
|
||||||
|
|
||||||
/* set up the percpu data structure pointer for the boot cpu */
|
/* set up the percpu data structure pointer for the boot cpu */
|
||||||
|
/* NOTE: assumes the local apic is 0, which is probably not a safe assumption. */
|
||||||
pushl $0
|
pushl $0
|
||||||
pushl $0
|
pushl $0
|
||||||
call x86_configure_percpu_early
|
call x86_configure_percpu_early
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ highaddr:
|
|||||||
call setup_idt
|
call setup_idt
|
||||||
|
|
||||||
/* set up the percpu data structure pointer for the boot cpu */
|
/* set up the percpu data structure pointer for the boot cpu */
|
||||||
|
/* NOTE: assumes the local apic is 0, which is probably not a safe assumption. */
|
||||||
xor %edi, %edi
|
xor %edi, %edi
|
||||||
xor %esi, %esi
|
xor %esi, %esi
|
||||||
call x86_configure_percpu_early
|
call x86_configure_percpu_early
|
||||||
|
|||||||
@@ -15,13 +15,18 @@
|
|||||||
|
|
||||||
// local apic
|
// local apic
|
||||||
void lapic_init(void);
|
void lapic_init(void);
|
||||||
uint32_t lapic_get_id_from_hardware(void);
|
|
||||||
status_t lapic_timer_init(bool invariant_tsc_supported);
|
status_t lapic_timer_init(bool invariant_tsc_supported);
|
||||||
void lapic_eoi(unsigned int vector);
|
void lapic_eoi(unsigned int vector);
|
||||||
void lapic_send_init_ipi(uint32_t apic_id, bool level);
|
void lapic_send_init_ipi(uint32_t apic_id, bool level);
|
||||||
void lapic_send_startup_ipi(uint32_t apic_id, uint32_t startup_vector);
|
void lapic_send_startup_ipi(uint32_t apic_id, uint32_t startup_vector);
|
||||||
void lapic_send_ipi(uint32_t apic_id, mp_ipi_t ipi);
|
void lapic_send_ipi(uint32_t apic_id, mp_ipi_t ipi);
|
||||||
|
|
||||||
|
// enable the local apic on the current cpu, panic if not present
|
||||||
|
void lapic_enable_on_local_cpu(void);
|
||||||
|
|
||||||
|
// read the apic id of the local apic on the current cpu, assumes lapic is present
|
||||||
|
uint32_t lapic_get_apic_id(void);
|
||||||
|
|
||||||
status_t lapic_set_oneshot_timer(platform_timer_callback callback, void *arg, lk_time_t interval);
|
status_t lapic_set_oneshot_timer(platform_timer_callback callback, void *arg, lk_time_t interval);
|
||||||
void lapic_cancel_timer(void);
|
void lapic_cancel_timer(void);
|
||||||
|
|
||||||
|
|||||||
@@ -267,13 +267,10 @@ static void lapic_init_postvm(uint level) {
|
|||||||
LK_INIT_HOOK(lapic_init_postvm, lapic_init_postvm, LK_INIT_LEVEL_VM + 1);
|
LK_INIT_HOOK(lapic_init_postvm, lapic_init_postvm, LK_INIT_LEVEL_VM + 1);
|
||||||
|
|
||||||
static void lapic_init_percpu(uint level) {
|
static void lapic_init_percpu(uint level) {
|
||||||
// Make sure the apic is enabled and x2apic mode is set (if supported)
|
// If we're on a secondary cpu we should have a local apic detected and present
|
||||||
uint64_t apic_base = read_msr(X86_MSR_IA32_APIC_BASE);
|
DEBUG_ASSERT(lapic_present);
|
||||||
apic_base |= (1u<<11);
|
|
||||||
if (lapic_x2apic) {
|
lapic_enable_on_local_cpu();
|
||||||
apic_base |= (1u<<10);
|
|
||||||
}
|
|
||||||
write_msr(X86_MSR_IA32_APIC_BASE, apic_base);
|
|
||||||
|
|
||||||
// set the spurious vector register
|
// set the spurious vector register
|
||||||
uint32_t svr = (LAPIC_INT_SPURIOUS | (1u<<8)); // enable
|
uint32_t svr = (LAPIC_INT_SPURIOUS | (1u<<8)); // enable
|
||||||
@@ -287,9 +284,21 @@ static void lapic_init_percpu(uint level) {
|
|||||||
}
|
}
|
||||||
LK_INIT_HOOK_FLAGS(lapic_init_percpu, lapic_init_percpu, LK_INIT_LEVEL_VM, LK_INIT_FLAG_SECONDARY_CPUS);
|
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) {
|
void lapic_enable_on_local_cpu(void) {
|
||||||
|
DEBUG_ASSERT(lapic_present);
|
||||||
|
|
||||||
|
// Make sure the apic is enabled and x2apic mode is set (if supported)
|
||||||
|
uint64_t apic_base = read_msr(X86_MSR_IA32_APIC_BASE);
|
||||||
|
apic_base |= (1u<<11);
|
||||||
|
if (lapic_x2apic) {
|
||||||
|
apic_base |= (1u<<10);
|
||||||
|
}
|
||||||
|
write_msr(X86_MSR_IA32_APIC_BASE, apic_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lapic_get_apic_id(void) {
|
||||||
if (!lapic_present) {
|
if (!lapic_present) {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lapic_x2apic) {
|
if (lapic_x2apic) {
|
||||||
|
|||||||
@@ -87,35 +87,13 @@ status_t arch_mp_send_ipi(mp_cpu_mask_t target, mp_ipi_t ipi) {
|
|||||||
|
|
||||||
void arch_mp_init_percpu(void) {}
|
void arch_mp_init_percpu(void) {}
|
||||||
|
|
||||||
/*
|
|
||||||
* Move to lapic.c
|
|
||||||
*
|
|
||||||
uint32_t x86_get_apic_id_from_hardware(void) {
|
|
||||||
uint32_t unused = 0, ecx = 0;
|
|
||||||
cpuid(0x1, &unused, &unused, &ecx, &unused);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
apic_id >>= 24;
|
|
||||||
return apic_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void x86_secondary_entry(uint cpu_num) {
|
void x86_secondary_entry(uint cpu_num) {
|
||||||
if (x86_feature_test(X86_FEATURE_X2APIC)) {
|
// Read the local apic id from the local apic.
|
||||||
uint64_t apic_base = read_msr(X86_MSR_IA32_APIC_BASE);
|
// NOTE: assumes a local apic is present but since this is a secondary cpu,
|
||||||
apic_base |= (1u << 10);
|
// it should be a safe assumption.
|
||||||
write_msr(X86_MSR_IA32_APIC_BASE, apic_base);
|
lapic_enable_on_local_cpu();
|
||||||
}
|
uint32_t apic_id = lapic_get_apic_id();
|
||||||
|
|
||||||
uint32_t apic_id = lapic_get_id_from_hardware();
|
|
||||||
x86_configure_percpu_early(cpu_num, apic_id);
|
x86_configure_percpu_early(cpu_num, apic_id);
|
||||||
|
|
||||||
x86_early_init_percpu();
|
x86_early_init_percpu();
|
||||||
|
|||||||
Reference in New Issue
Block a user