Non Maskable Interrupt(NMI)不可屏蔽中断 学习总结

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 00:26   204   0

CRBNMI.C里面有function

VOID CRBGpi8SmiHandler (

IN EFI_HANDLE DispatchHandle,

IN EFI_SMM_GPI_DISPATCH_CONTEXT *DispatchContext )

{

// Porting if needed

}

为什么通过相应的GPIO会产生一个SMI信号?

l The corresponding GPI must be routed in the GPI_ROUT register to cause an SMI.

l MmPci32(LPC_BUS, LPC_DEVICE, LPC_FUNC, ICH_REG_LPC_GPI_ROUT) |= 1 << (2 * GpiNo);

将配对的GPI在GPI_POUT中设置,SMI信号就可以rout到相应的GPIO

软件触发NMI的流程:

在SMI的Handle处理程序中设置相应的寄存器来触发NMI,流程如下(参考SBSMI.C里的SBGpi14SmiHandler() ):

TCO_BASE_ADDRESS=0x0460

ICH_IOREG_TCO1_CNT=0x08

ICH_IOREG_TCO1_STS=0x04

ALIASED_NMI_EN_PORT=0x74

NMI_EN_PORT=0x70

1、 Read the NMI2SMI_EN bit, save it for future restore:

Save_Nmi2Smi_En = IoRead8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1);

2、 Set the NMI2SMI_EN bit to 0

Data8 = (UINT8)(Save_Nmi2Smi_En & 0xFD);

IoWrite8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1, Data8);

3、 Enable NMI_EN

Save_Port70 = IoRead8(ALIASED_NMI_EN_PORT);

Data8 = (UINT8)(Save_Port70 & 0x7F);

IoWrite8(NMI_EN_PORT, Data8);

4、 Set NMI_NOW = 1

Data8 = IoRead8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1);

Data8 = (UINT8) (Data8 | 0x01);

IoWrite8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1, Data8);

5、 Clear NMI_NOW = 0 by writing 1 to NMI_NOW bit

Data8 = IoRead8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1);

Data8 = (UINT8) (Data8 | 0x01);

IoWrite8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1, Data8);

6、 Restore NMI2SMI_EN

IoWrite8(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_CNT + 1, Save_Nmi2Smi_En);

7、 Clear the MCHSERR_STS bit, bit 12

Data16 = IoRead16(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_STS);

Data16 = (UINT8) (Data16 | 0x1000);

IoWrite16(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_STS, Data16);

8、 Clear the NMI2SMI_STS bit if set

Data16 = IoRead16(TCO_BASE_ADDRESS + ICH_IOREG_TCO1_STS);

if (Data16 & 0x0001) {

// check port 0x61

Data8 = IoRead8(NMI_SC_PORT);

if (Data8 & 0x80) {

Data8 = IoRead8(NMI_SC_PORT);

Data8 = (UINT8) (Data8 | 0x04);

Data8 = (UINT8) (Data8 & 0x0F);

IoWrite8 (NMI_SC_PORT, Data8);

Data8 = (UINT8) (Data8 & 0x0B);

IoWrite8 (NMI_SC_PORT, Data8);

}

}

9、 Restore NMI_EN

IoWrite8(NMI_EN_PORT, Save_Port70);

NMI_EN是从0x74端口读,从0x70端口写

对怎样执行NMI中断处理程序的理解

当NMI被触发以后,interrupt controller(8259)会将NMI的中断向量(vector=02h)发送给CPU,CPU就会根据vector在中断向量表(interrupt table)中去寻找对应的NMI处理程序。在source code中找到这么一段代码:

PUBLIC CsmOemInterrupts

PUBLIC CsmOemInterruptsEnd

CsmOemInterrupts LABEL WORD

mBODY_ID_AND_TBL_CSM_ENTRY_NEAR 00002h, OEMINT2

mEND_TBL_CSM CsmOemInterrupts

mBODY_ID_AND_TBL_CSM_ENTRY_NEAR和mEND_TBL_CSM都是宏定义,它们表示在memory中分配了一段interrupt table的地址空间,范围是0000h——FFFFh。OEMINT2是处理NMI中断的proc,被定义在interrupt table中的02号位置处。这段code就表明了NMI的中断处理程序是OEMINT2。OEMINT2通过ELINK在CsmOemInterrupts执行后被调用,CsmOemInterrupts本身也是通过ELINK被调用,但不清楚何时被调用,source code 里面定义的调用顺序是InvokeOrder = TableFunction,找不到相关的解释,不知是否可理解成在CPU接到中断请求,准备查找中断向量表时调用。

硬件触发NMI的流程

1、 将对应的GPIO(GPIO9)设置成GPI

2、 将GPIO9的寄存器GPI_INV设置成0(上升沿触发)或1(下降沿触发)

3、 将GPI_ROUT寄存器routed到可触发GPIO9的NMI的功能

4、 将GPI_NMI_EN寄存器中GPIO9匹配的位置1

5、 将GPI_NMI_STS寄存器中GPIO9匹配的位写1清零

CPU怎样知道SMI被触发?

以产生GPIO14上的SMI为例。在DXE阶段,会为SMI做好准备,主要是在InSmmFunction()做两个动作,一是pBS->LocateProtocol(),二是pGpiDispatch->Register(),它的函数原形是EfiSmmSwRegister(),其作用就是注册一个SMI,具体过程是通过增加一个链表的节点来实现。注册好的SMI节点会存放在SMRAM这段地址空间中(30000h+8000h),SMRAM这段空间在非SMI模式下时当做常规内存使用,在SMI模式下,CPU就会在SMRAM这段空间中取得SMI的资源。注册了以后,CPU是怎样知道是GPIO14产生的SMI呢?当GPIO14的SMI被触发后,系统会进入SMM模式。在SMM模式中,CPU就会去寻找时哪个GPI产生的SMI。InstallChildDispatchHandler这个Driver的入口函数中,会调用InitSmmHandler()这个函数,这个函数中又会调用pSmmBase->RegisterCallback(pSmmBase, ImageHandle, ChildDispatcher, FALSE, FALSE),其中参数ChildDispatcher也是函数,CPU会通过ChildDispatcher()里的GetContextGpi()来判断是否有GPI产生了SMI中断,如有SMI中断的话,就将其中的gSmiContext.GpiSource 设置为TRUE,在ChildDispatcher()的另外一个地方调用if (gSmiContext.GpiSource)作判断,如为真,则执行EfiSmmGpiDispatch(&gSmiContext.GpiContext),在这个函数中有这么两条语句 if (Link->Context.GpiNum & Context->GpiNum)

Link->Function(Link, &Link->Context);

Link->Function()在注册的时候EfiSmmSwRegister()中赋值,其值就是设置触发NMI相关寄存器的SBGpi14SmiHandler()函数,经过这个过程以后,NMI就会被触发。

转载于:https://www.cnblogs.com/wudibuzaijia/p/8556572.html

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP