diff options
author | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2016-11-01 01:13:20 +0000 |
---|---|---|
committer | YASUOKA Masahiko <yasuoka@cvs.openbsd.org> | 2016-11-01 01:13:20 +0000 |
commit | 5ce25b2938db52f5d1e1d32970abe71e817f1c90 (patch) | |
tree | 9415e87f1790711bafbd37d968935aba8c2b355c /sys | |
parent | 216dea20ce4dc815066c5dd6585520661f6f30be (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')
-rw-r--r-- | sys/arch/amd64/amd64/lapic.c | 78 |
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(); } |