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
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user