From 654b095d6fc18c7e900fccaf46c74f771db5478f Mon Sep 17 00:00:00 2001 From: Abdur-Rahman Mansoor Date: Thu, 6 Jun 2024 13:28:31 -0400 Subject: [PATCH] add assertions for `nvme_identify` and wip implementation of `create_namespace` --- drivers/nvme/nvme.asm | 56 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index 5102c4b..d79afa8 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -110,14 +110,41 @@ proc set_cdw0 stdcall, opcode:byte, cid:word endp -proc nvme_identify stdcall, pci:dword, slot: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 mov esi, [pci] + + ; It's important to check if CNS is a valid value here. In revision 1.0 + ; CNS is a 1 bit field and a two bit field in revision 1.1, using invalid + ; values results in undefined behavior (see page 162 of NVMe 1.4 spec) + if __DEBUG__ + push esi + mov esi, dword [esi + pcidev.mmio_ptr] + mov eax, dword [esi + NVME_MMIO.VS] + cmp eax, VS110 + jne @f + cmp [cns], 11b + jle .ok + DEBUGF DBG_INFO, "(NVMe) FATAL ERROR: INVALID CNS VALUE ON v1.1.0 CONTROLLERS\n" + jmp .err + + @@: + cmp eax, VS100 + jne .ok + cmp [cns], 1b + jle .ok + DEBUGF DBG_INFO, "(NVMe) FATAL ERROR: INVALID CNS VALUE ON v1.0.0 CONTROLLERS\n" + jmp .err + + .err: + jmp @b + + .ok: + + end if + mov esi, [esi + pcidev.sq_ptr] - mov eax, [slot] - imul eax, sizeof.SQ_ENTRY - add esi, eax stdcall memset, esi, 0, sizeof.SQ_ENTRY mov eax, [nsid] @@ -137,6 +164,22 @@ proc nvme_identify stdcall, pci:dword, slot:dword, nsid:dword, dptr:dword, cid:w endp +; See pages 348-349 of the NVMe 1.4 specification for information on creating namespaces +proc create_namespace stdcall, pci:dword, cid:word + + push esi + invoke AllocPage + test eax, eax + jz .fail + invoke GetPhysAddr + stdcall nvme_identify, [pci], 0xffffffff, eax, [cid], CNS_IDNS + +.fail: + pop esi + ret + +endp + ; See page 101 of the NVMe 1.4 specification for reference proc create_io_completion_queue stdcall, pci:dword, prp1:dword, qid:word, ien:byte @@ -216,6 +259,7 @@ proc abort stdcall, pci:dword, cid:word, sqid:word endp + ; See page 205 of the NVMe 1.4 specification for reference proc set_features stdcall, pci:dword, dptr:dword, fid:byte @@ -513,8 +557,8 @@ proc nvme_init stdcall, pci:dword invoke AllocPage test eax, eax jz .exit_fail - ; pci:dword, slot:dword, nsid:dword, dptr:dword, cid:word, cns:byte - stdcall nvme_identify, [pci], 0, 0, eax, 0, CNS_IDCS + ; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte + stdcall nvme_identify, [pci], 0, eax, 0, CNS_IDCS xor eax, eax inc eax