【问题标题】:Level Triggered Interrupt handling and nested interrupts电平触发中断处理和嵌套中断
【发布时间】:2013-10-30 04:22:24
【问题描述】:

[更新问题,因为 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,中断仍处于挂起状态,设备中断线至中断控制器级别高
  • e.核心禁用其中断。 Core ACK 是否获得 IRQ,设备的中断线没有变化。

现在这里可能有两种情况。

  • A.核心屏蔽 GIC 上的特定中断,但在设备上不执行任何操作来清除设备上的中断。核心启用其中断
  • 乙。核心设置 GICC_EOImode =1,并将中断 id 写入 EOIR。核心启用其中断

基于 (A) 或 (B)

第一季度。中断会再次从中断控制器引发到核心吗?

现在interrupt nesting 在这种情况下如何工作?

【问题讨论】:

  • 查看我的 Edit2。我认为GICC_DIR 不是你想的那样。它不会禁用中断,它只是ack - 知道中断。 GIC IAR 或 ACK 更像是传统的 PEND,而 EOIR 是优先级丢弃(EOImode=1)。 DIR 是一个传统的ACK;即,CPU 确认中断完成。在 EOImode=0 的情况下,对 EOIR 的写入会丢弃活动中断的优先级(因此我的优先级较低)并一次性确认。您需要写信给ICENABLERx 或某个分发器寄存器以禁用它并阻止级别IRQ 再次发生。
  • GIC_DIR 是停用中断寄存器

标签: linux arm interrupt


【解决方案1】:

Q1.是否会再次从中断控制器向核心提出中断?

当然,它会被重新筹集。这是电平触发中断的一个属性。中断控制器中没有状态。很难判断中断是被重新提出还是持续存在。特别是,中断服务的时间可能很短,GIC 不会看到 high-low-high 转换来区分新中断源和现有中断源之间的区别。

Q2.如果在(e)核心直接做(g)之后,是否会再次从中断控制器向核心提出中断

这似乎与上述问题相同。可能有一个电平触发设备,服务设备使中断线保持高电平。例如,中断可能是FIFO 非空。如果 FIFO 有两个入口,第一次读取可能不会清除中断。

参见维基百科的level triggered interrupts维修此设备后...。您必须始终使用级别触发中断服务设备。中断控制器 (GIC) 不知道外设是如何工作的。将假设放入控制器将限制其使用。

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

不清楚什么是嵌套。例如,对于上面的 FIFO 示例,您可以读取设备的条目数或在每次读取后读取并检查 中断状态。当 read 清除中断时,可以重新启用中断源。

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

  • 设备升线通知 GIC。
  • GIC 向 ARM 内核发出信号并跳转到向量。
  • Vector 读取 GIC 中断 ACK 并跳转到 ISR。
  • 级别例程禁用级别 IRQ 并重新启用中断。
  • irqActive 低之前将例行服务设备调平。 (可在此处抢占其他 ISR)。
  • 屏蔽中断,重新启用 level 源,并返回给调用者。

如果在最后一步(或之前)发生了额外的服务项目,则会出现背靠背级中断。这种情况很少发生,因为多个中断源必须在同一时间段内发生。这是典型的中断嵌套。整个系统会更忙,但延迟会更好。

3.2.1 优先级下降和中断停用有以下步骤来禁用电平中断,

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

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

编辑:

现在这里可能有两种情况。

A.核心屏蔽 GIC 上的特定中断,但在设备上不执行任何操作来清除设备上的中断。核心启用其中断

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

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

编写 EOIR 将从 active+pending 转换为 active 并且中断将重新触发(如果您所做的只是 'B ')。

interrupt nesting 中,Linux 自然做了第一部分。当有两个活动 ISR(右侧)时,这是一个可选配置;在“IRQ-k”期间,必须重新启用中断。这样做需要更多的堆栈,您将不得不修改现有的 Linux afaik。

Edit2: GICC_CTRL.EOImode =1 令人困惑。这将 interrupt servicedpriority drop 部分分开。如果您有一个关键部分和非关键部分的中断,您可以将这些阶段分开。在关键部分之后写入 EOIR 以降低优先级。然后DIR寄存器表示中断服务结束。我总是会离开GICC_CTRL.EOImode=0,因为我认为这不是必需的。手册文档是从中断控制器的角度编写的,而不是从使用它的 CPU 的角度编写的(因此是程序员的心理模型); deactivated 表示当前的 IRQ 行,而不是一般的中断。

【讨论】:

  • 感谢您的回答,我已经更新了 GICv2 的问题
  • 将等待您的回复。如果您愿意,我们可以保留我们的邮件 ID 并交换知识
猜你喜欢
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多