
Топология шины PCI Express декларирует соединение двух ее агентов между собой по схеме «точка-точка». Параметры каждого линка — предмет особого внимания процедур BIOS. На этапе выполнения POST его задача состоит в том, чтобы определить функциональность таблично заданных агентов и подготовить их для операционной системы с помощью специальной процедуры, которая называется Link Training.
Инициализационные процедуры должны определить разрядность шины PCIe и проверить ее готовность к работе в заданной полосе пропускания. Кроме того, выполняется еще ряд манипуляций в конфигурационном PCI-пространстве, на которых мы останавливаться не будем, ограничив эксперименты стартовой процедурой, направленной, как следует из ее названия, на запуск и «тренировку» шинных соединений. Операционная система принимает в эксплуатацию PCIe-подсистему как данность, и обычно не переопределяет ее параметры. Из этого правила есть одно маленькое, но очень существенное исключение: функциональность PCIe-шины предполагает «горячую» замену плат расширения (только при наличии поддержки со стороны платформы). А это значит, что процедура Link Training не запрещается после ее выполнения в BIOS и может в любое время потребоваться для нужд операционки.
Постановка задачи
Реализация задуманного потребует повторного инициирования процедуры Link Training для заданного PCIe-порта уже после старта платформы.
В структуре PCI Express Capability Structure есть регистр Link Control Register. Его бит Retrain Link можно установить в «единицу» для запуска процедуры Link Retrain. Статус ее завершения можно проконтролировать по состоянию бита Link Training в регистре Link Status Register.
Если эксперимент будет успешным, мы можем рассчитывать на следующие бонусы тестирования:
- PCIe-контроллер будет аппаратно генерировать импульсные последовательности, заданные его разработчиком, оптимизированные для проверки соединительных цепей и пригодные для наблюдения внешними приборами.
- PCIe-контроллер при выполнении процедуры Link Training диагностирует функциональность линий заданного порта, и аппаратное отключение неисправных, выполняется только по результатам проверки. Мы ожидаем, что импульсы должны наблюдаться по всем линиям, что должно решить известную проблему с недоступностью неисправных линий Rx(i), Tx(i) из-за аппаратного их отключения на этапе POST.
- Процедура Link Training допускает цикличное выполнение. Результаты каждой итерации можно выводить в диагностический порт и мониторить их с помощью POST-карты. Например, порт 80h будет отображать разрядность шины, а в порт 81h — частоту. Предполагается, что для удобства данные визуализируются в двоично-десятичной системе: код 2516h будет означать полосу пропускания в 2.5GT/s на 16-ти битной шине.
- В качестве самопроверки можно намеренно вносить искажения путем замыкания керамических конденсаторов либо изоляцией ламелей PCIe-устройства, контролируя при этом статус процедуры Link Training на индикаторе POST-карты.
К недостаткам эксперимента (или чтобы сохранить лицо, скажем, — к особенностям :) можно отнести требование того порядка, что в список тестируемых линков будут включены только те из них, к которым подключены заведомо исправные бортовые контроллеры либо контроллеры, установленные в неповрежденный PCIe-слот. Связи, обеспечивающие «пустые» слоты, отслеживаться не могут по определению. Из точки А шагнуть в неизвестность не представляется возможным. Процедура BIOS POST обычно отключает PCI Express мосты, если не найдено подключенных к ним устройств. Поэтому, регистры, требуемые для выполнения эксперимента, будут недоступны в конфигурационном пространстве.
Описание эксперимента
Программный макет планируется отладить в среде MS-DOS, после чего возможна его реализация в виде UEFI-приложения или интеграция в Legacy BIOS. В качестве среды программирования используется язык ассемблера в версии Borland: TASM, TLINK и Turbo Debugger. Листинг программы приведен в Приложении.
Для последующей интеграции в BIOS намеренно не используются сервисные функции PCIBIOS (INT 1Ah) в силу того, что этот сервис может быть недоступен на момент выполнения макета в составе POST-процедуры. Доступ к PCI-пространству выполняется через порты Config_Address и Config_Data (0CF8h, 0CFCh).
Для простоты реализации макет не сканирует все конфигурационное пространство для поиска всех доступных PCIe линков. Адрес, задающий тестируемый порт, передается в виде константы BusDevFncReg, которую нужно установить вручную перед ассемблированием. Обращения к INT 16h и INT 21h, необходимые в DOS версии, потребуется убрать при интеграции в BIOS.
С целью адаптации эксперимента для ряда платформ NVidia, некорректно отрабатывающих 16-битный вывод в порт 80h, помимо коррекции константы BusDevFncReg, также потребуется изменить адрес порта на значение 1080h, инструкцию out 80h,ax заменить на последовательность:
mov dx,1080h
out dx,ax
Кроме того, переключить POST-контроллер IC80v5 на использование порта 1080h.
Программа циклически выполняет Link Training и выводит в диагностические порты его результаты: порт 80h — Width (разрядность), порт 81h — Speed (скорость). При ошибке программа завершается шестнадцатибитным выводом в порт 80h значения 0FFFFh. Штатно работу эскизного макета можно прекратить, нажав любую клавишу. В этом случае в порт 80h выводится значение 0000h.
Программа была проверена на плате с чипсетом i915 (ASUS P5GPL-X). Тестировался 16-битный PCI Express порт между северным мостом и видеокартой ATI Radeon X800. При отсутствии ошибок: Speed=2.5 Gb/S, Width=16 bit, как и должно быть. В 16-битный порт 80h выводится код 2516h.
Если во время выполнения нашего теста имитировать короткое замыкание между линиями PCI Express, программа детектирует ошибку. Детально увидеть процессы по линиям Rx, Tx осциллограф с полосой пропускания 100 МГц не позволяет, но вносимые замыкания влияют на статус контроллера, а значит, Link Training выполняется. На испытуемой платформе, искусственное внесение ошибок препятствует завершению процедуры Link Training, в результате происходит выход по таймауту и программа завершается с выводом на индикаторы пост карты кода FFFFh.
Информация о разрядности и частоте шины PCIe доступна в статусном регистре и без повторного выполнения Link Training в сеансе ОС. В этом случае данные параметры являются результатом выполнения Link Training при старте платформы. Именно поэтому были необходимы самопроверка с искусственным внесением ошибок непосредственно во время выполнения нашей программы, а также анализ времени выполнения процедуры, о котором будет идти речь ниже. Так мы убедились в том, что на испытуемой платформе Link Training в сеансе ОС действительно выполняется.
Для наборов системной логики и видео адаптеров NVidia, характерна поддержка переключения на меньшую разрядность шины PCI Express, если часть линий неработоспособна. На плате ASUS A8N-E (AMD Socket 939, Nvidia nF4) в сочетании с видеокартой ASUS EN9800GT мы изолировали контакты старших восьми линий шины PCI Express бумажной вставкой. В результате, при старте платформы, шина инициализировалась в режиме 8 бит и работоспособность видео адаптера сохранилась. При запуске нашей программы в сеансе ОС, на POST-карте получаем код 2508h. В режиме нормальной эксплуатации поддерживается разрядность в 16 бит, что подтверждается показаниями POST-карты:
Настройка на топологию платформы
Выбор адреса тестируемого PCIe-порта устанавливается вручную до ассемблирования программы. Для этого следует отредактировать константу BusDevFncReg.
Константа содержит битовые поля Bus, Device, Function, Register, задающие адрес в конфигурационном пространстве PCI. Эти параметры должны соответствовать адресу контроллера PCI Express, соответствующего тестируемому порту и представленному в конфигурационном пространстве как мост PCI-PCI. Параметр Register должен соответствовать адресу регистра Link Control внутри структуры PCI Express Capability. Смещение этого регистра относительно базового адреса структуры PCI Express Capability равно 10h. Заметим, что второй используемый нами регистр — Link Status имеет смещение 12h и находится в пределах того же 32-битного слова, что упрощает программное взаимодействие с ними. Базовый адрес структуры PCI Express Capability можно узнать из документации на чипсет, либо, если она недоступна, проследив цепочку Capability-структур в блоке конфигурационных регистров моста PCI-PCI, найти искомую структуру можно по Capability ID = 10h.
В соответствии со спецификацией PCI, битовые поля 32-битного регистра Configuration_Address, а значит и константа BusDevFncReg, формируются следующим образом:
D [31] = 1 for enable configuration space access
D [30-24] = 0000000b, reserved
D [23-16] = PCI Bus Number, 8-bit
D [15-11] = PCI Device Number, 5-bit
D [10-08] = PCI Function Number, 3-bit
D [07-00] = PCI Register Number, 8-bit, aligned by 4, bits [1-0] = 00b.
В экспериментах использовался диагностический контроллер IC80 V5.0 производства компании IC Book Labs. Устройство обеспечивает 16-битный вывод и возможность переназначения адреса диагностического порта, что существенно для обеспечения совместимости с некоторыми платформами. POST-карта также обеспечивает пошаговый режим с ожиданием нажатия кнопки после вывода каждого диагностического кода. Эта функция будет полезной при интеграции предлагаемого ассемблерного фрагмента в BIOS, так как делает возможным наблюдение быстропротекающих процессов при инициализации платформы.
Несколько слов об оценке времени выполнения процедуры Link Training. После ее завершения, в момент перехода на метку Train_Stop, регистр CX, используемый как декрементируемый счетчик цикла при ожидании выполнения Link Training, будет содержать 0, если имеет место одна из двух ошибок:
- Процедура не была запущена, контроллер сообщил о готовности на первой итерации цикла ожидания, то есть неожиданно быстро.
- Выход по таймауту, выполнено 65536 итераций, контроллер не сообщил о готовности.
Ненулевое значение CX может использоваться для оценки времени ожидания. Количество выполненных итераций равно разности 65536-CX. Например, CX=FFFFh означает выход после первой итерации, CX=FFFEh после второй, и так далее. Время выполнения одной итерации зависит от времени чтения регистра Configuration_Data и может быть различным у различных платформ. При необходимости точно измерить время выполнения, в программу следует добавить операции с системным таймером или TSC. А для определения причины ошибки, вызвавшей нулевое значение CX, может потребоваться дополнительный анализ статуса.
Справочная литература
Intel 915G/915GV/915GL/915P/915PL/910GL Express Chipset Datasheet. February 2005. Document number: 301467-005
- LCTL — Link Control (D1:F0) на странице 155.
- LSTS — Link Status (D1:F0) на странице 156