2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2024-12-22 22:08:47 +01:00

wip: controller initialization

This commit is contained in:
Abdur-Rahman Mansoor 2024-06-12 18:03:01 -04:00
parent 5f43171b7e
commit 544565bde9

View File

@ -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