Выбрать главу

6.2.6. Прерывания

В PC-совместимых компьютерах прерывания от устройств PCI обслуживаются с помощью традиционной связки пары контроллеров 8259А, расположенных на системной плате (см. п. 12.4), к которым обращается команда «подтверждение прерывания». Прерывания на шине PCI свободны от одной из нелепостей системы прерываний ISA. Устройство PCI вводит сигнал прерывания низким уровнем (выходом с открытым коллектором или стоком) на выбранную линию INTA#, INTB#, INTC# или INTD#. Этот сигнал должен удерживаться до тех пор, пока программный драйвер, вызванный по прерыванию, не сбросит запрос прерывания, обратившись по шине к данному устройству. Если после этого контроллер прерываний снова обнаруживает низкий уровень на линии запроса, это означает, что запрос на ту же линию ввело другое устройство, разделяющее данную линию с первым, и оно тоже требует обслуживания. Линии запросов от слотов PCI и PCI-устройств системной платы коммутируются на входы контроллеров прерываний относительно произвольно. Конфигурационное ПО может определить и указать занятые линии запросов и номер входа контроллера прерываний обращением к конфигурационному пространству устройства (см. п. 6.2.12). Программный драйвер, прочитав конфигурационные регистры, тоже может определить эти параметры для того, чтобы установить обработчик прерываний на нужный вектор и при обслуживании сбрасывать запрос с требуемой линии. К сожалению, в конфигурационных регистрах не нашлось стандартного места для бита, индицирующего введение запроса прерывания данным устройством, — тогда бы в прерываниях для PCI не было бы проблем с унификацией поддержки разделяемых прерываний.

Каждая функция устройства PCI может задействовать свою линию запроса прерывания, но должно быть готовым к ее разделению (совместному использованию) с другими устройствами. Если устройству требуется только одна линия запроса, то оно должно занимать линию INTA#, если две — INTA# и INTB#, и так далее. С учетом циклического сдвига линий запроса это правило позволяет установить в 4 соседних слота 4 простых устройства, и каждое из них будет занимать отдельную линию запроса прерывания. Если какой-то карте требуется две линии, то для монопольного использования прерываний нужно оставить соседний слот свободным. PCI-устройства системной платы тоже задействуют прерывания с той же закономерностью (кроме контроллера IDE, который, к счастью, держится особняком).

Назначение прерываний устройствам (функциям) выполняет процедура POST, и этот процесс управляем лишь частично. Параметрами CMOS Setup (PCI/PNP Configuration) пользователь определяет номера запросов прерываний, доступных шине PCI. В зависимости от версии BIOS это может выглядеть по- разному; либо каждой линии INTA#INTD# явно назначается свой номер, либо ряд номеров отдается «на откуп» устройствам PCI вместе с устройствами ISA PnP (в противоположность устройствам «Legacy ISA»). В итоге POST определяет соответствие линий INTA#INTD# номерам запросов контроллера и соответствующим образом программирует коммутатор запросов. По воле пользователя может оказаться так, что не каждой линии запроса шины PCI достается отдельный вход контроллера прерываний. Тогда коммутатор организует объединение нескольких линий запросов PCI на один вход контроллера, то есть разделяемые прерывания. В самом худшем случае устройствам PCI не достанется ни одного входа контроллера прерываний. Заметим, что BIOS вряд ли отдаст шине PCI прерывания 14 и 15 (их забирает контроллер IDE, если он не отключен), а также 3 и 4 (СОМ-порты).

Драйвер (или иное ПО), работающий с устройством PCI, определяет вектор прерывания, доставшийся устройству (точнее, функции), чтением конфигурационного регистра Interrupt Line. В этом регистре указывается номер входа контроллера прерывания (255 — номер не назначен), и по нему определяется вектор (см. п. 12.4). Номер входа каждому устройству заносит тест POST. Для этого он считывает регистр Interrupt Pin каждой обнаруженной функции и по адресу устройства (!) определяет, какая из линий (PCI_1…PCI_4) используется. Заметим, что правила, по которым на системной плате определяется соответствие между Interrupt Pin и входными линиями коммутатора запросов в зависимости от номера устройства, строго не регламентированы (деление номера устройства на 4 — это всего лишь рекомендация), но их твердо знает версия BIOS данной системной платы. К этому моменту тест POST уже определил таблицу соответствия этих линий номерам входов; пользуясь этой таблицей, он записывает нужное значение в конфигурационный регистр Interrupt Line. Определить, есть ли еще претенденты на тот же номер прерывания, можно, лишь просмотрев конфигурационные регистры функций всех устройств, обнаруженных на шине (это не так уж сложно сделать, пользуясь функциями PCI BIOS). «Прелести» разделяемых прерываний обсуждаются в п. 12.4.1.

