feat: add NVMe driver
This commit is contained in:
parent
975284f5f3
commit
d4441724ce
269
drivers/nvme/command.inc
Normal file
269
drivers/nvme/command.inc
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;; ;;
|
||||||
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
|
;; Version 2, June 1991 ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
proc set_cdw0 stdcall, pci:dword, y:dword, opcode:byte
|
||||||
|
|
||||||
|
stdcall get_new_cid, [pci], [y]
|
||||||
|
shl eax, 16
|
||||||
|
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, prp1:dword, cns:byte
|
||||||
|
|
||||||
|
push esi
|
||||||
|
mov esi, [pci]
|
||||||
|
mov dword [esi + pcidev.spinlock], 1
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
|
||||||
|
mov eax, [nsid]
|
||||||
|
mov dword [esp + SQ_ENTRY.nsid], eax
|
||||||
|
mov eax, [prp1]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_IDENTIFY
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov al, [cns]
|
||||||
|
mov byte [esp + SQ_ENTRY.cdw10], al
|
||||||
|
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||||
|
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall nvme_poll, esi
|
||||||
|
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:dword, ien:byte
|
||||||
|
|
||||||
|
push esi
|
||||||
|
mov esi, [pci]
|
||||||
|
mov dword [esi + pcidev.spinlock], 1
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_CRE_IO_COMPLETION_QUEUE
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov eax, [prp1]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
mov eax, CQ_ENTRIES shl 16 ; CDW10.QSIZE
|
||||||
|
or eax, [qid] ; CDW10.QID
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
|
movzx eax, [ien] ; CDW11.IEN
|
||||||
|
or eax, 0x1 ; CDW11.PC
|
||||||
|
; Don't set CDW11.IV since we're not using MSI-X or MSI vector
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||||
|
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall nvme_poll, esi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 103-104 of the NVMe 1.4 specification for reference
|
||||||
|
proc create_io_submission_queue stdcall, pci:dword, prp1:dword, qid:dword, cqid:word
|
||||||
|
|
||||||
|
push esi
|
||||||
|
mov esi, [pci]
|
||||||
|
mov dword [esi + pcidev.spinlock], 1
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_CRE_IO_SUBMISSION_QUEUE
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov eax, [prp1]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
mov eax, SQ_ENTRIES shl 16 ; CDW10.QSIZE
|
||||||
|
or eax, [qid]
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
|
movzx eax, [cqid]
|
||||||
|
shl eax, 16 ; CDW11.CQID
|
||||||
|
or eax, 0x1 ; CDW11.PC (always set this to 1 as some devices may not support non-contiguous pages)
|
||||||
|
; TODO: Set CDW10.QPRIO
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||||
|
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall nvme_poll, esi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 95-96 of the NVMe 1.4 specification for reference
|
||||||
|
proc abort stdcall, pci:dword, cid:word, sqid:word
|
||||||
|
|
||||||
|
push esi
|
||||||
|
mov esi, [pci]
|
||||||
|
mov dword [esi + pcidev.spinlock], 1
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_ABORT
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
movzx eax, [cid]
|
||||||
|
shl eax, 16
|
||||||
|
or eax, word [sqid]
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
|
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall nvme_poll, esi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
; See page 205 of the NVMe 1.4 specification for reference
|
||||||
|
proc set_features stdcall, pci:dword, prp1:dword, fid:byte, cdw11:dword
|
||||||
|
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_SET_FEATURES
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov eax, [prp1]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
movzx eax, [fid]
|
||||||
|
;or eax, 1 shl 31 ; CDW10.SV
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
|
mov eax, [cdw11]
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||||
|
stdcall sqytdbl_write, [pci], ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 105 of the NVMe 1.4 specification for reference
|
||||||
|
proc delete_io_completion_queue stdcall, pci:dword, qid:word
|
||||||
|
|
||||||
|
push esi
|
||||||
|
mov esi, [pci]
|
||||||
|
mov dword [esi + pcidev.spinlock], 1
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_DEL_IO_COMPLETION_QUEUE
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov ax, [qid]
|
||||||
|
mov word [esp + SQ_ENTRY.cdw10], ax
|
||||||
|
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall nvme_poll, esi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 114-116 of the NVMe 1.4 specification for reference
|
||||||
|
proc get_features stdcall, pci:dword, prp1:dword, sel:byte, fid:byte
|
||||||
|
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_GET_FEATURES
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
movzx eax, [sel]
|
||||||
|
and eax, 111b
|
||||||
|
shl eax, 8 ; CDW10.SEL
|
||||||
|
or eax, byte [fid] ; CDW10.FID
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
|
mov eax, [prp1]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
; TODO: Implement CDW14.UUID?
|
||||||
|
stdcall sqytdbl_write, [pci], ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 105-106 of the NVMe 1.4 specification for reference
|
||||||
|
proc delete_io_submission_queue stdcall, pci:dword, qid:word
|
||||||
|
|
||||||
|
push esi
|
||||||
|
mov esi, [pci]
|
||||||
|
mov dword [esi + pcidev.spinlock], 1
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, esi, ADMIN_QUEUE, ADM_CMD_DEL_IO_SUBMISSION_QUEUE
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov ax, [qid]
|
||||||
|
mov word [esp + SQ_ENTRY.cdw10], ax
|
||||||
|
stdcall sqytdbl_write, esi, ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall nvme_poll, esi
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 117-118 of the NVMe 1.4 specification for reference
|
||||||
|
; INCOMPLETE
|
||||||
|
proc get_log_page stdcall, pci:dword, prp1:dword, lid:byte
|
||||||
|
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, [pci], ADMIN_QUEUE, ADM_CMD_GET_LOG_PAGE
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax
|
||||||
|
mov eax, [prp1]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
ret
|
||||||
|
|
||||||
|
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, CNS_IDNS
|
||||||
|
test eax, eax
|
||||||
|
jz .fail
|
||||||
|
|
||||||
|
.fail:
|
||||||
|
pop esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; See page 258-261 (read) and 269-271 (write) of the NVMe 1.4 specification for reference
|
||||||
|
proc nvme_io_rw stdcall, pci:dword, qid:word, nsid:dword, prps:qword, slba:qword, nlb:dword, opcode:dword
|
||||||
|
|
||||||
|
; TODO: Use IDENTC.NOIOB to construct read/write commands that don't
|
||||||
|
; cross the I/O boundary to achieve optimal performance
|
||||||
|
;
|
||||||
|
; TODO: Read AWUN/NAWUN
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
movzx ecx, [qid]
|
||||||
|
stdcall set_cdw0, [pci], ecx, [opcode]
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw0], eax ; CDW0
|
||||||
|
mov eax, dword [prps]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp1], eax
|
||||||
|
mov eax, dword [prps + 4]
|
||||||
|
mov dword [esp + SQ_ENTRY.prp2], eax
|
||||||
|
mov eax, [nsid]
|
||||||
|
mov dword [esp + SQ_ENTRY.nsid], eax
|
||||||
|
mov eax, dword [slba] ; slba_lo
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
|
mov eax, dword [slba + 4] ; slba_hi
|
||||||
|
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||||
|
mov eax, [nlb]
|
||||||
|
mov word [esp + SQ_ENTRY.cdw12], ax
|
||||||
|
movzx ecx, [qid]
|
||||||
|
stdcall sqytdbl_write, [pci], ecx, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; vim: syntax=fasm
|
35
drivers/nvme/lib.inc
Normal file
35
drivers/nvme/lib.inc
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;; ;;
|
||||||
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
|
;; Version 2, June 1991 ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
proc memsetdz stdcall, dest:dword, sz:dword
|
||||||
|
|
||||||
|
push edi
|
||||||
|
mov edi, [dest]
|
||||||
|
mov ecx, [sz]
|
||||||
|
xor eax, eax
|
||||||
|
rep stosd
|
||||||
|
pop edi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc memcpyd stdcall, dest:dword, src:dword, sz:dword
|
||||||
|
|
||||||
|
push esi edi
|
||||||
|
mov esi, [src]
|
||||||
|
mov edi, [dest]
|
||||||
|
mov ecx, [sz]
|
||||||
|
rep movsd
|
||||||
|
pop edi esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; vim: syntax=fasm
|
30
drivers/nvme/macros.inc
Normal file
30
drivers/nvme/macros.inc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;; ;;
|
||||||
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
|
;; Version 2, June 1991 ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
macro PDEBUGF _level*, _fmt*, _bus*, _devfn*, [_args] {
|
||||||
|
common
|
||||||
|
if __DEBUG__
|
||||||
|
sub esp, 12
|
||||||
|
push ebx
|
||||||
|
movzx ebx, _bus
|
||||||
|
mov dword [esp + 4], ebx
|
||||||
|
movzx ebx, _devfn
|
||||||
|
shr ebx, 3 ; get rid of 3 lowest bits (function code), the rest bits is device code
|
||||||
|
mov dword [esp + 8], ebx
|
||||||
|
movzx ebx, _devfn
|
||||||
|
and ebx, 00000111b ; get only 3 lowest bits (function code)
|
||||||
|
mov dword [esp + 12], ebx
|
||||||
|
pop ebx
|
||||||
|
DEBUGF _level, _fmt, [esp], [esp + 4], [esp + 8], _args
|
||||||
|
add esp, 12
|
||||||
|
end if
|
||||||
|
}
|
||||||
|
|
||||||
|
; vim: syntax=fasm
|
1414
drivers/nvme/nvme.asm
Normal file
1414
drivers/nvme/nvme.asm
Normal file
File diff suppressed because it is too large
Load Diff
591
drivers/nvme/nvme.inc
Normal file
591
drivers/nvme/nvme.inc
Normal file
@ -0,0 +1,591 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||||
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
|
;; ;;
|
||||||
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||||
|
;; Version 2, June 1991 ;;
|
||||||
|
;; ;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
; NVMe Controller Versions
|
||||||
|
VS100 = 0x00010000 ; (v1.0.0)
|
||||||
|
VS110 = 0x00010100 ; (v1.1.0)
|
||||||
|
VS120 = 0x00010200 ; (V1.2.0)
|
||||||
|
VS121 = 0x00010201 ; (v1.2.1)
|
||||||
|
VS130 = 0x00010300 ; (v1.3.0)
|
||||||
|
VS140 = 0x00010400 ; (v1.4.0)
|
||||||
|
|
||||||
|
NVM_MPS = 0 ; Memory Page Size (2 ^ (12 + MPS))
|
||||||
|
NVM_ASQS = 64 ; Admin Submission Queue Size
|
||||||
|
NVM_ACQS = NVM_ASQS ; Admin Completion Queue Size
|
||||||
|
LAST_QUEUE_ID = 1 ; Index of the last queue
|
||||||
|
SQ_ENTRIES = NVM_ASQS ; I/O and Admin Submission Queue Size
|
||||||
|
CQ_ENTRIES = NVM_ACQS ; I/O and Admin Completion Queue Size
|
||||||
|
PAGE_SIZE = 4096 shl NVM_MPS ; Use 4KiB pages
|
||||||
|
SUPPORTED_LBADS = 9 ; KolibriOS only supports LBADS of 512, later on we may remove this restriction
|
||||||
|
SQ_ALLOC_SIZE = 0x1000
|
||||||
|
CQ_ALLOC_SIZE = 0x1000
|
||||||
|
QUEUE_ALLOC_SIZE = SQ_ALLOC_SIZE + CQ_ALLOC_SIZE
|
||||||
|
SIZEOF_SQ_ENTRY = 6 ; log2(sizeof.SQ_ENTRY)
|
||||||
|
SIZEOF_CQ_ENTRY = 4 ; log2(sizeof.CQ_ENTRY)
|
||||||
|
SIZEOF_NVM_QUEUE_ENTRY = 4 ; log2(sizeof.NVM_QUEUE_ENTRY)
|
||||||
|
SIZEOF_NVMQCMD = 4 ; log2(sizeof.NVMQCMD)
|
||||||
|
|
||||||
|
MSIXCAP_CID = 0x11
|
||||||
|
MSIXCAP_MXE = 1 shl 15 ; MSI-X Enable bit
|
||||||
|
MSICAP_CID = 0x05
|
||||||
|
MSICAP_MSIE = 1 ; MSI Enable bit
|
||||||
|
|
||||||
|
ADMIN_QUEUE = 0 ; Admin Queue ID
|
||||||
|
|
||||||
|
IEN_ON = 2
|
||||||
|
IEN_OFF = 0
|
||||||
|
|
||||||
|
; Opcodes for NVM commands
|
||||||
|
NVM_CMD_FLUSH = 0x00
|
||||||
|
NVM_CMD_WRITE = 0x01
|
||||||
|
NVM_CMD_READ = 0x02
|
||||||
|
NVM_CMD_WRITE_UNCORRECTABLE = 0x04
|
||||||
|
NVM_CMD_COMPARE = 0x05
|
||||||
|
NVM_CMD_WRITE_ZEROES = 0x08
|
||||||
|
NVM_CMD_DATASET_MANAGEMENT = 0x09
|
||||||
|
NVM_CMD_VERIFY = 0x0C
|
||||||
|
NVM_CMD_RESERVATION_REG = 0x0D
|
||||||
|
NVM_CMD_RESERVATION_REPORT = 0x0E
|
||||||
|
NVM_CMD_RESERVATION_ACQUIRE = 0x11
|
||||||
|
NVM_CMD_RESERVATION_RELEASE = 0x15
|
||||||
|
NVM_CMD_COPY = 0x19
|
||||||
|
|
||||||
|
; Opcodes for admin commands (Page 94 of NVMe 1.4 spec)
|
||||||
|
ADM_CMD_DEL_IO_SUBMISSION_QUEUE = 0x00
|
||||||
|
ADM_CMD_CRE_IO_SUBMISSION_QUEUE = 0x01
|
||||||
|
ADM_CMD_GET_LOG_PAGE = 0x02
|
||||||
|
ADM_CMD_DEL_IO_COMPLETION_QUEUE = 0x04
|
||||||
|
ADM_CMD_CRE_IO_COMPLETION_QUEUE = 0x05
|
||||||
|
ADM_CMD_IDENTIFY = 0x06
|
||||||
|
ADM_CMD_ABORT = 0x08
|
||||||
|
ADM_CMD_SET_FEATURES = 0x09
|
||||||
|
ADM_CMD_GET_FEATURES = 0x0A
|
||||||
|
|
||||||
|
; fuse (fused operation): In a fused operation, a complex command is created by 'fusing' together
|
||||||
|
; two simpler commands. This field specifies whether this command is part
|
||||||
|
; of a fused operation, and if so, which command it is in the sequence:
|
||||||
|
; 00b -> Normal operation
|
||||||
|
; 01b -> Fused operation, first command
|
||||||
|
; 10b -> Fused operation, second command
|
||||||
|
; 11b -> Reserved
|
||||||
|
NO_FUSE = 0
|
||||||
|
FUSE_OP_FIRST_CMD = 1 shl 8
|
||||||
|
FUSE_OP_SECOND_CMD = 2 shl 8
|
||||||
|
|
||||||
|
; sel (PRP or SGL for data transfer): This field specifies whether PRPs or SGLs are used for any
|
||||||
|
; data transfer associated with the command. PRPs shall be
|
||||||
|
; used for all Admin commands for NVMe over PCIe implementations.
|
||||||
|
; SGLs shall be used for all Admin and I/O commands for NVMe over
|
||||||
|
; Fabrics implementations (i.e., field set to 01b):
|
||||||
|
; 00b -> PRPs are used for this transfer
|
||||||
|
; 01b -> SGLs are used for this transfer, MPTR will contain address of
|
||||||
|
; a single contiguous physical buffer that is byte aligned
|
||||||
|
; 10b -> SGLs are used for this transfer. MPTR will contain address of
|
||||||
|
; an SGL segment containing exactly one SGL descriptor that is
|
||||||
|
; QWORD aligned
|
||||||
|
; 11b -> Reserved
|
||||||
|
SEL_PRP = 0
|
||||||
|
SEL_SGL = 1 shl 14
|
||||||
|
|
||||||
|
; Controller or Namespace Structure (CNS) specifies the information to be returned to the host.
|
||||||
|
CNS_IDNS = 0x0 ; Namespace data structure (NSID)
|
||||||
|
CNS_IDCS = 0x1 ; Controller data structure
|
||||||
|
CNS_ANIDL = 0x2 ; Active namespace ID list (NSID)
|
||||||
|
CNS_NIDL = 0x3 ; Namespace identification descriptor list (NSID)
|
||||||
|
CNS_NVM_SL = 0x4 ; NVM Set List
|
||||||
|
|
||||||
|
; Optional Admin Command Support (OACS) values
|
||||||
|
OACS_SEC_SEN_RECV_SUPPORTED = 1 shl 0
|
||||||
|
OACS_FMT_NVM_SUPPORTED = 1 shl 1
|
||||||
|
OACS_FIRM_COMDL_SUPPORTED = 1 shl 2
|
||||||
|
OACS_NSMAN_SUPPORTED = 1 shl 3
|
||||||
|
|
||||||
|
; scope is all attached namespaces or all namespaces in NVM subsystem
|
||||||
|
NSID_BROADCAST = 0xFFFFFFFF
|
||||||
|
|
||||||
|
NSSRC_RESET = 0x4E564D65 ; "NVMe" (initiates a NVMe subsystem reset)
|
||||||
|
|
||||||
|
; NVMe Capabilities
|
||||||
|
CAP_MQES = 0xff
|
||||||
|
CAP_CQR = 1 shl 16
|
||||||
|
CAP_AMS = (1 shl 17) or (1 shl 18)
|
||||||
|
CAP_TO = 0xff000000
|
||||||
|
CAP_DSTRD = 1 or (1 shl 1) or (1 shl 2) or (1 shl 3)
|
||||||
|
CAP_NSSRS = 1 shl 4
|
||||||
|
CAP_CSS_NVM_CMDSET = 1 shl 5
|
||||||
|
CAP_CSS_NOIO = 1 shl 12
|
||||||
|
CAP_BPS = 1 shl 14
|
||||||
|
CAP_CPS_COSCOP = 1 shl 15
|
||||||
|
CAP_CPS_DOSCOP = 1 shl 16
|
||||||
|
CAP_CPS_NVMSCOP = CAP_CPS_COSCOP or CAP_CPS_DOSCOP
|
||||||
|
CAP_MPSMIN = (1 shl 17) or (1 shl 18) or (1 shl 19) or (1 shl 20)
|
||||||
|
CAP_MPSMAX = (1 shl 21) or (1 shl 22) or (1 shl 23) or (1 shl 24)
|
||||||
|
CAP_PMRS = 1 shl 25
|
||||||
|
CAP_CMBS = 1 shl 26
|
||||||
|
CAP_NSSS = 1 shl 27
|
||||||
|
CAP_CRMS_CRWMS = 1 shl 28
|
||||||
|
CAP_CRMS_CRIMS = 1 shl 29
|
||||||
|
|
||||||
|
; Controller Configuration Bits
|
||||||
|
CC_EN = 1
|
||||||
|
CC_CSS = (1 shl 4) or (1 shl 5) or (1 shl 6)
|
||||||
|
CC_MPS = (1 shl 7) or (1 shl 8) or (1 shl 9) or (1 shl 10)
|
||||||
|
CC_AMS = (1 shl 11) or (1 shl 12) or (1 shl 13)
|
||||||
|
CC_SHN = (1 shl 14) or (1 shl 15)
|
||||||
|
CC_IOSQES = (1 shl 16) or (1 shl 17) or (1 shl 18) or (1 shl 19)
|
||||||
|
CC_IOCQES = (1 shl 20) or (1 shl 21) or (1 shl 22) or (1 shl 23)
|
||||||
|
CC_CRIME = 1 shl 24
|
||||||
|
|
||||||
|
CC_SHN_NORMAL_SHUTDOWN = 1 shl 14
|
||||||
|
CC_SHN_ABRUPT_SHUTDOWN = 1 shl 15
|
||||||
|
|
||||||
|
CC_DEFAULT_IOSQES = SIZEOF_SQ_ENTRY shl 16
|
||||||
|
CC_DEFAULT_IOCQES = SIZEOF_CQ_ENTRY shl 20
|
||||||
|
|
||||||
|
; Completion Queue Entry Status Field Values
|
||||||
|
CQ_PHASE_TAG = 1 shl 0
|
||||||
|
CQ_STATUS_SC = 0xfe
|
||||||
|
CQ_STATUS_SCT = (1 shl 9) or (1 shl 10) or (1 shl 11)
|
||||||
|
CQ_STATUS_CRD = (1 shl 12) or (1 shl 13)
|
||||||
|
CQ_STATUS_M = 1 shl 14
|
||||||
|
CQ_STATUS_DNR = 1 shl 15
|
||||||
|
|
||||||
|
; Completion Queue Entry Status Field - Status Code Type Values
|
||||||
|
CQ_STATUS_SCT_GCS = 0x0 ; Generic Command Status
|
||||||
|
CQ_STATUS_SCT_CSS = 0x1 ; Command Specific Status
|
||||||
|
CQ_STATUS_SCT_MADIE = 0x2 ; Media and Data Integrity Errors
|
||||||
|
CQ_STATUS_SCT_PRS = 0x3 ; Path Related Status
|
||||||
|
|
||||||
|
; Completion Queue Entry Status Field - Status Code Generic Command Values
|
||||||
|
CQ_STATUS_SC_GCS_SUCCESS = 0x00 ; Successful Completion
|
||||||
|
CQ_STATUS_SC_GCS_ICOP = 0x01 ; Invalid Command Opcode
|
||||||
|
CQ_STATUS_SC_GCS_IFIC = 0x02 ; Invalid Field in Command
|
||||||
|
CQ_STATUS_SC_GCS_CIDC = 0x03 ; Command ID Conflict
|
||||||
|
CQ_STATUS_SC_GCS_DTE = 0x04 ; Data Transfer Error
|
||||||
|
CQ_STATUS_SC_GCS_CAPLN = 0x05 ; Commands Aborted due to Power Loss Notification
|
||||||
|
CQ_STATUS_SC_GCS_INERR = 0x06 ; Internal Error
|
||||||
|
CQ_STATUS_SC_GCS_CAR = 0x07 ; Command Abort Requested
|
||||||
|
CQ_STATUS_SC_GCS_CASQD = 0x08 ; Command Aborted due to SQ Deletion
|
||||||
|
CQ_STATUS_SC_GCS_CAFFC = 0x09 ; Command Aborted due to Failed Fused Command
|
||||||
|
CQ_STATUS_SC_GCS_CAMFC = 0x0A ; Command Aborted due to Missing Fused Command
|
||||||
|
CQ_STATUS_SC_GCS_INNOF = 0x0B ; Invalid Namespace or Format
|
||||||
|
CQ_STATUS_SC_GCS_CSE = 0x0C ; Command Sequence Error
|
||||||
|
CQ_STATUS_SC_GCS_INSGL = 0x0D ; Invalid SGL Segment Descriptor
|
||||||
|
CQ_STATUS_SC_GCS_INNSGL = 0x0E ; Invalid Number of SGL Descriptors
|
||||||
|
CQ_STATUS_SC_GCS_OPDEN = 0x15 ; Operation Denied
|
||||||
|
CQ_STATUS_SC_GCS_NSIWP = 0x20 ; Namespace is Write Protected
|
||||||
|
CQ_STATUS_SC_GCS_CINT = 0x21 ; Command Interrupted
|
||||||
|
CQ_STATUS_SC_GCS_TTE = 0x22 ; Transient Transport Error
|
||||||
|
|
||||||
|
; Completion Queue Entry Status Field - Status Code Media and Data Integrity Errors
|
||||||
|
CQ_STATUS_SC_MADIE_WF = 0x80 ; Write Fault
|
||||||
|
CQ_STATUS_SC_MADIE_URE = 0x81 ; Unrecovered Read Error
|
||||||
|
CQ_STATUS_SC_MADIE_ACDEN = 0x86 ; Access Denied
|
||||||
|
CQ_STATUS_SC_MADIE_DOULB = 0x87 ; Deallocated or Unwritten Logical Block
|
||||||
|
|
||||||
|
; Controller Status (CSTS) Values
|
||||||
|
CSTS_RDY = 1
|
||||||
|
CSTS_CFS = 1 shl 1
|
||||||
|
CSTS_SHST = (1 shl 2) or (1 shl 3)
|
||||||
|
CSTS_NSSRO = 1 shl 4
|
||||||
|
CSTS_PP = 1 shl 5
|
||||||
|
CSTS_SHST_SHUTDOWN_OCCURRING = 1 shl 2
|
||||||
|
CSTS_SHST_SHUTDOWN_COMPLETE = 1 shl 3
|
||||||
|
|
||||||
|
; Admin Queue Attributes (AQA) Values
|
||||||
|
AQA_ASQS = 0xfff
|
||||||
|
AQA_ACQS = 0xfff shl 16
|
||||||
|
|
||||||
|
; CDW10.SEL Values (Page 115 of NVMe 1.4 specification)
|
||||||
|
CDW10_SEL_CURRENT = 000b
|
||||||
|
CDW10_SEL_DEFAULT = 001b
|
||||||
|
CDW10_SEL_SAVED = 010b
|
||||||
|
CDW10_SEL_SUPPORTED_CAPABILITIES = 011b
|
||||||
|
|
||||||
|
; Feature Identifiers (FID) Values (Page 206 of NVMe 1.4 specification)
|
||||||
|
; Used in Get/Set Features Commands
|
||||||
|
FID_ARBITRATION = 0x01
|
||||||
|
FID_POWER_MANAGEMENT = 0x02
|
||||||
|
FID_LBA_RANGE_TYPE = 0x03
|
||||||
|
FID_TEMPERATURE_THRESHOLD = 0x04
|
||||||
|
FID_ERROR_RECOVERY = 0x05
|
||||||
|
FID_VOLATILE_WRITE_CACHE = 0x06
|
||||||
|
FID_NUMBER_OF_QUEUES = 0x07
|
||||||
|
FID_INTERRUPT_COALESCING = 0x08
|
||||||
|
FID_INTERRUPT_VECTOR_CONFIGURATION = 0x09
|
||||||
|
FID_WRITE_ATOMICITY_NORMAL = 0x0A
|
||||||
|
FID_ASYNCHRONOUS_EVENT_CONFIGURATION = 0x0B
|
||||||
|
FID_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C
|
||||||
|
FID_HOST_MEMORY_BUFFER = 0x0D
|
||||||
|
FID_TIMESTAMP = 0x0E
|
||||||
|
FID_KEEP_ALIVE_TIMER = 0x0F
|
||||||
|
FID_HOST_CONTROLLED_THERMAL_MANAGEMENT = 0x10
|
||||||
|
FID_NON_OPERATIONAL_POWER_STATE_CONFIG = 0x11
|
||||||
|
FID_READ_RECOVERY_LEVEL_CONFIG = 0x12
|
||||||
|
FID_PREDICTABLE_LATENCY_MODE_CONFIG = 0x13
|
||||||
|
FID_PREDICTABLE_LATENCY_MODE_WINDOW = 0x14
|
||||||
|
FID_LBA_STATUS_INFORMATION_REPORT_INTERVAL = 0x15
|
||||||
|
FID_HOST_BEHAVIOR_SUPPORT = 0x16
|
||||||
|
FID_SANITIZE_CONFIG = 0x17
|
||||||
|
FID_ENDURANCE_GROUP_EVENT_CONFIGURATION = 0x18
|
||||||
|
; NVM Command Set Specific - FID
|
||||||
|
FID_SOFTWARE_PROGRESS_MARKER = 0x80
|
||||||
|
FID_HOST_IDENTIFIER = 0x81
|
||||||
|
FID_RESERVATION_NOTIFICATION_MASK = 0x82
|
||||||
|
FID_RESERVATION_PERSISTENCE = 0x83
|
||||||
|
FID_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84
|
||||||
|
|
||||||
|
; Get Log Page - Log Page Identifiers (Page 118-119 of NVMe 1.4 specification)
|
||||||
|
LID_ERROR_INFORMATION = 0x01
|
||||||
|
LID_SMARTHEALTH_INFORMATION = 0x02
|
||||||
|
LID_FIRMWARE_SLOT_INFORMATION = 0x03
|
||||||
|
LID_CHANGED_NAMESPACE_LIST = 0x04
|
||||||
|
LID_COMMANDS_SUPPORTED_AND_EFFECTS = 0x05
|
||||||
|
LID_DEVICE_SELF_TEST = 0x06
|
||||||
|
LID_TELEMETRY_HOST_INITIATED = 0x07
|
||||||
|
LID_TELEMETRY_CONTROLLER_INITIATED = 0x08
|
||||||
|
LID_ENDURANCE_GROUP_INFORMATION = 0x09
|
||||||
|
LID_PREDICTABLE_LATENCY_PER_NVM_SET = 0x0A
|
||||||
|
LID_PREDICTABLE_LATENCY_EVENT_AGGREGATE = 0x0B
|
||||||
|
LID_ASYMMETRIC_NAMESPACE_ACCESS = 0x0C
|
||||||
|
LID_PERSISTENT_EVENT_LOG = 0x0D
|
||||||
|
LID_LBA_STATUS_INFORMATION = 0x0E
|
||||||
|
LID_ENDURANCE_GROUP_EVENT_AGGREGATE = 0x0F
|
||||||
|
; I/O Command Set Specific - Log Page Identifiers
|
||||||
|
LID_RESERVATION_NOTIFICATION = 0x80
|
||||||
|
LID_SANITIZE_STATUS = 0x81
|
||||||
|
|
||||||
|
; Controller Type Values
|
||||||
|
CNTRLTYPE_IO_CONTROLLER = 0x1
|
||||||
|
CNTRLTYPE_DISCOVERY_CONTROLLER = 0x2
|
||||||
|
CNTRLTYPE_ADMIN_CONTROLLER = 0x3
|
||||||
|
|
||||||
|
struct NVME_MMIO
|
||||||
|
CAP dq ? ; Controller Capabilities
|
||||||
|
VS dd ? ; Version
|
||||||
|
INTMS dd ? ; Interrupt Mask Set
|
||||||
|
INTMC dd ? ; Interrupt Mask Clear
|
||||||
|
CC dd ? ; Controller Configuration
|
||||||
|
rd 1 ; Reserved
|
||||||
|
CSTS dd ? ; Controller Status
|
||||||
|
NSSR dd ? ; NVM Subsystem Reset
|
||||||
|
AQA dd ? ; Admin Queue Attributes
|
||||||
|
ASQ dq ? ; Admin Submission Queue Base Address
|
||||||
|
ACQ dq ? ; Admin Completion Queue Base Address
|
||||||
|
CMBLOC dd ? ; Controller Memory Buffer Location
|
||||||
|
CMBSZ dd ? ; Controller Memory Buffer Size
|
||||||
|
BPINFO dd ? ; Boot Partition Information
|
||||||
|
BPRSEL dd ? ; Boot Partition Read Select
|
||||||
|
BPMBL dq ? ; Boot Partition Memory Buffer Location
|
||||||
|
CMBMSC dd ? ; Controller Memory Buffer Memory Space
|
||||||
|
CMBSTS dd ? ; Controller Memory Buffer Status
|
||||||
|
rb 3492 ; Reserved
|
||||||
|
PMRCAP dd ? ; Persistent Memory Capabilities
|
||||||
|
PMRCTL dd ? ; Persistent Memory Region Control
|
||||||
|
PMRSTS dd ? ; Persistent Memory Region Status
|
||||||
|
PMREBS dd ? ; Persistent Memory Region Elasticity Buffer Size
|
||||||
|
PMRSWTP dd ? ; Persistent Memory Region Sustained Write Throughput
|
||||||
|
PMRMSC dq ? ; Persistent Memory Region Controller Memory Space Control
|
||||||
|
rb 484 ; Reserved
|
||||||
|
SQ0TDBL dd ? ; Submission Queue 0 Tail Doorbell (Admin)
|
||||||
|
ends
|
||||||
|
|
||||||
|
|
||||||
|
; Submission Queue Entry (64 bytes)
|
||||||
|
struct SQ_ENTRY
|
||||||
|
cdw0 dd ?
|
||||||
|
nsid dd ?
|
||||||
|
cdw2 dd ?
|
||||||
|
cdw3 dd ?
|
||||||
|
mptr dq ?
|
||||||
|
prp1 dq ?
|
||||||
|
prp2 dq ?
|
||||||
|
cdw10 dd ?
|
||||||
|
cdw11 dd ?
|
||||||
|
cdw12 dd ?
|
||||||
|
cdw13 dd ?
|
||||||
|
cdw14 dd ?
|
||||||
|
cdw15 dd ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
; Completion Queue Entry (16 bytes) - See page 77 of the NVMe 1.4 spec
|
||||||
|
struct CQ_ENTRY
|
||||||
|
cdw0 dd ?
|
||||||
|
rd 1 ; reserved
|
||||||
|
sqhd dw ?
|
||||||
|
sqid dw ?
|
||||||
|
cid dw ?
|
||||||
|
status dw ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct NSINFO
|
||||||
|
capacity dq ?
|
||||||
|
size dq ?
|
||||||
|
nsid dd ?
|
||||||
|
pci dd ?
|
||||||
|
lbads db ?
|
||||||
|
features db ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct pcidev
|
||||||
|
bus db ?
|
||||||
|
devfn db ?
|
||||||
|
ipin db ?
|
||||||
|
iline db ?
|
||||||
|
num dd ?
|
||||||
|
io_addr dd ?
|
||||||
|
queue_entries dd ?
|
||||||
|
version dd ?
|
||||||
|
nsid dd ?
|
||||||
|
spinlock dd ?
|
||||||
|
nsinfo dd ?
|
||||||
|
nn dd ?
|
||||||
|
dstrd db ?
|
||||||
|
rb 3 ; align
|
||||||
|
ends
|
||||||
|
TOTAL_PCIDEVS = 4
|
||||||
|
TOTAL_PCIDEVS_MALLOC_SZ = TOTAL_PCIDEVS * sizeof.pcidev
|
||||||
|
|
||||||
|
struct NVMQCMD
|
||||||
|
cid dd ?
|
||||||
|
mutex_ptr MUTEX
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct NVM_QUEUE_ENTRY
|
||||||
|
tail dw ?
|
||||||
|
head dw ?
|
||||||
|
sq_ptr dd ?
|
||||||
|
cq_ptr dd ?
|
||||||
|
cmd_ptr dd ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
; Identify Controller Data Structure
|
||||||
|
struct IDENTC
|
||||||
|
|
||||||
|
vid dw ?
|
||||||
|
ssvid dw ?
|
||||||
|
sn dt ?, ?
|
||||||
|
mn dt ?, ?, ?, ?
|
||||||
|
fr dq ?
|
||||||
|
rab db ?
|
||||||
|
ieee db ?, ?, ?
|
||||||
|
cmic db ?
|
||||||
|
mdts db ?
|
||||||
|
cntlid dw ?
|
||||||
|
ver dd ?
|
||||||
|
rtd3r dd ?
|
||||||
|
rtd3e dd ?
|
||||||
|
oaes dd ?
|
||||||
|
ctratt dd ?
|
||||||
|
rrls dw ?
|
||||||
|
rb 9 ; reserved
|
||||||
|
cntrltype db ?
|
||||||
|
fguid dq ?, ?
|
||||||
|
crdt1 dw ?
|
||||||
|
crdt2 dw ?
|
||||||
|
crdt3 dw ?
|
||||||
|
rb 106 ; reserved
|
||||||
|
rb 16 ; reserved (NVMMI)
|
||||||
|
oacs dw ?
|
||||||
|
acl db ?
|
||||||
|
aerl db ?
|
||||||
|
frmw db ?
|
||||||
|
lpa db ?
|
||||||
|
elpe db ?
|
||||||
|
npss db ?
|
||||||
|
avscc db ?
|
||||||
|
apsta db ?
|
||||||
|
wctemp dw ?
|
||||||
|
cctemp dw ?
|
||||||
|
mtfa dw ?
|
||||||
|
hmpre dd ?
|
||||||
|
hmmin dd ?
|
||||||
|
tnvmcap dq ?, ?
|
||||||
|
unvmcap dq ?, ?
|
||||||
|
rpmbs dd ?
|
||||||
|
edstt dw ?
|
||||||
|
dsto db ?
|
||||||
|
fwug db ?
|
||||||
|
kas dw ?
|
||||||
|
hctma dw ?
|
||||||
|
mntmt dw ?
|
||||||
|
mxtmt dw ?
|
||||||
|
sanicap dd ?
|
||||||
|
hmminds dd ?
|
||||||
|
hmmaxd dw ?
|
||||||
|
nsetidmax dw ?
|
||||||
|
endgidmax dw ?
|
||||||
|
anatt db ?
|
||||||
|
anacap db ?
|
||||||
|
anagrpmax dd ?
|
||||||
|
nanagrpid dd ?
|
||||||
|
pels dd ?
|
||||||
|
rb 156
|
||||||
|
sqes db ?
|
||||||
|
cqes db ?
|
||||||
|
maxcmd dw ?
|
||||||
|
nn dd ?
|
||||||
|
oncs dw ?
|
||||||
|
fuses dw ?
|
||||||
|
fna db ?
|
||||||
|
vwc db ?
|
||||||
|
awun dw ?
|
||||||
|
awupf dw ?
|
||||||
|
nvscc db ?
|
||||||
|
nwpc db ?
|
||||||
|
acwu dw ?
|
||||||
|
rb 2
|
||||||
|
sgls dd ?
|
||||||
|
mnan dd ?
|
||||||
|
rb 224
|
||||||
|
subnqn dq ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||||
|
rb 768
|
||||||
|
rb 256
|
||||||
|
psd0 dq ?, ?, ?, ?
|
||||||
|
psd1 dq ?, ?, ?, ?
|
||||||
|
psd2 dq ?, ?, ?, ?
|
||||||
|
psd3 dq ?, ?, ?, ?
|
||||||
|
psd4 dq ?, ?, ?, ?
|
||||||
|
psd5 dq ?, ?, ?, ?
|
||||||
|
psd6 dq ?, ?, ?, ?
|
||||||
|
psd7 dq ?, ?, ?, ?
|
||||||
|
psd8 dq ?, ?, ?, ?
|
||||||
|
psd9 dq ?, ?, ?, ?
|
||||||
|
psd10 dq ?, ?, ?, ?
|
||||||
|
psd11 dq ?, ?, ?, ?
|
||||||
|
psd12 dq ?, ?, ?, ?
|
||||||
|
psd13 dq ?, ?, ?, ?
|
||||||
|
psd14 dq ?, ?, ?, ?
|
||||||
|
psd15 dq ?, ?, ?, ?
|
||||||
|
psd16 dq ?, ?, ?, ?
|
||||||
|
psd17 dq ?, ?, ?, ?
|
||||||
|
psd18 dq ?, ?, ?, ?
|
||||||
|
psd19 dq ?, ?, ?, ?
|
||||||
|
psd20 dq ?, ?, ?, ?
|
||||||
|
psd21 dq ?, ?, ?, ?
|
||||||
|
psd22 dq ?, ?, ?, ?
|
||||||
|
psd23 dq ?, ?, ?, ?
|
||||||
|
psd24 dq ?, ?, ?, ?
|
||||||
|
psd25 dq ?, ?, ?, ?
|
||||||
|
psd26 dq ?, ?, ?, ?
|
||||||
|
psd27 dq ?, ?, ?, ?
|
||||||
|
psd28 dq ?, ?, ?, ?
|
||||||
|
psd29 dq ?, ?, ?, ?
|
||||||
|
psd30 dq ?, ?, ?, ?
|
||||||
|
psd31 dq ?, ?, ?, ?
|
||||||
|
rb 1024
|
||||||
|
ends
|
||||||
|
|
||||||
|
; Identify Namespace Data Structure
|
||||||
|
struct IDENTN
|
||||||
|
nsze dq ?
|
||||||
|
ncap dq ?
|
||||||
|
nuse dq ?
|
||||||
|
nsfeat db ?
|
||||||
|
nlbaf db ?
|
||||||
|
flbas db ?
|
||||||
|
mc db ?
|
||||||
|
dpc db ?
|
||||||
|
dps db ?
|
||||||
|
nmic db ?
|
||||||
|
rescap db ?
|
||||||
|
fpi db ?
|
||||||
|
dlfeat db ?
|
||||||
|
nawun dw ?
|
||||||
|
nawupf dw ?
|
||||||
|
nacwu dw ?
|
||||||
|
nabsn dw ?
|
||||||
|
nabo dw ?
|
||||||
|
nabspf dw ?
|
||||||
|
noiob dw ?
|
||||||
|
nvmcap dq ?
|
||||||
|
dq ?
|
||||||
|
npwg dw ?
|
||||||
|
npwa dw ?
|
||||||
|
npdg dw ?
|
||||||
|
npda dw ?
|
||||||
|
nows dw ?
|
||||||
|
rb 18
|
||||||
|
anagrpid dd ?
|
||||||
|
rb 3
|
||||||
|
nsattr db ?
|
||||||
|
nvmsetid dw ?
|
||||||
|
endgid dw ?
|
||||||
|
nguid dq ?
|
||||||
|
dq ?
|
||||||
|
eui64 dq ?
|
||||||
|
lbaf0 dd ?
|
||||||
|
lbaf1 dd ?
|
||||||
|
lbaf2 dd ?
|
||||||
|
lbaf3 dd ?
|
||||||
|
lbaf4 dd ?
|
||||||
|
lbaf5 dd ?
|
||||||
|
lbaf6 dd ?
|
||||||
|
lbaf7 dd ?
|
||||||
|
lbaf8 dd ?
|
||||||
|
lbaf9 dd ?
|
||||||
|
lbaf10 dd ?
|
||||||
|
lbaf11 dd ?
|
||||||
|
lbaf12 dd ?
|
||||||
|
lbaf13 dd ?
|
||||||
|
lbaf14 dd ?
|
||||||
|
lbaf15 dd ?
|
||||||
|
rb 3904
|
||||||
|
ends
|
||||||
|
|
||||||
|
; Namespace Granularity List (CNS 16h - Page 199 of NVMe specification 1.4)
|
||||||
|
struct NSGRANLS
|
||||||
|
|
||||||
|
nga dd ?
|
||||||
|
nod db ?
|
||||||
|
rb 27 ; reserved
|
||||||
|
ngd0 dq ?, ?
|
||||||
|
ngd1 dq ?, ?
|
||||||
|
ngd2 dq ?, ?
|
||||||
|
ngd3 dq ?, ?
|
||||||
|
ngd4 dq ?, ?
|
||||||
|
ngd5 dq ?, ?
|
||||||
|
ngd6 dq ?, ?
|
||||||
|
ngd7 dq ?, ?
|
||||||
|
ngd8 dq ?, ?
|
||||||
|
ngd9 dq ?, ?
|
||||||
|
ngd10 dq ?, ?
|
||||||
|
ngd11 dq ?, ?
|
||||||
|
ngd12 dq ?, ?
|
||||||
|
ngd13 dq ?, ?
|
||||||
|
ngd14 dq ?, ?
|
||||||
|
ngd15 dq ?, ?
|
||||||
|
|
||||||
|
ends
|
||||||
|
|
||||||
|
assert NVM_ASQS = NVM_ACQS
|
||||||
|
assert SQ_ENTRIES = NVM_ASQS
|
||||||
|
assert CQ_ENTRIES = NVM_ACQS
|
||||||
|
assert NVM_MPS = 0
|
||||||
|
assert PAGE_SIZE = 0x1000
|
||||||
|
assert sizeof.NVME_MMIO = 4096
|
||||||
|
assert sizeof.SQ_ENTRY = 64
|
||||||
|
assert sizeof.CQ_ENTRY = 16
|
||||||
|
assert sizeof.IDENTC = 4096
|
||||||
|
assert sizeof.IDENTN = 4096
|
||||||
|
assert sizeof.NSGRANLS = 288
|
||||||
|
assert sizeof.NVMQCMD = 16
|
||||||
|
assert SIZEOF_SQ_ENTRY = 6
|
||||||
|
assert SIZEOF_CQ_ENTRY = 4
|
||||||
|
assert SIZEOF_SQ_ENTRY = CC_DEFAULT_IOSQES shr 16
|
||||||
|
assert SIZEOF_CQ_ENTRY = CC_DEFAULT_IOCQES shr 20
|
||||||
|
|
||||||
|
; NOTE: DO NOT CHANGE THIS ASSERTION!
|
||||||
|
; If you do decide to change it, you'll have
|
||||||
|
; to modify the source code manually since it
|
||||||
|
; uses bit shifts to multiply by the struct size
|
||||||
|
assert sizeof.NVM_QUEUE_ENTRY = 16
|
||||||
|
assert SIZEOF_NVM_QUEUE_ENTRY = 4
|
||||||
|
; vim: syntax=fasm
|
Loading…
Reference in New Issue
Block a user