summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2010-07-03 20:19:20 +0000
committermarcel <marcel@FreeBSD.org>2010-07-03 20:19:20 +0000
commit94d3d209e1d15ce1ba3735812117345077e4a8bd (patch)
treee9655806d4ea74d6fd9abc3fd4ce77542e5bce71 /sys
parentc42c25e67714fad201eb9678798eeb6720db8fbf (diff)
downloadFreeBSD-src-94d3d209e1d15ce1ba3735812117345077e4a8bd.zip
FreeBSD-src-94d3d209e1d15ce1ba3735812117345077e4a8bd.tar.gz
Allocate and setup an interrupt vector for corrected machine checks.
For now, just print when we get the interrupt, but eventually we need to collect the details and provide a more useful report.
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/ia64/mca.c34
-rw-r--r--sys/ia64/ia64/mp_machdep.c2
-rw-r--r--sys/ia64/include/mca.h1
3 files changed, 37 insertions, 0 deletions
diff --git a/sys/ia64/ia64/mca.c b/sys/ia64/ia64/mca.c
index a11742a..c9f0ae5 100644
--- a/sys/ia64/ia64/mca.c
+++ b/sys/ia64/ia64/mca.c
@@ -28,6 +28,7 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -36,6 +37,7 @@
#include <sys/uuid.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
+#include <machine/intr.h>
#include <machine/mca.h>
#include <machine/pal.h>
#include <machine/sal.h>
@@ -72,6 +74,8 @@ SYSCTL_INT(_hw_mca, OID_AUTO, last, CTLFLAG_RD, &mca_last, 0,
static struct mtx mca_sysctl_lock;
+static u_int mca_xiv_cmc;
+
static int
mca_sysctl_inject(SYSCTL_HANDLER_ARGS)
{
@@ -227,6 +231,26 @@ ia64_mca_save_state(int type)
}
}
+static u_int
+ia64_mca_intr(struct thread *td, u_int xiv, struct trapframe *tf)
+{
+
+ if (xiv == mca_xiv_cmc) {
+ printf("MCA: corrected machine check (CMC) interrupt\n");
+ return (0);
+ }
+
+ return (0);
+}
+
+void
+ia64_mca_init_ap(void)
+{
+
+ if (mca_xiv_cmc != 0)
+ ia64_set_cmcv(mca_xiv_cmc);
+}
+
void
ia64_mca_init(void)
{
@@ -289,4 +313,14 @@ ia64_mca_init(void)
*/
for (i = 0; i < SAL_INFO_TYPES; i++)
ia64_mca_save_state(i);
+
+ /*
+ * Allocate a XIV for CMC interrupts, so that we can collect and save
+ * the corrected processor checks.
+ */
+ mca_xiv_cmc = ia64_xiv_alloc(PI_SOFT, IA64_XIV_PLAT, ia64_mca_intr);
+ if (mca_xiv_cmc != 0)
+ ia64_set_cmcv(mca_xiv_cmc);
+ else
+ printf("MCA: CMC vector could not be allocated\n");
}
diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c
index 05f352a..5b94e53 100644
--- a/sys/ia64/ia64/mp_machdep.c
+++ b/sys/ia64/ia64/mp_machdep.c
@@ -163,6 +163,8 @@ ia64_store_mca_state(void* arg)
sched_bind(td, pc->pc_cpuid);
thread_unlock(td);
+ ia64_mca_init_ap();
+
/*
* Get and save the CPU specific MCA records. Should we get the
* MCA state for each processor, or just the CMC state?
diff --git a/sys/ia64/include/mca.h b/sys/ia64/include/mca.h
index e13d2bf..1f38c13 100644
--- a/sys/ia64/include/mca.h
+++ b/sys/ia64/include/mca.h
@@ -240,6 +240,7 @@ struct mca_pcidev_reg {
#ifdef _KERNEL
void ia64_mca_init(void);
+void ia64_mca_init_ap(void);
void ia64_mca_save_state(int);
#endif /* _KERNEL */
OpenPOWER on IntegriCloud