5.10.10. Контроллер прерываний

Контроллер прерываний - устройство, которое получает запросы на аппарат-. прерывания от всех внешних устройств. Он определяет, какие запросы следу­ет обслужить, какие должны ждать своей очереди, а какие не будут обслуживаться

вообще. Существует два контроллера прерываний, так же как и DMA. Первый контроллер, обслуживающий запросы на прерывания от IRQ0 до IRQ7, управля­ется через порты 20h и 21h, а второй (IRQ8 - IRQ15) - через порты OAOh и OAlh.

Команды контроллеру делят на команды управления (OCW) и инициализа­ции (ICW):

порт 20h/OAOh для записи: OCW2, OCW3, ICW1

порт 20h/OAOh для чтения: см. команду OCW3

порт для чтения и записи: OCW1 - маскирование прерываний

порт 21h/OA1h для записи: ICW2, ICW3, ICW4 сразу после ICW1

Команды

OCW1:

биты 7-0: прерывание 7-0/15-8

При помощи этой команды можно временно запретить или разрешить то или иное аппаратное прерывание. Например, команды

in

or al,00000010b

out 21h,al

приводят к отключению то есть клавиатуры.шш

Мы пользовались OCW1 в программе term2.asm, чтобы разрешить IRQ3 -прерывание от последовательного порта COM2.

OCW2: команды конца прерывания и сдвига приоритетов биты 7-5: команда

000b: запрещение сдвига приоритетов в режиме без EOI

001b; неспецифичный EOI (конец прерывания в режиме с приоритетами)

01 Ob: нет операции

01 lb: специфичный EOI (конец прерывания в режиме без приоритетов) 100b: разрешение сдвига приоритетов в режиме без EOI 101Ь: сдвиг приоритетов с неспецифичным EOI 110b: сдвиг приоритетов

111b: сдвиг приоритетов со специфичным EOI

биты 4-3: 00Ь (указывают, что это OCW2)

биты 2-0: номер IRQ для команд 011b, 110b и 111b

Как упоминалось в разделе 5.8.2, если несколько прерываний происходят од­новременно, обслуживается в первую очередь то, у которого высший приоритет. При инициализации контроллера высший приоритет имеет IRQ0 (прерывание от системного таймера), а низший - IRQ7. Все прерывания второго контроллера (IRQ8 - IRQ 15) оказываются в этой последовательности между IRQ1 и IRQ3, так как именно IRQ2 используется для каскадирования этих двух контроллеров. Ко­манды сдвига приоритетов позволяют изменить ситуацию, присвоив завершаю­щемуся (команды 101 или 111) или обрабатывающемуся (ПО) прерыванию низ­ший приоритет, причем следующее прерывание получит наивысший, и далее по кругу.

Более того, в тот момент, когда выполняется обработчик аппаратного прерыва­ния, других прерываний с низшими приоритетами нет, даже если обработчик выполнил команду sti. Чтобы разрешить другие прерывания, каждый обработчик обязательно должен послать команду EOI - конец прерывания - в соответствую­щий контроллер. Именно поэтому обработчики аппаратных прерываний в про­граммах term2.asm и wavdma.asm заканчивались командами ,

mov       al,20h    ;  команда "неспецифичный конец прерывания" out       20h,al    ;  посылается в первый контроллер прерываний

Если бы контроллер был Инициализирован в режиме без приоритетов, вместо неспецифичного EOI пришлось бы посылать специфичный, содержащий в млад­ших трех битах номер прерывания, но BIOS инициализирует контроллер именно в режиме с приоритетами. Кроме того> контроллер мог быть инициализирован

в режиме без EOI, но тогда в ходе работы обработчика прерывания могли бы про­исходить все остальные прерывания, включая обрабатываемое. О способах ини­циализации контроллера говорится далее, а здесь рассмотрим последнюю коман­ду управления.

чтение состояния контроллера и режим специального маскирования бит 7: О

биты 6-5: режим специального маскирования 00 - не изменять

10 - выключить

11 - включить

биты 4-3: 01 - указывает, что это OCW3 бит 2: режим опроса

биты 1-0: чтение состояния контроллера 00 - не читать

10 - читать регистр запросов на прерывания

11 - читать регистр обслуживаемых прерываний

В режиме специального маскирования при выполнении обработчика преры­вания разрешены все прерывания, кроме осуществляющегося в настоящий мо­мент и маскируемых командой ОСW1, что имеет смысл сделать, если обработчи­ку прерывания с достаточно высоким приоритетом потребуется много времени.

Чаще всего OCW3 используют для чтения состояния контроллера - младшие два бита выбирают, какой из регистров контроллера будет возвращаться при пос­ледующем чтении из порта 21h/0/\lh: Оба возвращаемых регистра имеют струк­туру, аналогичную OCW1, - каждый бит отвечает соответствующему

Из регистра запросов на прерывания можно узнать, какие прерывания про­изошли, но пока не были обработаны, а из регистра обслуживаемых прерываний -

какие прерывания обрабатываются в данный момент. Итак, еще одна мера бе­зопасности, которую применяют резидентные программы, - нельзя работать с дисководом (IRQ6), если в данный момент обслуживается прерывание от пос­ледовательного порта (IRQ3), и нельзя работать с диском (IRQ14/15), если об­служивается прерывание от системного таймера

Команды инициализации

Чтобы инициализировать контроллер, BIOS посылает последовательность ко­манд: ICW1 в порт 20h/OAOh (она отличается от OCW своим битом 4) и ICW2, ICW3, ICW4 в порт сразу после этого.

ICW1:

