From 083d60f9beb70ca2efd64bda9f2f4c52b07cbf92 Mon Sep 17 00:00:00 2001 From: ps Date: Sun, 6 Aug 2000 14:17:21 +0000 Subject: 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 --- sys/amd64/amd64/trap.c | 40 ++++++++++++++++++++++++++++-------- sys/amd64/isa/intr_machdep.c | 49 ++++++++++++++++++++++++++++---------------- sys/amd64/isa/nmi.c | 49 ++++++++++++++++++++++++++++---------------- 3 files changed, 93 insertions(+), 45 deletions(-) (limited to 'sys/amd64') 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 #include #include +#include #include #include #include @@ -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); } /* -- cgit v1.1