From 9c1147b31dbdaa47b790e3655da5aa075f363b19 Mon Sep 17 00:00:00 2001 From: Abdur-Rahman Mansoor Date: Thu, 13 Jun 2024 12:46:34 -0400 Subject: [PATCH] fix admin commands and auto assign CIDS --- drivers/nvme/nvme.asm | 73 +++++++++++++++++++------------------------ drivers/nvme/nvme.inc | 2 ++ 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index e8a04d2..982f4ad 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -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 diff --git a/drivers/nvme/nvme.inc b/drivers/nvme/nvme.inc index 297e8bc..0a1c554 100644 --- a/drivers/nvme/nvme.inc +++ b/drivers/nvme/nvme.inc @@ -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