arch/x86: Add X2APIC_LATE_WORKAROUND

Add option to do AP bringup with LAPICs in XAPIC mode and
switch to X2APIC later in CPU init.

Change-Id: I94c9daa3bc7173628f84094a3d5ca59e699ad334
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/65766
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2022-07-12 10:55:21 +00:00 committed by Felix Held
parent c7c746c3b2
commit 2125a17c6a
3 changed files with 25 additions and 7 deletions

View File

@ -51,6 +51,17 @@ config X2APIC_RUNTIME
bool bool
depends on PARALLEL_MP depends on PARALLEL_MP
config X2APIC_LATE_WORKAROUND
prompt "Use XAPIC for AP bringup, then change to X2APIC"
bool
depends on PARALLEL_MP && MAX_CPUS < 255
help
Choose this option if the platform supports dynamic switching between
XAPIC to X2APIC. The initial Application Processors (APs) are configured
in XAPIC mode at reset and later enable X2APIC as a CPU feature.
All access mechanisms between XAPIC (mmio) and X2APIC (msr) switches
at runtime when this option is enabled.
endchoice endchoice
config UDELAY_LAPIC config UDELAY_LAPIC

View File

@ -9,10 +9,10 @@
#include <smp/node.h> #include <smp/node.h>
#include <stdint.h> #include <stdint.h>
void enable_lapic(void) void enable_lapic_mode(bool try_set_x2apic)
{ {
uintptr_t apic_base; uintptr_t apic_base;
bool use_x2apic; bool use_x2apic = false;
msr_t msr; msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR); msr = rdmsr(LAPIC_BASE_MSR);
@ -30,12 +30,8 @@ void enable_lapic(void)
apic_base = msr.lo & LAPIC_BASE_MSR_ADDR_MASK; apic_base = msr.lo & LAPIC_BASE_MSR_ADDR_MASK;
ASSERT(apic_base == LAPIC_DEFAULT_BASE); ASSERT(apic_base == LAPIC_DEFAULT_BASE);
if (CONFIG(XAPIC_ONLY)) { if (try_set_x2apic)
use_x2apic = false;
} else {
use_x2apic = !!(cpu_get_feature_flags_ecx() & CPUID_X2APIC); use_x2apic = !!(cpu_get_feature_flags_ecx() & CPUID_X2APIC);
ASSERT(CONFIG(X2APIC_RUNTIME) || use_x2apic);
}
if (use_x2apic == !!(msr.lo & LAPIC_BASE_MSR_X2APIC_MODE)) { if (use_x2apic == !!(msr.lo & LAPIC_BASE_MSR_X2APIC_MODE)) {
printk(BIOS_INFO, "LAPIC 0x%x in %s mode.\n", lapicid(), printk(BIOS_INFO, "LAPIC 0x%x in %s mode.\n", lapicid(),
@ -52,6 +48,16 @@ void enable_lapic(void)
} }
void enable_lapic(void)
{
bool try_set_x2apic = true;
if (CONFIG(XAPIC_ONLY) || CONFIG(X2APIC_LATE_WORKAROUND))
try_set_x2apic = false;
enable_lapic_mode(try_set_x2apic);
}
void disable_lapic(void) void disable_lapic(void)
{ {
msr_t msr; msr_t msr;

View File

@ -176,6 +176,7 @@ void stop_this_cpu(void);
#endif #endif
void enable_lapic(void); void enable_lapic(void);
void enable_lapic_mode(bool try_set_x2apic);
void disable_lapic(void); void disable_lapic(void);
void setup_lapic_interrupts(void); void setup_lapic_interrupts(void);