Как правильно распознать прерывание ATA/IDE?
В настоящее время я работаю над хобби ОС, в частности драйвер 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, затем очистил его, прежде чем уйти. Я думаю, что это не будет иметь никакого эффекта, но это должно быть связано с чтением / записью этого конкретного регистра.
1 ответ
Это всегда случается со мной, я отправляю вопрос, с которым я боролся, только чтобы вскоре найти ответ.
Спецификация ATA-6, на которую я ссылаюсь, содержит одну строку в разделе ввода данных PIO (9.5):
Находясь в этом состоянии, хост должен прочитать регистр состояния устройства.
В ATA регистр состояния имеет побочный эффект: он очищает ожидающее прерывание. Я знал это, но я не правильно прочитал эту часть раньше. Здесь не упоминается, почему вы должны читать регистр, просто указывается, как указано выше.
Важной частью является то, как это работает с обработчиком прерываний. После выдачи команды ввода данных PIO после подтверждения INTRQ вы просто один раз читаете регистр состояния, чтобы очистить прерывание, а затем продолжаете обрабатывать прерывание и возвращаться как обычно (просто отправляя EOI в PIC.) Что меня смутило в том, что ни в одной из прочитанных мной документов нет упоминания о том, как именно это должно работать с прерываниями (получение INTRQ, чтение статуса, обработка прерываний). Большинство онлайн-руководств имеют дело только с опрошенным вводом-выводом.
Это одна из трудностей при низкоуровневом программировании, на ключевые детали, такие как необходимость чтения регистра состояния в ISR, часто не обращают внимания. Этот был оставлен как одна строка в описании протокола. Назовите меня разборчивым, но я просто ожидал большего акцента на этом.