Шина PCI и разделяемые прерывания



Через год архитектура PC отпразднует свое двадцатилетие. Вместе с нею двадцатилетие отпразднует большой черный разъем, стоящий на краю платы — точнее, его восьмибитная часть. Шина ISA, которая должна была пропасть из компьютеров еще два года назад, вовсе не собирается сдаваться. В чем же причина? Ведь старые платы ISA по большей части уже можно заменить новыми, рассчитанными на шину PCI, благо и внутренние модемы и звуковые карты уже давно выпускаются почти исключительно для новой шины. Всякие специализированные устройства типа программаторов и электронных ключей уже давно подключаются либо к LPT-порту, либо к USB.

Количество разъемов PCI на современной плате полного размера обычно равно шести, если только на ней нет встроенной периферии. В принципе, этого должно хватить самому требовательному пользователю. Но ISA, "уплотненная" до одного-двух слотов, не желает совсем вымирать. Одна из причин, из-за которой откладывается смерть шины ISA — количество прерываний на шине PCI. Точнее, не количество, а то, как ими распоряжаются изготовители системных плат.

Теория

По спецификации PCI, на прерывания отведено четыре контакта. Это гораздо меньше, чем на ISA, где на 16-разрядной шине есть 11 входов запроса прерываний. Но дело в том, что прерывания на ISA и PCI принципиально разные сигналы.

На шине ISA прерывания срабатывают по перепаду из "0" в "1". Просто установленный "1" прерывания не вызовет, поэтому, если одно устройство выставило сигнал, то другому бесполезно выставлять на эту же линию "1" — контроллер прерываний на нее не среагирует. Поэтому на ISA закон прост: одно устройство — одно прерывание.

На шине PCI выход запроса прерывания должен быть с открытым стоком (то же самое, что открытый коллектор в TTL), несколько выходов разных устройств объединяются по схеме "проводного И", то есть их выходы просто соединяются вместе и, если хотя бы на одном из них "0", то и на всей линии "0". Поэтому активный запрос прерывания на шине PCI — "0". И контроллер прерываний должен реагировать не на перепад, а на уровень. Таким образом, если два устройства запросили прерывания по одной линии, то программа-обработчик должна сначала проверить, ее ли устройство вызвало прерывание, обработать вызов (при этом устройство снимет запрос, но на линии останется "0" из-за второго устройства). Контроллер, отреагировав на логический "0", снова вызовет обработчик. Тот, проверив, что "его" устройство прерывания не требовало, вызовет второй обработчик. Он выполнит уже код, отвечающий за второе устройство, после чего на входе запроса прерывания наконец-то появится "1".

Для того чтобы это стало возможным, в PCI-устройстве должно быть что-то, что бы позволяло определять, оно ли вызвало прерывание. В спецификации PCI конкретно не указывается, каким образом это достигается. Там только говорится о том, что все обработчики прерываний должны уметь работать с разделяемыми прерываниями, и должны уметь выстраиваться в цепочку ("Daisy chaining"). Этот механизм используется программистами уже давно, и проблем никаких не вызывает. На известной старшему поколению ЭВМ "Электронике-60" и всех ее родственниках на разъеме вообще только одно прерывание. При подтверждении прерывания устройство выдает на шину вектор, в котором содержится стартовый адрес обработчика именно этого устройства, при этом централизованный контроллер прерываний, характерный для архитектуры PC, вообще отсутствует. На PCI такой механизм легко реализуем, но для платформы х86 используется более традиционный способ — радиальное назначение, когда конкретной линии запроса ставится в соответствие какой-то вектор, генерируемый контроллером прерываний.

Чтобы "Daisy chaining" работал, достаточно в каком-то программно-доступном регистре иметь флажок, повторяющий состояние запроса прерывания этого устройства, а лучше — число не обслуженных прерываний. Регистр с такими функциями может находиться и среди портов I/O, и даже быть ячейкой памяти. Этот регистр позволяет всем PCI устройствам назначить вообще всего одно прерывание.

Зачем же тогда четыре линии запросов? Это запас для многофункциональных устройств. Например, плата Iomega BUZ содержит две совершенно независимых части — устройство видеозахвата и Ultra SCSI контроллер. Они могут использовать два отдельных запроса прерывания. Это позволяет нормально работать даже тогда, когда одна часть многофункционального устройства не поддерживается конкретной операционной системой. В случае Iomega BUZ видеоввод работает только под Win9x, а SCSI-контроллер и под WinNT.

В спецификации PCI 2.0 ничего не говорилось о конкретной реализации связи между устройствами на шине и контроллером прерываний. Поэтому на самых старых материнских платах с шиной PCI мы можем видеть конфигурационные перемычки ("джамперы"), позволяющие назначить любому устройству любое прерывание.

