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:
parent
482d186c1a
commit
dd3ebb1716
@ -110,6 +110,7 @@ proc set_cdw0 stdcall, opcode:byte, cid:word
|
||||
|
||||
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
|
||||
|
||||
push esi
|
||||
@ -448,10 +449,10 @@ proc device_is_compat stdcall, pci:dword
|
||||
and eax, CAP_DSTRD
|
||||
|
||||
; Stride is (2 ^ (2 + DSTRD)) bytes
|
||||
add eax, 2
|
||||
add al, 2
|
||||
stdcall pow2, eax
|
||||
mov ecx, eax
|
||||
mov dword [esi + pcidev.dstrd], eax
|
||||
mov byte [esi + pcidev.dstrd], al
|
||||
|
||||
; 1003h + ((2y + 1) * (4 << CAP.DSTRD))
|
||||
mov eax, 4
|
||||
@ -522,14 +523,6 @@ proc nvme_init stdcall, pci:dword
|
||||
cmp eax, NVM_MPS
|
||||
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
|
||||
mov eax, dword [edi + NVME_MMIO.CC]
|
||||
and eax, not (CC_AMS or CC_MPS or CC_CSS)
|
||||
@ -573,9 +566,11 @@ proc nvme_init stdcall, pci:dword
|
||||
; Restart the controller
|
||||
stdcall nvme_controller_start, edi
|
||||
|
||||
invoke AllocPage
|
||||
invoke KernelAlloc, 0x1000
|
||||
test eax, eax
|
||||
jz .exit_fail
|
||||
mov dword [dptr], eax
|
||||
invoke GetPhysAddr
|
||||
; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte
|
||||
stdcall nvme_identify, [pci], 0, eax, 0, CNS_IDCS
|
||||
|
||||
@ -643,21 +638,6 @@ proc nvme_wait stdcall, mmio:dword
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
; 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
|
||||
|
||||
push esi
|
||||
@ -724,19 +736,37 @@ endp
|
||||
|
||||
proc irq_handler
|
||||
|
||||
push esi
|
||||
push esi edi
|
||||
mov esi, dword [p_nvme_devices]
|
||||
mov esi, dword [esi + pcidev.cq_ptr]
|
||||
mov ax, word [esi + CQ_ENTRY.sqid]
|
||||
DEBUGF DBG_INFO, "SQID: %x\n", ax
|
||||
mov ax, word [esi + CQ_ENTRY.sqhd]
|
||||
DEBUGF DBG_INFO, "SQHD: %x\n", ax
|
||||
mov ax, word [esi + CQ_ENTRY.status]
|
||||
DEBUGF DBG_INFO, "Status: %x\n", ax
|
||||
mov edi, esi
|
||||
mov esi, dword [esi + pcidev.io_addr]
|
||||
mov edi, dword [edi + pcidev.cq_ptr]
|
||||
mov dword [esi + NVME_MMIO.INTMS], 0x1
|
||||
mov eax, dword [edi + CQ_ENTRY.sqid]
|
||||
DEBUGF DBG_INFO, "(NVMe) SQID: %u\n", eax
|
||||
mov eax, dword [edi + CQ_ENTRY.status]
|
||||
DEBUGF DBG_INFO, "(NVMe) Status: %x\n", eax
|
||||
test al, al
|
||||
jz @f
|
||||
|
||||
; Interrupt not handled by driver, return 0
|
||||
; error occurred
|
||||
|
||||
; 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
|
||||
pop esi
|
||||
inc eax
|
||||
pop edi esi
|
||||
ret
|
||||
|
||||
endp
|
||||
@ -766,6 +796,7 @@ endp
|
||||
align 4
|
||||
p_nvme_devices dd 0
|
||||
pcidevs_len dd 0
|
||||
dptr dd ?
|
||||
my_service db "NVMe",0 ;max 16 chars include zero
|
||||
if __DEBUG__
|
||||
include_debug_strings
|
||||
|
Loading…
Reference in New Issue
Block a user