summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2000-08-06 14:17:21 +0000
committerps <ps@FreeBSD.org>2000-08-06 14:17:21 +0000
commit083d60f9beb70ca2efd64bda9f2f4c52b07cbf92 (patch)
tree36f6b88a8a63a92accd746ecbdedf18bb4f4660c /sys/amd64
parentd4b9ebce72bd5d67e5d522b99ca35910ba6f014d (diff)
downloadFreeBSD-src-083d60f9beb70ca2efd64bda9f2f4c52b07cbf92.zip
FreeBSD-src-083d60f9beb70ca2efd64bda9f2f4c52b07cbf92.tar.gz
Change the behavior of isa_nmi to log an error message instead of
panicing and return a status so that we can decide whether to drop into DDB or panic. If the status from isa_nmi is true, panic the kernel based on machdep.panic_on_nmi, otherwise if DDB is enabled, drop to DDB based on machdep.ddb_on_nmi. Reviewed by: peter, phk
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/trap.c40
-rw-r--r--sys/amd64/isa/intr_machdep.c49
-rw-r--r--sys/amd64/isa/nmi.c49
3 files changed, 93 insertions, 45 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 5a435fe..51de1ac 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -56,6 +56,7 @@
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/syscall.h>
+#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/uio.h>
#include <sys/vmmeter.h>
@@ -147,6 +148,15 @@ static __inline int userret __P((struct proc *p, struct trapframe *frame,
extern int has_f00f_bug;
#endif
+#ifdef DDB
+static int ddb_on_nmi = 1;
+SYSCTL_INT(_machdep, OID_AUTO, ddb_on_nmi, CTLFLAG_RW,
+ &ddb_on_nmi, 0, "Go to DDB on NMI");
+#endif
+static int panic_on_nmi = 1;
+SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
+ &panic_on_nmi, 0, "Panic on NMI");
+
static __inline int
userret(p, frame, oticks, have_mplock)
struct proc *p;
@@ -372,13 +382,19 @@ restart:
/* machine/parity/power fail/"kitchen sink" faults */
if (isa_nmi(code) == 0) {
#ifdef DDB
- /* NMI can be hooked up to a pushbutton for debugging */
- printf ("NMI ... going to debugger\n");
- kdb_trap (type, 0, &frame);
+ /*
+ * NMI can be hooked up to a pushbutton
+ * for debugging.
+ */
+ if (ddb_on_nmi) {
+ printf ("NMI ... going to debugger\n");
+ kdb_trap (type, 0, &frame);
+ }
#endif /* DDB */
return;
- }
- panic("NMI indicates hardware failure");
+ } else if (panic_on_nmi)
+ panic("NMI indicates hardware failure");
+ break;
#endif /* POWERFAIL_NMI */
#endif /* NISA > 0 */
@@ -577,12 +593,18 @@ kernel_trap:
/* machine/parity/power fail/"kitchen sink" faults */
if (isa_nmi(code) == 0) {
#ifdef DDB
- /* NMI can be hooked up to a pushbutton for debugging */
- printf ("NMI ... going to debugger\n");
- kdb_trap (type, 0, &frame);
+ /*
+ * NMI can be hooked up to a pushbutton
+ * for debugging.
+ */
+ if (ddb_on_nmi) {
+ printf ("NMI ... going to debugger\n");
+ kdb_trap (type, 0, &frame);
+ }
#endif /* DDB */
return;
- }
+ } else if (panic_on_nmi == 0)
+ return;
/* FALL THROUGH */
#endif /* POWERFAIL_NMI */
#endif /* NISA > 0 */
diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c
index 576b054..34a8c22 100644
--- a/sys/amd64/isa/intr_machdep.c
+++ b/sys/amd64/isa/intr_machdep.c
@@ -229,32 +229,41 @@ int
isa_nmi(cd)
int cd;
{
+ int retval = 0;
#ifdef PC98
int port = inb(0x33);
+
+ log(LOG_CRIT, "NMI PC98 port = %x\n", port);
if (epson_machine_id == 0x20)
epson_outb(0xc16, epson_inb(0xc16) | 0x1);
if (port & NMI_PARITY) {
- panic("BASE RAM parity error, likely hardware failure.");
+ log(LOG_CRIT, "BASE RAM parity error, likely hardware failure.");
+ retval = 1;
} else if (port & NMI_EPARITY) {
- panic("EXTENDED RAM parity error, likely hardware failure.");
+ log(LOG_CRIT, "EXTENDED RAM parity error, likely hardware failure.");
+ retval = 1;
} else {
- printf("\nNMI Resume ??\n");
- return(0);
+ log(LOG_CRIT, "\nNMI Resume ??\n");
}
#else /* IBM-PC */
int isa_port = inb(0x61);
int eisa_port = inb(0x461);
+ log(LOG_CRIT, "NMI ISA %x, EISA %x\n", isa_port, eisa_port);
#if NMCA > 0
if (MCA_system && mca_bus_nmi())
return(0);
#endif
- if (isa_port & NMI_PARITY)
- panic("RAM parity error, likely hardware failure.");
+ if (isa_port & NMI_PARITY) {
+ log(LOG_CRIT, "RAM parity error, likely hardware failure.");
+ retval = 1;
+ }
- if (isa_port & NMI_IOCHAN)
- panic("I/O channel check, likely hardware failure.");
+ if (isa_port & NMI_IOCHAN) {
+ log(LOG_CRIT, "I/O channel check, likely hardware failure.");
+ retval = 1;
+ }
/*
* On a real EISA machine, this will never happen. However it can
@@ -262,20 +271,24 @@ isa_nmi(cd)
* error handling (very rare). Save them from a meaningless panic.
*/
if (eisa_port == 0xff)
- return(0);
+ return(retval);
- if (eisa_port & ENMI_WATCHDOG)
- panic("EISA watchdog timer expired, likely hardware failure.");
-
- if (eisa_port & ENMI_BUSTIMER)
- panic("EISA bus timeout, likely hardware failure.");
+ if (eisa_port & ENMI_WATCHDOG) {
+ log(LOG_CRIT, "EISA watchdog timer expired, likely hardware failure.");
+ retval = 1;
+ }
- if (eisa_port & ENMI_IOSTATUS)
- panic("EISA I/O port status error.");
+ if (eisa_port & ENMI_BUSTIMER) {
+ log(LOG_CRIT, "EISA bus timeout, likely hardware failure.");
+ retval = 1;
+ }
- printf("\nNMI ISA %x, EISA %x\n", isa_port, eisa_port);
- return(0);
+ if (eisa_port & ENMI_IOSTATUS) {
+ log(LOG_CRIT, "EISA I/O port status error.");
+ retval = 1;
+ }
#endif
+ return(retval);
}
/*
diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c
index 576b054..34a8c22 100644
--- a/sys/amd64/isa/nmi.c
+++ b/sys/amd64/isa/nmi.c
@@ -229,32 +229,41 @@ int
isa_nmi(cd)
int cd;
{
+ int retval = 0;
#ifdef PC98
int port = inb(0x33);
+
+ log(LOG_CRIT, "NMI PC98 port = %x\n", port);
if (epson_machine_id == 0x20)
epson_outb(0xc16, epson_inb(0xc16) | 0x1);
if (port & NMI_PARITY) {
- panic("BASE RAM parity error, likely hardware failure.");
+ log(LOG_CRIT, "BASE RAM parity error, likely hardware failure.");
+ retval = 1;
} else if (port & NMI_EPARITY) {
- panic("EXTENDED RAM parity error, likely hardware failure.");
+ log(LOG_CRIT, "EXTENDED RAM parity error, likely hardware failure.");
+ retval = 1;
} else {
- printf("\nNMI Resume ??\n");
- return(0);
+ log(LOG_CRIT, "\nNMI Resume ??\n");
}
#else /* IBM-PC */
int isa_port = inb(0x61);
int eisa_port = inb(0x461);
+ log(LOG_CRIT, "NMI ISA %x, EISA %x\n", isa_port, eisa_port);
#if NMCA > 0
if (MCA_system && mca_bus_nmi())
return(0);
#endif
- if (isa_port & NMI_PARITY)
- panic("RAM parity error, likely hardware failure.");
+ if (isa_port & NMI_PARITY) {
+ log(LOG_CRIT, "RAM parity error, likely hardware failure.");
+ retval = 1;
+ }
- if (isa_port & NMI_IOCHAN)
- panic("I/O channel check, likely hardware failure.");
+ if (isa_port & NMI_IOCHAN) {
+ log(LOG_CRIT, "I/O channel check, likely hardware failure.");
+ retval = 1;
+ }
/*
* On a real EISA machine, this will never happen. However it can
@@ -262,20 +271,24 @@ isa_nmi(cd)
* error handling (very rare). Save them from a meaningless panic.
*/
if (eisa_port == 0xff)
- return(0);
+ return(retval);
- if (eisa_port & ENMI_WATCHDOG)
- panic("EISA watchdog timer expired, likely hardware failure.");
-
- if (eisa_port & ENMI_BUSTIMER)
- panic("EISA bus timeout, likely hardware failure.");
+ if (eisa_port & ENMI_WATCHDOG) {
+ log(LOG_CRIT, "EISA watchdog timer expired, likely hardware failure.");
+ retval = 1;
+ }
- if (eisa_port & ENMI_IOSTATUS)
- panic("EISA I/O port status error.");
+ if (eisa_port & ENMI_BUSTIMER) {
+ log(LOG_CRIT, "EISA bus timeout, likely hardware failure.");
+ retval = 1;
+ }
- printf("\nNMI ISA %x, EISA %x\n", isa_port, eisa_port);
- return(0);
+ if (eisa_port & ENMI_IOSTATUS) {
+ log(LOG_CRIT, "EISA I/O port status error.");
+ retval = 1;
+ }
#endif
+ return(retval);
}
/*
OpenPOWER on IntegriCloud