В настоящее время я работаю над операционной системой для хобби, в частности над драйвером ATA. У меня проблемы с командами ввода данных PIO с прерываниями. Я пытаюсь выполнить команду READ MULTIPLE, чтобы прочитать несколько секторов с диска, блок за блоком, с прерыванием для каждого блока.
Если я запрашиваю чтение 4 блоков (1 сектор на блок). Я ожидаю получить 4 прерывания, по одному на каждый блок данных. Получив 4-е прерывание, я могу определить, что я передал все данные, и соответствующим образом обновить структуру своего запроса. Однако в VirtualBox я обнаружил, что после передачи последнего блока данных я получил еще одно прерывание (STATUS = 0x50, READY, OVERLAPPED MODE SERVER REQ). Я могу просто прочитать регистр STATUS, чтобы затем очистить его, но я не думаю, что когда-либо получу 5-е прерывание в соответствии со спецификациями.
Итак, как правильно подтвердить прерывание, выданное устройством ATA?
В этом примере я запускаю команду READ MULTIPLE, а затем моя ISR выполняет следующие действия:
- отключает прерывания процессора, устанавливает nIEN
- Прочтите один блок данных (не сектор!) Из регистра DATA,
- Если все данные были прочитаны, прочтите регистр STATUS, чтобы очистить «лишнее» прерывание.
- Выйдите, очистив nIEN и отправив EOI как ведущему, так и ведомому PIC.
Спецификации ATA для протокола команд ввода данных PIO не указывают, что вам необходимо читать регистр состояния. Исходя из этого, я предположил, что когда я получаю прерывание, все, что мне нужно сделать, это следовать протоколу и закончить отправкой EOI на PIC. Что касается установки / очистки nIEN, при работе с VirtualBox я обнаружил, что если я этого не сделаю, я не получу никаких прерываний после первого. Поэтому я устанавливаю nIEN при входе в ISR, а затем сбрасываю его перед уходом. Я бы подумал, что это не повлияет, но это должно быть связано с чтением / записью этого конкретного регистра.