每一个 error-reporting register bank都含有
IA32_MCi_CTL, IA32_MCi_STATUS, IA32_MCi_ADDR, 和
IA32_MCi_MISC 四个MSR。
IA32_MCG_CAP[7:0]指定了
bank的数量。第一个
error-reporting register (IA32_MC0_CTL)的起始地址为400H
1. IA32_MCi_CTL MSRs
IA32_MCi_CTL MSR 控制着某个(某组)硬件单元产生的error的
error reporting。64个标志位
(EEj)的每一位代表一种可能的error,设定
EEj的相应标志来使能相关error的
reporting,清除了就关闭相应error的
reporting功能。如果处理器没有实现某些error,那么是不会改变相应位的。
IA32_MCi_CTL如下所示
2. IA32_MCi_STATUS MSRS
如果VAL(vaild flag)被设置了,那么每一个
IA32_MCi_STATUS MSR都包含了一个
machine-check error的相关信息。软件通过显式地写入全0来清除
IA32_MCi_STATUS MSRs。对任何位写入1将会导致#GP
其中
MCA (machine-check architecture) error code field, bits 15:0 — 当
machine-check error被探测到,这里就写入了通用架构相关的
machine-check error code。既然是架构相关,那么所有种类的CPU都会理解这些error code的含义。注意这里也会保证和IA32的兼容。
Model-specific error code field, bits 31:16 — 指定了
model-specific error code,这种error code是每种CPU都有不同解释的,唯一的标识了一种错误
Reserved, Error Status, and Other Information fields, bits 56:32 — 这部分很乱,主要是Other Information用来提供额外信息和error发生的counter累加器用来判断是否超过阀值需要告警,
有兴趣的可以参考SDM。 最重要的是两个位。当
IA32_MCG_CAP[11] = 1时,
S (Signaling) flag, bit 56 为1 表示需要针对该error report需要发送#MC,
AR (Action Required) flag, bit 55为1表明是否需要软件采用recovery Action,这也是区分SRAR和SRAO的地方。
PCC (processor context corrupt) flag, bit 57 — 当设定了,就意味着整个处理器都被探测到的错误污染了,没法进行修复或者重新执行指令。当没有设置,表明处理器当前还没有被错误污染,软件有可能通过恢复动作让系统正常运行
ADDRV (IA32_MCi_ADDR register valid) flag, bit 58 — 当设定了,就代表
IA32_MCi_ADDR寄存器中含有发生错误时候的内存地址
MISCV (IA32_MCi_MISC register valid) flag, bit 59 — 当设定了,表明
IA32_MCi_MISC寄存器中包含了错误的额外信息
EN (error enabled) flag, bit 60 — 当设定了,就说明了改错误在
IA32_MCi_CTL寄存器中对应的
EEj位被设定了
UC (error uncorrected) flag, bit 61 — 当设定了,表明处理器不能依靠硬件来矫正这个错误(如多bit的内存错误),当清除则该错误可以被处理器硬件纠正(如单bit内存错误)
OVER (machine check overflow) flag, bit 62 — 当设定了,就表明发生了MC嵌套。也就是说
error-reporting register bank
里面还有着前一个错误信息(VAL=1,软件正在处理)时,另外一个错误就发生了。处理器会设置OVER位,软件负责清除。通常按照一定的规则对错误内容进行覆盖。通常来说,
enabled errors 覆盖 disabled errors,
uncorrected errors 覆盖
corrected errors。
Uncorrected errors不会覆盖前一个有效的
Uncorrected errors
VAL (IA32_MCi_STATUS register valid) flag, bit 63 — 当设定了,就意味着
IA32_MCi_STATUS中的错误信息是有效的,系统软件正在处理。当该位被设定时,处理器按照覆写规则来处理更多的错误信息。处理器负责设定VAL,系统软件负责清除这个位(当处理完成)。覆写规则很操蛋,筒子们自己看SDM吧
3. IA32_MCi_ADDR MSRs
当
IA32_MCi_STATUS.
ADDRV = 1的时候,
IA32_MCi_ADDR中含有产生本次错误的指令或数据内存的内存地址。当
IA32_MCi_STATUS.
ADDRV
= 0,任何读写IA32_MCi_ADDR的动作都会导致#GP
根据遇到的错误不同,返回的地址可能是一个段内偏移量、线性地址或物理地址。可以通过写入全0来清除该寄存器,如果在任何一位写入1都会导致#GP
4. IA32_MCi_MISC MSRs
当
IA32_MCi_STATUS.
MISCV = 1时,
IA32_MCi_MISC MSR中包含了本次
machine-check error的额外信息。如果
IA32_MCi_STATUS.
MISCV = 0,任何读写
IA32_MCi_MISC MSR都会导致#GP
软件通过显示的写入全0来清除该寄存器,当写入任意一位1都会导致#GP
如果
MISCV =1 且 IA32_MCG_CAP[24] = 1,
IA32_MCi_MISC_MSR的定义如下图所示,用来支持软件恢复
uncorrected errors
Recoverable Address LSB (bits 5:0): 表明error address的最低有效位。例如,
IA32_MCi_MISC.
LSB =
01001b (9), 那么
IA32_MCi_ADDR
中记录的错误地址[43:9]是有效的,[8:0]直接忽略。如果是12,那么就说明页面是4K对其的
Address Mode (bits 8:6):
IA32_MCi_ADDR中记录的地址的类型,支持的类型如下所示
Model Specific Information (bits 63:9): 非架构相关的
5. IA32_MCi_CTL2 MSRs
IA32_MCi_CTL2 MSR提供了对于
corrected MC error发送信号能力的可编程接口,也同时意味着要求
IA32_MCG_CAP[10] = 1。系统软件检查每个bank的
IA32_MCi_CTL2
当
IA32_MCG_CAP[10] = 1,每bank的
IA32_MCi_CTL2 MSR都存在。但是对于
corrected MC error不一定是每个bank都发送信号的,需要检查相应bank的标志位。
寄存器如下所示
Corrected error count threshold, bits 14:0 — 系统软件负责初始化这个域,然会会同
IA32_MCi_STATUS[52:38]比较。当
IA32_MCi_STATUS[52:38]等于阀值的时候,就会发送一个
overflow事件到APIC的
CMCI LVT entry(
APIC_BASE+02F0H
)。如果CMCI功能没有使能,但是
IA32_MCG_CAP[10] = 1,那么这个域总是0
CMCI_EN (Corrected error interrupt enable/disable/indicator), bits 30 — 系统软件设定这个位来使能发送
corrected machine-check error interrupt (CMCI) 的特性。如果某bank的CMCI没有使能,
但是
IA32_MCG_CAP[10] = 1,写1到这个bit会返回0,这个BIT也就意味着对应bank的CMCI是否被支持。
某些
微架构作为
corrected MC errors的源,肯能被多个逻辑处理器共享,那么这个bank的内容也就会被共享,软件需要负责
IA32_MCi_CTL2 MSR内容在多个逻辑处理器间的一致性问题
在系统重启后
IA32_MCi_CTL2 MSRs统统被清零
6. IA32_MCG Extended Machine Check State MSRs
对于Intel志强处理器,当
IA32_MCG_CAP.
MCG_EXT_P = 1 时,
实现了更多的扩展
machine-check state MSRs,可以记录更加详细的错误信息。
IA32_MCG_CAP.
MCG_EXT_CNT表明了这些扩展寄存器的数量。这些扩展寄存器如下所示
32位下的扩展寄存器
64为下的扩展寄存器
这些寄存器通过写入全零来进行清除,写入其他值会导致#GP。当硬重启时寄存器被清除(
power-up or RESET),当软重启这些寄存器的值保留(
INIT reset)
关于兼容性我就不讲了,有兴趣的参考Intel的SDM
参考文章