mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2025-01-03 11:25:55 +01:00
feat: add read functionality (to be tested)
This commit is contained in:
parent
b6e6a69de7
commit
f689eb5b2c
@ -18,6 +18,8 @@ __DEBUG_LEVEL__ = 1
|
|||||||
DRIVER_VERSION = 1
|
DRIVER_VERSION = 1
|
||||||
DBG_INFO = 1
|
DBG_INFO = 1
|
||||||
NULLPTR = 0
|
NULLPTR = 0
|
||||||
|
FALSE = 0
|
||||||
|
TRUE = 1
|
||||||
|
|
||||||
; flags for alloc_dptr
|
; flags for alloc_dptr
|
||||||
PRP1_ENTRY_ALLOCATED = 1
|
PRP1_ENTRY_ALLOCATED = 1
|
||||||
@ -506,7 +508,7 @@ proc build_prp_list stdcall, nprps:dword
|
|||||||
cmp ecx, PAGE_SIZE / 8 - 1
|
cmp ecx, PAGE_SIZE / 8 - 1
|
||||||
jne @f
|
jne @f
|
||||||
push ecx
|
push ecx
|
||||||
stdcall build_prp_list, eax
|
stdcall build_prp_list, eax, TRUE
|
||||||
pop ecx
|
pop ecx
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .cleanup_prp_list
|
jz .cleanup_prp_list
|
||||||
@ -554,7 +556,8 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, start_sector:qword, numsector
|
|||||||
push esi edi
|
push esi edi
|
||||||
mov esi, [ns]
|
mov esi, [ns]
|
||||||
mov edi, [prps_ptr]
|
mov edi, [prps_ptr]
|
||||||
mov qword [esi], 0
|
mov dword [esi], 0
|
||||||
|
mov dword [esi + 4], 0
|
||||||
invoke KernelAlloc, PAGE_SIZE
|
invoke KernelAlloc, PAGE_SIZE
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
@ -587,7 +590,7 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, start_sector:qword, numsector
|
|||||||
jmp .success
|
jmp .success
|
||||||
|
|
||||||
.free_prp_list:
|
.free_prp_list:
|
||||||
stdcall free_prp_list, edi, eax
|
stdcall free_prp_list, edi, eax, FALSE
|
||||||
|
|
||||||
.err:
|
.err:
|
||||||
mov eax, dword [edi]
|
mov eax, dword [edi]
|
||||||
@ -608,49 +611,113 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, start_sector:qword, numsector
|
|||||||
|
|
||||||
endp
|
endp
|
||||||
|
|
||||||
proc nvme_read ns:dword, dst:dword, start_sector:qword, numsectors_ptr:dword
|
; note that prp_list is required to be a physical address
|
||||||
|
proc write_prp_list_buf stdcall, prp_list:dword, dst:dword, nprps:dword
|
||||||
|
|
||||||
push ebx esi edi
|
push esi edi
|
||||||
sub esp, 8
|
mov esi, [prp_list]
|
||||||
stdcall alloc_dptr, [ns], esp, [start_sector], [numsectors_ptr]
|
invoke KernelAlloc, 0x1000
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .end
|
jz .err
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
invoke GetPhysAddr
|
push edi
|
||||||
mov esi, [ns]
|
invoke MapPage, edi, esi, PG_SW+PG_NOCACHE
|
||||||
|
mov esi, edi
|
||||||
|
mov edi, [dst]
|
||||||
|
mov ecx, [nprps]
|
||||||
|
cmp ecx, PAGE_SIZE
|
||||||
|
jae @f
|
||||||
|
shl ecx, 12 + NVM_MPS
|
||||||
|
rep stosd
|
||||||
|
pop edi
|
||||||
|
invoke KernelFree, edi
|
||||||
|
pop edi esi
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; more than or equal to 4096 PRP entries
|
||||||
|
@@:
|
||||||
|
mov ecx, PAGE_SIZE * PAGE_SIZE - 12
|
||||||
|
rep stosd
|
||||||
|
sub ecx, PAGE_SIZE
|
||||||
|
stdcall write_prp_list_buf, [prp_list], edi, ecx
|
||||||
|
mov esi, eax
|
||||||
|
pop edi
|
||||||
|
invoke KernelFree, edi
|
||||||
|
mov eax, esi
|
||||||
|
|
||||||
|
.err:
|
||||||
|
pop edi esi
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
|
||||||
|
nvme_read:
|
||||||
|
mov edx, NVM_CMD_READ
|
||||||
|
jmp nvme_readwrite
|
||||||
|
|
||||||
|
nvme_write:
|
||||||
|
mov edx, NVM_CMD_WRITE
|
||||||
|
|
||||||
|
proc nvme_readwrite stdcall, ns:dword, dst:dword, start_sector:qword, numsectors_ptr:dword
|
||||||
|
push ebx esi edi
|
||||||
|
sub esp, 12
|
||||||
mov ebx, [numsectors_ptr]
|
mov ebx, [numsectors_ptr]
|
||||||
mov ebx, [ebx]
|
mov ebx, [ebx]
|
||||||
stdcall nvme_io_rw, [esi + NSINFO.pci], \ ; PCI device
|
mov dword [esp + 8], edx
|
||||||
1, \ ; QID (1 for now)
|
; Note that [esp] will contain the value of PRP1 and [esp + 4] will
|
||||||
[esi + NSINFO.nsid], \ ; NSID
|
; contain the value of PRP2 (after this call, if it completes successfully)
|
||||||
eax, \ ; DPTR
|
stdcall alloc_dptr, [ns], esp, dword [start_sector], dword [start_sector + 4], ebx
|
||||||
dword [start_sector], \ ; SLBA_LO
|
test eax, eax
|
||||||
dword [start_sector + 4], \ ; SLBA_HI
|
jz .end
|
||||||
ebx, \ ; NLB
|
invoke GetPhysAddr
|
||||||
NVM_CMD_READ ; Command opcode
|
mov esi, [ns]
|
||||||
|
stdcall nvme_io_rw, [esi + NSINFO.pci], \
|
||||||
|
1, \
|
||||||
|
[esi + NSINFO.nsid], \
|
||||||
|
dword [esp], \
|
||||||
|
dword [esp + 4], \
|
||||||
|
dword [start_sector], \
|
||||||
|
dword [start_sector + 4], \
|
||||||
|
ebx, \
|
||||||
|
dword [esp + 8]
|
||||||
|
|
||||||
; assume command completes successfully for now
|
; assume command completes successfully for now
|
||||||
mov ecx, dword [esi + NSINFO.pg_sectors]
|
|
||||||
cmp ebx, ecx
|
|
||||||
ja .is_prp_list
|
|
||||||
|
|
||||||
; only 1-2 pages are used, which makes our life easier
|
; only 1-2 pages are used, which makes our life easier
|
||||||
mov ecx, dword [esi + NSINFO.lbads]
|
mov ecx, dword [esi + NSINFO.lbads]
|
||||||
imul ecx, ebx
|
imul ecx, ebx
|
||||||
mov esi, edi
|
|
||||||
mov edi, [dst]
|
mov edi, [dst]
|
||||||
|
mov esi, dword [esp]
|
||||||
rep movsd
|
rep movsd
|
||||||
add esp, 8
|
invoke KernelFree, dword [esp]
|
||||||
pop edi esi ebx
|
mov esi, dword [esp + 4]
|
||||||
xor eax, eax ; TODO: add proper return value later
|
mov ecx, dword [esi + NSINFO.pg_sectors]
|
||||||
ret
|
cmp ebx, ecx
|
||||||
|
ja .is_prp_list
|
||||||
|
xor eax, eax
|
||||||
|
test esi, esi
|
||||||
|
jz .end
|
||||||
|
rep movsd
|
||||||
|
invoke KernelFree, dword [esp + 4]
|
||||||
|
xor eax, eax
|
||||||
|
jmp .end
|
||||||
|
|
||||||
.is_prp_list:
|
.is_prp_list:
|
||||||
|
xor edx, edx
|
||||||
|
mov eax, ebx
|
||||||
|
mov ecx, dword [esi + NSINFO.lbads]
|
||||||
|
div ecx
|
||||||
|
mov ebx, eax
|
||||||
|
stdcall write_prp_list_buf, dword [esp + 4], [dst], ebx
|
||||||
|
test eax, eax
|
||||||
|
stdcall free_prp_list, dword [esp + 4], ebx, FALSE
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
add esp, 8
|
add esp, 12
|
||||||
pop edi esi ebx
|
pop edi esi ebx
|
||||||
xor eax, eax
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
endp
|
endp
|
||||||
@ -661,7 +728,7 @@ proc nvme_io_rw stdcall, pci:dword, qid:word, nsid:dword, prps:qword, slba_lo:dw
|
|||||||
; TODO: Use IDENTC.NOIOB to construct read/write commands that don't
|
; TODO: Use IDENTC.NOIOB to construct read/write commands that don't
|
||||||
; cross the I/O boundary to achieve optimal performance
|
; cross the I/O boundary to achieve optimal performance
|
||||||
;
|
;
|
||||||
; Read AWUN/NAWUN
|
; TODO: Read AWUN/NAWUN
|
||||||
sub esp, sizeof.SQ_ENTRY
|
sub esp, sizeof.SQ_ENTRY
|
||||||
stdcall memset, esp, 0, sizeof.SQ_ENTRY
|
stdcall memset, esp, 0, sizeof.SQ_ENTRY
|
||||||
movzx ecx, [qid]
|
movzx ecx, [qid]
|
||||||
|
Loading…
Reference in New Issue
Block a user