[更新的问题,因为GIC v2有3个寄存器ACK,EOIR,DIR]
这是我需要其他人澄清并说明以下序列正确的最基本问题。
在以下拱门中,
[Core] ----- [ Interrupt Controller ] --Level Triggered -- [Device]
注意:在GICv2实现中,将GICC_CTLR.EOImode设置为1可分离优先级丢弃和中断取消激活操作。
参考:3中断处理和优先级(ARM IHI 0048B.b ID072613)
现在需要确认的点数,
现在可能有两种情况。
基于(A)或(B)
Q1。中断是否会再次从中断控制器提升到核心?
现在interrupt nesting如何处理这种情况?
答案 0 :(得分:0)
Q1。中断是否会再次从中断控制器升级到核心?
当然,它会被重新提升。这是电平触发中断的属性。中断控制器中没有 state 。很难判断中断是否已被重新提升或是否持续存在。特别是,中断可能已经被服务了很短的时间,并且GIC不会看到高 - 低 - 高转换来区分新的和现有的中断源。
Q2。如果(e)核心直接执行(g)后,中断将再次从中断控制器提升到核心
这似乎与上述问题相同。可能有一个电平触发的设备,其中服务设备使中断线保持高电平。例如,中断可能 FIFO不为空。如果 FIFO 有两个条目,则第一次读取可能无法清除中断。
请参阅维基百科的level triggered interrupts。 维修此设备后...... 。您必须始终使用级别触发的中断为设备提供服务。中断控制器(GIC)不知道外围设备如何工作。将假设置于控制器中将限制其使用。
现在,在这种情况下,如何中断嵌套工作。
目前尚不清楚嵌套是什么。例如,使用上面的 FIFO 示例,您可以在每次读取后读取设备的条目数或读取并检查中断状态。当读取清除中断时,可以重新启用中断源。
单独的IRQ源的嵌套是标准的。在步骤 f ,IRQ服务例程必须为设备提供服务,直到不驱动该级别。可以读取0x300-0x304处的irqActive位以确定IRQ服务是否已完成。然后水平触发ISR返回。如果它在任何时候被抢占,控制器将检测到新的电平源,或者ISR将继续为外围设备提供服务。
如果在最后一步(或之前)发生了附加服务项,则会出现背对背级中断。这将是频繁的,因为在同一时间段内必须发生多个中断源。这是典型的中断嵌套。整个系统将更加繁忙,但延迟会更好。
部分 3.2.1优先级丢弃和中断取消激活具有以下步骤来禁用级别中断,
当确定已对实际设备进行维修时,将重新启用中断。如果您希望仅允许更高优先级的中断,则对EOIR
的写入将被延迟到ISR结束;较高优先级的中断自然会抢占级别中断。
修改强>
现在可能有两种情况。
一个。内核屏蔽GIC上的特定中断,但在设备上不执行任何操作以清除设备上的中断。核心启用其中断
如果中断被屏蔽,它将不会重新断言。
B中。核心设置GICC_EOImode = 1,并将中断ID写入EOIR。核心启用其中断
编写 EOIR 将从活动+待处理转换为活动,并且中断将重新启动(如果你正在做的是&# 39; B')
在interrupt nesting中,Linux自然会完成图片的第一部分。当有两个活动ISR(右侧)时,这是一个可选配置;在&IRQ-k'期间,必须重新启用中断。这需要更多的堆栈,你必须修改Linux版本。
编辑2: GICC_CTRL.EOImode =1
令人困惑。这将中断服务与优先级丢弃部分分开。如果您有关键部分和非关键部分的中断,则可以分离阶段。在关键部分之后写入 EOIR 以降低优先级。然后 DIR 寄存器表示中断服务已完成。我总是离开GICC_CTRL.EOImode=0
,因为我认为这不是必需的。手动文档是从中断控制器的角度编写的,而不是使用它的CPU(因此也是程序员的心理模型);取消激活表示当前的 IRQ 行,而不是一般的中断。