*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:
parent
206dfbf173
commit
a04256f55b
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user