Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Dec 2014 19:53:56 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r276076 - in stable/10/sys: amd64/amd64 i386/i386 i386/include i386/xen pc98/pc98 x86/x86
Message-ID:  <201412221953.sBMJruwk025467@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Dec 22 19:53:55 2014
New Revision: 276076
URL: https://svnweb.freebsd.org/changeset/base/276076

Log:
  MFC 271405,271408,271409,272658:
  MFamd64: Use initializecpu() to set various model-specific registers on
  AP startup and AP resume (it was already used for BSP startup and BSP
  resume).

Modified:
  stable/10/sys/amd64/amd64/mp_machdep.c
  stable/10/sys/i386/i386/initcpu.c
  stable/10/sys/i386/i386/machdep.c
  stable/10/sys/i386/i386/mp_machdep.c
  stable/10/sys/i386/include/md_var.h
  stable/10/sys/i386/xen/mp_machdep.c
  stable/10/sys/pc98/pc98/machdep.c
  stable/10/sys/x86/x86/identcpu.c
  stable/10/sys/x86/x86/local_apic.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- stable/10/sys/amd64/amd64/mp_machdep.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/amd64/amd64/mp_machdep.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -723,7 +723,7 @@ init_secondary(void)
 	/* set up CPU registers and state */
 	cpu_setregs();
 
-	/* set up SSE/NX registers */
+	/* set up SSE/NX */
 	initializecpu();
 
 	/* set up FPU state on the AP */

Modified: stable/10/sys/i386/i386/initcpu.c
==============================================================================
--- stable/10/sys/i386/i386/initcpu.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/i386/i386/initcpu.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -59,6 +59,12 @@ static void init_i486_on_386(void);
 static void init_6x86(void);
 #endif /* I486_CPU */
 
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+static void	enable_K5_wt_alloc(void);
+static void	enable_K6_wt_alloc(void);
+static void	enable_K6_2_wt_alloc(void);
+#endif
+
 #ifdef I686_CPU
 static void	init_6x86MX(void);
 static void	init_ppro(void);
@@ -451,7 +457,7 @@ init_winchip(void)
 	fcr &= ~(1ULL << 11);
 
 	/*
-	 * Additioanlly, set EBRPRED, E2MMX and EAMD3D for WinChip 2 and 3.
+	 * Additionally, set EBRPRED, E2MMX and EAMD3D for WinChip 2 and 3.
 	 */
 	if (CPUID_TO_MODEL(cpu_id) >= 8)
 		fcr |= (1 << 12) | (1 << 19) | (1 << 20);
@@ -527,6 +533,8 @@ init_6x86MX(void)
 	intr_restore(saveintr);
 }
 
+static int ppro_apic_used = -1;
+
 static void
 init_ppro(void)
 {
@@ -535,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;
+	}
 }
 
 /*
@@ -646,20 +674,6 @@ init_transmeta(void)
 }
 #endif
 
-/*
- * Initialize CR4 (Control register 4) to enable SSE instructions.
- */
-void
-enable_sse(void)
-{
-#if defined(CPU_ENABLE_SSE)
-	if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) {
-		load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
-		cpu_fxsr = hw_instruction_sse = 1;
-	}
-#endif
-}
-
 extern int elf32_nxstack;
 
 void
@@ -692,6 +706,27 @@ initializecpu(void)
 #ifdef I586_CPU
 	case CPU_586:
 		switch (cpu_vendor_id) {
+		case CPU_VENDOR_AMD:
+#ifdef CPU_WT_ALLOC
+			if (((cpu_id & 0x0f0) > 0) &&
+			    ((cpu_id & 0x0f0) < 0x60) &&
+			    ((cpu_id & 0x00f) > 3))
+				enable_K5_wt_alloc();
+			else if (((cpu_id & 0x0f0) > 0x80) ||
+			    (((cpu_id & 0x0f0) == 0x80) &&
+				(cpu_id & 0x00f) > 0x07))
+				enable_K6_2_wt_alloc();
+			else if ((cpu_id & 0x0f0) > 0x50)
+				enable_K6_wt_alloc();
+#endif
+			if ((cpu_id & 0xf0) == 0xa0)
+				/*
+				 * Make sure the TSC runs through
+				 * suspension, otherwise we can't use
+				 * it as timecounter
+				 */
+				wrmsr(0x1900, rdmsr(0x1900) | 0x20ULL);
+			break;
 		case CPU_VENDOR_CENTAUR:
 			init_winchip();
 			break;
@@ -762,7 +797,17 @@ initializecpu(void)
 	default:
 		break;
 	}
