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:
parent
5f43171b7e
commit
544565bde9
@ -27,6 +27,7 @@ include "../pci.inc"
|
|||||||
include "../peimport.inc"
|
include "../peimport.inc"
|
||||||
include "nvme.inc"
|
include "nvme.inc"
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
|
include "lib.asm"
|
||||||
|
|
||||||
proc START c, reason:dword
|
proc START c, reason:dword
|
||||||
|
|
||||||
@ -84,23 +85,6 @@ proc service_proc stdcall, ioctl:dword
|
|||||||
|
|
||||||
endp
|
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
|
proc set_cdw0 stdcall, opcode:byte, cid:word
|
||||||
|
|
||||||
movzx eax, [cid]
|
movzx eax, [cid]
|
||||||
@ -463,6 +447,7 @@ proc device_is_compat stdcall, pci:dword
|
|||||||
mov dword [esi + pcidev.io_addr], eax
|
mov dword [esi + pcidev.io_addr], eax
|
||||||
mov eax, dword [eax + NVME_MMIO.VS]
|
mov eax, dword [eax + NVME_MMIO.VS]
|
||||||
DEBUGF DBG_INFO, "(NVMe) Controller version: 0x%x\n", eax
|
DEBUGF DBG_INFO, "(NVMe) Controller version: 0x%x\n", eax
|
||||||
|
mov dword [esi + pcidev.version], eax
|
||||||
pop ecx edx esi
|
pop ecx edx esi
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
@ -494,11 +479,6 @@ proc nvme_init stdcall, pci:dword
|
|||||||
DEBUGF DBG_INFO, "(NVMe) CSTS: 0x%x\n", eax
|
DEBUGF DBG_INFO, "(NVMe) CSTS: 0x%x\n", eax
|
||||||
end if
|
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)
|
; 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.
|
; 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]
|
mov eax, dword [edi + NVME_MMIO.CAP + 4]
|
||||||
@ -518,10 +498,15 @@ proc nvme_init stdcall, pci:dword
|
|||||||
cmp eax, NVM_MPS
|
cmp eax, NVM_MPS
|
||||||
jl .exit_fail
|
jl .exit_fail
|
||||||
|
|
||||||
; Configure AMS, MPS, CSS
|
; Configure IOSQES, IOCQES, AMS, MPS, CSS
|
||||||
mov eax, dword [edi + NVME_MMIO.CC]
|
mov eax, dword [edi + NVME_MMIO.CC]
|
||||||
and eax, not (CC_AMS or CC_MPS or CC_CSS)
|
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
|
and dword [edi + NVME_MMIO.CC], eax
|
||||||
|
|
||||||
; Configure Admin Queue Attributes
|
; Configure Admin Queue Attributes
|
||||||
@ -581,18 +566,44 @@ proc nvme_init stdcall, pci:dword
|
|||||||
stdcall get_new_cid, [pci], 0
|
stdcall get_new_cid, [pci], 0
|
||||||
DEBUGF DBG_INFO, "(NVMe) Got Command Identifier: %u\n", eax
|
DEBUGF DBG_INFO, "(NVMe) Got Command Identifier: %u\n", eax
|
||||||
; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte
|
; pci:dword, nsid:dword, dptr:dword, cid:word, cns:byte
|
||||||
stdcall nvme_identify, [pci], 0, ebx, eax, CNS_IDCS
|
stdcall nvme_identify, [pci], 0, ebx, eax, CNS_IDCS
|
||||||
mov esi, dword [esi + pcidev.cq_ptr]
|
mov ebx, dword [esi + pcidev.cq_ptr]
|
||||||
|
|
||||||
; Wait until phase tag bit is set
|
; Wait until phase tag bit is set
|
||||||
@@:
|
@@:
|
||||||
mov al, byte [esi + CQ_ENTRY.status]
|
test byte [ebx + CQ_ENTRY.status], CQ_PHASE_TAG
|
||||||
test al, CQ_PHASE_TAG
|
|
||||||
jz @b
|
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 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
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
pop edi esi ebx
|
pop edi esi ebx
|
||||||
|
Loading…
Reference in New Issue
Block a user