2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2025-01-31 01:30:05 +01:00

add more PCI device initialization code

This commit is contained in:
ramenu 2024-04-19 23:39:34 -04:00
parent f652c5f362
commit 06cfd44233

View File

@ -35,11 +35,12 @@ proc START c, reason:dword
.entry:
DEBUGF DBG_INFO, "Detecting NVMe hardware...\n"
call detect_nvme
mov eax, dword [p_nvme_devices]
test eax, eax
jz .err ; no NVMe device found?
DEBUGF DBG_INFO, "Found NVMe device...\n"
stdcall nvme_init, dword [eax + PCIDEV.bus], dword [eax + PCIDEV.devfn]
mov eax, dword [eax]
stdcall nvme_init, dword [eax + pcidev.bus], dword [eax + pcidev.devfn]
test eax, eax
jz .err ; failed to initialize controller?
@ -47,6 +48,7 @@ proc START c, reason:dword
ret
.err:
DEBUGF DBG_INFO, "(NVMe) Cleaning up...\n"
call nvme_cleanup
xor eax, eax
ret
@ -114,7 +116,6 @@ proc nvme_identify stdcall, nsid:dword, dptr:dword, cns:byte
endp
;
proc detect_nvme
invoke GetPCIList
@ -130,15 +131,57 @@ proc detect_nvme
mov eax, dword [eax + PCIDEV.fd]
cmp eax, edx
jne .check_dev
xor eax, eax ; no more PCI devices to enumerate?
ret
.found_dev:
if __DEBUG__
movzx ebx, byte [eax + PCIDEV.devfn]
shr ebx, 3 ; get rid of 3 lowest bits (function code), the rest bits is device code
movzx ecx, byte [eax + PCIDEV.devfn]
and ecx, 00000111b ; get only 3 lowest bits (function code)
DEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", [eax + PCIDEV.bus], ebx, ecx
end if
push eax
mov eax, dword [pcidevs_len]
cmp eax, MAX_NVM_PCIDEVS
jne @f
pop eax
ret
@@:
mov ebx, dword [p_nvme_devices]
test ebx, ebx
jnz @f
invoke KernelAlloc, MAX_NVM_PCIDEVS_BYTES
test eax, eax
jz .err
mov dword [ebx], eax
@@:
mov ecx, dword [pcidevs_len]
inc ecx
mov dword [pcidevs_len], ecx
invoke KernelAlloc, sizeof.pcidev
test eax, eax
jz .err
mov dword [p_nvme_devices + ecx * 4], eax
mov ebx, eax
pop eax
mov ecx, dword [eax + PCIDEV.bus]
mov dword [ebx + pcidev.bus], ecx
mov ecx, dword [eax + PCIDEV.devfn]
mov dword [ebx + pcidev.devfn], ecx
jmp .check_dev
.err:
DEBUGF DBG_INFO, "error initializing NVMe driver: unable to allocate memory\n"
pop eax
ret
endp
; nvme_init: Initializes the NVMe controller
proc nvme_init, bus:dword, devfn:dword
proc device_is_compat, bus:dword, devfn:dword
invoke PciRead32, [bus], [devfn], PCI_header00.base_addr_0
and eax, 0xfffffff0
@ -149,6 +192,18 @@ proc nvme_init, bus:dword, devfn:dword
test eax, eax
jz .exit_fail
mov [p_mmap], eax
.exit_fail:
DEBUGF DBG_INFO, "(NVMe) Device is incompatible\n"
endp
; nvme_init: Initializes the NVMe controller
proc nvme_init, bus:dword, devfn:dword
test eax, eax
jz .exit_fail
mov eax, dword [p_mmap]
mov ebx, dword [eax + NVME_REG_MAP.CAP]
DEBUGF DBG_INFO, "(NVMe) Maximum queue entries supported: %u\n", bx
test ebx, CAP_CQR
@ -194,11 +249,23 @@ endp
proc nvme_cleanup
mov eax, [p_ident]
xor ecx, ecx
mov eax, dword [p_nvme_devices]
test eax, eax
jz @f
invoke KernelFree, eax
jz .last
@@:
mov ebx, dword [eax + ecx * 4]
invoke KernelFree, ebx
inc ecx
cmp ecx, dword [pcidevs_len]
jl @b
mov eax, dword [p_ident]
test eax, eax
jz .last
invoke KernelFree, eax
.last:
ret
endp
@ -210,6 +277,8 @@ align 4
;all initialized data place here
align 4
p_nvme_devices dd 0
pcidevs_len dd 0
my_service db "NVMe",0 ;max 16 chars include zero
include_debug_strings