summaryrefslogtreecommitdiffhomepage
path: root/dev/modules/NVME/NVME.h
blob: 29b2907bbbcc929aef0c6ea1c5ca27a7cda96dd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* -------------------------------------------

	Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.

	Revision History:

	??/??/24: Added file (amlel)
	23 Jul 24: Update filename to Defines.h and using NE_ALIGN_NVME for NVME structs. (amlel)

------------------------------------------- */

#ifndef __MODULE_NVME_H__
#define __MODULE_NVME_H__

#include <NewKit/Defines.h>

/// @file NVME.h
/// @brief NVME driver.

#define NE_ALIGN_NVME ATTRIBUTE(aligned(sizeof(Kernel::UInt32)))

namespace Kernel
{
	struct NE_ALIGN_NVME HAL_NVME_BAR_0 final
	{
		UInt32 fCapabilities;
		UInt32 fVersion;
		UInt32 fIntMaskSet;
		UInt32 fIntMaskClr;
		UInt32 fContrlConf;
		UInt32 fContrlStat;
		UInt32 fAdminQueueAttr;
		UInt32 fAdminSubmissionQueue;
		UInt32 fAdminCompletionQueue;
	};

	struct NE_ALIGN_NVME HAL_NVME_QUEUE final
	{
		UInt32 fOpcode;
		UInt32 fNSID;
		UInt32 fReserved[3];
		UInt32 fMetadataPtr[5];
		UInt32 fDataPtr[9];
		UInt32 CommandSpecific[15];
	};

	enum
	{
		kInvalidNVME,
		kCreateCompletionQueueNVME = 0x05,
		kCreateSubmissionQueueNVME = 0x01,
		kIdentifyNVME			   = 0x06,
		kReadNVME				   = 0x02,
		kWriteNVME				   = 0x01,
		kCountNVME				   = 5,
	};

	/// @brief Creates an admin command for a DMA operation.
	template <Int32 Opcode>
	inline Bool nvme_create_admin_command(HAL_NVME_QUEUE* entry, UInt32 nsid, UInt32 prpTransfer[3], UInt32 startingLba[2], UInt32 lowTransferBlocks)
	{
		if (entry == nullptr)
			return false;

		entry->CommandSpecific[9]  = startingLba[0];
		entry->CommandSpecific[10] = startingLba[1];

		entry->CommandSpecific[11] = lowTransferBlocks;

		entry->CommandSpecific[5] = prpTransfer[0];
		entry->CommandSpecific[6] = prpTransfer[1];
		entry->CommandSpecific[7] = prpTransfer[2];

		entry->CommandSpecific[0] = nsid;

		return true;
	}

	/// @brief Creates an I/O command for a DMA operation.
	template <Int32 Opcode>
	inline Bool nvme_create_io_command(HAL_NVME_QUEUE* entry, UInt64 baseAddress, UInt32 identLoAndQueueSizeHi, UInt32 flagsLoAndQueueComplIdHi, UInt32 identify, Bool provideIdentify = false, Bool namespaceIdentify = false)
	{
		if (entry == nullptr)
			return false;

		if (baseAddress == 0)
			return false;

		entry->fOpcode = Opcode;

		entry->CommandSpecific[5] = (baseAddress & 0xFF);
		entry->CommandSpecific[6] = static_cast<UInt32>(baseAddress);

		if (!provideIdentify)
		{
			entry->CommandSpecific[9]  = identLoAndQueueSizeHi;
			entry->CommandSpecific[10] = flagsLoAndQueueComplIdHi;
		}
		else
		{
			entry->CommandSpecific[9] = identify;

			if (namespaceIdentify)
			{
				entry->CommandSpecific[0] = 1;
			}
		}

		return true;
	}
} // namespace Kernel

#endif // ifndef __MODULE_NVME_H__