Non Maskable Interrupt

来自osdev
跳到导航 跳到搜索

不可屏蔽中断 (NMI-Non-Maskable Interrupt)是硬件驱动的中断,与PIC中断非常相似,但NMI要么直接进入CPU,要么通过另一个控制器(例如ISP)---在这种情况下,它可以被屏蔽。

关于

NMI用于RAM错误和不可恢复的硬件问题。 对于较新的计算机,可以使用机器检查异常和(或)SMI来处理这些事情。 对于最新的芯片组 (至少对于英特尔而言),还有一堆TCO内容 (“total cost of ownership”) 被捆绑在其中 (具有特殊的 “TCO IRQ” 和与SMI/SMM的连接等)。 所有TCO设备都可以连接到板载(onboard)以太网控制器,并且(至少部分)用于远程监控系统。 不幸的是,芯片组文档没有说明BIOS通常如何配置芯片组,并且芯片组本身在每种情况下都支持几个不同的选项。 例如,对于RAM错误,它可以由芯片组本身处理,它可以生成SMI (BIOS/SMM处理程序在软件中进行 “RAM清理”),它可以生成 “TCO中断” 等。 如果你把所有这些加起来,主板(甚至是具有相同芯片组的主板)之间可能会出现完全不同的巨大复杂混乱(TCO+SMI+SMBus+Northbridge(北桥)+PCI总线/控制器+PCI到LPC桥+天知道什么)。

这个故事的简短版本是,NMI实际上只有两个原因。 第一个原因是硬件故障。 第二个原因是“看门狗定时器”,它可以用来检测内核本身何时锁定(有时还用于更准确的分析,因为它允许在禁用IRQ时对EIP进行采样)。

如果硬件故障导致了NMI,则无法确定是哪一块硬件导致了NMI。 在这种情况下,您可能想通知用户发生了硬件错误,然后内核应该关闭/重置机器。

对于看门狗定时器,必须首先由操作系统设置。 即使芯片组本身没有专门的看门狗定时器(例如,在I/O APIC中将PIT、RTC/CMOS IRQ或HPET IRQ设置为“NMI,发送到所有CPU”),实际上也可以做到这一点。 在这种情况下,你希望看门狗定时器是快速的 (即没有缓慢的硬件任务切换和缓存刷新),你也希望所有的cpu共享同一个定时器,这意味着所有的cpu将在同一时间接收相同的IRQ。

作为替代方案,您也可以使用本地APIC的计时器或“每CPU”看门狗计时器的性能监视计数器溢出。

用法

当发生内存奇偶校验错误时,内存模块将启用NMI (设置为高)。

在长时间禁用NMI和PIC时要小心(请注意,看门狗定时器通常使用NMI)。

在XT上,可以通过在I/O端口0xA0上设置位7,可以屏蔽NMI。 在AT上,可以通过在I/O端口0x70上设置位7,可以屏蔽NMI。 该端口使用I/O端口0x70的位0到6与CMOS RAM索引寄存器共享。 CMOS RTC期望在对索引端口0x70执行任何写入操作后从数据端口0x71读取或写入数据端口0x71,否则可能进入未定义状态。 在访问索引和数据寄存器之间可能还需要 I/O 延迟。 索引端口0x70可能是一个只写端口,读取时总是返回0xFF。 因此,下面用于保留CMOS索引寄存器的位0至6的位掩码可能无法工作,也无法从端口0x70检索NMI掩码的当前状态。

 void NMI_enable() {
    outb(0x70, inb(0x70) & 0x7F);
    inb(0x71);
 }

 void NMI_disable() {
    outb(0x70, inb(0x70) | 0x80);
    inb(0x71);
 }

发生NMI时,您可以分别检查I/O地址0x92和0x61处的系统控制端口A和B,以指示导致错误的原因:

系统控制端口A(System Control Port A)(0x92)布局:

描述
0 备用热重置
1 备用gateA20
2 保留
3 安全锁
4* 看门狗定时器状态
5 保留
6 硬盘2活动
7 硬盘1驱动器活动

系统控制端口B(System Control Port B)(0x61)

描述
0 定时器2绑在扬声器上
1 扬声器数据开启
2 奇偶校验启用
3 通道检查启用
4 刷新请求
5 定时器2输出
6* 通道检查
7* 奇偶校验

重要位用 “*” 表示。 通道检查位(Channel Check bit)表示总线故障,可能是由调制解调器、声卡、NIC等外围设备造成的,而奇偶校验位表示内存读写故障。

de:Non Maskable Interrupt