summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubrata Banik <subratabanik@google.com>2022-07-12 10:55:21 +0000
committerFelix Held <felix-coreboot@felixheld.de>2022-07-18 15:40:46 +0000
commit2125a17c6a749651945a52ff39cbc8e81c3dcbd8 (patch)
tree5348508282dea5e7c337bb224c135c09bd95ffe1
parentc7c746c3b2cab52a80719bba39cbdc9ea4babb35 (diff)
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>
-rw-r--r--src/cpu/x86/Kconfig11
-rw-r--r--src/cpu/x86/lapic/lapic.c20
-rw-r--r--src/include/cpu/x86/lapic.h1
3 files changed, 25 insertions, 7 deletions
diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 5b9279511d..1617ad6953 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -51,6 +51,17 @@ config X2APIC_RUNTIME
bool
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
config UDELAY_LAPIC
diff --git a/src/cpu/x86/lapic/lapic.c b/src/cpu/x86/lapic/lapic.c
index 76f2d89db9..2d04fb3a80 100644
--- a/src/cpu/x86/lapic/lapic.c
+++ b/src/cpu/x86/lapic/lapic.c
@@ -9,10 +9,10 @@
#include <smp/node.h>
#include <stdint.h>
-void enable_lapic(void)
+void enable_lapic_mode(bool try_set_x2apic)
{
uintptr_t apic_base;
- bool use_x2apic;
+ bool use_x2apic = false;
msr_t msr;
msr = rdmsr(LAPIC_BASE_MSR);
@@ -30,12 +30,8 @@ void enable_lapic(void)
apic_base = msr.lo & LAPIC_BASE_MSR_ADDR_MASK;
ASSERT(apic_base == LAPIC_DEFAULT_BASE);
- if (CONFIG(XAPIC_ONLY)) {
- use_x2apic = false;
- } else {
+ if (try_set_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)) {
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)
{
msr_t msr;
diff --git a/src/include/cpu/x86/lapic.h b/src/include/cpu/x86/lapic.h
index c509e61b08..400199b029 100644
--- a/src/include/cpu/x86/lapic.h
+++ b/src/include/cpu/x86/lapic.h
@@ -176,6 +176,7 @@ void stop_this_cpu(void);
#endif
void enable_lapic(void);
+void enable_lapic_mode(bool try_set_x2apic);
void disable_lapic(void);
void setup_lapic_interrupts(void);