mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2024-12-22 13:58:47 +01:00
refactor: move NVMe commands to a separate file
This commit is contained in:
parent
534103061c
commit
e8a5910681
259
drivers/nvme/command.inc
Normal file
259
drivers/nvme/command.inc
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; ;;
|
||||||
|
;; 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, sizeof.CQ_ENTRY 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, [pci], 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, sizeof.SQ_ENTRY 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, [pci], 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, [pci], 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
|
||||||
|
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, [pci], 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, [pci], ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
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
|
||||||
|
|
||||||
|
sub esp, sizeof.SQ_ENTRY
|
||||||
|
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
||||||
|
stdcall set_cdw0, [pci], 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, [pci], ADMIN_QUEUE, esp
|
||||||
|
add esp, sizeof.SQ_ENTRY
|
||||||
|
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
|
@ -30,7 +30,8 @@ include "../pci.inc"
|
|||||||
include "../peimport.inc"
|
include "../peimport.inc"
|
||||||
include "nvme.inc"
|
include "nvme.inc"
|
||||||
include "macros.inc"
|
include "macros.inc"
|
||||||
include "lib.asm"
|
include "lib.inc"
|
||||||
|
include "command.inc"
|
||||||
|
|
||||||
struct DISKMEDIAINFO
|
struct DISKMEDIAINFO
|
||||||
flags dd ?
|
flags dd ?
|
||||||
@ -168,59 +169,6 @@ proc nvme_query_media stdcall, userdata:dword, info:dword
|
|||||||
|
|
||||||
endp
|
endp
|
||||||
|
|
||||||
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 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
|
|
||||||
|
|
||||||
; returns 1 if the given NSID is a an active NSID, returns
|
; returns 1 if the given NSID is a an active NSID, returns
|
||||||
; 0 otherwise
|
; 0 otherwise
|
||||||
proc is_active_namespace stdcall, pci:dword, nsid:dword
|
proc is_active_namespace stdcall, pci:dword, nsid:dword
|
||||||
@ -298,170 +246,6 @@ proc determine_active_nsids stdcall, pci:dword
|
|||||||
|
|
||||||
endp
|
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, sizeof.CQ_ENTRY 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, [pci], 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, sizeof.SQ_ENTRY 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, [pci], 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, [pci], 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
|
|
||||||
|
|
||||||
sub esp, sizeof.SQ_ENTRY
|
|
||||||
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
|
||||||
stdcall set_cdw0, [pci], 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, [pci], ADMIN_QUEUE, esp
|
|
||||||
add esp, sizeof.SQ_ENTRY
|
|
||||||
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
|
|
||||||
|
|
||||||
sub esp, sizeof.SQ_ENTRY
|
|
||||||
stdcall memsetdz, esp, sizeof.SQ_ENTRY / 4
|
|
||||||
stdcall set_cdw0, [pci], 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, [pci], ADMIN_QUEUE, esp
|
|
||||||
add esp, sizeof.SQ_ENTRY
|
|
||||||
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
|
|
||||||
|
|
||||||
proc build_prp_list stdcall, nprps:dword, buf:dword, prp_list_ptr:dword
|
proc build_prp_list stdcall, nprps:dword, buf:dword, prp_list_ptr:dword
|
||||||
|
|
||||||
push esi ebx edi
|
push esi ebx edi
|
||||||
@ -700,37 +484,6 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors
|
|||||||
|
|
||||||
endp
|
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
|
|
||||||
|
|
||||||
proc detect_nvme
|
proc detect_nvme
|
||||||
|
|
||||||
invoke GetPCIList
|
invoke GetPCIList
|
||||||
|
Loading…
Reference in New Issue
Block a user