Лекция 5 (2012-11-12)
Взаимодействие с периферией. PCIe.
Небольшая перестановка в плане курса.
Сегодняшняя тема -- периферия.
На предыдущей лекции был рассказ про память. Перескажем ее минут за 5.
Различают
- энергозависимую память
- SRAM ячейки на транзисторах
- DRAM отвратительный по интерфейсу способ, но хорош тем, что там только один конденсатор и один транзистор. Конденсатор может накапливать заряд, его там можно удреживать, а при появлении напряжения его разрядить. Отсюда недостатки - медленное, надо периодически перезаряжать. Был расмотрен интерфейс взаимодействия с драм памятью, в котором адресация выполняется по строкам и столбцам. Память драм представлена набором двумерных массивов (4-8-16), что позволяет считывать несколько бит параллельно. Были рассмотрены
- FPM DRAM
- (B)EDO DRAM
- DDRx SDRAM - отдает биты на удвоенной (х2, х4, х8) эффективной частоте. Связано с тем, что этот массив ячеек выгодно не разгонять, а увеличивать объемы, а скорость увеличивать за счет буферизации. Поэтому с каждым поколением DDR растет лэтенси в тактах и способствует работе с более крупными блоками.
- энергонезависимую память
Было рассмотрено взаимодействие процессора и памяти. Кэши инструкций. Блок MMU -- аппаратная поддержка виртуальной адресации (преобразование виртуальных адресов в физические). Чтобы это преобразование работало сколь либо эффективно, т.к. это страничная организация памяти, при адресации нескольких гигабайт страниц миллионы, хранение в виде линейной структуры не способствует эффективности поиска, поэтому используется иерархическая структура. Чтобы это работало эффективно используется TLB -- это тот же кэш, но обычно с полной ассоциативностью, его так же может быть несколько уровней.
Перифeрия
Нам бы хорошо бы взаимодействовать с внешним миром.
Есть периферийный устройства. Взаимодействие происходит различными способами
- memory mapped io чтение и запись в некие проассоциированные виртуальные порты
- PIO/ DMA -- некий способ отображать память устройств в адресное пространство процессора, а для устройств механизм изменения памяти хоста. Хост это связка процессор-память, устройство -- некое периферийное устройство.
Все упирается в физический уровень
- последовательные протоколы. Малое количество управляющих сигнальных линий для передачи данных, передача каким-либо образом сериализуется и реализуется какой-либо высокоуровневый протокол.
- Пример -- интерфейс JTAG, IEEE1149, служит преимущественно для чтения и записи внутренних регистров некоего устройства, в основном в отладочных целях.
В нем есть несколько линий. Тригеры соединяются в цепочку, и есть комбинаторная обвязка, включающая его в определенном режиме. Связываете такие ячейки набором триггеров, Все регистры объединяете вместе, три цепочки по несколько сотен тысяч бит, дальше путем тактирования можете продвигать значения этих бит. Чудесный интерфейс, в принципе один провод, на самом деле нет. Позволяет не только считывать, но и записывать значения в регистры. Позволяет остановить устройство, считать значения, понять что происходит (попытаться) потом записать и дальше. Хотя не все современные устройства позволяет так просто остановить клок. Например, PCI Express (??). Схема.- I^2C. Inter Integrated circuit. Интерфейс взаимодействия между интегральными схемами. Всего два сигнала SCL(clock) и SDA(data).
Устройства разделяются на мастер и слейв. Кодирвание за счет взаимного положения поднимаюшихся и опускающихся фронтов. Схема. Идея в том, что за счет взаимного расположения фронтов клока и данных, например если клок хай, то это старт условие с которого начинается передача данных. Довольно простая кодировка для передачи битов. Формат простой -- есть старт условие, адрес, бит чтения/записи, бит A, Data, A, P. Идея в том, что управляя этими сигналами, то мастер, то слейв померенно, мастер говорит что передает некий адрес, чтение запись и ждет подтверждения. Подтверждение делается так -- поднять Data флаг. Если у нас например запись, то потом у нас идут данные, 8 бит, после каждого байта ожидается подтверждение. Чтение аналогично. Всего две линии, но за счет кодировки можем передавать со скоростью больше 100 КГц. Прост в разводке. - параллельные протоколы. Обычно ориентированы на большое количество линий, доп. информация о разборе сообщений может идти доп. сигнальными линиями. Интерфейс с памятью -- один из видов параллельного протокола. DRAM параллельный, доп. линии говорят читаем мы или записываем, и вообще всякое.
- В противоположность I^2C в PowerPC используется протокол DCR. Там сигналов -- read, write, privilege, data [0..31], addr[0..31], master[0..31]. Этот интерфейс используется, смешно сказать, для чтения регистров. Но в нем можно видеть, что там сотни линий. Но в принципе все просто, принимаешь соответствуюшие битики и куда надо посылаешь. Нет никакой комбинаторной сложности в передаче, потом ожиданий, итд.
Параллельные интерфейсы были популярны по двум причинам
- проще логика разводки
- повышение скорости с повышением количества линий
Но возникала проблема -- выравнивание дорожек. 8 выровнять ещё можно, то 100 уже печально, особенно если разные устройства висят на одной шине. Пример перехода от грустно к чуть менее грустно это эволюция от ISA до PCI Express. В х86 это основной интерфейс, подключенный непосредственно к процессору. Их может быть несколько, последовательный порт, параллельный порт, но все остальные интерфейсы глобально и надежно периферия кард интерконнект. PCI (Perepherical Card Interconnect). До этого были (E) ISA. Первоначально ISA Это Industrial Standart ARchitecture. Была 8-битная шина, устройства подключались последовательно, позволяли передавать данные. В основном управлялось портами ввода-вывода. Потом появилось возможность управления, потом стала 16-битной, но это все совсем страшное легаси, хотя и до сих пор встречается. А потом появилась 32-разрядная PCI. Схема. В стандарте можно было иметь до 8 шин на каждой по 10 устройств. Много устройств на одной шине -- проводов меньше, но работает со скоростью самого медленного устройства. Выход несколько шин, но это требует пропорционального количества проводов.
Оснавная идея шины PCI достаточно простая. Хотим преимущественно читать или писать. Есть мастер, есть таргет, мастер может читать или передавать данные бёрстами. Шина 32-разрядная. Есть 32 бита данных, есть 32 бита на адрес и есть пачка служебных сигналов. Схема. Сигналы addr [0..31], data[0..31], clk, trdy, irdy, select, frame, devsel, jtag [0..4], etc. Шина PCI жила несколько дольше чем хотелось бы. Есть некий арбитр, который говорит, ты можешь что-то поделать (выставляется сигнал REQ) Пары req gnt заводились на каждый арбитр (каждое устройство) независимо. Когда устройство хотело что-то передать оно посылало REQ, потом поднимало бит адреса, получало сигнал, каждый знал свой диапазон адресов и соответственно отвечал, после чего начиналась собственно передача. Тактировалось по внешнему клоку. Клок мог иметь довольно произвольную частоту. Тот кто им управлял мог его полностью остановить. Изначально диапазон был 16-33Мгц до полной остановки, потом ограничение снизу сняли. Это частота и ширина 32 бита давали не очень большую скорость. Это повлекло расширение PCI -- до 64 бит, потом ещё было расширение до 66 мегагерц, в PCIx ещё в 2 раза частоту разогнали, что давало аж до Гб/сек, но это все было дорого. Поэтому произошел переход на шину PCI Express, тогда же примерно произошел переход от параллельного ата к последовательному.
PCIe
Достаточно интересный стандарт -- PCI Express. 3-я версия около 800 страниц. У стандарта PCI все было скромнее -- 200-300 страниц. PCI во многом определяет электромеханические особенности работы, это довольно значительная часть протокола. В противоположность этому в стандарте PCI экспресс гораздо больше уходит на логику.
В PCIe несколько лэйеров
- TLP транзакций
- DLLP -- как работает точка-точка.
- link layer инициализация линка, логика среды передачи данных. Два подуровня -- логический и физический.
У PCIe 3 версии
- PCIe gen1 - 2,5GT/s -- гигатрансферы в секунду. В реале 2 гигабита на линию(??). Стандарт поддерживает передачу по нескольким лэйнам.
- PCIe gen2 5 GT/s
- PCIe gen3 8 GT/s -- улучшили схему кодирования, вместо 8/10 стали использовать основанную на стейт машине схему 128/130. 125 пикосекунд.
Это очень красивые чиселки. Если у вас 16 лэйнов, то 16*8 это 16 гигабайт в секунду в одну сторону, очень много. Скоро ещё удвоят.
Если говорить более предметно, то PCIe определяет некоторую топологию устройств PCIe root complex -- некое устройство, с одной стороны корень иерархии, с другой стороны взаимодействует с хостом, преимущественно с его памятью. Далее топология имеет древовидную структуру, есть энд-пойнт девайсы, есть свитчи, есть всякие бриджи на PCI, которые могут подключать PCI устройства и обеспечивать интероперабельность между PCIe и PCI устройствами.
Есть некие сообщения которыми устройства обмениваются между собой. Чаще всего ендпойнт обмениваетс с хостом, или еп с еп. Есть ещё отдельно флоуконтрол.
Продолжение идеи PCI что отдельно выполняются запись и чтение. Посылается сообщение что происходит операция с такой то памятью. Сообщения имеют размер кратный DWORD (32 Бита). Есть префикс для служебной информации. Основная идея что у нас есть хедер, который имеет размер 2 дворда, определяет тип и разлиные характеристики, например таргет. В зависимости от типа определяется формат и размер заголовка.
Бывают операции, операций довольно много. Можно выделить 4 блока
- Memory. Операции с памятью. Чтение, запись, атомарные операции (какие) (начиная с стандарта 2.1). В принципе рут комплекс должен уметь говорить, что он умеет.
- IO. Это такое легаси. PCIe это такой инновационный протокол, но вот есть PCI железка, хочется к ней прикрутить PCIe, но не перекореживать всю логику, потому что ее может быть много разной. Есть два способа возбуждения сигнальных интерраптов -- вне сигнальной шины, использует выделенные сигналы, отдельные 4 дорожки, которые можно поднять, у неё возбуждалось желание, процессор поднимал, что поднялось, а потом устройство могло опустить. Это механизм при масщтабируемости стал печальным, поэтому перешли на другой -- специального вида сообщения, запись в определенный участок памяти, который специальным образом отмаплен и обрабатывается хостом. Легаси устройства могут многое, до сих пор присутствуют уже в третьей версии стандарта и не собираются уходить. При разработке новых устройств использовать эти механизмы не рекомендуется.
- Message. Используется для всяких сообщений -- прерывания, о питании, вендор-специфик месседж.
- Config. Работа с конфигурационным пространстов. Появилось ещё в PCI. У каждого устройства подразумевается некое адресное пространство, в котором это устройство всяко разно описано -- вендор ид, девайс ид, класс, фанкшн. Схема. Может поддерживать разные фичи, например ссылка на следующий экстеншн. Таким образом устройство может декларировать что поддерживает M?SI. Ещё устройство может декларироать, что у него есть некоторые участки памяти, отражающиеся в его. Базовые адресные регистры -- 4 младщих бит говорят тип, потом несколько бит захардварены в ноль, остальные просто захардварены. Чтобы понять его размер туда писали единички и их считали (?). Туда писался ио регион, ???. Далее всякие настройки питания, дальше шли всякие фичи. Всякие капабилити, например, максимальный размер пейлоада и запроса на чтение. Это характеристика ограничивающая как рут комплекс так и девайсы. У девайсов есть размер буффера, у подсистемы тоже есть ограничение.
В PCIe появилось более продвинутое Message Signal Interupr -- MSIx, проверяет до 4 тысяч. Немножко разный формат сообщений.
На уровне Transation Layer Protocol определены правила формирования транзакций, возможности по реордерингу, что делать если вы не умеет обрабатывать такой тип. Не одна сотня страниц посвящена тому, как рут комплекс должен обрабатывать разные типы сообщений.
На Datlink Layer Protocol добавляется чексумма транзакции (32 бита в концу) и 16 бит в начале -- номер транзакции для флоп контролл(?). Ожидается, что на этом уровне сообщения идут последовательно, если после н приходит н+2 вы по обратному каналу это сообщаете. Идея в том, что определяется закон обратной доставки и определяются кредиты для флопп контролл. В конце сообщается сколько места в буфере осталось под головы и вообще. Обеспечиваете, то не произойдет денайал оф сервис, а другая сторона будет ждать пока не придет достаточно кредитов чтобы продолжит передачу.
TLP добавляет маркеры конца и начала транзакций. Определяет, что должно происходить когда ничего не предается, что-то передается. В этом начинаются отличия ген3, изза другого кодирования на малых транзакциях может быть чуть похоже.
На верхнем уровне линк лэйера у вас есть несколько лэйнов и вам надо передать, например байт. Вы его раскладываете по лэйнам, забиваете лишнии, итд.
На этом же уровне вводится стейт машина. Есть начальное состояние, если появляется вольтаж, начинаете посылать синхропакеты, потом 2 конфиг пакета, потом линк поднялся. ???.
Это был сумбурный рассказ про PCIe. Что можно подчеркнуть. На данный момент это один из наиболее развитых способов передачи данных в малых и средних эвм, особенно в х86, а так же немного в паверах и спарках, хотя там и очень много интел специфичного, особенно в порядке байт. Основным конкурентом является гипертранспорт, который немножко умер, хотя по характеристикам и плюс-минус сопоставим.
В следующий раз про периферийные интерфейсы -- usb, firewire, sata.