Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Oct 2009 14:34:02 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r198589 - in stable/7/sys: . amd64/amd64 amd64/include conf contrib/pf i386/i386 i386/include
Message-ID:  <200910291434.n9TEY2Sj099334@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu Oct 29 14:34:02 2009
New Revision: 198589
URL: http://svn.freebsd.org/changeset/base/198589

Log:
  MFC 192050, 192343, 192440:
  Implement simple machine check support for amd64 and i386.  It is disabled
  by default but can be enabled via the 'hw.mca.enabled' tunable.

Added:
  stable/7/sys/amd64/amd64/mca.c
     - copied, changed from r192050, head/sys/amd64/amd64/mca.c
  stable/7/sys/amd64/include/mca.h
     - copied unchanged from r192050, head/sys/amd64/include/mca.h
  stable/7/sys/i386/i386/mca.c
     - copied, changed from r192050, head/sys/i386/i386/mca.c
  stable/7/sys/i386/include/mca.h
     - copied unchanged from r192050, head/sys/i386/include/mca.h
Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/amd64/amd64/machdep.c
  stable/7/sys/amd64/amd64/mp_machdep.c
  stable/7/sys/amd64/amd64/trap.c
  stable/7/sys/amd64/include/specialreg.h
  stable/7/sys/conf/files.amd64
  stable/7/sys/conf/files.i386
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/i386/i386/machdep.c
  stable/7/sys/i386/i386/mp_machdep.c
  stable/7/sys/i386/i386/trap.c
  stable/7/sys/i386/include/specialreg.h

Modified: stable/7/sys/amd64/amd64/machdep.c
==============================================================================
--- stable/7/sys/amd64/amd64/machdep.c	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/amd64/amd64/machdep.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -109,6 +109,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpu.h>
 #include <machine/cputypes.h>
 #include <machine/intr_machdep.h>
+#include <machine/mca.h>
 #include <machine/md_var.h>
 #include <machine/metadata.h>
 #include <machine/pc/bios.h>
@@ -261,6 +262,7 @@ cpu_startup(dummy)
 	vm_pager_bufferinit();
 
 	cpu_setregs();
+	mca_init();
 }
 
 /*

Copied and modified: stable/7/sys/amd64/amd64/mca.c (from r192050, head/sys/amd64/amd64/mca.c)
==============================================================================
--- head/sys/amd64/amd64/mca.c	Wed May 13 17:53:04 2009	(r192050, copy source)
+++ stable/7/sys/amd64/amd64/mca.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -55,10 +55,15 @@ struct mca_internal {
 
 static MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture");
 
-static struct sysctl_oid *mca_sysctl_tree;
-
 static int mca_count;		/* Number of records stored. */
 
+SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture");
+
+static int mca_enabled = 0;
+TUNABLE_INT("hw.mca.enabled", &mca_enabled);
+SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0,
+    "Administrative toggle for machine check support");
+
 static STAILQ_HEAD(, mca_internal) mca_records;
 static struct callout mca_timer;
 static int mca_ticks = 3600;	/* Check hourly by default. */
@@ -346,7 +351,7 @@ mca_scan(int mcip)
 
 	/* When handling a MCE#, treat the OVER flag as non-restartable. */
 	if (mcip)
-		ucmask = MC_STATUS_OVER;
+		ucmask |= MC_STATUS_OVER;
 	mcg_cap = rdmsr(MSR_MCG_CAP);
 	for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) {
 		rec = mca_record_entry(i);
@@ -426,7 +431,7 @@ static void
 mca_startup(void *dummy)
 {
 
-	if (!(cpu_feature & CPUID_MCA))
+	if (!mca_enabled || !(cpu_feature & CPUID_MCA))
 		return;
 
 	callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan,
@@ -442,17 +447,15 @@ mca_setup(void)
 	STAILQ_INIT(&mca_records);
 	TASK_INIT(&mca_task, 0x8000, mca_scan_cpus, NULL);
 	callout_init(&mca_timer, CALLOUT_MPSAFE);
-	mca_sysctl_tree = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw),
-	    OID_AUTO, "mca", CTLFLAG_RW, NULL, "MCA container");
-	SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "count", CTLFLAG_RD, &mca_count, 0, "Record count");
-	SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "interval", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &mca_ticks,
 	    0, sysctl_mca_ticks, "I",
 	    "Periodic interval in seconds to scan for machine checks");
-	SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "records", CTLFLAG_RD, sysctl_mca_records, "Machine check records");
-	SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "force_scan", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
 	    sysctl_mca_scan, "I", "Force an immediate scan for machine checks");
 }
@@ -465,7 +468,7 @@ mca_init(void)
 	int i;
 
 	/* MCE is required. */
