5289A 中断控制器

    本来想翻译一篇国外的文章, 因为不得不说他比我会写多了, 但貌似高质量的文章背后是将一个问题尽量拖长, 像是写小说似的, 很多东西似乎和想要说的无关, 只是为了流畅易懂来的。 全部翻译下来, 太累了, 干脆摘抄部分关键段落, 剩下的自己写。 而且我也有我自己的理解, 英文全文链接在此: http://blog.chinaunix.net/uid-7190305-id-3014030.html。
An interrupt source, fed into an 8259A, is known as an IRQ – Interrupt Request. An 8259A has 8
IRQ inputs.
The 8 IRQ inputs are fed into an 8 bit Interrupt Request Register (IRR), via some ”rising edge”
detection logic (8 bit Edge Sense Register – ESR).
The 8259A can be told to mask off any of the IRQ. The 8259A has an 8 bit Interrupt Mask Register
(IMR). A one bit in the IMR masks off the corresponding IRQ.
To perform its priority arbitration the 8259A has an 8 bit In Service Register (ISR). In the register
a bit is set to 1 when the corresponding interrupt has been passed to the CPU, and the CPU has not
yet signalled End of Interrupt (EOI)
The CPU interrupt input is known as INTR. The 8259A interrupt output is known as INT, which
is connected to the CPU (wait for it) INTR, or to another 8259A’s IRQ.
The 8 IRR bits are ANDed with the NOT of the IMR, giving the interrupt request input to the
priority arbitration logic. Reading between the lines, there is an INT latch, which is set by the OR
of the bits of (IRR AND NOT IMR) higher than the highest priority bit in the ISR.
The PC sets the 8259A into: Edge Triggered Interrupts  Cascaded (on AT and later) ; Single (on earlier machines)  Not Special Fully Nested (to do with Slave 8259A, see below)  Not Buffered Normal EOI (Not Automatic EOI on INTA)
With this in mind, we will start with the simple cases, and work up.
3.1 One 8259A, All IRQ Unmasked, No Interrupts In Service and None Active.
So we start from the simplest possible quiescent state. The sequence of actions is as follows:
1. The ESR, ISR, IRR and IMR are all zero.
2. IRQ3 becomes active (goes to 1)
3. B3 of the ESR is set to 1
4. B3 of the IRR is set to 1
5. B3 of the IMR is 0, so the IRR B3 is passed to the priority arbitration logic.
6. All bits of the ISR are 0 (no interrupts are in service), so the priority arbitration logic sets
the INT latch – so the INT output is set active.
7. Eventually the CPU issues the first of two INTA cycles. The contents of the IRR are frozen.
The 8279A selects the highest priority IRR (B3) and sets the corresponding ISR (B3).
8. Setting B3 of the ISR clears B3 of the ESR.
9. The CPU issues the second of two INTA cycles. The 8279A issues the interrupt vector
associated with the highest priority ISR (B3). The contents of the IRR are unfrozen.
10. The INT latch is cleared – so the INT output is set inactive.
11. B3 of the IRR is set to 0 (IRR is unfrozen and B3 of ESR is zero).
12. At some time in the future, the CPU issues an EOI command, which clears B3 of the ISR.
IRQ3 can remain active beyond step 10, without generating any further interrupts – because B3
of IRR has been cleared. To produce another interrupt requires IRQ3 to go inactive (0), and then
active (1) again.

