Диагностика PCI Express с помощью Link Training

Эскиз к диагностике шины PCI Express с помощью Link Training

Топология шины 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.

Если эксперимент будет успешным, мы можем рассчитывать на следующие бонусы тестирования:

  1. PCIe-контроллер будет аппаратно генерировать импульсные последовательности, заданные его разработчиком, оптимизированные для проверки соединительных цепей и пригодные для наблюдения внешними приборами.
  2. PCIe-контроллер при выполнении процедуры Link Training диагностирует функциональность линий заданного порта, и аппаратное отключение неисправных, выполняется только по результатам проверки. Мы ожидаем, что импульсы должны наблюдаться по всем линиям, что должно решить известную проблему с недоступностью неисправных линий Rx(i), Tx(i) из-за аппаратного их отключения на этапе POST.
  3. Процедура Link Training допускает цикличное выполнение. Результаты каждой итерации можно выводить в диагностический порт и мониторить их с помощью POST-карты. Например, порт 80h будет отображать разрядность шины, а в порт 81h — частоту. Предполагается, что для удобства данные визуализируются в двоично-десятичной  системе: код 2516h будет означать полосу пропускания в 2.5GT/s на 16-ти битной шине.  
  4. В качестве самопроверки можно намеренно вносить искажения путем замыкания керамических конденсаторов либо изоляцией ламелей 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 Tra­in­ing, будет содержать 0, если имеет место одна из двух ошибок:

  1. Процедура не была запущена, контроллер сообщил о готовности на первой итерации цикла ожидания, то есть неожиданно быстро.
  2. Выход по таймауту, выполнено 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