-	if (!(cpu_feature & CPUID_MCE))
+	if (!mca_enabled || !(cpu_feature & CPUID_MCE))
 		return;
 
 	if (cpu_feature & CPUID_MCA) {
@@ -488,10 +491,6 @@ mca_init(void)
 			if (!(i == 0 && (cpu_id & 0xf00) == 0x600))
 				wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL);
 
-			/* XXX: Better CPU test needed here. */
-			if ((cpu_id & 0xf00) == 0xf00)
-				mca_record_entry(i);
-
 			/* Clear all errors. */
 			wrmsr(MSR_MC_STATUS(i), 0);
 		}

Modified: stable/7/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- stable/7/sys/amd64/amd64/mp_machdep.c	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/amd64/amd64/mp_machdep.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/apicreg.h>
 #include <machine/cputypes.h>
+#include <machine/mca.h>
 #include <machine/md_var.h>
 #include <machine/mp_watchdog.h>
 #include <machine/pcb.h>
@@ -562,6 +563,8 @@ init_secondary(void)
 	KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
 	PCPU_SET(curthread, PCPU_GET(idlethread));
 
+	mca_init();
+
 	mtx_lock_spin(&ap_boot_mtx);
 
 	/* Init local apic for irq's */

Modified: stable/7/sys/amd64/amd64/trap.c
==============================================================================
--- stable/7/sys/amd64/amd64/trap.c	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/amd64/amd64/trap.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -89,6 +89,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/cpu.h>
 #include <machine/intr_machdep.h>
+#include <machine/mca.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
 #ifdef SMP
@@ -228,6 +229,12 @@ trap(struct trapframe *frame)
 		goto out;
 #endif
 
+	if (type == T_MCHK) {
+		if (!mca_intr())
+			trap_fatal(frame, 0);
+		goto out;
+	}
+
 #ifdef KDTRACE_HOOKS
 	/*
 	 * A trap can occur while DTrace executes a probe. Before

Copied: stable/7/sys/amd64/include/mca.h (from r192050, head/sys/amd64/include/mca.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/sys/amd64/include/mca.h	Thu Oct 29 14:34:02 2009	(r198589, copy of r192050, head/sys/amd64/include/mca.h)
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __MACHINE_MCA_H__
+#define	__MACHINE_MCA_H__
+
+struct mca_record {
+	uint64_t	mr_status;
+	uint64_t	mr_addr;
+	uint64_t	mr_misc;
+	uint64_t	mr_tsc;
+	int		mr_apic_id;
+};
+
+#ifdef _KERNEL
+
+void	mca_init(void);
+int	mca_intr(void);
+
+#endif
+
+#endif /* !__MACHINE_MCA_H__ */

