Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
A quote from the Intel manuals, Vol. 3, chapter 9.7.2 "NMI Interrupt Handling":
The NMI interrupt is always enabled (except when multiple NMIs are nested). If the IDT and the NMI interrupt handler need to be loaded into RAM, there will be a period of time following hardware reset wen an NMI interrupt cannot be handled. During this time, hardware must provide a mechanism to prevent an NMI interrupt from halting code execution until the IDT and the necessary NMI handler software is loaded. Here are two examples of how NMIs can be handled during the initial states of processor initialization:
* A simple IDT and NMI interrupt handler can be provided in EPROM. This allows an NMI interrupt to be handled immediately after reset initialization.
* The system hardware can provide a mechanism to enable and disable NMIs by passing the NMI# signal through an AND gate controlled by a flag in an I/O port. Hardware can clear the flag when the processor is reset, and software can set the flag when it is ready to handle NMI interrupts.
OK, so this is BIOS / chipset / motherboard voodoo. I understand why Intel doesn't actually tell the BIOS manufacturers how to do their work, in their CPU manuals, but...
...I still don't have a clue what actually happens if a NMI hits during early startup. I don't like to take chances ("won't happen too often...") so I am asking for experience, additional info links, whatever...
???
Every good solution is obvious once you've found it.
this sounds like the realtime clock is actually responsible for controlling the NMI line (through the mentionned AND gate
If this is the case, it is likely that the rtc takes care of keeping the NMI masked at system boot up, until the BIOS defines an NMI handler and installs a realmode handler for NMI.
iirc, NMI is exception #02 (isn't it ?), or interrupt 2 in realmode. This means that all you have to take care is that a NMI handler is ready in your IDT at the time you issue the lidt [...] command. As interrupts are always taken on an instruction limit, i guess it should handle any case properly (provided that the BIOS did its job too)
its better to read port 0x70 and then OR the byte with 0x80 (128) to enable NMI or if you want to disasble it And the byte with 0x7F (127)
because port 0x70 and 0x71 control other things
and then write the result into port 0x71. This way you will only be changing the bit you really want and not the whole register.