mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2024-11-14 03:56:09 +01:00
add IRQ completion queue head pointer wraparound and NSID identification
This commit is contained in:
parent
20b7315829
commit
7782f762ef
@ -179,7 +179,12 @@ proc is_active_namespace stdcall, pci:dword, nsid:dword
|
||||
@@:
|
||||
mov esi, eax
|
||||
invoke GetPhysAddr
|
||||
DEBUGF DBG_INFO, "Identify Namespace: %u\n", [nsid]
|
||||
stdcall nvme_identify, [pci], [nsid], eax, CNS_IDNS
|
||||
push esi
|
||||
mov esi, 130
|
||||
invoke Sleep
|
||||
pop esi
|
||||
xor ecx, ecx
|
||||
|
||||
@@:
|
||||
@ -191,12 +196,16 @@ proc is_active_namespace stdcall, pci:dword, nsid:dword
|
||||
jne @b
|
||||
|
||||
.not_active_nsid:
|
||||
DEBUGF DBG_INFO, "Not an active NSID\n"
|
||||
invoke KernelFree, esi
|
||||
pop edi esi
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.is_active_nsid:
|
||||
DEBUGF DBG_INFO, "ACTIVE NSID: %u\n", [nsid]
|
||||
cmp [nsid], 1
|
||||
jne @b
|
||||
invoke KernelFree, esi
|
||||
pop edi esi
|
||||
xor eax, eax
|
||||
@ -213,42 +222,34 @@ endp
|
||||
proc determine_active_nsids stdcall, pci:dword
|
||||
|
||||
push ebx esi edi
|
||||
mov esi, [pci]
|
||||
;mov edi, [edi + pcidev.nsids]
|
||||
xor ebx, ebx
|
||||
invoke KernelAlloc, 0x1000
|
||||
test eax, eax
|
||||
jnz @f
|
||||
pop edi esi ebx
|
||||
ret
|
||||
|
||||
@@:
|
||||
mov esi, eax
|
||||
invoke GetPhysAddr
|
||||
stdcall nvme_identify, [pci], 0, eax, CNS_IDCS
|
||||
mov edi, [pci]
|
||||
mov eax, dword [esi + IDENTC.nn] ; maximum value of a valid NSID for the NVM subsystem
|
||||
mov dword [edi + pcidev.nn], eax
|
||||
mov edi, [edi + pcidev.nsids]
|
||||
xor ecx, ecx
|
||||
xor edx, edx
|
||||
inc ecx
|
||||
|
||||
.loop:
|
||||
cmp ecx, dword [esi + IDENTC.nn]
|
||||
je .ret
|
||||
cmp ecx, dword [esi + pcidev.nn]
|
||||
jg .ret
|
||||
push ecx edx
|
||||
stdcall is_active_namespace, [pci], ecx
|
||||
pop edx ecx
|
||||
test eax, eax
|
||||
jz .not_active_namespace
|
||||
mov dword [edi + ecx * 4], ecx
|
||||
;mov dword [edi + ecx * 4], ecx
|
||||
mov ebx, ecx
|
||||
inc edx
|
||||
|
||||
.not_active_namespace:
|
||||
inc ecx
|
||||
jmp .loop
|
||||
|
||||
.ret:
|
||||
invoke KernelFree, esi
|
||||
pop edi esi ebx
|
||||
mov eax, ebx
|
||||
ret
|
||||
|
||||
|
||||
endp
|
||||
|
||||
; See page 101 of the NVMe 1.4 specification for reference
|
||||
@ -653,6 +654,9 @@ proc nvme_init stdcall, pci:dword
|
||||
; pci:dword, nsid:dword, dptr:dword, cns:byte
|
||||
stdcall nvme_identify, [pci], 0, eax, CNS_IDCS
|
||||
mov edi, ebx
|
||||
mov eax, dword [edi + IDENTC.nn]
|
||||
mov dword [esi + pcidev.nn], eax
|
||||
DEBUGF DBG_INFO, "(NVMe) Namespace Count: %u\n", eax
|
||||
lea ebx, byte [edi + IDENTC.sn]
|
||||
lea eax, byte [esi + pcidev.serial]
|
||||
stdcall memcpy, eax, ebx, 20
|
||||
@ -712,6 +716,8 @@ proc nvme_init stdcall, pci:dword
|
||||
mov dword [esi + NVM_QUEUE_ENTRY.sq_ptr], eax
|
||||
invoke GetPhysAddr
|
||||
stdcall create_io_submission_queue, [pci], eax, 1, 1
|
||||
|
||||
stdcall determine_active_nsids, [pci]
|
||||
|
||||
DEBUGF DBG_INFO, "(NVMe) Successfully initialized driver!\n"
|
||||
xor eax, eax
|
||||
@ -728,44 +734,14 @@ proc nvme_init stdcall, pci:dword
|
||||
endp
|
||||
|
||||
proc get_new_cid stdcall, pci:dword, y:dword
|
||||
|
||||
push esi ebx
|
||||
|
||||
push esi
|
||||
mov esi, [pci]
|
||||
mov esi, [esi + pcidev.queue_entries]
|
||||
mov ecx, [y]
|
||||
imul ecx, sizeof.NVM_QUEUE_ENTRY
|
||||
mov esi, [pci]
|
||||
mov esi, dword [esi + pcidev.queue_entries]
|
||||
lea esi, dword [esi + ecx]
|
||||
mov eax, dword [esi + NVM_QUEUE_ENTRY.cid_slots]
|
||||
xor edx, edx
|
||||
cmp eax, 0xffffffff
|
||||
jne @f
|
||||
mov eax, dword [esi + NVM_QUEUE_ENTRY.cid_slots + 4]
|
||||
add edx, 4
|
||||
cmp eax, 0xffffffff
|
||||
jne @f
|
||||
pop ebx esi
|
||||
mov eax, -1
|
||||
ret
|
||||
|
||||
@@:
|
||||
mov ebx, eax
|
||||
|
||||
; Equivalant to (~(-X) & ~(X)), retrieves first free bit
|
||||
not eax
|
||||
mov ecx, eax
|
||||
neg ecx
|
||||
and eax, ecx
|
||||
or ebx, eax
|
||||
|
||||
mov ecx, [y]
|
||||
mov dword [esi + edx + NVM_QUEUE_ENTRY.cid_slots], ebx
|
||||
bsf eax, eax
|
||||
cmp edx, 4
|
||||
jne @f
|
||||
add eax, 32
|
||||
|
||||
@@:
|
||||
pop ebx esi
|
||||
mov eax, dword [esi + ecx + NVM_QUEUE_ENTRY.tail]
|
||||
pop esi
|
||||
ret
|
||||
|
||||
endp
|
||||
@ -969,15 +945,20 @@ proc irq_handler
|
||||
; we have to initiate a controller reset if a admin command encounters
|
||||
; a fatal error or if a completion is not received for a deletion
|
||||
; of a submission or completion queue (section 10.1 - page 400 of NVMe 1.4 spec)
|
||||
mov esi, dword [p_nvme_devices]
|
||||
mov esi, dword [esi + pcidev.io_addr]
|
||||
stdcall nvme_controller_reset, esi
|
||||
stdcall nvme_controller_start, esi
|
||||
jmp .end
|
||||
jmp @b
|
||||
;mov esi, dword [p_nvme_devices]
|
||||
;mov esi, dword [esi + pcidev.io_addr]
|
||||
;stdcall nvme_controller_reset, esi
|
||||
;stdcall nvme_controller_start, esi
|
||||
;jmp .end
|
||||
|
||||
.ok:
|
||||
mov eax, dword [esi + edx + CQ_ENTRY.cdw0]
|
||||
inc ecx
|
||||
cmp ecx, NVM_ACQS
|
||||
jng @f
|
||||
xor ecx, ecx
|
||||
@@:
|
||||
; TODO: Check how many commands were consumed later
|
||||
stdcall cqyhdbl_write, dword [p_nvme_devices], 0, ecx
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user