Modified: stable/7/sys/amd64/include/specialreg.h
==============================================================================
--- stable/7/sys/amd64/include/specialreg.h	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/amd64/include/specialreg.h	Thu Oct 29 14:34:02 2009	(r198589)
@@ -339,6 +339,34 @@
 #define	DIR1			0xff
 
 /*
+ * Machine Check register constants.
+ */
+#define	MCG_CAP_COUNT		0x000000ff
+#define	MCG_CAP_CTL_P		0x00000100
+#define	MCG_CAP_EXT_P		0x00000200
+#define	MCG_CAP_TES_P		0x00000800
+#define	MCG_CAP_EXT_CNT		0x00ff0000
+#define	MCG_STATUS_RIPV		0x00000001
+#define	MCG_STATUS_EIPV		0x00000002
+#define	MCG_STATUS_MCIP		0x00000004
+#define	MCG_CTL_ENABLE		0xffffffffffffffffUL
+#define	MCG_CTL_DISABLE		0x0000000000000000UL
+#define	MSR_MC_CTL(x)		(MSR_MC0_CTL + (x) * 4)
+#define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
+#define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
+#define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
+#define	MC_STATUS_MCA_ERROR	0x000000000000ffffUL
+#define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000UL
+#define	MC_STATUS_OTHER_INFO	0x01ffffff00000000UL
+#define	MC_STATUS_PCC		0x0200000000000000UL
+#define	MC_STATUS_ADDRV		0x0400000000000000UL
+#define	MC_STATUS_MISCV		0x0800000000000000UL
+#define	MC_STATUS_EN		0x1000000000000000UL
+#define	MC_STATUS_UC		0x2000000000000000UL
+#define	MC_STATUS_OVER		0x4000000000000000UL
+#define	MC_STATUS_VAL		0x8000000000000000UL
+
+/*
  * The following four 3-byte registers control the non-cacheable regions.
  * These registers must be written as three separate bytes.
  *

Modified: stable/7/sys/conf/files.amd64
==============================================================================
--- stable/7/sys/conf/files.amd64	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/conf/files.amd64	Thu Oct 29 14:34:02 2009	(r198589)
@@ -99,6 +99,7 @@ amd64/amd64/legacy.c		standard
 amd64/amd64/local_apic.c	standard
 amd64/amd64/locore.S		standard	no-obj
 amd64/amd64/machdep.c		standard
+amd64/amd64/mca.c		standard
 amd64/amd64/mem.c		optional	mem
 amd64/amd64/minidump_machdep.c	standard
 amd64/amd64/mp_machdep.c	optional	smp

Modified: stable/7/sys/conf/files.i386
==============================================================================
--- stable/7/sys/conf/files.i386	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/conf/files.i386	Thu Oct 29 14:34:02 2009	(r198589)
@@ -282,6 +282,7 @@ i386/i386/local_apic.c		optional apic
 i386/i386/locore.s		standard	no-obj
 i386/i386/longrun.c		optional cpu_enable_longrun
 i386/i386/machdep.c		standard
+i386/i386/mca.c			standard
 i386/i386/mem.c			optional mem
 i386/i386/minidump_machdep.c	standard
 i386/i386/mp_clock.c		optional smp

Modified: stable/7/sys/i386/i386/machdep.c
==============================================================================
--- stable/7/sys/i386/i386/machdep.c	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/i386/i386/machdep.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -114,6 +114,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpu.h>
 #include <machine/cputypes.h>
 #include <machine/intr_machdep.h>
+#include <machine/mca.h>
 #include <machine/md_var.h>
 #include <machine/metadata.h>
 #include <machine/pc/bios.h>
@@ -290,6 +291,7 @@ cpu_startup(dummy)
 	vm_pager_bufferinit();
 
 	cpu_setregs();
+	mca_init();
 }
 
 /*

Copied and modified: stable/7/sys/i386/i386/mca.c (from r192050, head/sys/i386/i386/mca.c)
==============================================================================
--- head/sys/i386/i386/mca.c	Wed May 13 17:53:04 2009	(r192050, copy source)
+++ stable/7/sys/i386/i386/mca.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -55,10 +55,15 @@ struct mca_internal {
 
 static MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture");
 
-static struct sysctl_oid *mca_sysctl_tree;
-
 static int mca_count;		/* Number of records stored. */
 
+SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture");
+
+static int mca_enabled = 0;
+TUNABLE_INT("hw.mca.enabled", &mca_enabled);
+SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0,
+    "Administrative toggle for machine check support");
+
 static STAILQ_HEAD(, mca_internal) mca_records;
 static struct callout mca_timer;
 static int mca_ticks = 3600;	/* Check hourly by default. */
@@ -346,7 +351,7 @@ mca_scan(int mcip)
 
 	/* When handling a MCE#, treat the OVER flag as non-restartable. */
 	if (mcip)
-		ucmask = MC_STATUS_OVER;
+		ucmask |= MC_STATUS_OVER;
 	mcg_cap = rdmsr(MSR_MCG_CAP);
 	for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) {
 		rec = mca_record_entry(i);
@@ -426,7 +431,7 @@ static void
 mca_startup(void *dummy)
 {
 
-	if (!(cpu_feature & CPUID_MCA))
+	if (!mca_enabled || !(cpu_feature & CPUID_MCA))
 		return;
 
 	callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan,
@@ -442,17 +447,15 @@ mca_setup(void)
 	STAILQ_INIT(&mca_records);
 	TASK_INIT(&mca_task, 0x8000, mca_scan_cpus, NULL);
 	callout_init(&mca_timer, CALLOUT_MPSAFE);
-	mca_sysctl_tree = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw),
-	    OID_AUTO, "mca", CTLFLAG_RW, NULL, "MCA container");
-	SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "count", CTLFLAG_RD, &mca_count, 0, "Record count");
-	SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "interval", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &mca_ticks,
 	    0, sysctl_mca_ticks, "I",
 	    "Periodic interval in seconds to scan for machine checks");
-	SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "records", CTLFLAG_RD, sysctl_mca_records, "Machine check records");
-	SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO,
+	SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO,
 	    "force_scan", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
 	    sysctl_mca_scan, "I", "Force an immediate scan for machine checks");
 }
@@ -465,7 +468,7 @@ mca_init(void)
 	int i;
 
 	/* MCE is required. */
-	if (!(cpu_feature & CPUID_MCE))
+	if (!mca_enabled || !(cpu_feature & CPUID_MCE))
 		return;
 
 	if (cpu_feature & CPUID_MCA) {
@@ -488,10 +491,6 @@ mca_init(void)
 			if (!(i == 0 && (cpu_id & 0xf00) == 0x600))
 				wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL);
 
