;****************************************************
;* ПОИСК HDD и CD *
;****************************************************
OS_BASE equ 0
IDEBasesPorts equ OS_BASE+6F00h
IDEMaxConroller equ 4
IDEMaxCanals equ 8
;Таблица портов имеет следующий формат
;канал 0
;канал 1
;канал 2
;..
;канал 7
; * кажый канал это два порта
; Базовый адрес портов команд
; Базовый адрес порта контроля именно порта, а не блока.
; Всего 8 каналов 8*2*2=32Байта
IDEBusMaster equ IDEBasesPorts+20h
; Всего 4 вхождения по 4 байта.
IDEBusIRQ equ IDEBasesPorts+ 30h
; Всего 4 байта.
IDEHDD_CD equ IDEBasesPorts+34h
;4Байта 00b нет устройства 01b есть жесткий диск 10b есть Сидиром 11b рерв. 8 Каналов по два диска
IDELBA48 equ IDEBasesPorts+38h
;2 Байта 0 нет поддержки 1 есть поддержка и так 8 Каналов по два диска
FindHDD:
; Стандартные
xor eax, eax
mov ecx, 100h
mov edi, IDEBasesPorts
rep stosb
; Поиск контролеров и четение из них базовых портов
call FindBasesPorts
mov ecx, IDEMaxCanals-1
.Loop:
mov ah, cl
xor al, al ; al = 0
call TestDisks
mov ah, cl
mov al, 1 ; al = 1
call TestDisks
dec ecx
cmp ecx, dword -1
jne .Loop
ret
;***********************
; Функция для проверки существования диска.
; ah - канал
; al - диск мастер 0 слейв 1
;
buf dw 256 dup 0
TestDisks:
pushad
and al, 1
movzx esi, ah
movzx edi, al
mov dx, word [IDEBasesPorts+esi*4] ; базовый порт команд
test dx, dx ; dx == 0 ?
jz .end ; прыгаем, если dx == 0
shl esi, 1
add esi, edi
shl esi, 1
shl al, 4
add dx, 6 ;+6 Device
out dx, al
xor al, al ; al = 0
dec dx ;+5
out dx, al
dec dx ;+4
out dx, al
dec dx ;+3
out dx, al
dec dx ;+2
out dx, al
add dx, 5 ;+7 Command
mov al, 90h ; EXECUTE DEVICE DIAGNOSTIC
out dx, al
mov ecx, 0FFFFh
.loop:
out 0EBh, al ; задержка
in al, dx ;+7 Status
test al, 80h ;BSY
jz .ok1
loop .loop
.timeout:
; время вышло - устройства нет
mov eax, 3
mov ecx, esi
shl eax, cl
not eax
and dword [IDEHDD_CD], eax
sub dx, 7 ;+0
jmp .reset
.ok1:
sub dx, 6 ;+1
in al, dx
add dx, 6 ;+7
cmp edi, 1
je .label1
cmp al, 1
je .label2
sub dx, 7 ;+0
jmp .other1
.label1:
cmp al, 1
je .label2
cmp al, 80h
je .label2
sub dx, 7 ;+0
jmp .other1
.label2:
dec dx ;+6
dec dx ;+5
in al, dx
mov bl, al
shl ebx, 8
dec dx ;+4
in al, dx
mov bl, al
shl ebx, 8
dec dx ;+3
in al, dx
mov bl, al
shl ebx, 8
dec dx ;+2
in al, dx
mov bl, al
sub dx,2 ;+0
cmp ebx, 000000101h ; жесткий диск
jne .cd
mov eax, 1
mov ecx, esi
shl eax, cl
or dword [IDEHDD_CD], eax
jmp .indef
.cd:
cmp ebx, 0EB140101h ; сидиром
jne .other1
mov eax, 2
mov ecx, esi
shl eax, cl
or dword [IDEHDD_CD], eax
jmp .reset
.other1:
mov eax, 3
mov ecx, esi
shl eax, cl
not eax
and dword [IDEHDD_CD], eax
.reset:
add dx, 6 ;+6
mov eax, edi
shl al, 4
out dx, al
mov al, 0
dec dx ;+5
out dx, al
dec dx ;+4
out dx, al
dec dx ;+3
out dx, al
dec dx ;+2
out dx, al
add dx, 5 ;+7 Command
mov al, 08h ; Device RESET
out dx, al
mov ecx, 0FFFFh
.loop2:
out 0EBh, al ; задержка
in al, dx ;+7 Status
test al, 80h ;BSY
jz .ok2
loop .loop2
.timeout2:
; время вышло - устройства нет
mov eax, 2
mov ecx, esi
shl eax, cl
not eax
and dword [IDEHDD_CD], eax
sub dx, 7 ;+0
jmp .end
.ok2:
sub dx, 6 ;+1
in al, dx
add dx, 6 ;+7
cmp edi, 1
je .label3
cmp al, 1
je .label4
sub dx, 7 ;+0
jmp .other2
.label3:
cmp al, 1
je .label4
cmp al, 80h
je .label4
sub dx, 7 ;+0
jmp .other2
.label4:
dec dx ;+6
dec dx ;+5
in al, dx
mov bl, al
shl ebx, 8
dec dx ;+4
in al, dx
mov bl, al
shl ebx, 8
dec dx ;+3
in al, dx
mov bl, al
shl ebx, 8
dec dx ;+2
in al, dx
mov bl, al
sub dx, 2 ;+0
.cd2:
cmp ebx, 0EB140101h ; сидиром
jne .other2
mov eax, 2
mov ecx, esi
shl eax, cl
or dword [IDEHDD_CD], eax
jmp .indef
.other2:
mov eax, 3
mov ecx, esi
shl eax, cl
not eax
and dword [IDEHDD_CD], eax
.indef:
add dx, 6 ;+6 command
mov eax, edi
shl al, 4
out dx, al
inc dx ;+7 command
mov eax, dword [IDEHDD_CD]
mov ecx, esi
shr eax, cl
and al, 3
cmp al, 0
je .end
cmp al, 1
jne .cd3
mov al, 0ECh ; IDENTIFY DEVICE
out dx,al
jmp .read
.cd3:
cmp al, 2
jne .end
mov al, 0A1h ; IDENTIFY PACKET DEVICE
out dx,al
.read:
mov ecx, 0FFFFh
.loop3:
dec ecx
jz .timeout3
out 0EBh, AL ; задержка
in al, dx ;+7 Status
test al, 80h ; состояние сигнала BSY
jnz .loop3
test al, 08h ; состояние сигнала DRQ
jz .loop3
jmp .ok3
.timeout3:
mov eax, 3
mov ecx, esi
shl eax, cl
not eax
and dword [IDEHDD_CD], eax
sub dx, 7 ;+0
jmp .end
.ok3:
xchg edi, eax
mov edi, buf ;offset buf
sub dx, 7 ;+0 регистр данных
mov cx, 256 ;число считываемых слов
rep insw ;принять блок данных
xchg edi, eax
mov ecx, 255
mov ax, word [buf]
.loop4: ; проверяем на муссор вернулись одинаковые слова
mov bx, word [buf + ecx*2]
cmp ax,bx
jne .ok4
.equ:
loop .loop4
.error:
mov eax, 3
mov ecx, esi
shl eax, cl
not eax
and dword [IDEHDD_CD],eax
sub dx, 7 ;+0
jmp .end
.ok4:
; Все проверки пройдены
; LBA48
mov ax, word[buf+86*2]
shr ax, 10
and ax, 1
mov ecx, esi
shr ecx, 1
shl eax, cl
or [IDELBA48],ax
.end:
popad
ret
Addr_PCI DD 0 ; Адресс PCI устройства
;**********************
;Функция читает один регистр из конфигурационного пространства устройства
;по адресу Addr и заносит его в EAX.
;**********************
ReadPCIRegistr:
mov eax, [Addr_PCI] ;
and eax, 0FFFFFFFCh ; Проверяем Addr в начале должен быть два 00
or eax, 80000000h ; 31 бит обязан быть единицей.
mov dx, 0CF8h
out dx, EAX ; Устанавливаем адрес
mov dx, 0CFCh
in eax, DX ; Читаем регистр
push eax
xor eax, eax ; Сбрасываем адрес
mov dx, 0CF8h ; Чтобы не было претензий.
out dx, eax ;
pop eax
ret
;*********************************
; Функция для поиска устройства по его классу
; EAX -его базовый класс.
; На выходи адрес если нет то -1
;***********************************
FindPCIDevice3:
push ebx
push ecx
push edx
mov ebx, eax ; Сохраняем
mov ecx, [Addr_PCI] ; Счетчик он же адрес
and ecx, 0FFFFFFFCh ; Проверяем Addr в начале должен быть два 00
or ecx, 80000000h ; 31 бит обязан быть единицей.
.Label1:
and ecx, 0FFFFFF00h ; Выравниваем
mov eax, ecx
mov dx, 0CF8h
out dx, eax ; Устанавливаем адрес
mov dx, 0CFCh
in eax, dx ; Читаем регистр
cmp eax, 0FFFFFFFFh ; Не существующее устройство.
je .Label2
add ecx, 08 ; Наш Регистр
mov eax, ecx
mov dx, 0CF8h
out dx, eax ; Устанавливаем адрес
mov dx, 0CFCh
in eax, dx ; Читаем регистр
shr eax, 24 ; Base Class Code
cmp eax, ebx
je .Label3 ; Ура: нашли!
.Label2:
add ecx, 256
; Нужно бы добавить проверку на то, есть функции или нет.
cmp ecx, 80FFFF00h ; Максимум 256 шин.
jne .Label1
mov ecx, 0FFFFFFFFh ; Не нашли
.Label3:
xor eax, eax ; Сбрасываем адрес
mov dx, 0CF8h ; Чтобы не было претензий.
out dx, eax ;
and ecx, 0FFFFFF00h ; Сбрасываем индекс регистра
mov [Addr_PCI], ECX
cmp ecx, 0FFFFFF00h
jne .exit
mov ecx, 0FFFFFFFFh ; Не нашли
.exit:
mov eax, ecx
pop edx
pop ecx
pop ebx
ret
;**********************************************
;* ПОИСК КОНТРОЛЕРОВ и ЧЕТЕНИЕ ИХ ПОРТОВ
;* IDEBasesPorts - базовые порты
FindBasesPorts:
push eax
push esi ;
push edi ;
xor esi, esi
xor edi, edi
mov eax, 00 ;
mov [Addr_PCI], eax ; B0:D0:F0
.Next:
mov eax, 01 ; Base Class Code =01 накопитель
call FindPCIDevice3
cmp eax, 0FFFFFFFFh
je .end
add [Addr_PCI], 8
call ReadPCIRegistr
and eax, 0FFFF0000h ; Class Code
cmp eax, 001010000h ; IDE, SATA маскирующийся под IDE
je .IDE
cmp eax, 001040000h ; RAID,SATA маскирующийся под RAID
jne .NotIDE
.IDE:
add [Addr_PCI], 8 ; 8+8=10h
call ReadPCIRegistr
and eax, 0FFFCh ; зануляем лишнее
cmp eax, 0
jne .native1
mov eax, 01F0h
.native1:
mov [IDEBasesPorts+esi], ax
add [Addr_PCI], 4 ; 8+8+4=14h
call ReadPCIRegistr
and eax, 0FFFCh ; зануляем лишнее
cmp eax, 0
jne .native2
mov eax, 03F4h
.native2:
add ax, 2 ; Порт контроля+2
mov [IDEBasesPorts+esi+2], ax
.last:
add esi, 4
mov byte [Addr_PCI], 18h ; 14h+4=18h
call ReadPCIRegistr
and eax, 0FFFCh ; обнуляем лишнее
cmp eax, 0
jne .native3
mov eax, 0170h
.native3:
mov [IDEBasesPorts+esi], ax
mov byte [Addr_PCI],1Ch ; 18h+4=1Ch
call ReadPCIRegistr
and eax, 0FFFCh ; зануляем лишнее
cmp eax, 0
jne .native4
mov eax, 0374h
.native4:
add ax, 2 ; Порт контроля+2
mov [IDEBasesPorts+esi+2], ax
.MasterBus:
add esi, 4
mov byte [Addr_PCI], 20h ; 1Ch+4=20h
call ReadPCIRegistr
and eax, 0FFFCh ; зануляем лишнее Bus Master
mov [IDEBusMaster+edi*2], eax
add [Addr_PCI], 1Ch ; 1Ch+20h=3Ch
call ReadPCIRegistr
and eax, 0FFh ; зануляем лишнее Interrupt Line (IRQ)
mov byte [IDEBusIRQ+edi], al
inc edi
.NotIDE:
and [Addr_PCI], 0FFFFFF00h
add [Addr_PCI], 100h
cmp esi, IDEMaxCanals*4 ; 8*4=20h
jne .Next
pop edi
pop esi
pop eax
ret
Advertisement
304
страницы
Исходный код:Поиск HDD и CD
Advertisement