mirror of
https://git.missingno.dev/kolibrios-nvme-driver/
synced 2024-12-22 22:08:47 +01:00
fix: PRP list allocation
This commit is contained in:
parent
b88c5185a7
commit
1e315791fb
@ -454,29 +454,19 @@ proc get_log_page stdcall, pci:dword, prp1:dword, lid:byte
|
|||||||
|
|
||||||
endp
|
endp
|
||||||
|
|
||||||
proc build_prp_list stdcall, nprps:dword, buf_physical: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
|
||||||
sub esp, 16
|
sub esp, 4
|
||||||
|
|
||||||
|
; stack:
|
||||||
|
; [esp]: virtual pointer to first PRP list
|
||||||
; here, we store the pointer to the very first
|
; here, we store the pointer to the very first
|
||||||
; PRP list so that free_prp_list can free the
|
; PRP list so that free_prp_list can free the
|
||||||
; entire PRP list if something goes wrong, it
|
; entire PRP list if something goes wrong, it
|
||||||
; also serves as our return value placeholder
|
; also serves as our return value placeholder
|
||||||
mov dword [esp], 0
|
mov dword [esp], 0
|
||||||
|
|
||||||
; store the number of PRPs here, we need to
|
|
||||||
; cache the result here since we'll subtract
|
|
||||||
; nprps regularly. If we don't we will lose
|
|
||||||
; the value.
|
|
||||||
mov eax, [nprps]
|
|
||||||
mov dword [esp + 4], eax
|
|
||||||
|
|
||||||
; store consecutive PRP list buffer here, since
|
|
||||||
; we'll increment the PRP list pointer continuously
|
|
||||||
; its important to cache the value
|
|
||||||
mov dword [esp + 12], 0
|
|
||||||
|
|
||||||
xor edi, edi
|
xor edi, edi
|
||||||
xor esi, esi
|
xor esi, esi
|
||||||
mov ecx, [nprps]
|
mov ecx, [nprps]
|
||||||
@ -484,16 +474,20 @@ proc build_prp_list stdcall, nprps:dword, buf_physical:dword, prp_list_ptr:dword
|
|||||||
|
|
||||||
; we'll store consecutive PRP list buffers here, for example
|
; we'll store consecutive PRP list buffers here, for example
|
||||||
; given 2 PRP lists, we allocate 2 continuous pages
|
; given 2 PRP lists, we allocate 2 continuous pages
|
||||||
|
push ecx
|
||||||
invoke KernelAlloc, ecx ; store pointers to the PRP entries here
|
invoke KernelAlloc, ecx ; store pointers to the PRP entries here
|
||||||
|
pop ecx
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
mov dword [esp + 12], eax
|
mov dword [esp], eax
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
mov eax, [prp_list_ptr]
|
mov eax, [prp_list_ptr]
|
||||||
mov dword [eax], edi
|
mov dword [eax], edi
|
||||||
|
shr ecx, 1
|
||||||
|
stdcall memsetdz, edi, ecx
|
||||||
|
|
||||||
; note we assume buf_physical is page-aligned
|
; note we assume buf is page-aligned
|
||||||
mov esi, [buf_physical]
|
mov esi, [buf]
|
||||||
|
|
||||||
.build_prp_list:
|
.build_prp_list:
|
||||||
; ensure we don't cross a page boundary
|
; ensure we don't cross a page boundary
|
||||||
@ -505,40 +499,41 @@ proc build_prp_list stdcall, nprps:dword, buf_physical:dword, prp_list_ptr:dword
|
|||||||
|
|
||||||
@@:
|
@@:
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
cmp dword [esp], 0
|
cmp dword [esp], edi
|
||||||
jz @f
|
je .loop
|
||||||
|
|
||||||
; we need to store the pointer of the newly allocated
|
; we need to store the pointer of the next
|
||||||
; PRP list to the previous PRP list last slot
|
; PRP list to the previous PRP list last entry
|
||||||
mov eax, dword [esp + 8]
|
mov eax, edi
|
||||||
mov dword [eax + PAGE_SIZE - 8], esi
|
invoke GetPhysAddr
|
||||||
mov dword [eax + PAGE_SIZE - 4], 0
|
mov dword [edi - 8], eax
|
||||||
jmp .loop
|
mov dword [edi - 4], 0
|
||||||
|
|
||||||
@@:
|
|
||||||
mov dword [esp], esi
|
|
||||||
|
|
||||||
.loop:
|
.loop:
|
||||||
mov dword [edi + ecx * 4], esi
|
mov eax, esi
|
||||||
|
invoke GetPhysAddr
|
||||||
|
mov dword [edi + ecx * 4], eax
|
||||||
mov dword [edi + ecx * 4 + 4], 0
|
mov dword [edi + ecx * 4 + 4], 0
|
||||||
DEBUGF DBG_INFO, "PRP: %x\n", esi
|
DEBUGF DBG_INFO, "PRP: %x\n", eax
|
||||||
add esi, PAGE_SIZE
|
add esi, PAGE_SIZE
|
||||||
inc ecx
|
inc ecx
|
||||||
cmp ecx, ebx
|
cmp ecx, ebx
|
||||||
jne .loop
|
jne .loop
|
||||||
|
|
||||||
; check if we we need to build another PRP list
|
; check if we we need to build another PRP list
|
||||||
mov dword [esp + 8], edi
|
|
||||||
add edi, PAGE_SIZE
|
add edi, PAGE_SIZE
|
||||||
cmp ebx, PAGE_SIZE / 8
|
cmp ebx, PAGE_SIZE / 8
|
||||||
je .build_prp_list
|
je .build_prp_list
|
||||||
|
|
||||||
|
; PRP list successfully created
|
||||||
mov eax, dword [esp]
|
mov eax, dword [esp]
|
||||||
invoke GetPhysAddr
|
invoke GetPhysAddr
|
||||||
add esp, 16
|
add esp, 4
|
||||||
pop edi ebx esi
|
pop edi ebx esi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.err:
|
.err:
|
||||||
add esp, 16
|
add esp, 4
|
||||||
pop edi ebx esi
|
pop edi ebx esi
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
@ -607,12 +602,9 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, prp_list_pt
|
|||||||
inc eax
|
inc eax
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
mov edx, dword [buf]
|
mov eax, [buf]
|
||||||
and edx, not (PAGE_SIZE - 1)
|
and eax, not (PAGE_SIZE - 1)
|
||||||
add edx, PAGE_SIZE
|
add eax, PAGE_SIZE
|
||||||
xchg eax, edx
|
|
||||||
; push edx?
|
|
||||||
invoke GetPhysAddr
|
|
||||||
stdcall build_prp_list, edx, eax, [prp_list_ptr]
|
stdcall build_prp_list, edx, eax, [prp_list_ptr]
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .err
|
jz .err
|
||||||
@ -1092,11 +1084,12 @@ proc nvme_init stdcall, pci:dword
|
|||||||
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], 1
|
mov dword [eax], 17
|
||||||
add edi, 4094
|
;add edi, 4094
|
||||||
stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 0, 0, eax
|
stdcall nvme_readwrite, [esi + pcidev.nsinfo], edi, 0, 0, eax
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jz .exit_fail
|
jz .exit_fail
|
||||||
|
add edi, PAGE_SIZE
|
||||||
DEBUGF DBG_INFO, "STRING: %s\n", edi
|
DEBUGF DBG_INFO, "STRING: %s\n", edi
|
||||||
end if
|
end if
|
||||||
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…
Reference in New Issue
Block a user