summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2016-11-01 01:13:20 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2016-11-01 01:13:20 +0000
commit5ce25b2938db52f5d1e1d32970abe71e817f1c90 (patch)
tree9415e87f1790711bafbd37d968935aba8c2b355c /sys/arch/amd64
parent216dea20ce4dc815066c5dd6585520661f6f30be (diff)
Use x2APIC if it is enabled by BIOS. It is expected that this doesn't
change the behavior on the system whose x2apic is disabled by BIOS. ok sf
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/lapic.c78
1 files changed, 38 insertions, 40 deletions
diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c
index ad5ebb6f900..740347cf0bc 100644
--- a/sys/arch/amd64/amd64/lapic.c
+++ b/sys/arch/amd64/amd64/lapic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lapic.c,v 1.44 2016/06/22 01:12:38 mikeb Exp $ */
+/* $OpenBSD: lapic.c,v 1.45 2016/11/01 01:13:19 yasuoka Exp $ */
/* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */
/*-
@@ -170,59 +170,57 @@ lapic_map(paddr_t lapic_base)
int s;
pt_entry_t *pte;
vaddr_t va;
+ u_int64_t msr;
- /*
- * On real hardware, x2apic must only be enabled if interrupt remapping
- * is also enabled. See 10.12.7 of the SDM vol 3.
- * On hypervisors, this is not necessary. Hypervisors can implement
- * x2apic support even if the host CPU does not support it.
- * Until we support interrupt remapping, use x2apic only if the
- * hypervisor flag is also set.
- */
- if ((cpu_ecxfeature&CPUIDECX_X2APIC) && (cpu_ecxfeature&CPUIDECX_HV)) {
- u_int64_t msr;
-
- disable_intr();
- s = lapic_tpr;
-
- msr = rdmsr(MSR_APICBASE);
- msr |= APICBASE_ENABLE_X2APIC;
- wrmsr(MSR_APICBASE, msr);
+ disable_intr();
+ s = lapic_tpr;
+ msr = rdmsr(MSR_APICBASE);
+
+ if (ISSET(msr, APICBASE_ENABLE_X2APIC) ||
+ (ISSET(cpu_ecxfeature, CPUIDECX_HV) &&
+ ISSET(cpu_ecxfeature, CPUIDECX_X2APIC))) {
+ /*
+ * On real hardware, x2apic must only be enabled if interrupt
+ * remapping is also enabled. See 10.12.7 of the SDM vol 3.
+ * On hypervisors, this is not necessary. Hypervisors can
+ * implement x2apic support even if the host CPU does not
+ * support it. Until we support interrupt remapping, use
+ * x2apic only if the hypervisor flag is also set or it is
+ * enabled by BIOS.
+ */
+ if (!ISSET(msr, APICBASE_ENABLE_X2APIC)) {
+ msr |= APICBASE_ENABLE_X2APIC;
+ wrmsr(MSR_APICBASE, msr);
+ }
lapic_readreg = x2apic_readreg;
lapic_writereg = x2apic_writereg;
#ifdef MULTIPROCESSOR
x86_ipi = x2apic_ipi;
#endif
x2apic_enabled = 1;
-
codepatch_call(CPTAG_EOI, &x2apic_eoi);
lapic_writereg(LAPIC_TPRI, s);
- enable_intr();
+ } else {
+ /*
+ * Map local apic. If we have a local apic, it's safe to
+ * assume we're on a 486 or better and can use invlpg and
+ * non-cacheable PTE's
+ *
+ * Whap the PTE "by hand" rather than calling pmap_kenter_pa
+ * because the latter will attempt to invoke TLB shootdown
+ * code just as we might have changed the value of
+ * cpu_number()..
+ */
+ va = (vaddr_t)&local_apic;
+ pte = kvtopte(va);
+ *pte = lapic_base | PG_RW | PG_V | PG_N | PG_G | pg_nx;
+ invlpg(va);
- return;
+ lapic_tpr = s;
}
- va = (vaddr_t)&local_apic;
-
- disable_intr();
- s = lapic_tpr;
-
- /*
- * Map local apic. If we have a local apic, it's safe to assume
- * we're on a 486 or better and can use invlpg and non-cacheable PTE's
- *
- * Whap the PTE "by hand" rather than calling pmap_kenter_pa because
- * the latter will attempt to invoke TLB shootdown code just as we
- * might have changed the value of cpu_number()..
- */
-
- pte = kvtopte(va);
- *pte = lapic_base | PG_RW | PG_V | PG_N | PG_G | pg_nx;
- invlpg(va);
-
- lapic_tpr = s;
enable_intr();
}