В следующей версии, 2.1, появился пример воплощения универсального механизма назначения прерываний. При этом линия Int A на первом разъеме PCI становится Int B на втором разъеме, Int C на третьем и Int D на четвертом. Остальные линии тоже сдвигаются на один контакт. Эти четыре провода идут на матричный коммутатор, который доводит их до свободных входов контроллера прерываний. Такой матричный коммутатор 4X4 являлся частью моста PCI-ISA всех чипсетов предпоследнего поколения, — контроллер прерываний в архитектуре PC находится на шине ISA. Только сейчас искоренение ISA заставило перенести все устройства, включая BIOS, поближе к процессору.

Пока разъемов PCI на материнской плате было не больше четырех, такая схема работала идеально, — каждому устройству в итоге доставался свой запрос прерывания, и можно было не заботиться о разделении прерываний и выстраивании цепочек. Но очень скоро четырех слотов перестало хватать, и пришлось выдавать двум слотам одинаковый набор прерываний. Вот тут-то проблема interrupt sharing встала во всей красе.

Надо сказать, что в раскладе прерываний слот AGP выглядит, как еще один слот PCI, поэтому, на всех материнских платах, где ровно четыре PCI, но есть еще и AGP, обязательно есть одна связанная пара. А на каждый дополнительный слот PCI появляется еще одна пара.

Практика

Вот теперь мы перейдем от слов к делу и проверим, как нынешние PCI-устройства соблюдают требования спецификации и работают с разделяемыми прерываниями. Для лабораторной работы был использован компьютер на базе материнской платы ASUS P3B-F с процессором Celeron 566 и памятью 128 Мбайт.

Были протестированы:

  1. Видеокарта CreATive Annihilator Pro (GeForce256 DDR)
  2. Видеокарта ATi 3D Rage Pro
  3. Видеокарта i740 производства ATrend
  4. SCSI-2 контроллер на чипе Symbios 53C810 (не 53С810А, а старая версия)
  5. SCSI-2 контроллер Tekram 395 (на чипе AMD)
  6. UDMA/66 контроллер Promise Ultra66
  7. Сетевая плата на чипе Realtek RTL8139 (Ethernet 100/10 Mbps)
  8. Сетевая плата на чипе Realtek RTL8029AS (Ethernet 10 Mbps)
  9. Сетевая плата на чипе Winbond 89C940 (Ethernet 10Mbps)
  10. Звуковая плата Creative SB128PCI
  11. Плата видеоввода Miro Video DC10 (с драйверами от DC10+)

На испытуемом компьютере была установлена операционная система Windows95 OSR2.1 (2.0 c USB supplement), Internet Explorer 5.0 (это существенно, так как при его установке обновляются некоторые важные DLL-библиотеки). Кроме этого, все перечисленные устройства были поочередно вставлены, установлены их драйвера, и проверена работоспособность при обычном (монопольном) выделении запросов прерывания.

Помимо всего этого оборудования, в тестировании косвенно приняли участие два компьютера с Win95, служившие сетевыми клиентами. Один из них работал на 100 Мбит сегменте сети, а другой — на 10 Мбит. IP-routing был разрешен в соответствии с рекомендациями. Для проверки функционирования SCSI-2 контроллера к нему подключался CD-ROM NEC CDR-222. Для проверки функционирования платы видеозахвата к ней была подключена видеокамера.

Первый этап тестирования

Slot AGP ATi 3D RAGE PRO
1 PCI Realtek RTL8029AS
2 PCI Miro Video DC10
3 PCI SB128 PCI
4 PCI Realtek RTL8139
5 PCI Symbios 53C810
6 PCI не занят

Включаем машину, загружаемся. Загрузка проходит нормально. Разделенные прерывания достались в это раз двум парам — Realtek 8029AS и ATi 3D Rage Pro, и Realtek 8139 в паре с Symbios 53C810.

Диспетчер устройств рапортует, что все устройства работают. Но мы ему не верим, и правильно делаем! Вставляем CD в CD-ROM, и видим парадоксальный результат: все команды выполняются, но считать с диска ничего не удается! Звуковые диски при этом проигрываются нормально. Ладно, подождем пять минут. Через пять минут оглавление с диска все же удалось считать. Сеть — оба сегмента — работает нормально. Первый вывод: у SCSI-контроллера не все в порядке. Выключаем машину, меняем местами контроллер и Ethernet. Загружаемся. Контроллер работает, но только ДО ПЕРВОГО ПРИШЕДШЕГО ПО СЕТИ ПАКЕТА!!! Сеть, как и прежде, работает нормально. Втыкаем вместо него Tekram 395 и радуемся его нормальной работе. Втыкаем обратно старый контроллер и начинаем играть всеми документированными параметрами — никаких изменений к лучшему.

Итак, налицо факт — в чипе Symbios 53C810 аппаратной поддержки разделяемых прерываний нет! А драйверы как-то пытаются это обойти. По отзывам знающих людей, в 53C810A и всех старших моделях этой проблемы нет.

А что же видеокарта и другая сетевая карта? С ними все нормально? На вид — да, но… перейдем ко второму этапу.

Второй этап тестирования

Меняем видеокарту на GeForce. Эффект парадоксален. Машина начинает грузиться, и, в момент, когда должен был запуститься GUI, она отправляется на перезагрузку! И так по циклу.

Неужели такая современная и дорогая карта не умеет работать с shared interrupts?

