确认 ATA/IDE 中断的正确方法是什么?

发布于 2024-12-05 16:28:57 字数 797 浏览 1 评论 0原文

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

如果我请求读取 4 个块(每个块 1 个扇区)。我期望获得 4 个中断,每个数据块一个。收到第四个中断后,我可以识别出我已经传输了所有数据并相应地更新了我的请求结构。然而,在 VirtualBox 中,我发现在传输最后一个数据块后,我收到了另一个中断(STATUS = 0x50,READY,OVERLAPPED MODE SERVER REQ)。我可以简单地读取状态寄存器然后将其清除,但我认为根据规范我不应该收到第五个中断。

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

在此示例中,我发出 READ MULTIPLE 命令,然后 ISR 执行以下操作:

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

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

I am currently working on a hobby OS, specifically the ATA driver. I am having some issues with PIO data-in commands with interrupts. I am trying to execute the READ MULTIPLE command to read multiple sectors from the drive, block by block, with an interrupt firing for each block.

If I request a read of 4 blocks (1 sector per block). I expect to get 4 interrupts, one for each data block. Upon receiving the 4th interrupt I can identify that I've transferred all data and update my request structure accordingly. However, in VirtualBox I've found that after the last data block has been transferred I received yet another interrupt (STATUS = 0x50, READY, OVERLAPPED MODE SERVER REQ). I can simply read the STATUS register then to clear it, but I don't think I should ever receive the 5th interrupt according to the specs.

So what is the proper way acknowledge an interrupt issued by an ATA device?

In this example I issue a READ MULTIPLE command, and then my ISR does the following:

  1. disables CPU interrupts, sets nIEN
  2. Read a single data block (not sector!) fro the DATA register,
  3. If all data has been read, read the STATUS register to clear the 'extra' interrupt
  4. Exit by clearing nIEN, and sending EOI's to both the master and slave PICs

The ATA specs for the PIO data-in command protocol don't indicate that you need to read the status register. From that I assumed that when I receive an interrupt all I have to do is follow the protocol and finish by sending the EOIs to the PICs. As for the setting/clearing of nIEN, in dealing with VirtualBox I've found that if I don't do this I don't receive any interrupts past the first one. So I set nIEN when entering the ISR, then clear it before I leave. I'd think that wouldn't have any effect, but it must be related to reading/writing that specific register.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

断爱 2024-12-12 16:28:57

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

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

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

对于 ATA,状态寄存器有一个副作用:它会清除待处理的中断。我知道这一点,但我之前没有正确阅读这部分。它没有提到为什么你应该阅读寄存器,它只是按照上面的方式进行了说明。

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

这是低级编程的难点之一,关键细节,例如需要读取 ISR 中的状态寄存器,经常被忽略。这一条在协议描述中保留为一行。你可以说我很挑剔,但我只是希望更多地强调这一点。

This always happens to me, I post a question I've been struggling with, only to find the answer myself shortly after.

The ATA-6 spec I've been referencing has this one line in the PIO data-in section (9.5):

When in this state, the host shall read the device Status register.

With ATA the Status register has a side-effect: it clears a pending interrupt. I knew this, but I didn't correctly read this part before. It doesn't mention why you should read the register, it just states it exactly as above.

The important part is how this works with the interrupt handler. After issuing a PIO data-in command, once the INTRQ is asserted, you simply read the Status register once to clear the interrupt, then continue to processes the interrupt and return as normal (just sending EOIs to the PICs.) What had me confused is that none of the documentation I read mentioned exactly how this should work with interrupts (receive an INTRQ, read Status, processes interrupt.) Most online guides only deal with polled IO.

This is one of the difficulties with low-level programming, key details, such as needing to read the Status register in the ISR, are often glanced over. This one was left as a single line in the protocol description. Call me picky but I just would have expected more emphasis on this point.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文