зачем в вычислительную систему вводится контроллер прерываний
Архитектура ЭВМ
Компоненты ПК
Интерфейсы
Мини блог
Самое читаемое
Ввод-вывод
Контроллер прерываний
На наш взгляд, знакомство с системой прерываний микропроцессора Intel следует начать с обсуждения организации обработки аппаратных прерываний. Как видно из рис. 15.1, центральное место в схеме обработки аппаратных прерываний занимает программируемый контроллер прерываний (ПКП), выполненный в виде специальной микросхемы i8259А. Как мы уже говорили, эта микросхема может обрабатывать запросы от восьми источников внешних прерываний. Этого явно мало, поэтому в стандартной конфигурации вычислительной системы обычно используют две последовательно соединенные микросхемы i8259A. В результате такого соединения количество возможных источников внешних прерываний возрастает до 15.
Для того чтобы разобраться с обработкой аппаратных прерываний, нам придется проникнуть внутрь микросхемы i8259A. Перечислим функции, выполняемые микросхемой контроллера прерываний:
На рисунке ниже показано схематическое представление внутренней структуры и физических выводов микросхемы i8259А.
Рассмотрим назначение представляющих для нас интерес выводов i8259А:
Важное свойство данного контроллера — возможность его программирования, что позволяет достаточно гибко изменять алгоритмы обработки аппаратных прерываний. Исходя из этого, микросхема i8259А имеет два состояния:
Рассмотрим назначение основных структурных компонентов контроллера прерываний (см. рис. 15.2):
Рассмотрим возможные прохождение и обработку сигнала прерывания от некоторого внешнего устройства. При этом воспользуемся структурной схемой контроллера прерываний и обозначениями на ней (см. рис. 15.2).
Допустим, на вход irq0 поступает сигнал прерывания, что приводит к установке нулевого бита регистра IRR. Этот регистр связан с регистром маски IMR, состояние битов которого определяет, какие уровни прерываний запрещены (единичные биты) или разрешены к обработке (нулевые биты). Управление данным регистром осуществляется через порт 21h. Таким образом, если бит 0 в IMR равен нулю, то прерывание уровня 0 разрешено. Далее сигнал поступает к арбитру приоритетов. Как мы уже отметили, функция этого блока — разрешение конфликтов при одновременном поступлении запросов на несколько уровней. Обычно самый высокий приоритет у уровня irq_0, и далее приоритет уменьшается с возрастанием номера уровня. Если конфликта нет, то сигнал поступает на схему управления контроллером прерываний, которая формирует сигнал на выводе int. Этот вывод связан со входом микропроцессора INTR. Таким образом, сигнал на входе i8259A достиг микропроцессора. Что происходит далее в микропроцессоре, мы рассмотрим ниже. Сейчас отметим только значимые для данного обсуждения моменты. Итак, при поступлении сигнала на вход INTR в микропроцессоре происходят следующие процессы:
Таким образом, сигнал о прерывании прошел через микропроцессор и вернулся обратно в контроллер прерываний i8259A через вывод INTA. Данный вывод внутри контроллера прерываний замкнут на его схему управления, которая выполняет сразу несколько действий при поступлении этого сигнала:
На данном этапе обработки прерывания, после того как номер прерывания по шине данных поступил в микропроцессор, последнему стало известно все об источнике прерывания. Далее микропроцессор осуществляет процедуру обработки прерывания. Если в это время придет другой сигнал о прерывании того же уровня, то он будет запомнен установкой бита в IRR, и обслуживание этого прерывания будет отложено. Если приходит прерывание другого уровня, то его дальнейшая обработка зависит от приоритета, который оно имеет по отношению к уже обрабатываемым прерываниям. Если приоритет выше, то текущая процедура обработки прерывания останавливается, и вызывается процедура обработки более приоритетного прерывания.
Очень важный момент связан с процессом завершения обработки прерывания. Проблема здесь состоит в следующем. После принятия микропроцессором запроса на обслуживание прерывания в контроллере устанавливается бит в регистре ISR, номер этого бита соответствует уровню прерывания. Установка бита с данным номером блокирует все прерывания уровня, начиная с текущего, и менее приоритетные в блоке-арбитре приоритетов. Если процедура прерывания закончит свою работу, то она сама должна этот бит сбросить, иначе все прерывания этого уровня и менее приоритетные будут игнорироваться. Для осуществления такого сброса необходимо послать код 20h в порт 20h. Есть и другая возможность — установить такой режим работы микросхемы i8259A, когда сброс этого бита будет производиться автоматически. Тонкий момент заключается в том, что происходить такой автоматический сброс будет одновременно с приходом сигнала INTA (то есть извещения о том, что запрос на обработку прерывания принят к обработке микропроцессором). Недостаток автоматического сброса в том, что существует вероятность прихода прерывания того же уровня, который уже обрабатывается в данный момент микропроцессором. В этом случае процедура обработки прерывания должна обладать свойством реентерабельности, то есть допускать повторное обращение к себе до завершения обработки предыдущего обращения. Для того чтобы процедура была реентерабельной, она должна иметь специфическую структуру, в частности, для каждого сеанса обращения к ней создается своя область для хранения переменных и значений регистров, а исполняемая часть процедуры находится в оперативной памяти только в одном экземпляре. Иногда может потребоваться подобный автоматический сброс, но надежнее и проще, конечно, контролировать этот процесс и самостоятельно сбрасывать бит в ISR. Это можно сделать либо в конце работы процедуры, либо в том месте процедуры, начиная с которого можно разрешить рекурсивный вызов данной процедуры, будучи уверенным в том, что она не разрушит никаких данных и работу программы в целом.
Другой не менее интересный момент заключается в том, что микропроцессор при принятии к обработке запроса на прерывание сбросил флаг IF в ноль, тем самым запретив все последующие аппаратные прерывания. Этим обстоятельством программист может пользоваться по своему усмотрению. Вы, конечно, помните, что все запросы на прерывания с приоритетом, равным текущему или меньшим, будут запрещены в любом случае, — это обусловлено логикой работы контроллера i8259A. Поэтому программист должен решить, насколько его замыслам могут помешать запросы на более приоритетные прерывания. Если это некритично, то лучше сразу, в начале процедуры обработки прерывания установить флаг IF в единицу. В большинстве случаев эту операцию нужно делать как можно раньше. Для установки флага IF в единицу в системе команд микропроцессора есть специальная команда, не имеющая операндов:
sti — разрешить аппаратные прерывания.
Наиболее наглядный пример, показывающий важность своевременной установки IF, связан с отсчетом времени. Если вы не знакомы с тем, как ведется учет времени в компьютере, то уделим этому немного внимания. Как после включения компьютер определяет текущее время суток или как он запоминает информацию о своей конфигурации после выключения? Все дело в том, что компьютер имеет небольшую энергонезависимую память, которая питается от аккумулятора и не зависит от подключения к электросети. Конструктивно эта память выполнена на специальном типе полупроводниковых элементов с так называемой CMOS-структурой (Complementar Metal Oxide Semiconductor — комплиментарная МОП-структура). Особенность таких элементов памяти — в их пониженной по сравнению с обычными микросхемами потребляемой мощности (при этом они являются и более медленными, что в данном случае непринципиально). Аккумулятор кроме CMOS-памяти питает еще и микросхему системных часов, в функции которой входит отсчет текущих даты и времени суток. Таким образом, текущие значения даты и времени постоянно хранятся в CMOS-памяти и поддерживаются в актуальном состоянии даже после выключения компьютера. Кроме того, в CMOS-памяти хранится некоторая другая информация, в частности, о конфигурации компьютера. Во время загрузки компьютера дата и время считываются в область данных BIOS. Дальнейший отсчет времени, после загрузки системы, ведется уже с помощью системного таймера — другой микросхемы на системной плате, в функции которой входит регулярно, примерно 18,2 раза в секунду, генерировать сигнал, который в качестве прерывания подается на уровень irq0 контроллера прерываний i8259A. Во время работы компьютера соответствующая программа BIOS обрабатывает прерывание данного уровня и ведет счет времени. Если терять такты по этому входу, то фактическое время на часах будет отставать, и поэтому в большинстве случаев в обработчиках прерываний есть смысл как можно раньше выдавать команду sti.
Прерывания от внешних устройств в системе x86. Часть 1. Эволюция контроллеров прерываний
В данной статье хотелось бы рассмотреть механизмы доставки прерываний от внешних устройств в системе x86 и попытаться ответить на вопросы:
Введение
Все мы знаем, что такое прерывание. Для тех, кто нет, цитата из википедии:
Прерывание (англ. interrupt) — сигнал от программного или аппаратного обеспечения, сообщающий процессору о наступлении какого-либо события, требующего немедленного внимания. Прерывание извещает процессор о наступлении высокоприоритетного события, требующего прерывания текущего кода, выполняемого процессором. Процессор отвечает приостановкой своей текущей активности, сохраняя свое состояние и выполняя функцию, называемую обработчиком прерывания (или программой обработки прерывания), которая реагирует на событие и обслуживает его, после чего возвращает управление в прерванный код.
В зависимости от источника возникновения сигнала прерывания делятся на:
В данной статье хотелось бы обсудить внешние прерывания IRQ.
Зачем они нужны? Допустим мы хотим выполнить какое-либо действие со входным пакетом для сетевой карты, когда он придёт. Чтобы не спрашивать сетевую карту постоянно «есть ли у тебя новый пакет?» и не тратить на это ресурсы процессора, можно использовать прерывание IRQ. Линия прерываний устройства соединяется с линией INTR процессора, и при получении пакета сетевая карта «дергает» эту линию. Процессор понимает, что для него есть информация и читает пакет.
Но что делать если устройств много? На все внешние устройства ножек процессора не напасёшься.
Чтобы решить эту проблему, придумали микросхему — контроллер прерываний.
Первой была микросхема Intel 8259 PIC. 8 входных линий (IRQ0-7), и одна выходная, соединяющая контроллер с линией INTR процессора. Когда возникает прерывание от какого-либо устройства, 8259 дёргает линию INTR, процессор понимает, что какое-то устройство сигнализирует о прерывании и опрашивает PIC, чтобы понять по какой именно ножке IRQx возникло прерывание. Появляется дополнительная задержка на данный опрос, но зато количество линий прерываний увеличивается до 8.
Однако 8 линий быстро оказалось мало, и чтобы увеличить их количество стали использовать 2 контроллера 8259 (master и slave) соединённых каскадно (Dual PIC).
IRQ с 0 по 7 обрабатываются первым Intel 8259 PIC (master), а IRQ с 8 по 15 вторым 8259 PIC (slave). О возникновении прерывания CPU сигнализирует только master. Если возникло прерывание на линиях 8-15, второй PIC (slave) сигнализирует о прерывании мастеру по линии IRQ 2, и тот уже в свою очередь сигнализирует CPU. Это каскадное прерывание отнимает одну из 16 линий, но в итоге даёт 15 доступных прерываний для устройств.
Схема утвердилась, и именно её имеют ввиду, когда говорят сейчас о PIC (Programm Interrupt Controller). Впоследствии контроллеры 8259 получили некоторые улучшения, и стали называться 8259A, а эта схема вошла в состав чипсета. Во времена когда основной шиной для подключения внешних устройств была шина ISA, такой системы в целом хватало. Надо было лишь следить, чтобы разные устройства не подключались на одну линию IRQ для избежания конфликтов, так как прерывания ISA не разделяемые.
Обычно раскладка прерываний под устройства была более менее стандартная
Пример (взят отсюда):
IRQ 0 — system timer
IRQ 1 — keyboard controller
IRQ 2 — cascade (прерывание от slave контроллера)
IRQ 3 — serial port COM2
IRQ 4 — serial port COM1
IRQ 5 — parallel port 2 and 3 or sound card
IRQ 6 — floppy controller
IRQ 7 — parallel port 1
IRQ 8 — RTC timer
IRQ 9 — ACPI
IRQ 10 — open/SCSI/NIC
IRQ 11 — open/SCSI/NIC
IRQ 12 — mouse controller
IRQ 13 — math co-processor
IRQ 14 — ATA channel 1
IRQ 15 — ATA channel 2
Конфигурация и работа с микросхемами 8259 осуществляется через I/O порты:
Чип | Регистр | I/O port |
---|---|---|
Master PIC | Command | 0x0020 |
Master PIC | Data | 0x0021 |
Slave PIC | Command | 0x00A0 |
Slave PIC | Data | 0x00A1 |
→Документацию на 8259A можно найти тут
На смену шине ISA пришла шина PCI. И количество устройств явно стало превосходить число 15, плюс в отличие от статической шины ISA в данном случае случае устройства могут добавляться в систему динамически. Но к счастью в данной шине прерывания могут быть разделяемыми (то есть к одной линии IRQ можно подсоединить несколько устройств). В итоге чтобы решить проблему нехватки линий IRQ, прерывания ото всех PCI устройств решили группировать в линии PIRQ (Programmable Interrupt Request).
Допустим у нас 4 линии прерываний свободно на PIC контроллере, а PCI устройств 20 штук. Мы объединяем прерывания по 5 устройств на линию PIRQx и подключаем линии PIRQx к контроллеру. При возникновении прерывания на линии PIRQx процессору придётся опросить все устройства подключённые к данной линии, чтобы понять от кого именно пришло прерывание, но в целом это решает задачу. Устройство осуществляющее связывание линий прерываний PCI в линии PIRQ часто называют PIR router.
В данном методе надо следить, чтобы линии PIRQx не подсоединялись к линиям IRQx на которых уже заведены прерывания ISA (так как это вызовет конфликты), и чтобы линии PIRQx были сбалансированы (ведь чем больше устройств мы подключили к одной линии PIRQ, тем больше устройств надо будет опрашивать процессору, чтобы понять, какое именно из этих устройств вызвало прерывание).
По сути функции это отдельные логические блоки. Например в одном PCI устройстве может быть функция Smbus controller, функция SATA controller, функция LPC bridge. Со стороны ОС каждая функция — это как отдельное устройство со своим конфигурационным пространством PCI Config.
Предыдущий метод работал пока не появились многопроцессорные системы. Дело в том, что по своему устройству PIC может передавать прерывания только на один главный процессор. А хотелось бы, чтобы нагрузка на процессоры от обработки прерываний была сбалансированной. Решением данной задачи стал новый интерфейс APIC (Advanced PIC).
Для каждого процессора добавляется специальный контроллер LAPIC (Local APIC) и для маршрутизации прерываний от устройств добавляется контроллер I/O APIC. Все эти контроллеры объединяются в общую шину с названием APIC (новые системы сейчас уже соединяются по стандартной системной шине).
Когда прерывание от устройства приходит на вывод I/O APIC, контроллер направляет прерывание в LAPIC одного из процессоров. Наличие I/O APIC позволяет сбалансировано распределять прерывания от внешних устройств между процессорами.
Первой микросхемой APIC был 82489DX, это был отдельный чип, соединяющий в себе LAPIC и I/O APIC. Для создания системы из 2 процессоров нужно было 3 таких микросхемы. 2 функционировали бы как LAPIC и одна как I/O APIC. Позднее функциональность LAPIC была напрямую включена в процессоры, а функциональность I/O APIC была оформлена в чип 82093AA.
I/O APIC 82093AA содержала 24 входных вывода, а архитектура APIC могла поддерживать до 16 CPU. Для поддержки совместимости со старыми системами, прерывания 0
15 отвели под старые прерывания ISA. А прерывания от PCI устройств стали выводить на линии IRQ 16-23. Теперь можно было не задумываться о конфликтах прерываний от ISA и PCI устройств. Также благодаря увеличенному количеству свободных линий прерываний возможно стало также увеличить количество линий PIRQx.
Программирование I/O APIC и LAPIC осуществляется через MMIO. Регистры LAPIC расположены обычно по адресу 0xFEE00000, регистры I/O APIC по адресу 0xFEС00000. Хотя в принципе все эти адреса возможно переконфигурировать.
Как и в случае с PIC первоначально отдельные микросхемы позже вошли в состав чипсета.
В дальнейшем архитектура APIC получила модернизацию и новый вариант получил название xAPIC (x — extended). Сохранена обратная совместимость с предыдущим вариантом. Количество возможных CPU в системе увеличилось до 256.
Следующий виток развития архитектуры получил название x2APIC. Количество возможных CPU в системе увеличилось до 2^32. Контроллеры могут работать в режиме совместимости с xAPIC, а могут в новом режиме x2APIC, где программирование LAPIC осуществляется не через MMIO, а через MSR регистры (что гораздо быстрее). Cудя по этой ссылке для работы этого режима необходима поддержка IOMMU.
Следует заметить, что в системе может быть несколько контроллеров I/O APIC. Например один на 24 прерывания в южном мосту, другой на 32 в северном. В контексте I/O APIC прерывания часто обозначаются GSI (Global System Interrupt). Так вот в такой системе будут GSI 0-55.
Предыдущий вариант с APIC хорош, но не лишён недостатков. Все эти линии прерываний от устройств усложняют схему, и увеличивают вероятности ошибок. На смену шины PCI пришёл PCI express, в котором линии прерываний решили просто-напросто убрать. Чтобы сохранить совместимость, сигналы о возникновении прерываний (INTx#) эмулируются отдельными видами сообщений. В этой схеме логическое сложение линий прерываний, которое раньше производилось физическим соединением проводов, легло на плечи PCI мостов. Однако поддержка legacy INTx прерываний — это лишь поддержка обратной совместимости с шиной PCI. На деле PCI express предложил новый метод доставки сообщений о прерываниях — MSI (Message Signaled Interrupts). В этом методе для сигнализации о прерывании устройство просто производит запись в MMIO область отведённую под LAPIC процессора.
Если раньше на одно PCI устройство (то есть на все его функции) выделялось всего 4 прерывания, то сейчас сейчас стало возможным адресовать до 32 прерываний.
В случае с MSI нет никакого sharing для линий, каждое прерывание соответствует своему устройству.
Прерывания MSI решают также ещё одну проблему. Допустим устройство проводит memory-write транзакцию, и хочет сообщить о её завершении через прерывание. Но write транзакция может быть задержана на шине в процессе передачи (о чём устройство никак не знает), и сигнал о прерывании придёт до процессора раньше. Таким образом CPU будет читать ещё невалидные данные. В случае если используется MSI, информация об MSI передаётся также как и данные, и раньше прийти просто не сможет.
Следует заметить, что прерывания MSI не могут работать без LAPIC, но использование MSI может заменить нам I/O APIC (упрощение дизайна).
В последствии данный метод получил расширение MSI-X. Теперь каждое устройство может иметь до 2048 прерываний. И стало возможным указывать индивидуально каждому прерыванию на каком процессоре оно должно выполняться. Это может быть очень полезно для высоконагруженных устройств, например сетевых карт.
Для поддержки MSI не требуется никаких дополнительных таблиц BIOS. Но устройство должно сообщить о поддержке MSI в одной из Capability в своём PCI Config, а драйвер устройства должен поддерживать работу с MSI.
Заключение
В данной статье мы рассмотрели эволюцию контроллеров прерываний, и получили общую теоретическую информацию о доставке прерываний от внешних устройств в x86 системе.
В следующей части мы посмотрим как на практике задействовать в Linux каждый из описанных контроллеров.
Прерывания и особые случаи
Контроллер приоритетных прерываний
Его структура представлена на рис. 7.5.
Функции контроллера приоритетных прерываний :
При использовании КПП обработка запросов немаскируемых прерывание проходит следующие этапы:
Каскадное включение контроллеров приоритетных прерываний
Для расширения количества запросов прерываний, которые могут быть подключены к микропроцессору, в микропроцессорной системе может быть использовано несколько КПП. Схема каскадного подключения двух контроллеров представлена на рис. 7.6.
Регистры КПП делятся на 2 группы: регистры инициализации ICW1-ICW4 и операционные регистры OCW1-OCW3.
Регистры инициализации загружаются при инициализации контроллера и в процессе работы КПП не меняются.
Контроллер | IRQ | Тип | Назначение | Начальное состояние маски |
---|---|---|---|---|
Ведущий контроллер | 0 | 8 | Таймер | 0 |
1 | 9 | Клавиатура | 0 | |
2 | A | Ведомый КПП | 0 | |
3 | B | Последовательный порт 2 (COM2) | 1 | |
4 | C | Последовательный порт 1 (COM1) | 1 | |
5 | D | Последовательный принтер ( LPT2 ) | 1 | |
6 | E | НГМД | 0 | |
7 | F | Параллельный принтер ( LPT1 ) | 1 | |
Ведомый контроллер | 8 | 70 | Часы реального времени | 1 |
9 | 71 | Резерв. Программно переназначен на IRQ2 | 0 | |
10 | 72 | Резерв | 1 | |
11 | 73 | Резерв | 1 | |
12 | 74 | Мышь | 1 | |
13 | 75 | Ошибка сопроцессора | 1 | |
14 | 76 | НЖМД | 0 | |
15 | 77 | Резерв | 1 |
Так как для КПП определено только 2 допустимых состояния (ведущий или ведомый), максимальная конфигурация контроллеров приоритетных прерываний состоит из 1 ведущего и 8 ведомых КПП. Это обеспечивает возможность подключения к входу INT микропроцессора до 64 запросов прерываний.
Содержимое операционных регистров изменяется в процессе работы КПП записью в них новой информации.
В персональной ЭВМ установлено постоянство приоритетов запросов прерываний, при этом запрос IRQ0 имеет самый высокий приоритет.
Так как здесь используются два каскадно включенных контроллера (см.рис. 7.6), приоритеты запросов прерываний IRQi имеют вид, представленный на рис. 7.8.