summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-09-10 21:37:47 +0000
committerjhb <jhb@FreeBSD.org>2014-09-10 21:37:47 +0000
commitfa53fae9e4783e35e0dfe1b2a3b7c12c507ecc7a (patch)
tree096dcded9470e01dbdcbd5fc7b3a662dda064543
parent6f8d6cd57bddceacf4eae89310571ca78900e548 (diff)
downloadFreeBSD-src-fa53fae9e4783e35e0dfe1b2a3b7c12c507ecc7a.zip
FreeBSD-src-fa53fae9e4783e35e0dfe1b2a3b7c12c507ecc7a.tar.gz
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). - Split code to do one-time probing of cache properties out of initializecpu() and into initializecpucache(). This is called once on the BSP during boot. - Move enable_sse() into initializecpu(). - Call initializecpu() for AP startup instead of enable_sse() and manually frobbing MSR_EFER to enable PG_NX. - Call initializecpu() when an AP resumes. In theory this will now properly re-enable PG_NX in MSR_EFER when resuming a PAE kernel on APs.
-rw-r--r--sys/amd64/amd64/mp_machdep.c2
-rw-r--r--sys/i386/i386/initcpu.c28
-rw-r--r--sys/i386/i386/machdep.c1
-rw-r--r--sys/i386/i386/mp_machdep.c17
-rw-r--r--sys/i386/include/md_var.h2
-rw-r--r--sys/i386/xen/mp_machdep.c17
-rw-r--r--sys/pc98/pc98/machdep.c1
7 files changed, 24 insertions, 44 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 15d3a7b..3184f13 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -721,7 +721,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 */
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index fa2c6e1..6872aec 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -457,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);
@@ -674,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
@@ -811,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
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index ed7b072..94e9db4 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2753,6 +2753,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 */
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 51e8f49..3b112aa 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -745,25 +745,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()) {
@@ -1528,6 +1518,7 @@ cpususpend_handler(void)
} else {
npxresume(&susppcbs[cpu]->sp_fpususpend);
pmap_init_pat();
+ initializecpu();
PCPU_SET(switchtime, 0);
PCPU_SET(switchticks, ticks);
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index 8669815..950fa1f 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -99,9 +99,9 @@ void doreti_popl_fs_fault(void) __asm(__STRING(doreti_popl_fs_fault));
void dump_add_page(vm_paddr_t);
void dump_drop_page(vm_paddr_t);
void finishidentcpu(void);
-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);
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index 165b319..3502151 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -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()) {
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 4ae80ae..c42b4ce 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -2315,6 +2315,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 */
OpenPOWER on IntegriCloud