diff options
author | Wonkyu Kim <wonkyu.kim@intel.com> | 2021-03-22 19:59:18 -0700 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2021-04-15 10:56:13 +0000 |
commit | 26ab9bfeb53a5d73ff4fdb01c8a15417a2f76876 (patch) | |
tree | 635f0ce598d308c13cb36845702240d1dcd0b47a /src/cpu/x86/mp_init.c | |
parent | 5c9bacca32c4554db0d2f04d371525c20488fac4 (diff) |
*x86: Support x2apic mode
Implement x2apic mode as existing code only supports apic mode.
Use info from LAPIC_BASE_MSR (LAPIC_BASE_MSR_X2APIC_MODE) to check
if apic mode or x2apic mode and implement x2apic mode according to
x2apic specfication.
Reference:
https://software.intel.com/content/www/us/en/develop/download/intel-64-architecture-x2apic-specification.html
BUG=None
BRANCH=None
TEST=boot to OS and check apic mode
cat /proc/cpuinfo | grep "apicid"
ex) can see apicid bigger than 255
apicid : 256
apicid : 260
Signed-off-by: Wonkyu Kim <wonkyu.kim@intel.com>
Change-Id: I0bb729b0521fb9dc38b7981014755daeaf9ca817
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51723
Reviewed-by: Ravishankar Sarawadi <ravishankar.sarawadi@intel.com>
Reviewed-by: Jamie Ryu <jamie.m.ryu@intel.com>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/cpu/x86/mp_init.c')
-rw-r--r-- | src/cpu/x86/mp_init.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 94a8fd8d8b..76f2650330 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -435,6 +435,28 @@ static int start_aps(struct bus *cpu_bus, int ap_count, atomic_t *num_aps) printk(BIOS_DEBUG, "Attempting to start %d APs\n", ap_count); + if (is_x2apic_mode()) { + x2apic_send_ipi(LAPIC_DM_INIT | LAPIC_INT_LEVELTRIG | + LAPIC_INT_ASSERT | LAPIC_DEST_ALLBUT, 0); + mdelay(10); + x2apic_send_ipi(LAPIC_DM_STARTUP | LAPIC_INT_LEVELTRIG | + LAPIC_DEST_ALLBUT | sipi_vector, 0); + + /* Wait for CPUs to check in up to 200 us. */ + wait_for_aps(num_aps, ap_count, 200 /* us */, 15 /* us */); + + x2apic_send_ipi(LAPIC_DM_STARTUP | LAPIC_INT_LEVELTRIG | + LAPIC_DEST_ALLBUT | sipi_vector, 0); + + /* Wait for CPUs to check in. */ + if (wait_for_aps(num_aps, ap_count, 100000 /* 100 ms */, 50 /* us */)) { + printk(BIOS_ERR, "Not all APs checked in: %d/%d.\n", + atomic_read(num_aps), ap_count); + return -1; + } + return 0; + } + if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) { printk(BIOS_DEBUG, "Waiting for ICR not to be busy..."); if (apic_wait_timeout(1000 /* 1 ms */, 50)) { @@ -653,6 +675,11 @@ static void mp_initialize_cpu(void) void smm_initiate_relocation_parallel(void) { + if (is_x2apic_mode()) { + x2apic_send_ipi(LAPIC_DM_SMI | LAPIC_INT_LEVELTRIG, lapicid()); + return; + } + if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) { printk(BIOS_DEBUG, "Waiting for ICR not to be busy..."); if (apic_wait_timeout(1000 /* 1 ms */, 50)) { |