2
0
mirror of https://git.missingno.dev/kolibrios-nvme-driver/ synced 2024-12-22 13:58:47 +01:00
kolibrios-nvme-driver/drivers/nvme/nvme.asm

200 lines
4.6 KiB
NASM
Raw Normal View History

2024-03-28 23:43:18 +01:00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
2024-03-31 21:43:38 +02:00
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
2024-03-28 23:43:18 +01:00
;; 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
2024-03-30 04:42:01 +01:00
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
DRIVER_VERSION = 1
DBG_INFO = 1
2024-03-28 23:43:18 +01:00
section ".flat" code readable writable executable
include "../proc32.inc"
include "../struct.inc"
include "../macros.inc"
2024-03-30 04:42:01 +01:00
include "../fdo.inc"
2024-03-28 23:43:18 +01:00
include "../pci.inc"
2024-03-30 04:42:01 +01:00
include "../peimport.inc"
2024-03-31 21:43:38 +02:00
include "nvme.inc"
2024-03-28 23:43:18 +01:00
proc START c, reason:dword
cmp [reason], DRV_ENTRY
jne .exit
.entry:
push esi
2024-03-30 04:42:01 +01:00
DEBUGF DBG_INFO,"Detecting NVMe hardware...\n"
2024-03-28 23:43:18 +01:00
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
2024-03-31 21:43:38 +02:00
proc memset stdcall, p_data:dword, val:byte, sz:dword
2024-03-31 22:13:17 +02:00
mov bh, byte [val]
xor eax, eax
2024-03-31 21:43:38 +02:00
@@:
2024-03-31 22:13:17 +02:00
mov byte [p_data + eax], bh
inc eax
cmp eax, dword [sz]
2024-03-31 21:43:38 +02:00
jne @b
ret
endp
; Submit a Command in the Admin Submission Queue
proc submit_asq stdcall, p_sq:dword
2024-03-31 22:13:17 +02:00
mov ebx, dword [bar0]
add ebx, NVME_REG_ASQ
2024-03-31 21:43:38 +02:00
2024-03-31 22:13:17 +02:00
xor eax, eax
ret
2024-03-31 21:43:38 +02:00
endp
proc nvme_identify stdcall, nsid:dword, dptr:dword, cns:byte
2024-03-31 22:13:17 +02:00
sub esp, sizeof.SQ_ENTRY
stdcall memset, esp, 0, sizeof.SQ_ENTRY
2024-03-30 04:42:01 +01:00
mov eax, dword [nsid]
2024-03-31 22:13:17 +02:00
mov [esp + SQ_ENTRY.nsid], eax
2024-03-31 21:43:38 +02:00
mov eax, dword [dptr]
2024-03-31 22:13:17 +02:00
mov dword [esp + SQ_ENTRY.dptr], eax
2024-03-30 04:42:01 +01:00
; TODO: setting CID to 1 for now but later on keep a list of unique list of identifiers
2024-03-31 22:13:17 +02:00
mov dword [esp + SQ_ENTRY.cdw0], ADM_CMD_IDENTIFY or (1 shl 16)
2024-03-31 21:43:38 +02:00
mov ah, byte [cns]
2024-03-31 22:13:17 +02:00
mov byte [esp + SQ_ENTRY.cdw10], ah
stdcall submit_asq, esp
add esp, sizeof.SQ_ENTRY
xor eax, eax
ret
2024-03-30 04:42:01 +01:00
endp
2024-03-28 23:43:18 +01:00
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
2024-03-30 04:42:01 +01:00
je .check_cap
2024-03-28 23:43:18 +01:00
.next_dev:
mov eax, [eax + PCIDEV.fd]
cmp eax, edx
jne .check_dev
; no more PCI devices to enumerate?
2024-03-30 04:42:01 +01:00
xor eax, eax
pop ebx
2024-03-28 23:43:18 +01:00
ret
.check_cap:
push eax
movzx ebx, [eax + PCIDEV.bus]
2024-03-30 04:42:01 +01:00
mov [pcidev_bus], ebx
2024-03-28 23:43:18 +01:00
movzx ebx, [eax + PCIDEV.devfn]
2024-03-30 04:42:01 +01:00
mov [pcidev_devfn], ebx
invoke PciRead16, [pcidev_bus], [pcidev_devfn], PCI_header00.status
2024-03-28 23:43:18 +01:00
test ax, 0x10 ; check capabilities list bit
jnz .got_cap
pop eax
.got_cap:
2024-03-30 04:42:01 +01:00
DEBUGF DBG_INFO,"Found NVMe device with capabilities\n"
invoke PciRead8, [pcidev_bus], [pcidev_devfn], PCI_header00.cap_ptr
2024-03-28 23:43:18 +01:00
and eax, 11111100b
mov edi, eax
@@:
2024-03-30 04:42:01 +01:00
invoke PciRead32, [pcidev_bus], [pcidev_devfn], edi
2024-03-28 23:43:18 +01:00
mov ecx, eax
2024-03-30 04:42:01 +01:00
;and ecx, 0xff
2024-03-28 23:43:18 +01:00
mov eax, ecx
movzx edi, ah
test edi, edi
jnz @b
2024-03-30 04:42:01 +01:00
; read BAR0
invoke PciRead32, [pcidev_bus], [pcidev_devfn], PCI_header00.base_addr_0
mov [bar0], eax
2024-03-31 22:13:17 +02:00
invoke Kmalloc, sizeof.NVME_IDENT_CONTROLLER
2024-03-31 21:43:38 +02:00
test eax, eax
2024-03-31 22:13:17 +02:00
jz .alloc_ident_controller_fail
DEBUGF DBG_INFO,"Successfully allocated %u bytes for 'NVME_IDENT_CONTROLLER'\n",sizeof.NVME_IDENT_CONTROLLER
2024-03-31 21:43:38 +02:00
mov [p_ident], eax
stdcall nvme_identify, 0, dword [p_ident], CNS_IDCS
mov ecx, dword [p_ident]
2024-03-31 22:13:17 +02:00
mov edx, dword [ecx + NVME_IDENT_CONTROLLER.tnvmcap]
DEBUGF DBG_INFO,"Total NVMe SSD capacity: %ub\n", edx
2024-03-30 04:42:01 +01:00
2024-03-28 23:43:18 +01:00
; return successfully
2024-03-31 21:43:38 +02:00
call nvme_cleanup
pop eax
pop ebx
2024-03-28 23:43:18 +01:00
xor eax, eax
inc eax
ret
2024-03-31 21:43:38 +02:00
2024-03-31 22:13:17 +02:00
.alloc_ident_controller_fail:
DEBUGF DBG_INFO,"ERROR: failed to allocate %u bytes for 'NVME_IDENT_CONTROLLER'\n", sizeof.NVME_IDENT_CONTROLLER
2024-03-31 21:43:38 +02:00
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
2024-03-28 23:43:18 +01:00
endp
; uninitialized data
2024-03-31 21:43:38 +02:00
align 4
2024-03-30 04:42:01 +01:00
pcidev_bus dd ?
pcidev_devfn dd ?
bar0 dd ?
2024-03-31 21:43:38 +02:00
p_ident dd ?
2024-03-28 23:43:18 +01:00
;all initialized data place here
align 4
2024-03-30 04:42:01 +01:00
my_service db "NVMe Service",0 ;max 16 chars include zero
include_debug_strings
2024-03-28 23:43:18 +01:00
align 4
data fixups
end data