На ПЛИС Virtex5 реализовал Serial ATA Host Bus Adapter (HBA) с интерфейсом PCI Express. Работает в режиме эмуляции IDE. Тестировал на материнке (Intel MB950F). Пробовал под Linux (Ubuntu 10.04), Windows XP SP3. В конфигурационном пространстве моей платы прописана следующая инфа:
1) VendorID/DeviceID = 8086/3B26h (подсмотрел по аналогии на встроенных контроллерах).
2) ClassCode = 010105h. Интерфейс 05h потому что пока только в PIO режиме тестирую.
3) BAR0/BAR2 -- ATA Command/Control блоки. Размеры регистров прописаны по 128 байт (аппаратное ядро PCI Express в virtex5 не позволяет поставить меньший размер IO, только больше).
4) BAR1/BAR3/BAR4 пока 0h (не используются).
Проблема в том, что под Linux контроллер работает как надо с помощью стандартных драйверов, а под Windows нет, загрузка с диска тоже невозможна.
Начну с BIOS(AMI BIOS 8). На этапе загрузки выводится список HDD. Подключенного через мою плату HDD в этом списке нет. В Setup Utility также диск отсутствует во всех соответствующих вкладках. Загрузка продолжается. На экране появляется табличка с номерами прерываний. Вижу там свой контроллер с номером прерывания (пишет: PCIe to IDE bridge). Далее boot menu загрузчика grub, который установлен на другом диске. Если в системе оставить только 1 hdd, который подключен через мой контроллер, то BIOS говорит, что нет системного диска. Смотрю, что происходит на интерфейсе PCI Express внутри ПЛИС с помощью отладчика chipscope во время загрузки BIOS. Меня интересуют только транзакции уровня TLP. Таковых не наблюдается вообще в процессе загрузки BIOS. Вероятно, и скорее всего, что конфигурационные запросы приходят, так как прерывание моей плате все же назначается. Далее BIOS-у что-то не нравится в конфиге и он не работает с мои контроллером (вопрос что именно?). Есть предположение, что BIOS для класса устройства 0101h проверяет размеры BAR'ов. Ведь другие контроллеры на плате имеют размеры по 8/4 байта на BAR для соответственно Command и Control блоков ATA.
Теперь о Windows. Система обнаруживает новое устройство и ставит ему стандартный драйвер драйвер (Стандартный двухканальный контроллер PCI IDE), и отмечает его восклицательным знаком. На вкладке "Ресурсы" не отображаются занимаемые диапазоны IO/MEM. Только присутствует надпись: "устройство не использует ресурсов, возможно, в его работе присутствуют ошибки". Далее просматриваю конфигурационное пространство своего контроллера прог-ой PCI Tree. К моему удивлению, диапазоны IO для BAR'ов все-таки выделены и адреса прописаны в BAR'ы (сс00h-сс7Fh, 8800h-887Fh). Смотрю, что происходит на интерфейсе PCI Express внутри ПЛИС с помощью отладчика chipscope во время загрузки Windows. Меня интересуют только транзакции уровня TLP. Таковых не наблюдается вообще в процессе загрузки Windows. Вероятно, и скорее всего, что конфигурационные запросы приходят, так как прерывание моей плате все же назначается и IO ресурсы также выделяются (хотя в диспетчере устройств они не отображаются).
Из всех этих экспериментов прихожу к выводу, что драйвера HDD контроллеров в BIOS и Windows проверяют размер BAR'ов для устройств класса 0101h, а при несовпадении с ожидаемыми просто прекращают работать с таким устройством.
Проверял на другой материнке с BIOS от AWARD -- все также.
Какие есть соображения по этому поводу?
Т.е. понятие "стандартность" не ограничивается стандартными действиями над стандартными объектами. Может понадобиться стандартное расположение этих объектов в адресном пространстве, например.
Постепенно начинаю понимать о чем вы пишете. И, видимо, если же проблема, которую я описал решится, то этот вариант будет для меня единственным верным. То есть, как я понимаю, все внешние адаптеры обязательно содержат expansion rom на своей плате, и мне его заполнять придется заветным кодом?
Однако, отсутствие сего аддона не корень зла. И не побегу я радостный наполнять expansion rom своей платы спасительными кодами, да не спасут они меня. BIOS-то по прежнему не обращается к заветному BAR'у, да и к остальным тоже. А встраивать аддон для дебага в bios вообще не вижу смысла. Чего дебажить-то? Контроллер? Так под linux я его уже отдебажил, работает как часы. Устройство должно запускаться на любой машине без дополнительных вмешательств.
Что делает код BIOS, когда обнаруживает устройство с классом 0101h на на шине PCI/PCI-E ? Ведь мой контроллер он находит, иначе бы прерывание не назначал ему. Что его дальше смущает? Аналогичный вопрос по винде. Пока я склоняюсь, как и писал в первом посте, к "неправильным" размерам BAR'ов -- 128 байт вместо 4/8/16 байт. Прошу подтвердить или опровергнуть мои предположения.
Я бы поглядел в отладке, какие обращения производятся к устройству до загрузки ОС и уже на основе этой информации пытался бы думать дальше. Хотя не факт, что это даст что-то полезное.
На протяжении всей дискуссии, начиная с первого поста, я пытаюсь до читателей донести эту информацию. На уровне TLP никаких обращений (а это уровень, куда как раз выплевываются всякие запросы на чтение регистров BAR). На уровне конфигурационных запросов что-то есть. Но посмотреть не могу, это скрыто в аппаратном ядре PCI-E, наружу только TLP уровень торчит.
Вы уверены? На мой взгляд, в classcode лежит важная информация для BIOS.
Чтобы узнать об этом желании, BIOS'у нужно прочитать первые байты Addon ROM платы? Так вот до этого и не доходит.
Что значит "вообще функционировать"?
> Надеюсь, теперь вы точно представляете, что именно за устройство я делаю?
Это неважно. Просто ответьте - тоеретически оно по функционалу совпадает с набортным SATA-контроллером? И теоретически соответстует тем же спецификациям?
Вопрос-то чисто философский. И ответа ровно 2 - либо вы делаете ТОЧНО по спецификации (мне, честно говоря, лень искать/читать спецификацию на PCI IDE-контроллер, но думаю, что отступления есть), либо выясняете, что хочет BIOS/драйвер и подпиливаете конкретные места.
Насчет BIOS - у Вас несколько завышенные ожидания, IMHO. BIOS пишется под плату. На ней есть устройство 8086/3B26h и MainBIOS заранее знает характеристики устройства. Банальная неимплементация BAR'ов или код интерфейса 05h может привести к тому, что MainBIOS не признает устройство за свое. Код класса тут как раз не играет определяющей роли - разве что в выводе типа в списке PCI.
При этом размер BAR'ов - всего лишь один из факторов "неприятия", причем, на мой взгляд - не самый важный.
Кстати, Гугл дает довольно много инфы по "xilinx sata controller". Например, opencores.org/project,sata_controller_core
А в Винде - хотсвапом подлкючать, и смотреть почему падает хотя бы Alter'овский драйвер. Ну, и в ReactOS можно глянуть ATAPI.SYS.
При правильно имплементированном ROMBAR - попытается. Должен.
Энумерировать. выдать ресурсы, при необходимости - отработать Expansion ROM.
А кому счас легко...
Да, у меня есть все необходимые спеки и я по ним все делал (могу перечислить, если требуется). Проблема не в функционале контроллера, как видно из экспериментов, а в собственно, его интерфейсной части pci-e. Тут как бы инфы недостаточно у меня. Все возможные рекомендации по этому поводу из спеков я вроде выполнил.
Так и мое устройство с таким же кодом присутствует. Или там еще привязка по номеру шины, девайса,функции?
Да, смотрел весной еще эти корки, запускал, кучу багов правил, еще игрался с groundhog проектом... Вердикт -- УГ. Этим поделкам далеко до настоящего Serial ATA HBA, уж поверьте. Это просто глючные недоделанные SATA корки студентов. На electronix.ru писал про свой экспириенс в их освоении. А вы думали я сам не хотел на халяву сделать это устройство, что мне принципиально важно все писать с 0?
Адекватного материала по этой теме не так уж много в интернетах, помогают лишь спеки до поры.
Похоже этого условия недостаточно, он ведь имплементирован, и правильно.
PS: Вы поймите, я не спец в исходниках BIOS, потому мои вопросы могут казаться вам примитивом.
> Так и мое устройство с таким же кодом присутствует. Или там еще привязка по номеру шины, девайса,функции?
Тоже вариант. Кроме того - MainBIOS может банально считать, что bus mastering и т.п. устройство 8086/3B26h должно уметь, иначе оно невалидное. Впрочем, как и драйвер в винде.
Я бы все же попробовал VID от xilinx и произвольным DID, например. В этом случае MainBIOS обязан прочитать ROMBAR (т.к. это generic устройство, о котором он ничего не знает, т.е. должен работать по спецификации).
А в ОСях ничего не изменится, по идее, т.к. драйвер типа "Стандартный IDE-контроллер" ставится по Class Code.
А кому счас легко...
Попробовал сменить VID/DID как вы посоветовали (10EEh/0h). Линукс начал вести себя как винда раньше,то есть перестал обращаться к контроллеру. Винда по прежнему не обращается. И после того как в винде вкорячил кое-как дебаговую версию uniata, после перезагрузки винда начала работать с контроллером, hdd led радостно замигал. Но тут сказке не конец. Моргает он и моргает, потом начинает загораться на секунду и гаснет, и так пока ресет не дернешь. Дело было уже после рабочего дня, так что не успел подробно выяснить чего ему там не нравится. Посмотрел какие там пакеты на pcie гуляют. Ситуация такая: сначала куча трансферов в регистры, потом вычитка pio fifo (резалт команды identify_device), потом выполняется какая-то команда записи в режиме pio с непонятными данными. Потом, очевидно после soft reset, все повторяется. Похоже нужно курить исходники uniata.
BIOS по прежнему нифига не пытается что-то прочитать или записать, только как и раньше в config space.
Провел еще несколько экспериментов. Экспериментировал на двух чипах Spartan6, Virtex5.
1) Если VID/DID 8086/2B26h, то есть как у контроллера на плате, то BIOS не читает XROM BAR. Винда аналогично. .
2) Если VID/DID 10EE/0000h, то есть как хз какой девайс, то BIOS читает первые 2 байта XROM BAR. Винда тоже.
3) Вчерашний эксперимент с установкой uniata на плату с VID/DID 10EE/0000h завершился обращением драйвера к контроллеру.
Из этих экспериментов делаю вывод, что мое предположение по поводу проверки размеров BAR для устройства класса 0101h следует признать неверным и забыть.
Однако, полностью так и не уверен, что все решиться написание магического addon rom. Проблему с загрузкой с устройства в BIOS я решу таким образом. Но дальше идет операционка, как она будет взаимодействовать с моим устройством? Если линукс можно обмануть, подсунув cуществующий VID/DID, то с виндой не прокатывает, нужен драйвер. При этом, на интегрированные контроллеры тоже стоят стандартные драйвера, и это никого не смущает.
Моя задача, чтобы контроллер не нуждался в дополнительном ПО для ОС.
1) Как мне решить эту задачу?
2) Чего такого нестандартного хочет стандартный виндузовый драйвер от моего контроллера? Мой контроллер же выдает стандартный интерфейс для него.
Отправить комментарий