Шины PCI, USB и FireWire
Шрифт:
Для определения теоретического предела пропускной способности вернемся к рис. 2.1, чтобы определить минимальное время (число тактов) транзакций чтения и записи. В транзакции чтения после подачи команды и адреса инициатором (такт 1) меняется текущий «владелец» шины AD. На этот так называемый пируэт (turnaround) уходит такт 2, что обусловливается задержкой сигнала TRDY# целевым устройством. Далее может следовать фаза данных (такт 3), если целевое устройство достаточно расторопно. После последней фазы данных требуется еще 1 такт на обратный пируэт шины AD (в нашем случае это такт 4). Таким образом, одиночное чтение двойного слова (4 байта) занимает минимум 4 такта по 30 нс (33 МГц). Если эти транзакции следуют непосредственно друг за другом (если на такое способен инициатор и у него не отбирают право на управление шиной), то можно говорить о максимальной скорости чтения в 33 Мбайт/с при одиночных транзакциях. В транзакциях записи шиной AD все время управляет инициатор, так что здесь нет потери тактов на пируэт.
Скорость, соизмеримую с максимальной пиковой, можно получить только при пакетных передачах, когда дополнительные 3 такта при чтении и 1 такт при записи добавляются не к одной фазе данных, а к их последовательности. Так, для чтения пакета с числом фаз данных 4 требуется 7 тактов (V = 16/(7 х 30) байт/нс = = 76 Мбайт/с), а для записи – 5 (V = 16/(5 х 30) байт/нс = 106,6 Мбайт/с). При 16 фазах данных скорость чтения может достигать 112 Мбайт/с, а записи – 125 Мбайт/с.
В этих выкладках не учитывались потери времени, связанные со сменой инициатора. Инициатор может начинать транзакцию по получении сигнала GNT#, только убедившись в том, что шина находится в покое (сигналы FRAME# и IRDY# пассивны); на фиксацию состояния покоя уходит 1 такт. Как видно, захватывать для одного инициатора большую часть пропускной способности шины можно, увеличивая длину пакета. Однако при этом возрастет задержка получения управления шиной для других устройств, что не всегда допустимо. Отметим также, что далеко не все устройства способны отвечать на транзакции без тактов ожидания, так что реальные цифры будут скромнее.
Итак, для выхода на максимальную производительность обмена устройства PCI сами должны быть ведущими устройствами шины, причем способными генерировать пакетные циклы. Поддержку пакетного режима имеют далеко не все устройства PCI, а у имеющих, как правило, есть существенные ограничения на максимальную длину пакета. Радикально повысить пропускную способность позволяет переход на частоту 66 МГц и разрядность 64 бита, что обходится недешево. Для того чтобы на шине могли нормально работать устройства, критичные к времени доставки данных (сетевые адаптеры, устройства, участвующие в записи и воспроизведении аудио-видеоданных и др.), не следует пытаться выжать из шины ее декларированную полосу пропускания полностью. Перегрузка шины может привести, например, к потере пакетов из-за несвоевременности доставки данных. Заметим, что адаптер Fast Ethernet (100 Мбит/с) в полудуплексном режиме занимает полосу около 13 Мбайт/с (10 % декларируемой полосы обычной шины), а в полнодуплексном – уже 26 Мбайт/с. Адаптер Gigabit Ethernet даже в полудуплексном режиме вписывается в полосу шины уже с натяжкой (он «выживает» лишь за счет больших внутренних буферов), для него больше подходит 64 бит / 66 МГц. Существенное повышение пиковой скорости и эффективной пропускной способности дает переход на PCI–X с более высокими тактовыми частотами (PCI–X66, PCI–X100, PCI–X133) и быстрой записью в память (PCI–X266 и PCI–X533).
Говоря о пропускной способности шины и эффективной скорости обмена с устройствами PCI, следует помнить об издержках, вносимых дополнительными мостами PCI/PCI. Устройство, находящееся на дальней шине, получит меньшую пропускную способность, чем устройство, находящееся сразу за главным мостом и для которого справедливы вышеприведенные рассуждения. Это обусловлено механизмом работы моста – транзакции через мост выполняются в несколько этапов (см. главу 4).
ГЛАВА 3Прерывания PCI: INTx#, PME#, MSI и SERR#
Устройства PCI имеют возможность сигнализации об асинхронных событиях с помощью прерываний. На шине PCI возможны четыре типа сигнализации прерываний:
• традиционная проводная сигнализация по линиям INTx;
• проводная сигнализация событий управления энергопотреблением по линии PME#;
• сигнализация с помощью сообщений – M5I; • сигнализация фатальной ошибки по линии SERR#.
В данной главе рассматриваются все эти типы сигнализации, а также общая картина поддержки аппаратных прерываний в PC-совместимых компьютерах.
Аппаратные прерывания в PC-совместимых компьютерах
Аппаратные прерывания обеспечивают реакцию процессора на события, происходящие асинхронно по отношению к исполняемому программному коду. Прерывания в процессорах x86, используемых в PC-совместимых компьютерах, подробно рассмотрены в литературе [2]. Напомним, что аппаратные прерывания делятся на маскируемые и немаскируемые. Процессор x86 по сигналу прерывания приостанавливает выполнение текущего потока инструкций, сохраняя в стеке состояние (флаги и адрес возврата), и выполняет процедуру обработки прерывания. Конкретная процедура обработки выбирается из таблицы прерываний по вектору прерывания – однобайтному номеру элемента в данной таблице. Вектор прерывания доводится до процессора разными способами: для немаскируемого прерывания он фиксирован, для маскируемых прерываний его сообщает специальный контроллер прерываний. Кроме аппаратных прерываний у процессоров x86 имеются также внутренние прерывания – исключения (exceptions), связанные с особыми случаями выполнения инструкций, и программные прерывания. Для исключений вектор определяется самим особым условием, и под исключения фирмой Intel зарезервированы первые 32 вектора (0-31 или 00-1Fh). В программных прерываниях номер вектора содержится в самой инструкции (программные прерывания – это лишь специфический способ вызова процедур по номеру, с предварительным сохранением в стеке регистра флагов). Все эти прерывания используют один и тот же набор из 256 возможных векторов. Исторически сложилось так, что векторы, используемые для аппаратных прерываний, пересекаются с векторами исключений и векторами для программных прерываний, используемых для вызовов сервисов BIOS и DOS. Таким образом, для ряда номеров векторов процедура, на которую ссылается таблица прерываний, должна в начале содержать программный код, определяющий, по какому поводу она вызвана: из-за исключения, аппаратного прерывания или же для вызова какого-то системного сервиса. Таким образом, процедура, собственно и обеспечивающая реакцию процессора на то самое асинхронное событие, будет вызвана только после ряда действий по идентификации источника прерываний. Здесь еще заметим, что один и тот же вектор прерывания может использоваться и несколькими периферийными устройствами – это так называемое разделяемое использование прерываний, которое подробно обсуждается ниже.
Вызов процедуры обслуживания прерываний в реальном и защищенном режимах процессора существенно различается:
• в реальном режиме таблица прерываний содержит 4-байтные дальние указатели (сегмент и смещение) на соответствующие процедуры, которые вызываются дальним вызовом (Call Far с предварительным сохранением флагов). Размер (256 х 4 байт) и положение таблицы (начинается с адреса 0) фиксированы;
• в защищенном режиме (и в его частном случае – режиме V86) таблица содержит 8-байтные дескрипторы прерываний, которые могут быть шлюзами прерываний (interrupt Gate), ловушек (Trap Gate) или задач (Task Gate). Размер таблицы может быть уменьшен (максимальный – 256 х 8 байт), положение таблицы может меняться (определяется содержимым регистра iDT процессора). Код обработчика прерываний должен быть не менее привилегированным, чем код прерываемой задачи (иначе сработает исключение защиты). По этой причине обработчики прерываний должны работать на уровне ядра ОС (на нулевом уровне привилегий). Смена уровня привилегии при вызове обработчика приводит к дополнительным затратам времени на переопределение стека. Прерывания, вызывающие переключение задач (через Task Gate), расходуют значительное время на переключение контекста – выгрузку регистров процессора в сегмент состояния старой задачи и их загрузку из сегмента состояния новой.
Номера векторов, используемых для аппаратных прерываний в операционных системах защищенного режима, отличаются от номеров, используемых в ОС реального режима, чтобы исключить их конфликты с векторами, используемыми для исключений процессора.
На немаскируемое прерывание (NMI – Non-Maskable Interrrupt) процессор реагирует всегда (если обслуживание предыдущего NMI завершено); этому прерыванию соответствует фиксированный вектор 2. Немаскируемые прерывания в PC используются для сигнализации о фатальных аппаратных ошибках. Сигнал на линию NMI приходит от схем контроля памяти (четности или ECC), от линий контроля шины ISA (IOCHK) и шины PCI (SERR#). Сигнал NMI блокируется до входа процессора установкой в 1 бита 7 порта 070h, отдельные источники разрешаются и идентифицируются битами порта 061h:
• бит 2 R/W – ERP – разрешение контроля ОЗУ и сигнала SERR# шины PCI;
• бит 3 R/W – EIC – разрешение контроля шины ISA;
• бит 6 R – IOCHK – ошибка контроля на шине ISA (сигнал IOCHK#);
• бит 7 R – PCK – ошибка четности ОЗУ или сигнал SERR# на шине PCI.
Реакция процессора на маскируемые прерывания может быть задержана сбросом его внутреннего флага IF (инструкция CLI запрещает прерывания, STI – разрешает). Маскируемые прерывания используются для сигнализации о событиях в устройствах. По возникновении события, требующего реакции, адаптер (контроллер) устройства формирует запрос прерывания, который поступает на вход контроллера прерываний. Задача контроллера прерываний – довести до процессора запрос прерывания и сообщить вектор, по которому выбирается программная процедура обработки прерываний.
Процедура обработки прерывания от устройства должна выполнить действия по обслуживанию данного устройства, включая сброс его запроса для обеспечения возможности реакции на следующие события, и послать команды завершения в контроллер прерываний. Вызывая процедуру обработки, процессор автоматически сохраняет в стеке значение всех флагов и сбрасывает флаг IF, что запрещает маскируемые прерывания. При возврате из этой процедуры (по инструкции IRET) процессор восстанавливает сохраненные флаги, в том числе и установленный (до прерывания) IF, что снова разрешает прерывания. Если во время работы обработчика прерываний требуется реакция на иные прерывания (более приоритетные), то в обработчике должна присутствовать инструкция STI. Особенно это касается длинных обработчиков; здесь инструкция STI должна вводиться как можно раньше, сразу после критической (не допускающей прерываний) секции. Следующие прерывания того же или более низкого уровня приоритета контроллер прерываний будет обслуживать только после получения команды завершения прерывания EOI (End Of Interrupt).