summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/x86/smm/smm_stub.S31
-rw-r--r--src/include/cpu/x86/lapic.h6
-rw-r--r--src/include/cpu/x86/lapic_def.h2
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 f479d62536..28b7d57635 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 e2ca297659..717fc9aa38 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 5b25e5a968..d5e863a26c 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