-			/* XXX: Better CPU test needed here. */
-			if ((cpu_id & 0xf00) == 0xf00)
-				mca_record_entry(i);
-
 			/* Clear all errors. */
 			wrmsr(MSR_MC_STATUS(i), 0);
 		}

Modified: stable/7/sys/i386/i386/mp_machdep.c
==============================================================================
--- stable/7/sys/i386/i386/mp_machdep.c	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/i386/i386/mp_machdep.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/apicreg.h>
 #include <machine/cputypes.h>
+#include <machine/mca.h>
 #include <machine/md_var.h>
 #include <machine/mp_watchdog.h>
 #include <machine/pcb.h>
@@ -612,6 +613,8 @@ init_secondary(void)
 	KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
 	PCPU_SET(curthread, PCPU_GET(idlethread));
 
+	mca_init();
+
 	mtx_lock_spin(&ap_boot_mtx);
 
 	/* Init local apic for irq's */

Modified: stable/7/sys/i386/i386/trap.c
==============================================================================
--- stable/7/sys/i386/i386/trap.c	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/i386/i386/trap.c	Thu Oct 29 14:34:02 2009	(r198589)
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/cpu.h>
 #include <machine/intr_machdep.h>
+#include <machine/mca.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
 #ifdef SMP
@@ -242,6 +243,12 @@ trap(struct trapframe *frame)
 	    goto out;
 #endif
 
+	if (type == T_MCHK) {
+		if (!mca_intr())
+			trap_fatal(frame, 0);
+		goto out;
+	}
+
 #ifdef KDTRACE_HOOKS
 	/*
 	 * A trap can occur while DTrace executes a probe. Before

Copied: stable/7/sys/i386/include/mca.h (from r192050, head/sys/i386/include/mca.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/sys/i386/include/mca.h	Thu Oct 29 14:34:02 2009	(r198589, copy of r192050, head/sys/i386/include/mca.h)
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2009 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __MACHINE_MCA_H__
+#define	__MACHINE_MCA_H__
+
+struct mca_record {
+	uint64_t	mr_status;
+	uint64_t	mr_addr;
+	uint64_t	mr_misc;
+	uint64_t	mr_tsc;
+	int		mr_apic_id;
+};
+
+#ifdef _KERNEL
+
+void	mca_init(void);
+int	mca_intr(void);
+
+#endif
+
+#endif /* !__MACHINE_MCA_H__ */

Modified: stable/7/sys/i386/include/specialreg.h
==============================================================================
--- stable/7/sys/i386/include/specialreg.h	Thu Oct 29 14:22:09 2009	(r198588)
+++ stable/7/sys/i386/include/specialreg.h	Thu Oct 29 14:34:02 2009	(r198589)
@@ -408,6 +408,34 @@
 #define	DIR1			0xff
 
 /*
+ * Machine Check register constants.
+ */
+#define	MCG_CAP_COUNT		0x000000ff
+#define	MCG_CAP_CTL_P		0x00000100
+#define	MCG_CAP_EXT_P		0x00000200
+#define	MCG_CAP_TES_P		0x00000800
+#define	MCG_CAP_EXT_CNT		0x00ff0000
+#define	MCG_STATUS_RIPV		0x00000001
+#define	MCG_STATUS_EIPV		0x00000002
+#define	MCG_STATUS_MCIP		0x00000004
+#define	MCG_CTL_ENABLE		0xffffffffffffffffUL
+#define	MCG_CTL_DISABLE		0x0000000000000000UL
+#define	MSR_MC_CTL(x)		(MSR_MC0_CTL + (x) * 4)
+#define	MSR_MC_STATUS(x)	(MSR_MC0_STATUS + (x) * 4)
+#define	MSR_MC_ADDR(x)		(MSR_MC0_ADDR + (x) * 4)
+#define	MSR_MC_MISC(x)		(MSR_MC0_MISC + (x) * 4)
+#define	MC_STATUS_MCA_ERROR	0x000000000000ffffUL
+#define	MC_STATUS_MODEL_ERROR	0x00000000ffff0000UL
+#define	MC_STATUS_OTHER_INFO	0x01ffffff00000000UL
+#define	MC_STATUS_PCC		0x0200000000000000UL
+#define	MC_STATUS_ADDRV		0x0400000000000000UL
+#define	MC_STATUS_MISCV		0x0800000000000000UL
+#define	MC_STATUS_EN		0x1000000000000000UL
+#define	MC_STATUS_UC		0x2000000000000000UL
+#define	MC_STATUS_OVER		0x4000000000000000UL
+#define	MC_STATUS_VAL		0x8000000000000000UL
+
+/*
  * The following four 3-byte registers control the non-cacheable regions.
  * These registers must be written as three separate bytes.
  *



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910291434.n9TEY2Sj099334>