电平触发中断处理和嵌套中断

[GIC v2更新的问题有3个寄存器ACK,EOIR,DIR]

这是我需要别人澄清和说明以下顺序是正确的最基本的问题。

在下面的曲拱中,

[Core] ----- [ Interrupt Controller ] --Level Triggered -- [Device] 
  • 一个。 设备提高水平并通知中断控制器
  • 湾 中断控制器触发中断的核心。 (假设核心的中断被允许)
  • C。 假设中断控制器是GIC(与ARM一起使用)并且有3个寄存器
    1. – 中断禁用(GICC_DIR)
    2. – 中断ACK(返回IRQ号),(GICC_IAR)
    3. – 中断寄存器结束(GICC_EOIR)

注意:在GICv2实现中,将GICC_CTLR.EOImode设置为1会分离优先级丢弃和中断禁用操作。
参考:3中断处理和优先级(ARM IHI 0048B.b ID072613)

现在需要确认的几点,

  • d。 直到核心没有确认中断获得IRQ,中断保持挂起,并且设备中断线路到中断控制器电平高
  • 即 核心禁止其中断。 核心ACK是否得到IRQ,中断线没有改变。

现在可以有两种情况。

  • A.核心屏蔽GIC上的特定中断,但在设备上什么都不做,这将清除设备上的中断。 核心启用其中断
  • B.内核设置GICC_EOImode = 1,并将中断ID写入EOIR。 核心启用其中断

基于(A)或(B)

Q1。 中断是否会从中断控制器再次提升到核心?

现在怎么会在这种情况下中断嵌套工作呢?

Solutions Collecting From Web of "电平触发中断处理和嵌套中断"

Q1。 中断是否会从中断控制器再次提升到核心?

当然,这将被重新提出。 这是电平触发中断的属性。 中断控制器中没有状态 。 要判断中断是否已经重新产生或者是否持续,将很难确定。 特别是,中断可能已经服务了很短的时间,并且GIC不会看到高 – 低 – 高的转换来区分新的和现有的中断源。

Q2。 如果(e)核心直接做了(g)之后,将中断控制器重新中断到核心

这似乎与上述问题相同。 可能有一个电平触发设备,在维修设备时将中断线路保持在高位。 例如,一个中断可能是FIFO不为空 。 如果FIFO有两个入口,则第一次读取可能无法清除中断。

请参阅维基百科的电平触发中断 。 在维修这个设备之后…… 您必须始终使用电平触发的中断服务设备。 中断控制器(GIC)不知道外设是如何工作的。 假设控制器将限制其使用。

现在在这种情况下如何中断嵌套工作。

目前还不清楚什么是嵌套。 例如上面的FIFO例子中,您可以读取设备的条目数量,或者在每次读取之后读取并检查中断状态 。 当读取清除中断时,可以重新中断中断源。

独立IRQ源的嵌套是标准的。 在步骤f ,IRQ服务程序必须为设备提供服务,直到电平不被驱动。 可以读取0x300-0x304的irqActive位来确定IRQ服务是否完成。 然后等级触发ISR返回。 如果在任何时候被抢占,控制器将检测到新的电平信号源,或者ISR将继续为外设提供服务。

  • 设备上线通知GIC。
  • GIC发信号给ARM内核并跳转到向量。
  • 向量读取GIC中断ACK并跳转到ISR。
  • 级别例程禁用级别IRQ并重新启用中断。
  • 水平例行服务设备,直到irqActive低。 (可能会抢先到其他ISR)。
  • 屏蔽中断,重新启用电平源,并返回给调用者。

如果在最后一步(或之前)发生附加服务项目,则会出现背靠背级别中断。 由于多个中断源在同一时间段内必须发生,所以这会频繁发生。 这是中断嵌套的典型特征。 整个系统会更忙,但延迟会更好。

3.2.1节的优先级下降和中断禁止有以下步骤来禁止级别中断,

  1. 读取IAR – 活动中断的初始读取。
  2. 写EOIR–将其从优先级中删除; 允许较低优先级的嵌套。
  3. 写DIR – 说它已经结束 (或服务)。

当确定实际设备已经被服务时,中断被重新启用。 如果您希望只允许更高优先级的中断,那么写入EOIR将被延迟,直到ISR结束; 更高优先级的中断将自然地预占中断级别。

编辑:

现在可以有两种情况。

A.核心屏蔽GIC上的特定中断,但在设备上什么都不做,这将清除设备上的中断。 核心启用其中断

如果中断被屏蔽,则不会重新置位。

B.内核设置GICC_EOImode = 1,并将中断ID写入EOIR。 核心启用其中断

写入EOIR将从主动+等待状态转换为主动 状态 ,并且中断将会重新启动(如果你正在做的是'B')。

在中断嵌套中 ,Linux自然会做图片的第一部分。 当有两个主动ISR(右侧)时,这是一个可选的配置; 在'IRQ-k'期间,中断必须重新启用。 它需要更多的堆栈来做到这一点,你将不得不修改股票Linux afaik。

编辑2: GICC_CTRL.EOImode =1令人困惑。 这将分离从优先级丢弃部分服务中断 。 如果你有一个关键部分和非关键的中断,你可以分开各个阶段。 在关键部分之后写入EOIR以删除优先级。 然后DIR寄存器说中断服务完成。 我会永远离开GICC_CTRL.EOImode=0因为我不认为这是必要的。 手册文档是从中断控制器的角度编写的,而不是使用它的CPU(因此也是程序员的心智模型)。 去激活意味着当前的IRQ线,而不是一般的中断。