diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-07-09 18:09:09 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-07-09 18:09:09 +0200 |
| commit | 891245c6c9a78cea6074e336d1b04a2264b2fcce (patch) | |
| tree | 05e82ca5bd807c7646337a8c3f6adcbf630d5f17 | |
| parent | 560a6c233286ec736a7a7c570efc68161c9953be (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.make | 7 | ||||
| -rw-r--r-- | Kernel/Modules/NVME/NVME.hxx | 107 | ||||
| -rw-r--r-- | Kernel/Sources/Storage/NVMEDeviceInterface.cxx | 13 | ||||
| -rw-r--r-- | Kernel/StorageKit/NVME.hpp | 15 |
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; |
