目录
一、当中断变为pending时发生了什么?
二、中断响应
三、虚假的中断
四、运行优先级&抢占
五、结束中断
六、检查系统的当前状态
6.1最高优先级等待中断和运行优先级
6.2单个INTID的状态
前面的文章介绍了当中断源断言时,中断如何从 inactive状态转到pending状态。这通常是由于一个外围设备断言了一个专用的中断信号。当中断挂起(pending)时,中断控制器(gic)决定是否将中断发送到已连接的PE之一。中断控制器选择的PE,取决于以下设置:
前文描述了如何将INTID分配给一个组(Group 0,Secure Group1 or Non-secure Group 1)。对于每个组,在Distributor和CPU接口中都有一个Group bit。作为已禁用组的成员的中断不能向PE发出信号。
单独禁用的中断可能会挂起,但不会转发到PE。
根据中断的类型,中断控制器必须决定哪些PE可以接收到中断。
对于SPI,这是由GICD_IROUTERn控制的。SPI可以针对一个特定的PE,或任何一个已连接的PE。
对于LPI,如果集成了ITS,路由信息来自ITS。
PPIs是特定于一个PE的,并且只能由该PE来处理。
对于SGIs,原始PE定义了目标PE的列表。
每个PE在其CPU接口中都有一个优先级掩码寄存器(ICC_PMR_EL1)。此寄存器设置了将中断转发到该PE所需的最小优先级。只有优先级高于寄存器中的值的中断才会向PE发出信号。
运行优先级:如果PE尚未处理中断,则运行的优先级是空闲优先级(0xFF)。只有优先级高于运行优先级的中断才能抢占当前中断。
CPU接口有两个IAR寄存器。读取IAR将返回INTID,并向前推进中断状态机。在一个典型的中断处理程序中,处理中断的第一步是读取其中一个IAR。
INTID范围1020到1023如何被保留用于特殊用途。这些初始属性可以通过读取IAR返回,并指示异常处理中的特殊情况。
INTID = 1023,当轮询IAR时,此值表示没有可供响应的中断。当中断触发后又撤回时,可以向寄存器写入这个ID,表示一个虚假的中断。
PMR设置了一个中断必须被转发到一个特定的PE的最小优先级。GICv3体系结构具有运行优先级的概念。当PE响应一个中断时,其运行优先级就是该中断的优先级。当PE写入其中一个EOI寄存器时,当前运行优先级返回到其以前的值。
当前的运行优先级将在CPU接口中的(ICC_RPR_EL1)寄存器上报。
在考虑优先级抢占时,运行优先级的概念是很重要的。当高优先级中断指向已经在处理低优先级中断的PE时,就会发生抢占。抢占为软件带来了一些额外的复杂性,但是它可以防止低优先级中断阻塞对高优先级中断的处理。
在某些情况下,可能不需要或不需要抢占。GICv3体系结构允许通过二进制点寄存器(ICC_BPRn_EL1)来控制抢占所需的优先级差异。
(ICC_BPRn_EL1)寄存器将优先级分为两个字段,组优先级和子优先级:
对于抢占,只考虑组优先级位,忽略子优先级位。例如,考虑以下三个中断:
INTID A has priority 0x10,
INTID B has priority 0x20,
INTID C has priority 0x21,
在这种情况下,我们决定了:
A可以抢占B或C。·
B不能抢占C,因为B和C有相似的优先级。
为了实现这一点,组和子优先级之间的划分可以设置为N=4:
通过这种分割,B和C现在被认为对抢占具有相同的优先权。但是,A仍然有更高的优先级,因此它可以抢占B或c。
注意:抢占要求编写中断处理程序支持嵌套。
当中断被处理时,软件必须通知中断控制器中断已经被处理,以便状态机可以转换到下一个状态。GICv3体系结构将其视为两个任务:
这意味着将运行优先级放回执行中断之前的值。(IDLE)
这意味着要更新当前正在处理的中断的状态机。通常,这将是从Active状态到Inactive状态的转换。
在GICv3体系结构中,Priority drop和Deactivation可以同时发生或单独发生。这是由 ICC_CTLR_ELn.EOImode的设置决定的。
Group 0 中断写ICC_EOIR0_EL1,Group 1中断写ICC_EOIR1_EL1,来同时执行priority drop和deactivation。这个模型通常用于简单的裸机环境。
Group 0 中断写ICC_EOIR0_EL1,Group 1中断写ICC_EOIR1_EL1,来执行priority drop。通过单独写ICC_DIR_EL1来执行deactivation。此模式通常用于虚拟化目的。
在写入这些寄存器时,软件必须写入INTID。
顾名思义,最高优先级挂起中断寄存器(ICC_HPPIR0_EL1 & ICC_HPPIR1_EL1)上报此PE的最高优先级挂起中断的INTID。这在不同的PE上可能会有所不同。例如,因为SPI的路由设置不同而优先级不同。运行优先级在(ICC_RPR_EL1)上报。
Distributor提供了指示每个SPI的当前状态的寄存器。同样地,Redistributor提供了指示其所连接PE的PPIs和SGIs状态的寄存器。这些寄存器还可以将一个中断移动到一个特定的状态。这可能很有用,例如,对于测试配置是否正确,而不需要外围设备断言中断。有单独的寄存器来报告active状态和pending状态。下表列出了active状态寄存器。Pending状态寄存器具有相同的格式
注意:当启用了亲和路由时,GICD_ISACTIVER0和GICD_ICACTIVER0被视为保留值0。这是因为GICD_ISACTIVER0和GICD_ICACTIVER0对应于0-31的INTIDs,而INTID = 0-31是按每个PE备份(banked),并通过每个PE的Redistributor上报。
注意:在非安全状态下执行的软件无法看到组0或安全组1的状态中断,除非GICD_NASCRn或GICR_NASCRn允许访问。