Я настраиваю u-boot для поддержки Cyclone V SX PCIe + NVMe. Я получил его через серию хаков для форка socfpga версии 2020.10.
У меня есть две проблемы, которые необходимо решить:
u-boot, похоже, не понимает, что адресное пространство PCI и адресное пространство хоста не обязательно одинаковы, и когда nvme выбирает адрес, назначенный порту PCIe, драйвер PCI предполагает, что считанный адрес отображается непосредственно в основную память. Это не так. Он полностью сопоставлен с другим адресом. У меня есть хитрость, чтобы с этим справиться. Я собираюсь попытаться добавить функцию в утилиты дерева устройств в u-boot, чтобы выполнять преобразование адресов без нарушения существующей функциональности.
Существуют значительные проблемы с тем, как драйвер nvme обрабатывает очистку и аннулирование кеша, чтобы улавливать изменения в памяти после того, как NVMe выполнил команду. Во время опроса регистры дверного звонка должны быть очищены на исходящих и признаны недействительными на входящих, что является почти полностью неправильным по-разному.
Вот где мне нужно руководство.
В u-boot есть два бита кода для обработки очистки / аннулирования кеша. Один является частью кода ядра arm v7, а другой - кодом контроллера pl310. Код arm v7 считает, что строка кэша составляет 64 байта, код pl310 считает, что строка кеша составляет 32 байта. Wtf?
Оба кода используются кодом nvme. Я думаю, что очистка проходит через pl310, а недействительность проходит через руку v7, но у меня может быть это наоборот, я все еще учусь и мог легко их перепутать.
Проблема с драйвером nvme проста: он просит очистить диапазон адресов, который не выровнен с кешем, и оба кода задыхаются и делают неправильные вещи и в конечном итоге не очищают или не аннулируют кеш, где его необходимо очистить и сделать недействительным. В случае pl310 он округляет начальный адрес в большую сторону и ничего не делает, а в случае кода arm v7, если начало и остановка после выравнивания их по границам 64 байтов совпадают, код выполняет ничего такого.
Я взломал это, установив выравнивание до 64 байтов в коде nvme и убедившись, что он полностью очищает кеш, добавляя единицу к остановке, если она совпадает с запуском в случае вызова arm v7.
Если ты все еще следишь за мной. Спасибо, я очень ценю это.
Как правильно это исправить. Ни один из этих кодов не является моим. Мне кажется, что в коде кеша есть ошибки. Pl310 не должен добавлять единицу к начальному адресу, возможно, он должен добавить его к конечному адресу, в зависимости от того, как написан цикл for. Цикл for для аннулирования в коде arm v7 должен выполняться хотя бы один раз, чтобы убедиться, что он очищает начальную позицию. Таким образом, цикл недействительности должен быть ‹=, а не‹.
Я мог бы опубликовать этот код, если кому-то интересно, просто дайте мне знать.
Но большой вопрос: почему существует два способа очистки / аннулирования кеша и почему оба используются? Мне кажется, что, поскольку Cyclone V использует контроллер кеш-памяти pl310, его код следует использовать как для очистки, так и для аннулирования. Это настраивается с помощью #define для определения вызываемого кода, и что-то подсказывает мне, что это тоже нужно исправить.
Мнения? Параметры? Идеи?
Я открыт, дайте мне знать, что вы думаете.