Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Sep 2014 21:25:55 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r271408 - in head/sys: i386/i386 i386/include x86/x86
Message-ID:  <201409102125.s8ALPtJv078977@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Wed Sep 10 21:25:54 2014
New Revision: 271408
URL: http://svnweb.freebsd.org/changeset/base/271408

Log:
  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.

Modified:
  head/sys/i386/i386/initcpu.c
  head/sys/i386/include/md_var.h
  head/sys/x86/x86/local_apic.c

Modified: head/sys/i386/i386/initcpu.c
==============================================================================
--- head/sys/i386/i386/initcpu.c	Wed Sep 10 21:24:15 2014	(r271407)
+++ head/sys/i386/i386/initcpu.c	Wed Sep 10 21:25:54 2014	(r271408)
@@ -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;
+	}
 }
 
 /*

Modified: head/sys/i386/include/md_var.h
==============================================================================
--- head/sys/i386/include/md_var.h	Wed Sep 10 21:24:15 2014	(r271407)
+++ head/sys/i386/include/md_var.h	Wed Sep 10 21:25:54 2014	(r271408)
@@ -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);

Modified: head/sys/x86/x86/local_apic.c
==============================================================================
--- head/sys/x86/x86/local_apic.c	Wed Sep 10 21:24:15 2014	(r271407)
+++ head/sys/x86/x86/local_apic.c	Wed Sep 10 21:25:54 2014	(r271408)
@@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
 #include <vm/pmap.h>
 
 #include <x86/apicreg.h>
-#include <machine/cpu.h>
 #include <machine/cputypes.h>
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
@@ -1331,9 +1330,6 @@ static void
 apic_init(void *dummy __unused)
 {
 	struct apic_enumerator *enumerator;
-#ifndef __amd64__
-	uint64_t apic_base;
-#endif
 	int retval, best;
 
 	/* We only support built in local APICs. */
@@ -1375,12 +1371,7 @@ apic_init(void *dummy __unused)
 	 * CPUs during early startup.  We need to turn the local APIC back
 	 * on on such CPUs now.
 	 */
-	if (cpu == CPU_686 && cpu_vendor_id == CPU_VENDOR_INTEL &&
-	    (cpu_id & 0xff0) == 0x610) {
-		apic_base = rdmsr(MSR_APICBASE);
-		apic_base |= APICBASE_ENABLED;
-		wrmsr(MSR_APICBASE, apic_base);
-	}
+	ppro_reenable_apic();
 #endif
 
 	/* Probe the CPU's in the system. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409102125.s8ALPtJv078977>