From 8eb5990c320925fb6a2e38ad3634329419a0ff4b Mon Sep 17 00:00:00 2001 From: Abdur-Rahman Mansoor Date: Thu, 11 Jul 2024 17:02:30 -0400 Subject: [PATCH] remove a lot of code, refactor alloc_dptr to use buf directly --- drivers/nvme/nvme.asm | 169 ++++++------------------------------------ 1 file changed, 24 insertions(+), 145 deletions(-) diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index 1ea821e..fe3d715 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -579,34 +579,48 @@ proc build_prp_list stdcall, nprps:dword endp -proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, nprps_ptr:dword +proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, nprps_ptr:dword, buf:dword push esi edi mov edi, [prps_ptr] mov dword [edi], 0 mov dword [edi + 4], 0 - invoke AllocPage - test eax, eax - jz .err + mov eax, [buf] + invoke GetPhysAddr mov dword [edi], eax + mov eax, [numsectors] + mov [numsectors], 0 + cmp eax, dword [esi + NSINFO.pg_sectors] + jbe @f + sub eax, dword [esi + NSINFO.pg_sectors] + mov [numsectors], eax + +@@: mov esi, [ns] mov edx, [numsectors] mov eax, dword [esi + NSINFO.pg_sectors] + ; is the buffer offset portion equal to 0? + mov ecx, [buf] + and ecx, PAGE_SIZE - 1 + jnz @f + ; is the number of sectors less than or equal to one memory page? cmp edx, eax jbe .success + shl eax, 1 ; it is page aligned, so set eax to 2 memory pages - ; is the number of sectors greater than to two memory pages? - shl eax, 1 +@@: + ; is the number of sectors greater than to one or two memory pages? cmp edx, eax jae .build_prp_list - ; allocate a single PRP entry for PRP2 - invoke AllocPage - test eax, eax - jz .err + ; set PRP2 + mov eax, dword [edi] + mov ecx, eax + and ecx, PAGE_SIZE - 1 + add eax, ecx mov dword [edi + 4], eax jmp .success @@ -651,106 +665,6 @@ proc alloc_dptr stdcall, ns:dword, prps_ptr:dword, numsectors:dword, nprps_ptr:d endp -proc write_prp_buf stdcall, ns:dword, prp:dword, dst:dword, numsectors_ptr:dword - - push esi edi ebx - mov esi, [prp] - test esi, esi - jz .err - invoke KernelAlloc, PAGE_SIZE - test eax, eax - jz .err - push eax - mov edi, eax - mov esi, [prp] - invoke MapPage, edi, esi, PG_SW+PG_NOCACHE - mov esi, edi - mov edi, [dst] - ; determine if the number of sectors crosses a page boundary - mov eax, [ns] - mov ebx, [numsectors_ptr] - mov ecx, dword [eax + NSINFO.lbads] - mov eax, dword [eax + NSINFO.pg_sectors] - cmp dword [ebx], eax - jae @f - mov eax, dword [ebx] - imul ecx, eax - shr ecx, 2 - sub dword [ebx], eax - jmp .copy - -@@: - mov ecx, PAGE_SIZE / 4 - sub dword [ebx], eax - -.copy: - rep movsd - pop eax - invoke KernelFree, eax - invoke FreePage, [prp] - pop ebx edi esi - xor eax, eax - inc eax - ret - -.err: - mov esi, [prp] - test esi, esi - jz @f - invoke FreePage, esi - -@@: - pop ebx edi esi - xor eax, eax - ret - -endp - -; 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 esi edi - mov esi, [prp_list] - invoke KernelAlloc, 0x1000 - test eax, eax - jz .err - mov edi, eax - push edi - 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) - 2 - rep movsd - pop edi - invoke KernelFree, edi - pop edi esi - xor eax, eax - inc eax - ret - -; more than or equal to 4096 PRP entries -@@: - ; WIP: Work on this later - if 0 - mov ecx, PAGE_SIZE * PAGE_SIZE / 4 - 3 - rep movsd - stdcall write_prp_list_buf, [prp_list], edi, ecx - mov esi, eax - pop edi - invoke KernelFree, edi - mov eax, esi - end if - -.err: - pop edi esi - ret - -endp - - nvme_read: mov edx, NVM_CMD_READ jmp nvme_readwrite @@ -794,41 +708,6 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors ; assume command completes successfully for now - ; Write PRP1 - ; investigate: why does this change the value of esi?? - push esi ebx edi - stdcall write_prp_buf, esi, dword [ebx], edi, [numsectors_ptr] - pop edi ebx esi - test eax, eax - jz .end - - DEBUGF DBG_INFO, "Successfully wrote PRP1\n" - ; check if PRP2 is needed at all - mov ecx, dword [esi + NSINFO.pg_sectors] - mov edx, dword [ebx + 12] - cmp edx, ecx - jbe .end - - ; check if PRP2 should be a PRP list or a regular entry - shl ecx, 1 - cmp edx, ecx - ja .is_prp_list - - DEBUGF DBG_INFO, "PRP2 entry\n" - ; PRP2 is a PRP entry - mov eax, dword [ebx + 12] - imul eax, dword [esi + NSINFO.lbads] - mov edx, [numsectors_ptr] - sub eax, dword [edx] - add edi, eax - stdcall write_prp_buf, esi, dword [ebx + 4], edi, [numsectors_ptr] - jmp .end - -.is_prp_list: - stdcall write_prp_list_buf, dword [ebx + 4], [buf], [ebx + 16] - ;stdcall free_prp_list, dword [ebx + 4], ebx - jmp .end - .dptr_fail: mov ebx, [numsectors_ptr] mov dword [ebx], 0