2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2025-01-22 05:08:16 +01:00

fix admin commands and auto assign CIDS

This commit is contained in:
Abdur-Rahman Mansoor 2024-06-13 12:46:34 -04:00
parent 544565bde9
commit 9c1147b31d
2 changed files with 34 additions and 41 deletions

View File

@ -85,17 +85,18 @@ proc service_proc stdcall, ioctl:dword
endp
proc set_cdw0 stdcall, opcode:byte, cid:word
proc set_cdw0 stdcall, pci:dword, y:dword, opcode:byte
movzx eax, [cid]
stdcall get_new_cid, [pci], [y]
DEBUGF DBG_INFO, "(NVMe) get_new_cid: %u\n", eax
shl eax, 16
or eax, [opcode]
or al, [opcode]
ret
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, cns:byte
push esi
mov esi, [pci]
@ -137,10 +138,8 @@ proc nvme_identify stdcall, pci:dword, nsid:dword, dptr:dword, cid:word, cns:byt
mov dword [esi + SQ_ENTRY.nsid], eax
mov eax, [dptr]
mov dword [esi + SQ_ENTRY.dptr], eax
movzx eax, [cid]
shl eax, 16
mov dword [esi + SQ_ENTRY.cdw0], ADM_CMD_IDENTIFY
or dword [esi + SQ_ENTRY.cdw0], eax
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_IDENTIFY
mov dword [esi + SQ_ENTRY.cdw0], eax
mov al, [cns]
mov byte [esi + SQ_ENTRY.cdw10], al
stdcall write_admin_cmd, [pci]
@ -158,7 +157,7 @@ proc create_namespace stdcall, pci:dword, cid:word
test eax, eax
jz .fail
invoke GetPhysAddr
stdcall nvme_identify, [pci], 0xffffffff, eax, [cid], CNS_IDNS
stdcall nvme_identify, [pci], 0xffffffff, eax, CNS_IDNS
.fail:
pop esi
@ -181,7 +180,7 @@ proc create_io_completion_queue stdcall, pci:dword, prp1:dword, qid:word, ien:by
or ebx, eax ; CDW.PC
mov esi, [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_CRE_IO_COMPLETION_QUEUE, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_CRE_IO_COMPLETION_QUEUE
mov dword [esi + SQ_ENTRY.cdw0], eax
; Since we are not using MSI-X or MSI vector (yet), CDW11.IV must be set to 0
mov dword [esi + SQ_ENTRY.cdw11], ebx
@ -190,8 +189,7 @@ proc create_io_completion_queue stdcall, pci:dword, prp1:dword, qid:word, ien:by
mov dword [esi + SQ_ENTRY.cdw10], ebx
mov ebx, [prp1]
mov dword [esi + SQ_ENTRY.dptr], ebx
stdcall sqytdbl_write, [pci], [qid], 0 ; setting last param to 0 for now, change later
stdcall write_admin_cmd, [pci]
pop ebx esi
ret
@ -207,7 +205,7 @@ proc create_io_submission_queue stdcall, pci:dword, prp1:dword, qid:word, cqid:w
and ebx, 0x1 ; CDW11.PC
mov esi, [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_CRE_IO_SUBMISSION_QUEUE, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_CRE_IO_SUBMISSION_QUEUE
mov dword [esi + SQ_ENTRY.cdw0], eax
movzx eax, [cqid]
shl eax, 16
@ -220,8 +218,7 @@ proc create_io_submission_queue stdcall, pci:dword, prp1:dword, qid:word, cqid:w
mov dword [esi + SQ_ENTRY.cdw10], ebx
mov ebx, [prp1]
mov dword [esi + SQ_ENTRY.dptr], ebx
stdcall sqytdbl_write, [pci], [qid], 0 ; setting last param to 0 for now, change later
stdcall write_admin_cmd, [pci]
pop ebx esi
ret
@ -233,13 +230,13 @@ proc abort stdcall, pci:dword, cid:word, sqid:word
push esi
mov esi, [pci]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_ABORT, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_ABORT
mov dword [esi + SQ_ENTRY.cdw0], eax
mov eax, [cid]
shl eax, 16
or eax, [sqid]
mov dword [esi + SQ_ENTRY.cdw10], eax
stdcall sqytdbl_write, [pci], 0, 0
stdcall write_admin_cmd, [pci]
pop esi
ret
@ -251,15 +248,15 @@ proc set_features stdcall, pci:dword, dptr:dword, fid:byte
push esi
mov esi, [pci]
mov esi, [esi + pcidev.sq_ptr]
mov esi, dword [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, AMD_CMD_SET_FEATURES, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, AMD_CMD_SET_FEATURES
mov eax, [dptr]
mov dword [esi + SQ_ENTRY.dptr], eax
mov al, [fid]
mov byte [esi + SQ_ENTRY.cdw10], al
; TODO: Set CDW10.SV and CDW14.UUID to valid value
stdcall sqytdbl_write, [pci], 0, 0
stdcall write_admin_cmd, [pci]
pop esi
ret
@ -270,13 +267,13 @@ proc delete_io_completion_queue stdcall, pci:dword, qid:word
push esi
mov esi, [pci]
mov esi, [esi + pcidev.sq_ptr]
mov esi, dword [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_DEL_IO_COMPLETION_QUEUE, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_DEL_IO_COMPLETION_QUEUE
mov dword [esi + SQ_ENTRY.cdw0], eax
mov ax, [qid]
mov word [esi + SQ_ENTRY.cdw10], ax
stdcall sqytdbl_write, [pci], [qid], 0 ; setting last param to 0 for now, change later
stdcall write_admin_cmd, [pci]
pop esi
ret
@ -289,7 +286,7 @@ proc get_features stdcall, pci:dword, dptr:dword, sel:byte, fid:byte
mov esi, [pci]
mov esi, [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_GET_FEATURES, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_GET_FEATURES
mov dword [esi + SQ_ENTRY.cdw0], eax
movzx eax, [fid] ; CDW10.FID
movzx ebx, [sel]
@ -300,7 +297,7 @@ proc get_features stdcall, pci:dword, dptr:dword, sel:byte, fid:byte
mov eax, [dptr]
mov dword [esi + SQ_ENTRY.dptr], eax
; TODO: Implement CDW14.UUID?
stdcall sqytdbl_write, [pci], 0, 0
stdcall write_admin_cmd, [pci]
pop ebx esi
ret
@ -313,11 +310,11 @@ proc delete_io_submission_queue stdcall, pci:dword, qid:word
mov esi, [pci]
mov esi, [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_DEL_IO_SUBMISSION_QUEUE, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_DEL_IO_SUBMISSION_QUEUE
mov dword [esi + SQ_ENTRY.cdw0], eax
mov ax, [qid]
mov word [esi + SQ_ENTRY.cdw10], ax
stdcall sqytdbl_write, [pci], [qid], 0 ; setting last param to 0 for now, change later
stdcall write_admin_cmd, [pci]
pop esi
ret
@ -331,7 +328,7 @@ proc get_log_page stdcall, pci:dword, dptr:dword, lid:byte
mov esi, [pci]
mov esi, [esi + pcidev.sq_ptr]
stdcall memset, esi, 0, sizeof.SQ_ENTRY
stdcall set_cdw0, ADM_CMD_GET_LOG_PAGE, 0 ; [TODO: Set CID to valid value]
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_GET_LOG_PAGE
mov dword [esi + SQ_ENTRY.cdw0], eax
mov eax, [dptr]
mov dword [esi + SQ_ENTRY.dptr], eax
@ -407,14 +404,6 @@ proc device_is_compat stdcall, pci:dword
push esi edx ecx
mov esi, [pci]
invoke PciRead8, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header00.interrupt_pin
test eax, eax
jz .failure
mov byte [esi + pcidev.ipin], al
;invoke PciRead16, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header.command
;test eax, eax
;jz .failure
;DEBUGF DBG_INFO, "(NVMe) CMD: %x\n", eax
invoke PciRead8, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header00.interrupt_line
mov byte [esi + pcidev.iline], al
invoke PciRead32, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header00.base_addr_0
@ -562,11 +551,8 @@ proc nvme_init stdcall, pci:dword
jz .exit_fail
mov dword [dptr], eax
invoke GetPhysAddr
mov ebx, eax
stdcall get_new_cid, [pci], 0
DEBUGF DBG_INFO, "(NVMe) Got Command Identifier: %u\n", eax
; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte
stdcall nvme_identify, [pci], 0, ebx, eax, CNS_IDCS
; pci:dword, nsid:dword, dptr:dword, cns:byte
stdcall nvme_identify, [pci], 0, eax, CNS_IDCS
mov ebx, dword [esi + pcidev.cq_ptr]
; Wait until phase tag bit is set
@ -602,6 +588,11 @@ proc nvme_init stdcall, pci:dword
and al, 11110000b
and al, 0x40 ; maximum completion queue entry size should at least be 16 bytes
jl .exit_fail
;invoke GetPhysAddr, esi
;stdcall set_features, [pci], eax, FID_NUMBER_OF_QUEUES
; Creates I/O Queues
;stdcall create_io_completion_queue, [pci],
;DEBUGF DBG_INFO, "(NVMe) Successfully initialized driver!\n"
xor eax, eax

View File

@ -21,6 +21,8 @@ NVM_MPS = 0 ; Memory Page Size (2 ^ (12 + MPS))
NVM_ASQS = 2 ; Admin Submission Queue Size
NVM_ACQS = NVM_ASQS ; Admin Completion Queue Size
ADMIN_QUEUE = 0 ; Admin Queue ID
; Opcodes for NVM commands
NVM_CMD_FLUSH = 0x00
NVM_CMD_WRITE = 0x01