How do I disable non maskable interrupts programmatically?

"with external circuitry" means that on the board there are gates before the NMI pins of the processor chip and if these gates are turned off (closed), no interrupt signals will reach the processor chip's NMI pins.

The outb calls probably activate/deactivate these gates.

NMI means non-maskable and it means you cannot disable them with software only.


The CPU has a Non-Maskable Interrupt (NMI) pin (or hardware equivalent) that is used to trigger an NMI. There is external circuitry (or hardware equivalent) to prevent NMIs from reaching the CPU. Since the 80286 the mechanism used was through IO ports associated with the CMOS/Realtime Clock(RTC) controller. This same mechanism is still mimicked in hardware today.

The CMOS/RTC ports are 0x70 and 0x71. Port 0x70 is used to select a CMOS/RTC address to read or write from. The top 2 bits of the CMOS/RTC address don't form part of the actual address. The top most bit was re-purposed to be the NMI toggle. If you write a byte to port 0x70 where bit 7 (most significant bit) is set, NMI is disabled. If you write a value where bit 7 is clear then NMIs are enabled.

The inb and outb functions are C wrappers around the low level IN (byte) and OUT (byte) instructions. These instructions read and write to the IO port space. This C code from NMI_enable:

outb(0x70, inb(0x70) & 0x7F);

Is the equivalent of:

uint8_t curbyte = inb(0x70);   /* Read current port 0x70 state */
outb(0x70, curbyte & 0x7F);    /* Update current state by clearing NMI bit */
                               /* and write new value back to port 0x70 */

0x7f is the bit pattern 01111111. ANDing 01111111 with the current byte clears the top most bit (enabling NMI).

This C code from NMI_disable:

outb(0x70, inb(0x70) | 0x80);

Is the equivalent of:

uint8_t curbyte = inb(0x70);   /* Read current port 0x70 state */
outb(0x70, curbyte | 0x80);    /* Update current state by setting NMI bit */
                               /* and write new value back to port 0x70 */

0x80 is the bit pattern 10000000. ORing 10000000 with the current byte sets the top most bit (disabling NMI).