[ Тематический план ] [ Контроллер прерываний ] [ 1 ] [ 2 ]
Обработка прерываний на основе контроллера 8259A
Программируемый контроллер прерываний (ПКП-PIC) 8259A представляет
собой устройство, реализующее до восьми уровней запросов на прерывания
с возможностью программного маскирования и изменения порядка
обслуживания прерываний. За счет каскадного включения число уровней
прерывания может быть расширено до 64. Установка контроллера в исходное
состояние и "настройка" его на определенный режим обслуживания
прерываний происходит с помощью двух типов команд: команд инициализации
(ICW) и команд управления операциями (OCW). На рисунке 1 показана
структурная схема контроллера прерываний. Контроллер прерываний
включает следующие блоки:
RGI - регистр запросов прерываний IRQx.
PRB - схема принятия решений по приоритетам; схема идентифицирует приоритет запросов и выбирает запрос с наивысшим приоритетом.
ISR - регистр обслуживаемых прерываний; сохраняет запросы прерываний, находящиеся на обслуживании контроллера прерываний.
RGM - регистр маскирования прерываний; обеспечивает запрещение одной или нескольких линий запросов прерывания.
BD - буфер данных; предназначен для сопряжения с системной шиной данных.
RWCU - блок управления записью/чтением; принимает управляющие сигналы
от микропроцессора и задает режим функционирования контроллера
прерываний.
CMP - схема каскадного буфера-компаратора; используется для включения в систему нескольких контроллеров.
CU - схема управления; вырабатывает сигналы прерывания и формирует трехбайтовую команду CALL для выдачи на шину данных.
Рис.1. Структура контроллера прерываний 8259А
И так, один контроллер 8259A способен обслуживать прерывания от 8
источников и этого было достаточно для компьютеров IBM PC ХT. В
системах IBM PC AT применяется каскадное соединение двух контроллеров
(рис.2), один из которых является ведущим, другой — ведомым. Ведущий
контроллер 8259A#1( master) обслуживает запросы 0, 1, 3–7; его выход
подключается к входу запроса прерываний процессора. К входу 2
контроллера 8259A#1 подключен ведомый контроллер 8259A#2 (slave),
который обслуживает запросы 8–15. При этом поддерживается вложенность
приоритетов — запросы 8–15 со своим рядом убывающих приоритетов
вклиниваются между запросами 1 и 3 ведущего контроллера, приоритеты
запросов которого также убывают с ростом номера. В качестве примера
отметим, что к линии IRQ 0 подключен системный таймер, к линии IRQ 1 -
клавиатура, к линии IRQ 8 - часы реального времени и т.д. Такое
каскадное подключение позволяет 15-ти устройствам посылать запрос на
обслуживание (прерывание текущей программы).
Рис. 2. Каскадное включение контроллеров прерываний
На современных системных платах функции контроллеров прерываний
возлагаются на чипсет, который может иметь и более гибкие возможности
управления, чем пара контроллеров 8259A. Процедура инициализации
контроллеров может отличаться от традиционной, ею занимается тест POST,
который учитывает особенности системной платы. Однако при выполнении
операций, связанных с реализацией режима прерывания всегда сохраняется
программная совместимость с 8259A. Поскольку в каждый момент времени
может поступить более чем один запрос на прерывание, контроллер
прерываний имеет схему приоритетов. В основном режиме - режиме полного
вложения, - до тех пор, пока установлен разряд в регистре ISR,
соответствующий запрашиваемому прерыванию, все последующие запросы с
таким же или более низким приоритетом игнорируются, подтверждаются лишь
запросы с более высоким приоритетом.
В циклическом режиме используется круговой порядок использования
приоритетов. Последнему обслуженному запросу присваивается низший
приоритет, следующему по кругу - наивысший, что гарантирует
обслуживание остальных устройств до очередного обслуживания данного
устройства.
Контроллер допускает маскирование отдельных запросов прерываний, что
позволяет устройствам с более низким приоритетом получить возможность
генерировать прерывания. Режим специального маскирования разрешает
прерывания всех уровней, кроме уровней, обслуживаемых в данный момент.
Кроме того, для каскадного включения возможен специальный режим полного
вложения. Этот режим программируется при инициализации контроллера. В
данном режиме игнорируются запросы с приоритетом более низким, чем
приоритет обрабатываемого в данный момент запроса, и обслуживаются все
запросы с равным или более высоким приоритетом.
Взаимодействие контроллера прерываний с внешним устройством
осуществляется по следующей схеме. Пусть в некоторый момент времени
контроллер клавиатуры с помощью единичного сигнала по линии IRQ 1
известил контроллер прерываний о своей готовности к обмену. В ответ на
запрос контроллер прерываний генерирует сигнал INTR (запрос на
прерывание) и посылает его на соответствующий вход процессора.
Процессор, если маскируемые прерывания разрешены (т.е. установлен флаг
прерываний IF в регистре флагов процессора), посылает на контроллер
шины сигналы R# - чтение, C# - управление и IO# - ввод/вывод,
определяющие тип цикла шины. Контроллер шины, в свою очередь,
генерирует два сигнала подтверждения прерывания INTA# и направляет их
на контроллер прерываний. По второму импульсу контроллер прерываний
выставляет на шину данных восьмибитный номер вектора прерывания,
соответствующий данной линии IRQ.
В режиме реального адреса ("реальном" режиме) векторы прерываний
хранятся в таблице векторов прерываний, которая находится в первом
килобайте оперативной памяти. Под каждый вектор отведено 4 байта (2
байта под адрес сегмента и 2 байта под смещение), т.е. в таблице может
содержаться 256 векторов.
Далее процессор считывает номер вектора прерывания. Сохраняет в стеке
содержимое регистра флагов, сбрасывает флаг прерываний IF и помещает в
стек адрес возврата в прерванную программу (регистры CS и IP). После
этого процессор извлекает из таблицы векторов прерываний адрес
подпрограммы обработки прерываний для данного устройства и приступает к
ее выполнению.
Процедура обработки аппаратного прерывания должна завершаться командой
конца прерывания EOI (End of Interruption), посылаемой контроллеру
прерываний. Для этого необходимо записать байт 20h в порт 20h (для
первого контроллера) и в порт A0h (для второго).
В IBM PC/AT используется режим прерываний с фиксированными
приоритетами. Как мы уже отмечали, высшим приоритетом обладает запрос
по линии IRQ0, низшим - IRQ7. Так как второй контроллер подключен к
линии IRQ2 первого контроллера, то приоритеты линий IRQ в порядке
убывания приоритета располагаются следующим образом: IRQ0, IRQ1, IRQ8 -
IRQ15, IRQ3 - IRQ7. Если запрос на обслуживание посылают одновременно
два устройства с разными приоритетами, то контроллер обслуживает запрос
с большим приоритетом, а запрос с меньшим приоритетом блокирует.
Блокировка сохраняется до получения команды EOI. В таблице 1. приведены
источники прерываний, соответствующие им линии запроса, расположенные
по убыванию приоритета - P, вектор1 - значение вектора в таблице
векторов реального режима (реального адреса), вектор2 - значение
вектора, который использует операционная система (в защищенном режиме).
Таблица прерываний защищённого режима называется дескрипторной таблицей прерываний IDT (Interrupt Descriptor Table).
Таблица 1. Источники аппаратных прерываний в IBM PC AT