Спасением от бед «разделяемости» может быть перестановка карт в подходящий слот. Однако попадаются «подарки разработчиков» интегрированных плат, у которых из нескольких слотов PCI неразделяемая линия прерывания есть только у одного (а то и нет вообще). Такие недуги без скальпеля и паяльника, как правило, не лечатся.

На шине PCI имеется и иной механизм оповещения об асинхронных событиях, основанный на передаче сообщений (PCI Message-Based Interrupts). Для сигнализации запроса прерывания устройство запрашивает управление шиной и, получив его, выполняет запись номера прерывания по заранее оговоренному адресу.

Этот механизм может использоваться на системных платах, имеющих «продвинутый» контроллер прерываний APIC. Запись номера запроса производится в соответствующий регистр APIC. Для системных плат на чипсете с хабом ICH2 82801 этот регистр находится по адресу памяти FEC00020h, а номер прерывания может быть в диапазоне 0-23h. Однако одновременно оба механизма работать не могут; если разрешена работа APIC, то логика контроллеров 8259 не используется, и наоборот.

6.2.7. Прямой доступ к памяти, эмуляция ISA DMA (PC/PCI)

Как было сказано выше, шина PCI не предоставляет возможности прямого доступа к памяти с использованием централизованного контроллера в стиле 8237А (как для шины ISA). Для разгрузки центрального процессора от рутинных перекачек данных предлагается прямое управление шиной со стороны устройств, называемых ведущими устройствами шины (PCI Bus Master). Степень интеллектуальности ведущего устройства может быть различной. В простейшем варианте ведущее устройство обеспечивает пересылку блоков данных между устройством и системной памятью (или памятью других устройств) по указанию от CPU. Здесь CPU командами обращения к определенным регистрам ведущего устройства задает начальный адрес, длину блока, направление пересылки и разрешает запуск передачи. После этого пересылка выполняется по готовности (или инициативе) устройства, без отвлечения CPU. Таким образом выполняется прямой доступ к памяти (DMA). Более сложный контроллер DMA может организовывать сцепку буферов при чтении, разбросанную запись и т. п. — возможности, знакомые еще по «продвинутым» контроллерам DMA для ISA/EISA. Более интеллектуальное ведущее устройство, как правило, обладающее собственным микроконтроллером, не ограничивается такой простой работой по указке CPU — оно выполняет обмены уже по программе своего контроллера.

Для совместимости устройств PCI со старым PC-ориентированным ПО и упрощения устройств PCI фирма Intel разработала специальный протокол PC/PCI DMA, изменяющий назначение пары сигналов REQi# и GNTi# для заранее выбранного агента шины, являющегося «проводником» DMA. Этот агент имеет внешние (по отношению к шине PCI) пары сигналов DRQx# и DACKx# с логикой, аналогичной одноименным сигналам ISA (см. п. 6.1), а линии REQi# и GNTi# в процессе запроса управления шиной использует особым образом. Когда агент получает запрос DRQx (один или несколько), он по линии REQi# передает в последовательном коде номера активных линий запросов DRQx, с синхронизацией по линии CLK. В первом такте CLK передается старт-бит — низкий уровень REQi#, во втором — активность запроса DRQ0, затем DRQ1 и так далее до DRQ7, после чего сохраняется низкий уровень REQ#. На это сообщение арбитр ответит по линии GNTi# посылкой, также начинающейся со старт-бита, за которой последуют три бита кода номера канала, которому дается подтверждение DACK# для передачи данных в этой транзакции. Агент должен сообщать арбитру обо всех изменениях линий запроса, в том числе и о снятии сигналов запроса. Механизм PC/PCI DMA может быть реализован только в чипсете системной платы.