Инструменты пользователя

Инструменты сайта


interrupt

Это старая версия документа!


Прерывания

Прерывание (interrupt) - это технология, которая позволяет программе реагировать на внешние события. При наступлении события процессор временно прекращает выполнять свою текущую работу и переходит в специальную функцию, называемую обработчиком прерывания. Когда обработка завершается, процессор возвращается к выполнению программы.

Прерывания могут быть как программными, так и аппаратными. На PlayStation программные прерывания часто называются исключениями (exception). Обработку прерываний, по большей части, берет на себя BIOS (хотя и делает это неэффективно - см. на сайте problemkaputt).

Управлением прерываниями занимается сопроцессор COP0. Пользовательский код может взаимодействовать с ним при помощи специальных регистров:

  • SR (cop0r12) - статусный регистр; позволяет произвольно включать и выключать обработку прерываний, а также маскировать те или иные линии.
  • Cause (cop0r13) - регистр причины прерывания. Предоставляет битовые флаги линий прерываний и код, идентифицирующий тип последнего прерывания. Регистр имеет 8 линий: 2 для исключений (биты 8–9) и 6 для аппаратных прерываний (биты 10-15). PlayStation использует только одну линию аппаратных прерываний (бит 10), все остальные всегда нулевые.
  • EPC (cop0r14) - содержит адрес инструкции, которая вызвала исключение. Если произошло аппаратное прерывание, то EPC содержит адрес следующей инструкции, которая должна выполниться после обработки.
  • BadVaddr (cop0r8) - используется при исключениях шины. Содержит адрес, обращение по которому вызвало исключение.

Процесс обработки прерывания выглядит следующим образом:

  1. COP0 сохраняет значение программного счетчика (PC) в регистр EPC. Если текущая инструкция - это слот задержки ветвления, то будет записано значение PC-4, т.е. адрес предыдущей инструкции. В регистре Cause устанавливается бит, означающий, что прерывание сработало в слоте задержки ветвления.
  2. Код прерывания записывается в регистр Cause.
  3. Отключается обработка дальнейших прерываний до тех пор, пока не завершится обработка текущего. Включается режим ядра (на PlayStation он обычно и так всегда включен). Предыдущее состояние сохраняется в регистр SR.
  4. Если сработало исключение шины, проблемный адрес записывается в BadVaddr.
  5. CPU переходит по вектору 0xBFC00180, если в SR установлен бит Boot Exception Vectors (BEV), либо по вектору 0x80000080 в противном случае. BEV устанавливается при включении, но BIOS его зануляет. По адресу 0x80000080, который находится в рабочем пространстве BIOS, начинается базовый код обработки прерывания.

Перед загрузкой игры BIOS отключает обработку прерываний, поэтому, чтобы работать с периферийными устройствами (геймпад, CD-ROM и пр.), нужно либо вручную установить биты 2 и 10 статусного регистра COP0, либо проинициализировать геймпад функцией BIOS InitPad.

Функции BIOS, относящиеся к обработке прерываний:

  • int EnterCriticalSection(), вызов через syscall с номером 0x01 в регистре $a0 - отключает обработку прерываний, зануляя биты 2 и 10 регистра SR (cop0r12). Возвращает 1, если оба бита были установлены, и 0 в противном случае. Эту функцию нужно вызывать в редких случаях, когда нужно выполнить код, который не должен прерываться.
  • void ExitCriticalSection(), вызов через syscall с номером 0x01 в регистре $a0 - включает обработку прерываний, устанавливая биты 2 и 10 регистра SR (cop0r12).
interrupt.1792096200.txt.gz · Последнее изменение: — gecko

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki