В практике тестовых лабораторий нередко возникают ситуации, когда приходится удаленно работать с аппаратным обеспечением недоступным по сети. Незаменимым помощником в этом случае может оказаться программная оснастка для сохранения профилей оборудования. В этом смысле рапорты информационно-диагностических утилит давно стали своего рода эталоном. К сожалению, их вторичность и уровень детализации не всегда удовлетворяет взыскательного исследователя.
Как сохранить главный профиль современной платформы — образ конфигурационного PCI-пространства — в двоичный файл? Архитектура нынешних PC-платформ такова, что для этого требуется доступ к memory-mapped диапазону, базовый адрес и размер которого декларируется в ACPI-таблице с сигнатурой «MCFG». Постараемся выполнить этот эксперимент на стенде, где хозяйничает материнская плата ASUS TUF Gaming X570-Plus, которая оснащена системной логикой AMD X570. Посмотрим заодно, что там интересного, заглянув в регистровые поля с помощью RWEverything.
Установив RWEverything, открываем два ее окна: «ACPI» (отмечено красным) и «Memory» (если что — третья слева). В окне ACPI переходим на закладку MCFG (выделена розовым цветом), а в Memory кликаем на вторую слева иконку «Save as binary» (она у нас на розовом фоне).
Осталась пара пустяков: ввести стартовый и конечный адреса нужного нам региона памяти. Первый из них нам поможет определить закладка MCFG в окне ACPI — он там указан, как базовый и равен F8000000h (красное подчеркивание).
Размер диапазона равен количеству шин, умноженному на 1 MB — для представления конфигурационной информации используется именно 1 MB данных на каждую PCIe-шину. Значение 3Fh соответствует шине 63. С учетом того, что нумерация выполняется с 0, максимальное количество шин равно 64.
Диапазон размером в 64 MB адресуется от 00000000h до 03FFFFFFh, всего — 4000000h байт. Это шестнадцатеричное число и соответствует объему нашего 64MB-пространства. Сложив его с базовым адресом диапазона, получим:
End Address = F8000000h + 03FFFFFFh = FBFFFFFFh
Можно приступать к сохранению, которое выполняется очень и очень небыстро. Стоит набраться терпения до окончания операции — и бинарный файл готов. Это саязано с тем, что время выполнения операции зависит от размера двоичного образа и таймингов системной логики. Типовое значение составляет единицы-десятки минут. Мониторинг процесса лучше всего вести открыв каталог, где находится сохраняемый файл.
В типовой системе количество реально используемых номеров шин значительно меньше ограничения, обусловленного размером диапазона. Максимальное количество устройств на шину (32) и функций на устройство (8) также, как правило, не используется. Это означает, что двоичный файл содержит разреженные данные и может быть эффективно упакован архиватором.
Полученный дамп можно проанализировать с помощью программного обеспечения JavaCrossPlatformPciDump.
Замечания и уточнения
Численные значения базового адреса диапазона и количество шин являются параметрами, зависящими от конфигурации платформы. Обновление UEFI, изменения в состоянии опций CMOS Setup, добавление или удаление оборудования может привести к другому результату. Об этом стоит помнить перед каждой операцией сохранения образа конфигурационного PCI-пространства.
Системы с несколькими сегментами PCI Express шин (например, Intel VMD/VROC) опционально могут содержать несколько диапазонов MCFG — по одному диапазону на шинный сегмент. Описанная методика поддерживается для системных плат не только с шинами PCI Express, но также и с PCI-X топологией. Разумеется, речь идет о поддержке конфигурационных механизмов, а не о наличии физических слотов.
Для платформ более ранних поколений, не использующих диапазон MCFG, один из вариантов решения может состоять в написании программы, последовательно считывающей информацию, используя порты:
- 0CF8h = CONFIGURATION ADDRESS
- 0CFCh = CONFIGURATION DATA
Код, осуществляющий данную операцию, должен иметь привилегии Ring 0 в операционной системе — выполняться в режиме Kernel Mode драйвера, либо запускаться в среде DOS или UEFI. Вместо непосредственного доступа к портам, в зависимости от контекста, можно использовать функции Legacy PCI BIOS или EFI PCI I/O Protocol. Удачи!