Вообще-то у меня цель прочитать BAR’ы HDD из PCI CFG, но мне не удаётся даже правильно прочитать VendorID и DeviceID. Вроде всё правильно делаю: в порт 0CF8h засылаю адрес SATA HDD, заранее узнанный в свойствах IDE ATA/ATAPI контроллеров. В моём случае это Bus 00 Device 1f Function 02 для одного и Bus 00 Device 1f Function 05 для второго HDD. В 31 бит вписываю единицу, а в 0 и 1-ый биты вписываю нули, как и полагается. Но из порта 0CFCh всегда получаю только одно и то же значение - 8000FFFFh. При чём не имеет значения, в какой регистр я засылаю команду в 00h, в 10h, в 14h и т.д., возвращается всегда только 8000FFFFh. Что не так я делаю и как прочитать Device code и Vendor code, прочитав которые, я смогу прочитать и всё остальное? Мне должно возвращаться 3a208086h для одного и 3a268086h для второго HDD. В моём БИОСе в строке выбора SATA Configuration три опции для выбора: Enhaned, Compatible и Disable. Выбрана первая. В Configure SATA as тоже три опции выбора: IDE, RAID и AHCI. Здесь тоже выбрана первая опция – IDE. Моя ОС – Windows SP2. Вот часть кода: ;устанавливаем адрес начала конфигурационного пространства mov ecx,8000FA00h ;(шина 0, устройство 31, функция 2, регистр 00 mov eax,ecx ;10000000-00000000-11111010-00000000) mov dx,0CF8h out dx,eax mov dx,0CFCh in eax,dx ;Читаем х00h, там 8000FFFFh
А почему SATA HDD? HDD не подключены напрямую к шине PCI. Нужно брать адреса контролера (IDE, AHCI, ...). А потом опрашивать его на наличие жестких дисков. Причем как опрашивать зависит от тика контролера. По приведенным тобой Device ID и Vendor ID получаем: Код (Text): 0x3A26 SATA2(2Port2) 0x8086 Intel Corporation Судя по-всему ты не для того устройства хотел получить, и прочитал не то, что нужно, потому что такого устройства нет на PCI шине.
Да, не напрямую, конечно, подключены. Просто у меня 2 жёстких SATA, а адреса SATA берутся из PCI CFG, а они могут быть разными. Так, а как это сделать программно? Можно подсмотреть в Мой компьютер-Свойства-Оборудование-Диспетчер устройств-IDE ATA/ATAPI-Свойства. Я ещё проверял наличие устройств с помощью программы PciDump, всё сходится. Но так каждый сможет узнать адреса. А вот когда стал проверять программой скомпилированного листинга «Нахождение и вывод VendorID и DeviceID всех PCI устройств (PCI.asm) из статьи Dark_Master'а «Определение конфигурации на аппаратном уровне», то мне показывалось только Vendor code: FFFF, т.е. устройство не обнаружено. И программа с сайта wiki то же самое показывает FFFF. У меня 2 контроллера Intel ICH10, хотя почему-то один имеет 2 port, а другой 4 port. Жёсткие одной фирмы, серии, объёма. Я же заранее знаю адрес HDD, но почему мне пишется FFFFh. Ясно, что что-то не так делаю, вот хочу и понять, что именно.
Ты либо снова что-то попутал, либо не понял меня в первый раз. Адрес HDD ты знать не можешь. И прочитать его конфигурацинное пространство тоже. Приведи подромнее с названиями что и где ты смотришь. В моем случае получаем так: Device Manager -> IDE ATA/ATAPI Controllers -> Standard Dual Channel PCI IDE Controller -> Properties -> Details -> Location Information Получаем следующее: PCI bus 0, device 13, function 0. Можешь, показать где ты искал данные также, как я тебе написал? Мне все же кажется, что ты не там смотрел. Я сам последнее время занимаюсь подобным, и у меня таких проблем не было. P.S. Нули не обязательно туда писать. Точнее не всегд нужно. Можно читать байт из конфигурационного пространства, тогда 0 и 1 биты могут быть не нулями, можно читать 2 байта, тогда 1-ый бит может быть не нулем... Думаю логика ясна. P.P.S. Кстати, для определения того, что утройства нет, проверяют DeviceId (Он равен FFFF). Для твоего DeviceId = 0x8000 получаем следующее:
Пардон, тут я тебя обманул. 0 и 1 бит обязательно должны быть нулями, но если нужно прочитать 1 байт, то делают так: Код (Text): mov eax, Address & ~3 mov dx, 0x0CF8 out dx, eax mov dx, 0x0CFC + 1 ;или 0x0CFC, 0x0CFC + 2, 0x0CFC + 3 in al, dx
Моя задача - прочитать СОДЕРЖИМОЕ регистров базовых адресов (BAR’ов), при этом уже ЗАРАНЕЕ известен адрес, содержимое которого нужно прочитать (содержимое, кстати, тоже мне уже известно). Конечно, сначала ищется контроллер методом перебора функций и устройств (шины, думаю, не обязательно перебирать для HDD). Но на ДАННЫЙ МОМЕНТ перебор мне не нужен: раз я простое не могу сделать, т.е.из УЖЕ ИЗВЕСТНОГО адреса не могу ничего прочитать, зачем буду усложнять задачу. Адрес регистра конфигурации – это номер шины, функции, устройства и регистра. Плюс выставленный в единицу старший 31 бит (флаг переноса CF=1) и обнулённые два младших бита 0 и 1 (тип 00 - для обычных устройств). При этом номер регистра указывает на один из регистров конфигурации устройства. С помощью засылки в порт управления 0CF8h этого адреса я через порт данных 0CFCh могу прочитать содержимое этих регистров, в том числе и BAR’ы. Но я не могу прочитать даже Vendor ID Intel’а = 8086, мне уж не до BAR’ов. Диспетчер устройств-IDE ATA/ATAPI-Свойства: Intel(R) ICH10 Family 2 port Serial ATA Storage Controller 2 – 3A26. В строке «Размещение» указан адрес контроллера: PCI шина 0, устройство 31, функция 5. Понятно, что здесь регистр 00 будет, а BAR’ы начинаются с 10h. И если в Свойствах контроллера открыть вкладку Ресурсы, можно прочитать и Параметры. У меня они для Диапазона ввода/вывода (I/O) такие: A000 – A007; 9C00 – 9C03; 9880 – 9887; 9800 -9803; 9480 – 948F; 9400 – 940F. Для IPQ - 19. Но эти параметры и есть содержимое BAR’ов: BAR 0 - BAR 5, кроме IRQ. Это как решаешь задачку по алгебре, у тебя один ответ, а в решебнике другой. P.S. Вышлю программу, с помощью которой пытаюсь читать с УЖЕ известного адреса. Можешь заменить на свой адрес, интересно, что у тебя показывать будет
Попробуй обратится по адресу Bus 0, Device 31, Function 0. Что-то меня смущает, что у тебя Function 5... Необычно как-то.
У меня ещё один контроллер есть Intel(R) ICH10 Family 4 port Serial ATA Storage Controller 1 – 3A20, который размещён на PCI шина 0, устройство 31, функция 2. Bus 00 Device 1f Function 00 Vendor: 8086 Intel Device: 3a16 Revision: 00 Device class: 06 Bridge Device Но это я с помощью программы PciDump узнал. А так-то, конечно, пробовал, но результат тот же: 8000FFFFh. А почему смущает-то, на функцию же 3 бита отводится, т.е. их до 7 может быть. И что скажешь насчёт посланной мною тебе программы?