What is the proper way to acknowledge an ATA / IDE interrupt?

I am currently working on a hobby operating system, in particular the ATA driver. I'm having some problems with interrupt PIO I / O commands. I am trying to execute the READ MULTIPLE command to read multiple sectors from disk, block by block, with interrupt for each block.

If I request reading 4 blocks (1 sector per block). I expect to get 4 interrupts, one for each data block. After receiving the fourth interrupt, I can determine that I transferred all the data and accordingly updated the structure of the request. However, in VirtualBox, I found that after transferring the last data block, I received another interrupt (STATUS = 0x50, READY, OVERLAPPED MODE SERVER REQ). I can just read the STATUS register to clear it, but I don't think that I ever get the 5th interrupt according to the specifications.

So, what is the correct way to acknowledge an interrupt issued by an ATA?

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

  • disables processor interrupts, sets nIEN
  • Read one block of data (not a sector!) In the DATA register,
  • If all data has been read, read the STATUS register to clear the "extra" interrupt
  • Exit by clearing the nIEN and sending the EOI to both the master and slave PIC

The ATA specifications for the PIO data entry protocol do not indicate that you need to read the status register. From this, I suggested that when I get an interrupt, all I have to do is follow the protocol and end by sending the EOI to the PIC. As for installing / cleaning nIEN, when working with VirtualBox, I found that if I do not, I do not receive any interruptions after the first. Therefore, I install nIEN when I enter the ISR, and then clean it before I leave. I would think that this would not have any effect, but it should be related to reading / writing this particular register.

+4
source share
1 answer

It always happens to me, I post a question that I struggled with, only to find the answer right away.

The ATA-6 specification that I referenced has one line in the PIO data section (9.5):

When in this state, the host must read the device status register.

With ATA, the status register has a side effect: it clears a pending interrupt. I knew this, but I had not read this part before. It does not mention why you should read the register, it simply sets it as indicated above.

The important part is how this works with the interrupt handler. After issuing the PIO data input command after the INTRQ statement, you simply read the status register once to clear the interrupt, then continue to process the interrupt and return as usual (just sending the EOI to the PIC.) What bothered me was that none of the documentation which I read did not mention exactly how this should work with interrupts (receive INTRQ, read status, interrupt processes). Most online guides deal only with IO surveys.

This is one of the difficulties with low-level programming; key information, such as the need to read the status register in the ISR, is often viewed. This was left as one line in the protocol description. Call me picky, but I just expected more attention on this issue.

+6
source

All Articles