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

wip: add interrupt handling code

This commit is contained in:
Abdur-Rahman Mansoor 2024-06-09 13:07:01 -04:00
parent 482d186c1a
commit dd3ebb1716

View File

@ -110,6 +110,7 @@ proc set_cdw0 stdcall, opcode:byte, cid:word
endp endp
; See pages 161-205 of the NVMe 1.4 specification for reference
proc nvme_identify stdcall, pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte proc nvme_identify stdcall, pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte
push esi push esi
@ -448,10 +449,10 @@ proc device_is_compat stdcall, pci:dword
and eax, CAP_DSTRD and eax, CAP_DSTRD
; Stride is (2 ^ (2 + DSTRD)) bytes ; Stride is (2 ^ (2 + DSTRD)) bytes
add eax, 2 add al, 2
stdcall pow2, eax stdcall pow2, eax
mov ecx, eax mov ecx, eax
mov dword [esi + pcidev.dstrd], eax mov byte [esi + pcidev.dstrd], al
; 1003h + ((2y + 1) * (4 << CAP.DSTRD)) ; 1003h + ((2y + 1) * (4 << CAP.DSTRD))
mov eax, 4 mov eax, 4
@ -522,14 +523,6 @@ proc nvme_init stdcall, pci:dword
cmp eax, NVM_MPS cmp eax, NVM_MPS
jl .exit_fail jl .exit_fail
; Check Interrupt Mask Set/Clear
if 0
mov eax, dword [edi + NVME_MMIO.INTMS]
DEBUGF DBG_INFO, "(NVMe) INTMS: %x\n", eax
mov eax, dword [edi + NVME_MMIO.INTMC]
DEBUGF DBG_INFO, "(NVMe) INTMC: %x\n", eax
end if
; Configure AMS, MPS, CSS ; Configure AMS, MPS, CSS
mov eax, dword [edi + NVME_MMIO.CC] mov eax, dword [edi + NVME_MMIO.CC]
and eax, not (CC_AMS or CC_MPS or CC_CSS) and eax, not (CC_AMS or CC_MPS or CC_CSS)
@ -573,9 +566,11 @@ proc nvme_init stdcall, pci:dword
; Restart the controller ; Restart the controller
stdcall nvme_controller_start, edi stdcall nvme_controller_start, edi
invoke AllocPage invoke KernelAlloc, 0x1000
test eax, eax test eax, eax
jz .exit_fail jz .exit_fail
mov dword [dptr], eax
invoke GetPhysAddr
; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte ; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte
stdcall nvme_identify, [pci], 0, eax, 0, CNS_IDCS stdcall nvme_identify, [pci], 0, eax, 0, CNS_IDCS
@ -643,21 +638,6 @@ proc nvme_wait stdcall, mmio:dword
endp endp
; Writes to completion queue 'y' head doorbell
proc cqyhdbl_write stdcall, mmio:dword, dstrd:byte, y:byte
; 1000h + ((2y + 1) * (4 << CAP.DSTRD))
xor ecx, ecx
shl ecx, [y]
inc ecx
mov eax, 4
shl eax, [dstrd]
imul eax, ecx
add eax, 0x1000
ret
endp
; Writes to submission queue 'y' tail doorbell ; Writes to submission queue 'y' tail doorbell
proc sqytdbl_write stdcall, pci:dword, y:byte, sqt:word proc sqytdbl_write stdcall, pci:dword, y:byte, sqt:word
@ -684,6 +664,38 @@ proc sqytdbl_write stdcall, pci:dword, y:byte, sqt:word
endp endp
; Writes to completion queue 'y' head doorbell
proc cqyhdbl_write stdcall, pci:dword, y:byte, cqh:word
push esi
mov esi, [pci]
; 1000h + ((2y + 1) * (4 << CAP.DSTRD))
xor eax, eax
mov cl, [y]
shl eax, cl
inc eax
mov edx, 4
mov cl, byte [esi + pcidev.dstrd]
shl edx, cl
imul edx, eax
add edx, 0x1000
movzx eax, [cqh]
cmp ax, NVM_ACQS
jl @f
xor ax, ax
@@:
inc ax
mov esi, dword [esi + pcidev.io_addr]
;DEBUGF DBG_INFO, "(NVMe) Writing to CQ%uHDBL\n", edx
mov word [esi + edx], ax ; Write to CQyHDBL
pop esi
ret
endp
proc write_admin_cmd stdcall, pci:dword proc write_admin_cmd stdcall, pci:dword
push esi push esi
@ -724,19 +736,37 @@ endp
proc irq_handler proc irq_handler
push esi push esi edi
mov esi, dword [p_nvme_devices] mov esi, dword [p_nvme_devices]
mov esi, dword [esi + pcidev.cq_ptr] mov edi, esi
mov ax, word [esi + CQ_ENTRY.sqid] mov esi, dword [esi + pcidev.io_addr]
DEBUGF DBG_INFO, "SQID: %x\n", ax mov edi, dword [edi + pcidev.cq_ptr]
mov ax, word [esi + CQ_ENTRY.sqhd] mov dword [esi + NVME_MMIO.INTMS], 0x1
DEBUGF DBG_INFO, "SQHD: %x\n", ax mov eax, dword [edi + CQ_ENTRY.sqid]
mov ax, word [esi + CQ_ENTRY.status] DEBUGF DBG_INFO, "(NVMe) SQID: %u\n", eax
DEBUGF DBG_INFO, "Status: %x\n", ax mov eax, dword [edi + CQ_ENTRY.status]
DEBUGF DBG_INFO, "(NVMe) Status: %x\n", eax
test al, al
jz @f
; error occurred
; Interrupt not handled by driver, return 0 ; 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)
stdcall nvme_controller_reset, esi
stdcall nvme_controller_start, esi
jmp .exit
@@:
stdcall cqyhdbl_write, [p_nvme_devices], 0, 0x0
mov dword [esi + NVME_MMIO.INTMC], 0x1
.exit:
; Interrupt handled by driver, return 1
xor eax, eax xor eax, eax
pop esi inc eax
pop edi esi
ret ret
endp endp
@ -766,6 +796,7 @@ endp
align 4 align 4
p_nvme_devices dd 0 p_nvme_devices dd 0
pcidevs_len dd 0 pcidevs_len dd 0
dptr dd ?
my_service db "NVMe",0 ;max 16 chars include zero my_service db "NVMe",0 ;max 16 chars include zero
if __DEBUG__ if __DEBUG__
include_debug_strings include_debug_strings