CF8h - регистр адреса
CFCh - регистр данных
Если читали Пинчакку, или смотрели описаловку на Intel-чипсеты, то понято что адрес требуемого регистра задается значением 8000ХХХХh, где ХХХХ адрес регистра в виде Dev, Func, Reg.
Если эти ХХХХ перевести в двоичный код, то первые пять разрядов слева задают номер устройства (максимальное значение 31 десятичное), потом три разряда номер функции и последние восемь - номер регистра (hex).
Пример:
0F01Ch -> 1111000000011100b -> 11110 000 00011100b -> Dev 30 (11110b), Func 0 (000b), Reg 1Ch
Загвоздка обычно в том, что device считается в десятичной системе счисления (d), тогда как все остальное в шестнадцатиричной (hex).
Ну и пример кода без объяснений:
Заходим в подпрограмму с параметром, например cx (задаем адрес)
mov cx, 0F8A4h ; dev31 func0 regA4
call Read_PCI
Read_PCI:
mov ax, 8000h ;
shl eax, 10h ; Shift Logical Left
mov ax, cx
and al, 0FCh ; Logical AND
mov dx, 0CF8h
out dx, eax
add dl, 4 ; Add
mov al, cl
and al, 3 ; Logical AND
add dl, al ; Add
in al, dx
retn ; Return Near from Procedure
Соответственно в подпрограмме записи будет out dx, al или ax или eax.
Также большая часть функциональности чипсета программируется через блоки регистров, относящиеся к некому базовому адресу.
Например:
Root-регистры (база Root Complex Base Address) - огромное количество низкоуровневых настроек чипсета (смотрите даташиты на южный мосты, как пример ICH7)
MCHBAR - регистры конфигурирования памяти и контроллера памяти (правда подробного описания регистров относительно этой базы не встречал)
и многие другие....
Вот пример кода из Award-Phoenix:
Функция поиска PCI устройства по классу
Функции чтения и записи в PCI
Отправить комментарий