----------------------------------------------------
Расковырял обработку устройств на шине
Базовый цикл:
.
.
.
.
mov cx, [3BF6] Загружаем количество слотов
mov di, 3AC2 Загружаем адрес области конфигурации
Next_Dev:
push cx Сохраняем счетчик слотов
call Add_Device Обрабатываем слот
pop cx Восстанавливаем счетчик слотов
add di, 004D Переходим с следующему адресу
loop Next_Dev Продолжаем цикл
mov al, [3C6C] Флаг "Видеоадаптер найден"
cmp al, 01 Видеоадаптер найден ?
je PCIVIDEO Да - переход
.
.
.
.
.
Вот сама обработка
Вроде ничего подозрительного.....
Add_Device: Обработка очередного устройства на шине
lea bx, [di+09] Загружаем адрес памяти конфигурации
mov eax, 00000000 Смещение=0 - VendorID\DeviceID
call PCI_Read Читаем дв.слово
mov [bx], ecx Запоминаем в свою область памяти
cmp ecx, FFFFFFFF Слот не отвечает ?
je EXIT Да - выход,переходим с следующему
mov eax, 00000008 Смещение=8 - RevisionID\DeviceClassCode
call PCI_Read Читаем дв.слово
mov [bx+08], ecx Запоминаем в свою область памяти
and ecx, FFFFFF00 Накладываем маску - в ecx теперь DeviceClassCode
cmp ecx, 01000000 Устройство - SCSI ?
je SCSI Да - обрабатываем как SCSI
shr ecx, 10 Передвигаем ecx - теперь там только BaseClass
cmp ch, 02 Базовый класс - Сетевой Адаптер ?
je NET Да - обрабатываем как NET
cmp ch, 03 Базовый класс - Видеоадаптер ?
je VIDEO Да - обрабатываем как VIDEO
cmp ch, 04 Базовый класс - Мультимедиа ?
je MMED Да - обрабатываем как MMED
jmp OTHER Обрабатываем как Др.
.
.
.Обработка сети, скази, мултимедиа - пропускаем - неинтересно
.
.
VIDEO:
mov al, [3C6C] Флаг "Видеоадаптер Есть"
cmp al, 01 Видео есть?
jne NEW_VIDEO Нет - обрабатываем
jmp EXIT Есть - хватит и одной, выход
NEW_VIDEO:
mov eax, 00000010 Смещение=10 - Базовые Адресные Регистры
lea bx, [di+09] Заново загружаем указатель на нашу облать
add bx, 0010 Также смещение = 10
BAR_CYCLE:
mov ecx, FFFFFFFF Все биты 1 для записи - проверяем БАР
call PCI_Write Записываем еденицы
call PCI_Read Читаем регистр
mov [bx], ecx Запоминаем содержимое
cmp ecx, FFFFFFFF Регистр не отвечает?
je ROMPR Да - переходим к обработке ROM
or ecx, ecx Регистр пуст?
je ROMPR Да - переходим к обработке ROM
test cl, 01 БАР типа ПАМЯТЬ ?
je MEMREG Да - обрабатываем как память
call GO_IOSpace В противном случае - обрабатываем как ввод\вывод
jmp NEXTBAR
MEMREG:
call GO_MEMSpace Обрабатываем как память
NEXTBAR:
add bx, 0004 Переходим с следующему БАР
add eax, 00000004 Переходим с следующему БАР
cmp eax, 00000024 БАР кончились?
jbe BAR_CYCLE Нет - продолжаем
ROMPR:
mov eax, 00000030 Смещение=30 - Расширение ROM
mov ecx, FFFFFFFF Все биты 1 для записи - проверяем Расширение ROM
call PCI_Write Записывем еденицы
call PCI_Read Читаем регистр
lea bx, [di+09] Заново загружаем указатель на нашу область
mov [bx+30], ecx Запоминаем регистр ROM
cmp ecx, FFFFFFFF Регистр не отвечает?
je INTPR Да - переходим к обработке прерываний
or ecx, ecx Регистр пуст?
je INTPR Да - переходим к обработке прерываний
mov si, 3C60 Загружаем в SI смещение ячейки (в прошивке = 000C0000)
call GO_ROM Обрабатываем как ROM
INTPR:
mov ecx, 000000FF В ecx - 00..11111111
mov eax, 0000003C Смешение = 3С - IntLine\IntPin\MinGnt\MaxLat
mov [bx+3C], ecx Запоминаем 00..11111111 (Очищаем InterruptLine)
call PCI_Write Пишем это же в регистр
mov al, [3C68] Загружаем флаг "Запретить прерывания" (???????????)
test al, 01 Флаг = 1 ?
je EDIT_CR Да - переходим к записи в ControlRegister
Нет - все таки обрабатываем прерываение
mov eax, 0000003C Смещение = 3C - IntLine\IntPin\MinGnt\MaxLat
call PCI_Read Читаем регистр
mov [bx+3C], ecx Запоминаем регистр
or ch, ch InterruptPin пуст ?
je EDIT_CR Да - переходим к записи в ControlRegister
call GO_IRQ Нет - обрабатываем прерывание
EDIT_CR:
mov eax, 00000004 Смещение = 4 - ControlRegister \ StatusRegister
mov ecx, 00000003 Уст. биты 000.....011 - Рарешить IO, Разрешить MEM, Запретить BusMaster
call PCI_Write Пишем в CR
call 40BA Вызываем COPYROM !!!
mov eax, 00000030 Смещение = 30 - Расширение ROM
mov ecx, 00000000 В ecx=0
call PCI_Write Записываем 0 в регистр ROM (Зачеи ?????)
mov al, 01 В AL - 1
mov byte ptr [3C6C], al Устанавливаем флаг "Видеоадаптер Есть"
jmp EXIT Выход - с следующему устройству
EXIT:
ret Выход
Рассаматривал процедуры GO_IO, GO_MEM и GO_ROM - принцип ясен, непонятны детали
Кажется есть какой-то криминал
Кто может, прошу оказать помощи:
1) Как устройство в одном BAR заявляет и базовый адрес памяти и его размер? Целый час перечитывал абзац в спецификации - не понял
Понятно что записав все 111 мы можем по оставшимся 0 определить размер, но как определить нужный адрес памяти? (Пример - видео, адрес 000A0000)
2) COPYROM все-таки вызывается, поэтому всплывает прошлый вопрос - про порты E0, E1 и непривычный механизм копирования
Если кто знает - подскажите пожалуйста, нигде не найду инфу
Заранее благодарен
----------------------------------------------------
Расковырял обработку устройств на шине
Базовый цикл:
. . . . mov cx, [3BF6] Загружаем количество слотов mov di, 3AC2 Загружаем адрес области конфигурации Next_Dev: push cx Сохраняем счетчик слотов call Add_Device Обрабатываем слот pop cx Восстанавливаем счетчик слотов add di, 004D Переходим с следующему адресу loop Next_Dev Продолжаем цикл mov al, [3C6C] Флаг "Видеоадаптер найден" cmp al, 01 Видеоадаптер найден ? je PCIVIDEO Да - переход . . . . .Вот сама обработка
Вроде ничего подозрительного.....
Add_Device: Обработка очередного устройства на шине lea bx, [di+09] Загружаем адрес памяти конфигурации mov eax, 00000000 Смещение=0 - VendorID\DeviceID call PCI_Read Читаем дв.слово mov [bx], ecx Запоминаем в свою область памяти cmp ecx, FFFFFFFF Слот не отвечает ? je EXIT Да - выход,переходим с следующему mov eax, 00000008 Смещение=8 - RevisionID\DeviceClassCode call PCI_Read Читаем дв.слово mov [bx+08], ecx Запоминаем в свою область памяти and ecx, FFFFFF00 Накладываем маску - в ecx теперь DeviceClassCode cmp ecx, 01000000 Устройство - SCSI ? je SCSI Да - обрабатываем как SCSI shr ecx, 10 Передвигаем ecx - теперь там только BaseClass cmp ch, 02 Базовый класс - Сетевой Адаптер ? je NET Да - обрабатываем как NET cmp ch, 03 Базовый класс - Видеоадаптер ? je VIDEO Да - обрабатываем как VIDEO cmp ch, 04 Базовый класс - Мультимедиа ? je MMED Да - обрабатываем как MMED jmp OTHER Обрабатываем как Др. . . .Обработка сети, скази, мултимедиа - пропускаем - неинтересно . . VIDEO: mov al, [3C6C] Флаг "Видеоадаптер Есть" cmp al, 01 Видео есть? jne NEW_VIDEO Нет - обрабатываем jmp EXIT Есть - хватит и одной, выход NEW_VIDEO: mov eax, 00000010 Смещение=10 - Базовые Адресные Регистры lea bx, [di+09] Заново загружаем указатель на нашу облать add bx, 0010 Также смещение = 10 BAR_CYCLE: mov ecx, FFFFFFFF Все биты 1 для записи - проверяем БАР call PCI_Write Записываем еденицы call PCI_Read Читаем регистр mov [bx], ecx Запоминаем содержимое cmp ecx, FFFFFFFF Регистр не отвечает? je ROMPR Да - переходим к обработке ROM or ecx, ecx Регистр пуст? je ROMPR Да - переходим к обработке ROM test cl, 01 БАР типа ПАМЯТЬ ? je MEMREG Да - обрабатываем как память call GO_IOSpace В противном случае - обрабатываем как ввод\вывод jmp NEXTBAR MEMREG: call GO_MEMSpace Обрабатываем как память NEXTBAR: add bx, 0004 Переходим с следующему БАР add eax, 00000004 Переходим с следующему БАР cmp eax, 00000024 БАР кончились? jbe BAR_CYCLE Нет - продолжаем ROMPR: mov eax, 00000030 Смещение=30 - Расширение ROM mov ecx, FFFFFFFF Все биты 1 для записи - проверяем Расширение ROM call PCI_Write Записывем еденицы call PCI_Read Читаем регистр lea bx, [di+09] Заново загружаем указатель на нашу область mov [bx+30], ecx Запоминаем регистр ROM cmp ecx, FFFFFFFF Регистр не отвечает? je INTPR Да - переходим к обработке прерываний or ecx, ecx Регистр пуст? je INTPR Да - переходим к обработке прерываний mov si, 3C60 Загружаем в SI смещение ячейки (в прошивке = 000C0000) call GO_ROM Обрабатываем как ROM INTPR: mov ecx, 000000FF В ecx - 00..11111111 mov eax, 0000003C Смешение = 3С - IntLine\IntPin\MinGnt\MaxLat mov [bx+3C], ecx Запоминаем 00..11111111 (Очищаем InterruptLine) call PCI_Write Пишем это же в регистр mov al, [3C68] Загружаем флаг "Запретить прерывания" (???????????) test al, 01 Флаг = 1 ? je EDIT_CR Да - переходим к записи в ControlRegister Нет - все таки обрабатываем прерываение mov eax, 0000003C Смещение = 3C - IntLine\IntPin\MinGnt\MaxLat call PCI_Read Читаем регистр mov [bx+3C], ecx Запоминаем регистр or ch, ch InterruptPin пуст ? je EDIT_CR Да - переходим к записи в ControlRegister call GO_IRQ Нет - обрабатываем прерывание EDIT_CR: mov eax, 00000004 Смещение = 4 - ControlRegister \ StatusRegister mov ecx, 00000003 Уст. биты 000.....011 - Рарешить IO, Разрешить MEM, Запретить BusMaster call PCI_Write Пишем в CR call 40BA Вызываем COPYROM !!! mov eax, 00000030 Смещение = 30 - Расширение ROM mov ecx, 00000000 В ecx=0 call PCI_Write Записываем 0 в регистр ROM (Зачеи ?????) mov al, 01 В AL - 1 mov byte ptr [3C6C], al Устанавливаем флаг "Видеоадаптер Есть" jmp EXIT Выход - с следующему устройству EXIT: ret ВыходРассаматривал процедуры GO_IO, GO_MEM и GO_ROM - принцип ясен, непонятны детали
Кажется есть какой-то криминал
Кто может, прошу оказать помощи:
1) Как устройство в одном BAR заявляет и базовый адрес памяти и его размер? Целый час перечитывал абзац в спецификации - не понял
Понятно что записав все 111 мы можем по оставшимся 0 определить размер, но как определить нужный адрес памяти? (Пример - видео, адрес 000A0000)
2) COPYROM все-таки вызывается, поэтому всплывает прошлый вопрос - про порты E0, E1 и непривычный механизм копирования
Если кто знает - подскажите пожалуйста, нигде не найду инфу
Заранее благодарен