*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 <wonkyu.kim@intel.com>
Change-Id: Ia28f60a077182c3753f6ba9fbdd141f951d39b37
Reviewed-on: https://review.coreboot.org/c/coreboot/+/52696
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Wonkyu Kim 2021-04-27 01:52:57 -07:00 committed by Patrick Georgi
parent 206dfbf173
commit a04256f55b
3 changed files with 22 additions and 17 deletions

View File

@ -98,28 +98,31 @@ smm_trampoline32:
/* The CPU number is calculated by reading the initial APIC id. Since /* 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 * 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 space. */
apic_id: apic_id:
mov $LAPIC_BASE_MSR, %ecx mov $LAPIC_BASE_MSR, %ecx
rdmsr rdmsr
andl $LAPIC_BASE_MSR_X2APIC_MODE, %eax and $LAPIC_BASE_X2APIC_ENABLED, %eax
jz xapic cmp $LAPIC_BASE_X2APIC_ENABLED, %eax
jne xapic
x2apic: x2apic:
mov $X2APIC_LAPIC_ID, %ecx mov $0xb, %eax
rdmsr mov $0, %ecx
jmp apicid_end cpuid
mov %edx, %eax
jmp apicid_end
xapic: xapic:
movl $(LOCAL_APIC_ADDR | LAPIC_ID), %esi mov $1, %eax
movl (%esi), %eax cpuid
shr $24, %eax mov %ebx, %eax
shr $24, %eax
apicid_end: apicid_end:
mov $(apic_to_cpu_num), %ebx
mov $(apic_to_cpu_num), %ebx xor %ecx, %ecx
xor %ecx, %ecx
1: 1:
cmp (%ebx, %ecx, 2), %ax cmp (%ebx, %ecx, 2), %ax

View File

@ -12,7 +12,7 @@ static inline bool is_x2apic_mode(void)
{ {
msr_t msr; msr_t msr;
msr = rdmsr(LAPIC_BASE_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) 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) static __always_inline unsigned int initial_lapicid(void)
{ {
uint32_t lapicid; uint32_t lapicid;
if (is_x2apic_mode()) if (is_x2apic_mode() && cpuid_get_max_func() >= 0xb)
lapicid = lapic_read(LAPIC_ID); lapicid = cpuid_ext(0xb, 0).edx;
else else
lapicid = cpuid_ebx(1) >> 24; lapicid = cpuid_ebx(1) >> 24;
return lapicid; return lapicid;

View File

@ -5,6 +5,8 @@
#define LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR (1 << 8) #define LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR (1 << 8)
#define LAPIC_BASE_MSR_X2APIC_MODE (1 << 10) #define LAPIC_BASE_MSR_X2APIC_MODE (1 << 10)
#define LAPIC_BASE_MSR_ENABLE (1 << 11) #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 #define LAPIC_BASE_MSR_ADDR_MASK 0xFFFFF000
#ifndef LOCAL_APIC_ADDR #ifndef LOCAL_APIC_ADDR