Управление интерфейсом и выполнение команд
Для управления интерфейсом служит система сообщений — Message System , которыми обмениваются ИУ и ЦУ. Обмен происходит в фазах Message IN/OUT (см. выше), в одной фазе может передаваться несколько сообщений.
С помощью сообщений согласуются параметры синхронного режима и разрядность данных. Процесс согласования синхронного обмена называется Synchronous Negotiation . Устройство, запрашивающее синхронный обмен, посылает сообщение Synchronous Data Transfer Request с указанием допустимого периода цикла и отставания REQ/ACK. Если другой участник обмена поддерживает синхронный режим, он предложит свои параметры. Согласованными параметрами будут максимальный период и минимальное отставание (нулевое отставание эквивалентно асинхронному режиму). Выбранный режим будет относиться только к фазам передачи между данной парой устройств. Отвергнутое сообщение является требованием асинхронного режима. Поскольку старые хост-адаптеры не поддерживали согласование синхронного режима, на ЦУ запрос синхронного режима может быть заблокирован. О возможности работы в синхронном режиме хост может узнать, послав команды Request Sense и Inquiry.
Разрядность передач согласуется аналогично посредством сообщений Wide Data Transfer Request . Согласованные режимы будут действовать до сброса устройств по сообщению Bus Device Reset или «жесткого» сброса, что приведет к установке предопределенных режимов по включению. Согласование режимов не должно инициироваться в каждом процессе, поскольку затраты времени на эту процедуру сводят на нет выигрыш в производительности.
Система команд SCSI включает общие команды, применимые для устройств всех классов, и специфические для каждого класса. Любое SCSI-устройство должно поддерживать обязательные команды общего набора и своего класса, чем обеспечивается высокий уровень совместимости. Команда передается ИУ в ЦУ через блок дескриптора команды (command descriptor block), посылаемый в фазе Command . Некоторые команды сопровождаются блоком параметров, следующим за блоком дескриптора в фазе Data . Форматы блоков стандартизованы; длина блока, определяемая кодом операции (первым байтом блока), может составлять б, 10 или 12 байт.
Рассмотрим процесс на шине SCSI на примере одиночной команды чтения Read. ИУ имеет активный набор указателей и несколько сохраненных наборов, по одному на каждый из допустимого числа одновременных конкурирующих процессов. ИУ восстанавливает указатели процесса в активный набор и, выиграв арбитраж, выбирает ЦУ. Как только ЦУ выбрано, оно берет на себя управление процессом. В фазе Selection ИУ вводит сигнал ATN#, сообщая о намерении послать сообщение Identify с указанием адресуемого ЛУ. ЦУ переходит в фазу Command и принимает блок дескриптора команды Read. Интерпретировав команду, ЦУ переходит в фазу Data IN , передает запрошенные данные, затем переводится в фазу Status и посылает состояние Good . Затем в фазе Message IN устройство посылает сообщение Command Complete , после чего освобождает шину (фаза Bus Free ). Процесс завершен.
Рассмотрим тот же пример, но при условии отключения от шины (Disconnect ) в процессе выполнения команды. Если устройство, получив команду Read, определит, что для получения затребованных данных необходимо много времени, оно освободит шину, послав сообщение Disconnect . Как только требуемые данные готовы в ЦУ, оно, выиграв арбитраж, выберет ИУ (в фазе Reselect ) и в фазе Message IN пошлет ему сообщение Identify . ИУ вернет соответствующий набор указателей в активное состояние и продолжит выполнение процесса, как описано выше. Если ЦУ хочет отсоединиться, когда часть данных уже передана (например, головка диска дошла до конца цилиндра и требуется время на позиционирование), оно посылает сообщение Save Data Pointer , а затем — Disconnect . После повторного соединения передача данных возобновится с точки, определенной последним сохраненным значением указателя. Если произошла ошибка или исключение, ЦУ может повторить обмен данными, послав сообщение Restore Pointers или отсоединившись без сообщения Save Data Pointers .
Теперь рассмотрим процесс с цепочкой связанных команд . По успешному завершению каждой команды цепочки ЦУ автоматически переходит к исполнению следующей. Все команды цепочки являются частью одного процесса. Команды не являются полностью независимыми — при относительной адресации последний блок, адресованный предыдущей командой, доступен для следующей. Так, например, можно исполнить команду Search Data, по которой на диске будет найден блок, содержащий информацию, совпадающую с эталоном поиска. Связав с ней команду чтения Read, можно прочитать этот блок или блок с указанным смещением относительно найденного. По выполнении связанных команд ЦУ посылает сообщения Linked Command Complete (возможно, с флагом), а ИУ обновляет набор сохраненных указателей, так что они указывают на очередную команду цепочки. Команды в цепочке выполняются как одиночные, но с возможностью относительной адресации.
Команды могут исполняться с использованием очередей . ЦУ могут поддерживать немаркированные и маркированные очереди. Поддержка немаркированных очередей , определенная еще в SCSI-1, позволяет любому ЛУ (LUN) или целевой программе, занятым процессом от одного ИУ, принимать команды (начинать процесс) с другими ИУ.
Маркированные очереди (tagged queue) определены в SCSI-2 для ЛУ. Для каждой связи I_T_L (ИУ-ЦУ-ЛУ) существует своя очередь размером до 256 процессов. Каждый процесс, использующий маркированные очереди, идентифицируется связью I_T_L_Q , где Q — однобайтный тег очереди (queue tag). Теги процессам назначаются ИУ, их значения на порядок выполнения операций не влияют.
Постановка в очередь выполняется через механизм сообщений, при этом очередной процесс можно поставить в очередь «по-честному», а можно «пропихнуть» вне очереди: процесс, поставленный в очередь с сообщением Head Of Queue Tag , будет выполняться сразу после завершения текущего активного процесса. Процессы, поставленные в очередь с сообщением Simple Queue Tag , исполняются ЦУ в порядке, который оно сочтет оптимальным. Процесс, поставленный в очередь с сообщением Ordered Queue Tag , будет исполняться последним. ИУ может удалить процесс из очереди, сославшись на него по тегу. Изменение порядка выполнения команд ЦУ не касается порядка в цепочке команд, поскольку цепочка принадлежит одному процессу, а в очередь ставятся именно процессы.
Здесь мы не рассматриваем различные ситуации, приводящие к отклонениям от нормальной последовательности событий интерфейса. К ним относятся некорректные соединения со стороны ИУ, выбор несуществующего ЛУ, неожиданные выборки ИУ, округление параметров, реакция на асинхронные события и т. п.
Глава 6
Шины и карты расширения
Шины расширения (Expansion Bus) являются средствами подключения системного уровня: они позволяют адаптерам и контроллерам непосредственно использовать системные ресурсы PC — пространства памяти и ввода-вывода, прерывания, каналы прямого доступа к памяти. Устройства, подключенные к шинам расширения, могут и сами управлять этими шинами, получая доступ к остальным ресурсам компьютера (обычно к ячейкам памяти). Такое прямое управление (bus mastering) позволяет разгружать центральный процессор и добиваться высоких скоростей обмена данными. Шины расширения механически реализуются в виде слотов (щелевых разъемов) или штырьковых разъемов; для них характерна малая длина проводников, что позволяет достигать высоких частот работы. Эти шины могут и не выводиться на разъемы, но использоваться для подключения устройств в интегрированных системных платах.
В современных компьютерах основной шиной расширения является PCI; ее дополняет порт AGP. Шина ISA из настольных компьютеров уходит, но она сохраняет свои позиции в промышленных и встраиваемых компьютерах, как в традиционном слотовом варианте, так и в «бутербродном» варианте PC/104. В блокнотных компьютерах широко применяются слоты PCMCIA с шинами PC Card и Card Bus. Шина LPC является современным дешевым средством подключения нересурсоемких устройств на системной плате. Все эти шины подробно рассматриваются в данной главе. Информацию по отжившим шинам MCA, EISA, VLB можно найти в литературе [1, 2, 5].
Изготовителям карт расширения приходится точно следовать протоколам шины, включая жесткие частотные и нагрузочные параметры, а также временные диаграммы. Отклонения приводят к несовместимости с некоторыми системными платами. Если при подключении к внешним интерфейсам это ведет к неработоспособности только самого устройства, то некорректное подключение к системной шине может блокировать работу всего компьютера. Следует также учитывать ограниченность ресурсов PC. Самые дефицитные из них — линии запросов прерываний; проблема прерываний, известная по шине ISA, так и не была радикально решена с переходом на PCI. Другой дефицит — каналы прямого доступа шины ISA, используемые и для прямого управления шиной, — в шине PCI преодолен. Доступное адресное пространство памяти и портов ввода-вывода, в котором было тесновато абонентам шины ISA, в PCI существенно расширено. Проблемы распределения ресурсов на шинах решаются по-разному, но чаще всего применяется технология PnP.
В табл. 6.1 дана характеристика стандартных шин расширения PC.
Таблица 6.1 . Характеристики шин расширения
Шина | Пропускная способность, Мбайт/с¹ | Каналы DMA | Bus-Master | ACFG² | Разрядность данных | Разрядность адреса | Частота, МГЦ |
ISA-8 | - | - | |||||
ISA-16 | + | - | |||||
LPC | 6,7 | + | - | 8/16/32 | |||
EISA | 33,3 | + | + | 8,33 | |||
MCA-16 | - | + | + | ||||
MCA-32 | - | + | + | ||||
VLB | - | (+) | - | 32/64 | 33-50(66) | ||
PCI | 132/264 | - | + | + | 32/64 | 33/66 | |
PCI–X | 532/1064 | - | + | + | 32/64 | 32/64 | 33/66 |
AGP 1x/2x/4x | 266/532/1064 | - | + | + | 32/64 | ||
PCMCIA | 10/20 | + | - | + | 8/16 | ||
Card Bus | - | + | + |
¹ Указана максимальная пропускная способность. Реальная примерно в 2 раза ниже за счет прерываний, регенерации и протокольных процедур.
² Поддержка автоматического конфигурирования. Для ISA PnP является позднейшей надстройкой, реализуемой адаптерами и ПО.
Шины ISA, EISA и PC/104
ISA Bus (Industry Standard Architecture) — шина расширения, применявшаяся с первых моделей PC и ставшая промышленным стандартом, В компьютере XT использовалась шина с разрядностью данных 8 бит и адреса — 20 бит. В компьютерах AT ее расширили до 16 бит данных и 24 бит адреса. Конструктивно, как показано на рис. 6.1, шина выполнена в виде двух щелевых разъемов с шагом выводов 2,54 мм (0,1 дюйма). В подмножестве ISA-8 используется только 62-контактный слот (ряды А, В), в ISA-16 применяется дополнительный 36-контактный слот (ряды С, D). Шина PC/104, разработанная для встраиваемых контроллеров на базе PC, отличается от обычной ISA только конструктивно. В шине EISA — дорогом 32-разрядном расширении ISA — используется «двухэтажный» слот, позволяющий устанавливать и обычные карты ISA.
Рис. 6.1 . Слот ISA
Для шины ISA выпущено (и продолжает выпускаться) огромное количество разнообразных карт расширения. Ряд фирм выпускает карты-прототипы (Prototype Card), представляющие собой печатные платы полного или уменьшенного формата с крепежной скобой. На платах установлены обязательные интерфейсные цепи — буфер данных, дешифратор адреса и некоторые другие. Остальная часть платы свободна, и здесь разработчик может разместить макетный вариант своего устройства. Эти платы удобны для проверки нового изделия, а также для монтажа единичных экземпляров устройства, когда разработка и изготовление печатной платы нерентабельно.
В каждый момент времени шиной может управлять только одно устройство-задатчик , обращающееся к ресурсам (портам или ячейкам памяти) устройств-исполнителей. Шина ISA обеспечивает возможность обращения к 8- или 16-битным регистрам устройств, отображенным на пространства ввода-вывода и памяти. Диапазон адресов памяти для устройств ограничен областью верхней памяти UMА (А0000-FFFFFh). Для шины ISA-16 настройками CMOS Setup может быть разрешено пространство между 15-м и 16-м мегабайтом памяти (при этом компьютер не сможет использовать более 15 Мбайт ОЗУ). Для шины ISA диапазон адресов ввода-вывода сверху ограничен количеством задействованных для дешифрации бит адреса, нижняя областью адресов 0-FFh недоступна (зарезервирована под устройства системной платы). В PC была принята 10-битная адресация ввода-вывода, при которой линии адреса А[15:10] устройствами игнорировались. Таким образом, диапазон адресов устройств шины ISA ограничивается областью 100h–3FFh. Впоследствии стали применять 12-битную адресацию (диапазон 100h-FFFh). При этом приходится учитывать возможность присутствия на шине старых 10-битных адаптеров, которые «отзовутся» на адрес с подходящими ему битами А[9:0] во всей допустимой области 12-битного адреса четыре раза (у каждого 10-битного адреса будет еще по три 12-битных псевдонима). Полный 16-битный адрес используется только в шинах EISA и PCI.
Шина ISA-8 может предоставить до 6 линий запросов прерываний, ISА-16 — 11. Часть из них могут «отобрать» устройства системной платы или шина PCI.
Шина ISA-8 позволяет использовать до трех 8-битных каналов DMA. На 16-битной шине доступны еще три 16-битных и один 8-битный канал.
Все перечисленные ресурсы шины должны быть бесконфликтно распределены. Бесконфликтность подразумевает выполнение перечисленных ниже условий.
♦ Каждое устройство-исполнитель должно управлять шиной данных только при чтении по его адресам или по используемому им каналу DMA. Области адресов, по которым выполняется чтение регистров различных устройств, не должны пересекаться. Поскольку при записи шиной данных управляет лишь текущий задатчик, возможность конфликтов, приводящих к искажениям данных, исключена. «Подсматривать» операции записи, адресованные не данному устройству, не возбраняется.
♦ Назначенную линию IRQx или DRQx устройство должно держать на низком уровне в пассивном состоянии и переводить в высокий уровень для активации запроса. Неиспользуемыми линиями запросов устройство управлять не имеет права, они должны электрически отсоединяться или подключаться к буферу, находящемуся в третьем состоянии. Одной линией запроса может пользоваться только одно устройство. Такая нелепость (с точки зрения схемотехники ТТЛ) была допущена в первых PC и из требований совместимости тиражируется до сих пор.
Задача распределения ресурсов для старых адаптеров решалась с помощью джамперов, затем появились программно конфигурируемые устройства, которые вытесняются автоматически конфигурируемыми платами PnP.
Назначение контактов слотов шин ISA и EISA приведено в табл. 6.2 и 6.3.
Таблица 6.2 . Основной разъем шин ISA-8, ISA-16 и EISA
Ряд В | № | Ряд А |
GND | IOCHK# | |
Reset | SD7 | |
+5 В | SD6 | |
IRQ2/9¹ | SD5 | |
-5 В | SD4 | |
DRQ2 | SD3 | |
-12 В | SD2 | |
0WS#² | SD1 | |
+12 В | SD0 | |
GND | IOCHRDY | |
SMEMW# | AEN | |
SMEMR# | SA19 | |
IOWR# | SA18 | |
IORD# | SA17 | |
DACK3# | SA16 | |
DRQ3 | SA15 | |
DACK1# | SA14 | |
DRQ1 | SA13 | |
REFRESH# | SA12 | |
BCLK | SA11 | |
IRQ7 | SA10 | |
IRQ6 | SA9 | |
IRQ5 | SA8 | |
IRQ4 | SA7 | |
IRQ3 | SA6 | |
DACK2# | SA5 | |
TC | SA4 | |
BALE | SA3 | |
+5 В | SA2 | |
Osc | SA1 | |
GND | SA0 |
¹ B4: XT=IRQ2, AT=IRQ9.
² B8: XT-Card Selected.
Таблица 6.3 . Дополнительный разъем шин ISA-16 и EISA
Ряд D | № | Ряд С |
MEMCS16# | SBHE# | |
IOCS16# | LA23 | |
IRQ10 | LA22 | |
IRQ 11 | LA21 | |
IRQ12 | LA20 | |
IRQ 15 | LA19 | |
IRQ14 | LA18 | |
DACK0# | LA17 | |
DRQ0 | MEMR# | |
DACK5# | MEMW# | |
DRQ5 | SD8 | |
DACK6# | SD9 | |
DRQ6 | SD10 | |
DACK7# | SD11 | |
DRQ7 | SD12 | |
+5 B | SD13 | |
MASTER# | SD14 | |
GND | SD15 |
Сигналы шины ISA естественны для периферийных микросхем фирмы Intel (в стиле семейства 8080). Набор сигналов ISA-8 предельно прост. Программное обращение к ячейкам памяти и пространства ввода-вывода обеспечивают следующие сигналы.
♦ SD[7:0] — шина данных. Иное название сигналов — Data или D.
♦ SA[19:0] (Addr[19:0], A[19:0]) — шина адреса.
♦ AEN — разрешение адресации портов (запрещает ложную дешифрацию адреса в цикле DMA).
♦ IOW# (IOWC#, IOWR#) — запись в порт.
♦ IOR# (IORC#, IORD#) — чтение порта.
♦ SMEMW# (SMEMWR#, SMWTC#) — запись в системную память (в диапазоне адресов 0-FFFFFh).
♦ SMEMR# (SMEMRD#, SMRDC#) — чтение системной памяти (в диапазоне адресов 0-FFFFFh).
Ниже перечислены сигналы, относящиеся к сигналам запросов прерывания и каналам прямого доступа к памяти.
♦ IRQ2/9, IRQ[3:7] — запросы прерываний. Положительный перепад сигнала вызывает запрос аппаратного прерывания. Для идентификации источника высокий уровень должен сохраняться до подтверждения прерывания процессором, что затрудняет разделение (совместное использование) прерываний. Линия IRQ2/9 в шинах XT вызывает аппаратное прерывание с номером 2, а в AT — с номером 9.
♦ DRQ[1:3] — запросы 8-битных каналов DMA (положительным перепадом).
♦ DACK[1:3]# — подтверждение запросов 8-битных каналов DMA.
♦ TC — признак завершения счетчика циклов DMA.
Шина имеет и несколько служебных сигналов синхронизации, сброса и регенерации памяти, установленной на адаптерах.
♦ IOCHRDY (CHRDY, I/OCHRDY) — готовность устройства, низкий уровень удлиняет текущий цикл (не более 15 икс).
♦ BALE (ALE) — разрешение защелки адреса. После его спада в каждом цикле процессора линии SA[0:19] гарантированно содержат действительный адрес.
♦ REFRESH# (REF#) — цикл регенерации памяти (в XT называется DACK0#). Сигнал появляется каждые 15 мкс, при этом шина адреса указывает на очередную регенерируемую строку памяти.
♦ IOCHK# — контроль канала, низкий уровень вызывает NMI CPU (разрешение и индикация в системных портах 061h, 062h).
♦ RESET (RESDRV, RESETDRV) — сигнал аппаратного сброса (активный уровень — высокий).
♦ BCLK (CLK) — синхронизация шины с частотой около 8 МГц. ПУ могут не использовать этот сигнал, работая только по управляющим сигналам записи и чтения.
♦ OSC — несинхронизированная с шиной частота 14,431818 МГц (использовалась старыми дисплейными адаптерами).
Кроме логических сигналов шина имеет контакты для разводки питания +5, -5, +12 и -12 В.
Дополнительный разъем , расширяющий шину до 16-битной, содержит линии данных, адреса, запросов прерываний и каналов прямого доступа.
♦ SD[15:8] — шина данных.
♦ SBHE# — признак наличия данных на линиях SD[15:8].
♦ LA[23:17] — нефиксированные сигналы адреса, требующие защелкивания по спаду сигнала BALE. Такой способ подачи адреса позволяет сократить задержку. Кроме того, схемы дешифратора адреса памяти плат расширения начинают декодирование несколько раньше спада BALE.
♦ IRQ[10:12], IRQ[14:15] — дополнительные запросы прерываний.
♦ DRQ[5:7] — запросы 16-битных каналов DMA (положительным перепадом).
♦ DACK[5:7]# — подтверждение запросов 16-битных каналов DMA.
♦ DRQ0 и DACK0# — запрос и подтверждение 8-битного канала DMA, освободившегося от регенерации памяти.
Перечисленные ниже сигналы связаны с переключением разрядности данных.
♦ МEMCS16# (M16#) — адресуемое устройство поддерживает 16-битные обращения к памяти.
♦ IOCS16# (I/OCS16#, IO16#) — адресуемое устройство поддерживает 16-битные обращения к портам.
К новым управляющим сигналам относятся следующие.
♦ MEMW# (MWTC#) — запись в память в любой области до 16 Мбайт.
♦ MEMR# (MRDC#) — чтение памяти в любой области до 16 Мбайт.
♦ OWS# (SRDY#, NOWS#, ENDXFR) — укорочение текущего цикла по инициативе адресованного устройства.
♦ MASTER# (MASTER16#) — запрос от устройства, использующего 16-битный канал DMA на управление шиной. При получении подтверждения DACK[5:7] Bus-Master может захватить шину.
В шине EISA на дополнительных контактах слотов (недоступных картам ISA) располагается расширение шин данных и адреса до 32 бит, а также набор сигналов, обеспечивающих передачу данных в синхронном режиме с возможностью пакетных циклов.
Обычная передача данных
Для передачи данных от исполнителя к задатчику предназначены циклы чтения ячейки памяти или порта ввода-вывода, для передачи данных от задатчика к исполнителю — циклы записи ячейки памяти или порта ввода-вывода. В каждом цикле текущий (на время данного цикла) задатчик формирует адрес обращения и управляющие сигналы, а в циклах записи еще и данные на шине. Адресуемое устройство-исполнитель в соответствии с полученными управляющими сигналами принимает (в цикле записи) или формирует (в цикле чтения) данные. Также оно может, при необходимости, управлять длительностью цикла и разрядностью передачи. Обобщенные временные диаграммы циклов чтения или записи памяти или ввода-вывода приведены на рис. 6.2. Здесь условный сигнал CMD* изображает один из следующих сигналов:
♦ SMEMR#, MEMR# — в цикле чтения памяти;
♦ SMEMW#, MEMW# — в цикле записи памяти;
♦ IOR# — в цикле чтения порта ввода-вывода;
♦ IOW# — в цикле записи порта ввода-вывода.
Рис. 6.2 . Временные диаграммы циклов чтения или записи на шине ISA
В каждом из рассматриваемых циклов активными (с низким уровнем) могут быть только сигналы лишь из одной строки данного списка, и во время всего цикла сигнал AEN имеет низкий уровень. Цикл прямого доступа к памяти, в котором это правило не соблюдается, рассмотрен ниже, и в таком цикле сигнал AEN будет иметь высокий уровень. Сигналы SMEMR# и SMEMW# вырабатываются из сигналов MEMR# и MEMW# соответственно, когда адрес принадлежит диапазону 0-FFFFFh. Поэтому сигналы SMEMR# и SMEMW# задержаны относительно MEMR# и MEMW# на 5-10 нс.
В начале каждого цикла контроллер шины устанавливает адрес обращения: на линиях SA[19:0] и SBHE# действительный адрес сохраняется на время всего текущего цикла; на линиях LA[23:17] адрес действителен только в начале цикла, так что требуется его «защелкивание». Каждое устройство имеет дешифратор адреса — комбинационную схему, срабатывающую только тогда, когда на шине присутствует адрес, относящийся к данному устройству. В фазе адресации устройства еще «не знают», к какому из пространств (памяти или ввода-вывода) относится выставленный адрес. Но дешифраторы адресов уже срабатывают, и, когда в следующей фазе шина управления сообщает тип операции, адресуемое устройство уже оказывается готовым к ее исполнению. Если устройство использует линии LA[23:17] (они нужны лишь для обращений к памяти выше границы FFFFFh), то они на дешифратор адреса должны проходить через регистр-защелку, «прозрачный» во время действия сигнала BALE и фиксирующий состояние выходов по его спаду. Это позволяет дешифратору, всегда вносящему некоторую задержку, начинать работу раньше, чем поступит управляющий сигнал чтения или записи. При обращении к портам ввода-вывода сигналы LA[32:17] не используются.
Если устройство имеет более одного регистра (ячейки), то для выбора конкретного регистра (ячейки) ему требуется несколько линий адреса. Как правило, старшие биты шины адреса поступают на вход дешифраторов адреса, формирующих сигналы выборки устройств, а младшие биты — на адресные входы самих устройств. Тогда каждое устройство в пространстве будет занимать наиболее компактную область смежных адресов размером в 2n байт, где n — номер младшей линии адреса, поступающей на дешифратор. Из них реально необходимы 2m адресов, где m — номер самой старшей линии адреса, участвующей в выборе регистра устройства. В идеале должно быть n=m+1: при большем значении n отведенное (по дешифратору) пространство адресов не будет использовано полностью и регистры устройства будут повторяться в отведенной области 2n-m-1 раз, то есть у них появятся адреса-псевдонимы (alias). Адреса-псевдонимы будут отличаться от истинного адреса (минимального из всех псевдонимов) на K×2m+1, где K — целое число. Меньшее значение n недопустимо, поскольку тогда не все регистры устройства будут доступны задатчику. В принципе можно использовать дешифратор адреса, срабатывающий только на какой-то части адресов из области 2n (не кратной степени двойки), если устройству требуется «неудобное» количество регистров. Однако на практике «фигурное выпиливание» областей из пространства адресов обычно не делают, так что часть адресов может пропадать бесполезно.
Разрядность данных в каждом цикле обращения определяется потребностями текущего задатчика и возможностями исполнителя. В IBM PC/XT и системная шина, и шина ISA были 8-разрядными, так что вопросов согласования разрядности не возникало. В IBM PC/AT286 (и 386-SX) системная шина уже 16-разрядная, и в современных ПК с 32- и 64-разрядными системными шинами контроллер шины ISA является ее 16-разрядным задатчиком. На системной плате имеется «косой буфер», он же перестановщик байтов, который при необходимости транслирует данные с младшего байта шины на старшую или обратно. Логика управления этим буфером использует сигналы SBHE#, SA0, IOCS16# и MEMCS16#. Поддержка 16-разрядных передач сообщается адресуемым исполнителем сигналами IOCS16# и MEMCS16# при срабатывании его дешифратора адреса. Сигнал IOCS16# влияет только на разрядность обращений к портам, MEMCS16# — к памяти. Все операции обмена (транзакции) начинаются задатчиком единообразно, поскольку он еще не «знает» возможностей исполнителя. Развитие событий зависит от намерений задатчика и полученных сигналов разрешения 16-битных передач. В чисто 16-разрядных машинах начальный адрес однозначно соответствует передаваемому байту или младшему байту передаваемого слова[3]. В машинах с 32-разрядными процессорами начальный адрес, выставляемый на шине в начале транзакции, зависит от разрядности данных, запланированной задатчиком, и может зависеть от положения адресуемых данных относительно границы двойного слова (32 битного). 16-разрядные передачи выполняются за 1 цикл только при условии передачи по четному адресу (A0=0) и при ответе исполнителя сигналом IOCS16# или MEMCS16#, в иных случаях они разбиваются на два цикла. 32-разрядные передачи будут разбиваться на 2 (16+16), 3 (8+16+8) или 4 (8+8+8+8) цикла, в зависимости от возможностей исполнителя и четности адреса. Порядок, в котором передаются байты (во времени), неоднозначен (возможен как инкремент, так и декремент адреса), но в адресном пространстве они раскладываются по своим местам однозначно.
В табл. 6.4 приводятся состояния сигналов шины ISA для различных вариантов записи в порты ввода-вывода, проверенные экспериментальным путем. Вывод 16-разрядных данных выполнялся командой OUT DX, AX (в DX — адрес порта, в АХ — данные; AL содержит младший байт, АН — старший), вывод 8-разрядных — командой OUT DX, AL. Несколько неожиданные (для автора) варианты 3 и 6 с декрементом адреса, возможно, будут иметь место не на всех системных платах, но их следует иметь в виду при проектировании устройств, претендующих на глобальную совместимость. Правда на практике 16-битных передач по нечетным адресам обычно избегают (даже чисто подсознательно), и побочные эффекты от такого порядка маловероятны.
Таблица 6.4 . Состояние сигналов при 8- и 16-битных обращениях к устройству ISA
Сигнал (шина) | 1 цикл | 2 цикл |
1. Вывод 16-разрядных данных в 16-битное устройство по четному адресу | ||
SBHE# | L | - |
SA | DX(A0=0) | - |
D[15:8] | АН | - |
D[7:0] | AL | - |
IOCS16# | L | - |
2. Вывод 16-разрядных данных в 16-битное устройство по нечетному адресу ххх1, ххх5, xxx9, xxxD | ||
SBHE# | L | H |
SA | DX(A0=1) | DX+1 (A0=0) |
D[15:8] | AL | |
D[7:0] | AL | AH |
IOCS16# | L | L |
3. Вывод 16-разрядных данных в 16-битное устройство | ||
SBHE# | H | L |
SA | DX+1 (A0=0) | DX (A0=1) |
D[15:8] | AL | |
D[7:0] | AH | |
IOCS16# | L | L |
4. Вывод 16-разрядных данных в 8-битное устройство по четному адресу | ||
SBHE# | L | L |
SA[1:0] | DX(A0=0) | DX+1 (A0=1) |
D[15:8] | AH | AH |
D[7:0] | AL | AH |
IOCS16# | H | H |
5. Вывод 16-разрядных данных в 8-битное устройство по нечетному адресу ххх1, ххх5, xxx9, xxxD | ||
SBHE# | L | H |
SA[1:0] | DX(A0=1) | DX+1 (A0=0) |
D[15:8] | AL | |
D[7:0] | AL | AH |
IOCS16# | H | H |
6. Вывод 16-разрядных данных в 8-битное устройство по нечетному адресу xxx3, ххх7, xxxB, xxxF | ||
SBHE# | H | L |
SA[1:0] | DX+1(A0=0) | DX(A0=1) |
D[15:8] | AL | |
D[7:0] | AH | AL |
IOCS16# | H | H |
7. Вывод 8-разрядных данных в 16-битное устройство по четному адресу | ||
SBHE# | H | - |
SA[1:0] | DX(A0=0) | - |
D[15:8] | - | |
D[7:0] | AL | - |
IOCS16# | L | - |
8. Вывод 8-разрядных данных в 16-битное устройство по нечетному адресу | ||
SBHE# | L | - |
SA[1:0] | DX(A0=1) | - |
D[15:8] | AL | - |
D[7:0] | 0(AL?) | - |
IOCS16# | L | - |
Момент помещения действительных данных на линии SD[15:0] определяется управляющими сигналами чтения/записи, так что исполнителю не требуется синхронизация с тактовым сигналом шины. В циклах чтения адресованный исполнитель должен выдать данные на шину по началу (спаду) соответствующего сигнала чтения (IOR#, MEMR#, SMEMR#) и удерживать их до конца действия сигнала (пока не произойдет подъем сигнала). В циклах записи задатчик выставляет действительные данные несколько позже начала (спада) сигнала записи (IOW#, MEMW#, SMEMW#). Устройство-исполнитель должно фиксировать для себя эти данные в конце цикла по подъему сигнала записи. От устройства-исполнителя не предусматривается никаких подтверждений исполнения циклов; длительность цикла устанавливает задатчик, но исполнитель может потребовать удлинения или укорочения циклов. С помощью сигнала IOCHRDY исполнитель может удлинить цикл на произвольное число тактов, при этом задатчик будет вводить дополнительные такты ожидания (wait states). Обычно контроллер шины следит за длительностью цикла и по достижении критического времени принудительно его завершает (по тайм-ауту, возможно, и не сообщая об этом событии). Слишком длинные циклы тормозят работу компьютера, а превышение длительности 15 мкс может привести к сбою регенерации и потере данных в ОЗУ. С помощью сигнала 0W# исполнитель предлагает задатчику укоротить цикл, исключив такты ожидания. Реакция задатчика на одновременное использование сигналов IOCHRDY и 0WS# непредсказуема, этой ситуации следует избегать.
ВНИМАНИЕ
Некорректное управление сигналом IOCHRDY (его «залипание» на низком уровне) тормозит работу компьютера.
Номинальная длительность цикла определяется чипсетом и может программироваться в BIOS Setup заданием числа тактов ожидания (wait states). При этом циклы обращения к памяти, как правило, короче циклов обращения к портам ввода-вывода. Для управления длительностью цикла используются также сигналы управления разрядностью передачи: если устройство поддерживает 16-битные передачи, предполагается, что оно может работать с меньшим количеством тактов ожидания. Этим объясняется, что в BIOS Setup длительности циклов ISA задаются раздельно как для памяти и ввода-вывода, так и для 8- и 16-битных операций.
Кроме длительности цикла, устройства могут быть критичны к времени восстановления (recovery time) — длительности пассивного состояния управляющих сигналов чтения-записи между циклами. Этот параметр также может программироваться в BIOS Setup и тоже раздельно для 8- и 16-разрядных операций.
Карты расширения для подключения к шине данных, как правило, используют буферные микросхемы, раздельные для линий SD[7:0] и SD[15:8]. Здесь широко применяются микросхемы 74ALS245 (1533АП6) — 8-разрядные двунаправленные приемопередатчики. Буфер должен открываться сигналом ОЕ# (Output Enable — разрешение выхода), когда на шине адреса присутствует адрес, относящийся к диапазону адресов подключаемого устройства. «Дежурным» является направление передачи «от шины — к устройству»; переключение в обратную сторону производится по сигналу IOR#, если устройство представляет порты ввода-вывода, или MEMRD#, если устройство приписано к пространству памяти. Таким образом, буферы имеют право передавать данные на шину (управлять шиной данных) только во время действия сигнала чтения, относящегося к зоне адресов данного устройства. Карта расширения может являться комбинацией 8- и 16-битных устройств; например, некогда популярные мультикарты содержали 16-битный адаптер ATA и набор 8-битных контроллеров портов COM, LPT, GAME и контроллера НГМД. В таких картах логика управления буферами и сигналами IOCS16# и MSC16# управляется сигналами от дешифратора адреса. Если устройство по данному адресу является 8-разрядным (не формирует сигналы IOCS16# или MSC16#), то оно имеет право разрешать чтение только через буфер линий SD[7:0], а буфер старших линий SD[15:8] (если он имеется на карте) должен быть переведен в третье состояние. Если устройство по данному адресу является 16-разрядным, то оно формирует сигнал IOCS16# или MSC16#, а разрешением буферов управляют сигналы SBHE# и SA0. В этом случае буфер линий SD[7:0] разрешается только при SA0=0, а буфер линий SD[15:8] разрешается только при SBHE#=L. Некорректное разрешение буферов может приводить к их конфликту с перестановщиком байтов системной платы и искажениям данных.
Восьмиразрядные устройства (например, микросхемы 8255, 8250, 8253 и т. п.) следует подключать только к линиям SD[7:0] и при обращении к ним не формировать сигналы IOCS16# или MSC16#. Никакие «косые» буферы (перестановщики байтов) на интерфейсных картах не нужны.
В одном из источников описывается эффект перестановки байтов при обращении к порту ввода-вывода: «Если прочитать слово из порта по четному адресу, значение одно, а если по нечетному — старшие 8 бит предыдущего значения становятся младшими, а старшие нового = FFh». Первые подозрения падают на ошибку в логике управления буферами. На самом деле все объясняется гораздо проще. Пусть имеется устройство с двухбайтным регистром, младший байт которого имеет адрес R0 (четный), старший — R0+1, а по адресу R+2 устройство (и никакие другие) не откликается. Пусть в данный момент в нем записано число AA55h, тогда чтением порта по команде IN AX, R0 получим в регистрах процессора AL=55h, AH=AAh. Теперь если попытаться его «прочитать по нечетному адресу», то есть командой IN АХ, R0+1, то получим AL=AAh (содержимое R0+1, к которому мы на самом деле и адресовались!)