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

more refactoring

This commit is contained in:
ramenu 2024-04-01 19:47:14 -04:00
parent 43a3db6f1e
commit bc11bcfa37
2 changed files with 97 additions and 26 deletions

View File

@ -69,16 +69,13 @@ proc memset stdcall, p_data:dword, val:byte, sz:dword
@@:
mov byte [p_data + eax], bh
inc eax
cmp eax, dword [sz]
jne @b
test eax, dword [sz]
jnz @b
ret
endp
; Submit a Command in the Admin Submission Queue
proc submit_asq stdcall, p_sq:dword
mov ebx, dword [bar0]
add ebx, NVME_REG_ASQ
xor eax, eax
ret
endp
@ -90,8 +87,8 @@ proc nvme_identify stdcall, nsid:dword, dptr:dword, cns:byte
mov [esp + SQ_ENTRY.nsid], eax
mov eax, dword [dptr]
mov dword [esp + SQ_ENTRY.dptr], eax
; TODO: setting CID to 1 for now but later on keep a list of unique list of identifiers
mov dword [esp + SQ_ENTRY.cdw0], ADM_CMD_IDENTIFY or (1 shl 16)
; TODO: setting CID to 0 for now but later on keep a list of unique list of identifiers
mov dword [esp + SQ_ENTRY.cdw0], ADM_CMD_IDENTIFY
mov ah, byte [cns]
mov byte [esp + SQ_ENTRY.cdw10], ah
stdcall submit_asq, esp
@ -144,14 +141,44 @@ proc detect
; read BAR0
invoke PciRead32, [pcidev_bus], [pcidev_devfn], PCI_header00.base_addr_0
mov [bar0], eax
and eax, 0xfffffff0
test eax, eax
jz .no_mmio
invoke MapIoMem, eax, sizeof.NVME_REG_MAP, PG_SW+PG_NOCACHE
test eax, eax
jz .no_mmio
mov [p_mmap], eax
mov ebx, dword [eax + NVME_REG_MAP.CAP]
DEBUGF DBG_INFO,"(NVMe) Maximum queue entries supported: %u\n", bx
test ebx, CAP_CQR
jz .cqr_not_req
DEBUGF DBG_INFO,"(NVMe) Contiguous queues required\n"
.cqr_not_req:
mov ebx, dword [eax + NVME_REG_MAP.CAP + 4]
mov ecx, ebx
test ebx, CAP_CSS_NVM_CMDSET
jz .exit_fail
and ebx, CAP_MPSMIN
and ecx, CAP_MPSMAX
shr ebx, 16
shr ecx, 16
DEBUGF DBG_INFO,"(NVMe) Memory page size minimum: %u\n", ebx
DEBUGF DBG_INFO,"(NVMe) Memory page size maximum: %u\n", ecx
invoke Kmalloc, sizeof.NVME_IDENT_CONTROLLER
mov ebx, dword [eax + NVME_REG_MAP.CC]
mov ecx, ebx
and ebx, CC_IOSQES
and ecx, CC_IOCQES
shl ebx, 16
shl ecx, 16
DEBUGF DBG_INFO,"(NVMe) I/O Submission Queue Entry Size: %u\n", ebx
DEBUGF DBG_INFO,"(NVMe) I/O completion queue entry size: %u\n", ecx
; Initialize the controller
invoke KernelAlloc, sizeof.NVME_IDENT_CONTROLLER
test eax, eax
jz .alloc_ident_controller_fail
DEBUGF DBG_INFO,"Successfully allocated %u bytes for 'NVME_IDENT_CONTROLLER'\n",sizeof.NVME_IDENT_CONTROLLER
mov [p_ident], eax
stdcall nvme_identify, 0, dword [p_ident], CNS_IDCS
mov ecx, dword [p_ident]
mov edx, dword [ecx + NVME_IDENT_CONTROLLER.tnvmcap]
@ -167,6 +194,10 @@ proc detect
.alloc_ident_controller_fail:
DEBUGF DBG_INFO,"ERROR: failed to allocate %u bytes for 'NVME_IDENT_CONTROLLER'\n", sizeof.NVME_IDENT_CONTROLLER
jmp .exit_fail
.no_mmio:
DEBUGF DBG_INFO,"ERROR: NVMe Device has no MMIO\n"
.exit_fail:
pop eax
pop ebx
xor eax, eax
@ -186,7 +217,7 @@ endp
align 4
pcidev_bus dd ?
pcidev_devfn dd ?
bar0 dd ?
p_mmap dd ?
p_ident dd ?
;all initialized data place here

View File

@ -8,20 +8,6 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; NVMe Registers
NVME_REG_CAP = 0x0 ; Controller Capabilities
NVME_REG_VS = 0x8 ; Version
NVME_REG_INTMS = 0xC ; Interrupt Mask Set
NVME_REG_INTMC = 0xF ; Interrupt Mask Clear
NVME_REG_CC = 0x14 ; Controller Configuration
NVME_REG_CSTS = 0x1C ; Controller Status
NVME_REG_NSSR = 0x20 ; NVM Subsystem Reset
NVME_REG_AQA = 0x24 ; Admin Queue Attributes
NVME_REG_ASQ = 0x28 ; Admin Submission Queue Base Address
NVME_REG_ACQ = 0x30 ; Admin Completion Queue Base Address
NVME_REG_CMBLOC = 0x38 ; Controller Memory Buffer Location
; Opcodes for NVM commands
NVM_CMD_FLUSH = 0x00
NVM_CMD_WRITE = 0x01
@ -90,6 +76,58 @@ 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_OMCS = 1 shl 11
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_ENABLE = 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_DEFAULT_IOSQES = 6 shl 16
CC_DEFAULT_IOCQES = 4 shl 16
struct NVME_REG_MAP
CAP rq 1 ; Controller Capabilities
VS rd 1 ; Version
INTMS rd 1 ; Interrupt Mask Set
INTMC rd 1 ; Interrupt Mask Clear
CC rd 1 ; Controller Configuration
rd 1 ; Reserved
CSTS rd 1 ; Controller Status
NSSR rd 1 ; NVM Subsystem Reset
AQA rd 1 ; Admin Queue Attributes
ASQ rq 1 ; Admin Submission Queue Base Address
ACQ rq 1 ; Admin Completion Queue Base Address
CMBLOC rd 1 ; Controller Memory Buffer Location
ends
; Submission Queue Entry (64 bytes)
struct SQ_ENTRY
cdw0 rd 1
@ -106,6 +144,8 @@ struct SQ_ENTRY
cdw15 rd 1
ends
; Completion Queue Entry ()
struc nvme_dev {
.pci_bus dd ?
.pci_devfn dd ?