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>