Вынимаем GeForce, ставим i740. И с ней такая же картина. Значит, виновата сетевая плата? Но как же она тогда работала с 3D RagePRO? Осматриваем 3D RagePRO, и обнаруживаем на ней джампер, который запрещает прерывания от видеокарты. Но они, вроде бы, включены. Внимательно прочитав все доступные материалы про эту видеокарту, удается, наконец, выяснить, что она прерываниями не пользуется. То есть обработчик прерывания, устанавливаемый драйвером этой видеокарты, представляет собой простую заглушку. И, следовательно, можно считать, что она никому не мешает использовать свое прерывание.

Пытаемся заставить RTL8029AS работать в паре хоть с кем-нибудь, но эффект одинаков — если к ней подключен сетевой кабель, то приход пакетов во время загрузки Windows вызывает перезагрузку. При этом работа на монопольно выделенном прерывании абсолютно стабильна и никаких нареканий не вызывает.

Вывод: может быть, железо карты и имеет средства разделения прерываний, но драйвер об этом не подозревает! К счастью, у 100-мегабитной RTL8139 никаких проблем разделение прерываний не вызывает. Но что делать, если софт требует совместимости с NE2000? У нас в запасе есть другая сетевушка такого же класса, но на чипе Winbond 940. Ее драйвер оказывается способен работать с разделяемыми прерываниями, но скорость 10-Мбит сегмента падает почти вдвое, с 600 Кбайт/с до 320. Видимо, в рамках совместимости с NE2000 аппаратная поддержка shared interrupts реализована очень криво…

Третий этап тестирования

Видеокарта — GeForce. Она совершенно точно использует свое прерывание. Устанавливаем в первый слот PCI контроллер Ultra-ATA Promise Ultra66, подключаем к нему жесткий диск, и запускаем с него Half Life. Контроллер диска и видео оказываются на одном прерывании.

Система работает, как швейцарские часы! При том, что интенсивно работает как 3D-вывод, так и обмен с диском, программы успешно разбираются, кто из них вызвал прерывание! Вот все бы так!

Заменив видеокарту на i740, с удовлетворением наблюдаем, что, за исключением уменьшившейся производительности 3D, ничего не пострадало. Было бы неприлично нарушать спецификации, в составлении которых фирма Intel принимала такое большое участие.

Четвертый этап тестирования

Несмотря на то, что во многих FAQ'ах написано, что нельзя заставлять звуковые карты работать с shared interrupts, мы все же проверим, так ли это на самом деле. Будем для начала спаривать мультимедиа с RTL8139, с которой до этого никаких проблем не обнаружено. SB128 PCI показал себя с лучшей стороны — никаких проблем не замечено, количество fps в Timedemo Quake2 не изменилось, занятость процессора при декодировании DVD не возросла.

Но вот при спаривании его с видеокартой было обнаружено слабое "запинание" звука при работе Direct3D, например, во время работы Final Reality. Значит, FAQ в чем-то правы, и, несмотря на возможность такой работы, лучше ее избегать.

В инструкции к плате Miro Video DC10 прямо написано, что ее прерывание не может быть разделяемым. Несмотря на это, она отлично работает как в паре с RTL8139, так и в паре с SB128 PCI, причем ни VIDCAP32, ни SMARTCAP не выявляют никаких проблем ни со звуком, ни с изображением. Правда, это относится только к драйверам для Studio DC10+, может быть, со своими родными она бы так не работала.

Итоги

В целом, проверка показала, что современные устройства, для которых декларируется совместимость с PCI 2.1, правильно работают с разделяемыми прерываниями. Исключения составляют относительно старые платы, как Symbios 53C810, или те, у которых совместимость со старым "железом" поставлена во главу угла, как RTL8029AS (она совместима с NE2000 по регистрам).

Тем не менее, для устройств, которые генерируют большой поток прерываний, нежелательна работа с разделяемыми прерываниями, — она может вызвать потери времени, и, как следствие, потери информации.

Конечно, за разумное время невозможно проверить работу каждого устройства с каждым, но обычно это и не требуется — в наихудшем случае у нас будет три цепочки из двух устройств каждая, и, комбинируя эти пары, можно получить нормальную работу всей системы. И самое упрямое устройство можно воткнуть во второй слот PCI — там оно сможет насладиться монополией на свое прерывание.

К сожалению, универсальных рекомендаций дать нельзя, но можно, тем не менее, утверждать, что практически все выпущенные в этом и прошлом году платы не вызовут проблем с выделением им прерываний. И, значит, шина ISA утратит еще один свой козырь — большее количество независимых запросов прерывания.

Для тех, кому скучно читать статью целиком

Из протестированных плат с разделяемыми прерываниями не смогли работать только RTL8029AS и Symbios 53C810. В обоих случаях это может быть объяснено "почтенным" по компьютерным меркам возрастом "железа". Тем не менее, не рекомендуется работа мультимедиа с shared interrupts, и вообще, не следует назначать одинаковых прерываний больше, чем заставляет конструкция материнской платы.





Дополнительно