Точные детали записи байта в адресное пространство PCIe от процессора - PullRequest
0 голосов
/ 18 октября 2019

Я очень озадачен серией шагов , точных , которые связаны с тем, что процессор записывает значение в память карты PCIe. Очень трудно понять точное значение того, что вы читаете в Интернете, поэтому я надеюсь, что кто-то сможет прочитать мою теорию о том, что происходит, и указать на любые ошибки.

Настройка

Предположим, у меня есть карта PCIe с некоторым объемом памяти. Для обсуждения предположим следующую конкретную настройку:

  • Имеется 4 МБ для доступа через регистр базового адреса 0 (что бы это ни значило)
  • Это единственная карта PCIeво всей системе
  • Он подключен к слоту PCIe, который соединяется с корневым комплексом через медные провода в материнской плате
  • Существует корневой комплекс, подключенный непосредственно к шине ЦП (этокак все нормально?)
  • PCIe-карта каким-то образом настроена на устройство с номером 0 (как это делается?)
  • Мы используем Linux.

Давайте также остановимся на терминологии:

  • Системная шина - это собственная шина ЦП.
  • Шина PCIe связывает буквенные провода на материнской плате между процессором и слотом PCIe
  • Драйвер - это модуль ядра Linux
  • A устройство - это буквальный физический объект
  • A структура устройства - это pci_dev структура, заполненная ядром
  • A BAR (регистр базового адреса) - это поле в конфигурационном пространстве устройства PCIe
  • A BAR-пространство - это адресное пространство, которое обозначается (?) Значением в BAR.

Моя теория о том, что происходит

  1. Во время загрузки Linux начинает проверять разные адреса, чтобы выяснить, есть ли там что-нибудь.

    • Поскольку провода шины PCIe подключаются к проводам системной шины только через мост (т. Е. Контроллер PCIe на системной шине), Linux должен знать, как взаимодействовать с контроллером PCIe.
    • Linux отправляет специальные командык контроллеру PCIe (через IO?), что в конечном итоге тривывод правильной последовательности напряжений на проводах PCIe
    • Если он получит ответ, он заполнит структуру pci_dev другой информацией в пространстве конфигурации
    • В какой-то момент в будущем(когда?) ядро ​​будет перебирать список драйверов PCI, чтобы попытаться сопоставить их с устройствами
  2. Когда Linux обнаружит устройство, оно отобразит свое пространство BAR на системную шину. (Как это сделать?) Предположим, он отображает пространство BAR0 по адресу 0x55500000 на 0x5550FFFF на системной шине.
    • Linux должен сообщить корневому комплексу, чтобы он прослушивал эти адреса и соответствовал ли он обнаруженной карте PCIe.
    • Кстати, Linux установит регистр базовых адресов 0 на нашемКарта PCIe должна иметь 0x55500000 в поле базового адреса (зачем?)
  3. Последующие записи на системной шине между 0x55500000 и 0x5550FFFF "перехватываются" корневым каталогомсложный и выданный на карту PCIe
    • Корневой комплекс, по сути, создаст пакет, объединит все заголовки и контрольные суммы и тому подобное и вытолкнет их через медные провода материнской платы в слот PCIe
  4. Предположим, что ЦП записал 0xDEADBEEF по адресу 0x55501230 на системной шине, и что корневой комплекс отправил пакет на карту PCIe, карта получает пакет и записывает 0xDEADBEEF в 0x01230 в локальной 4 МБ памяти

Итак: какие части этого правильные, а какие неправильные?

1 Ответ

1 голос
/ 01 ноября 2019

Мой опыт работы с процессорами Intel, поэтому некоторые подробности ниже могут относиться к процессорам Intel, но в основном это общие сведения. Также я не знаю деталей того, как Linux определяет драйвер для загрузки для каждого устройства, поэтому я пропустил этот вопрос.

Современные процессоры не имеют системную шину (кроме скрытыхвнутри самого процессора). Они имеют каналы памяти, корневые порты PCIe и порт DMI, который подключается к чипсету (также называемый концентратором периферийного контроллера или PCH). PCH содержит дополнительные устройства и может иметь дополнительные корневые порты. Корневой комплекс состоит из схем, интегрированных как в CPU, так и в PCH. (Некоторые процессорные SoC не имеют DMI или PCH, и все корневые сложные схемы находятся внутри SoC CPU.)

Даже если ваша карта является единственной картой PCIe во всей системе, существуют другие PCIeустройства, интегрированные в корневой комплекс (называемые RCIEP или интегрированные конечные точки корневого комплекса). Они могут находиться в ЦП или в PCH.

Ваше устройство, подключенное к корневому порту PCIe, будет настроено как устройство 0 на некотором ненулевом номере шины. Номер шины зависит от корневого порта PCIe (т. Е. Слота), к которому подключено устройство, и способа, которым BIOS конфигурирует шину PCIe. (Как правило, один и тот же слот будет иметь один и тот же номер шины, но это может быть не так, в зависимости от того, что подключено к другим корневым портам PCIe.)

Остальные ваши предположения и терминология в порядке.

Программное обеспечение обращается к пространству конфигурации PCI либо с помощью инструкций ввода / вывода к портам ввода-вывода 0xcf8 и 0xcfc, либо с помощью пространства конфигурации с отображением в памяти. Диапазон адресов памяти пространства конфигурации PCI устанавливается BIOS. Программное обеспечение узнает адрес, просматривая таблицы ACPI. Механизм, с помощью которого эти входы / выходы или доступ к памяти преобразуются в сигналы PCIe, полностью находится внутри аппаратного обеспечения корня.

Смещение в диапазоне адресов пространства конфигурации PCI определяет, к какому программному обеспечению устройства / регистра осуществляется доступ. Например, доступ к MMCFG + 0 осуществляет доступ к смещению регистра 0 устройства 0: 0.0. Доступ к MMCFG + 0x1000 обращается к смещению регистра 0 устройства 0: 0.1, а доступ к MMCFG + 0x102000 обращается к смещению 0 регистра устройства 1: 0.2.

Программное обеспечение считывает регистры идентификатора поставщика / идентификатора устройства со смещением3: 0 каждого адреса устройства, чтобы определить, существует ли устройство по этому адресу. Если устройства нет, контроллер PCI возвращает 0xffffffff. Если устройство присутствует, оно возвращает идентификатор поставщика и идентификатор устройства, что позволяет программному обеспечению определять тип устройства.

Каждое устройство имеет 6 регистров BAR, со смещением 0x10, 0x14, ... 0x24. Если устройство поддерживает 64-битные BAR, два соседних регистра BAR используются для настройки одного региона. Обычно BIOS конфигурирует BAR каждого устройства, а также настраивает другие (скрытые) регистры внутри корневого комплекса, чтобы позволить ему перенаправлять доступ к памяти на соответствующее устройство. Обычно программное обеспечение записывает данные в регистры BAR для определения размера региона, а затем восстанавливает значения, установленные BIOS. В зависимости от корневого сложного аппаратного обеспечения, программное обеспечение может или не может изменять значения BAR, и при этом доступы работают правильно.

...