Дескрипторная таблица прерываний IDT (Interrupt Descriptor Table)
располагается по адресу, который заносится в 5-байтовый внутренний
регистр процессора IDTR. Регистр IDTR содержит 24-битовый физический
адрес дескрипторной таблицы прерываний IDT и её предел.
Для обработки особых ситуаций - исключений был зарезервирован 31 номер
прерывания. В таблице 2 приведён полный список зарезервированных
прерываний защищённого режима.
Таблица 2. Зарезервированные прерывания защищённого режима.

Перед тем, как передать управление обработчику исключения, процессор
для некоторых исключений помещает в стек 16-битовый код ошибки. Код
ошибки программа анализирует и получает дополнительную информацию об
ошибке. Коды ошибок включаются в стек не только для следующих
исключений:
08h - двойная ошибка;
0Ah - недействительный сегмент состояния задачи TSS;
0Bh - отсутствие сегмента в памяти;
0Ch - исключение при работе со стеком;
0Dh - исключение по защите памяти.
Заметим, что аналога коду ошибки для зарезервированных прерываний в
реальном режиме нет. Рассмотрим следующий пример: Пусть в нашей системе
реализована виртуальная память. Программа в некоторый момент времени
обратилась к отсутствующему в оперативной памяти сегменту, выполняя
какую-либо команду, например MOV или ADD. Возникло исключение 0Bh -
отсутствие сегмента в памяти. Обработчик этого исключения, входящий в
состав операционной системы поместил соответствующий сегмент в
оперативную память. Затем выполнение прерванной команды повторяется.
Это можно сделать, так как для всех повторно запускаемых исключений
(кроме 03h - прерывание по точке останова и 04h - переполнение) в стек
включается адрес не следующей за прерванной командой, а адрес первого
байта команды, которая вызвала исключение. Выполнив команду IRET,
программа обработки исключения вновь передаст управление прерванной
команде. Свойством повторной запускаемости обладает большинство
зарезервированных прерываний, кроме следующих:
01h - прерывание для пошаговой работы;
08h - двойная ошибка;
09h - превышение сегмента сопроцессором;
0Dh - исключение по защите памяти;
10h - исключение сопроцессора.
После возврата процессора в реальный режим необходимо восстановить
состояния контроллера прерываний. При этом BIOS перепрограммирует
контроллер прерываний для работы в реальном режиме При загрузке
операционной системы, после инициализации процедурой POST, все
неиспользуемые входы контроллеров будут замаскированы (на запросы
прерываний реагировать не будут), их векторы прерываний указывают на
процедуру с единственной инструкцией IRET (возврат). Для подключения
программы обработчика прерывания необходимо загрузить обработчик в
память и установить указатель на него в таблице прерываний,
размаскировать соответствующий ему вход в контроллере прерываний, для
чего выполняется обнуление соответствующего бита регистра маски. Если
же обработчик прерывания удаляется из памяти, предварительно должен
быть замаскирован соответствующий ему вход контроллера. Все изменения в
таблице прерываний должны выполняться при замаскированных прерываниях,
чтобы избежать попытки использования вектора в процессе его
модификации. Для устройств PCI выделяется четыре проводных линии
запросов (IRQX, IRQY, IRQZ, IRQW), соединяемых с контактами INTA#,
INTB#, INTC# и INTD# всех слотов PCI с циклическим смещением цепей.
Таким образом, на слотах PCI остаются доступными лишь четыре обычные
линии запросов. Устройство PCI вводит сигнал прерывания низким уровнем
на выбранную линию INTx#. Этот сигнал должен удерживаться до тех пор,
пока программный драйвер, вызванный по прерыванию, не сбросит запрос
прерывания, обратившись по шине к данному устройству. Если после этого
контроллер прерываний снова обнаруживает низкий уровень на линии
запроса, это означает, что запрос на ту же линию ввело другое
устройство, разделяющее данную линию с первым, и оно тоже требует
обслуживания. Линии запросов от слотов PCI и PCI-устройств системной
платы коммутируются на входы контроллеров прерываний относительно
произвольно. Конфигурационное программное обеспечиние может определить
и указать занятые линии запросов и номер входа контроллера прерываний
обращением к конфигурационному пространству устройства. Программный
драйвер, прочитав конфигурационные регистры, тоже может определить эти
параметры для того, чтобы установить обработчик прерываний на нужный
вектор и при обслуживании сбрасывать запрос с требуемой линии. Каждая
функция устройства PCI может задействовать свою линию запроса
прерывания, но его обработчик прерывания должен быть готовым к ее
разделению (совместному использованию) с другими устройствами.