SCO OpenServer


add_nmi_handler -- register an NMI handler function


int add_nmi_handler(int (*nmi_handler)(), int reserved);


The add_nmi_handler function registers a handler to be called on receipt of a non-maskable interrupt (NMI). The handler will be called whenever an NMI occurs on any of the processors in the system. The handler will be running on the processor on which the NMI occurred.


Address of the NMI handler routine to be registered. This routine will execute in interrupt context.

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.

reserved for future expansion; driver should set this parameter to 0.

Return values

The following return values are possible from add_nmi_handler( ): add_nmi_handler:

the handler was successfully registered

the handler has already been registered

add_nmi_handler cannot be called from within the context of an NMI handler

the maximum number of NMI handlers has already been registered


Multiple NMI handlers can be registered at the same time. On any given processor, the last handler registered using add_nmi_handler will be the first handler to be called on receipt of an NMI.

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.

Context and synchronization

Initialization context

The routine pointed to by the nmi_handler argument executes in interrupt context.

Hardware applicability


Version applicability

oddi: 1, 2, 2mp, 3, 3mp, 4, 4mp, 4, 5, 5mp, 6, 6mp

SVR5 DDI compatibility

See ``Non-Maskable interrupts (NMI)'' in HDK Technical Reference for information about handling non-maskable interrupts in DDI drivers.



``Non-Maskable interrupts (NMI)'' in HDK Technical Reference


The following example shows how an NMI handler may be registered:
   #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. */ }

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 5 HDK - June 2005