diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index e28729f..10a6970 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -11,8 +11,8 @@ format PE DLL native entry START -API_VERSION equ 0 ;debug -SRV_GETVERSION equ 0 +API_VERSION = 0 ;debug +SRV_GETVERSION = 0 __DEBUG__ = 1 __DEBUG_LEVEL__ = 1 DRIVER_VERSION = 1 @@ -58,7 +58,7 @@ proc START c, reason:dword jne .err .entry: - DEBUGF DBG_INFO, "Detecting NVMe hardware...\n" + DEBUGF DBG_INFO, "Detecting NVMe device...\n" call detect_nvme test eax, eax jz .err @@ -123,8 +123,7 @@ proc add_nvme_disk stdcall, pci:dword push "n" push dword [esi + pcidev.num] push "nvme" - mov eax, esp - invoke DiskAdd, disk_functions, eax, [esi + pcidev.nsinfo], 0 + invoke DiskAdd, disk_functions, esp, [esi + pcidev.nsinfo], 0 add esp, 20 test eax, eax jz @f @@ -145,18 +144,21 @@ endp proc nvme_query_media stdcall, userdata:dword, info:dword - push esi edi + push ebx esi edi mov esi, [userdata] + mov ebx, dword [esi + NSINFO.pci] mov edi, [info] mov dword [edi + DISKMEDIAINFO.flags], 0 mov eax, dword [esi + NSINFO.lbads] + DEBUGF DBG_INFO, "nvme%un%u (Query Media): Sector size = %u\n", [ebx + pcidev.num], [esi + NSINFO.nsid], eax mov dword [edi + DISKMEDIAINFO.sectorsize], eax mov eax, dword [esi + NSINFO.capacity] mov dword [edi + DISKMEDIAINFO.capacity], eax mov eax, dword [esi + NSINFO.capacity + 4] mov dword [edi + DISKMEDIAINFO.capacity + 4], eax + DEBUGF DBG_INFO, "nvme%un%u (Query Media): Capacity = %u + %u sectors\n", [ebx + pcidev.num], [esi + NSINFO.nsid], [esi + NSINFO.capacity], [esi + NSINFO.capacity + 4] xor eax, eax - pop edi esi + pop edi esi ebx ret endp @@ -692,14 +694,13 @@ proc nvme_readwrite stdcall, ns:dword, buf:dword, start_sector:qword, numsectors dword [ebx + 8] ; assume command completes successfully for now - mov ecx, dword [ebx + 12] - mov eax, [numsectors_ptr] - mov dword [eax], ecx + xor eax, eax jmp .end .dptr_fail: mov ebx, [numsectors_ptr] mov dword [ebx], 0 + or eax, -1 ; generic disk error .end: add esp, 20 @@ -758,7 +759,7 @@ proc detect_nvme .found_dev: push edx eax - PDEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", byte [eax + PCIDEV.bus], byte [eax + PCIDEV.devfn] + ;PDEBUGF DBG_INFO, "PCI(%u.%u.%u): Detected NVMe device...\n", byte [eax + PCIDEV.bus], byte [eax + PCIDEV.devfn] cmp dword [pcidevs_len], TOTAL_PCIDEVS jne @f pop eax edx @@ -773,7 +774,7 @@ proc detect_nvme test eax, eax jz .err_no_mem mov dword [p_nvme_devices], eax - DEBUGF DBG_INFO, "(NVMe) Allocated pcidev struct at 0x%x\n", [p_nvme_devices] + ;DEBUGF DBG_INFO, "(NVMe) Allocated pcidev struct at 0x%x\n", [p_nvme_devices] @@: mov ecx, dword [pcidevs_len] @@ -837,7 +838,7 @@ proc device_is_compat stdcall, pci:dword invoke MapIoMem, edx, ecx, PG_SW+PG_NOCACHE mov dword [esi + pcidev.io_addr], eax mov eax, dword [eax + NVME_MMIO.VS] - DEBUGF DBG_INFO, "nvme%u: Controller version: 0x%x\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Controller version: 0x%x\n", [esi + pcidev.num], eax mov dword [esi + pcidev.version], eax pop ecx edx esi xor eax, eax @@ -963,11 +964,11 @@ proc nvme_init stdcall, pci:dword ; Attach interrupt handler mov esi, [pci] movzx eax, byte [esi + pcidev.iline] - DEBUGF DBG_INFO, "nvme%u: Attaching interrupt handler to IRQ %u\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Attaching interrupt handler to IRQ %u\n", [esi + pcidev.num], eax invoke AttachIntHandler, eax, irq_handler, 0 test eax, eax jz .exit_fail - DEBUGF DBG_INFO, "nvme%u: Successfully attached interrupt handler\n", [esi + pcidev.num] + ;DEBUGF DBG_INFO, "nvme%u: Successfully attached interrupt handler\n", [esi + pcidev.num] ; Restart the controller stdcall nvme_controller_start, esi @@ -981,15 +982,15 @@ proc nvme_init stdcall, pci:dword stdcall nvme_identify, [pci], 0, eax, CNS_IDCS mov eax, dword [edi + IDENTC.nn] mov dword [esi + pcidev.nn], eax - DEBUGF DBG_INFO, "nvme%u: Namespace Count: %u\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Namespace Count: %u\n", [esi + pcidev.num], eax lea ebx, byte [edi + IDENTC.sn] lea eax, byte [esi + pcidev.serial] stdcall memcpy, eax, ebx, 20 - DEBUGF DBG_INFO, "nvme%u: Serial Number: %s\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Serial Number: %s\n", [esi + pcidev.num], eax add ebx, 20 lea eax, byte [esi + pcidev.model] stdcall memcpy, eax, ebx, 40 - DEBUGF DBG_INFO, "nvme%u: Model: %s\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Model: %s\n", [esi + pcidev.num], eax mov edx, dword [esi + pcidev.version] cmp edx, VS140 @@ -998,7 +999,7 @@ proc nvme_init stdcall, pci:dword mov al, byte [edi + IDENTC.cntrltype] cmp al, CNTRLTYPE_IO_CONTROLLER jne .exit_fail - DEBUGF DBG_INFO, "nvme%u: I/O controller detected...\n", [esi + pcidev.num] + ;DEBUGF DBG_INFO, "nvme%u: I/O controller detected...\n", [esi + pcidev.num] @@: ; TODO: check IDENTC.AVSCC @@ -1019,7 +1020,7 @@ proc nvme_init stdcall, pci:dword mov esi, dword [esi + NVM_QUEUE_ENTRY.cq_ptr] mov eax, dword [esi + sizeof.CQ_ENTRY + CQ_ENTRY.cdw0] if __DEBUG__ - DEBUGF DBG_INFO, "nvme%u: Set Features CDW0: 0x%x\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Set Features CDW0: 0x%x\n", [esi + pcidev.num], eax end if test ax, ax ; Number of I/O Submission Queues allocated jz .exit_fail @@ -1036,11 +1037,11 @@ proc nvme_init stdcall, pci:dword mov eax, dword [esi + NVM_QUEUE_ENTRY.cq_ptr] invoke GetPhysAddr stdcall create_io_completion_queue, [pci], eax, 1, IEN_ON - DEBUGF DBG_INFO, "nvme%u: Successfully created I/O completion queue 1\n", [edi + pcidev.num] + ;DEBUGF DBG_INFO, "nvme%u: Successfully created I/O completion queue 1\n", [edi + pcidev.num] mov eax, dword [esi + NVM_QUEUE_ENTRY.sq_ptr] invoke GetPhysAddr stdcall create_io_submission_queue, [pci], eax, 1, 1 - DEBUGF DBG_INFO, "nvme%u: Successfully created I/O submission queue 1\n", [edi + pcidev.num] + ;DEBUGF DBG_INFO, "nvme%u: Successfully created I/O submission queue 1\n", [edi + pcidev.num] if 1 stdcall determine_active_nsids, [pci] @@ -1048,7 +1049,7 @@ proc nvme_init stdcall, pci:dword jz .exit_fail ; No active NSIDS mov esi, [pci] mov dword [esi + pcidev.nsid], eax - DEBUGF DBG_INFO, "nvme%u: Found active NSID: %u\n", [esi + pcidev.num], eax + ;DEBUGF DBG_INFO, "nvme%u: Found active NSID: %u\n", [esi + pcidev.num], eax else mov esi, [pci] xor eax, eax @@ -1069,7 +1070,7 @@ proc nvme_init stdcall, pci:dword mov dword [esi + pcidev.nsinfo], eax mov al, byte [edi + IDENTN.nsfeat] mov byte [ebx + NSINFO.features], al - DEBUGF DBG_INFO, "nvme%un%u: Namespace Features: 0x%x\n", [esi + pcidev.num], [esi + pcidev.nsid], al + ;DEBUGF DBG_INFO, "nvme%un%u: Namespace Features: 0x%x\n", [esi + pcidev.num], [esi + pcidev.nsid], al mov dword [ebx + NSINFO.pci], esi mov eax, dword [edi + IDENTN.nsze] mov dword [ebx + NSINFO.size], eax @@ -1079,13 +1080,19 @@ proc nvme_init stdcall, pci:dword mov dword [ebx + NSINFO.capacity], eax mov eax, dword [edi + IDENTN.ncap + 4] mov dword [ebx + NSINFO.capacity + 4], eax - DEBUGF DBG_INFO, "nvme%un%u: Namespace Size: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.nsze], [edi + IDENTN.nsze + 4] - DEBUGF DBG_INFO, "nvme%un%u: Namespace Capacity: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.ncap], [edi + IDENTN.ncap + 4] + ;DEBUGF DBG_INFO, "nvme%un%u: Namespace Size: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.nsze], [edi + IDENTN.nsze + 4] + ;DEBUGF DBG_INFO, "nvme%un%u: Namespace Capacity: %u + %u logical blocks\n", [esi + pcidev.num], [esi + pcidev.nsid], [edi + IDENTN.ncap], [edi + IDENTN.ncap + 4] mov eax, dword [edi + IDENTN.lbaf0] shr eax, 16 ; Get LBADS and eax, 0xff stdcall pow2, eax - DEBUGF DBG_INFO, "nvme%un%u: Namespace LBA Data Size: %u\n", [esi + pcidev.num], [esi + pcidev.nsid], eax + ;DEBUGF DBG_INFO, "nvme%un%u: Namespace LBA Data Size: %u\n", [esi + pcidev.num], [esi + pcidev.nsid], eax + + ; KolibriOS only supports a LBADS of 512, so if it's a higher value then we + ; have to ignore this namespace + cmp eax, SUPPORTED_LBADS + jne .exit_fail + mov dword [ebx + NSINFO.lbads], eax mov ecx, PAGE_SIZE xchg eax, ecx diff --git a/drivers/nvme/nvme.inc b/drivers/nvme/nvme.inc index 74ae1bd..87e38ab 100644 --- a/drivers/nvme/nvme.inc +++ b/drivers/nvme/nvme.inc @@ -24,6 +24,7 @@ LAST_QUEUE_ID = 1 ; Index of the last queue SQ_ENTRIES = NVM_ASQS ; I/O and Admin Submission Queue Size CQ_ENTRIES = NVM_ACQS ; I/O and Admin Completion Queue Size PAGE_SIZE = 4096 shl NVM_MPS +SUPPORTED_LBADS = 512 ; KolibriOS only supports LBADS of 512, later on we may remove this restriction ADMIN_QUEUE = 0 ; Admin Queue ID