|
|
int add_nmi_handler(int (nmi_handler)(), int reserved);
This is a pointer to the stacked registers at the time of the NMI. The values of the various registers are stored at different offsets from this pointer. A definition of the offsets can be found in the /usr/include/sys/reg.h header file. For an example of how to access the registers, see ``Examples'', below.
The handler should be defined as returning an integer value and as being passed a pointer argument, as the following example shows:
int nmi_handler(int r0ptr);
If the handler recognizes the cause of the NMI and deals with it successfully, the handler should return a non-zero value. This indicates to the kernel that the NMI handling is complete and that no further NMI handlers should be called.
If the handler does not recognize the NMI, it should return zero. This will cause the next registered NMI handler to be called, with the process continuing from there.
If none of the handlers called were able to deal with the NMI, the kernel default NMI handler will be invoked.
A handler should not induce a kernel panic if it cannot determine the cause of an NMI.
The routine pointed to by the nmi_handler argument executes in interrupt context.
``Non-Maskable interrupts (NMI)'' in HDK Technical Reference
#include <sys/reg.h>/* xxinit routine registers the NMI handler */
void tstinit() { int tst_handler(); add_nmi_handler(tst_handler, 0); }
/* the NMI handler */
int tst_handler(int r0ptr); { int tst_eip;
/* The following line is an example of how you would * access a register value */
tst_eip = r0ptr[EIP];
/* check whether the NMI is one which we can handle */
if (tst_nmi_servicable()) {
/* code to service the NMI */
return(1); } else return(0); /* not one of ours */ }
int tst_nmi_servicable() { /* fictitious routine that determines whether the * NMI is one which the NMI handler was designed to * service. Returns non-zero if so, else zero. */ }