2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2024-12-22 22:08:47 +01:00

more refactoring and fixes

This commit is contained in:
Abdur-Rahman Mansoor 2024-06-09 18:13:01 -04:00
parent 83004aca87
commit 4e9a9cc8c2

View File

@ -540,21 +540,31 @@ proc nvme_init stdcall, pci:dword
test eax, eax
jz .exit_fail
mov dword [esi + pcidev.sq_ptr], eax
DEBUGF DBG_INFO, "(NVMe) ASQ: Virtual Address: 0x%x\n", eax
invoke GetPhysAddr
DEBUGF DBG_INFO, "(NVMe) ASQ: Physical Address: 0x%x\n", eax
mov dword [edi + NVME_MMIO.ASQ], eax
and dword [edi + NVME_MMIO.ASQ + 4], 0
invoke KernelAlloc, 0x1000
test eax, eax
jz .exit_fail
mov dword [esi + pcidev.cq_ptr], eax
DEBUGF DBG_INFO, "(NVMe) ACQ: Virtual Address: 0x%x\n", eax
invoke GetPhysAddr
DEBUGF DBG_INFO, "(NVMe) ACQ: Physical Address: 0x%x\n", eax
mov dword [edi + NVME_MMIO.ACQ], eax
and dword [edi + NVME_MMIO.ACQ + 4], 0
stdcall memset, dword [esi + pcidev.sq_ptr], 0, sizeof.SQ_ENTRY * NVM_ASQS
stdcall memset, dword [esi + pcidev.cq_ptr], 0, sizeof.CQ_ENTRY * NVM_ACQS
; Allocate list of queues
invoke KernelAlloc, sizeof.NVM_QUEUE * NVM_ASQS
test eax, eax
jz .exit_fail
mov dword [esi + pcidev.queue_ptr], eax
stdcall memset, eax, 0, sizeof.NVM_QUEUE * NVM_ASQS
; we want to disable all interrupts for now, since the controller randomly
; generates interrupts while starting up
mov dword [edi + NVME_MMIO.INTMS], 0xffffffff
; Attach interrupt handler
movzx eax, byte [esi + pcidev.iline]
DEBUGF DBG_INFO, "(NVMe) Attaching interrupt handler to IRQ %u\n", eax
@ -565,6 +575,7 @@ proc nvme_init stdcall, pci:dword
; Restart the controller
stdcall nvme_controller_start, edi
mov dword [edi + NVME_MMIO.INTMC], 0xffffffff ; re-enable interrupts
invoke KernelAlloc, 0x1000
test eax, eax
@ -631,7 +642,7 @@ proc nvme_wait stdcall, mmio:dword
mov esi, dword [esi + NVME_MMIO.CAP]
and esi, CAP_TO
shr esi, 24
imul esi, 50
imul esi, 100 ; TODO: bad time delay, set to appropriate value later
invoke Sleep
pop esi
ret
@ -656,7 +667,6 @@ proc sqytdbl_write stdcall, pci:dword, y:byte, sqt:word
DEBUGF DBG_INFO, "(NVMe) Writing to submission queue 0x%x doorbell register\n", ebx
mov esi, [esi + pcidev.io_addr]
DEBUGF DBG_INFO, "(NVMe) MMIO: %x\n", esi
mov ax, [sqt]
mov word [esi + ebx], ax ; Write to register
pop esi ebx
@ -665,23 +675,24 @@ proc sqytdbl_write stdcall, pci:dword, y:byte, sqt:word
endp
; Writes to completion queue 'y' head doorbell
proc cqyhdbl_write stdcall, pci:dword, y:byte, cqh:word
proc cqyhdbl_write stdcall, pci:dword, y:byte
push esi
push esi edi
mov esi, [pci]
; 1000h + ((2y + 1) * (4 << CAP.DSTRD))
xor eax, eax
mov cl, [y]
shl eax, cl
inc eax
mov edx, 4
movzx eax, [y]
shl al, 1
inc al
mov dx, 4
mov cl, byte [esi + pcidev.dstrd]
shl edx, cl
imul edx, eax
add edx, 0x1000
shl dx, cl
imul dx, ax
add dx, 0x1000
movzx eax, [cqh]
movzx ecx, [y]
mov edi, dword [esi + pcidev.queue_ptr]
mov ax, word [edi + ecx * sizeof.NVM_QUEUE + NVM_QUEUE.head] ; get head for completion queue Y
cmp ax, NVM_ACQS
jl @f
xor ax, ax
@ -689,9 +700,10 @@ proc cqyhdbl_write stdcall, pci:dword, y:byte, cqh:word
@@:
inc ax
mov esi, dword [esi + pcidev.io_addr]
;DEBUGF DBG_INFO, "(NVMe) Writing to CQ%uHDBL\n", edx
DEBUGF DBG_INFO, "(NVMe) Writing to completion queue doorbell register 0x%x: %u\n", dx, ax
mov word [esi + edx], ax ; Write to CQyHDBL
pop esi
mov word [edi + ecx * sizeof.NVM_QUEUE + NVM_QUEUE.head], ax
pop edi esi
ret
endp
@ -700,16 +712,18 @@ proc write_admin_cmd stdcall, pci:dword
push esi
mov esi, [pci]
mov ax, word [esi + pcidev.sq_adm_tail]
mov esi, dword [esi + pcidev.queue_ptr]
mov ax, word [esi + NVM_QUEUE.tail]
cmp ax, NVM_ASQS
jl @f
xor ax, ax
@@:
mov word [esi + pcidev.sq_adm_tail], ax
mov esi, [pci]
mov esi, dword [esi + pcidev.io_addr]
inc ax
mov word [esi + 0x1000], ax
mov word [esi + NVM_QUEUE.tail], ax
pop esi
ret
@ -758,8 +772,8 @@ proc irq_handler
jmp .exit
@@:
stdcall cqyhdbl_write, [p_nvme_devices], 0, 0x0
mov dword [esi + NVME_MMIO.INTMC], 0x1
stdcall cqyhdbl_write, [p_nvme_devices], 0
.exit:
; Interrupt handled by driver, return 1