mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2025-02-07 12:46:51 +01:00
more fixes to nvme_io_rw and alloc_dptr
This commit is contained in:
parent
66d24f8e49
commit
c9143ca99d
@ -551,26 +551,32 @@ proc build_prp_list stdcall, nprps:dword
|
|||||||
|
|
||||||
endp
|
endp
|
||||||
|
|
||||||
proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, start_sector:qword, numsectors:dword
|
proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword
|
||||||
|
|
||||||
push esi edi
|
push esi edi
|
||||||
mov esi, [ns]
|
|
||||||
mov edi, [prps_ptr]
|
mov edi, [prps_ptr]
|
||||||
mov dword [esi], 0
|
mov dword [edi], 0
|
||||||
mov dword [esi + 4], 0
|
mov dword [edi + 4], 0
|
||||||
invoke KernelAlloc, PAGE_SIZE
|
invoke AllocPage
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
mov dword [edi], eax
|
mov dword [edi], eax
|
||||||
|
|
||||||
; is the number of sectors equal to two memory pages in size?
|
mov esi, [ns]
|
||||||
|
mov edx, [numsectors]
|
||||||
mov eax, dword [esi + NSINFO.pg_sectors]
|
mov eax, dword [esi + NSINFO.pg_sectors]
|
||||||
|
|
||||||
|
; is the number of sectors less than or equal to one memory page?
|
||||||
|
cmp eax, edx
|
||||||
|
jbe .success
|
||||||
|
|
||||||
|
; is the number of sectors equal to two memory pages in size? (todo: fix???)
|
||||||
shl eax, 1
|
shl eax, 1
|
||||||
cmp eax, [numsectors]
|
cmp eax, edx
|
||||||
jne @f
|
jne @f
|
||||||
|
|
||||||
; allocate a single PRP entry for PRP2
|
; allocate a single PRP entry for PRP2
|
||||||
invoke KernelAlloc, PAGE_SIZE
|
invoke AllocPage
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
mov dword [edi + 4], eax
|
mov dword [edi + 4], eax
|
||||||
@ -596,7 +602,7 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, start_sector:qword, numsector
|
|||||||
mov eax, dword [edi]
|
mov eax, dword [edi]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz @f
|
jz @f
|
||||||
invoke KernelFree, eax
|
invoke FreePage, eax
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
@ -720,65 +726,67 @@ proc nvme_readwrite stdcall, ns:dword, dst:dword, start_sector:qword, numsectors
|
|||||||
|
|
||||||
push ebx esi edi
|
push ebx esi edi
|
||||||
sub esp, 16
|
sub esp, 16
|
||||||
mov ebx, [numsectors_ptr]
|
mov ebx, esp
|
||||||
mov ebx, [ebx]
|
mov eax, [numsectors_ptr]
|
||||||
|
mov eax, dword [eax]
|
||||||
mov dword [esp + 8], edx ; command type (read or write)
|
mov dword [esp + 8], edx ; command type (read or write)
|
||||||
mov dword [esp + 12], ebx ; save original numsectors value
|
mov dword [esp + 12], eax ; save original numsectors value
|
||||||
|
mov esi, [ns]
|
||||||
|
mov edi, [dst]
|
||||||
|
|
||||||
|
mov edx, [numsectors_ptr]
|
||||||
|
mov edx, [edx]
|
||||||
; Note that [esp] will contain the value of PRP1 and [esp + 4] will
|
; Note that [esp] will contain the value of PRP1 and [esp + 4] will
|
||||||
; contain the value of PRP2 (after this call, if it completes successfully)
|
; contain the value of PRP2 (after this call, if it completes successfully)
|
||||||
stdcall alloc_dptr, [ns], esp, dword [start_sector], dword [start_sector + 4], ebx
|
stdcall alloc_dptr, esi, ebx, edx
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .end
|
jz .end
|
||||||
invoke GetPhysAddr
|
|
||||||
mov esi, [ns]
|
|
||||||
stdcall nvme_io_rw, [esi + NSINFO.pci], \
|
stdcall nvme_io_rw, [esi + NSINFO.pci], \
|
||||||
1, \
|
1, \
|
||||||
[esi + NSINFO.nsid], \
|
[esi + NSINFO.nsid], \
|
||||||
dword [esp], \
|
dword [ebx], \
|
||||||
dword [esp + 4], \
|
dword [ebx + 4], \
|
||||||
dword [start_sector], \
|
dword [start_sector], \
|
||||||
dword [start_sector + 4], \
|
dword [start_sector + 4], \
|
||||||
ebx, \
|
dword [ebx + 12], \
|
||||||
dword [esp + 8]
|
dword [ebx + 8]
|
||||||
|
|
||||||
; assume command completes successfully for now
|
; assume command completes successfully for now
|
||||||
|
|
||||||
; Write PRP1
|
; Write PRP1
|
||||||
stdcall write_prp_buf, [ns], dword [esp], [dst], [numsectors_ptr]
|
stdcall write_prp_buf, esi, dword [ebx], edi, [numsectors_ptr]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .end
|
jz .end
|
||||||
|
|
||||||
; check if PRP2 is needed at all
|
; check if PRP2 is needed at all
|
||||||
mov ecx, dword [esi + NSINFO.pg_sectors]
|
mov ecx, dword [esi + NSINFO.pg_sectors]
|
||||||
cmp ecx, ebx
|
mov edx, dword [ebx + 8]
|
||||||
|
cmp edx, ecx
|
||||||
jbe .end
|
jbe .end
|
||||||
|
|
||||||
; check if PRP2 should be a PRP list or a regular entry
|
; check if PRP2 should be a PRP list or a regular entry
|
||||||
shl ecx, 1
|
shl ecx, 1
|
||||||
cmp ecx, ebx
|
cmp ecx, edx
|
||||||
ja .is_prp_list
|
ja .is_prp_list
|
||||||
|
|
||||||
; PRP2 is a PRP entry
|
; PRP2 is a PRP entry
|
||||||
mov edi, [dst]
|
mov eax, dword [ebx + 12]
|
||||||
mov eax, dword [esp + 12]
|
imul eax, dword [esi + NSINFO.lbads]
|
||||||
mov edx, [ns]
|
mov edx, [numsectors_ptr]
|
||||||
imul eax, dword [edx + NSINFO.lbads]
|
sub eax, dword [edx]
|
||||||
mov ebx, [numsectors_ptr]
|
|
||||||
sub eax, dword [ebx]
|
|
||||||
add edi, eax
|
add edi, eax
|
||||||
stdcall write_prp_buf, [ns], dword [esp + 4], edi, [numsectors_ptr]
|
stdcall write_prp_buf, esi, dword [ebx + 4], edi, [numsectors_ptr]
|
||||||
jmp .end
|
jmp .end
|
||||||
|
|
||||||
.is_prp_list:
|
.is_prp_list:
|
||||||
mov esi, [ns]
|
; TODO: Fix this
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
mov ecx, dword [esi + NSINFO.lbads]
|
mov ecx, dword [esi + NSINFO.lbads]
|
||||||
div ecx
|
div ecx
|
||||||
mov ebx, eax
|
mov ebx, eax
|
||||||
stdcall write_prp_list_buf, dword [esp + 4], [dst], ebx
|
stdcall write_prp_list_buf, dword [ebx + 4], [dst], ebx
|
||||||
stdcall free_prp_list, dword [esp + 4], ebx, FALSE
|
stdcall free_prp_list, dword [ebx + 4], ebx, FALSE
|
||||||
|
|
||||||
.end:
|
.end:
|
||||||
add esp, 16
|
add esp, 16
|
||||||
@ -788,7 +796,7 @@ proc nvme_readwrite stdcall, ns:dword, dst:dword, start_sector:qword, numsectors
|
|||||||
endp
|
endp
|
||||||
|
|
||||||
; See page 258-261 (read) and 269-271 (write) of the NVMe 1.4 specification for reference
|
; 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_lo:dword, slba_hi:dword, nlb:word, opcode:dword
|
proc nvme_io_rw stdcall, pci:dword, qid:word, nsid:dword, prps:qword, slba:qword, nlb:word, opcode:dword
|
||||||
|
|
||||||
; 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
|
||||||
@ -805,9 +813,9 @@ proc nvme_io_rw stdcall, pci:dword, qid:word, nsid:dword, prps:qword, slba_lo:dw
|
|||||||
mov dword [esp + SQ_ENTRY.dptr + 8], eax
|
mov dword [esp + SQ_ENTRY.dptr + 8], eax
|
||||||
mov eax, [nsid]
|
mov eax, [nsid]
|
||||||
mov dword [esp + SQ_ENTRY.nsid], eax
|
mov dword [esp + SQ_ENTRY.nsid], eax
|
||||||
mov eax, [slba_lo]
|
mov eax, dword [slba] ; slba_lo
|
||||||
mov dword [esp + SQ_ENTRY.cdw10], eax
|
mov dword [esp + SQ_ENTRY.cdw10], eax
|
||||||
mov eax, [slba_hi]
|
mov eax, dword [slba + 4] ; slba_hi
|
||||||
mov dword [esp + SQ_ENTRY.cdw11], eax
|
mov dword [esp + SQ_ENTRY.cdw11], eax
|
||||||
movzx eax, [nlb]
|
movzx eax, [nlb]
|
||||||
mov word [esp + SQ_ENTRY.cdw12], ax
|
mov word [esp + SQ_ENTRY.cdw12], ax
|
||||||
@ -1171,12 +1179,12 @@ proc nvme_init stdcall, pci:dword
|
|||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit_fail
|
jz .exit_fail
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
invoke KernelAlloc, 0x4
|
invoke KernelAlloc, 0x8
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit_fail
|
jz .exit_fail
|
||||||
mov edx, NVM_CMD_READ
|
mov edx, NVM_CMD_READ
|
||||||
mov dword [eax], 0x1
|
mov dword [eax], 0x1
|
||||||
stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 1, eax
|
stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 1, 0, eax
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit_fail
|
jz .exit_fail
|
||||||
DEBUGF DBG_INFO, "nvme%u: Successfully initialized driver\n", [esi + pcidev.num]
|
DEBUGF DBG_INFO, "nvme%u: Successfully initialized driver\n", [esi + pcidev.num]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user