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).
This commit is contained in:
parent
77f68eb34a
commit
71f9e38fa2
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -99,14 +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);
|
||||
#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);
|
||||
|
@ -598,22 +598,13 @@ init_secondary(void)
|
||||
for (addr = 0; addr < NKPT * NBPDR - 1; addr += PAGE_SIZE)
|
||||
invlpg(addr);
|
||||
|
||||
#if 0
|
||||
/* set up SSE/NX */
|
||||
initializecpu();
|
||||
#endif
|
||||
|
||||
/* set up FPU state on the AP */
|
||||
npxinit();
|
||||
#if 0
|
||||
|
||||
/* set up SSE registers */
|
||||
enable_sse();
|
||||
#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
|
||||
#if 0
|
||||
/* A quick check from sanity claus */
|
||||
if (PCPU_GET(apic_id) != lapic_id()) {
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user