summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-09-10 21:25:54 +0000
committerjhb <jhb@FreeBSD.org>2014-09-10 21:25:54 +0000
commit6f8d6cd57bddceacf4eae89310571ca78900e548 (patch)
treef3618d75880a1e32d2bb0e86dbd15e6d3ba17d2f /sys/i386
parenta3e07f1c6ab759432e67fc2c454166c54f5a825c (diff)
downloadFreeBSD-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.c28
-rw-r--r--sys/i386/include/md_var.h1
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);
OpenPOWER on IntegriCloud