diff options
author | marcel <marcel@FreeBSD.org> | 2010-07-03 20:19:20 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2010-07-03 20:19:20 +0000 |
commit | 94d3d209e1d15ce1ba3735812117345077e4a8bd (patch) | |
tree | e9655806d4ea74d6fd9abc3fd4ce77542e5bce71 /sys | |
parent | c42c25e67714fad201eb9678798eeb6720db8fbf (diff) | |
download | FreeBSD-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.c | 34 | ||||
-rw-r--r-- | sys/ia64/ia64/mp_machdep.c | 2 | ||||
-rw-r--r-- | sys/ia64/include/mca.h | 1 |
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 */ |