2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2024-12-23 06:18:47 +01:00
kolibrios-nvme-driver/drivers/nvme/nvme.asm
2024-03-31 15:43:38 -04:00

200 lines
4.5 KiB
NASM

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;driver sceletone
format PE DLL native
entry START
API_VERSION equ 0 ;debug
SRV_GETVERSION equ 0
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
DRIVER_VERSION = 1
DBG_INFO = 1
section ".flat" code readable writable executable
include "../proc32.inc"
include "../struct.inc"
include "../macros.inc"
include "../fdo.inc"
include "../pci.inc"
include "../peimport.inc"
include "nvme.inc"
proc START c, reason:dword
cmp [reason], DRV_ENTRY
jne .exit
.entry:
push esi
DEBUGF DBG_INFO,"Detecting NVMe hardware...\n"
call detect
pop esi
test eax, eax
jz .exit
invoke RegService, my_service, service_proc
ret
.exit:
xor eax, eax
ret
endp
proc service_proc stdcall, ioctl:dword
mov ebx, [ioctl]
mov eax, [ebx+IOCTL.io_code]
cmp eax, SRV_GETVERSION
jne @F
mov eax, [ebx+IOCTL.output]
cmp [ebx+IOCTL.out_size], 4
jne .fail
mov dword [eax], API_VERSION
xor eax, eax
ret
@@:
.fail:
or eax, -1
ret
endp
; todo complete
proc ns_management_supported stdcall
mov eax, [p_ident + id_controller.oacs]
test eax, OACS_NSMAN_SUPPORTED
ret
endp
proc memset stdcall, p_data:dword, val:byte, sz:dword
mov ah, byte [val]
xor ebx, ebx
@@:
mov byte [p_data + ebx], ah
inc ebx
cmp ebx, dword [sz]
jne @b
ret
endp
; Submit a Command in the Admin Submission Queue
proc submit_asq stdcall, p_sq:dword
mov eax, dword [p_sq]
endp
proc nvme_identify stdcall, nsid:dword, dptr:dword, cns:byte
sub esp, sizeof.sq_entry
stdcall memset, esp, 0, sizeof.cq_entry
mov eax, dword [nsid]
mov [esp + sq_entry.nsid], eax
mov eax, dword [dptr]
mov [esp + sq_entry.dptr], eax
; TODO: setting CID to 1 for now but later on keep a list of unique list of identifiers
mov dword [esp + sq_entry.cdw0], ADM_CMD_IDENTIFY or (1 shl 16)
mov ah, byte [cns]
mov byte [esp + sq_entry.cdw10], ah
add esp, sizeof.sq_entry
endp
proc detect
push ebx
invoke GetPCIList
mov edx, eax
.check_dev:
mov ecx, [eax+PCIDEV.class]
and ecx, 0x00ffff00 ; retrieve class/subclass code only
cmp ecx, 0x00010800 ; Mass Storage Controller - Non-Volatile Memory Controller
je .check_cap
.next_dev:
mov eax, [eax + PCIDEV.fd]
cmp eax, edx
jne .check_dev
; no more PCI devices to enumerate?
xor eax, eax
pop ebx
ret
.check_cap:
push eax
movzx ebx, [eax + PCIDEV.bus]
mov [pcidev_bus], ebx
movzx ebx, [eax + PCIDEV.devfn]
mov [pcidev_devfn], ebx
invoke PciRead16, [pcidev_bus], [pcidev_devfn], PCI_header00.status
test ax, 0x10 ; check capabilities list bit
jnz .got_cap
pop eax
.got_cap:
DEBUGF DBG_INFO,"Found NVMe device with capabilities\n"
invoke PciRead8, [pcidev_bus], [pcidev_devfn], PCI_header00.cap_ptr
and eax, 11111100b
mov edi, eax
@@:
invoke PciRead32, [pcidev_bus], [pcidev_devfn], edi
mov ecx, eax
;and ecx, 0xff
mov eax, ecx
movzx edi, ah
test edi, edi
jnz @b
; read BAR0
invoke PciRead32, [pcidev_bus], [pcidev_devfn], PCI_header00.base_addr_0
mov [bar0], eax
invoke Kmalloc, sizeof.id_controller
test eax, eax
jz .alloc_id_controller_fail
DEBUGF DBG_INFO,"Successfully allocated %u bytes for 'id_controller'\n",sizeof.id_controller
mov [p_ident], eax
stdcall nvme_identify, 0, dword [p_ident], CNS_IDCS
mov ecx, dword [p_ident]
DEBUGF DBG_INFO,"Total NVMe SSD capacity: %ub\n",dword [ecx + id_controller.tnvmcap]
; return successfully
call nvme_cleanup
pop eax
pop ebx
xor eax, eax
inc eax
ret
.alloc_id_controller_fail:
DEBUGF DBG_INFO,"ERROR: failed to allocate %u bytes for 'id_controller'\n", sizeof.id_controller
pop eax
pop ebx
xor eax, eax
ret
endp
proc nvme_cleanup
mov eax, [p_ident]
test eax, eax
jz @f
invoke Kfree, eax
@@:
ret
endp
; uninitialized data
align 4
pcidev_bus dd ?
pcidev_devfn dd ?
bar0 dd ?
p_ident dd ?
;all initialized data place here
align 4
my_service db "NVMe Service",0 ;max 16 chars include zero
include_debug_strings
align 4
data fixups
end data