问题描述
我最近在我的应用程序中添加了一个部件,旨在允许它使用属于辅助 PIC 的 IRQ 进行操作。特别是,中断处理程序需要向两个 PIC 发出中断结束条件信号,而不是仅向主 PIC 发出信号。 This is my code:
try (Session session = storage.start()) {}
现在,在添加这部分时,我考虑是先将 EOI 发送给次要 PIC,还是先发送给主要 PIC。以任何方式搜索都没有产生任何陈述。但是,我发现一些示例似乎选择了我最终实施的顺序;即先是次要 PIC,然后是主要 PIC。
我的问题是,这有关系吗?是否有实际的理由更喜欢这两种顺序?
次要PIC的例子
bootlib 中断处理程序:
push cs
pop ds
mov al,20h ; acknowledge interrupt
cmp byte [serial_use_irqmask + 1],0
je @F
out 0A0h,al ; to secondary PIC
@@:
out 20h,al ; to primary PIC
osdev.org wiki 的文章 on Interrupts:
movb $0x20,%al # end of interrupt command
outb %al,$0xA0 # PIC2 command port
outb %al,$0x20 # PIC1 command port
Pure64 中断处理程序:
mov al,20h
out A0h,al
out 20h,al
Dos64-stub 中断处理程序:
mov al,0x20 ; Acknowledge the IRQ
out 0xA0,al
out 0x20,al
主PIC优先的例子
德语维基百科文章 "Softwarebremse" 中的示例(“Bremse”的意思是“刹车”):
Irq0007_1:
mov al,20h
out 20h,al
pop rax
swint:
iretq
;--- IRQs 8-F
Irq080F:
push rax
mov al,20h
out 0A0h,al
jmp Irq0007_1
解决方法
我认为这不重要。
8259A 数据表没有提供更多信息,只是说明(两次):
EOI 命令必须发出两次:一次针对主站,一次针对相应的从站。
没有明确说明顺序。
首先向从站发送 EOI 仍然不允许来自从站的任何 IRQ(直到 EOI 到主站),因为主站不会为任何从站请求提供服务。 当master收到EOI后,所有的IRQ都会被允许。
首先将 EOI 发送给主站将允许新的主站 IRQ 但不允许从站 IRQ,直到从站也收到 EOI。
因此,当主站仍在等待其 EOI 时,首先将 EOI 发送给从站不会改变系统的“可中断性”。
这允许更好地控制系统准备好接受较低优先级中断的时刻。
假设在 iret
之前设置了 IF 标志。
就PIC而言,没有使用特定顺序的技术要求。
我认为丢失从设备 IRQ 的风险没有区别:
PIC 将在相关 IRQ 引脚置位后立即设置 IRR 位,但只有在收到来自 CPU 的 ACK 后才会设置 ISR 位(并且 IRR 位被清除)。
IRR-ISR 对形成一个迷你队列,当中断仍在服务时,IRR 会缓冲请求。
当从设备首先收到 EOI 而主设备没有收到时,是主设备通过不向 CPU 发出中断请求来阻止从设备设置 ISR 和清除 IRR。当master先收到EOI而slave没有收到时,slave本身不会发出中断请求。
在任何情况下,IRR 都不会被清除,只能缓冲一个 IRQ 请求。
首先将 EOI 发送给 master 可能会更早解锁其(高优先级)IRQ,但我们正在讨论一些指令的时间安排。
再次假设在 iret
之前设置了 IF 标志。
我认为没有任何理由更喜欢这两种排序中的任何一种。