From 544565bde90eb70c6104b4322015ad58d59d8101 Mon Sep 17 00:00:00 2001 From: Abdur-Rahman Mansoor Date: Wed, 12 Jun 2024 18:03:01 -0400 Subject: [PATCH] wip: controller initialization --- drivers/nvme/nvme.asm | 71 +++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index 17c7b36..e8a04d2 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -27,6 +27,7 @@ include "../pci.inc" include "../peimport.inc" include "nvme.inc" include "macros.inc" +include "lib.asm" proc START c, reason:dword @@ -84,23 +85,6 @@ proc service_proc stdcall, ioctl:dword endp -proc memset stdcall, p_data:dword, val:byte, sz:dword - - push ebx ecx - mov eax, [p_data] - mov ecx, [sz] - mov bl, [val] - -@@: - mov byte [eax + ecx], bl - dec ecx - test ecx, ecx - jnz @b - pop ecx ebx - ret - -endp - proc set_cdw0 stdcall, opcode:byte, cid:word movzx eax, [cid] @@ -463,6 +447,7 @@ proc device_is_compat stdcall, pci:dword mov dword [esi + pcidev.io_addr], eax mov eax, dword [eax + NVME_MMIO.VS] DEBUGF DBG_INFO, "(NVMe) Controller version: 0x%x\n", eax + mov dword [esi + pcidev.version], eax pop ecx edx esi xor eax, eax inc eax @@ -494,11 +479,6 @@ proc nvme_init stdcall, pci:dword DEBUGF DBG_INFO, "(NVMe) CSTS: 0x%x\n", eax end if - mov eax, dword [edi + NVME_MMIO.CAP] - test eax, CAP_CQR - jz .cqr_not_req - -.cqr_not_req: ; For some reason, bit 7 (No I/O command set supported) is also set to 1 despite bit 0 (NVM command set) ; being set to 1.. so I am not sure if bit 7 should be checked at all.. investigate later. mov eax, dword [edi + NVME_MMIO.CAP + 4] @@ -518,10 +498,15 @@ proc nvme_init stdcall, pci:dword cmp eax, NVM_MPS jl .exit_fail - ; Configure AMS, MPS, CSS + ; Configure IOSQES, IOCQES, AMS, MPS, CSS mov eax, dword [edi + NVME_MMIO.CC] and eax, not (CC_AMS or CC_MPS or CC_CSS) - or eax, 111b shl 4 ; Admin Command Set Only (temporary) + ; CSS = 0 (NVM Command Set) + ; AMS = 0 (Round Robin) + ; MPS = 0 (4KiB Pages) + ; IOSQES = 6 (64B) + ; IOCQES = 4 (16B) + or eax, (4 shl 20) or (6 shl 16) and dword [edi + NVME_MMIO.CC], eax ; Configure Admin Queue Attributes @@ -581,18 +566,44 @@ proc nvme_init stdcall, pci:dword 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 - mov esi, dword [esi + pcidev.cq_ptr] + stdcall nvme_identify, [pci], 0, ebx, eax, CNS_IDCS + mov ebx, dword [esi + pcidev.cq_ptr] ; Wait until phase tag bit is set @@: - mov al, byte [esi + CQ_ENTRY.status] - test al, CQ_PHASE_TAG + test byte [ebx + CQ_ENTRY.status], CQ_PHASE_TAG jz @b + mov edx, dword [dptr] + lea edx, byte [edx + IDENTC.sn] + lea eax, byte [esi + pcidev.serial] + stdcall memcpy, eax, edx, 20 + DEBUGF DBG_INFO, "(NVMe) Serial Number: %s\n", eax + add edx, 20 + lea eax, byte [esi + pcidev.model] + stdcall memcpy, eax, edx, 40 + DEBUGF DBG_INFO, "(NVMe) Model: %s\n", eax + mov ebx, dword [esi + pcidev.version] mov esi, dword [dptr] - mov ax, word [esi + IDENTC.vid] - DEBUGF DBG_INFO, "(NVMe) IDENTC.vid = %x\n", ax + cmp ebx, VS140 + jl @f + ; This is a reserved field in pre-1.4 controllers + mov al, byte [esi + IDENTC.cntrltype] + cmp al, CNTRLTYPE_IO_CONTROLLER + jne .exit_fail + DEBUGF DBG_INFO, "(NVMe) I/O controller detected...\n" + +@@: + mov al, byte [esi + IDENTC.sqes] + and al, 11110000b + cmp al, 0x60 ; maximum submission queue size should at least be 64 bytes + jl .exit_fail + mov al, byte [esi + IDENTC.cqes] + and al, 11110000b + and al, 0x40 ; maximum completion queue entry size should at least be 16 bytes + jl .exit_fail + + ;DEBUGF DBG_INFO, "(NVMe) Successfully initialized driver!\n" xor eax, eax inc eax pop edi esi ebx