-	enable_sse();
+#if defined(CPU_ENABLE_SSE)
+	if ((cpu_feature & CPUID_XMM) && (cpu_feature & CPUID_FXSR)) {
+		load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
+		cpu_fxsr = hw_instruction_sse = 1;
+	}
+#endif
+}
+
+void
+initializecpucache(void)
+{
 
 	/*
 	 * CPUID with %eax = 1, %ebx returns
@@ -839,7 +884,7 @@ initializecpu(void)
  * Enable write allocate feature of AMD processors.
  * Following two functions require the Maxmem variable being set.
  */
-void
+static void
 enable_K5_wt_alloc(void)
 {
 	u_int64_t	msr;
@@ -885,7 +930,7 @@ enable_K5_wt_alloc(void)
 	}
 }
 
-void
+static void
 enable_K6_wt_alloc(void)
 {
 	quad_t	size;
@@ -945,7 +990,7 @@ enable_K6_wt_alloc(void)
 	intr_restore(saveintr);
 }
 
-void
+static void
 enable_K6_2_wt_alloc(void)
 {
 	quad_t	size;

Modified: stable/10/sys/i386/i386/machdep.c
==============================================================================
--- stable/10/sys/i386/i386/machdep.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/i386/i386/machdep.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -2733,6 +2733,7 @@ init386(first)
 	setidt(IDT_GP, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL,
 	    GSEL(GCODE_SEL, SEL_KPL));
 	initializecpu();	/* Initialize CPU registers */
+	initializecpucache();
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
 	/* Note: -16 is so we can grow the trapframe if we came from vm86 */
@@ -3009,6 +3010,7 @@ init386(first)
 	setidt(IDT_GP, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL,
 	    GSEL(GCODE_SEL, SEL_KPL));
 	initializecpu();	/* Initialize CPU registers */
+	initializecpucache();
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
 	/* Note: -16 is so we can grow the trapframe if we came from vm86 */

Modified: stable/10/sys/i386/i386/mp_machdep.c
==============================================================================
--- stable/10/sys/i386/i386/mp_machdep.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/i386/i386/mp_machdep.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -747,25 +747,15 @@ init_secondary(void)
 	/* set up CPU registers and state */
 	cpu_setregs();
 
+	/* set up SSE/NX */
+	initializecpu();
+
 	/* set up FPU state on the AP */
 	npxinit();
 
-	/* set up SSE registers */
-	enable_sse();
-
 	if (cpu_ops.cpu_init)
 		cpu_ops.cpu_init();
 
-#ifdef PAE
-	/* Enable the PTE no-execute bit. */
-	if ((amd_feature & AMDID_NX) != 0) {
-		uint64_t msr;
-
-		msr = rdmsr(MSR_EFER) | EFER_NXE;
-		wrmsr(MSR_EFER, msr);
-	}
-#endif
-
 	/* A quick check from sanity claus */
 	cpuid = PCPU_GET(cpuid);
 	if (PCPU_GET(apic_id) != lapic_id()) {
@@ -1530,6 +1520,7 @@ cpususpend_handler(void)
 	} else {
 		npxresume(&susppcbs[cpu]->sp_fpususpend);
 		pmap_init_pat();
+		initializecpu();
 		PCPU_SET(switchtime, 0);
 		PCPU_SET(switchticks, ticks);
 

Modified: stable/10/sys/i386/include/md_var.h
==============================================================================
--- stable/10/sys/i386/include/md_var.h	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/i386/include/md_var.h	Mon Dec 22 19:53:55 2014	(r276076)
@@ -99,14 +99,9 @@ void	doreti_popl_fs_fault(void) __asm(__
 void	dump_add_page(vm_paddr_t);
 void	dump_drop_page(vm_paddr_t);
 void	finishidentcpu(void);
-#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
-void	enable_K5_wt_alloc(void);
-void	enable_K6_wt_alloc(void);
-void	enable_K6_2_wt_alloc(void);
-#endif
-void	enable_sse(void);
 void	fillw(int /*u_short*/ pat, void *base, size_t cnt);
 void	initializecpu(void);
+void	initializecpucache(void);
 void	i686_pagezero(void *addr);
 void	sse2_pagezero(void *addr);
 void	init_AMD_Elan_sc520(void);
@@ -114,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: stable/10/sys/i386/xen/mp_machdep.c
==============================================================================
--- stable/10/sys/i386/xen/mp_machdep.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/i386/xen/mp_machdep.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -598,22 +598,13 @@ init_secondary(void)
 	for (addr = 0; addr < NKPT * NBPDR - 1; addr += PAGE_SIZE)
 		invlpg(addr);
 
-	/* set up FPU state on the AP */
-	npxinit();
 #if 0
-	
-	/* set up SSE registers */
-	enable_sse();
+	/* set up SSE/NX */
+	initializecpu();
 #endif
-#if 0 && defined(PAE)
-	/* Enable the PTE no-execute bit. */
-	if ((amd_feature & AMDID_NX) != 0) {
-		uint64_t msr;
 
-		msr = rdmsr(MSR_EFER) | EFER_NXE;
-		wrmsr(MSR_EFER, msr);
-	}
-#endif
+	/* set up FPU state on the AP */
+	npxinit();
 #if 0
 	/* A quick check from sanity claus */
 	if (PCPU_GET(apic_id) != lapic_id()) {

Modified: stable/10/sys/pc98/pc98/machdep.c
==============================================================================
--- stable/10/sys/pc98/pc98/machdep.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/pc98/pc98/machdep.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -2310,6 +2310,7 @@ init386(first)
 	setidt(IDT_GP, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL,
 	    GSEL(GCODE_SEL, SEL_KPL));
 	initializecpu();	/* Initialize CPU registers */
+	initializecpucache();
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
 	/* Note: -16 is so we can grow the trapframe if we came from vm86 */

Modified: stable/10/sys/x86/x86/identcpu.c
==============================================================================
--- stable/10/sys/x86/x86/identcpu.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/x86/x86/identcpu.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -405,30 +405,11 @@ printcpuinfo(void)
 			break;
 		case 0x5a0:
 			strcat(cpu_model, "Geode LX");
-			/*
-			 * Make sure the TSC runs through suspension,
-			 * otherwise we can't use it as timecounter
-			 */
-			wrmsr(0x1900, rdmsr(0x1900) | 0x20ULL);
 			break;
 		default:
 			strcat(cpu_model, "Unknown");
 			break;
 		}
-#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
-		if ((cpu_id & 0xf00) == 0x500) {
-			if (((cpu_id & 0x0f0) > 0)
-			    && ((cpu_id & 0x0f0) < 0x60)
-			    && ((cpu_id & 0x00f) > 3))
-				enable_K5_wt_alloc();
-			else if (((cpu_id & 0x0f0) > 0x80)
-				 || (((cpu_id & 0x0f0) == 0x80)
-				     && (cpu_id & 0x00f) > 0x07))
-				enable_K6_2_wt_alloc();
-			else if ((cpu_id & 0x0f0) > 0x50)
-				enable_K6_wt_alloc();
-		}
-#endif
 #else
 		if ((cpu_id & 0xf00) == 0xf00)
 			strcat(cpu_model, "AMD64 Processor");

Modified: stable/10/sys/x86/x86/local_apic.c
==============================================================================
--- stable/10/sys/x86/x86/local_apic.c	Mon Dec 22 19:10:21 2014	(r276075)
+++ stable/10/sys/x86/x86/local_apic.c	Mon Dec 22 19:53:55 2014	(r276076)
@@ -56,7 +56,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>
@@ -1264,9 +1263,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. */
@@ -1308,12 +1304,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?201412221953.sBMJruwk025467>