summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-07-09 18:09:09 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-07-09 18:09:09 +0200
commit891245c6c9a78cea6074e336d1b04a2264b2fcce (patch)
tree05e82ca5bd807c7646337a8c3f6adcbf630d5f17
parent560a6c233286ec736a7a7c570efc68161c9953be (diff)
MHR-36: IMP: NVME core driver, check ticket.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
-rw-r--r--Boot/amd64-efi.make7
-rw-r--r--Kernel/Modules/NVME/NVME.hxx107
-rw-r--r--Kernel/Sources/Storage/NVMEDeviceInterface.cxx13
-rw-r--r--Kernel/StorageKit/NVME.hpp15
4 files changed, 129 insertions, 13 deletions
diff --git a/Boot/amd64-efi.make b/Boot/amd64-efi.make
index 16cb936e..97c553f7 100644
--- a/Boot/amd64-efi.make
+++ b/Boot/amd64-efi.make
@@ -25,14 +25,17 @@ NEWOS_MODEL=-DkMachineModel="\"Generic Zeta HD\""
endif
BIOS=OVMF.fd
-IMG=epm.img
+IMG=epm-master-1.img
IMG_2=epm-slave.img
+IMG_3=epm-master-2.img
EMU_FLAGS=-net none -m 4G -M q35 -d int \
-bios $(BIOS) -device piix3-ide,id=ide \
-drive id=disk,file=$(IMG),format=raw,if=none \
-device ide-hd,drive=disk,bus=ide.0 -drive \
- file=fat:rw:Sources/Root/,index=2,format=raw -d int -hdd $(IMG_2)
+ file=fat:rw:Sources/Root/,index=2,format=raw -d int -hdd $(IMG_2) \
+ -drive file=$(IMG_3),if=none,id=nvm
+ -device nvme,serial=Zeta,drive=nvm
LD_FLAGS=-e Main --subsystem=10
diff --git a/Kernel/Modules/NVME/NVME.hxx b/Kernel/Modules/NVME/NVME.hxx
new file mode 100644
index 00000000..8b47e5bc
--- /dev/null
+++ b/Kernel/Modules/NVME/NVME.hxx
@@ -0,0 +1,107 @@
+/* -------------------------------------------
+
+ Copyright Zeta Electronics Corporation
+
+------------------------------------------- */
+
+#ifndef __MODULE_NVME_HXX__
+#define __MODULE_NVME_HXX__
+
+#include <NewKit/Defines.hpp>
+
+/// TODO: checklist in: https://wiki.osdev.org/NVMe
+
+#define mNVMEAlign ATTRIBUTE(aligned(sizeof(Kernel::NVMEInt32)))
+
+namespace Kernel
+{
+ typedef UInt32 NVMEInt32;
+
+ struct NVMEBar0 final
+ {
+ NVMEInt32 fCap;
+ NVMEInt32 fVer;
+ NVMEInt32 fIntMaskSet;
+ NVMEInt32 fIntMaskClr;
+ NVMEInt32 fContrlConf;
+ NVMEInt32 fContrlStat;
+ NVMEInt32 fAdminQueueAttr;
+ NVMEInt32 fAdminSubmissionQueue;
+ NVMEInt32 fAdminCompletionQueue;
+ };
+
+ struct NVMEQueue final
+ {
+ NVMEInt32 fOpcode;
+ NVMEInt32 fNSID;
+ NVMEInt32 fReserved[3];
+ NVMEInt32 fMetadataPtr[5];
+ NVMEInt32 fDataPtr[9];
+ NVMEInt32 CommandSpecific[15];
+ };
+
+ enum
+ {
+ eCreateCompletionQueueNVME = 0x05,
+ eCreateSubmissionQueueNVME = 0x01,
+ eIdentifyNVME = 0x06,
+ eReadNVME = 0x02,
+ eWriteNVME = 0x01,
+ };
+
+ template <Int32 Opcode>
+ inline Bool nvme_create_admin_command(NVMEQueue* 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;
+ }
+
+ template <Int32 Opcode>
+ inline Bool nvme_create_admin_command(NVMEQueue* 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;
+ }
+ }
+
+ // use (1 << 0) as contigunous is better supported.
+
+ return true;
+ }
+} // namespace Kernel
+
+#endif // ifndef __MODULE_NVME_HXX__
diff --git a/Kernel/Sources/Storage/NVMEDeviceInterface.cxx b/Kernel/Sources/Storage/NVMEDeviceInterface.cxx
index 9b2da7c2..82b21dbe 100644
--- a/Kernel/Sources/Storage/NVMEDeviceInterface.cxx
+++ b/Kernel/Sources/Storage/NVMEDeviceInterface.cxx
@@ -8,6 +8,19 @@
namespace Kernel
{
+ NVMEDeviceInterface::NVMEDeviceInterface(void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void))
+ : DeviceInterface(Out, In), fCleanup(Cleanup)
+ {
+ }
+
+ NVMEDeviceInterface::~NVMEDeviceInterface()
+ {
+ if (fCleanup)
+ fCleanup();
+ }
+
const char* NVMEDeviceInterface::Name() const
{
return ("NVMEDeviceInterface");
diff --git a/Kernel/StorageKit/NVME.hpp b/Kernel/StorageKit/NVME.hpp
index c7ff0e66..48761334 100644
--- a/Kernel/StorageKit/NVME.hpp
+++ b/Kernel/StorageKit/NVME.hpp
@@ -12,21 +12,14 @@
namespace Kernel
{
- class NVMEDeviceInterface : public DeviceInterface<MountpointInterface*>
+ class NVMEDeviceInterface final : public DeviceInterface<MountpointInterface*>
{
public:
explicit NVMEDeviceInterface(void (*Out)(MountpointInterface* outpacket),
void (*In)(MountpointInterface* inpacket),
- void (*Cleanup)(void))
- : DeviceInterface(Out, In), fCleanup(Cleanup)
- {
- }
-
- virtual ~NVMEDeviceInterface()
- {
- if (fCleanup)
- fCleanup();
- }
+ void (*Cleanup)(void));
+
+ ~NVMEDeviceInterface() override;
public:
NVMEDeviceInterface& operator=(const NVMEDeviceInterface&) = default;