биты 7-4: 0001b

бит 3: 1/0: срабатывание по уровню/фронту сигнала IRQ (принято 0)

бит 2: 1/0: размер вектора прерывания 4 байта/8 байт (1 для 80x86)

бит    каскадирования нет, не будет послано

бит 0: ICW4 будет послано ICW2: номер обработчика прерывания для IRQO/IRQ8 (кратный восьми)

(08h - для первого контроллера, 70h - для второго. Некоторые операцион­ные системы изменяют первый обработчик на 50h) ICW3 для ведущего контроллера:

биты 7-0: к выходу 7-0 присоединен подчиненный контроллер (ОЮОЬв PC)

ICW3 для подчиненного контроллера:

биты 3-0: номер выхода ведущего контроллера, к которому подсоединен ведомый

ICW4:

биты 7-5: О

бит 4: контроллер в режиме фиксированных приоритетов

биты 3-2: режим:

00, 01 - небуферированный

10 - буферированный/подчиненный

11 - буферированный/ведущий бит 1: режим с автоматическим EOI

(то есть обработчикам не надо посылать EOI в контроллер) бит 0: 0 - режим совместимости с 8085; 1 - обычный

Повторив процедуру инициализации, программа может, например, изменить

соответствие между обработчиками прерываний и реальными аппаратными пре­рываниями. Переместив базовый адрес первого контроллера на неиспользуемую область (например, 50h) и установив собственные обработчики на каждое из пре­рываний INT 50h - 58h, вызывающие INT 08h - OFh, вы будете абсолютно увере­ны в том, что никакая программа не определит обработчик аппаратного прерыва­ния, который получил бы управление раньше вашего.

picinit.asm

Выполняет полную инициализацию обоих контроллеров прерываний с отображением прерываний IRQO - IRQ7 на векторы INT 5Gh - 57h. Программа остается резидентной и издает короткий звук после каждого IRQ1. Восстановление старых обработчиков прерываний и переинициализация

контроллера в прежнее состояние опущены.

.model tiny . code

org 1GGh

PIC1_BASE

PIC2_BASE

start:

jmp

i-rqO_handler:

push in and out

pop int iret

irq1_handler:

push in equ equ

50h 7Gh

СОМ-программа.

процедура pic_init перенесет

end_of_resident

ах

al,6lh

al,ni11100b

61h,al

ах

G8h

ах

al,6ln

На этот адрес ЩО - Ш07.

На этот адрес процедура ріс_іпЮ перенесет Щ8 - 1И015.

Переход на начало инсталляционной части. Обработчик ЩО

(прерывания от системного таймера). Выключение динамика.

Старый обработчик ЩО.

Он послал ЕОІ, так что завершить простым ігеб обработчик Щ1  (прерывание от клавиатуры).

or

out

pop

int

iret

irq2_handler: int iret

irq3_handler: int iret

irq4_handler: int ' iret

irq5_handler: int iret

irq6_handler: int iret

irq7_handler:

int iret

end_of_resident: call

call

mov

int

al,00000011 b

61h,al

ax

09h

OArt

Включение динамика.

Старый обработчик IRQ1. И так далее.

ОВп

ОСИ

ODh

OEh

OFh

; Конец резидентной части. hook_pid_ints    ; Установка наших обработчиков

■;  INT 50h - 57h. init_pic ; Переинициализация контроллера прерываний,

dx, offset end j)f„r<3Sident

27h ; Оставить наши новые обработчики резидентными.

Процедура init_pic.

Выполняет инициализацию обоих контроллеров прерываний, отображая IRQO - IRQ7 на PICl.BASE - PIC1_BASE+7, a IR08 - IRQ15 на PIC2_BASE - PIC2_BASE+7. Для возврата в стандартное состояние вызвать

PIC1 BASE

= 08h,

 

 

PIC2 BASE

= 70h.

 

 

t_pic

proc near

 

 

cli

 

 

 

■ mov

al,00010101b

;- ICW1.

 

out

20h,al ■

 

 

out

OAOh.al

 

 

mov

al,PIC1_BASE

ICW2

для первого контроллера.

out

21h,al

 

 

mov

al,PIC2_BASE

; ICW2

для второго контроллера.

out

0A1h,al

 

 

mov

al,04h

: ICW3

для первого контроллера.

out

21h,al

 

 

mov

al,02h

; ICW3

для второго контроллера.

Программирование на уровне портов

out

0A1h,al

 

 

 

mov

al,00001101b

■ для

первого

контроллера

out

21h,al

 

 

 

mov

al,00001001b

■ для

второго

контроллера

out

OAlh.al

 

 

 

sti

 

 

 

 

ret

endp

 

 

 

init_pic

;  Перехват прерываний от PIC1_BASE до PIC1_BASE*7.

1_ints

proc near

mov

ax,2500h+PICl BASE

mov

dx,offset irqO handler

int

21h

mov

ax,2501h+PIC1 BASE

mov

dx, offset irqfhandler

int

2 lh

mov

ax,2502h+PIC1 BASE

mov

dx,offset irq2_handler

int

21h

mov

ax,2503h+PIC1 BASE.

mov

dx, offset irq3_handler

int

21h

mov

ax,2504h+PIC1 BASE

mov

dx, offset irq4_handler

int

21h

mov

ax,2505h+PIC1_BAS£

mov

dx,offset irq5_handler

int

21h

mov

ax,2506h+PICl BASE

mov

dx,offset irq6_handler

int

21h

mov

ax,2507h+PIC1_BASE

mov

dx,offset irq7_handler

int

21b

ret

 

lints

endp

end

start