3.2 Meaning of ”Edge Triggered Interrupt Mode”
The behaviour of the ESR, IRR and ISR described above is what happens in the famous Edge
Triggered Interrupt Mode.
The purpose is to allow for IRQ signals to be short down/up pulses. When the 8259A is reset
the ESR is set to zero. An upward transition of the IRQ sets the corresponding ESR bit to 1,
which allows the IRQ state to be copied to the IRR – provoking the interrupt. When the interrupt
is acknowledged the ISR bit is set, which resets the ESR bit, which forces the IRR bit to zero –
irrespective of the IRQ. So even if IRQ is still 1 when the ISR bit is cleared, at End of Interrupt,
no further interrupts will be generated.
3.3 What Happens if IRQ Changes with the Interrupt is In Service
It is clear what happens if IRQ does not do any further down/up transitions until after EOI. It is
OK for IRQ to go down before EOI, but going up again is not explicitly described in the manuals.
If a down/up IRQ transition cannot be prevented before EOI, then it can be (reasonably safely)
assumed that this will generate a further interrupt after EOI – provided the IRQ is still up (active,
1) at EOI. Multiple down/up transitions can be assumed to have the same effect.
What happens if there are one or more down/up IRQ transitions followed by a final down transition
before EOI, is also undocumented. I guess that this has no effect. The corresponding IRR bit will
follow the IRQ, but this may be expected to have no effect on the (supposed) INT latch, because
the ISR bit prevents it.
Obviously, it would be safer to ensure that IRQ does not go down and then up again before EOI
(just down is OK). If this is not possible, then I believe the given assumptions to be reasonable –
perhaps MEJ’s boys could help us !

    基本上, 这是那篇文章的实质内容, 我很肯定的说, 作者的理解来自于下面这张图, 下面这张图来自 intel 8259A 手册:

    
 
    以下是我对这图的理解, 和文章作者的理解有不完全相同的部分, 也不知道谁对:
    文章认为, 如果一个中断信号在 INTA cycle 启动后产生, 在 INTA cycle 结束前消失, 则这个中断信号会丢失, 我不觉的会这样。 因为很显然, 图上的 EDGE SENSE LATCH 是一个锁存器。 那么这个信号到来的时候, 无疑会被锁存。
 
    8259A 一个工作周期具体步骤如下:
    1. CPU INTA 周期开始, 8259A 的动作应该是, a) freeze 线拉低, 因此 IRR 锁存; b) 将选择出的最高优先级的中断放入 ISR, 同时 CLR ESR 锁存器
    2. CPU 第二个 INTA 发送到 8259A,  8259A 将中断向量发给 CPU. 而后 freeze 线升高, IRR 锁存结束。
    3. 8259A 收到 EOI 消息, 清除 ISR 中优先级最高的中断位。
 
    首先, 如果一个从不消失的中断信号会不会引起不间断的 CPU 中断(假设没有其他更高优先级的中断在), 答案是会, 因为尽管从不消失的信号没有边缘, 不会锁存, 用不消失的信号本身和锁存的表现一致, 同样若发生了第一个信号消失, 而后出现第二个信号, 则会引起锁存; 从流程看, 只要 INTA 周期结束, 则ESR信号会畅通无阻的到达 priority resolver, 在此只有 ISR 中的最高优先级位能够组织它被发送到 CPU, 而一旦 EOI 收到,  ISR 也不能阻止它了, 于是必然是这个中断再次被发送; 因此, 这里依赖的事实是一个中断信号时长不会任意长, 很可能小于 CPU 对他进行服务的时间长度。 那么, 现在假设在EOI消息到达之前, 这个中断信号消失了, 然后再次出现在线路上, 在物理意义上, 就是某个设备在第一个中断CPU还没有结束服务前发生了第二次中断, 那么其实这两个中断可以被CPU当成一个中断, 因为中断是不会累计的, 第二次中断的意义只在于其发生在CPU结束了第一次的中断服务, 还没有来的及发送EOI的那个窗口期。 但这也不是问题, 这里又分两个情况, a) 在发送 EOI 之后, 这个信号依旧存在 b) 在发送 EOI 之前, 这个信号消失了; 但都没有问题, 原因就是 ESR 的锁存作用会记住曾经发生的信号, 这样就算是线路上信号丢失,  IRR 照样是能够收到这个信号的。
 
   ESR 是在第一次 INTA 的时候 CLR 的, 因此第一次 INTA 之后, 就具备了锁存下一次信号的能力, 而这个时候, 很显然, 第二个INTA 尚未发送, CPU 还没有开始服务第一个中断, 如果这时发生第二次中断, 则其实会在服务第一次中断期间给搞定, 那么之后EOI 收到, 第二次中断再次发送给 CPU, CPU 只是将设备轮询一遍其实会什么事情也不做。
 
    另外, IMR 的锁存应该和 IRR 的相同, 否则在两次 INTA 之前有程序修改了 IMR, 会导致中断丢失, 过程如下:
    1. 第一个 INTA 锁存 IRR
    2. 中断信号消失
    3. ISR 置位, ESR 重置
    3. IMR 被修改
    4. 第二个 INTA 到来, 然而这时 IMR 导致会引起一个伪中断而不是信号刚消失的中断
    5. 因为 ESR 已经重置, 锁存作用消失,  IRR 锁存作用消失时, 之前的信号彻底消失, 不会被 CPU 看到。
 
    有人可能认为, 如果第二次 INTA 到来的时候, 8259A 检索 ISR 而不是 IRR & ~(IMR) 则不会出现这个问题, 因为在这种情况下 IMR 的修改根本不会被 8259A 注意到; 但如果 IMR 在 ISR 置位前, INT 信号发出后被修改(INT 也是一个锁存器), 还是会出这个问题。
    错了错了,  IMR 在 ISR 置位前, INT 信号发出后被修改 也是没问题的, 因为这个时候 IRR 还么有锁存呢
原文地址:https://www.cnblogs.com/zylthinking/p/2886690.html