5

我目前正在开发一个爱好操作系统,特别是 ATA 驱动程序。我在使用带有中断的 PIO 数据输入命令时遇到了一些问题。我正在尝试执行 READ MULTIPLE 命令以逐块读取驱动器中的多个扇区,并为每个块触发一个中断。

如果我请求读取 4 个块(每块 1 个扇区)。我希望得到 4 个中断,每个数据块一个。在收到第四次中断后,我可以确定我已经传输了所有数据并相应地更新了我的请求结构。但是,在 VirtualBox 中,我发现在传输最后一个数据块后,我收到了另一个中断(状态 = 0x50,就绪,重叠模式服务器请求)。我可以简单地读取状态寄存器然后将其清除,但我认为根据规范我不应该收到第 5 个中断。

那么,什么是正确的方法来确认 ATA 设备发出的中断呢?

在这个例子中,我发出一个 READ MULTIPLE 命令,然后我的 ISR 执行以下操作:

  1. 禁用 CPU 中断,设置 nIEN
  2. 从 DATA 寄存器读取单个数据块(不是扇区!),
  3. 如果已读取所有数据,则读取 STATUS 寄存器以清除“额外”中断
  4. 通过清除 nIEN 退出,并向主从 PIC 发送 EOI

PIO 数据输入命令协议的 ATA 规范并不表示您需要读取状态寄存器。由此我假设当我收到中断时,我所要做的就是遵循协议并通过将 EOI 发送到 PIC 来完成。至于 nIEN 的设置/清除,在处理 VirtualBox 时,我发现如果我不这样做,我不会收到任何超过第一个中断的中断。所以我在进入ISR的时候设置了nIEN,然后在我离开之前清除它。我认为这不会有任何影响,但它必须与读取/写入该特定寄存器有关。

4

1 回答 1

8

这总是发生在我身上,我发布了一个我一直在努力解决的问题,但不久之后我自己找到了答案。

我一直引用的 ATA-6 规范在 PIO 数据输入部分(9.5)中有这一行:

当处于此状态时,主机应读取设备状态寄存器。

使用 ATA 时,状态寄存器有一个副作用:它会清除挂起的中断。我知道这一点,但我之前没有正确阅读这部分。它没有提到为什么你应该阅读寄存器,它只是像上面一样说明它。

重要的部分是它如何与中断处理程序一起工作。发出 PIO 数据输入命令后,一旦 INTRQ 被断言,您只需读取一次状态寄存器以清除中断,然后继续处理中断并正常返回(只是将 EOI 发送到 PIC。)让我感到困惑的是是我读过的文档都没有提到这应该如何处理中断(接收 INTRQ,读取状态,处理中断。)大多数在线指南只处理轮询 IO。

这是低级编程的难点之一,关键细节,例如需要读取 ISR 中的状态寄存器,往往一目了然。这个在协议描述中被保留为单行。叫我挑剔,但我只是希望更多地强调这一点。

于 2011-09-20T17:21:13.227 回答