From a04256f55b783716ef5933fcff59014bd41db2a8 Mon Sep 17 00:00:00 2001 From: Wonkyu Kim Date: Tue, 27 Apr 2021 01:52:57 -0700 Subject: *x86: fix x2apic mode boot issue Fix booting issues on google/kahlee introduced by CB:51723. Update use inital apic id in smm_stub.S to support xapic mode error. Check more bits(LAPIC_BASE_MSR BIT10 and BIT11) for x2apic mode. TEST=Boot to OS and check apicid, debug log for CPUIDs cpuid_ebx(1), cpuid_ext(0xb, 0), cpuid_edx(0xb) etc Signed-off-by: Wonkyu Kim Change-Id: Ia28f60a077182c3753f6ba9fbdd141f951d39b37 Reviewed-on: https://review.coreboot.org/c/coreboot/+/52696 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Angel Pons --- src/cpu/x86/smm/smm_stub.S | 31 +++++++++++++++++-------------- src/include/cpu/x86/lapic.h | 6 +++--- src/include/cpu/x86/lapic_def.h | 2 ++ 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S index f479d6253652..28b7d5763562 100644 --- a/src/cpu/x86/smm/smm_stub.S +++ b/src/cpu/x86/smm/smm_stub.S @@ -98,28 +98,31 @@ smm_trampoline32: /* The CPU number is calculated by reading the initial APIC id. Since * the OS can maniuplate the APIC id use the non-changing cpuid result - * for APIC id (ax). A table is used to handle a discontiguous + * for APIC id (eax). A table is used to handle a discontiguous * APIC id space. */ apic_id: - mov $LAPIC_BASE_MSR, %ecx - rdmsr - andl $LAPIC_BASE_MSR_X2APIC_MODE, %eax - jz xapic + mov $LAPIC_BASE_MSR, %ecx + rdmsr + and $LAPIC_BASE_X2APIC_ENABLED, %eax + cmp $LAPIC_BASE_X2APIC_ENABLED, %eax + jne xapic x2apic: - mov $X2APIC_LAPIC_ID, %ecx - rdmsr - jmp apicid_end + mov $0xb, %eax + mov $0, %ecx + cpuid + mov %edx, %eax + jmp apicid_end xapic: - movl $(LOCAL_APIC_ADDR | LAPIC_ID), %esi - movl (%esi), %eax - shr $24, %eax + mov $1, %eax + cpuid + mov %ebx, %eax + shr $24, %eax apicid_end: - - mov $(apic_to_cpu_num), %ebx - xor %ecx, %ecx + mov $(apic_to_cpu_num), %ebx + xor %ecx, %ecx 1: cmp (%ebx, %ecx, 2), %ax diff --git a/src/include/cpu/x86/lapic.h b/src/include/cpu/x86/lapic.h index e2ca2976597c..717fc9aa3847 100644 --- a/src/include/cpu/x86/lapic.h +++ b/src/include/cpu/x86/lapic.h @@ -12,7 +12,7 @@ static inline bool is_x2apic_mode(void) { msr_t msr; msr = rdmsr(LAPIC_BASE_MSR); - return (msr.lo & LAPIC_BASE_MSR_X2APIC_MODE); + return ((msr.lo & LAPIC_BASE_X2APIC_ENABLED) == LAPIC_BASE_X2APIC_ENABLED); } static inline void x2apic_send_ipi(uint32_t icrlow, uint32_t apicid) @@ -79,8 +79,8 @@ static inline void disable_lapic(void) static __always_inline unsigned int initial_lapicid(void) { uint32_t lapicid; - if (is_x2apic_mode()) - lapicid = lapic_read(LAPIC_ID); + if (is_x2apic_mode() && cpuid_get_max_func() >= 0xb) + lapicid = cpuid_ext(0xb, 0).edx; else lapicid = cpuid_ebx(1) >> 24; return lapicid; diff --git a/src/include/cpu/x86/lapic_def.h b/src/include/cpu/x86/lapic_def.h index 5b25e5a9681c..d5e863a26ce3 100644 --- a/src/include/cpu/x86/lapic_def.h +++ b/src/include/cpu/x86/lapic_def.h @@ -5,6 +5,8 @@ #define LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR (1 << 8) #define LAPIC_BASE_MSR_X2APIC_MODE (1 << 10) #define LAPIC_BASE_MSR_ENABLE (1 << 11) +#define LAPIC_BASE_X2APIC_ENABLED \ + (LAPIC_BASE_MSR_X2APIC_MODE | LAPIC_BASE_MSR_ENABLE) #define LAPIC_BASE_MSR_ADDR_MASK 0xFFFFF000 #ifndef LOCAL_APIC_ADDR -- cgit v1.2.3