diff options
author | jhb <jhb@FreeBSD.org> | 2014-09-10 21:25:54 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2014-09-10 21:25:54 +0000 |
commit | 6f8d6cd57bddceacf4eae89310571ca78900e548 (patch) | |
tree | f3618d75880a1e32d2bb0e86dbd15e6d3ba17d2f /sys/i386 | |
parent | a3e07f1c6ab759432e67fc2c454166c54f5a825c (diff) | |
download | FreeBSD-src-6f8d6cd57bddceacf4eae89310571ca78900e548.zip FreeBSD-src-6f8d6cd57bddceacf4eae89310571ca78900e548.tar.gz |
To workaround an errata on certain Pentium Pro CPUs, i386 disables
the local APIC in initializecpu() and re-enables it if the APIC code
decides to use the local APIC after all. Rework this workaround
slightly so that initializecpu() won't re-disable the local APIC if
it is called after the APIC code re-enables the local APIC.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/initcpu.c | 28 | ||||
-rw-r--r-- | sys/i386/include/md_var.h | 1 |
2 files changed, 26 insertions, 3 deletions
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c index a2b9192..fa2c6e1 100644 --- a/sys/i386/i386/initcpu.c +++ b/sys/i386/i386/initcpu.c @@ -533,6 +533,8 @@ init_6x86MX(void) intr_restore(saveintr); } +static int ppro_apic_used = -1; + static void init_ppro(void) { @@ -541,9 +543,29 @@ init_ppro(void) /* * Local APIC should be disabled if it is not going to be used. */ - apicbase = rdmsr(MSR_APICBASE); - apicbase &= ~APICBASE_ENABLED; - wrmsr(MSR_APICBASE, apicbase); + if (ppro_apic_used != 1) { + apicbase = rdmsr(MSR_APICBASE); + apicbase &= ~APICBASE_ENABLED; + wrmsr(MSR_APICBASE, apicbase); + ppro_apic_used = 0; + } +} + +/* + * If the local APIC is going to be used after being disabled above, + * re-enable it and don't disable it in the future. + */ +void +ppro_reenable_apic(void) +{ + u_int64_t apicbase; + + if (ppro_apic_used == 0) { + apicbase = rdmsr(MSR_APICBASE); + apicbase |= APICBASE_ENABLED; + wrmsr(MSR_APICBASE, apicbase); + ppro_apic_used = 1; + } } /* diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index 89f8b51..8669815 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -109,6 +109,7 @@ int is_physical_memory(vm_paddr_t addr); int isa_nmi(int cd); vm_paddr_t kvtop(void *addr); void panicifcpuunsupported(void); +void ppro_reenable_apic(void); void printcpuinfo(void); void setidt(int idx, alias_for_inthand_t *func, int typ, int dpl, int selec); int user_dbreg_trap(void); |