From owner-svn-src-head@FreeBSD.ORG Wed Sep 10 21:25:56 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DC571EB1; Wed, 10 Sep 2014 21:25:55 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C7B71E82; Wed, 10 Sep 2014 21:25:55 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s8ALPtTT078980; Wed, 10 Sep 2014 21:25:55 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s8ALPtJv078977; Wed, 10 Sep 2014 21:25:55 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201409102125.s8ALPtJv078977@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Wed, 10 Sep 2014 21:25:55 +0000 (UTC) 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 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Sep 2014 21:25:56 -0000 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 #include -#include #include #include #include @@ -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. */