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. */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to