В топике даётся обзор в исторической перспективе механизмов, используемых для сопряжения внешних устройств с CPU архитектуры x86.
i8080 имеет набор из восьми однобайтовых команд RSTn: RST0 — RST7, функционально эквивалентных командам вызова подпрограмм CALL по фиксированным адресам n*8.
Блок обработки прерываний i8080 связан с двумя выделенными ножками:
В первом такте каждого машинного цикла i8080 выдаёт на шину данных слово состояния, нулевой бит которого (INTA, interrupt acknowledge) сигнализирует подтверждение прерывания.
Единственное отличие цикла прерывания от обычного цикла выборки кода инструкции из памяти состоит в том, что процессор не увеличивает адрес счётчика команд; после приёма запроса на прерывание процессор как обычно читает код команды с шины данных (в такте T3 цикла M1, см. рис.). Задача контроллера прерываний состоит в том чтобы по слову состояния понять, что запрос на прерывание принят и поместить на шину данных подходящую команду. Команда может быть произвольной, обычно это RSTn или CALL.
Детально цикл обработки прерывания описан на стр. 2-11 [0].
i8086 имеет в наборе команд 256 инструкций INTn: INT 0 — INT 0ffh, и таблицу из 256 адресов. Каждая инструкция INTn запрещает прерывания, сохраняет регистр флагов и счётчик команд на стеке и выполняет переход по адресу, записанному в n-м элементе таблицы прерываний.
Блок обработки прерываний i8086 связан с тремя выделенными ножками:
Кроме того, выходные сигналы процессора S0# — S2# индицируют схожим с i8080 образом тип текущего машинного цикла. Комбинация 000 соответствует циклу подтверждения прерывания.
Детально цикл обработки прерывания описан на стр. 11 [1].
Не смотря на то, что программная сторона обработки прерываний значительно изменилась с появлением защищённого режима, страничной адресации и 32-битных инструкций, аппаратная сторона доставки запросов на прерывание в процессор претерпела минимальные изменения.
Выделенный сигнал подтверждения прерывания INTA# исчез. Количество сигналов статуса машинного цикла увеличилось до 4 в i80286, потом уменьшилось до 3; комбинация 0000/000 по-прежнему обозначает цикл подтверждения прерывания. Приём прерывания по-прежнему генерирует два цикла подтверждения, вектор прерывания считывается с битов D0-D7 шины данных в конце второго цикла. Начиная с i80386 бит адресной шины A2 устанавливается в 1 на первом и в 0 на втором цикле подтверждения прерывания.
Характерная картинка (i80386):
Подробности на стр. 3-33 [2], в п. 5.4.4 [3] и п. 7.2.10 [4].
С выходом процессора i8085 интел выпустил контроллер прерываний (PIC, programmable interrupt controller) — i8259 [5]. Этот контроллер, способный работать как с i8080, так и с x86, почти в неизменном виде использовался в моделях от IBM PC до IBM PC/AT на базе i80486. С появлением SMP-чипсетов он стал медленно вытесняться комбинацией IO-APIC (I/O advanced PIC) i82093 + LAPIC (local APIC) i82489.
Контроллер имеет следующие характеристики:
Упрощённо логика работы контроллера такова:
Ранние отечественные разработки на базе i8080 (КР580ВМ80), такие как Микро-80 и Радио-86РК не использовали механизм прерываний. Более поздние, например ЮТ-88, использовали периодические прерывания для таймера, подавая на ввод INT сигнал невысокой частоты и никак не управляя шиной данных в цикле подтверждения (на свободной шине все биты данных читались как 1, формируя команду RST7).
На западе шина S-100 компьютера Altair 8800 стала де-факто стандартом, позднее принятым как IEEE-696 [6]. Шина предусматривала сигнал запроса прерывания INT* предназначенный мастеру и 8 выделенных линий векторизованных прерываний. Подразумевалось что некий контроллер прерываний будет преобразовывать сигналы векторизованных прерываний в запрос INT* и формировать вектор в цикле подтверждения.
ISA (industry standard architecture) была разработана IBM в 1981 для IBM PC и в моделях PС и PC/XT имела восьмибитную шину данных и 5 линий запроса прерывания IRQ3 — IRQ7, заведённых на соответствующие входы единственного контроллера прерываний. IRQ0 присоединялся к таймеру, а IRQ1 — к контроллеру клавиатуры. Начиная с PC/AT в системе появился второй контроллер прерываний каскадно подключенный к IRQ2 первого i8259, шина данных расширилась до 16 бит, разъём ISA удлинился и в нём появились линии IRQ10-12, 14 и 15.
Традиционно (по крайней мере для MS-DOS) контроллеры прерываний инициализируются на работу по фронту IRQ с базовыми векторами 8 и 0x70, так что IRQ0 вызывает INT 8, IRQ1 — INT 9, IRQ8 — INT 70h, IRQ9 — INT 71h и т.д.
Чипсеты для ISA, например i82340SX [7], содержат в своём составе в неизменном виде каскад из двух 8259A и по сути ничем не отличаются от оригинального дизайна PC/AT в этом отношении.
PCI (peripheral component interconnect) была разработана Intel в 1993. Одной из целей, которые преследовал Intel при разработке этой шины была независимость дизайна от архитектуры процессора/материнской платы. Для прерываний последствия этого решения таковы:
Чипсеты для PCI, например PIIX [8] имеют выделенные ножки для входов INTA#...INTD# соединяемые с линиями запроса прерывания, идущими от разъёмов PCI. Для совмещения функциональности требуемой ISA и PCI чипсеты начали добавлять регистры, позволяющие выбирать для каждого прерывания, уровнем или фронтом оно активизируется, а так же в некоторых пределах переназначать номер IRQ соответствующий некоторым входам IRQ#. Но в своей основе контроллер прерываний в этих чипсетах по-прежнему представляет собой каскад из двух 8259.
[0] Спецификация i8080: arcarc.xmission.com/Tech/CPU/8080/8080.pdf
[1] Спецификация i8086: datasheets.chipdb.org/Intel/x86/808x/datashts/8086/231455-005.pdf
[2] Спецификация i80286: datasheets.chipdb.org/Intel/x86/286/datashts/intel-80286.pdf
[3] Спецификация i80386: datasheets.chipdb.org/Intel/x86/386/datashts/23163011.pdf
[4] Спецификация i80486: datasheets.chipdb.org/Intel/x86/486/datashts/240440-006.pdf
[5] Спецификация i8259A: pdos.csail.mit.edu/6.828/2005/readings/hardware/8259A.pdf
[6] Спецификация IEEE696: https://web.archive.org/web/20120330015830/http://www.imsai.net/download/IEEE_696_1983.pdf
[7] Спецификация чипсета 82340SX (ISA): www.datasheetarchive.com/pdf/download.php?id=7307256284271468fbe93b200907c75d7727e3&type=O&term=823400X
[8] Спецификация чипсета 82371 (PIIX) pdf.datasheetcatalog.com/datasheet/Intel/mXvqwzr.pdf
Спойлер
Я понял, что никогда уже не допишу этот грандиозный обзор во всей его полноте, поэтому я просто убрал «часть 1» из названия. Возможно эта часть всё же будет кому-нибудь полезна.
Интерфейс процессора
i8080 [0]
i8080 имеет набор из восьми однобайтовых команд RSTn: RST0 — RST7, функционально эквивалентных командам вызова подпрограмм CALL по фиксированным адресам n*8.
Блок обработки прерываний i8080 связан с двумя выделенными ножками:
- INTE (interrupt enabled) — выход, отражающий готовность процессора принять прерывание. Команды EI и DI, разрешающие и запрещающие прерывания, устанавливают соответственно высокий и низкий уровень на этом выводе. Низкий уровень устанавливается на этом выводе также после приёма запроса на прерывание.
- INT — вход запроса прерывания. Сигнал высокого уровня на этом входе, при условии наличия высокого уровня на выходе INTE, инициирует цикл обработки прерывания по окончании выполнения текущей команды.
В первом такте каждого машинного цикла i8080 выдаёт на шину данных слово состояния, нулевой бит которого (INTA, interrupt acknowledge) сигнализирует подтверждение прерывания.
Единственное отличие цикла прерывания от обычного цикла выборки кода инструкции из памяти состоит в том, что процессор не увеличивает адрес счётчика команд; после приёма запроса на прерывание процессор как обычно читает код команды с шины данных (в такте T3 цикла M1, см. рис.). Задача контроллера прерываний состоит в том чтобы по слову состояния понять, что запрос на прерывание принят и поместить на шину данных подходящую команду. Команда может быть произвольной, обычно это RSTn или CALL.
Детально цикл обработки прерывания описан на стр. 2-11 [0].
i8086 [1]
i8086 имеет в наборе команд 256 инструкций INTn: INT 0 — INT 0ffh, и таблицу из 256 адресов. Каждая инструкция INTn запрещает прерывания, сохраняет регистр флагов и счётчик команд на стеке и выполняет переход по адресу, записанному в n-м элементе таблицы прерываний.
Блок обработки прерываний i8086 связан с тремя выделенными ножками:
- NMI (non-maskable interrupt) — вход немаскируемого прерывания, нарастающий фронт сигнала на этом входе приводит к исполнению инструкции INT 2 по окончании выполнения текущей команды;
- INTR (interrupt request) — вход запроса прерывания. Сигнал высокого уровня на этом входе, при условии готовности процессора принять прерывание, инициирует цикл обработки прерывания по окончании выполнения текущей команды.
- INTA# (interrupt acknowledge) — выход подтверждения прерывания. При приёме прерывания i8086 генерирует два цикла подтверждения, в течение которых сигнал INTA# переводится в активное (низкое) состояние. По нарастающему фронту этого сигнала во втором цикле процессор считывает с шины данных 8 битов D0-D7, называемых вектором прерывания, и выполняет команду INTn, где n — значение считанного байта. Задача контроллера прерываний состоит в том чтобы в этот момент поместить вектор прерывания на шину данных.
Кроме того, выходные сигналы процессора S0# — S2# индицируют схожим с i8080 образом тип текущего машинного цикла. Комбинация 000 соответствует циклу подтверждения прерывания.
Детально цикл обработки прерывания описан на стр. 11 [1].
i80286 — i80486 [2][3][4]
Не смотря на то, что программная сторона обработки прерываний значительно изменилась с появлением защищённого режима, страничной адресации и 32-битных инструкций, аппаратная сторона доставки запросов на прерывание в процессор претерпела минимальные изменения.
Выделенный сигнал подтверждения прерывания INTA# исчез. Количество сигналов статуса машинного цикла увеличилось до 4 в i80286, потом уменьшилось до 3; комбинация 0000/000 по-прежнему обозначает цикл подтверждения прерывания. Приём прерывания по-прежнему генерирует два цикла подтверждения, вектор прерывания считывается с битов D0-D7 шины данных в конце второго цикла. Начиная с i80386 бит адресной шины A2 устанавливается в 1 на первом и в 0 на втором цикле подтверждения прерывания.
Характерная картинка (i80386):
Подробности на стр. 3-33 [2], в п. 5.4.4 [3] и п. 7.2.10 [4].
Контроллер прерываний
С выходом процессора i8085 интел выпустил контроллер прерываний (PIC, programmable interrupt controller) — i8259 [5]. Этот контроллер, способный работать как с i8080, так и с x86, почти в неизменном виде использовался в моделях от IBM PC до IBM PC/AT на базе i80486. С появлением SMP-чипсетов он стал медленно вытесняться комбинацией IO-APIC (I/O advanced PIC) i82093 + LAPIC (local APIC) i82489.
Контроллер имеет следующие характеристики:
- 8 входов IRQ (interrupt request) запроса прерывания от внешних устройств;
- приём запроса на прерывание по уровню или по фронту сигнала IRQ (общая настройка для всех входов IRQ);
- каждый вход IRQ может быть замаскирован независимо от других;
- несколько режимов приоритизации IRQ; возможность динамического изменения приоритетов IRQ;
- возможность объединения в двухуровневый каскад в качестве ведущего или ведомого (64 независимые линии IRQ в максимальной конфигурации);
- программируемый базовый вектор прерывания;
Упрощённо логика работы контроллера такова:
- сигналы на линиях IRQ фиксируются во внутреннем регистре IRR. Если контроллер работает по уровню, биты IRR сбрасываются когда уровень сигнала IRQ спадает;
- как только в IRR устанавливаются биты не замаскированные текущей маской (в регистре IMR), контроллер выдаёт сигнал INT процессору или ведущему контроллеру;
- по приходе первого подтверждения прерывания (сигнала INTA#) контроллер находит незамаскированный бит IRR с наивысшим приоритетом, устанавливает его в регистре ISR (прерывания в обработке) и очищает в IRR. Если подходящих битов в IRR не найдено, устанавливается бит 7;
- по приходе второго сигнала INTA# контроллер формирует на шине данных вектор прерывания со значением (базовый вектор прерывания + номер IRQ в обработке);
- по команде завершения обработки прерывания (от процессора или автоматической) соответствующий бит регистра ISR очищается;
Шины
Ранние отечественные разработки на базе i8080 (КР580ВМ80), такие как Микро-80 и Радио-86РК не использовали механизм прерываний. Более поздние, например ЮТ-88, использовали периодические прерывания для таймера, подавая на ввод INT сигнал невысокой частоты и никак не управляя шиной данных в цикле подтверждения (на свободной шине все биты данных читались как 1, формируя команду RST7).
На западе шина S-100 компьютера Altair 8800 стала де-факто стандартом, позднее принятым как IEEE-696 [6]. Шина предусматривала сигнал запроса прерывания INT* предназначенный мастеру и 8 выделенных линий векторизованных прерываний. Подразумевалось что некий контроллер прерываний будет преобразовывать сигналы векторизованных прерываний в запрос INT* и формировать вектор в цикле подтверждения.
ISA
ISA (industry standard architecture) была разработана IBM в 1981 для IBM PC и в моделях PС и PC/XT имела восьмибитную шину данных и 5 линий запроса прерывания IRQ3 — IRQ7, заведённых на соответствующие входы единственного контроллера прерываний. IRQ0 присоединялся к таймеру, а IRQ1 — к контроллеру клавиатуры. Начиная с PC/AT в системе появился второй контроллер прерываний каскадно подключенный к IRQ2 первого i8259, шина данных расширилась до 16 бит, разъём ISA удлинился и в нём появились линии IRQ10-12, 14 и 15.
Традиционно (по крайней мере для MS-DOS) контроллеры прерываний инициализируются на работу по фронту IRQ с базовыми векторами 8 и 0x70, так что IRQ0 вызывает INT 8, IRQ1 — INT 9, IRQ8 — INT 70h, IRQ9 — INT 71h и т.д.
Чипсеты для ISA, например i82340SX [7], содержат в своём составе в неизменном виде каскад из двух 8259A и по сути ничем не отличаются от оригинального дизайна PC/AT в этом отношении.
PCI
PCI (peripheral component interconnect) была разработана Intel в 1993. Одной из целей, которые преследовал Intel при разработке этой шины была независимость дизайна от архитектуры процессора/материнской платы. Для прерываний последствия этого решения таковы:
- каждая PCI-функция должна быть готова разделять свою линию запроса прерывания с другими функциями;
- каждый разъём шины имеет 4 линии запроса прерывания: INTA#, INTB#, INTC#, INTD#. Их связь с номерами IRQ контроллера прерываний не специфицируется, но рекомендуется циклический сдвиг установленного соответствия в зависимости от номера разъёма;
- в отличие от прерываний ISA активизируемых фронтом, запросы прерывания PCI активизируются низким уровнем сигнала;
Чипсеты для PCI, например PIIX [8] имеют выделенные ножки для входов INTA#...INTD# соединяемые с линиями запроса прерывания, идущими от разъёмов PCI. Для совмещения функциональности требуемой ISA и PCI чипсеты начали добавлять регистры, позволяющие выбирать для каждого прерывания, уровнем или фронтом оно активизируется, а так же в некоторых пределах переназначать номер IRQ соответствующий некоторым входам IRQ#. Но в своей основе контроллер прерываний в этих чипсетах по-прежнему представляет собой каскад из двух 8259.
Ссылки
[0] Спецификация i8080: arcarc.xmission.com/Tech/CPU/8080/8080.pdf
[1] Спецификация i8086: datasheets.chipdb.org/Intel/x86/808x/datashts/8086/231455-005.pdf
[2] Спецификация i80286: datasheets.chipdb.org/Intel/x86/286/datashts/intel-80286.pdf
[3] Спецификация i80386: datasheets.chipdb.org/Intel/x86/386/datashts/23163011.pdf
[4] Спецификация i80486: datasheets.chipdb.org/Intel/x86/486/datashts/240440-006.pdf
[5] Спецификация i8259A: pdos.csail.mit.edu/6.828/2005/readings/hardware/8259A.pdf
[6] Спецификация IEEE696: https://web.archive.org/web/20120330015830/http://www.imsai.net/download/IEEE_696_1983.pdf
[7] Спецификация чипсета 82340SX (ISA): www.datasheetarchive.com/pdf/download.php?id=7307256284271468fbe93b200907c75d7727e3&type=O&term=823400X
[8] Спецификация чипсета 82371 (PIIX) pdf.datasheetcatalog.com/datasheet/Intel/mXvqwzr.pdf
Комментарии (8)
Ghost_nsk
17.04.2019 13:29А потом железа становилось все больше и линий прерываний они стали просить все больше. Каскад из 8259 стал рудиментом который нужен первые миллисекунды, на смену ему пришел APIC а описание что и куда лежит в ACPI ни то ни другое простотой как в старину не отличается.
Smayliks
А ещё была т.н. VESA между ISA и PCI.
HackerDelphi
Точности ради, она называлась VESA local bus (сокращённо — VLB)
VadimGrad
Ещё у IBM была MicroChannel.
Была и EISA.
old_gamer
Если мне не изменяет память, то прерывания на VLB никак не заводились, они брались из слота ISA, к которому VLB был пристыкован.
JerleShannara
А это было сложно сделать, VLB вешалась напрямую на процессор(собственно от чего и вымерла — слишком высокая нагрузка (токовая) на процессор, нормально и быстро работало только одно устройство на шине).
old_gamer
Это понятно, просто статья про прерывания, а в VLB их и не было, в общем… Так что VLB ни при чем.