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: .entry:
DEBUGF DBG_INFO, "Detecting NVMe hardware...\n" DEBUGF DBG_INFO, "Detecting NVMe hardware...\n"
call detect_nvme call detect_nvme
test eax, eax mov eax, dword [p_nvme_devices]
test eax, eax
jz .err ; no NVMe device found? 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 test eax, eax
jz .err ; failed to initialize controller? jz .err ; failed to initialize controller?
@ -47,6 +48,7 @@ proc START c, reason:dword
ret ret
.err: .err:
DEBUGF DBG_INFO, "(NVMe) Cleaning up...\n"
call nvme_cleanup call nvme_cleanup
xor eax, eax xor eax, eax
ret ret
@ -114,7 +116,6 @@ proc nvme_identify stdcall, nsid:dword, dptr:dword, cns:byte
endp endp
;
proc detect_nvme proc detect_nvme
invoke GetPCIList invoke GetPCIList
@ -130,15 +131,57 @@ proc detect_nvme
mov eax, dword [eax + PCIDEV.fd] mov eax, dword [eax + PCIDEV.fd]
cmp eax, edx cmp eax, edx
jne .check_dev jne .check_dev
xor eax, eax ; no more PCI devices to enumerate? ret
.found_dev: .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 ret
endp endp
; nvme_init: Initializes the NVMe controller proc device_is_compat, bus:dword, devfn:dword
proc nvme_init, bus:dword, devfn:dword
invoke PciRead32, [bus], [devfn], PCI_header00.base_addr_0 invoke PciRead32, [bus], [devfn], PCI_header00.base_addr_0
and eax, 0xfffffff0 and eax, 0xfffffff0
@ -149,6 +192,18 @@ proc nvme_init, bus:dword, devfn:dword
test eax, eax test eax, eax
jz .exit_fail jz .exit_fail
mov [p_mmap], eax 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] mov ebx, dword [eax + NVME_REG_MAP.CAP]
DEBUGF DBG_INFO, "(NVMe) Maximum queue entries supported: %u\n", bx DEBUGF DBG_INFO, "(NVMe) Maximum queue entries supported: %u\n", bx
test ebx, CAP_CQR test ebx, CAP_CQR
@ -187,18 +242,30 @@ proc nvme_init, bus:dword, devfn:dword
.exit_fail: .exit_fail:
DEBUGF DBG_INFO, "ERROR: failed to initialize NVMe controller\n" DEBUGF DBG_INFO, "ERROR: failed to initialize NVMe controller\n"
xor eax, eax xor eax, eax
ret ret
endp endp
proc nvme_cleanup proc nvme_cleanup
mov eax, [p_ident] xor ecx, ecx
test eax, eax mov eax, dword [p_nvme_devices]
jz @f test eax, eax
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 ret
endp endp
@ -210,6 +277,8 @@ align 4
;all initialized data place here ;all initialized data place here
align 4 align 4
p_nvme_devices dd 0
pcidevs_len dd 0
my_service db "NVMe",0 ;max 16 chars include zero my_service db "NVMe",0 ;max 16 chars include zero
include_debug_strings include_debug_strings