全部博文(44)
分类:
2010-03-08 11:06:59
收到来自IOAPIC的中断消息后,LAPIC会将该中断交由CPU处理。和IOAPIC比较,LAPIC具有更多的寄存器以及更复杂的机制。但对于处理来自IOAPIC的中断消息,最重要的寄存器还是IRR、ISR以及EOI。
图1-4显示了x86平台上,IRR和ISR的格式:
图1-4 IRR、ISR构成
与PIC中的IRR、ISR不同的是,LAPIC的ISR、IRR均为256bit寄存器,对应x86平台上的256个中断vector,其中0~15为架构预留。
u IRR:功能和PIC的类似,代表LAPIC已接收中断,但还未交CPU处理。
u ISR:功能和PIC类似,代表CPU已开始处理中断,但还未完成。与PIC有所不同的是,当CPU正在处理某中断时,同类型中断如果发生,相应的IRR bit会再次置一(PIC模式下,同类型的中断被屏蔽);如果某中断被pending在IRR中,同类型的中断发生,则ISR中相应的bit被置一。这说明在APIC系统中,同一类型中断最多可以被计数两次(想不通什么意思?想不通就联想一下Linux可信信号)。超过两次时,不同架构处理不一样。对于Pentium系列CPU和P6架构,中断消息被LAPIC拒绝;对于Pentium4和Xeon系列,新来的中断和IRR中对应的bit重叠。
笔者:上图还有个TMR寄存器,即Trigger Mode Register,用于表示当前正在处理中断的触发模式。1为level,0为edge。对于level触发的中断,当软件写EOI时,会被广播到所有IOAPIC,消息中含有中断的vector,IOAPIC收到后检查自己的PRT表,把相应RTE的Remote IRR位清零。
对于IRR,x86 spec说:“当CPU准备处理中断时,IRR中最高优先级的bit被清零,ISR中对应bit被置一”。这样说不能算错,但至少不准确。根据《Multi-Processor Computer System With Interrupt Controllers Providing Remote Reading》一文中APIC的实现,只有对于edge触发的中断,ISR对应bit置一时IRR相应 bit才清零。对于level触发,IRR中的bit保留到软件写EOI,LAPIC收到IOAPIC发出的Level-deassert消息后才清零。
如果你仔细看了前面关于Remote IRR的介绍,此时一定会产生一个疑问。这里说同类型中断发生两次,会同时Pending在ISR和IRR的对应bit中。问题是,前面Remote IRR的异或逻辑保证了在写EOI前,新的中断不会发过来啊?呵呵,或许你想到答案了,这种pending两次的机制,只对edge触发中断有效。
与PIC一样,LAPIC同样需要软件写EOI来知会中断处理的完成,不同的是,LAPIC中的EOI是一个32bit寄存器,如下图:
图1-5 EOI寄存器格式
X86架构中,对EOI写0表示中断处理完成。由上述几个寄存器相互配合,一个典型的LAPIC中断处理流程是:
对于Pentium4、Xeon系列:
1. 通过中断消息的destination field字段,确定该中断是否是发送给自己的。
2. 如果该中断的delivery mode为NMI、SMI、INIT、ExtINT、SIPI,直接交由CPU处理。
3. 如果不为2)中所列的中断,置一IRR中相应的bit。
4. 当中断被pending到IRR或ISR中后,根据TPR和PPR寄存器,判断当前最高优先级的中断是否能发送给CPU处理。
5. 软件写EOI通知中断处理完成。如果中断为level触发,该EOI广播到所有IOAPIC(见前)。NMI、SMI、INIT、ExtINT、SIPI类型中断无需写EOI。
对于Pentium系列和P6架构:
1. 确定该中断是否由自己接收。如果是一个IPI,且delivery mode为lowest priority,LAPIC与其它LAPIC一起仲裁该IPI由谁接收。
2. 若该中断由自己接收,且类型为NMI、SMI、INIT、ExtINIT、INIT-deassert、或MP协议中的IPI中断(BIPI、FIPI、SIPI),直接交由CPU处理。
3. 将中断pending到IRR或ISR,若该已有相同的的中断pending到IRR和ISR上,拒绝该中断消息,并通知IOAPIC “retry”。
4. 同Pentium4、Xeon系列流程。
5. 同Pentium4、Xeon系列流程。