09.1 Conspect (ru)
Системные события.
В архитектуре MIPS существует много разных типов системных событий. Системное событие – это такая новая потребность. Программа работает, а в это время с вашей вычислительной системой что-то происходит (неважно что и как) и оно незапланированное. То есть происходит “Событие”, которое внезапно нужно обработать и обработать его программой.
Типичное событие: ты кладешь в регистр кривое число, а потом пытаешься обратиться по этому адресу и у тебя программа вылетает с диагностикой “невалидный адрес”.
Как решить эту проблему, когда нужно каждый раз проверять данные при работе с ними, иначе выполнение просто будет невозможным дальше. Для каждой проблемы есть свои индивидуальные решения. Но наиболее разумным будет выделить какую-то специальную подпрограмму отдельно лежащую отдельно от вашей программы, которая бы обрабатывала такую исключительную ситуацию.
Что явилось причиной “Исключительной ситуации”: • Инициатива вашей аппаратуры (аппаратный сбой или пользователь случайно нажал на клавиатуру во время выполнения программы) (Внешнее прерывание Interrupt) • Мы сами виновны в том, что допустили ошибку в написании программы (Внутреннее прерывание Exeption) • Ситуация, когда мы имитировали исключение для собственных целей (Trap)
Для того, чтобы такая аппаратная ситуация работала нужно: иметь поддержку, переключение в какое-то другое место, где лежит эта программа-обработчик, выполнение того, что там произошло и возвращение обратно. Это ни единственный способ!
Исключительные ситуации, в особенности прерывание, могут быть асинхронными, то есть: программа работала и в произвольный момент времени случилось прерывание снаружи и его надо обработать. Это означает, что если ваши действия состоят из трех команд или четырех инструкций на ассемблере и у вас произошло прерывание, когда программа выполняла вторую, то нужно думать, о том, что вся пачка из четырех инструкций не прошла.
Наша задача по тому, чтобы в нашей архитектуре возникло понятие “Cистемное событие”, как обычно в таких случаях приводит к усложнению архитектуры и усложнению программирования.
Вариант реализации: • Вектор прерывания (самый популярный из современных способов организации обработчика прерываний) • Единственный вариант реализации в MIPS: в MIPS есть один единственный обработчик, он лежит по адресу 0х80000180 и это тот программист, который будет программировать этот обработчик должен разобрать: а что, собственно, тут происходит?
Что должны делать аппаратура: • А что, если при обработке прерывания произошло прерывание? o Запретить прерывания на время обработки прерывания • Когда произошла Исключительная ситуация и этот идентификатор события записать • Если обработчик сдергивает поток выполнения с основного места и перекладывает его в куда-то другое место , надо запомнить, где находился поток выполнения исходной, чтобы потом туда вернуться.
MIPS: Для управления потоком вычислений, выискиванием всяких штук в MIPS’е есть еще один сопроцессор CPU0, в чьи обязанности входит следить за тем, что в нашей вычислительной системе произошла Исключительная ситуация и что-то с этой Исключительной ситуацией делать. Еще у него есть свои собственные команды, которые с этими регистрами работают: • Взять из регистра • Положить в регистр • Eret – выход из подпрограммы
Регистры: • EPC – это тот регистр, на который сохраняется адрес инструкции, на которой произошло исключение. • Cause – содержит информацию о том, что произошло, причина • BadVAddr – для плохих адресов
Как всё происходит: произошло исключение: 1. В регистре status возводим 1 бит, который означает, что мы вошли в обработчик исключений 2. В $13 записали причину прерывания (в биты от 2 до 6) 3. Сохраняет адрес по которому произошло исключение в регистр EPC ( $14 в CPU0) 4. Если была плохая адресация, то еще сохранить в регистр BadVaddr 5. Переход на 0х8000180 (тут обработчик всех Исключительных ситуаций в MIPS) a. .text – секция кода ядра 6. Выполняется операция eret => выходит из исключений и переходит на адрес, который лежит в $14 EPC в CPU0 a. Будет хорошей идеей увеличить его на 4 прежде, чем вернуться.
Регистры статуса. Бит 1: Exception level – который включается, когда мы входим в обработчик и выключается, когда мы выходим из него Бит 0: разрешает или запрещает прерывания 15-8 биты: Int.mash можем запрещать лишь некоторые прерывания, при работе с какими-то конкретными исключениями. Регистр причины C0: 1-0 биты: не используются 6-2 биты: номер произошедшего исключения 31 бит: определяет остановку по break point’у
Исключения: • Плохой адрес при попытке прочитать • Плохой адрес при попытке записать • Плохой системный вызов • Break point исключение • Попытка интерпретировать кусок памяти как инструкцию, но в этом куске памяти записано, что-то, что не соответствует инструкции • Арифметическое исключение • Trap исключение • Деление на 0 • Ошибки сопроцессора
$k0 и $k1 используются для написания обработчика. Желательно для ядра завести стек.