diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
| commit | 83d870e58457a1d335a1d9b9966a6a1887cc297b (patch) | |
| tree | 72888f88c7728c82f3f6df1f4f70591de15eab36 /dev/kernel | |
| parent | ab37adbacf0f33845804c788b39680cd754752a8 (diff) | |
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel')
261 files changed, 0 insertions, 23879 deletions
diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h deleted file mode 100644 index 626f1e0b..00000000 --- a/dev/kernel/ArchKit/ArchKit.h +++ /dev/null @@ -1,108 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/Function.h> - -#include <FirmwareKit/Handover.h> - -#ifdef __NE_AMD64__ -#include <HALKit/AMD64/Hypervisor.h> -#include <HALKit/AMD64/Paging.h> -#include <HALKit/AMD64/Processor.h> -#elif defined(__NE_POWER64__) -#include <HALKit/POWER/Processor.h> -#elif defined(__NE_ARM64__) -#include <HALKit/ARM64/Processor.h> -#elif defined(__NE_SDK__) -#include <HALKit/ARM64/Processor.h> -#else -#error !!! unknown architecture !!! -#endif - -#define kMaxDispatchCallCount (512U) - -namespace Kernel { -inline SizeT rt_hash_seed(const Char* seed, UInt32 mul) { - SizeT hash = 0; - - for (SSizeT idx = 0; seed[idx] != 0; ++idx) { - hash += seed[idx]; - hash ^= mul; - } - - return hash; -} - -/// @brief write to mapped memory register -/// @param base the base address. -/// @param reg the register. -/// @param value the write to write on it. -template <typename DataKind> -inline Void ke_dma_write(UIntPtr base, DataKind reg, DataKind value) noexcept { - *(volatile DataKind*) (base + reg) = value; -} - -/// @brief read from mapped memory register. -/// @param base base address -/// @param reg the register. -/// @return the value inside the register. -template <typename DataKind> -inline UInt32 ke_dma_read(UIntPtr base, DataKind reg) noexcept { - return *(volatile DataKind*) (base + reg); -} - -/// @brief Hardware Abstraction Layer -namespace HAL { - /// @brief Check whether this pointer is a bitmap object. - /// @param ptr argument to verify. - /// @param whether successful or not. - auto mm_is_bitmap(VoidPtr ptr) -> Bool; -} // namespace HAL -} // namespace Kernel - -typedef Kernel::Void (*rt_syscall_proc)(Kernel::VoidPtr); - -/// @brief System Call Dispatch. -struct HAL_DISPATCH_ENTRY final { - Kernel::UInt64 fHash; - Kernel::Bool fHooked; - rt_syscall_proc fProc; - - BOOL IsKernCall() { return NO; } - BOOL IsSysCall() { return YES; } - - operator bool() { return fHooked; } -}; - -typedef Kernel::Void (*rt_kerncall_proc)(Kernel::SizeT, Kernel::VoidPtr, Kernel::SizeT); - -/// @brief Kernel Call Dispatch. -struct HAL_KERNEL_DISPATCH_ENTRY final { - Kernel::UInt64 fHash; - Kernel::Bool fHooked; - rt_kerncall_proc fProc; - - BOOL IsKernCall() { return YES; } - BOOL IsSysCall() { return NO; } - - operator bool() { return fHooked; } -}; - -inline Kernel::Array<HAL_DISPATCH_ENTRY, kMaxDispatchCallCount> kSysCalls; - -inline Kernel::Array<HAL_KERNEL_DISPATCH_ENTRY, kMaxDispatchCallCount> kKernCalls; - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - -inline Kernel::VoidPtr kKernelVM = nullptr; - -#endif // __NE_VIRTUAL_MEMORY_SUPPORT__ - -inline Kernel::SizeT kBitMapCursor = 0UL; diff --git a/dev/kernel/CFKit/GUIDWizard.h b/dev/kernel/CFKit/GUIDWizard.h deleted file mode 100644 index 8745a1f9..00000000 --- a/dev/kernel/CFKit/GUIDWizard.h +++ /dev/null @@ -1,21 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CFKit/GUIDWrapper.h> -#include <NeKit/Array.h> -#include <NeKit/ArrayList.h> -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/KString.h> -#include <NeKit/Ref.h> -#include <NeKit/Stream.h> - -namespace Kernel::CF::XRN::Version1 { -Ref<GUIDSequence*> cf_make_sequence(const ArrayList<UInt32>& seq); -ErrorOr<Ref<KString>> cf_try_guid_to_string(Ref<GUIDSequence*>& guid); -} // namespace Kernel::CF::XRN::Version1 diff --git a/dev/kernel/CFKit/GUIDWrapper.h b/dev/kernel/CFKit/GUIDWrapper.h deleted file mode 100644 index 2bf7b64e..00000000 --- a/dev/kernel/CFKit/GUIDWrapper.h +++ /dev/null @@ -1,48 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/Ref.h> -#include <NeKit/Stream.h> - -/* GUID for C++ classes. */ - -#define kXRNNil "@{........-....-M...-N...-............}" - -/// @brief eXtended Resource Namespace -namespace Kernel::CF::XRN { -union GUIDSequence final { - alignas(8) UShort fU8[16]; - alignas(8) UShort fU16[8]; - alignas(8) UInt fU32[4]; - alignas(8) ULong fU64[2]; - - struct GUID { - alignas(8) UInt fMs1; - UShort fMs2; - UShort fMs3; - UChar fMs4[8]; - } fUuid; -}; - -class GUID final { - public: - explicit GUID() = default; - ~GUID() = default; - - public: - NE_COPY_DEFAULT(GUID) - - public: - GUIDSequence& operator->() noexcept { return fUUID; } - GUIDSequence& Leak() noexcept { return fUUID; } - - private: - GUIDSequence fUUID; -}; -} // namespace Kernel::CF::XRN diff --git a/dev/kernel/CFKit/Property.h b/dev/kernel/CFKit/Property.h deleted file mode 100644 index cfb8a599..00000000 --- a/dev/kernel/CFKit/Property.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef CFKIT_PROPS_H -#define CFKIT_PROPS_H - -#include <CFKit/GUIDWrapper.h> -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/Function.h> -#include <NeKit/KString.h> - -#define kMaxPropLen (256U) - -namespace Kernel::CF { -/// @brief handle to anything (number, ptr, string...) -using PropertyId = UIntPtr; - -/// @brief Kernel property class. -/// @example /prop/smp_max or /prop/kern_ver -class Property { - public: - Property(); - virtual ~Property(); - - public: - Property& operator=(const Property&) = default; - Property(const Property&) = default; - - BOOL StringEquals(KBasicString<>& name); - PropertyId& GetValue(); - KBasicString<>& GetKey(); - - private: - KString fName{kMaxPropLen}; - PropertyId fValue{0UL}; - Ref<XRN::GUID> fGUID{}; -}; - -template <SizeT N> -using PropertyArray = Array<Property, N>; -} // namespace Kernel::CF - -namespace Kernel { -using namespace Kernel::CF; -} - -#endif // !CFKIT_PROPS_H diff --git a/dev/kernel/CFKit/Utils.h b/dev/kernel/CFKit/Utils.h deleted file mode 100644 index 247ad5fb..00000000 --- a/dev/kernel/CFKit/Utils.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef CFKIT_UTILS_H -#define CFKIT_UTILS_H - -#include <KernelKit/MSDOS.h> -#include <KernelKit/PE.h> - -/// @brief CFKit -namespace Kernel::CF { -/// @brief Finds the PE header inside the blob. -inline auto ldr_find_exec_header(DosHeaderPtr ptrDos) -> LDR_EXEC_HEADER_PTR { - if (!ptrDos) return nullptr; - - if (ptrDos->eMagic[0] != kMagMz0) return nullptr; - - if (ptrDos->eMagic[1] != kMagMz1) return nullptr; - -#ifdef __NE_AMD64__ - return (LDR_EXEC_HEADER_PTR) (VoidPtr) (&ptrDos->eLfanew + 1); -#else - return (LDR_EXEC_HEADER_PTR) (VoidPtr) (&ptrDos->eLfanew); -#endif -} - -/// @brief Finds the PE optional header inside the blob. -inline auto ldr_find_opt_exec_header(DosHeaderPtr ptrDos) -> LDR_OPTIONAL_HEADER_PTR { - if (!ptrDos) return nullptr; - - auto exec = ldr_find_exec_header(ptrDos); - - if (!exec) return nullptr; - - return (LDR_OPTIONAL_HEADER_PTR) (VoidPtr) (&exec->Characteristics + 1); -} - -/// @brief Finds the PE header inside the blob. -/// @note overloaded function. -inline auto ldr_find_exec_header(const Char* ptrDos) -> LDR_EXEC_HEADER_PTR { - return ldr_find_exec_header((DosHeaderPtr) ptrDos); -} - -/// @brief Finds the PE header inside the blob. -/// @note overloaded function. -inline auto ldr_find_opt_exec_header(const Char* ptrDos) -> LDR_OPTIONAL_HEADER_PTR { - return ldr_find_opt_exec_header((DosHeaderPtr) ptrDos); -} -} // namespace Kernel::CF - -#endif // ifndef CFKIT_UTILS_H diff --git a/dev/kernel/CompilerKit/CompilerKit.h b/dev/kernel/CompilerKit/CompilerKit.h deleted file mode 100644 index 523a4ecd..00000000 --- a/dev/kernel/CompilerKit/CompilerKit.h +++ /dev/null @@ -1,13 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef _INC_CL_H -#define _INC_CL_H - -#include <CompilerKit/Detail.h> -#include <CompilerKit/Version.h> - -#endif /* ifndef _INC_CL_H */ diff --git a/dev/kernel/CompilerKit/Detail.h b/dev/kernel/CompilerKit/Detail.h deleted file mode 100644 index 93e9b2dd..00000000 --- a/dev/kernel/CompilerKit/Detail.h +++ /dev/null @@ -1,27 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#ifdef __NEOSKRNL__ -#include <NeKit/Defines.h> -#endif // ifdef __NEOSKRNL__ - -#define NE_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; - -#define NE_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; - -#define NE_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; - -#define NE_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; diff --git a/dev/kernel/CompilerKit/Version.h b/dev/kernel/CompilerKit/Version.h deleted file mode 100644 index 4250531a..00000000 --- a/dev/kernel/CompilerKit/Version.h +++ /dev/null @@ -1,9 +0,0 @@ -// (c) Amlal El Mahrouss - -#pragma once - -#define BOOTLOADER_VERSION "v0.0.2-bootz" -#define KERNEL_VERSION "v0.0.2-krnl" - -#define BOOTLOADER_VERSION_BCD (0x0002) -#define KERNEL_VERSION_BCD (0x0002) diff --git a/dev/kernel/DmaKit/DmaPool.h b/dev/kernel/DmaKit/DmaPool.h deleted file mode 100644 index e20f8c69..00000000 --- a/dev/kernel/DmaKit/DmaPool.h +++ /dev/null @@ -1,101 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss , licensed under the Apache 2.0 license. - - File: DmaPool.h - Purpose: Dma Pool Manager. - -======================================== */ - -#pragma once - -#include <KernelKit/DebugOutput.h> - -#ifdef __NE_AMD64__ -#include <HALKit/AMD64/Processor.h> -#define kNeDMAPoolStart (0x1000000) -#define kNeDMAPoolSize (0x1000000) -#elif defined(__NE_ARM64__) -#include <HALKit/ARM64/Processor.h> - -/// @todo what reference offset shall we use? -#define kNeDMAPoolStart (0x1000000) -#define kNeDMAPoolSize (0x1000000) -#endif - -#define kNeDMABestAlign (8) - -namespace Kernel { -/// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it. -inline UInt8* kDmaPoolPtr = (UInt8*) kNeDMAPoolStart; -inline const UInt8* kDmaPoolEnd = (UInt8*) (kNeDMAPoolStart + kNeDMAPoolSize); - -/***********************************************************************************/ -/// @brief allocate from the rtl_dma_alloc system. -/// @param size the size of the chunk to allocate. -/// @param align alignement of pointer. -/***********************************************************************************/ -inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { - if (!size) { - return nullptr; - } - - /// Check alignement according to architecture. - if ((align % kNeDMABestAlign) != 0) { - return nullptr; - } - - UIntPtr addr = (UIntPtr) kDmaPoolPtr; - - /// here we just align the address according to a `align` variable, i'd rather be a power of two - /// really. - addr = (addr + (align - 1)) & ~(align - 1); - - if ((addr + size) > reinterpret_cast<UIntPtr>(kDmaPoolEnd)) { - err_global_get() = kErrorDmaExhausted; - return nullptr; - } - - kDmaPoolPtr = (UInt8*) (addr + size); - - HAL::mm_memory_fence((VoidPtr) addr); - - return (VoidPtr) addr; -} - -/***********************************************************************************/ -/// @brief Free DMA pointer. -/***********************************************************************************/ -inline Void rtl_dma_free(SizeT size) { - if (!size) return; - - auto ptr = (kDmaPoolPtr - size); - - if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) { - err_global_get() = kErrorDmaExhausted; - return; - } - - kDmaPoolPtr = ptr; - - HAL::mm_memory_fence(ptr); -} - -/***********************************************************************************/ -/// @brief Flush DMA pointer. -/***********************************************************************************/ -inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) { - if (ptr > kDmaPoolEnd) { - return; - } - - if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) { - err_global_get() = kErrorDmaExhausted; - return; - } - - for (SizeT buf_idx = 0UL; buf_idx < size_buffer; ++buf_idx) { - HAL::mm_memory_fence((VoidPtr) ((UInt8*) ptr + buf_idx)); - } -} -} // namespace Kernel diff --git a/dev/kernel/FSKit/Defines.h b/dev/kernel/FSKit/Defines.h deleted file mode 100644 index c5bf8f88..00000000 --- a/dev/kernel/FSKit/Defines.h +++ /dev/null @@ -1,12 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -#define FSKIT_VERSION "1.0.0" -#define FSKIT_VERSION_BCD 0x0100 diff --git a/dev/kernel/FSKit/Ext2+IFS.h b/dev/kernel/FSKit/Ext2+IFS.h deleted file mode 100644 index 01ca4c90..00000000 --- a/dev/kernel/FSKit/Ext2+IFS.h +++ /dev/null @@ -1,273 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <FSKit/Ext2.h> -#include <KernelKit/DriveMgr.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/KPC.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> - -namespace Kernel { -/// @brief Context for an EXT2 filesystem on a given drive -class Ext2Context final { - public: - DriveTrait* drive{nullptr}; - EXT2_SUPER_BLOCK* superblock{nullptr}; - - /// @brief context with a drive - Ext2Context(Kernel::DriveTrait* drv) : drive(drv) {} - - /// @brief Clean up - ~Ext2Context() { - if (superblock) { - Kernel::mm_free_ptr(superblock); - superblock = nullptr; - } - } - - Ext2Context(const Ext2Context&) = delete; - Ext2Context& operator=(const Ext2Context&) = delete; - - Ext2Context(Ext2Context&& other) noexcept : drive(other.drive), superblock(other.superblock) { - other.drive = nullptr; - other.superblock = nullptr; - } - - Ext2Context& operator=(Ext2Context&& other) noexcept { - if (this != &other) { - if (superblock) { - Kernel::mm_free_ptr(superblock); - } - drive = other.drive; - superblock = other.superblock; - other.drive = nullptr; - other.superblock = nullptr; - } - return *this; - } - - SizeT BlockSize() const { - if (!superblock) return kExt2FSBlockSizeBase; - return kExt2FSBlockSizeBase << superblock->fLogBlockSize; - } - - operator BOOL() { return superblock != nullptr; } -}; - -/// ======================================================================= /// -/// IFS FUNCTIONS -/// ======================================================================= /// - -inline BOOL ext2_read_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, VoidPtr buffer, - Kernel::UInt32 size) { - if (!drv || !buffer) return false; - - Kernel::DriveTrait::DrivePacket pkt{}; - pkt.fPacketContent = buffer; - pkt.fPacketSize = size; - pkt.fPacketLba = lba; - drv->fInput(pkt); - - return pkt.fPacketGood; -} - -inline BOOL ext2_write_block(Kernel::DriveTrait* drv, Kernel::UInt32 lba, const VoidPtr buffer, - Kernel::UInt32 size) { - if (!drv || !buffer) return false; - - Kernel::DriveTrait::DrivePacket pkt{}; - pkt.fPacketContent = const_cast<VoidPtr>(buffer); - pkt.fPacketSize = size; - pkt.fPacketLba = lba; - drv->fOutput(pkt); - return pkt.fPacketGood; -} - -inline Kernel::ErrorOr<EXT2_SUPER_BLOCK*> ext2_load_superblock(Ext2Context* ctx) { - if (!ctx || !ctx->drive) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData); - - auto buf = Kernel::mm_alloc_ptr(sizeof(EXT2_SUPER_BLOCK), true, false); - if (!buf) return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorHeapOutOfMemory); - - Kernel::UInt32 blockLba = kExt2FSSuperblockOffset / ctx->drive->fSectorSz; - - if (!ext2_read_block(ctx->drive, blockLba, buf, sizeof(EXT2_SUPER_BLOCK))) { - Kernel::mm_free_ptr(buf); - return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorDisk); - } - - auto sb = reinterpret_cast<EXT2_SUPER_BLOCK*>(buf); - if (sb->fMagic != kExt2FSMagic) { - Kernel::mm_free_ptr(buf); - return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(Kernel::kErrorInvalidData); - } - - ctx->superblock = sb; - return Kernel::ErrorOr<EXT2_SUPER_BLOCK*>(sb); -} - -// Load inode -inline Kernel::ErrorOr<Ext2Node*> ext2_load_inode(Ext2Context* ctx, Kernel::UInt32 inodeNumber) { - if (!ctx || !ctx->superblock) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorInvalidData); - - auto nodePtr = Kernel::mm_alloc_ptr(sizeof(Ext2Node), true, false); - if (!nodePtr) return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorHeapOutOfMemory); - - auto ext2Node = reinterpret_cast<Ext2Node*>(nodePtr); - ext2Node->inodeNumber = inodeNumber; - - // Compute block group and index within group - Kernel::UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup; - Kernel::UInt32 group = (inodeNumber - 1) / inodesPerGroup; - - // dummy: just offset first inode - Kernel::UInt32 inodeTableBlock = ctx->superblock->fFirstInode + group; - - if (!ext2_read_block(ctx->drive, inodeTableBlock, &ext2Node->inode, sizeof(EXT2_INODE))) { - Kernel::mm_free_ptr(nodePtr); - return Kernel::ErrorOr<Ext2Node*>(Kernel::kErrorDisk); - } - - ext2Node->cursor = 0; - return Kernel::ErrorOr<Ext2Node*>(ext2Node); -} - -/* - * Ext2FileSystemParser Class - * - * Provides high-level interface for EXT2 filesystem operations - */ -class Ext2FileSystemParser final { - private: - Ext2Context fCtx; // Internal EXT2 context - - public: - /* - * Constructor - * Initializes the parser with a drive interface - * - * @param drive: Pointer to drive trait for disk I/O operations - */ - explicit Ext2FileSystemParser(DriveTrait* drive); - - NE_COPY_DELETE(Ext2FileSystemParser) - - /* - * Open a file or directory by path - * - * @param path: Full path to the file/directory (e.g., "/home/user/file.txt") - * @param restrict_type: Access mode restriction (e.g., "r", "w", "rw") - * @return: VoidPtr handle to the opened file/directory, or nullptr on failure - */ - VoidPtr Open(const char* path, const char* restrict_type); - - /* - * Read data from an open file node - * - * @param node: File node handle returned by Open() - * @param flags: Read operation flags - * @param size: Number of bytes to read - * @return: Pointer to allocated buffer containing read data, or nullptr on failure - * Caller is responsible for freeing the returned buffer - */ - VoidPtr Read(VoidPtr node, Int32 flags, SizeT size); - - /* - * Write data to an open file node - * - * @param node: File node handle returned by Open() - * @param data: Buffer containing data to write - * @param flags: Write operation flags - * @param size: Number of bytes to write - */ - Void Write(VoidPtr node, VoidPtr data, Int32 flags, SizeT size); - - /* - * Seek to a specific position in the file - * - * @param node: File node handle - * @param offset: Byte offset from beginning of file - * @return: true on success, false on failure - */ - BOOL Seek(VoidPtr node, SizeT offset); - - /* - * Get current position in the file - * - * @param node: File node handle - * @return: Current byte offset from beginning of file - */ - SizeT Tell(VoidPtr node); - - /* - * Reset file position to beginning - * - * @param node: File node handle - * @return: true on success, false on failure - */ - BOOL Rewind(VoidPtr node); - - /* - * Read data from a named file within a directory node - * - * @param name: Name of file within the directory - * @param node: Directory node handle - * @param flags: Read operation flags - * @param size: Number of bytes to read - * @return: Pointer to allocated buffer containing read data, or nullptr on failure - */ - VoidPtr Read(const char* name, VoidPtr node, Int32 flags, SizeT size); - - /* - * Write data to a named file within a directory node - * - * @param name: Name of file within the directory - * @param node: Directory node handle - * @param data: Buffer containing data to write - * @param flags: Write operation flags - * @param size: Number of bytes to write - */ - Void Write(const char* name, VoidPtr node, VoidPtr data, Int32 flags, SizeT size); - - /* - * Create a new regular file - * - * @param path: Full path for the new file - * @return: VoidPtr handle to the created file, or nullptr on failure - */ - VoidPtr Create(const char* path); - - /* - * Create a new directory - * - * @param path: Full path for the new directory - * @return: VoidPtr handle to the created directory, or nullptr on failure - */ - VoidPtr CreateDirectory(const char* path); - - /* - * Close and free a file/directory node - * Note: This method is not shown in the implementation but would typically be needed - * - * @param node: Node handle to close and free - */ - Void Close(VoidPtr node); - - /* - * Get file/directory information - * Note: This method is not shown in the implementation but would typically be needed - * - * @param node: Node handle - * @param info: Structure to fill with file information (size, type, permissions, etc.) - * @return: true on success, false on failure - */ - BOOL GetInfo(VoidPtr node, VoidPtr info); -}; -} // namespace Kernel diff --git a/dev/kernel/FSKit/Ext2.h b/dev/kernel/FSKit/Ext2.h deleted file mode 100644 index e979e556..00000000 --- a/dev/kernel/FSKit/Ext2.h +++ /dev/null @@ -1,148 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/DriveMgr.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <hint/CompilerHint.h> - -/// @file Ext2.h -/// @brief EXT2 filesystem structures, constants, and base wrappers. - -/// EXT2 Constants -#define kExt2FSMagic (0xEF53) -#define kExt2FSMaxFileNameLen (255U) -#define kExt2FSSuperblockOffset (1024) -#define kExt2FSRootInodeNumber (2) -#define kExt2FSInodeSize (128U) -#define kExt2FSBlockSizeBase (1024U) - -#define kExt2FSRev0 (0) -#define kExt2FSRev1 (1) - -/// EXT2 file types -enum { - kExt2FileTypeUnknown = 0, - kExt2FileTypeRegular = 1, - kExt2FileTypeDirectory = 2, - kExt2FileTypeCharDevice = 3, - kExt2FileTypeBlockDevice = 4, - kExt2FileTypeFIFO = 5, - kExt2FileTypeSocket = 6, - kExt2FileTypeSymbolicLink = 7 -}; - -typedef struct EXT2_GROUP_DESCRIPTOR final { - UInt32 fBlockBitmap; - UInt32 fInodeBitmap; - UInt32 fInodeTable; - UInt16 fFreeBlocksCount; - UInt16 fFreeInodesCount; - UInt16 fBgUsedDirsCount; - UInt16 fBgPad; - UInt32 fBgReserved[3]; -} EXT2_GROUP_DESCRIPTOR; - -struct PACKED EXT2_SUPER_BLOCK final { - Kernel::UInt32 fInodeCount; - Kernel::UInt32 fBlockCount; - Kernel::UInt32 fReservedBlockCount; - Kernel::UInt32 fFreeBlockCount; - Kernel::UInt32 fFreeInodeCount; - Kernel::UInt32 fFirstDataBlock; - Kernel::UInt32 fLogBlockSize; - Kernel::UInt32 fLogFragmentSize; - Kernel::UInt32 fBlocksPerGroup; - Kernel::UInt32 fFragmentsPerGroup; - Kernel::UInt32 fInodesPerGroup; - Kernel::UInt32 fMountTime; - Kernel::UInt32 fWriteTime; - Kernel::UInt16 fMountCount; - Kernel::UInt16 fMaxMountCount; - Kernel::UInt16 fMagic; - Kernel::UInt16 fState; - Kernel::UInt16 fErrors; - Kernel::UInt16 fMinorRevision; - Kernel::UInt32 fLastCheck; - Kernel::UInt32 fCheckInterval; - Kernel::UInt32 fCreatorOS; - Kernel::UInt32 fRevisionLevel; - Kernel::UInt16 fDefaultUID; - Kernel::UInt16 fDefaultGID; - - // EXT2_DYNAMIC_REV fields - Kernel::UInt32 fFirstInode; - Kernel::UInt16 fInodeSize; - Kernel::UInt16 fBlockGroupNumber; - Kernel::UInt32 fFeatureCompat; - Kernel::UInt32 fFeatureIncompat; - Kernel::UInt32 fFeatureROCompat; - Kernel::UInt8 fUUID[16]; - Kernel::Char fVolumeName[16]; - Kernel::Char fLastMounted[64]; - Kernel::UInt32 fAlgoBitmap; - - Kernel::UInt8 fPreallocBlocks; - Kernel::UInt8 fPreallocDirBlocks; - Kernel::UInt16 fReservedGDTBlocks; - - Kernel::UInt8 fJournalUUID[16]; - Kernel::UInt32 fJournalInode; - Kernel::UInt32 fJournalDevice; - Kernel::UInt32 fLastOrphan; - - Kernel::UInt32 fHashSeed[4]; - Kernel::UInt8 fDefHashVersion; - Kernel::UInt8 fReservedCharPad; - Kernel::UInt16 fReservedWordPad; - Kernel::UInt32 fDefaultMountOpts; - Kernel::UInt32 fFirstMetaBlockGroup; - - Kernel::UInt8 fReserved[760]; // Padding to make 1024 bytes -}; - -struct PACKED EXT2_INODE final { - Kernel::UInt16 fMode; - Kernel::UInt16 fUID; - Kernel::UInt32 fSize; - Kernel::UInt32 fAccessTime; - Kernel::UInt32 fCreateTime; - Kernel::UInt32 fModifyTime; - Kernel::UInt32 fDeleteTime; - Kernel::UInt16 fGID; - Kernel::UInt16 fLinksCount; - Kernel::UInt32 fBlocks; - Kernel::UInt32 fFlags; - Kernel::UInt32 fOSD1; - - Kernel::UInt32 fBlock[15]; // direct 0-11, indirect 12, double 13, triple 14 - - Kernel::UInt32 fGeneration; - Kernel::UInt32 fFileACL; - Kernel::UInt32 fDirACL; - Kernel::UInt32 fFragmentAddr; - - Kernel::UInt8 fOSD2[12]; -}; - -/// Directory entry -struct PACKED EXT2_DIR_ENTRY final { - Kernel::UInt32 fInode; - Kernel::UInt16 fRecordLength; - Kernel::UInt8 fNameLength; - Kernel::UInt8 fFileType; - Kernel::Char fName[kExt2FSMaxFileNameLen]; -}; - -/// VFS usage -struct Ext2Node { - Kernel::UInt32 inodeNumber; - EXT2_INODE inode; - Kernel::UInt32 cursor{0}; -}; diff --git a/dev/kernel/FSKit/IndexableProperty.h b/dev/kernel/FSKit/IndexableProperty.h deleted file mode 100644 index a89e78b8..00000000 --- a/dev/kernel/FSKit/IndexableProperty.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CFKit/Property.h> -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/DriveMgr.h> - -#define kIndexerCatalogNameLength (256U) -#define kIndexerClaimed (0xCF) -#define kIndexerUnclaimed (0xCA) - -namespace Kernel { -namespace Indexer { - struct Index final { - public: - Char Drive[kDriveNameLen]{}; - Char Path[kIndexerCatalogNameLength]{}; - }; - - class IndexableProperty final : public Property { - public: - explicit IndexableProperty() : Property() { - KBasicString<> strProp(kMaxPropLen); - strProp += "/prop/indexable"; - - this->GetKey() = strProp; - } - - ~IndexableProperty() override = default; - - NE_COPY_DEFAULT(IndexableProperty) - - public: - Index& Leak() noexcept; - - public: - Void AddFlag(UInt16 flag); - Void RemoveFlag(UInt16 flag); - UInt16 HasFlag(UInt16 flag); - - private: - Index fIndex; - UInt32 fFlags{}; - }; - - /// @brief Index a file into the indexer instance. - /// @param filename path - /// @param filenameLen used bytes in path. - /// @param indexer the filesystem indexer. - /// @return none. - Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer); -} // namespace Indexer -} // namespace Kernel diff --git a/dev/kernel/FSKit/NeFS.h b/dev/kernel/FSKit/NeFS.h deleted file mode 100644 index 54861dec..00000000 --- a/dev/kernel/FSKit/NeFS.h +++ /dev/null @@ -1,413 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - FILE: NeFS.h - PURPOSE: NeFS (New extended File System) support. - - Revision History: - - ?/?/?: Added file (amlel) - 12/02/24: Add UUID macro for EPM and GPT partition schemes. - 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by -default. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/DriveMgr.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <hint/CompilerHint.h> - -/** - @brief New extended File System specification. - @author Amlal El Mahrouss (Amlal El Mahrouss, amlalelmahrouss at icloud dot com) -*/ - -#define kNeFSInvalidFork (-1) -#define kNeFSInvalidCatalog (-1) -#define kNeFSCatalogNameLen (256) - -#define kNeFSVolumeName "NeFS Volume" - -#define kNeFSMinimumDiskSize (mib_cast(8)) - -#define kNeFSSectorSz (512) - -#define kNeFSIdentLen (8) -#define kNeFSIdent " NeFS" -#define kNeFSPadLen (392) - -#define kNeFSMetaFilePrefix '$' - -#define kNeFSVersionInteger (0x0129) -#define kNeFSVerionString "1.2.9" - -/// @brief Standard fork types. -#define kNeFSDataFork "main_data" -#define kNeFSResourceFork "main_rsrc" - -#define kNeFSForkSize (sizeof(NEFS_FORK_STRUCT)) - -#define kNeFSPartitionTypeStandard (7) -#define kNeFSPartitionTypePage (8) -#define kNeFSPartitionTypeBoot (9) - -#define kNeFSCatalogKindFile (1) -#define kNeFSCatalogKindDir (2) -#define kNeFSCatalogKindAlias (3) - -//! Shared between network and/or partitions. Export forks as .zip when copying. -#define kNeFSCatalogKindShared (4) - -#define kNeFSCatalogKindResource (5) -#define kNeFSCatalogKindExecutable (6) - -#define kNeFSCatalogKindPage (8) - -#define kNeFSCatalogKindDevice (9) -#define kNeFSCatalogKindLock (10) - -#define kNeFSCatalogKindRLE (11) -#define kNeFSCatalogKindMetaFile (12) - -#define kNeFSCatalogKindTTF (13) -#define kNeFSCatalogKindRIFF (14) -#define kNeFSCatalogKindMPEG (15) -#define kNeFSCatalogKindMOFF (16) - -#define kNeFSSeparator '/' -#define kNeFSSeparatorAlt '/' - -#define kNeFSUpDir ".." -#define kNeFSRoot "/" -#define kNeFSRootAlt "/" - -#define kNeFSLF '\r' -#define kNeFSEOF (-1) - -#define kNeFSBitWidth (sizeof(Kernel::Char)) -#define kNeFSLbaType (Kernel::Lba) - -/// @note Start after the partition map header. (Virtual addressing) -#define kNeFSRootCatalogStartAddress (1024) -#define kNeFSCatalogStartAddress (kNeFSRootCatalogStartAddress + sizeof(NEFS_ROOT_PARTITION_BLOCK)) - -#define kResourceTypeDialog (10) -#define kResourceTypeString (11) -#define kResourceTypeMenu (12) -#define kResourceTypeSound (13) -#define kResourceTypeFont (14) -#define kNeFSPartLen (32) - -#define kNeFSFlagDeleted (70) -#define kNeFSFlagUnallocated (0) -#define kNeFSFlagCreated (71) - -#define kNeFSMimeNameLen (200) -#define kNeFSForkNameLen (199) - -#define kNeFSFrameworkExt ".fwrk/" -#define kNeFSStepsExt ".step/" -#define kNeFSApplicationExt ".app/" -#define kNeFSJournalExt ".jrnl" - -struct NEFS_CATALOG_STRUCT; -struct NEFS_FORK_STRUCT; -struct NEFS_ROOT_PARTITION_BLOCK; - -enum { - kNeFSHardDrive = 0xC0, // Hard Drive - kNeFSSolidStateDrive = 0xC1, // Solid State Drive - kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD - kNeFSMassStorageDevice = 0xCC, // USB - kNeFSScsiDrive = 0xC4, // SCSI Hard Drive - kNeFSFlashDrive = 0xC6, - kNeFSUnknown = 0xFF, // Unknown device. - kNeFSDriveCount = 7, -}; - -enum { - kNeFSStatusUnlocked = 0x18, - kNeFSStatusLocked, - kNeFSStatusError, - kNeFSStatusInvalid, - kNeFSStatusCount, -}; - -/// @brief Catalog record type. -struct PACKED NEFS_CATALOG_STRUCT final { - BOOL ForkOrCatalog : 1 {0}; - - Kernel::Char Name[kNeFSCatalogNameLen] = {0}; - Kernel::Char Mime[kNeFSMimeNameLen] = {0}; - - /// Catalog flags. - Kernel::UInt16 Flags; - - /// Catalog allocation status. - Kernel::UInt16 Status; - - /// Custom catalog flags. - Kernel::UInt16 CatalogFlags; - - /// Catalog kind. - Kernel::Int32 Kind; - - /// Size of the data fork. - Kernel::Lba DataForkSize; - - /// Size of all resource forks. - Kernel::Lba ResourceForkSize; - - /// Forks LBA. - Kernel::Lba DataFork; - Kernel::Lba ResourceFork; - - /// Buddy allocation tracker. - Kernel::Lba NextSibling; - Kernel::Lba PrevSibling; - - /// Best-buddy tracker. - Kernel::Lba NextBestSibling; - Kernel::Lba NextPrevSibling; - - Kernel::UInt32 Checksum; -}; - -/// @brief Fork type, contains a data page. -/// @note The way we store is way different than how other filesystems do, specific chunk of code -/// are written into either the data fork or resource fork, the resource fork is reserved for file -/// metadata. whereas the data fork is reserved for file data. -struct PACKED NEFS_FORK_STRUCT final { - BOOL ForkOrCatalog : 1 {1}; - - Kernel::Char ForkName[kNeFSForkNameLen] = {0}; - Kernel::Char CatalogName[kNeFSCatalogNameLen] = {0}; - - Kernel::Int32 Flags; - Kernel::Int32 Kind; - - Kernel::Int64 ResourceId; - Kernel::Int32 ResourceKind; - Kernel::Int32 ResourceFlags; - - Kernel::Lba DataOffset; // 8 Where to look for this data? - Kernel::SizeT DataSize; /// Data size according using sector count. - - Kernel::Lba NextSibling; - Kernel::Lba PreviousSibling; -}; - -/// @brief Partition block type -struct PACKED NEFS_ROOT_PARTITION_BLOCK final { - Kernel::Char Ident[kNeFSIdentLen] = {0}; - Kernel::Char PartitionName[kNeFSPartLen] = {0}; - - Kernel::Int32 Flags; - Kernel::Int32 Kind; - - Kernel::Lba StartCatalog; - Kernel::SizeT CatalogCount; - - Kernel::SizeT DiskSize; - - Kernel::SizeT FreeCatalog; - Kernel::SizeT FreeSectors; - - Kernel::SizeT SectorCount; - Kernel::SizeT SectorSize; - - Kernel::UInt64 Version; - - Kernel::Lba EpmBlock; - - Kernel::Char Pad[kNeFSPadLen]; -}; - -namespace Kernel { -class NeFileSystemParser; -class NeFileSystemJournal; -class NeFileSystemHelper; - -enum { - kNeFSSubDriveA, - kNeFSSubDriveB, - kNeFSSubDriveC, - kNeFSSubDriveD, - kNeFSSubDriveInvalid, - kNeFSSubDriveCount, -}; - -/// \brief Resource fork kind. -enum { kNeFSRsrcForkKind = 0, kNeFSDataForkKind = 1 }; - -/// -/// \name NeFileSystemParser -/// \brief NeFS parser class. (catalog creation, remove removal, root, -/// forks...) Designed like the DOM, detects the filesystem automatically. -/// -class NeFileSystemParser final { - public: - explicit NeFileSystemParser() = default; - ~NeFileSystemParser() = default; - - public: - NE_COPY_DELETE(NeFileSystemParser) - - NE_MOVE_DELETE(NeFileSystemParser) - - public: - /// @brief Creates a new fork inside the NeFS partition. - /// @param catalog it's catalog - /// @param theFork the fork itself. - /// @return the fork - _Output BOOL CreateFork(_Input NEFS_FORK_STRUCT& in); - - /// @brief Find fork inside New filesystem. - /// @param catalog the catalog. - /// @param name the fork name. - /// @return the fork. - _Output NEFS_FORK_STRUCT* FindFork(_Input NEFS_CATALOG_STRUCT* catalog, _Input const Char* name, - Boolean data); - - _Output Void RemoveFork(_Input NEFS_FORK_STRUCT* fork); - - _Output Void CloseFork(_Input NEFS_FORK_STRUCT* fork); - - _Output NEFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalog_name, Lba& ou_lba, - Bool search_hidden = YES, Bool local_search = NO); - - _Output NEFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name); - - _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name, _Input const Int32& flags, - _Input const Int32& kind); - - _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name); - - _Output Bool WriteCatalog(_Input const Char* catalog, _Input Bool rsrc, _Input VoidPtr data, - _Input SizeT sz, _Input const Char* name); - - _Output VoidPtr ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog, _Input Bool isRsrcFork, - _Input SizeT dataSz, _Input const Char* forkName); - - _Output Bool Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off); - - _Output SizeT Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog); - - _Output Bool RemoveCatalog(_Input const Char* catalog); - - _Output Bool CloseCatalog(_InOut NEFS_CATALOG_STRUCT* catalog); - - /// @brief Make a EPM+NeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, - const Char* part_name); - - public: - UInt32 mDriveIndex{kNeFSSubDriveA}; -}; - -/// -/// \name NeFileSystemHelper -/// \brief Filesystem helper class. -/// - -class NeFileSystemHelper final { - public: - STATIC const Char* Root(); - STATIC const Char* UpDir(); - STATIC Char Separator(); - STATIC Char MetaFile(); -}; - -/// @brief Journal class for NeFS. -class NeFileSystemJournal final { - private: - NEFS_CATALOG_STRUCT* mNode{nullptr}; - - public: - explicit NeFileSystemJournal(const char* stamp = nullptr) { - if (!stamp) { - kout << "Invalid: Journal stamp, using default name.\r"; - return; - } - - (Void)(kout << "Info: Journal stamp: " << stamp << kendl); - rt_copy_memory((VoidPtr) stamp, this->mStamp, rt_string_len(stamp)); - } - - ~NeFileSystemJournal() = default; - - NE_COPY_DEFAULT(NeFileSystemJournal) - - Bool CreateJournal(NeFileSystemParser* parser) { - if (!parser) return NO; - - delete parser->CreateCatalog("/etc/xml/", 0, kNeFSCatalogKindDir); - mNode = parser->CreateCatalog(mStamp); - - if (!mNode) return NO; - - return YES; - } - - Bool GetJournal(NeFileSystemParser* parser) { - if (!parser) return NO; - - auto node = parser->GetCatalog(mStamp); - - if (node) { - mNode = node; - return YES; - } - - return NO; - } - - Bool ReleaseJournal() { - if (mNode) { - delete mNode; - mNode = nullptr; - return YES; - } - - return NO; - } - - Bool CommitJournal(NeFileSystemParser* parser, Char* xml_data, Char* journal_name) { - if (!parser || !mNode) return NO; - - NEFS_FORK_STRUCT new_fork{}; - - rt_copy_memory(mStamp, new_fork.CatalogName, rt_string_len(mStamp)); - rt_copy_memory(journal_name, new_fork.ForkName, rt_string_len(journal_name)); - - new_fork.ResourceKind = 0; - new_fork.ResourceId = 0; - new_fork.ResourceFlags = 0; - new_fork.DataSize = rt_string_len(xml_data); - new_fork.Kind = kNeFSRsrcForkKind; - - if (!parser->CreateFork(new_fork)) return NO; - - (Void)(kout << "XML commit: " << xml_data << " to fork: " << journal_name << kendl); - - auto ret = parser->WriteCatalog(new_fork.CatalogName, YES, xml_data, rt_string_len(xml_data), - new_fork.ForkName); - - return ret; - } - - private: - Char mStamp[kNeFSCatalogNameLen] = {"/etc/xml/journal" kNeFSJournalExt}; -}; - -namespace NeFS { - Boolean fs_init_nefs(Void) noexcept; -} // namespace NeFS -} // namespace Kernel diff --git a/dev/kernel/FSKit/OpenHeFS.h b/dev/kernel/FSKit/OpenHeFS.h deleted file mode 100644 index 04f07b8e..00000000 --- a/dev/kernel/FSKit/OpenHeFS.h +++ /dev/null @@ -1,434 +0,0 @@ -/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#pragma once
-
-#include <CompilerKit/CompilerKit.h>
-#include <KernelKit/DriveMgr.h>
-#include <KernelKit/UserMgr.h>
-#include <NeKit/Crc32.h>
-#include <NeKit/Defines.h>
-#include <NeKit/KString.h>
-#include <hint/CompilerHint.h>
-
-/// @file OpenHeFS.h
-/// @brief OpenHeFS filesystem support.
-
-#define kHeFSVersion (0x0104)
-#define kHeFSMagic "OpenHeFS"
-#define kHeFSMagicLen (9U)
-
-#define kHeFSBlockLen (512U)
-#define kHeFSFileNameLen (256U)
-#define kHeFSPartNameLen (128U)
-
-#define kHeFSMinimumDiskSize (gib_cast(128))
-
-#define kHeFSDefaultVolumeName u8"OpenHeFS Volume"
-
-#define kHeFSINDStartOffset (sizeof(HEFS_BOOT_NODE))
-#define kHeFSINStartOffset (sizeof(HEFS_INDEX_NODE_DIRECTORY))
-
-#define kHeFSRootDirectory "/"
-#define kHeFSRootDirectoryU8 u8"/"
-
-#define kHeFSSeparator '/'
-#define kHeFSUpDir ".."
-
-#define kHeFSRootDirectoryLen (2U)
-
-#define kHeFSSearchAllStr u8"*"
-
-struct HEFS_BOOT_NODE;
-struct HEFS_INDEX_NODE;
-struct HEFS_INDEX_NODE_DIRECTORY;
-struct HEFS_JOURNAL_NODE;
-
-enum : UInt8 {
- kHeFSHardDrive = 0xC0, // Hard Drive
- kHeFSSolidStateDrive = 0xC1, // Solid State Drive
- kHeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
- kHeFSMassStorageDevice = 0xCC, // USB
- kHeFSScsiDrive = 0xC4, // SCSI Hard Drive
- kHeFSFlashDrive = 0xC6,
- kHeFSUnknown = 0xFF, // Unknown device.
- kHeFSDriveCount = 8,
-};
-
-enum : UInt8 {
- kHeFSStatusUnlocked = 0x18,
- kHeFSStatusLocked,
- kHeFSStatusError,
- kHeFSStatusInvalid,
- kHeFSStatusCount,
-};
-
-enum : UInt16 {
- kHeFSEncodingFlagsUTF8 = 0x50,
- kHeFSEncodingFlagsUTF16,
- kHeFSEncodingFlagsUTF32,
- kHeFSEncodingFlagsUTF16BE,
- kHeFSEncodingFlagsUTF16LE,
- kHeFSEncodingFlagsUTF32BE,
- kHeFSEncodingFlagsUTF32LE,
- kHeFSEncodingFlagsUTF8BE,
- kHeFSEncodingFlagsUTF8LE,
- kHeFSEncodingFlagsBinary,
- kHeFSEncodingFlagsCount = 11,
- kHeFSFlagsNone = 0,
- kHeFSFlagsReadOnly = 0x100,
- kHeFSFlagsHidden,
- kHeFSFlagsSystem,
- kHeFSFlagsArchive,
- kHeFSFlagsDevice,
- kHeFSFlagsCount = 7
-};
-
-inline constexpr UInt16 kHeFSFileKindRegular = 0x00;
-inline constexpr UInt16 kHeFSFileKindDirectory = 0x01;
-inline constexpr UInt16 kHeFSFileKindBlock = 0x02;
-inline constexpr UInt16 kHeFSFileKindCharacter = 0x03;
-inline constexpr UInt16 kHeFSFileKindFIFO = 0x04;
-inline constexpr UInt16 kHeFSFileKindSocket = 0x05;
-inline constexpr UInt16 kHeFSFileKindSymbolicLink = 0x06;
-inline constexpr UInt16 kHeFSFileKindUnknown = 0x07;
-inline constexpr UInt16 kHeFSFileKindCount = 0x08;
-
-/// @brief OpenHeFS blocks are array containing sparse blocks of data.
-/// @details The blocks are used to store the data of a file. Each block is a pointer to a block of
-/// data on the disk.
-inline constexpr UInt16 kHeFSSliceCount = 0x10;
-
-inline constexpr UInt16 kHeFSInvalidVID = 0xFFFF;
-
-namespace Kernel {
-/// @brief Access time type.
-/// @details Used to keep track of the INode, INodeDir allocation status.
-typedef UInt64 ATime;
-
-/// @brief OpenHeFS Boot node.
-/// @details Acts like a superblock, it contains the information about the filesystem.
-/// @note The boot node is the first block of the filesystem.
-struct PACKED HEFS_BOOT_NODE final {
- Char fMagic[kHeFSMagicLen]; /// @brief Magic number of the filesystem.
- Utf8Char fVolName[kHeFSPartNameLen]; /// @brief Volume name.
- UInt32 fVersion; /// @brief Version of the filesystem.
- UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem.
- UInt64 fSectorCount; /// @brief Number of sectors in the filesystem.
- UInt64 fSectorSize; /// @brief Size of the sector.
- UInt32 fChecksum; /// @brief Checksum of the boot node.
- UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical
- /// Drive, etc).
- UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc).
- UInt64 fStartIND; /// @brief Start of the INode directory tree.
- UInt64 fEndIND; /// @brief End of the INode directory tree.
- UInt64 fINDCount; /// @brief Number of leafs in the INode tree.
- UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the
- /// real size of the disk.)
- UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid).
- UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc).
- UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used).
- UInt64 fStartIN; /// @brief Start INodes range
- UInt64 fEndIN; /// @brief End INodes range
- UInt64 fStartBlock; /// @brief Start Blocks range
- UInt64 fEndBlock; /// @brief End Blocks range
- UInt64 fJournalLBA; /// @brief Boot Node's COW journal LBA.
- Char fPad[264];
-};
-
-inline constexpr ATime kHeFSTimeInvalid = 0x0000000000000000;
-inline constexpr ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1;
-
-/// @brief Journal Node structure
-/// @param fHashPath target hash path
-/// @param fStatus target status
-/// @param fCopyElem copy of element
-/// @param fCopyKind kind of element
-struct PACKED HEFS_JOURNAL_NODE {
- UInt64 fHashPath;
- UInt64 fStatus;
- UInt64 fCopyElem;
- UInt8 fCopyKind;
- UInt8 fPad[487];
-};
-
-/// @brief This enum defines the opcode of the journal, here mentioned as 'kinds'
-enum HeFSJournalKind : UInt8 {
- kJournalKindInvalid = 0x00,
- kJournalKindWrite = 0x01,
- kJournalKindRename = 0x02,
- kJournalKindDelete = 0x03,
- kJournalKindFlagEdit = 0x04,
- kJournalKindCreate = 0x05,
- kJournalKindCount,
-};
-
-/// @brief OpenHeFS index node.
-/// @details This structure is used to store the file information of a file.
-/// @note The index node is a special type of INode that contains the file information.
-/// @note The index node is used to store the file information of a file.
-struct PACKED HEFS_INDEX_NODE final {
- UInt64 fHashPath; /// @brief File name.
- UInt32 fFlags; /// @brief File flags.
- UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
- /// Symbolic Link, Unknown).
- UInt32 fSize; /// @brief File size.
- UInt32 fChecksum; /// @brief Checksum.
-
- Boolean fSymLink; /// @brief Is this a symbolic link? (if yes, the fName is the path to
- /// the file and blocklinkstart and end contains it's inodes.)
-
- ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps.
- UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
- UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
-
- /// @brief Extents system by using blocks
- /// @details Using an offset to ask fBase, and fLength to compute each slice's length.
- UInt32 fOffsetSliceLow;
- UInt32 fOffsetSliceHigh;
-
- Char fPad[437];
-};
-
-enum {
- kHeFSInvalidColor = 0,
- kHeFSRed = 100,
- kHeFSBlack,
- kHeFSColorCount,
-};
-
-/// @brief OpenHeFS directory node.
-/// @details This structure is used to store the directory information of a file.
-/// @note The directory node is a special type of INode that contains the directory entries.
-struct PACKED HEFS_INDEX_NODE_DIRECTORY final {
- UInt64 fHashPath; /// @brief Directory path as FNV hash.
-
- UInt32 fFlags; /// @brief File flags.
- UInt16 fReserved; /// @note Reserved for future use.
- UInt32 fEntryCount; /// @brief Entry Count of this directory inode.
- UInt32 fChecksum; /// @brief Checksum of the file, index node checksum.
-
- ATime fCreated, fAccessed, fModified,
- fDeleted; /// @brief File timestamps and allocation status.
- UInt32 fUID, fGID; /// @brief User ID and Group ID of the file.
- UInt32 fMode; /// @brief File mode. (read, write, execute, etc).
-
- /// @note These slices are organized as:
- /// [0] = OFFSET
- /// [1] = SIZE
- /// @note Thus the += 2 when iterating over them.
- UInt64 fINSlices[kHeFSSliceCount]; /// @brief Start of the index node.
-
- UInt8 fColor; /// @brief Color of the node. (Red or Black).
- Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers.
-
- Char fPad[285];
-};
-} // namespace Kernel
-
-namespace Kernel::Detail {
-/// @brief OpenHeFS get year from ATime.
-/// @param raw_atime the raw ATime value.
-/// @return the year value.
-/// @note The year is stored in the upper 32 bits of the ATime value.
-inline UInt32 hefs_year_get(ATime raw_atime) noexcept {
- return (raw_atime) >> 32;
-}
-
-/// @brief OpenHeFS get month from ATime.
-/// @param raw_atime the raw ATime value.
-/// @return the month value.
-/// @note The month is stored in the upper 24 bits of the ATime value.
-inline UInt32 hefs_month_get(ATime raw_atime) noexcept {
- return (raw_atime) >> 24;
-}
-
-/// @brief OpenHeFS get day from ATime.
-/// @param raw_atime the raw ATime value.
-/// @return the day value.
-/// @note The day is stored in the upper 16 bits of the ATime value.
-inline UInt32 hefs_day_get(ATime raw_atime) noexcept {
- return (raw_atime) >> 16;
-}
-
-/// @brief OpenHeFS get hour from ATime.
-/// @param raw_atime the raw ATime value.
-/// @return the hour value.
-/// @note The hour is stored in the upper 8 bits of the ATime value.
-inline UInt32 hefs_hour_get(ATime raw_atime) noexcept {
- return (raw_atime) >> 8;
-}
-
-/// @brief OpenHeFS get minute from ATime.
-/// @param raw_atime the raw ATime value.
-/// @return the minute value.
-/// @note The minute is stored in the lower 8 bits of the ATime value.
-inline UInt32 hefs_minute_get(ATime raw_atime) noexcept {
- return (raw_atime) &0xFF;
-}
-
-inline constexpr UInt32 kHeFSBaseYear = 1970;
-inline constexpr UInt32 kHeFSBaseMonth = 1;
-inline constexpr UInt32 kHeFSBaseDay = 1;
-inline constexpr UInt32 kHeFSBaseHour = 0;
-inline constexpr UInt32 kHeFSBaseMinute = 0;
-
-inline const Char* hefs_status_to_string(UInt16 status) noexcept {
- switch (status) {
- case kHeFSStatusUnlocked:
- return "Unlocked";
- case kHeFSStatusLocked:
- return "Locked";
- case kHeFSStatusError:
- return "Error";
- case kHeFSStatusInvalid:
- return "Invalid";
- default:
- return "Unknown";
- }
-}
-
-inline const Char* hefs_drive_kind_to_string(UInt8 kind) noexcept {
- switch (kind) {
- case kHeFSHardDrive:
- return "Hard Drive";
- case kHeFSSolidStateDrive:
- return "Solid State Drive";
- case kHeFSOpticalDrive:
- return "Optical Drive";
- case kHeFSMassStorageDevice:
- return "Mass Storage Device";
- case kHeFSScsiDrive:
- return "SCSI/SAS Drive";
- case kHeFSFlashDrive:
- return "Flash Drive";
- case kHeFSUnknown:
- default:
- return "Unknown";
- }
-}
-
-inline const Char* hefs_encoding_to_string(UInt8 encoding) noexcept {
- switch (encoding) {
- case kHeFSEncodingFlagsUTF8:
- return "UTF-8";
- case kHeFSEncodingFlagsUTF16:
- return "UTF-16";
- case kHeFSEncodingFlagsUTF32:
- return "UTF-32";
- case kHeFSEncodingFlagsUTF16BE:
- return "UTF-16BE";
- case kHeFSEncodingFlagsUTF16LE:
- return "UTF-16LE";
- case kHeFSEncodingFlagsUTF32BE:
- return "UTF-32BE";
- case kHeFSEncodingFlagsUTF32LE:
- return "UTF-32LE";
- case kHeFSEncodingFlagsUTF8BE:
- return "UTF-8BE";
- case kHeFSEncodingFlagsUTF8LE:
- return "UTF-8LE";
- default:
- return "Unknown";
- }
-}
-
-inline const Char* hefs_file_kind_to_string(UInt16 kind) noexcept {
- switch (kind) {
- case kHeFSFileKindRegular:
- return "Regular File";
- case kHeFSFileKindDirectory:
- return "Directory";
- case kHeFSFileKindBlock:
- return "Block Device";
- case kHeFSFileKindCharacter:
- return "Character Device";
- case kHeFSFileKindFIFO:
- return "FIFO";
- case kHeFSFileKindSocket:
- return "Socket";
- case kHeFSFileKindSymbolicLink:
- return "Symbolic Link";
- case kHeFSFileKindUnknown:
- default:
- return "Unknown";
- }
-}
-
-inline const Char* hefs_file_flags_to_string(UInt32 flags) noexcept {
- switch (flags) {
- case kHeFSFlagsNone:
- return "No Flags";
- case kHeFSFlagsReadOnly:
- return "Read Only";
- case kHeFSFlagsHidden:
- return "Hidden";
- case kHeFSFlagsSystem:
- return "System";
- case kHeFSFlagsArchive:
- return "Archive";
- case kHeFSFlagsDevice:
- return "Device";
- default:
- return "Unknown";
- }
-}
-} // namespace Kernel::Detail
-
-namespace Kernel {
-/// @brief OpenHeFS filesystem parser class.
-/// @details This class is used to parse the OpenHeFS filesystem.
-class HeFileSystemParser final {
- public:
- HeFileSystemParser() = default;
- ~HeFileSystemParser() = default;
-
- public:
- HeFileSystemParser(const HeFileSystemParser&) = delete;
- HeFileSystemParser& operator=(const HeFileSystemParser&) = delete;
-
- HeFileSystemParser(HeFileSystemParser&&) = delete;
- HeFileSystemParser& operator=(HeFileSystemParser&&) = delete;
-
- public:
- /// @brief Make a EPM+OpenHeFS drive out of the disk.
- /// @param drive The drive to write on.
- /// @return If it was sucessful, see err_local_get().
- _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* part_name);
-
- _Output Bool CreateINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir);
-
- _Output Bool RemoveINodeDirectory(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir);
-
- _Output Bool CreateINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
- const Utf8Char* name, const UInt8 kind);
-
- _Output Bool DeleteINode(_Input DriveTrait* drive, _Input const Int32 flags, const Utf8Char* dir,
- const Utf8Char* name, const UInt8 kind);
-
- _Output Bool INodeManip(_Input DriveTrait* drive, VoidPtr block, SizeT block_sz,
- const Utf8Char* dir, const Utf8Char* name, const UInt8 kind,
- const BOOL input);
-
- private:
- _Output Bool INodeCtlManip(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir, const Utf8Char* name, const BOOL delete_or_create,
- const UInt8 kind);
-
- _Output Bool INodeDirectoryCtlManip(_Input DriveTrait* drive, _Input const Int32 flags,
- const Utf8Char* dir, const BOOL delete_or_create);
-};
-
-namespace OpenHeFS {
-
- /// @brief Initialize OpenHeFS inside the main disk.
- /// @return Whether it successfuly formated it or not.
- Boolean fs_init_openhefs(Void) noexcept;
-} // namespace OpenHeFS
-} // namespace Kernel
diff --git a/dev/kernel/FirmwareKit/.gitkeep b/dev/kernel/FirmwareKit/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/dev/kernel/FirmwareKit/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/dev/kernel/FirmwareKit/EFI.h b/dev/kernel/FirmwareKit/EFI.h deleted file mode 100644 index f75f0fbe..00000000 --- a/dev/kernel/FirmwareKit/EFI.h +++ /dev/null @@ -1,12 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <FirmwareKit/EFI/EFI.h> -#include <FirmwareKit/GPT.h> - -/// @note this header is used to reference the EFI/EFI.h diff --git a/dev/kernel/FirmwareKit/EFI/API.h b/dev/kernel/FirmwareKit/EFI/API.h deleted file mode 100644 index 24fceb2b..00000000 --- a/dev/kernel/FirmwareKit/EFI/API.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __EFI_API__ -#define __EFI_API__ - -#include <FirmwareKit/EFI/EFI.h> -#include <FirmwareKit/Handover.h> -#include <KernelKit/MSDOS.h> -#include <KernelKit/PE.h> - -#ifdef __BOOTZ__ -// forward decl. -class BootTextWriter; - -#define __BOOTKIT_NO_INCLUDE__ 1 - -#include <BootKit/BootKit.h> -#include <modules/CoreGfx/CoreGfx.h> -#endif // ifdef __BOOTZ__ - -inline EfiSystemTable* ST = nullptr; -inline EfiBootServices* BS = nullptr; - -EXTERN_C void rt_cli(); -EXTERN_C void rt_halt(); - -namespace Boot { -/// @brief Halt and clear interrut flag on x86. -/// @return -inline Void Stop() noexcept { - while (YES) { - rt_cli(); - rt_halt(); - } -} - -/** -@brief Exit EFI API to let the OS load correctly. -Bascially frees everything we have in the EFI side. -*/ -inline Void ExitBootServices(UInt64 MapKey, EfiHandlePtr ImageHandle) noexcept { - if (!ST) return; - - ST->BootServices->ExitBootServices(ImageHandle, MapKey); -} - -inline UInt32 Platform() noexcept { - return kPeMachineAMD64; -} - -/*** - * @brief Throw an error, stop execution as well. - * @param ErrorCode error code to be print. - * @param Reason reason to be print. - */ -inline void ThrowError(const EfiCharType* ErrorCode, const EfiCharType* Reason) noexcept { - ST->ConOut->OutputString(ST->ConOut, L"\r*** STOP ***\r"); - - ST->ConOut->OutputString(ST->ConOut, L"*** ERROR: "); - ST->ConOut->OutputString(ST->ConOut, ErrorCode); - - ST->ConOut->OutputString(ST->ConOut, L" ***\r *** REASON: "); - ST->ConOut->OutputString(ST->ConOut, Reason); - - ST->ConOut->OutputString(ST->ConOut, L" ***\r"); - - Boot::Stop(); -} -} // namespace Boot - -inline void fw_init_efi(EfiSystemTable* SystemTable) noexcept { - if (!SystemTable) return; - - ST = SystemTable; - BS = ST->BootServices; -} - -#ifdef __BOOTZ__ - -#include <BootKit/Platform.h> - -#endif // ifdef __BOOTZ__ - -#endif /* ifndef __EFI_API__ */ diff --git a/dev/kernel/FirmwareKit/EFI/EFI.h b/dev/kernel/FirmwareKit/EFI/EFI.h deleted file mode 100644 index 240fb9ea..00000000 --- a/dev/kernel/FirmwareKit/EFI/EFI.h +++ /dev/null @@ -1,916 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef FIRMWARE_KIT_EFI_H -#define FIRMWARE_KIT_EFI_H - -/** -@brief Implementation of the main EFI protocols. -*/ - -#include <NeKit/Defines.h> - -using namespace Kernel; - -/* we always use stdcall in EFI, the pascal way of calling functions. */ - -#ifndef EPI_API -#define EFI_API __attribute__((ms_abi)) -#endif // ifndef EPI_API - -#ifndef EPIAPI -#define EFIAPI __attribute__((ms_abi)) -#endif // ifndef EPIAPI - -#define IN -#define OUT -#define OPTIONAL - -#define EFI_STATUS EfiStatusType - -#define EFI_FINAL final - -// Forward decls - -struct EfiTableHeader; -struct EfiLoadFileProtocol; -struct EfiSimpleTextOutputProtocol; -struct EfiDevicePathProtocol; -struct EfiBootServices; -struct EfiMemoryDescriptor; -struct EfiSystemTable; -struct EFI_GUID; -struct EfiFileDevicePathProtocol; -struct EfiHandle; -struct EfiGraphicsOutputProtocol; -struct EfiBitmask; -struct EfiFileProtocol; -struct EfiSimpleTextInputProtocol; - -typedef UInt64 EfiStatusType; - -typedef Char16 EfiChar16Type; - -/// @brief Core Handle Kind -/// Self is like NT's Win32 HANDLE type. -typedef struct EfiHandle { -} * EfiHandlePtr; - -/* UEFI uses wide characters by default. */ -typedef WideChar EfiCharType; - -typedef UInt64 EfiPhysicalAddress; -typedef UIntPtr EfiVirtualAddress; - -/// What's BootBolicy? -/// If TRUE, indicates that the request originates from the boot manager, and -/// that the boot manager is attempting to load FilePath as a boot selection. If -/// FALSE, then FilePath must match an exact file to be loaded. - -typedef UInt64(EFI_API* EfiTextString)(struct EfiSimpleTextOutputProtocol* Self, - const WideChar* OutputString); - -typedef UInt64(EFI_API* EfiTextAttrib)(struct EfiSimpleTextOutputProtocol* Self, - const WideChar Attribute); - -typedef UInt64(EFI_API* EfiTextClear)(struct EfiSimpleTextOutputProtocol* Self); - -typedef UInt64(EFI_API* EfiLoadFile)(EfiLoadFileProtocol* Self, EfiFileDevicePathProtocol* FilePath, - Boolean BootPolicy, UInt32* BufferSize, VoidPtr Buffer); - -typedef UInt64(EFI_API* EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length); - -typedef UInt64(EFI_API* EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length); - -typedef UInt64(EFI_API* EfiHandleProtocol)(EfiHandlePtr Handle, EFI_GUID* Guid, VoidPtr* Device); - -typedef UInt64(EFI_API* EfiLocateDevicePath)(EFI_GUID* Protocol, EfiDevicePathProtocol** DevicePath, - EfiHandlePtr Device); - -typedef UInt64(EFI_API* EfiStartImage)(EfiHandlePtr Handle, VoidPtr ArgsSize, VoidPtr ArgsPtr); - -typedef UInt64(EFI_API* EfiLoadImage)(Boolean BootPolicy, EfiHandlePtr ParentHandle, - EfiFileDevicePathProtocol* DeviceFile, VoidPtr buffer, - SizeT size, EfiHandlePtr* ppHandle); - -/// EFI pool helpers, taken from iPXE. - -typedef enum EfiMemoryType { - /// - /// Not used. - /// - EfiReservedMemoryType, - /// - /// The code portions of a loaded application. - /// (Note that UEFI OS loaders are UEFI applications.) - /// - EfiLoaderCode, - /// - /// The data portions of a loaded application and the default data allocation - /// type used by an application to allocate pool memory. - /// - EfiLoaderData, - /// - /// The code portions of a loaded Boot Services Driver. - /// - EfiBootServicesCode, - /// - /// The data portions of a loaded Boot Serves Driver, and the default data - /// allocation type used by a Boot Services Driver to allocate pool memory. - /// - EfiBootServicesData, - /// - /// The code portions of a loaded Runtime Services Driver. - /// - EfiRuntimeServicesCode, - /// - /// The data portions of a loaded Runtime Services Driver and the default - /// data allocation type used by a Runtime Services Driver to allocate pool - /// memory. - /// - EfiRuntimeServicesData, - /// - /// Free (unallocated) memory. - /// - EfiConventionalMemory, - /// - /// Memory in which errors have been detected. - /// - EfiUnusableMemory, - /// - /// Memory that holds the ACPI tables. - /// - EfiACPIReclaimMemory, - /// - /// Address space reserved for use by the firmware. - /// - EfiACPIMemoryNVS, - /// - /// Used by system firmware to request that a memory-mapped IO region - /// be mapped by the OS to a virtual address so it can be accessed by EFI - /// runtime services. - /// - EfiMemoryMappedIO, - /// - /// System memory-mapped IO region that is used to translate memory - /// cycles to IO cycles by the processor. - /// - EfiMemoryMappedIOPortSpace, - /// - /// Address space reserved by the firmware for code that is part of the - /// processor. - /// - EfiPalCode, - /// - /// A memory region that operates as EfiConventionalMemory, - /// however it happens to also support byte-addressable non-volatility. - /// - EfiPersistentMemory, - /// - /// A memory region that describes system memory that has not been accepted - /// by a corresponding call to the underlying isolation architecture. - /// - EfiUnacceptedMemoryType, - /// - /// The last type of memory. - /// Not a real type. - /// - EfiMaxMemoryType, -} EfiMemoryType; - -typedef enum EfiAllocateType { - /// Anything that satisfy the request. - AllocateAnyPages, - AllocateMaxAddress, - /// - /// Allocate pages at a specified address. - /// - AllocateAddress, - /// - /// Maximum enumeration value that may be used for bounds checking. - /// - MaxAllocateType -} EfiAllocateType; - -typedef struct EfiMemoryDescriptor { - /// @brief Kind of the memory region. - UInt32 Kind; - - /// @brief Physical address of the first byte in the memory region. PhysicalStart - EfiPhysicalAddress PhysicalStart; - /// - /// Virtual address of the first byte in the memory region. - /// VirtualStart must be aligned on a 4 KiB boundary, - /// and must not be above 0xfffffffffffff000. - /// - EfiVirtualAddress VirtualStart; - /// - /// NumberOfPages Number of 4 KiB pages in the memory region. - /// NumberOfPages must not be 0, and must not be any value - /// that would represent a memory page with a start address, - /// either physical or virtual, above 0xfffffffffffff000. - /// - UInt64 NumberOfPages; - /// - /// Attributes of the memory region that describe the bit mask of capabilities - /// for that memory region, and not necessarily the current settings for that - /// memory region. - /// - UInt64 Attribute; -} EfiMemoryDescriptor; - -typedef UInt64(EFI_API* EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size, VoidPtr* Buffer); - -typedef UInt64(EFI_API* EfiFreePool)(VoidPtr Buffer); - -typedef UInt64(EFI_API* EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize, UInt32* CrcOut); - -/** -@brief Present in every header, used to identify a UEFI structure. -*/ -typedef struct EfiTableHeader { - UInt64 Signature; - UInt32 Revision; - UInt32 HeaderSize; - UInt32 Crc32; - UInt32 Reserved; -} EfiTableHeader; - -#define EFI_ACPI_TABLE_PROTOCOL_GUID \ - { \ - 0xffe06bdd, 0x6107, 0x46a6, { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c } \ - } - -#define EFI_LOAD_FILE_PROTOCOL_GUID \ - { \ - 0x56EC3091, 0x954C, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#define EFI_LOAD_FILE2_PROTOCOL_GUID \ - { \ - 0x4006c0c1, 0xfcb3, 0x403e, { 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d } \ - } - -#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ - { \ - 0x5B1B31A1, 0x9562, 0x11d2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ - } - -#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ - { \ - 0x9042a9de, 0x23dc, 0x4a38, { 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \ - } - -#define EFI_SIMPLE_NETWORK_PROTOCOL_GUID \ - { \ - 0xA19832B9, 0xAC25, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define EFI_SIMPLE_NETWORK_PROTOCOL_REVISION 0x00010000 - -#define EFI_IP4_PROTOCOL_GUID \ - { \ - 0x41d94cd2, 0x35b6, 0x455a, { 0x82, 0x58, 0xd4, 0xe5, 0x13, 0x34, 0xaa, 0xdd } \ - } - -#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000 - -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { \ - 0x0964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } \ - } - -#define EFI_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0x9576e91, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ - { \ - 0x0964e5b22, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -typedef UInt64(EfiImageUnload)(EfiHandlePtr ImageHandle); - -enum { - kPixelRedGreenBlueReserved8BitPerColor, - kPixelBlueGreenRedReserved8BitPerColor, - kPixelBitMask, - kPixelBltOnly, - kPixelFormatMax -}; - -struct EFI_SIMPLE_NETWORK_PROTOCOL; - -typedef EFI_STATUS(EFI_API* EFI_SIMPLE_NETWORK_START)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This); - -typedef EFI_STATUS(EFI_API* EFI_SIMPLE_NETWORK_STOP)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This); - -typedef EFI_STATUS(EFI_API* EFI_SIMPLE_NETWORK_INITIALIZE)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This, - IN UInt32 ExtraRxBufferSize OPTIONAL, - IN UInt32 ExtraTxBufferSize OPTIONAL); - -typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_RESET)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This, - IN Boolean ExtendedVerification); - -typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_SHUTDOWN)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This); - -typedef UInt8 EfiMacAddress[32]; - -#define MAX_MCAST_FILTER_CNT 16 - -typedef struct { - UInt32 State; - UInt32 HwAddressSize; - UInt32 MediaHeaderSize; - UInt32 MaxPacketSize; - UInt32 NvRamSize; - UInt32 NvRamAccessSize; - UInt32 ReceiveFilterMask; - UInt32 ReceiveFilterSetting; - UInt32 MaxMCastFilterCount; - UInt32 MCastFilterCount; - EfiMacAddress MCastFilter[MAX_MCAST_FILTER_CNT]; - EfiMacAddress CurrentAddress; - EfiMacAddress BroadcastAddress; - EfiMacAddress PermanentAddress; - UInt8 IfType; - BOOL MacAddressChangeable; - BOOL MultipleTxSupported; - BOOL MediaPresentSupported; - BOOL MediaPresent; -} EFI_SIMPLE_NETWORK_MODE; - -typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_TRANSMIT)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This, - IN UInt32 HeaderSize, IN UInt32 BufferSize, - IN Void* Buffer, - IN EfiMacAddress* SrcAddr OPTIONAL, - IN EfiMacAddress* DestAddr OPTIONAL, - IN UInt16* Protocol OPTIONAL); - -typedef EFI_STATUS(EFIAPI* EFI_SIMPLE_NETWORK_RECEIVE)(IN EFI_SIMPLE_NETWORK_PROTOCOL* This, - OUT UInt32* HeaderSize OPTIONAL, - IN OUT UInt32* BufferSize, OUT Void* Buffer, - OUT EfiMacAddress* SrcAddr OPTIONAL, - OUT EfiMacAddress* DestAddr OPTIONAL, - OUT UInt16* Protocol OPTIONAL); - -typedef struct EFI_SIMPLE_NETWORK_PROTOCOL { - UInt64 Revision; - EFI_SIMPLE_NETWORK_START Start; - EFI_SIMPLE_NETWORK_STOP Stop; - EFI_SIMPLE_NETWORK_INITIALIZE Initialize; - EFI_SIMPLE_NETWORK_RESET Reset; - EFI_SIMPLE_NETWORK_SHUTDOWN Shutdown; - VoidPtr ReceiveFilters; - VoidPtr StationAddress; - VoidPtr Statistics; - VoidPtr MCastIpToMac; - VoidPtr NvData; - VoidPtr GetStatus; - EFI_SIMPLE_NETWORK_TRANSMIT Transmit; - EFI_SIMPLE_NETWORK_RECEIVE Receive; - VoidPtr WaitForPacket; - EFI_SIMPLE_NETWORK_MODE* Mode; -} EFI_SIMPLE_NETWORK_PROTOCOL; - -typedef struct EfiBitmask { - UInt32 RedMask; - UInt32 GreenMask; - UInt32 BlueMask; - UInt32 ReservedMask; -} EfiBitmask; - -typedef struct { - UInt8 Blue; - UInt8 Green; - UInt8 Red; - UInt8 Reserved; -} EfiGraphicsOutputBltPixel; - -typedef enum EfiGraphicsOutputProtocolBltOperation { - EfiBltVideoFill, - EfiBltVideoToBltBuffer, - EfiBltBufferToVideo, - EfiBltVideoToVideo, - EfiGraphicsOutputBltOperationMax -} EfiGraphicsOutputProtocolBltOperation; - -typedef struct EfiGraphicsOutputProtocolModeInformation { - UInt32 Version; - UInt32 HorizontalResolution; - UInt32 VerticalResolution; - UInt32 PixelFormat; - EfiBitmask PixelInformation; - UInt32 PixelsPerScanLine; -} EfiGraphicsOutputProtocolModeInformation; - -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolQueryMode)( - EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber, UInt32* SizeOfInfo, - EfiGraphicsOutputProtocolModeInformation** Info); - -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolSetMode)(EfiGraphicsOutputProtocol* Self, - UInt32 ModeNumber); - -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolBlt)( - EfiGraphicsOutputProtocol* Self, EfiGraphicsOutputBltPixel* BltBuffer, - EfiGraphicsOutputProtocolBltOperation BltOperation, UInt32 SourceX, UInt32 SourceY, - UInt32 DestinationX, UInt32 DestinationY, UInt32 Width, UInt32 Height, UInt32 Delta); - -typedef struct { - UInt32 MaxMode; - UInt32 Mode; - EfiGraphicsOutputProtocolModeInformation* Info; - UInt32 SizeOfInfo; - UIntPtr FrameBufferBase; - UInt32 FrameBufferSize; -} EfiGraphicsOutputProtocolMode; - -typedef struct EfiGraphicsOutputProtocol { - EfiGraphicsOutputProtocolQueryMode QueryMode; - EfiGraphicsOutputProtocolSetMode SetMode; - EfiGraphicsOutputProtocolBlt Blt; - EfiGraphicsOutputProtocolMode* Mode; -} EfiGraphicsOutputProtocol; - -typedef struct EfiLoadImageProtocol { - UInt32 Revision; - EfiHandlePtr ParentHandle; - EfiSystemTable* SystemTable; - - // Source location of the image - EfiHandlePtr DeviceHandle; - EfiDevicePathProtocol* FilePath; - Void* Reserved; - - // Image’s load options - UInt32 LoadOptionsSize; - Void* LoadOptions; - - // Location where image was loaded - Void* ImageBase; - UInt64 ImageSize; - EfiMemoryType ImageCodeType; - EfiMemoryType ImageDataType; - EfiImageUnload Unload; -} EfiLoadImageProtocol; - -typedef struct EfiLoadFileProtocol { - EfiLoadFile LoadFile; -} EfiLoadFileProtocol; - -typedef struct EfiDevicePathProtocol { - UInt8 Kind; - UInt8 SubType; - UInt8 Length[2]; -} EfiDevicePathProtocol; - -typedef struct EfiFileDevicePathProtocol { - EfiDevicePathProtocol Proto; - - /// - /// File Path of this struct - /// - WideChar Path[kPathLen]; -} EfiFileDevicePathProtocol; - -typedef UInt64(EFI_API* EfiExitBootServices)(VoidPtr ImageHandle, UInt32 MapKey); - -typedef UInt64(EFI_API* EfiAllocatePages)(EfiAllocateType AllocType, EfiMemoryType MemType, - UInt32 Count, EfiPhysicalAddress* Memory); - -typedef UInt64(EFI_API* EfiFreePages)(EfiPhysicalAddress* Memory, UInt32 Pages); - -typedef UInt64(EFI_API* EfiGetMemoryMap)(UInt32* MapSize, EfiMemoryDescriptor* DescPtr, - UInt32* MapKey, UInt32* DescSize, UInt32* DescVersion); - -/** - * @brief GUID type, something you can also find in CFKit. - */ -typedef struct EFI_GUID EFI_FINAL { - UInt32 Data1; - UInt16 Data2; - UInt16 Data3; - UInt8 Data4[8]; -} EFI_GUID; - -/*** - * Protocol stuff... - */ - -#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ - { \ - 0x387477c1, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -/** some helpers */ -#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 -#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 -#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 -#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 -#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 -#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 - -typedef UInt64(EFI_API* EfiLocateProtocol)(EFI_GUID* Protocol, VoidPtr Registration, - VoidPtr* Interface); - -typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EFI_GUID* Guid, VoidPtr* Interface, - EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle, - UInt32 Attributes); - -typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Boolean Visible); - -/** -@name EfiBootServices -@brief UEFI Boot Services record, it contains functions necessary to a -firmware level application. -*/ -typedef struct EfiBootServices { - EfiTableHeader SystemTable; - VoidPtr RaiseTPL; - VoidPtr RestoreTPL; - EfiAllocatePages AllocatePages; - EfiFreePages FreePages; - EfiGetMemoryMap GetMemoryMap; - EfiAllocatePool AllocatePool; - EfiFreePool FreePool; - VoidPtr CreateEvent; - VoidPtr SetTimer; - VoidPtr WaitForEvent; - VoidPtr SignalEvent; - VoidPtr CloseEvent; - VoidPtr CheckEvent; - VoidPtr InstallProtocolInterface; - VoidPtr ReinstallProtocolInterface; - VoidPtr UninstallProtocolInterface; - EfiHandleProtocol HandleProtocol; - VoidPtr Reserved; - VoidPtr RegisterProtocolNotify; - VoidPtr LocateHandle; - EfiLocateDevicePath LocateDevicePath; - VoidPtr InstallConfigurationTable; - EfiLoadImage LoadImage; - EfiStartImage StartImage; - VoidPtr Exit; - VoidPtr UnloadImage; - EfiExitBootServices ExitBootServices; - VoidPtr GetNextMonotonicCount; - VoidPtr Stall; - EfiStatusType(EFI_API* SetWatchdogTimer)(UInt32 Timeout, UInt64 WatchdogCode, UInt32 DataSize, - EfiCharType* Data); - VoidPtr ConnectController; - VoidPtr DriveonnectController; - EfiOpenProtocol OpenProtocol; - VoidPtr CloseProtocol; - VoidPtr OpenProtocolInformation; - VoidPtr ProtocolsPerHandle; - VoidPtr LocateHandleBuffer; - EfiLocateProtocol LocateProtocol; - VoidPtr InstallMultipleProtocolInterfaces; - VoidPtr UninstallMultipleProtocolInterfaces; - EfiCalculateCrc32 CalculateCrc32; - EfiCopyMem CopyMem; - EfiSetMem SetMem; - VoidPtr CreateEventEx; -} EfiBootServices; - -#define kEntireDevPath 0xFF -#define kThisInstancePath 0x01 - -/** -@brief PrintF like protocol. -*/ -typedef struct EfiSimpleTextOutputProtocol { - VoidPtr Reset; - EfiTextString OutputString; - VoidPtr TestString; - VoidPtr QueryMode; - VoidPtr SetMode; - EfiTextAttrib SetAttribute; - EfiTextClear ClearScreen; - VoidPtr SetCursorPosition; - EfiEnableCursor EnableCursor; - VoidPtr Mode; -} EfiSimpleTextOutputProtocol; - -typedef struct { - UInt16 ScanCode; - EfiChar16Type UnicodeChar; -} EfiInputKey; - -typedef EfiStatusType(EFI_API* EfiInputReadKey)(IN EfiSimpleTextInputProtocol* This, - OUT EfiInputKey* Key); - -typedef EfiStatusType(EFI_API* EfiInputReset)(IN EfiSimpleTextInputProtocol* This, - IN Boolean ExtendedChk); - -typedef EfiStatusType(EFI_API* EfiWaitForEvent)(IN UInt32 NumberOfEvents, IN VoidPtr Event, - OUT UInt32* Index); - -typedef struct EfiSimpleTextInputProtocol { - EfiInputReset Reset; - EfiInputReadKey ReadKeyStroke; - EfiWaitForEvent WaitForKey; -} EfiSimpleTextInputProtocol; - -/// @biref Open Volume procedure ptr. -typedef UInt64(EFI_API* EfiOpenVolume)(struct EfiSimpleFilesystemProtocol*, - struct EfiFileProtocol**); - -struct EfiSimpleFilesystemProtocol { - UInt64 Revision; - EfiOpenVolume OpenVolume; -}; - -typedef struct EfiRuntimeServices { - EfiTableHeader SystemTable; - VoidPtr GetTime, SetTime, GetWakeupTime, SetWakeupTime, SetVirtualAddressMap, ConvertPointer; - UInt64(EFI_API* GetVariable)(const WideChar* Name, EFI_GUID VendorGUID, UInt32* Attributes, - UInt32* DataSize, VoidPtr Data); - VoidPtr GetNextVariable; - UInt64(EFI_API* SetVariable)(const WideChar* Name, EFI_GUID VendorGUID, UInt32* Attributes, - UInt32* DataSize, VoidPtr Data); - VoidPtr GetNextHighMonotonicCount; - VoidPtr ResetSystem; - VoidPtr UpdateCapsule; - VoidPtr QueryCapsuleCapabilites; - VoidPtr QueryVariableInfo; -} EfiRuntimeServices; - -/** -@brief The Structure that they give you when booting. -*/ -typedef struct EfiSystemTable { - EfiTableHeader SystemHeader; - WideChar* FirmwareVendor; - UInt32 FirmwareRevision; - EfiHandlePtr ConsoleInHandle; - EfiSimpleTextInputProtocol* ConIn; - EfiHandlePtr ConsoleOutHandle; - EfiSimpleTextOutputProtocol* ConOut; - EfiHandlePtr StandardErrorHandle; - VoidPtr StdErr; - EfiRuntimeServices* RuntimeServices; - EfiBootServices* BootServices; - UInt64 NumberOfTableEntries; - /// The configuration table (contains the RSD PTR entry.) - struct { - EFI_GUID VendorGUID; - VoidPtr VendorTable; - } * ConfigurationTable; -} EfiSystemTable; - -#define kEfiOk 0 -#define kEfiFail -1 -#define kBufferTooSmall 5 - -#define EFI_EXTERN_C extern "C" - -typedef struct EfiIPV4 { - UInt8 Addr[4]; -} EfiIPV4; - -/// -/// 16-byte buffer. An IPv6 internet protocol address. -/// -typedef struct EfiIPV6 { - UInt8 Addr[16]; -} EfiIPV6; - -#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08) - -#ifdef __x86_64 -#define __EFI_x86_64__ 1 -#endif // __x86_64 - -enum { - kEFIHwDevicePath = 0x01, - kEFIAcpiDevicePath = 0x02, - kEFIMessaingDevicePath = 0x03, - kEFIMediaDevicePath = 0x04, - kEFIBiosBootPath = 0x05, - kEFIEndOfPath = 0x06, - kEFICount = 6, -}; - -#define END_DEVICE_PATH_TYPE 0x7f -#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF -#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 - -#define kEfiOffsetOf(T, F) __builtin_offsetof(T, F) - -/// File I/O macros - -#define kEFIFileRead 0x0000000000000001 -#define kEFIFileWrite 0x0000000000000002 -#define kEFIFileCreate 0x0000000000000000 - -#define kEFIReadOnly 0x01 -#define kEFIHidden 0x02 -#define kEFISystem 0x04 -#define kEFIReserved 0x08 -#define kEFIDirectory 0x10 -#define kEFIArchive 0x20 - -#define EFI_FILE_PROTOCOL_REVISION 0x00010000 -#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 -#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2 - -#define EFI_EXTRA_DESCRIPTOR_SIZE 8 - -#define EFI_MP_SERVICES_PROTOCOL_GUID \ - { \ - 0x3fdda605, 0xa76e, 0x4f46, { 0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08 } \ - } - -#define PROCESSOR_AS_BSP_BIT 0x00000001 -#define PROCESSOR_ENABLED_BIT 0x00000002 -#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004 - -#define END_OF_CPU_LIST 0xffffffff - -typedef struct EfiIOToken { - // - // If Event is NULL, then blocking I/O is performed. - // If Event is not NULL and non-blocking I/O is supported, then non-blocking - // I/O is performed, and Event will be signaled when the read request is - // completed. The caller must be prepared to handle the case where the - // callback associated with Event occurs before the original asynchronous I/O - // request call returns. - // - UInt64 Event; - - // - // Defines whether or not the signaled event encountered an error. - // - UInt64 Status; - - // - // For OpenEx(): Not Used, ignored. - // For ReadEx(): On input, the size of the Buffer. On output, the amount of - // data returned in Buffer. - // In both cases, the size is measured in bytes. - // For WriteEx(): On input, the size of the Buffer. On output, the amount of - // data actually written. - // In both cases, the size is measured in bytes. - // For FlushEx(): Not used, ignored. - // - UInt32 BufferSize; - - // - // For OpenEx(): Not Used, ignored. - // For ReadEx(): The buffer into which the data is read. - // For WriteEx(): The buffer of data to write. - // For FlushEx(): Not Used, ignored. - // - Void* Buffer; -} EfiIOToken; - -typedef struct EfiFileProtocol { - UInt64 Revision; - - EfiStatusType(EFI_API* Open)(struct EfiFileProtocol* Self, struct EfiFileProtocol** Out, - EfiCharType* CharType, UInt64 OpenMode, UInt64 Attrib); - - EfiStatusType(EFI_API* Close)(struct EfiFileProtocol* Self); - - EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self); - - EfiStatusType(EFI_API* Read)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); - - EfiStatusType(EFI_API* Write)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); - - EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position); - - EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position); - - EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EFI_GUID*, UInt32*, void*); - - EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EFI_GUID*, UInt32*, void*); - - EfiStatusType(EFI_API* Flush)(EfiFileProtocol*); - - EfiStatusType(EFI_API* OpenEx)(EfiFileProtocol* Self, EfiFileProtocol** OutHandle, - EfiCharType* Path, UInt64 Mode, UInt64 Attrib, - struct EfiIOToken* Token); - - EfiStatusType(EFI_API* ReadEx)(EfiFileProtocol* Self, struct EfiIOToken* Token); - - EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self, struct EfiIOToken* Token); - - EfiStatusType(EFI_API* FlushEx)(EfiFileProtocol* Self, struct EfiIOToken* Token); -} EfiFileProtocol, *EfiFileProtocolPtr; - -typedef UInt64 EfiCursorType; - -typedef struct EfiTime { - UInt16 Year; - UInt8 Month; - UInt8 Day; - UInt8 Hour; - UInt8 Minute; - UInt8 Second; - UInt8 Pad1; - UInt32 Nanosecond; - Int16 TimeZone; - UInt8 Daylight; - UInt8 Pad2; -} EfiTime; - -#define EFI_FILE_INFO_GUID \ - { \ - 0x09576e92, 0x6d3f, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -struct EfiFileInfo EFI_FINAL { - /// @brief Structure size. - UInt64 Size; - /// @brief File size. - UInt64 FileSize; - /// @brief Physical size on disk. - UInt64 PhysicalSize; - /// @brief Create time. - EfiTime CreateTime; - /// @brief Last access time. - EfiTime LastAccessTime; - /// @brief Edit time. - EfiTime EditTime; - /// @brief Attributes. - UInt64 Attribute; - /// @brief VLA file name. - WideChar FileName[1]; -}; - -//******************************************************* -// EFI_CPU_PHYSICAL_LOCATION -// @note As in the EFI specs. -//******************************************************* -typedef struct _EfiCPUPhyiscalLocation { - UInt32 Package; - UInt32 Core; - UInt32 Thread; -} EfiCPUPhyiscalLocation; - -typedef union _EfiExtendedProcessorInformation { - EfiCPUPhyiscalLocation Location2; -} EfiExtendedProcessorInformation; - -typedef struct _EfiProcessorInformation { - UInt64 ProcessorId; - UInt32 StatusFlag; - EfiCPUPhyiscalLocation Location; - EfiExtendedProcessorInformation ExtendedInformation; -} EfiProcessorInformation; - -typedef EfiStatusType EFI_API (*EfiMpServicesGetNumberOfProcessors)( - IN struct _EfiMpServicesProtocol* Self, OUT UInt32* NumberOfProcessors, - OUT UInt32* NumberOfEnabledProcessors); - -typedef EfiStatusType EFI_API (*EfiMpServicesGetProcessorInfo)( - IN struct _EfiMpServicesProtocol* Self, IN UInt32* ProcessorNumber, - OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors); - -typedef void EFI_API (*EFI_AP_PROCEDURE)(IN VoidPtr ProcedureArgument); - -typedef EfiStatusType EFI_API (*EfiMpServicesStartupAllAPS)( - IN struct _EfiMpServicesProtocol* Self, IN EFI_AP_PROCEDURE Procedure, IN Boolean SingleThread, - IN VoidPtr WaitEvent OPTIONAL, // EFI_EVENT first, but unused here. - IN UInt32 TimeoutInMicroSeconds, IN Void* ProcedureArgument OPTIONAL, - OUT UInt32** FailedCpuList OPTIONAL); - -typedef EfiStatusType EFI_API (*EfiMpServicesSwitchBSP)(IN struct _EfiMpServicesProtocol* Self, - IN UInt32 ProcessorNumber, - IN Boolean EnableOldBSP); - -typedef EfiStatusType EFI_API (*EfiMpServicesStartupThisAP)( - IN struct _EfiMpServicesProtocol* Self, IN EFI_AP_PROCEDURE Procedure, - IN UInt32 ProcessorNumber, IN VoidPtr WaitEvent OPTIONAL, IN UInt32 TimeoutInMicroseconds, - IN Void* ProcedureArgument OPTIONAL, OUT Boolean* Finished OPTIONAL); - -typedef EfiStatusType EFI_API (*EfiMpServicesDisableThisAP)(IN struct _EfiMpServicesProtocol* Self, - IN UInt32 ProcessorNumber, - IN Boolean EnableAP, - IN UInt32* HealthFlag OPTIONAL); - -typedef EfiStatusType EFI_API (*EfiMpServicesWhoAmI)(IN struct _EfiMpServicesProtocol* Self, - OUT UInt32* ProcessorNumber); - -typedef struct _EfiMpServicesProtocol { - EfiMpServicesGetNumberOfProcessors GetNumberOfProcessors; - EfiMpServicesGetProcessorInfo GetProcessorInfo; - EfiMpServicesStartupAllAPS StartupAllAPs; - EfiMpServicesStartupThisAP StartupThisAP; - EfiMpServicesSwitchBSP SwitchBSP; - EfiMpServicesDisableThisAP EnableDisableAP; - EfiMpServicesWhoAmI WhoAmI; -} EfiMpServicesProtocol; - -#endif // ifndef FIRMWARE_KIT_EFI_H diff --git a/dev/kernel/FirmwareKit/EFI/NS.h b/dev/kernel/FirmwareKit/EFI/NS.h deleted file mode 100644 index 64e59870..00000000 --- a/dev/kernel/FirmwareKit/EFI/NS.h +++ /dev/null @@ -1,18 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Firmware::Detail::EFI { -using namespace Kernel; - -EXTERN_C { -#include <FirmwareKit/EFI/EFI.h> -} - -} // namespace Firmware::Detail::EFI diff --git a/dev/kernel/FirmwareKit/EPM.h b/dev/kernel/FirmwareKit/EPM.h deleted file mode 100644 index 8df4d345..00000000 --- a/dev/kernel/FirmwareKit/EPM.h +++ /dev/null @@ -1,112 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - @brief The Explicit Partition Map scheme. -*/ - -#ifndef FIRMWAREKIT_EPM_H -#define FIRMWAREKIT_EPM_H - -#include <NeKit/Defines.h> - -#define kEPMNameLength (32) -#define kEPMFilesystemLength (16) -#define kEPMMagicLength (5) - -/* @brief AMD64 magic for EPM */ -#define kEPMMagic86 "EPMAM" - -/* @brief RISC-V magic for EPM */ -#define kEPMMagicRISCV "EPMRV" - -/* @brief ARM magic for EPM */ -#define kEPMMagicARM "EPMAR" - -/* @brief 64x0 magic for EPM */ -#define kEPMMagic64k "EPM64" - -/* @brief 32x0 magic for EPM */ -#define kEPMMagic32k "EPM32" - -/* @brief POWER magic for EPM */ -#define kEPMMagicPPC "EPMPC" - -/* @brief Invalid magic for EPM */ -#define kEPMMagicError "EPM??" - -#ifdef __NE_AMD64__ -#define kEPMMagic kEPMMagic86 -#else -#ifdef __NE_ARM64__ -#define kEPMMagic kEPMMagicARM -#else -#define kEPMMagic kEPMMagicError -#endif -#endif - -///! @brief partition must start at this address. -///! Anything below is reserved for Data backup by the Main OS. -#define kEPMPartBlockLba (sizeof(EPM_PART_BLOCK)) - -///! @brief Current EPM revision. -#define kEPMRevisionBcd (0x0100) - -/// !@brief EPM boot block address. -#define kEPMBootBlockLba (0U) - -#define kEPMReserveLen (399) - -struct EPM_GUID; -struct EPM_PART_BLOCK; - -/* The first 0 > 128 addresses of a disk contains these headers. */ - -/// @brief EPM GUID structure. -typedef struct EPM_GUID { - Kernel::UInt32 Data1; - Kernel::UInt16 Data2; - Kernel::UInt16 Data3; - Kernel::UInt8 Data4[8]; -} PACKED EPM_GUID; - -/** - * @brief The EPM boot block. - * @note NumBlock and LbaStart are ignored on some platforms. - */ -struct PACKED EPM_PART_BLOCK { - Kernel::Char Magic[kEPMMagicLength]; - Kernel::Char Name[kEPMNameLength]; - EPM_GUID Guid; - Kernel::Int32 Version; - Kernel::Int64 NumBlocks; - Kernel::Int64 SectorSz; - Kernel::Int64 LbaStart; // base offset - Kernel::Int64 LbaEnd; // end offset - Kernel::Int16 Kind; - Kernel::Int16 Flags; - Kernel::Int32 FsVersion; - Kernel::Char Fs[kEPMFilesystemLength]; /* NeFS, OpenHeFS... */ - Kernel::Char Reserved[kEPMReserveLen]; // to fill a full sector. -}; - -///! @brief Version kind enum. -///! @brief Use in boot block version field. - -enum { - kEPMInvalid = 0x00, - kEPMGeneric = 0xcf, /// @brief Generic OS - kEPMLinux = 0x8f, /// @brief Linux on EPM. - kEPMBSD = 0x9f, /// @brief BSD on EPM. - kEPMNeKernel = 0x1f, /// @brief NeKernel. - kEPMLegacy = 0x2f, /// @brief Legacy VMKernel. - /// @note ... the rest is reserved for future OSes. - kEPMInvalidOS = 0xff, -}; - -inline EPM_GUID kEPMNilGuid = {0x0U, 0x0U, 0x0U, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; - -#endif // ifndef FIRMWAREKIT_EPM_H diff --git a/dev/kernel/FirmwareKit/GPT.h b/dev/kernel/FirmwareKit/GPT.h deleted file mode 100644 index 1772cc79..00000000 --- a/dev/kernel/FirmwareKit/GPT.h +++ /dev/null @@ -1,48 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <FirmwareKit/EFI/EFI.h> -#include <NeKit/Defines.h> - -#define kSectorAlignGPT_PartTbl (420U) -#define kSectorAlignGPT_PartEntry (72U) -#define kMagicLenGPT (8U) -#define kMagicGPT ("EFI PART") // "EFI PART" -#define kGPTPartitionTableLBA (512U + sizeof(GPT_PARTITION_TABLE)) - -namespace Kernel { -struct GPT_PARTITION_TABLE; -struct GPT_PARTITION_ENTRY; - -struct PACKED GPT_PARTITION_TABLE final { - Char Signature[kMagicLenGPT]; - UInt32 Revision; - UInt32 HeaderSize; - UInt32 CRC32; - UInt32 Reserved1; - UInt64 LBAHeader; - UInt64 LBAAltHeader; - UInt64 FirstGPTEntry; - UInt64 LastGPTEntry; - EFI_GUID Guid; - UInt64 StartingLBA; - UInt32 NumPartitionEntries; - UInt32 SizeOfEntries; - UInt32 CRC32PartEntry; - UInt8 Reserved2[kSectorAlignGPT_PartTbl]; -}; - -struct PACKED GPT_PARTITION_ENTRY { - EFI_GUID PartitionTypeGUID; - EFI_GUID UniquePartitionGUID; - UInt64 StartLBA; - UInt64 EndLBA; - UInt64 Attributes; - UInt8 Name[kSectorAlignGPT_PartEntry]; -}; -} // namespace Kernel diff --git a/dev/kernel/FirmwareKit/Handover.h b/dev/kernel/FirmwareKit/Handover.h deleted file mode 100644 index 354b6e57..00000000 --- a/dev/kernel/FirmwareKit/Handover.h +++ /dev/null @@ -1,108 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @file Handover.h - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief The handover boot protocol. - * @version 1.15 - * @date 2024-02-23 - * - * @copyright Copyright (c) 2024, Amlal El Mahrouss - * - */ - -#pragma once - -#include <FirmwareKit/EFI/EFI.h> -#include <NeKit/Defines.h> - -#define kHandoverMagic (0xBADCC) -#define kHandoverVersion (0x0117) - -/* Initial bitmap pointer location and size. */ -#define kHandoverBitMapSz (gib_cast(4)) -#define kHandoverStructSz sizeof(HEL::BootInfoHeader) - -namespace Kernel::HEL { -/** -@brief The executable type enum. -*/ -enum { - kTypeKernel = 100, - kTypeKernelDriver = 101, - kTypeRsrc = 102, - kTypeInvalid = 103, - kTypeCount = 4, -}; - -/** -@brief The executable architecture enum. -*/ - -enum { - kArchAMD64 = 122, - kArchARM64 = 123, - kArchRISCV = 124, - kArchCount = 3, -}; - -struct BootInfoHeader final { - UInt64 f_Magic; - UInt64 f_Version; - - VoidPtr f_BitMapStart; - SizeT f_BitMapSize; - - VoidPtr f_PageStart; - - VoidPtr f_KernelImage; - SizeT f_KernelSz; - - VoidPtr f_LibSystemImage; - SizeT f_LibSystemSz; - - VoidPtr f_StackTop; - SizeT f_StackSz; - - WideChar f_FirmwareVendorName[32]; - SizeT f_FirmwareVendorLen; - - VoidPtr f_FirmwareCustomTables[2]; // On EFI 0: BS 1: ST - - struct { - VoidPtr f_SmBios; - VoidPtr f_VendorPtr; - VoidPtr f_MpPtr; - Bool f_MultiProcessingEnabled; - UInt32 f_ImageKey; - EfiHandlePtr f_ImageHandle; - } f_HardwareTables; - - struct { - UIntPtr f_The; - SizeT f_Size; - UInt32 f_Width; - UInt32 f_Height; - UInt32 f_PixelFormat; - UInt32 f_PixelPerLine; - } f_GOP; - - UInt64 f_FirmwareSpecific[8]; -}; - -enum { - kHandoverTableBS, - kHandoverTableST, - kHandoverTableCount, -}; - -/// @brief Alias of bootloader main type. -typedef Int32 (*HandoverProc)(BootInfoHeader* boot_info); -} // namespace Kernel::HEL - -/// @brief Bootloader information header global variable. -inline Kernel::HEL::BootInfoHeader* kHandoverHeader = nullptr; diff --git a/dev/kernel/FirmwareKit/NeBoot/BootNet.h b/dev/kernel/FirmwareKit/NeBoot/BootNet.h deleted file mode 100644 index 3637bab0..00000000 --- a/dev/kernel/FirmwareKit/NeBoot/BootNet.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -#define kBootNetINetMagic "ONET" -#define kBootNetINetMagicLength (4) -#define kBootNetVersion (0x001) -#define kBootNetNameLen (256U) - -struct _BOOTNET_INTERNET_HEADER; - -/// @brief Netboot Internet Header -/// Consists of 4 magic characters, and a set of fields describing the current patch that's being -/// sent (if m_preflight = 0) -/// @note Can be used to patch ROMs too (if ImpliesProgram = 1) -typedef struct _BOOTNET_INTERNET_HEADER { - Kernel::Char NB1; /// magic char 1 'O' - Kernel::Char NB2; /// magic char 2 'N' - Kernel::Char NB3; /// magic char 3 'E' - Kernel::Char NB4; /// magic char 4 'T' - - Kernel::UInt16 Version; - - Kernel::Char Name[kBootNetNameLen]; /// example: Modjo - - Kernel::Int32 Length; /// the patch length. - Kernel::Char Target[kBootNetNameLen]; /// the target file. - - Kernel::Boolean ImpliesProgram : 1; /// does it imply reprogramming? - - Kernel::Boolean Preflight : 1; /// is it a preflight packet. - Kernel::Char Data[1]; /// non preflight packet has a patch blob for a **PatchTarget** -} PACKED BOOTNET_INTERNET_HEADER; - -using BOOTNET_INTERNET_HEADER_PTR = BOOTNET_INTERNET_HEADER*; diff --git a/dev/kernel/FirmwareKit/NeBoot/NS.h b/dev/kernel/FirmwareKit/NeBoot/NS.h deleted file mode 100644 index 3a6bed6d..00000000 --- a/dev/kernel/FirmwareKit/NeBoot/NS.h +++ /dev/null @@ -1,10 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <FirmwareKit/NeBoot/BootNet.h> -#include <FirmwareKit/NeBoot/NeBoot.h>
\ No newline at end of file diff --git a/dev/kernel/FirmwareKit/NeBoot/NeBoot.h b/dev/kernel/FirmwareKit/NeBoot/NeBoot.h deleted file mode 100644 index 8e8fd87f..00000000 --- a/dev/kernel/FirmwareKit/NeBoot/NeBoot.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Firmware::Detail::NeBoot { -using namespace Kernel; - -struct NEBOOT_LINEAR_EXEC; - -/// @brief Linear Executable Header -/// @author Amlal El Mahrouss -struct ATTRIBUTE(aligned(4)) NEBOOT_LINEAR_EXEC { - const Char fMagic[2]; // magic number - const Char fName[10]; // operating system name - const UInt32 fRevision; // firmware revision - const UInt32 fStartAddress; // start address (master/slave(s) thread) - -#ifdef NE_IS_EXTENDED_COREBOOT - UIntPtr fMasterStructure; // master structure for MP/PM and device tree and such. (ARM) - UIntPtr fMasterStructureVersion; // master structure version. -#endif - -#ifdef NE_IS_MBCI_COREBOOT - UIntPtr fMBCIStructure; // MBCI structure for MBCI (ARM) - UIntPtr fMBCIStructureVersion; // MBCI structure version. -#endif -}; -} // namespace Firmware::Detail::NeBoot diff --git a/dev/kernel/FirmwareKit/VEPM.h b/dev/kernel/FirmwareKit/VEPM.h deleted file mode 100644 index b2bee0d3..00000000 --- a/dev/kernel/FirmwareKit/VEPM.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef FIRMWAREKIT_VEPM_H -#define FIRMWAREKIT_VEPM_H - -#include <FirmwareKit/EFI.h> -#include <FirmwareKit/EPM.h> - -/// =========================================================== /// -/// @brief The Virtual Explicit Partition Map scheme extension. -/// =========================================================== /// - -#if defined(__NE_VEPM__) -#ifdef kEPMMagic -#undef kEPMMagic -#endif // kEPMMagic - -/// =========================================================== /// -/// @brief VEPM Ident String. -/// =========================================================== /// -#define kEPMMagic "EPMVM" - -/// =========================================================== /// -/// @brief VEPM GUID. -/// @note This is the GUID used to identify a VEPM partition. -/// =========================================================== /// -inline EPM_GUID kVEPMGuidEPM = { - 0x9a1b3f2e, 0x4c3f, 0x4d52, {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}}; - -/// =========================================================== /// -/// @brief VEPM GUID. -/// @note This is the GUID used to identify a VEPM partition (EFI version) -/// =========================================================== /// -inline EFI_GUID kVEPMGuidEFI = { - 0x9a1b3f2e, 0x4c3f, 0x4d52, {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}}; - -/// =========================================================== /// -/// @brief VEPM GUID String. -/// =========================================================== /// -#define kVEPMGuidStr "9a1b3f2e-4c3f-4d52-a783-9c217b5e4dac" -#endif // __NE_VEPM__ - -#endif // FIRMWAREKIT_VEPM_H
\ No newline at end of file diff --git a/dev/kernel/GfxKit/FB.h b/dev/kernel/GfxKit/FB.h deleted file mode 100644 index c8a2dc4b..00000000 --- a/dev/kernel/GfxKit/FB.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DeviceMgr.h> - -namespace Kernel { -class FBDeviceInterface; -struct FBDevicePacket; - -typedef UInt32 FBCoord2x2; -typedef UInt32 FBDim2x2; -typedef UInt32 FBColorProfile; -typedef UInt32 FBFlags; - -/// @brief Framebuffer device interface packet. -/// @details This structure is used to send and receive data from the framebuffer device. -/// @note The structure is packed to ensure that the data is aligned correctly for the device. -struct PACKED FBDevicePacket final { - FBCoord2x2 fX; - FBCoord2x2 fY; - FBDim2x2 fWidth; - FBDim2x2 fHeight; - FBColorProfile fColor; - FBFlags fFlags; -}; - -/// @brief Framebuffer device interface. -/// @details This class is used to send and receive data from the framebuffer device. -/// @note The class is derived from the DeviceInterface class. -class FBDeviceInterface NE_DEVICE<FBDevicePacket*> { - public: - explicit FBDeviceInterface(void (*out)(DeviceInterface* self, FBDevicePacket* out), - void (*in)(DeviceInterface* self, FBDevicePacket* in)); - - virtual ~FBDeviceInterface() override; - - public: - FBDeviceInterface& operator=(const FBDeviceInterface&) = default; - FBDeviceInterface(const FBDeviceInterface&) = default; - - const Char* Name() const override; - - public: - FBDeviceInterface& operator<<(FBDevicePacket* dat) override; - FBDeviceInterface& operator>>(FBDevicePacket* dat) override; -}; -} // namespace Kernel diff --git a/dev/kernel/HALKit/.gitkeep b/dev/kernel/HALKit/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/AMD64/CPUID.h b/dev/kernel/HALKit/AMD64/CPUID.h deleted file mode 100644 index 0ab95c07..00000000 --- a/dev/kernel/HALKit/AMD64/CPUID.h +++ /dev/null @@ -1,89 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: CPUID.h - Purpose: CPUID flags. - - Revision History: - - 30/01/24: Added file (amlel) - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -EXTERN_C { -#include <cpuid.h> -} - -namespace Kernel { - -enum { - kCPUFeatureSSE3 = 1 << 0, - kCPUFeaturePCLMUL = 1 << 1, - kCPUFeatureDTES64 = 1 << 2, - kCPUFeatureMONITOR = 1 << 3, - kCPUFeatureDS_CPL = 1 << 4, - kCPUFeatureVMX = 1 << 5, - kCPUFeatureSMX = 1 << 6, - kCPUFeatureEST = 1 << 7, - kCPUFeatureTM2 = 1 << 8, - kCPUFeatureSSSE3 = 1 << 9, - kCPUFeatureCID = 1 << 10, - kCPUFeatureSDBG = 1 << 11, - kCPUFeatureFMA = 1 << 12, - kCPUFeatureCX16 = 1 << 13, - kCPUFeatureXTPR = 1 << 14, - kCPUFeaturePDCM = 1 << 15, - kCPUFeaturePCID = 1 << 17, - kCPUFeatureDCA = 1 << 18, - kCPUFeatureSSE4_1 = 1 << 19, - kCPUFeatureSSE4_2 = 1 << 20, - kCPUFeatureX2APIC = 1 << 21, - kCPUFeatureMOVBE = 1 << 22, - kCPUFeaturePOP3C = 1 << 23, - kCPUFeatureECXTSC = 1 << 24, - kCPUFeatureAES = 1 << 25, - kCPUFeatureXSAVE = 1 << 26, - kCPUFeatureOSXSAVE = 1 << 27, - kCPUFeatureAVX = 1 << 28, - kCPUFeatureF16C = 1 << 29, - kCPUFeatureRDRAND = 1 << 30, - kCPUFeatureHYPERVISOR = 1 << 31, - kCPUFeatureFPU = 1 << 0, - kCPUFeatureVME = 1 << 1, - kCPUFeatureDE = 1 << 2, - kCPUFeaturePSE = 1 << 3, - kCPUFeatureEDXTSC = 1 << 4, - kCPUFeatureMSR = 1 << 5, - kCPUFeaturePAE = 1 << 6, - kCPUFeatureMCE = 1 << 7, - kCPUFeatureCX8 = 1 << 8, - kCPUFeatureAPIC = 1 << 9, - kCPUFeatureSEP = 1 << 11, - kCPUFeatureMTRR = 1 << 12, - kCPUFeaturePGE = 1 << 13, - kCPUFeatureMCA = 1 << 14, - kCPUFeatureCMOV = 1 << 15, - kCPUFeaturePAT = 1 << 16, - kCPUFeaturePSE36 = 1 << 17, - kCPUFeaturePSN = 1 << 18, - kCPUFeatureCLFLUSH = 1 << 19, - kCPUFeatureDS = 1 << 21, - kCPUFeatureACPI = 1 << 22, - kCPUFeatureMMX = 1 << 23, - kCPUFeatureFXSR = 1 << 24, - kCPUFeatureSSE = 1 << 25, - kCPUFeatureSSE2 = 1 << 26, - kCPUFeatureSS = 1 << 27, - kCPUFeatureHTT = 1 << 28, - kCPUFeatureTM = 1 << 29, - kCPUFeatureIA64 = 1 << 30, - kCPUFeaturePBE = 1 << 31 -}; - -typedef Int64 CPUID; -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/CxxAbi.cc b/dev/kernel/HALKit/AMD64/CxxAbi.cc deleted file mode 100644 index 9049457b..00000000 --- a/dev/kernel/HALKit/AMD64/CxxAbi.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DebugOutput.h> -#include <KernelKit/KPC.h> -#include <KernelKit/UserProcessScheduler.h> -#include <NeKit/CxxAbi.h> - -atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; - -uarch_t __atexit_func_count; - -/// @brief dynamic shared object Handle. -Kernel::UIntPtr __dso_handle; - -EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) { - (Kernel::Void)(Kernel::kout << "object: " - << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self))); - (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); -} - -EXTERN_C void ___chkstk_ms(PtrDiff frame_size) { - char* sp; - asm volatile("mov %%rsp, %0" : "=r"(sp)); - - for (PtrDiff offset = kPageSize; offset < frame_size; offset += kPageSize) { - sp[-offset] = 0; - } -} - -EXTERN_C int atexit(void (*f)()) { - if (__atexit_func_count >= kAtExitMacDestructors) return 1; - - __atexit_funcs[__atexit_func_count].destructor_func = f; - - __atexit_func_count++; - - return 0; -} - -EXTERN_C void __cxa_finalize(void* f) { - uarch_t i = __atexit_func_count; - if (!f) { - while (i--) { - if (__atexit_funcs[i].destructor_func) { - (*__atexit_funcs[i].destructor_func)(); - }; - } - - return; - } - - while (i--) { - if (__atexit_funcs[i].destructor_func) { - (*__atexit_funcs[i].destructor_func)(); - __atexit_funcs[i].destructor_func = 0; - }; - } -} - -namespace cxxabiv1 { -EXTERN_C int __cxa_guard_acquire(__guard g) { - if ((*g & 1) || (*g & 2)) return 1; - *g |= 2; - return 0; -} - -EXTERN_C void __cxa_guard_release(__guard g) { - *g |= 1; - *g &= 2; -} - -EXTERN_C void __cxa_guard_abort(__guard g) { - *g &= ~2; -} -} // namespace cxxabiv1 diff --git a/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc deleted file mode 100644 index 83545df8..00000000 --- a/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <HALKit/AMD64/Processor.h> -#include <KernelKit/HeapMgr.h> -#include <NeKit/KString.h> -#include <modules/ACPI/ACPIFactoryInterface.h> - -namespace Kernel { -namespace Detail { - struct FADT final : public SDT { - UInt32 FirmwareCtrl; - UInt32 Dsdt; - - // field used in ACPI 1.0; no longer in use, for compatibility only - UInt8 Reserved; - - UInt8 PreferredPowerManagementProfile; - UInt16 SCI_Interrupt; - UInt32 SMI_CommandPort; - UInt8 AcpiEnable; - UInt8 AcpiDisable; - UInt8 S4BIOS_REQ; - UInt8 PSTATE_Control; - UInt32 PM1aEventBlock; - UInt32 PM1bEventBlock; - UInt32 PM1aControlBlock; - UInt32 PM1bControlBlock; - UInt32 PM2ControlBlock; - UInt32 PMTimerBlock; - UInt32 GPE0Block; - UInt32 GPE1Block; - UInt8 PM1EventLength; - UInt8 PM1ControlLength; - UInt8 PM2ControlLength; - UInt8 PMTimerLength; - UInt8 GPE0Length; - UInt8 GPE1Length; - UInt8 GPE1Base; - UInt8 CStateControl; - UInt16 WorstC2Latency; - UInt16 WorstC3Latency; - UInt16 FlushSize; - UInt16 FlushStride; - UInt8 DutyOffset; - UInt8 DutyWidth; - UInt8 DayAlarm; - UInt8 MonthAlarm; - UInt8 Century; - - // reserved in ACPI 1.0; used since ACPI 2.0+ - UInt16 BootArchitecturkMMFlags; - - UInt8 Reserved2; - UInt32 Flags; - - // 12 byte structure; see below for details - ACPI_ADDRESS ResetReg; - - UInt8 ResetValue; - UInt8 Reserved3[3]; - - // 64bit pointers - Available on ACPI 2.0+ - UInt64 X_FirmwareControl; - UInt64 X_Dsdt; - - ACPI_ADDRESS X_PM1aEventBlock; - ACPI_ADDRESS X_PM1bEventBlock; - ACPI_ADDRESS X_PM1aControlBlock; - ACPI_ADDRESS X_PM1bControlBlock; - ACPI_ADDRESS X_PM2ControlBlock; - ACPI_ADDRESS X_PMTimerBlock; - ACPI_ADDRESS X_GPE0Block; - ACPI_ADDRESS X_GPE1Block; - }; -} // namespace Detail - -ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {} - -Bool ACPIFactoryInterface::Shutdown() { - return NO; -} - -/// @brief Reboot machine in either ACPI or by triple faulting. -/// @return nothing it's a reboot. -Void ACPIFactoryInterface::Reboot() { - asm volatile( - ".intel_syntax noprefix; " - "rt_reset_hardware:; " - "cli; " - "wait_gate1: ; " - "in al,0x64 ; " - "and al,2 ; " - "jnz wait_gate1 ; " - "mov al,0x0D1 ; " - "out 0x64,al ; " - "wait_gate2: ; " - "in al,0x64 ; " - "and al,2 ; " - "jnz wait_gate2 ; " - "mov al,0x0FE ; " - "out 0x60,al ; " - "xor rax,rax ; " - "lidt [rax] ; " - "reset_wait: ; " - "jmp reset_wait ; " - ".att_syntax; "); -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc b/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc deleted file mode 100644 index 36a027a2..00000000 --- a/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <HALKit/AMD64/Processor.h> -#include <modules/ACPI/ACPIFactoryInterface.h> - -namespace Kernel::HAL { -/***********************************************************************************/ -/// Constructors. -/***********************************************************************************/ -LAPICDmaWrapper::LAPICDmaWrapper(VoidPtr base) : fApic(base) {} -LAPICDmaWrapper::~LAPICDmaWrapper() = default; - -/***********************************************************************************/ -/// @brief Read from APIC controller. -/// @param reg register. -/***********************************************************************************/ -UInt32 LAPICDmaWrapper::Read(UInt16 reg) noexcept { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - return io_apic[reg]; -} - -/***********************************************************************************/ -/// @brief Write to APIC controller. -/// @param reg register. -/// @param value value. -/***********************************************************************************/ -Void LAPICDmaWrapper::Write(UInt16 reg, UInt32 value) noexcept { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - io_apic[reg] = value; -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc deleted file mode 100644 index 5a530457..00000000 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ /dev/null @@ -1,221 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/// Different than the MADT, might be confusing to some. -#define APIC_MAG "APIC" - -#define APIC_ICR_LOW 0x300 -#define APIC_ICR_HIGH 0x310 -#define APIC_SIPI_VEC 0x00500 -#define APIC_EIPI_VEC 0x00400 - -#define LAPIC_REG_TIMER_LVT 0x320 -#define LAPIC_REG_TIMER_INITCNT 0x380 -#define LAPIC_REG_TIMER_CURRCNT 0x390 -#define LAPIC_REG_TIMER_DIV 0x3E0 -#define LAPIC_REG_ENABLE 0x80 -#define LAPIC_REG_SPURIOUS 0xF0 - -#define APIC_BASE_MSR 0x1B -#define APIC_BASE_MSR_BSP 0x100 -#define APIC_BASE_MSR_ENABLE 0x800 - -#include <ArchKit/ArchKit.h> -#include <HALKit/AMD64/Processor.h> -#include <KernelKit/BinaryMutex.h> -#include <KernelKit/HardwareThreadScheduler.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/Timer.h> -#include <NeKit/KernelPanic.h> -#include <modules/ACPI/ACPIFactoryInterface.h> -#include <modules/CoreGfx/TextGfx.h> - -/////////////////////////////////////////////////////////////////////////////////////// - -/// @note: _hal_switch_context is internal. -/// @brief The **HAL** namespace. - -/////////////////////////////////////////////////////////////////////////////////////// - -namespace Kernel::HAL { -struct HAL_APIC_MADT; -struct HAL_HARDWARE_THREAD; - -struct HAL_HARDWARE_THREAD final { - StackFramePtr mFramePtr; - ProcessID mThreadID{0}; -}; - -EXTERN_C Void sched_jump_to_task(StackFramePtr stack_frame); - -STATIC HAL_APIC_MADT* kSMPBlock = nullptr; -STATIC Bool kSMPAware = false; -STATIC Int64 kSMPCount = 0; - -EXTERN_C UIntPtr kApicBaseAddress; - -STATIC Int32 kSMPInterrupt = 0; -STATIC UInt64 kAPICLocales[kMaxAPInsideSched] = {0}; -STATIC VoidPtr kRawMADT = nullptr; - -STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; - -/// @brief Multiple APIC Descriptor Table. -struct HAL_APIC_MADT final SDT_OBJECT { - UInt32 Address; // Madt address - UInt32 Flags; // Madt flags - UInt8 List[1]; // Records List -}; - -/// @brief Local APIC Descriptor Table. -struct LAPIC final { - UInt8 Type; - UInt8 Length; - UInt8 ProcessorID; - UInt8 APICID; - UInt32 Flags; -}; - -/////////////////////////////////////////////////////////////////////////////////////// - -/***********************************************************************************/ -/// @brief Send end IPI for CPU. -/// @param apic_id -/// @param vector -/// @param target -/// @return -/***********************************************************************************/ -EXTERN_C Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) { - Kernel::ke_dma_write<UInt32>(target, APIC_ICR_HIGH, apic_id << 24); - Kernel::ke_dma_write<UInt32>(target, APIC_ICR_LOW, 0x00000600 | 0x00004000 | 0x00000000 | vector); - - while (Kernel::ke_dma_read<UInt32>(target, APIC_ICR_LOW) & 0x1000) { - NE_UNUSED(0); - } -} - -/***********************************************************************************/ -/// @brief Get current stack frame for a thread. -/// @param thrdid The thread ID. -/***********************************************************************************/ - -EXTERN_C HAL::StackFramePtr mp_get_current_task(ThreadID thrdid) { - if (thrdid > kSMPCount) return nullptr; - return kHWThread[thrdid].mFramePtr; -} - -/***********************************************************************************/ -/// @brief Register current stack frame for a thread. -/// @param stack_frame The current stack frame. -/// @param thrdid The thread ID. -/***********************************************************************************/ - -EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ThreadID thrdid) { - if (!stack_frame) return NO; - - if (!kSMPAware) { - sched_jump_to_task(kHWThread[thrdid].mFramePtr); - return YES; - } - - if (thrdid > kSMPCount) return NO; - - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - kHWThread[thrdid].mFramePtr = stack_frame; - - return YES; -} - -/***********************************************************************************/ -/// @brief Is the current config SMP aware? -/// @return True if YES, False if not. -/***********************************************************************************/ - -Bool mp_is_smp(Void) noexcept { - return kSMPAware; -} - -/***********************************************************************************/ -/// @brief Fetch and enable SMP scheduler. -/// @param vendor_ptr SMP containing structure. -/***********************************************************************************/ - -Void mp_init_cores(VoidPtr vendor_ptr) noexcept { - if (!vendor_ptr) return; - - PowerFactoryInterface hw_and_pow_int{vendor_ptr}; - - auto pwr = hw_and_pow_int.Find(APIC_MAG); - - if (pwr.HasError()) { - kSMPAware = NO; - return; - } - - kRawMADT = pwr.Leak().Leak(); - kSMPBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT); - kSMPAware = NO; - - if (kSMPBlock) { - kSMPInterrupt = 0; - kSMPCount = 0; - - UInt32 lo = 0U, hi = 0U; - - hal_get_msr(APIC_BASE_MSR, &lo, &hi); - - UInt64 apic_base = ((UInt64) hi << 32) | lo; - - apic_base |= APIC_BASE_MSR_ENABLE; // Enable APIC. - - lo = apic_base & 0xFFFFFFFF; - hi = apic_base >> 32; - - hal_set_msr(APIC_BASE_MSR, lo, hi); - - kApicBaseAddress = apic_base & 0xFFFFF000; - - LAPICDmaWrapper controller{(VoidPtr) kApicBaseAddress}; - - controller.Write(LAPIC_REG_ENABLE, 0); - controller.Write(LAPIC_REG_SPURIOUS, 0x1FF); // Enable bit, spurious interrupt vector register. - controller.Write(LAPIC_REG_TIMER_DIV, 0b0011); - controller.Write(LAPIC_REG_TIMER_LVT, 0x20 | (1 << 17)); - controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000); - - volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kSMPBlock->List); - volatile UInt8* end_ptr = ((UInt8*) kSMPBlock) + kSMPBlock->Length; - - while (entry_ptr < end_ptr) { - UInt8 type = *entry_ptr; - UInt8 length = *(entry_ptr + 1); - - if (type == 0 && length == sizeof(struct LAPIC)) { - volatile LAPIC* entry_struct = (volatile LAPIC*) entry_ptr; - - if (entry_struct->Flags & 0x1) { - kAPICLocales[kSMPCount] = entry_struct->ProcessorID; - kHWThread[kSMPCount].mThreadID = kAPICLocales[kSMPCount]; - - ++kSMPCount; - - kout << "AP: kind: LAPIC: ON.\r"; - } else { - kout << "AP: kind: LAPIC: OFF.\r"; - } - } else { - kout << "AP: kind: UNKNOWN: OFF.\r"; - } - - entry_ptr += length; - } - - kSMPAware = kSMPCount > 1; - } -} -} // namespace Kernel::HAL - -/////////////////////////////////////////////////////////////////////////////////////// diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s deleted file mode 100644 index 7b383404..00000000 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.s +++ /dev/null @@ -1,23 +0,0 @@ - /* - * ======================================================== - * - * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -.text - -.global hal_ap_blob_start -.global hal_ap_blob_length - -hal_ap_blob_start: - cli - hlt - jmp hal_ap_blob_start - -.data - -hal_ap_blob_length: - .long 4 diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm deleted file mode 100644 index 9f3652bc..00000000 --- a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm +++ /dev/null @@ -1,137 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. -;; * -;; * ======================================================== -;; */ - -section .text - -extern rt_wait_400ns - -global rt_out8 -global rt_out16 -global rt_out32 - -global rt_in8 -global rt_in16 -global rt_in32 - -rt_out8: - mov al, dl - mov dx, cx - out dx, al - ret - -rt_out16: - mov ax, dx - mov dx, cx - out dx, ax - ret - -rt_out32: - mov eax, edx - mov edx, ecx - out dx, eax - ret - -rt_in8: - mov dx, cx - in al, dx - ret - -rt_in16: - mov edx, ecx - in ax, dx - ret - -rt_in32: - mov rdx, rcx - in eax, dx - ret - -extern hal_system_call_enter -global mp_system_call_handler - -mp_system_call_handler: - push rbp - mov rbp, rsp - - push r8 - push r9 - push r10 - push r11 - push r12 - push r13 - push r14 - push r15 - - jmp hal_system_call_enter - - pop r15 - pop r14 - pop r13 - pop r12 - pop r11 - pop r10 - pop r9 - pop r8 - - pop rbp - - o64 iret - - -section .text - -global sched_jump_to_task - -sched_jump_to_task: - push rbp - mov rbp, rsp - - mov ax, 0x30 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - mov ax, 0x18 - ltr ax - - push 0x30 - mov rdx, [rcx + 0x08] - push rdx - o64 pushf - push 0x28 - mov rdx, [rcx + 0x00] - push rdx - - call sched_recover_registers - - o64 iret - -global sched_idle_task - -sched_idle_task: - jmp $ - ret - -sched_recover_registers: - push rbp - mov rbp, rsp - - mov r8, [rcx + 0x10] - mov r9, [rcx + 0x18] - mov r10, [rcx + 0x20] - mov r11, [rcx + 0x28] - mov r12, [rcx + 0x30] - mov r13, [rcx + 0x38] - mov r14, [rcx + 0x40] - mov r15, [rcx + 0x48] - - pop rbp - - ret
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalControlRegisterAPI.s b/dev/kernel/HALKit/AMD64/HalControlRegisterAPI.s deleted file mode 100644 index 90fdeb81..00000000 --- a/dev/kernel/HALKit/AMD64/HalControlRegisterAPI.s +++ /dev/null @@ -1,45 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -.globl hal_write_cr3 -.globl hal_write_cr0 -.globl hal_read_cr2 -.globl hal_read_cr3 -.globl hal_read_cr0 -.globl hal_flush_tlb -.globl hal_invl_tlb - -.text - -hal_invl_tlb: - invlpg (%rcx) - retq - -hal_flush_tlb: - call hal_read_cr3 - mov %rax, %rcx - call hal_write_cr3 - retq - -hal_read_cr3: - movq %cr3, %rax - retq - -hal_read_cr0: - movq %cr0, %rax - retq - -hal_read_cr2: - movq %cr2, %rax - retq - -hal_write_cr3: - movq %rcx, %cr3 - retq - -hal_write_cr0: - movq %rcx, %cr0 - retq diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc deleted file mode 100644 index f19e49b5..00000000 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr.h> -#include <NeKit/KString.h> -#include <SignalKit/Signals.h> - -EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); - -EXTERN_C Kernel::UIntPtr kApicBaseAddress; - -STATIC BOOL kIsRunning = NO; - -/// @brief Notify APIC and PIC that we're done with the interrupt. -/// @note -STATIC void hal_idt_send_eoi(UInt8 vector) { - ((volatile UInt32*) kApicBaseAddress)[0xB0 / 4] = 0; - - if (vector >= kPICCommand && vector <= 0x2F) { - if (vector >= 0x28) { - Kernel::HAL::rt_out8(kPIC2Command, kPICCommand); - } - Kernel::HAL::rt_out8(kPICCommand, kPICCommand); - } -} - -/// @brief Handle GPF fault. -/// @param rsp -EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_idt_send_eoi(13); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Handle page fault. -/// @param rsp -EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_idt_send_eoi(14); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Handle scheduler interrupt. -EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { - NE_UNUSED(rsp); - - hal_idt_send_eoi(32); - - while (kIsRunning) - ; - - kIsRunning = YES; - - Kernel::UserProcessHelper::StartScheduling(); - - kIsRunning = NO; -} - -/// @brief Handle math fault. -/// @param rsp -EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_idt_send_eoi(8); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = sig_generate_unique<SIGKILL>(); - ; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Handle any generic fault. -/// @param rsp -EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_idt_send_eoi(30); - - Kernel::kout << "Kernel: Generic Process Fault.\r"; - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = sig_generate_unique<SIGSEG>(); - ; - process.Leak().Signal.Status = process.Leak().Status; - - Kernel::kout << "Kernel: SIGKILL status.\r"; -} - -EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - - hal_idt_send_eoi(3); - - process.Leak().Signal.SignalArg = rip; - process.Leak().Signal.SignalID = sig_generate_unique<SIGTRAP>(); - - process.Leak().Signal.Status = process.Leak().Status; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; -} - -/// @brief Handle #UD fault. -/// @param rsp -EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_idt_send_eoi(6); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = sig_generate_unique<SIGKILL>(); - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Enter syscall from assembly (libSystem only) -/// @param stack the stack pushed from assembly routine. -/// @return nothing. -EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash, - Kernel::UIntPtr rdx_syscall_arg) { - hal_idt_send_eoi(50); - - if (!Kernel::kCurrentUser) return; - - for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { - if (kSysCalls[i].fHooked && rcx_hash == kSysCalls[i].fHash) { - if (kSysCalls[i].fProc) { - (kSysCalls[i].fProc)((Kernel::VoidPtr) rdx_syscall_arg); - } - } - } -} - -/// @brief Enter Kernel call from assembly (libDDK only). -/// @param stack the stack pushed from assembly routine. -/// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt, - Kernel::UIntPtr arg, Kernel::SizeT sz) { - hal_idt_send_eoi(51); - - if (!Kernel::kRootUser) return; - if (Kernel::kCurrentUser != Kernel::kRootUser) return; - if (!Kernel::kCurrentUser->IsSuperUser()) return; - - for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { - if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) { - if (kKernCalls[i].fProc) { - (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz); - } - } - } -} diff --git a/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc b/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc deleted file mode 100644 index f50e4abd..00000000 --- a/dev/kernel/HALKit/AMD64/HalCoreSystemCalls.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - ======================================== */ - -#include <ArchKit/ArchKit.h> - -using namespace Kernel; diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc deleted file mode 100644 index 8e5f4cbd..00000000 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DebugOutput.h> -#include <NeKit/New.h> -#include <NeKit/Utils.h> -#include <modules/CoreGfx/CoreGfx.h> -#include <modules/CoreGfx/TextGfx.h> - -namespace Kernel { -enum CommStatus : UInt16 { - kStateInvalid = 0x64, - kStateReady = 0xCF, - kStateTransmit = 0xFC, - kStateCnt = 3 -}; - -namespace Detail { - constexpr ATTRIBUTE(unused) const UInt16 kPort = 0x3F8; - STATIC ATTRIBUTE(unused) UInt16 kState = kStateInvalid; - - /// @brief Init COM1. - /// @return - template <UInt16 PORT> - bool hal_serial_init() noexcept { - if (kState == kStateReady || kState == kStateTransmit) return true; - - HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts - HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) - HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud - HAL::rt_out8(PORT + 1, 0x00); // (hi byte) - HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit - HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set - HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip - HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if - // serial returns same byte) - - // Check if serial is faulty (i.e: not same byte as sent) - if (HAL::rt_in8(PORT) != 0xAE) { - return false; - } - - kState = kStateReady; - - // If serial is not faulty set it in normal operation mode - // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - HAL::rt_out8(PORT + 4, 0x0F); - - return true; - } -} // namespace Detail - -TerminalDevice::~TerminalDevice() = default; - -#ifdef __DEBUG__ -STATIC SizeT kX = kFontSizeX, kY = kFontSizeY; -#endif // __DEBUG__ - -EXTERN_C void ke_utf_io_write(DeviceInterface<const Utf8Char*>* obj, const Utf8Char* bytes) { - NE_UNUSED(bytes); - NE_UNUSED(obj); - -#ifdef __DEBUG__ - Detail::hal_serial_init<Detail::kPort>(); - - if (!bytes || Detail::kState != kStateReady) return; - - if (*bytes == 0) return; - - Detail::kState = kStateTransmit; - - SizeT index = 0; - SizeT len = 0; - - index = 0; - len = urt_string_len(bytes); - - Char tmp_str[2]; - - while (index < len) { - if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); - - HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); - - tmp_str[0] = (bytes[index] > 127) ? '?' : bytes[index]; - tmp_str[1] = 0; - - cg_render_string(tmp_str, kY, kX, RGB(0xff, 0xff, 0xff)); - - if (bytes[index] == '\r') { - kY += kFontSizeY; - kX = kFontSizeX; - } - - kX += kFontSizeX; - - if (kX > kHandoverHeader->f_GOP.f_Width) { - kX = kFontSizeX; - } - - if (kY > kHandoverHeader->f_GOP.f_Height) { - kY = kFontSizeY; - - FBDrawInRegion(cg_get_clear_clr(), FB::CGAccessibilty::Height(), FB::CGAccessibilty::Width(), - 0, 0); - } - - ++index; - } - - Detail::kState = kStateReady; -#endif // __DEBUG__ -} - -EXTERN_C void ke_io_write(DeviceInterface<const Char*>* obj, const Char* bytes) { - NE_UNUSED(bytes); - NE_UNUSED(obj); - -#ifdef __DEBUG__ - Detail::hal_serial_init<Detail::kPort>(); - - if (!bytes || Detail::kState != kStateReady) return; - - if (*bytes == 0) return; - - Detail::kState = kStateTransmit; - - SizeT index = 0; - SizeT len = 0; - - index = 0; - len = rt_string_len(bytes); - - Char tmp_str[2]; - - while (index < len) { - if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); - - HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); - - tmp_str[0] = bytes[index]; - tmp_str[1] = 0; - - cg_render_string(tmp_str, kY, kX, RGB(0xff, 0xff, 0xff)); - - if (bytes[index] == '\r') { - kY += kFontSizeY; - kX = kFontSizeX; - } - - kX += kFontSizeX; - - if (kX > kHandoverHeader->f_GOP.f_Width) { - kX = kFontSizeX; - } - - if (kY > kHandoverHeader->f_GOP.f_Height) { - kY = kFontSizeY; - - FBDrawInRegion(cg_get_clear_clr(), FB::CGAccessibilty::Height(), FB::CGAccessibilty::Width(), - 0, 0); - } - - ++index; - } - - Detail::kState = kStateReady; -#endif // __DEBUG__ -} - -EXTERN_C void ke_io_read(DeviceInterface<const Char*>*, const Char* bytes) { - NE_UNUSED(bytes); - -#ifdef __DEBUG__ - Detail::hal_serial_init<Detail::kPort>(); - - if (!bytes || Detail::kState != kStateReady) return; - - Detail::kState = kStateTransmit; - - SizeT index = 0; - - ///! TODO: Look on how to wait for the UART to complete. - while (true) { - auto in = HAL::rt_in8(Detail::kPort); - - ///! If enter pressed then break. - if (in == 0xD) { - break; - } - - if (in < '0' || in < 'A' || in < 'a') { - if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') { - continue; - } - } - - ((char*) bytes)[index] = in; - - ++index; - } - - ((char*) bytes)[index] = 0; - - Detail::kState = kStateReady; -#endif // __DEBUG__ -} - -TerminalDevice TerminalDevice::The() noexcept { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; -} - -Utf8TerminalDevice::~Utf8TerminalDevice() = default; - -Utf8TerminalDevice Utf8TerminalDevice::The() noexcept { - Utf8TerminalDevice out(Kernel::ke_utf_io_write, - [](DeviceInterface<const Utf8Char*>*, const Utf8Char*) -> Void {}); - return out; -} - -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalDebugProtocol.cc b/dev/kernel/HALKit/AMD64/HalDebugProtocol.cc deleted file mode 100644 index 1adfff3e..00000000 --- a/dev/kernel/HALKit/AMD64/HalDebugProtocol.cc +++ /dev/null @@ -1,16 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -//! @file DebuggerPort.cc -//! @brief UART debug via packets. - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DebugOutput.h> -#include <NetworkKit/NetworkDevice.h> - -// after that we have start of additional data. - -namespace Kernel {} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc deleted file mode 100644 index 65bf0b1e..00000000 --- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <FSKit/NeFS.h> -#include <HALKit/AMD64/Processor.h> - -namespace Kernel::HAL { -namespace Detail { - STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 kInterruptVectorTable[kKernelIdtSize] = - {}; -} // namespace Detail - -/// @brief Loads the provided Global Descriptor Table. -/// @param gdt -/// @return -Void GDTLoader::Load(Register64& gdt) { -#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ - hal_load_gdt(gdt); -#endif // __NE_MODULAR_KERNEL_COMPONENTS__ -} - -Void IDTLoader::Load(Register64& idt) { -#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ - rt_cli(); - - volatile UIntPtr** ptr_ivt = (volatile UIntPtr**) idt.Base; - - for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) { - Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector; - Detail::kInterruptVectorTable[idt_indx].Ist = 0; - Detail::kInterruptVectorTable[idt_indx].TypeAttributes = - kKernelInterruptId ? kUserInterruptGate : kInterruptGate; - Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr) ptr_ivt[idt_indx] & 0xFFFF); - Detail::kInterruptVectorTable[idt_indx].OffsetMid = - (((UIntPtr) ptr_ivt[idt_indx] >> 16) & 0xFFFF); - Detail::kInterruptVectorTable[idt_indx].OffsetHigh = - (((UIntPtr) ptr_ivt[idt_indx] >> 32) & 0xFFFFFFFF); - - Detail::kInterruptVectorTable[idt_indx].Zero = 0; - } - - idt.Base = (UIntPtr) &Detail::kInterruptVectorTable[0]; - idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * (kKernelIdtSize); - - hal_load_idt(idt); - rt_sti(); -#endif // __NE_MODULAR_KERNEL_COMPONENTS__ - - return; -} - -/// @brief Loads the Global Descriptor Table into the CPU. -/// @param gdt GDT register wrapped in a ref. -void GDTLoader::Load(Ref<Register64>& gdt) { - if (!gdt) return; - - GDTLoader::Load(gdt.Leak()); -} - -/// @brief Loads the IDT, for interupts. -/// @param idt IDT register wrapped in a ref. -void IDTLoader::Load(Ref<Register64>& idt) { - if (!idt) return; - - IDTLoader::Load(idt.Leak()); -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalHandoverStub.asm b/dev/kernel/HALKit/AMD64/HalHandoverStub.asm deleted file mode 100644 index c9cabd1c..00000000 --- a/dev/kernel/HALKit/AMD64/HalHandoverStub.asm +++ /dev/null @@ -1,30 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. -;; * -;; * ======================================================== -;; */ - -[bits 64] - -%define kTypeKernel 100 -%define kArchAmd64 122 -%define kHandoverMagic 0xBADCC - -global _HandoverMagic -global _HandoverType -global _HandoverPad -global _HandoverArch - -section .ldr - -_HandoverMagic: - dq kHandoverMagic -_HandoverType: - dw kTypeKernel -_HandoverPad: - dw 0 -_HandoverArch: - dw kArchAmd64 diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm deleted file mode 100644 index c761684e..00000000 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ /dev/null @@ -1,370 +0,0 @@ -;; /* -;; * --------------------------------------------------- -;; * -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. -;; * -;; * File: HalInterruptAPI.asm -;; * Purpose: Interrupt API, redirect raw interrupts into their handlers. -;; * -;; * --------------------------------------------------- -;; */ - -[bits 64] - -%define kInterruptId 50 - -%macro IntExp 1 -global __NE_INT_%1 -__NE_INT_%1: - cli - - std - - o64 iret -%endmacro - -%macro IntNormal 1 -global __NE_INT_%1 -__NE_INT_%1: - cli - - std - - add rsp, 8 - - o64 iret -%endmacro - -; This file handles the core interrupt table -; Last edited 31/01/24 - -global ke_handle_irq -global kInterruptVectorTable - -extern idt_handle_gpf -extern idt_handle_pf -extern ke_io_write -extern idt_handle_ud -extern idt_handle_generic -extern idt_handle_breakpoint -extern idt_handle_math - -section .text - -__NE_INT_0: - cli - push rcx - call idt_handle_generic - pop rcx - - std - - o64 iret - -__NE_INT_1: - cli - push rcx - call idt_handle_generic - pop rcx - - std - - o64 iret - -__NE_INT_2: - cli - push rcx - call idt_handle_generic - pop rcx - - std - - o64 iret - -;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. -__NE_INT_3: - cli - push rcx - call idt_handle_breakpoint - pop rcx - - std - - o64 iret - -__NE_INT_4: - cli - - push rcx - call idt_handle_generic - pop rcx - - std - - o64 iret - -__NE_INT_5: - cli - std - - o64 iret - -;; Invalid opcode interrupt -__NE_INT_6: - cli - push rcx - call idt_handle_ud - pop rcx - - std - - o64 iret - -__NE_INT_7: - cli - push rcx - call idt_handle_generic - pop rcx - - std - - o64 iret - -;; Invalid opcode interrupt -__NE_INT_8: - cli - - push rcx - call idt_handle_math - pop rcx - - std - - o64 iret - -IntNormal 9 -IntExp 10 -IntExp 11 - -IntExp 12 - -__NE_INT_13: - cli - - push rcx - call idt_handle_gpf - pop rcx - - std - - add rsp, 8 - - o64 iret - -__NE_INT_14: - cli - push rcx - call idt_handle_pf - pop rcx - - std - - o64 iret - -IntNormal 15 -IntNormal 16 -IntExp 17 -IntNormal 18 -IntNormal 19 -IntNormal 20 -IntNormal 21 - -IntNormal 22 - -IntNormal 23 -IntNormal 24 -IntNormal 25 -IntNormal 26 -IntNormal 27 -IntNormal 28 -IntNormal 29 -IntExp 30 -IntNormal 31 - -[extern idt_handle_scheduler] -[extern kApicBaseAddress] - -__NE_INT_32: - cli - - push rax - mov rcx, rsp - call idt_handle_scheduler - pop rax - - std - - o64 iret - -IntNormal 33 - -IntNormal 34 -IntNormal 35 -IntNormal 36 -IntNormal 37 -IntNormal 38 -IntNormal 39 - -[extern rtl_rtl8139_interrupt_handler] - -__NE_INT_40: - cli - - push rax - mov rcx, rsp - call rtl_rtl8139_interrupt_handler - pop rax - - std - - o64 iret - -IntNormal 41 - -IntNormal 42 -IntNormal 43 -IntNormal 44 -IntNormal 45 -IntNormal 46 -IntNormal 47 -IntNormal 48 -IntNormal 49 - -[extern hal_system_call_enter] -[extern hal_kernel_call_enter] - -__NE_INT_50: - cli - - push rax - mov rax, hal_system_call_enter - - mov rcx, r8 - mov rdx, r9 - mov r8, r10 - mov r9, r11 - - call rax - pop rax - - std - - o64 iret - -__NE_INT_51: - cli - - push rax - mov rax, hal_kernel_call_enter - - mov rcx, r8 - mov rdx, r9 - mov r8, r10 - mov r9, r11 - - call rax - pop rax - - std - - o64 iret - -IntNormal 52 - -IntNormal 53 -IntNormal 54 -IntNormal 55 -IntNormal 56 -IntNormal 57 -IntNormal 58 -IntNormal 59 -IntNormal 60 - -%assign i 61 -%rep 195 - IntNormal i -%assign i i+1 -%endrep - -section .text - -[global hal_load_gdt] - -hal_load_gdt: - cli - - lgdt [rcx] - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - mov rax, 0x08 - push rax - push hal_reload_segments - - o64 retf - -extern hal_real_init - -hal_reload_segments: - std - jmp hal_real_init - ret - -global hal_load_idt - -hal_load_idt: - lidt [rcx] - - ; Master PIC initialization - mov al, 0x11 ; Start initialization in cascade mode - out 0x20, al ; Send initialization command to Master PIC - out 0xA0, al ; Send initialization command to Slave PIC - - ; Remap the PIC to use vectors 32-39 for Master and 40-47 for Slave - mov al, 0x20 ; Set Master PIC offset to 32 - out 0x21, al ; Send offset to Master PIC - - mov al, 0x28 ; Set Slave PIC offset to 40 - out 0xA1, al ; Send offset to Slave PIC - - ; Configure Master PIC to inform Slave PIC at IRQ2 - mov al, 0x04 ; Tell Master PIC there is a Slave PIC at IRQ2 - out 0x21, al - - ; Configure Slave PIC identity - mov al, 0x02 ; Tell Slave PIC its cascade identity - out 0xA1, al - - ; Set both PICs to 8086 mode - mov al, 0x01 ; 8086 mode - out 0x21, al - out 0xA1, al - - ret - -section .data - -kInterruptVectorTable: - %assign i 0 - %rep 256 - dq __NE_INT_%+i - %assign i i+1 - %endrep - -kApicBaseAddress: - dq 0
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc deleted file mode 100644 index e23c5bc1..00000000 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <CFKit/Property.h> -#include <FirmwareKit/EFI/API.h> -#include <FirmwareKit/EFI/EFI.h> -#include <KernelKit/CodeMgr.h> -#include <KernelKit/HardwareThreadScheduler.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/Timer.h> -#include <NetworkKit/IPC.h> -#include <StorageKit/AHCI.h> -#include <misc/BenchKit/HWChronometer.h> -#include <modules/ACPI/ACPIFactoryInterface.h> -#include <modules/CoreGfx/TextGfx.h> - -#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ -EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; - -/// @brief Kernel init function. -/// @param handover_hdr Handover boot header. -EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { - using namespace Kernel; - - if (handover_hdr->f_Magic != kHandoverMagic && handover_hdr->f_Version != kHandoverVersion) { - return kEfiFail; - } - - HAL::rt_sti(); - - fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]); - - Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, - handover_hdr->f_HardwareTables.f_ImageHandle); - - kHandoverHeader = handover_hdr; - - kKernelVM = kHandoverHeader->f_PageStart; - - if (!kKernelVM) { - MUST_PASS(kKernelVM); - return kEfiFail; - } - - hal_write_cr3(kKernelVM); - - /************************************** */ - /* INITIALIZE BIT MAP. */ - /************************************** */ - - kBitMapCursor = 0UL; - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = - reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(kHandoverHeader->f_BitMapStart)); - - /************************************** */ - /* INITIALIZE GDT AND SEGMENTS. */ - /************************************** */ - - STATIC CONST auto kGDTEntriesCount = 8; - - STATIC HAL::Detail::NE_TSS kKernelTSS{}; - - kKernelTSS.fRsp0 = (UInt64) kHandoverHeader->f_StackTop; - kKernelTSS.fIopb = sizeof(HAL::Detail::NE_TSS); - - /* The GDT, mostly descriptors for user and kernel segments. */ - STATIC HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { - {.fLimitLow = 0, - .fBaseLow = 0, - .fBaseMid = 0, - .fAccessByte = 0x00, - .fFlags = 0x00, - .fBaseHigh = 0}, // Null entry - {.fLimitLow = 0x0, - .fBaseLow = 0, - .fBaseMid = 0, - .fAccessByte = 0x9A, - .fFlags = 0xAF, - .fBaseHigh = 0}, // Kernel code - {.fLimitLow = 0x0, - .fBaseLow = 0, - .fBaseMid = 0, - .fAccessByte = 0x92, - .fFlags = 0xCF, - .fBaseHigh = 0}, // Kernel data - {}, // TSS data low - {}, // TSS data high - {.fLimitLow = 0x0, - .fBaseLow = 0, - .fBaseMid = 0, - .fAccessByte = 0xFA, - .fFlags = 0xAF, - .fBaseHigh = 0}, // User code - {.fLimitLow = 0x0, - .fBaseLow = 0, - .fBaseMid = 0, - .fAccessByte = 0xF2, - .fFlags = 0xCF, - .fBaseHigh = 0}, // User data - }; - - kGDTArray[3].fLimitLow = sizeof(HAL::Detail::NE_TSS) - 1; - kGDTArray[3].fBaseLow = ((UIntPtr) &kKernelTSS) & 0xFFFF; - kGDTArray[3].fBaseMid = (((UIntPtr) &kKernelTSS) >> 16) & 0xFF; - kGDTArray[3].fAccessByte = 0x89; // Present, type 9 = 64-bit available TSS - kGDTArray[3].fFlags = 0x20 | ((((UIntPtr) &kKernelTSS) >> 24) & 0x0F); - kGDTArray[3].fBaseHigh = (((UIntPtr) &kKernelTSS) >> 24) & 0xFF; - - kGDTArray[4].fLimitLow = ((UIntPtr) &kKernelTSS >> 32) & 0xFFFF; - kGDTArray[4].fBaseLow = 0; - kGDTArray[4].fBaseMid = 0; - kGDTArray[4].fAccessByte = 0; - kGDTArray[4].fFlags = 0; - kGDTArray[4].fBaseHigh = 0; - - FB::cg_clear_video(); - - // Load memory descriptors. - HAL::Register64 gdt_reg; - - gdt_reg.Base = reinterpret_cast<UIntPtr>(kGDTArray); - gdt_reg.Limit = (sizeof(HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1; - - //! GDT will load hal_read_init after it successfully loads the segments. - HAL::GDTLoader gdt_loader; - gdt_loader.Load(gdt_reg); - - return kEfiFail; -} - -EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { -#ifdef __FSKIT_INCLUDES_OPENHEFS__ - OpenHeFS::fs_init_openhefs(); -#endif - -#ifdef __FSKIT_INCLUDES_NEFS__ - NeFS::fs_init_nefs(); -#endif - - UserProcessScheduler::The().SwitchTeam(kHighUserTeam); - - rtl_create_user_process([]() -> void { while (YES); }, "NeKernel"); - - HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast<UIntPtr>(kInterruptVectorTable); - - HAL::IDTLoader idt_loader; - idt_loader.Load(idt_reg); - - while (YES) - ; -} -#endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__ diff --git a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc deleted file mode 100644 index 12538667..00000000 --- a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <FirmwareKit/Handover.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/FileMgr.h> -#include <KernelKit/Timer.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> -#include <modules/CoreGfx/CoreGfx.h> -#include <modules/CoreGfx/TextGfx.h> - -/* Each error code is attributed with an ID, which will prompt a string onto the - * screen. Wait for debugger... */ - -namespace Kernel { -/// @brief Dumping factory class. -class RecoveryFactory final { - public: - STATIC Void Recover() noexcept; -}; - -/***********************************************************************************/ -/// @brief Stops execution of the kernel. -/// @param id kernel stop ID. -/***********************************************************************************/ -Void ke_panic(const Kernel::Int32& id, const Char* message) { - (Void)(kout << "*** STOP ***\r"); - - (Void)(kout << "Kernel_Panic_MSG: " << message << kendl); - (Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl); - (Void)(kout << "Kernel_Panic_CR2: " << hex_number((UIntPtr) hal_read_cr2()) << kendl); - - RecoveryFactory::Recover(); -} - -Void RecoveryFactory::Recover() noexcept { - while (YES) { - HAL::rt_halt(); - } -} - -void ke_runtime_check(bool expr, const Char* file, const Char* line) { - if (!expr) { - (Void)(kout << "*** CHECK ***\r"); - - (Void)(kout << "Kernel_Panic_FILE: " << file << kendl); - (Void)(kout << "Kernel_Panic_LINE: " << line << kendl); - - ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed - } -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgr.cc b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc deleted file mode 100644 index 4043da96..00000000 --- a/dev/kernel/HALKit/AMD64/HalPagingMgr.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: HalPagingMgr.cc - Purpose: Platform Paging Manager. - -======================================== */ - -#include <HALKit/AMD64/Paging.h> -#include <HALKit/AMD64/Processor.h> - -namespace Kernel::HAL { -namespace Detail { - /// @brief Page Table Entry for AMD64. - struct PTE { - UInt64 Present : 1; - UInt64 Wr : 1; - UInt64 User : 1; - UInt64 Pwt : 1; // Page-level Write-Through - UInt64 Pcd : 1; // Page-level Cache Disable - UInt64 Accessed : 1; - UInt64 Dirty : 1; - UInt64 Pat : 1; // Page Attribute Table (or PS for PDE) - UInt64 Global : 1; - UInt64 Ignored1 : 3; // Available to software - UInt64 PhysicalAddress : 40; // Physical page frame address (bits 12–51) - UInt64 Ignored2 : 7; // More software bits / reserved - UInt64 ProtectionKey : 4; // Optional (if PKU enabled) - UInt64 Reserved : 1; // Usually reserved - UInt64 Nx : 1; // No Execute - }; -} // namespace Detail - -/***********************************************************************************/ -/// \brief Retrieve the page status of a PTE. -/// \param pte Page Table Entry pointer. -/***********************************************************************************/ -STATIC Void mmi_page_status(Detail::PTE* pte) { - NE_UNUSED(pte); - -#ifdef __NE_VERBOSE_BITMAP__ - (Void)(kout << "Flag: " << (pte->Present ? "Present" : "Not Present") << kendl); - (Void)(kout << "Flag: " << (pte->Wr ? "W/R" : "Not W/R") << kendl); - (Void)(kout << "Flag: " << (pte->Nx ? "NX" : "Not NX") << kendl); - (Void)(kout << "Flag: " << pte->User ? "User" : "Not User") << kendl); - (Void)(kout << "Flag: " << (pte->Pcd ? "Not Cached" : "Cached") << kendl); - (Void)(kout << "Flag: " << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); - (Void)(kout << "Flag: " << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") - << kendl); - (Void)(kout << "Physical Address: " << hex_number(pte->PhysicalAddress) << kendl); -#endif -} - -/***********************************************************************************/ -/// @brief Gets a physical address from a virtual address. -/// @param virt a valid virtual address. -/// @return Physical address. -/***********************************************************************************/ -EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virt) { - const UInt64 kVMAddr = (UInt64) virt; - const UInt64 kMask9Bits = 0x1FFULL; - const UInt64 kPageOffsetMask = 0xFFFULL; - - UInt64 cr3 = (UInt64) hal_read_cr3() & ~kPageOffsetMask; - - // Level 4 - auto pml4 = reinterpret_cast<UInt64*>(cr3); - UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9Bits]; - - if (!(pml4e & 1)) return 0; - - // Level 3 - auto pdpt = reinterpret_cast<UInt64*>(pml4e & ~kPageOffsetMask); - UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9Bits]; - - if (!(pdpte & 1)) return 0; - - // Level 2 - auto pd = reinterpret_cast<UInt64*>(pdpte & ~kPageOffsetMask); - UInt64 pde = pd[(kVMAddr >> 21) & kMask9Bits]; - - if (!(pde & 1)) return 0; - - // 1 GiB page support - if (pde & (1 << 7)) { - return (pde & ~((1ULL << 30) - 1)) | (kVMAddr & ((1ULL << 30) - 1)); - } - - // Level 1 - auto pt = reinterpret_cast<UInt64*>(pde & ~kPageOffsetMask); - Detail::PTE* pte = (Detail::PTE*) pt[(kVMAddr >> 12) & kMask9Bits]; - - if (!pte->Present) return 0; - - mmi_page_status((Detail::PTE*) pte); - - return (pte->PhysicalAddress << 12) | (kVMAddr & 0xFFF); -} - -/***********************************************************************************/ -/// @brief clflush+mfence helper function. -/***********************************************************************************/ -EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address) { - if (!virtual_address || !mm_get_page_addr(virtual_address)) return kErrorInvalidData; - - asm volatile("clflush (%0)" : : "r"(virtual_address) : "memory"); - asm volatile("mfence" ::: "memory"); - - return kErrorSuccess; -} - -/***********************************************************************************/ -/// @brief Maps or allocates a page from virtual_address. -/// @param virtual_address a valid virtual address. -/// @param phys_addr point to physical address. -/// @param flags the flags to put on the page. -/// @return Status code of page manipulation process. -/***********************************************************************************/ -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, - UInt32 level) { - if (physical_address == 0) return kErrorInvalidData; - - NE_UNUSED(level); /// @todo support PML4, and PDPT levels. - - const UInt64 kVMAddr = (UInt64) virtual_address; - constexpr UInt64 kMask9 = 0x1FF; - constexpr UInt64 kPageMask = 0xFFF; - - UInt64 cr3 = (UIntPtr) hal_read_cr3() & ~kPageMask; - - auto pml4 = reinterpret_cast<UInt64*>(cr3); - UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9]; - - if (!(pml4e & 1)) return kErrorInvalidData; - - UInt64* pdpt = reinterpret_cast<UInt64*>(pml4e & ~kPageMask); - UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9]; - - if (!(pdpte & 1)) return kErrorInvalidData; - - UInt64* pd = reinterpret_cast<UInt64*>(pdpte & ~kPageMask); - UInt64 pde = pd[(kVMAddr >> 21) & kMask9]; - - if (!(pde & 1)) return kErrorInvalidData; - - UInt64* pt = reinterpret_cast<UInt64*>(pde & ~kPageMask); - Detail::PTE* pte = (Detail::PTE*) pt[(kVMAddr >> 12) & kMask9]; - - pte->Present = !!(flags & kMMFlagsPresent); - pte->Wr = !!(flags & kMMFlagsWr); - pte->User = !!(flags & kMMFlagsUser); - pte->Nx = !!(flags & kMMFlagsNX); - pte->Pcd = !!(flags & kMMFlagsPCD); - pte->Pwt = !!(flags & kMMFlagsPwt); - - pte->PhysicalAddress = ((UIntPtr) (physical_address)) >> 12; - - hal_invl_tlb(virtual_address); - - mm_memory_fence(virtual_address); - - mmi_page_status(pte); - - return kErrorSuccess; -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalProcessor.cc b/dev/kernel/HALKit/AMD64/HalProcessor.cc deleted file mode 100644 index d202a758..00000000 --- a/dev/kernel/HALKit/AMD64/HalProcessor.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: HalCPU.cc - Purpose: Platform processor routines. - -======================================== */ - -#include <HALKit/AMD64/Paging.h> -#include <HALKit/AMD64/Processor.h> - -/** - * @file HalCPU.cc - * @brief Common CPU API. - */ - -namespace Kernel::HAL { -inline Bool hal_has_msr() noexcept { - static UInt32 eax, unused, edx; // eax, edx - - __get_cpuid(1, &eax, &unused, &unused, &edx); - - // edx returns the flag for MSR (which is 1 shifted to 5.) - return edx & (1 << 5); -} - -Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept { - if (!lo || !hi) return; - asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); -} - -Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept { - asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); -} - -Void lrt_hal_out8(UInt16 port, UInt8 value) { - asm volatile("outb %%al, %1" : : "a"(value), "Nd"(port) : "memory"); -} - -Void lrt_hal_out16(UInt16 port, UInt16 value) { - asm volatile("outw %%ax, %1" : : "a"(value), "Nd"(port) : "memory"); -} - -Void lrt_hal_out32(UInt16 port, UInt32 value) { - asm volatile("outl %%eax, %1" : : "a"(value), "Nd"(port) : "memory"); -} - -UInt8 lrt_hal_in8(UInt16 port) { - UInt8 value = 0UL; - asm volatile("inb %1, %%al" : "=a"(value) : "Nd"(port) : "memory"); - - return value; -} - -UInt16 lrt_hal_in16(UInt16 port) { - UInt16 value = 0UL; - asm volatile("inw %1, %%ax" : "=a"(value) : "Nd"(port) : "memory"); - - return value; -} - -UInt32 lrt_hal_in32(UInt16 port) { - UInt32 value = 0UL; - asm volatile("inl %1, %%eax" : "=a"(value) : "Nd"(port) : "memory"); - - return value; -} - -Void rt_halt() { - asm volatile("hlt"); -} - -Void rt_cli() { - asm volatile("cli"); -} - -Void rt_sti() { - asm volatile("sti"); -} - -Void rt_cld() { - asm volatile("cld"); -} - -Void rt_std() { - asm volatile("std"); -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalRoutineWait.s b/dev/kernel/HALKit/AMD64/HalRoutineWait.s deleted file mode 100644 index 89051ba4..00000000 --- a/dev/kernel/HALKit/AMD64/HalRoutineWait.s +++ /dev/null @@ -1,11 +0,0 @@ -.globl rt_wait_400ns - -.section .text -rt_wait_400ns: - jmp .loop - pause - .loop: - jmp .loop2 - pause - .loop2: - ret diff --git a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc deleted file mode 100644 index 44ec2a37..00000000 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitives.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <HALKit/AMD64/Processor.h> -#include <KernelKit/ProcessScheduler.h> - -namespace Kernel { -/***********************************************************************************/ -/// @brief Unimplemented function (crashes by default) -/// @param -/***********************************************************************************/ - -EXTERN_C Void __ne_pure_call(USER_PROCESS* process) { - if (process) process->Crash(); -} - -/***********************************************************************************/ -/// @brief Validate user stack. -/// @param stack_ptr the frame pointer. -/***********************************************************************************/ - -EXTERN_C Bool hal_check_task(HAL::StackFramePtr stack_ptr) { - if (!stack_ptr) return No; - - return stack_ptr->SP > 0 && stack_ptr->IP > 0; -} - -/// @brief Wakes up thread. -/// Wakes up thread from the hang state. -Void mp_wakeup_thread(HAL::StackFrame* stack) { - if (!hal_check_task(stack)) return; - - // RIP is always in R15. R15 is reserved for the RIP. - stack->IP = stack->R15; - - Kernel::UserProcessHelper::StartScheduling(); -} - -/// @brief makes the thread sleep on a loop. -/// hooks and hangs thread to prevent code from executing. -Void mp_hang_thread(HAL::StackFrame* stack) { - if (!hal_check_task(stack)) return; - - // Store IP in R15 - stack->R15 = stack->IP; - stack->IP = 0UL; -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalTimer.cc b/dev/kernel/HALKit/AMD64/HalTimer.cc deleted file mode 100644 index f6488b05..00000000 --- a/dev/kernel/HALKit/AMD64/HalTimer.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
- File: HalTimer.cc
- Purpose: HAL timer
-
- Revision History:
-
- 07/07/24: Added file (amlel)
-
-======================================== */
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/Timer.h>
-#include <modules/ACPI/ACPIFactoryInterface.h>
-
-/// ================================================================================
-/// @note timer slot 0
-/// ================================================================================
-
-#define kHPETSignature ("HPET")
-
-#define kHPETCounterRegValue (0x00)
-#define kHPETConfigRegValue (0x20)
-#define kHPETCompRegValue (0x24)
-#define kHPETInterruptRegValue (0x2C)
-
-/// ================================================================================
-///! BUGS: 0
-///! @file HalTimer.cc
-///! @brief Hardware Timer (HPET)
-/// ================================================================================
-
-namespace Kernel::Detail {
-struct HPET_BLOCK : public Kernel::SDT {
- Kernel::UInt8 hardware_rev_id;
- Kernel::UInt8 comparator_count : 5;
- Kernel::UInt8 counter_size : 1;
- Kernel::UInt8 reserved : 1;
- Kernel::UInt8 legacy_replacement : 1;
- Kernel::UInt16 pci_vendor_id;
- ACPI_ADDRESS address;
- Kernel::UInt8 hpet_number;
- Kernel::UInt16 minimum_tick;
- Kernel::UInt8 page_protection;
-} PACKED;
-} // namespace Kernel::Detail
-
-using namespace Kernel;
-
-HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) {
- auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr);
-
- auto hpet = (Detail::HPET_BLOCK*) power.Find(kHPETSignature).Leak().Leak();
- MUST_PASS(hpet);
-
- fDigitalTimer = (UInt8*) hpet->address.Address;
-
- if (hpet->page_protection) {
- HAL::mm_map_page((VoidPtr) fDigitalTimer, (VoidPtr) fDigitalTimer,
- HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt);
- }
-
- // if not enabled yet.
- if (!(*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) & (1 << 0))) {
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | (1 << 0) |
- (1 << 3); // enable timer & one shot conf
- }
-}
-
-HardwareTimer::~HardwareTimer() {
- fDigitalTimer = nullptr;
- fWaitFor = 0;
-}
-
-/***********************************************************************************/
-/// @brief Wait for the timer to stop spinning.
-/***********************************************************************************/
-
-BOOL HardwareTimer::Wait() noexcept {
- if (fWaitFor < 1) return NO;
- if (fWaitFor > 1'000'000) return NO; // max 1000s = 16 minutes
-
- UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer));
- UInt64 femtoseconds_per_tick = (hpet_cap >> 32);
-
- if (femtoseconds_per_tick == 0) return NO;
-
- volatile UInt64* timer = (volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue);
-
- UInt64 now = *timer;
-
- UInt64 fs_wait = fWaitFor * 1'000'000'000'000ULL;
- UInt64 stop_at = now + (fs_wait / femtoseconds_per_tick);
-
- while (*timer < (stop_at)) asm volatile("pause");
-
- return YES;
-}
diff --git a/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm b/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm deleted file mode 100644 index 2a0a5eff..00000000 --- a/dev/kernel/HALKit/AMD64/HalUtilsAPI.asm +++ /dev/null @@ -1,24 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. -;; * -;; * ======================================================== -;; */ - -[bits 64] - -[global rt_install_tib] - -section .text - -;; changed: rs, fs -;; expected: rcx, rdx - -rt_install_tib: - mov rcx, gs ;; TIB -> Thread Information Block - mov rdx, fs ;; PIB -> Process Information Block - ret - -;; //////////////////////////////////////////////////// ;; diff --git a/dev/kernel/HALKit/AMD64/Hypervisor.h b/dev/kernel/HALKit/AMD64/Hypervisor.h deleted file mode 100644 index 4cacb003..00000000 --- a/dev/kernel/HALKit/AMD64/Hypervisor.h +++ /dev/null @@ -1,24 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -MAKE_STRING_ENUM(HYPERVISOR) -ENUM_STRING(Qemu, "TCGTCGTCGTCG"); -ENUM_STRING(KVM, " KVMKVMKVM "); -ENUM_STRING(VMWare, "VMwareVMware"); -ENUM_STRING(VirtualBox, "VBoxVBoxVBox"); -ENUM_STRING(Xen, "XenVMMXenVMM"); -ENUM_STRING(Microsoft, "Microsoft Hv"); -ENUM_STRING(Parallels, " prl hyperv "); -ENUM_STRING(ParallelsAlt, " lrpepyh vr "); -ENUM_STRING(Bhyve, "bhyve bhyve "); -ENUM_STRING(Qnx, " QNXQVMBSQG "); -END_STRING_ENUM() -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc deleted file mode 100644 index f9865139..00000000 --- a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* ======================================== - -Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <DmaKit/DmaPool.h> -#include <HALKit/AMD64/Processor.h> -#include <modules/ACPI/ACPIFactoryInterface.h> - -using namespace Kernel; -using namespace Kernel::HAL; - -STATIC UInt16 kRTLIOBase = 0xFFFF; - -STATIC BOOL kTXRXEnabled = NO; - -STATIC UInt32 kRXOffset = 0UL; -STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500; - -STATIC UInt8* kRXUpperLayer = nullptr; -STATIC UInt8* kRXBuffer = nullptr; - -/***********************************************************************************/ -///@brief RTL8139 Init routine. -/***********************************************************************************/ - -EXTERN_C BOOL rtl_init_nic_rtl8139(UInt16 io_base) noexcept { - if (kTXRXEnabled) return NO; - - kRTLIOBase = io_base; - - MUST_PASS(io_base != 0xFFFF); - - kRXBuffer = reinterpret_cast<UInt8*>(rtl_dma_alloc(sizeof(UInt8) * kRXBufferSize, 0)); - - MUST_PASS(kRXBuffer); - - /// Reset first. - - rt_out8(io_base + 0x37, 0x10); - - UInt16 timeout = 0U; - - while (rt_in8(io_base + 0x37) & 0x10) { - ++timeout; - if (timeout > 0x1000) break; - } - - if (timeout <= 0x1000) { - return NO; - } - - rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer); - - rt_out8(io_base + 0x37, 0x0C); - - rt_out32(io_base + 0x44, 0xF | (1 << 7)); - - rt_out16(io_base + 0x3C, 0x0005); - - kTXRXEnabled = YES; - - return YES; -} - -/***********************************************************************************/ -/// @brief RTL8139 I/O interrupt handler. -/// @param rsp stack pointer. -/// @note This function is called when the device interrupts to retrieve network data. -/***********************************************************************************/ - -EXTERN_C Void rtl_rtl8139_interrupt_handler(UIntPtr rsp) { - if (kRTLIOBase == 0xFFFF || kRTLIOBase == 0) return; - - NE_UNUSED(rsp); - - UInt16 status = rt_in16(kRTLIOBase + 0x3E); - rt_out16(kRTLIOBase + 0x3E, status); - - if (status & 0x01) { - // While we receive data. - while ((rt_in8(kRTLIOBase + 0x37) & 0x01) == 0) { - // We grab an offset from the RX buffer. - UInt32 offset = kRXOffset % kRXBufferSize; - - // If the offset is too high, we reset it. - if (offset >= (kRXBufferSize - 16)) { - kRXOffset = 0UL; - offset = 0UL; - } - - volatile UInt8* packet = kRXBuffer + offset + 4; - UInt16 len = *(UInt16*) (kRXBuffer + offset + 2); - - kRXUpperLayer[(offset + 4)] = *packet; - kRXOffset += (len + 4); - - rt_out16(kRTLIOBase + 0x38, (UInt16) (kRXOffset - 16)); - } - } - - if (!(status & 0x04)) { - err_global_get() = kErrorNoNetwork; - } -} - -/***********************************************************************************/ -/// @brief RTL8139 get upper layer function -/// @return the upper layer. -/// @retval nullptr if no upper layer is set. -/// @retval pointer to the upper layer if set. -/***********************************************************************************/ - -EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() { - return kRXUpperLayer; -} - -/***********************************************************************************/ -/// @brief RTL8139 set upper layer function -/// @param layer the upper layer. -/***********************************************************************************/ - -EXTERN_C BOOL rtl_rtl8139_set_upper_layer(UInt8* layer) { - if (!layer) return NO; - kRXUpperLayer = layer; - - return YES; -} diff --git a/dev/kernel/HALKit/AMD64/PCI/DMA.cc b/dev/kernel/HALKit/AMD64/PCI/DMA.cc deleted file mode 100644 index 809494b6..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/DMA.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/PCI/DMA.h> - -namespace Kernel { -DMAWrapper::operator bool() { - return this->fAddress; -} - -bool DMAWrapper::operator!() { - return !this->fAddress; -} - -Boolean DMAWrapper::Check(UIntPtr offset) const { - if (!this->fAddress) return false; - - if (offset == 0) return false; - - kout << "[DMAWrapper::IsIn] Checking offset...\r"; - return reinterpret_cast<UIntPtr>(this->fAddress) >= offset; -} - -bool DMAWrapper::Write(UIntPtr& bit, const UInt32& offset) { - kout << "[DMAWrapper::Read] Checking this->fAddress...\r"; - - if (!this->fAddress) return false; - - (Void)(kout << "[DMAWrapper::Write] Writing at address: " - << hex_number(reinterpret_cast<UIntPtr>(this->fAddress) + offset) << kendl); - - ke_dma_write<UInt32>(reinterpret_cast<UIntPtr>(this->fAddress), offset, bit); - - return true; -} - -UIntPtr DMAWrapper::Read(const UInt32& offset) { - kout << "[DMAWrapper::Read] Checking this->fAddress...\r"; - - if (!this->fAddress) return ~0; - - (Void)(kout << "[DMAWrapper::Write] Writing at address: " - << hex_number(reinterpret_cast<UIntPtr>(this->fAddress) + offset) << kendl); - - return (UIntPtr) ke_dma_read<UInt32>(reinterpret_cast<UIntPtr>(this->fAddress), offset); -} - -UIntPtr DMAWrapper::operator[](UIntPtr& offset) { - return this->Read(offset); -} - -OwnPtr<IOBuf<Char*>> DMAFactory::Construct(OwnPtr<DMAWrapper>& dma) { - if (!dma) return {}; - - OwnPtr<IOBuf<Char*>> dmaOwnPtr = - mm_make_own_ptr<IOBuf<Char*>, char*>(reinterpret_cast<char*>(dma->fAddress)); - - if (!dmaOwnPtr) return {}; - - kout << "Returning the new OwnPtr<IOBuf<Char*>>!\r"; - return dmaOwnPtr; -} - -DMAWrapper& DMAWrapper::operator=(voidPtr Ptr) { - this->fAddress = Ptr; - return *this; -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/PCI/Database.cc b/dev/kernel/HALKit/AMD64/PCI/Database.cc deleted file mode 100644 index ba3e946c..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/Database.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/PCI/Database.h> - -namespace Kernel {} diff --git a/dev/kernel/HALKit/AMD64/PCI/Device.cc b/dev/kernel/HALKit/AMD64/PCI/Device.cc deleted file mode 100644 index 65af2f25..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/Device.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/PCI/Device.h> - -#define PCI_BAR_IO (0x01) -#define PCI_BAR_LOWMEM (0x02) -#define PCI_BAR_64 (0x04) -#define PCI_BAR_PREFETCH (0x08) -#define PCI_ENABLE_BIT (0x80000000) - -static Kernel::UInt NE_PCIReadRaw(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, - Kernel::UShort fun) { - Kernel::UInt target = PCI_ENABLE_BIT | ((Kernel::UInt) bus << 16) | ((Kernel::UInt) dev << 11) | - ((Kernel::UInt) fun << 8) | (bar & 0xFC); - - Kernel::HAL::rt_out32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigAddress, target); - - Kernel::HAL::rt_wait_400ns(); - - return Kernel::HAL::rt_in32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigData); -} - -static Kernel::Void NE_PCISetCfgTarget(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, - Kernel::UShort fun) { - Kernel::UInt target = 0x80000000 | ((Kernel::UInt) bus << 16) | ((Kernel::UInt) dev << 11) | - ((Kernel::UInt) fun << 8) | (bar & 0xFC); - - Kernel::HAL::rt_out32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigAddress, target); - - Kernel::HAL::rt_wait_400ns(); -} - -namespace Kernel::PCI { -Device::Device(UShort bus, UShort device, UShort func, UInt32 bar) - : fBus(bus), fDevice(device), fFunction(func), fBar(bar) {} - -Device::~Device() = default; - -UInt Device::Read(UInt bar, Size sz) { - // Ensure aligned access by masking to 4-byte boundary - NE_PCISetCfgTarget(bar & 0xFC, fBus, fDevice, fFunction); - - // Read 4 bytes and shift out the correct value - UInt data = HAL::rt_in32((UShort) PciConfigKind::ConfigData); - - if (sz == 4) return data; - if (sz == 2) return (data >> ((bar & 2) * 8)) & 0xFFFF; - if (sz == 1) return (data >> ((bar & 3) * 8)) & 0xFF; - - return (UShort) PciConfigKind::Invalid; -} - -void Device::Write(UInt bar, UIntPtr data, Size sz) { - NE_PCISetCfgTarget(bar & 0xFC, fBus, fDevice, fFunction); - - if (sz == 4) { - HAL::rt_out32((UShort) PciConfigKind::ConfigAddress, (UInt) data); - } else if (sz == 2) { - UInt temp = HAL::rt_in32((UShort) PciConfigKind::ConfigData); - - temp &= ~(0xFFFF << ((bar & 2) * 8)); - temp |= (data & 0xFFFF) << ((bar & 2) * 8); - - HAL::rt_out32((UShort) PciConfigKind::ConfigAddress, temp); - } else if (sz == 1) { - UInt temp = HAL::rt_in32((UShort) PciConfigKind::ConfigData); - - temp &= ~(0xFF << ((bar & 3) * 8)); - temp |= (data & 0xFF) << ((bar & 3) * 8); - - HAL::rt_out32((UShort) PciConfigKind::ConfigAddress, temp); - } -} - -UShort Device::DeviceId() { - return (UShort) (NE_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); -} - -UShort Device::VendorId() { - return (UShort) (NE_PCIReadRaw(0x0, fBus, fDevice, fFunction) & 0xFFFF); -} - -UShort Device::InterfaceId() { - return (UShort) (NE_PCIReadRaw(0x09, fBus, fDevice, fFunction) >> 16); -} - -UChar Device::Class() { - return (UChar) (NE_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 24); -} - -UChar Device::Subclass() { - return (UChar) (NE_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 16); -} - -UChar Device::ProgIf() { - return (UChar) (NE_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 8); -} - -UChar Device::HeaderType() { - return (UChar) (NE_PCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16); -} - -void Device::EnableMmio() { - UInt32 command = Read(0x04, sizeof(UInt32)); - command |= (1 << 1); // Memory Space Enable (bit 1) - - Write(0x04, command, sizeof(UInt32)); -} - -void Device::BecomeBusMaster() { - UInt32 command = Read(0x04, sizeof(UInt32)); - command |= (1 << 2); // Bus Master Enable (bit 2) - Write(0x04, command, sizeof(UInt32)); -} - -UIntPtr Device::Bar(UInt32 bar_in) { - UInt32 bar = NE_PCIReadRaw(bar_in, fBus, fDevice, fFunction); - - if (bar & PCI_BAR_IO) return static_cast<UIntPtr>(bar & ~0x03); - - if (bar & PCI_BAR_64) { - UInt32 high = NE_PCIReadRaw((bar_in + 4) & ~0x03, fBus, fDevice, fFunction); - return (static_cast<UIntPtr>(high) << 32) | (bar & ~0x0F); - } - - return static_cast<UIntPtr>(bar & ~0x0F); -} - -UShort Device::Vendor() { - UShort vendor = this->VendorId(); - return vendor; -} - -Device::operator bool() { - return this->VendorId() != (UShort) PciConfigKind::Invalid; -} -} // namespace Kernel::PCI diff --git a/dev/kernel/HALKit/AMD64/PCI/Express.cc b/dev/kernel/HALKit/AMD64/PCI/Express.cc deleted file mode 100644 index 2b6ba8d3..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/Express.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/PCI/Express.h> - -namespace Kernel {} diff --git a/dev/kernel/HALKit/AMD64/PCI/IO.cc b/dev/kernel/HALKit/AMD64/PCI/IO.cc deleted file mode 100644 index 233c8ef2..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/IO.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/PCI/IO.h> diff --git a/dev/kernel/HALKit/AMD64/PCI/Iterator.cc b/dev/kernel/HALKit/AMD64/PCI/Iterator.cc deleted file mode 100644 index 103ddb2c..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/Iterator.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/PCI/Iterator.h> - -namespace Kernel::PCI { -Iterator::Iterator(const Types::PciDeviceKind type, UInt32 bar) { - // probe devices. - for (Int32 bus = 0; bus < NE_BUS_COUNT; ++bus) { - for (Int32 device = 0; device < NE_DEVICE_COUNT; ++device) { - for (Int32 function = 0; function < NE_FUNCTION_COUNT; ++function) { - Device dev(bus, device, function, bar); - - if (dev.Class() == type) { - fDevices[bus] = dev; - } - } - } - } -} - -Iterator::~Iterator() {} - -Ref<PCI::Device> Iterator::operator[](const Size& at) { - return fDevices[at]; -} -} // namespace Kernel::PCI diff --git a/dev/kernel/HALKit/AMD64/PCI/PCI.cc b/dev/kernel/HALKit/AMD64/PCI/PCI.cc deleted file mode 100644 index a8c48fb9..00000000 --- a/dev/kernel/HALKit/AMD64/PCI/PCI.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/PCI/PCI.h> diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h deleted file mode 100644 index a938700e..00000000 --- a/dev/kernel/HALKit/AMD64/Paging.h +++ /dev/null @@ -1,91 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#ifdef __NE_AMD64__ - -/** --------------------------------------------------- - - * THIS FILE CONTAINS CODE FOR X86_64 PAGING. - -------------======================================== */ - -#include <NeKit/Defines.h> - -#ifndef kPageMax -#define kPageMax (0x200) -#endif //! kPageMax - -#ifndef kPageAlign -#define kPageAlign (0x08) -#endif //! kPageAlign - -#ifndef kPageSize -#define kPageSize (0x1000) -#endif // !kPageSize - -#ifndef kAlign -#define kAlign __BIGGEST_ALIGNMENT__ -#endif // !kAlign - -EXTERN_C void hal_flush_tlb(); -EXTERN_C void hal_invl_tlb(Kernel::VoidPtr addr); -EXTERN_C void hal_write_cr3(Kernel::VoidPtr cr3); -EXTERN_C void hal_write_cr0(Kernel::VoidPtr bit); - -EXTERN_C Kernel::VoidPtr hal_read_cr0(); // @brief CPU control register. -EXTERN_C Kernel::VoidPtr hal_read_cr2(); // @brief Fault address. -EXTERN_C Kernel::VoidPtr hal_read_cr3(); // @brief Page directory inside cr3 register. - -namespace Kernel::HAL { -namespace Detail { - enum class ControlRegisterBits { - kProtectedModeEnable = 0, - kMonitorCoProcessor = 1, - kEmulation = 2, - kTaskSwitched = 3, - kExtensionType = 4, - kNumericError = 5, - kWriteProtect = 16, - kAlignementMask = 18, - kNotWriteThrough = 29, - kCacheDisable = 30, - kPageEnable = 31, - }; - - inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); } -} // namespace Detail - -auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr; -auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; -} // namespace Kernel::HAL - -namespace Kernel { -struct PTE { - UInt64 Present : 1; - UInt64 Wr : 1; - UInt64 User : 1; - UInt64 Pwt : 1; // Page-level Write-Through - UInt64 Pcd : 1; // Page-level Cache Disable - UInt64 Accessed : 1; - UInt64 Dirty : 1; - UInt64 Pat : 1; // Page Attribute Table (or PS for PDE) - UInt64 Global : 1; - UInt64 Ignored1 : 3; // Available to software - UInt64 PhysicalAddress : 40; // Physical page frame address (bits 12–51) - UInt64 Ignored2 : 7; // More software bits / reserved - UInt64 ProtectionKey : 4; // Optional (if PKU enabled) - UInt64 Reserved : 1; // Usually reserved - UInt64 Nx : 1; // No Execute -}; - -struct PDE { - ATTRIBUTE(aligned(kib_cast(4))) PTE fPTE[512]; -}; -} // namespace Kernel - -#endif // __NE_AMD64__
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h deleted file mode 100644 index db1ed573..00000000 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ /dev/null @@ -1,283 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: Prcoessor.h - Purpose: AMD64 processor abstraction. - - Revision History: - - 30/01/24: Added file (amlel) - -======================================== */ - -#pragma once - -#ifdef __NE_AMD64__ - -#include <FirmwareKit/Handover.h> -#include <HALKit/AMD64/Paging.h> -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/Utils.h> - -#include <HALKit/AMD64/CPUID.h> - -#define kPITControlPort (0x43) -#define kPITChannel0Port (0x40) -#define kPITFrequency (1193180) - -#define kPICCommand (0x20) -#define kPICData (0x21) -#define kPIC2Command (0xA0) -#define kPIC2Data (0xA1) - -#define kIOAPICRegVal (4) -#define kIOAPICRegReg (0) - -#define rtl_nop_op() asm volatile("nop") - -/// @brief Maximum entries of the interrupt descriptor table. -#define kKernelIdtSize (0x100) - -/// @brief interrupt for system call. -#define kKernelInterruptId (0x32) - -#define IsActiveLow(FLG) (FLG & 2) -#define IsLevelTriggered(FLG) (FLG & 8) - -#define kInterruptGate (0x8E) -#define kUserInterruptGate (0xEE) -#define kTrapGate (0xEF) -#define kTaskGate (0b10001100) -#define kIDTSelector (0x08) - -namespace Kernel { -namespace Detail::AMD64 { - struct PACKED InterruptDescriptorAMD64 final { - UInt16 OffsetLow; // offset bits 0..15 - UInt16 Selector; // a code segment selector in GDT or LDT - UInt8 Ist; - UInt8 TypeAttributes; - UInt16 OffsetMid; - UInt32 OffsetHigh; - UInt32 Zero; // reserved - }; -} // namespace Detail::AMD64 -} // namespace Kernel - -namespace Kernel::HAL { -/// @brief Memory Manager mapping flags. -enum { - kMMFlagsInvalid = 1 << 0, - kMMFlagsPresent = 1 << 1, - kMMFlagsWr = 1 << 2, - kMMFlagsUser = 1 << 3, - kMMFlagsNX = 1 << 4, - kMMFlagsPCD = 1 << 5, - kMMFlagsPwt = 1 << 6, - kMMFlagsCount = 6, -}; - -struct PACKED Register64 final { - UShort Limit; - UIntPtr Base; -}; - -using RawRegister = UInt64; -using Reg = RawRegister; -using InterruptId = UInt16; /* For each element in the IVT */ - -/// @brief Stack frame (as retrieved from assembly.) -struct PACKED StackFrame { - Reg IP; - Reg SP; - Reg R8; - Reg R9; - Reg R10; - Reg R11; - Reg R12; - Reg R13; - Reg R14; - Reg R15; -}; - -typedef StackFrame* StackFramePtr; - -class InterruptDescriptor final { - public: - UShort Offset; - UShort Selector; - UChar Ist; - UChar Atrributes; - - UShort SecondOffset; - UInt ThirdOffset; - UInt Zero; - - operator bool() { return Offset != 0xFFFF; } -}; - -using InterruptDescriptorArray = Array<InterruptDescriptor, 256>; - -class SegmentDescriptor final { - public: - UInt16 Base; - UInt8 BaseMiddle; - UInt8 BaseHigh; - - UShort Limit; - UChar Gran; - UChar AccessByte; -}; - -/*** - * @brief Segment Boolean operations - */ -class SegmentDescriptorComparator final { - public: - Bool IsValid(SegmentDescriptor& seg) { return seg.Base > seg.Limit; } - - Bool Equals(SegmentDescriptor& seg, SegmentDescriptor& segRight) { - return seg.Base == segRight.Base && seg.Limit == segRight.Limit; - } -}; - -using SegmentArray = Array<SegmentDescriptor, 6>; - -class GDTLoader final { - public: - static Void Load(Register64& gdt); - static Void Load(Ref<Register64>& gdt); -}; - -class IDTLoader final { - public: - static Void Load(Register64& idt); - static Void Load(Ref<Register64>& idt); -}; - -/***********************************************************************************/ -/// @brief Is the current config SMP aware? -/// @return True if YES, False if not. -/***********************************************************************************/ - -Bool mp_is_smp(Void) noexcept; - -/***********************************************************************************/ -/// @brief Fetch and enable SMP scheduler. -/// @param vendor_ptr SMP containing structure. -/***********************************************************************************/ -Void mp_init_cores(VoidPtr vendor_ptr) noexcept; - -/***********************************************************************************/ -/// @brief Do a cpuid to check if MSR exists on CPU. -/// @retval true it does exists. -/// @retval false it doesn't. -/***********************************************************************************/ -Bool hal_has_msr() noexcept; - -/***********************************************************************************/ -/// @brief Get Model specific register inside core. -/// @param msr MSR -/// @param lo low byte -/// @param hi high byte -/***********************************************************************************/ -Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept; - -/// @brief Set Model-specific register. -/// @param msr MSR -/// @param lo low byte -/// @param hi high byte -Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept; - -/// @brief Processor specific namespace. -namespace Detail { - /* @brief TSS struct. */ - struct NE_TSS final { - UInt32 fReserved1; - UInt64 fRsp0; - UInt64 fRsp1; - UInt64 fRsp2; - UInt64 fReserved2; - UInt64 fIst1; - UInt64 fIst2; - UInt64 fIst3; - UInt64 fIst4; - UInt64 fIst5; - UInt64 fIst6; - UInt64 fIst7; - UInt64 fReserved3; - UInt16 fReserved4; - UInt16 fIopb; - }; - - /** - @brief Global descriptor table entry, either null, code or data. - */ - - struct PACKED NE_GDT_ENTRY final { - UInt16 fLimitLow; - UInt16 fBaseLow; - UInt8 fBaseMid; - UInt8 fAccessByte; - UInt8 fFlags; - UInt8 fBaseHigh; - }; -} // namespace Detail - -class LAPICDmaWrapper final { - public: - explicit LAPICDmaWrapper(VoidPtr base); - ~LAPICDmaWrapper(); - - NE_COPY_DEFAULT(LAPICDmaWrapper) - - public: - UInt32 Read(UInt16 reg) noexcept; - Void Write(UInt16 reg, UInt32 value) noexcept; - - private: - VoidPtr fApic{nullptr}; -}; - -/// @brief Set a PTE from pd_base. -/// @param virt_addr a valid virtual address. -/// @param phys_addr point to physical address. -/// @param flags the flags to put on the page. -/// @return Status code of page manip. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, - UInt32 level = 2); - -EXTERN_C UInt8 rt_in8(UInt16 port); -EXTERN_C UInt16 rt_in16(UInt16 port); -EXTERN_C UInt32 rt_in32(UInt16 port); - -EXTERN_C Void rt_out16(UShort port, UShort byte); -EXTERN_C Void rt_out8(UShort port, UChar byte); -EXTERN_C Void rt_out32(UShort port, UInt byte); - -EXTERN_C Void rt_wait_400ns(); -EXTERN_C Void rt_halt(); -EXTERN_C Void rt_cli(); -EXTERN_C Void rt_sti(); -EXTERN_C Void rt_cld(); -EXTERN_C Void rt_std(); - -EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address); - -EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_address); -} // namespace Kernel::HAL - -EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp); -EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp); -EXTERN_C Kernel::Void idt_handle_math(Kernel::UIntPtr rsp); -EXTERN_C Kernel::Void idt_handle_pf(Kernel::UIntPtr rsp); - -EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr); -EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::Register64 ptr); - -inline Kernel::VoidPtr kKernelBitMpStart = nullptr; -inline Kernel::UIntPtr kKernelBitMpSize = 0UL; - -#endif // __NE_AMD64__ */
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc deleted file mode 100644 index 14b40b98..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ /dev/null @@ -1,600 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @file AHCI+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief AHCI Generic driver. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - */ - -#include <DmaKit/DmaPool.h> -#include <FirmwareKit/EPM.h> -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/DriveMgr.h> -#include <KernelKit/KPC.h> -#include <KernelKit/LockDelegate.h> -#include <KernelKit/PCI/Iterator.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/Timer.h> -#include <NeKit/Utils.h> -#include <StorageKit/AHCI.h> -#include <modules/AHCI/AHCI.h> -#include <modules/ATA/ATA.h> - -#define kSATAErrTaskFile (1 << 30) -#define kSATAPxCmdST (0x0001) -#define kSATAPxCmdFre (0x0010) -#define kSATAPxCmdFR (0x4000) -#define kSATAPxCmdCR (0x8000) - -#define kSATALBAMode (1 << 6) - -#define kSATASRBsy (0x80) -#define kSATASRDrq (0x08) - -#define kSATABohcBiosOwned (1 << 0) -#define kSATABohcOSOwned (1 << 1) - -#define kSATAPortCnt (0x20) - -#define kSATASig (0x00000101) -#define kSATAPISig (0xEB140101) - -#define kSATAProgIfAHCI (0x01) -#define kSATASubClass (0x06) -#define kSATABar5 (0x24) - -using namespace Kernel; - -STATIC PCI::Device kSATADev; -STATIC HbaMemRef kSATAHba; -STATIC Lba kSATASectorCount = 0UL; -STATIC UInt16 kSATAIndex = 0U; -STATIC Char kCurrentDiskModel[50] = {"GENERIC SATA"}; -STATIC UInt16 kSATAPortsImplemented = 0U; -STATIC ALIGN(kib_cast(4)) UInt8 kIdentifyData[kAHCISectorSize] = {0}; - -template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, - SizeT size_buffer) noexcept; - -STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept; - -STATIC Void drv_compute_disk_ahci() noexcept; - -STATIC SizeT drv_get_size_ahci(); - -STATIC SizeT drv_get_sector_count_ahci(); - -/***********************************************************************************/ -/// @brief Identify device and read LBA info, Disk OEM vendor. -/***********************************************************************************/ -STATIC Void drv_compute_disk_ahci() noexcept { - kSATASectorCount = 0UL; - - rt_set_memory(kIdentifyData, 0, kAHCISectorSize); - - drv_std_input_output_ahci<NO, YES, YES>(0, kIdentifyData, kAHCISectorSize, kAHCISectorSize); - - // --> Reinterpret the 512-byte buffer as an array of 256 UInt16 words - UInt16* identify_words = reinterpret_cast<UInt16*>(kIdentifyData); - - /// Extract 48-bit LBA. - UInt64 lba48_sectors = 0UL; - lba48_sectors |= (UInt64) identify_words[100]; - lba48_sectors |= (UInt64) identify_words[101] << 16; - lba48_sectors |= (UInt64) identify_words[102] << 32; - - if (lba48_sectors == 0) - kSATASectorCount = (identify_words[61] << 16) | identify_words[60]; - else - kSATASectorCount = lba48_sectors; - - for (Int32 i = 0; i < 20; i++) { - kCurrentDiskModel[i * 2] = (identify_words[27 + i] >> 8) & 0xFF; - kCurrentDiskModel[i * 2 + 1] = identify_words[27 + i] & 0xFF; - } - - kCurrentDiskModel[40] = '\0'; - - (Void)(kout << "SATA Sector Count: " << hex_number(kSATASectorCount) << kendl); - (Void)(kout << "SATA Disk Model: " << kCurrentDiskModel << kendl); -} - -/***********************************************************************************/ -/// @brief Finds a command slot for a HBA port. -/// @param port The port to search on. -/// @return The slot, or -1. -/***********************************************************************************/ -STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept { - UInt32 slots = port->Sact | port->Ci; - - for (Int32 i = 0; i < kSATAPortCnt; ++i) // AHCI supports up to 32 slots - { - if ((slots & (1U << i)) == 0) return i; - } - - return -1; // no free slot found -} - -/***********************************************************************************/ -/// @brief Send an AHCI command, according to the template parameters. -/// @param lba Logical Block Address to look for. -/// @param buffer The data buffer to transfer. -/// @param sector_sz The disk's sector size (unused) -/// @param size_buffer The size of the **buffer** parameter. -/***********************************************************************************/ -template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, - SizeT size_buffer) noexcept { - if (sector_sz == 0) { - kout << "ahci: Invalid sector size.\r"; - err_global_get() = kErrorDisk; - return; - } - - lba /= sector_sz; - - if (!buffer || size_buffer == 0) { - kout << "ahci: Invalid buffer for AHCI I/O.\r"; - err_global_get() = kErrorDisk; - return; - } - - UIntPtr slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); - - UInt16 timeout = 0; - - constexpr static UInt16 kTimeout = 0x8000; - - while (slot == ~0UL) { - if (timeout > kTimeout) { - kout << "ahci: No free command slot found, AHCI disk is busy!\r"; - - err_global_get() = kErrorDisk; - return; - } - - slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); - ++timeout; - } - - volatile HbaCmdHeader* command_header = - (volatile HbaCmdHeader*) ((UInt64) kSATAHba->Ports[kSATAIndex].Clb); - - command_header += slot; - - MUST_PASS(command_header); - - // Clear old command table memory - volatile HbaCmdTbl* command_table = - (volatile HbaCmdTbl*) (((UInt64) command_header->Ctbau << 32) | command_header->Ctba); - - MUST_PASS(command_table); - - rt_set_memory((VoidPtr) command_table, 0, sizeof(HbaCmdTbl)); - - VoidPtr ptr = rtl_dma_alloc(size_buffer, kib_cast(4)); - - rtl_dma_flush(ptr, size_buffer); - - if (Write) { - rt_copy_memory(buffer, ptr, size_buffer); - } - - rtl_dma_flush(ptr, size_buffer); - - // Build the PRD table. - SizeT bytes_remaining = size_buffer; - SizeT prdt_index = 0; - UIntPtr buffer_phys = (UIntPtr) ptr; - - while (bytes_remaining > 0) { - SizeT chunk_size = bytes_remaining; - - if (chunk_size > kib_cast(32)) chunk_size = kib_cast(32); - - command_table->Prdt[prdt_index].Dba = (UInt32) (buffer_phys & 0xFFFFFFFF); - command_table->Prdt[prdt_index].Dbau = (UInt32) (buffer_phys >> 32); - command_table->Prdt[prdt_index].Dbc = (UInt32) (chunk_size - 1); - command_table->Prdt[prdt_index].Ie = NO; - - buffer_phys += chunk_size; - bytes_remaining -= chunk_size; - - ++prdt_index; - } - - // Mark the last PRD entry, for the FIS to process the table. - command_table->Prdt[prdt_index - 1].Ie = YES; - - if (bytes_remaining > 0) { - kout << "ahci: AHCI PRDT overflow, cannot map full buffer.\r"; - err_global_get() = kErrorDisk; - rtl_dma_free(size_buffer); - - return; - } - - command_header->Prdtl = prdt_index; - command_header->HbaFlags.Struct.Cfl = sizeof(FisRegH2D) / sizeof(UInt32); - command_header->HbaFlags.Struct.Write = Write; - - volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*) (&command_table->Cfis[0]); - - h2d_fis->FisType = kFISTypeRegH2D; - h2d_fis->CmdOrCtrl = CommandOrCTRL; - h2d_fis->Command = - (Identify ? kAHCICmdIdentify : (Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx)); - - h2d_fis->Lba0 = (lba >> 0) & 0xFF; - h2d_fis->Lba1 = (lba >> 8) & 0xFF; - h2d_fis->Lba2 = (lba >> 16) & 0xFF; - h2d_fis->Lba3 = (lba >> 24) & 0xFF; - h2d_fis->Lba4 = (lba >> 32) & 0xFF; - h2d_fis->Lba5 = (lba >> 40) & 0xFF; - - h2d_fis->Device = 0; - - if (Identify) { - h2d_fis->CountLow = 1; - h2d_fis->CountHigh = 0; - } else { - h2d_fis->Device = kSATALBAMode; - h2d_fis->CountLow = (size_buffer / kAHCISectorSize) & 0xFF; - h2d_fis->CountHigh = ((size_buffer / kAHCISectorSize) >> 8) & 0xFF; - } - - rtl_dma_flush(ptr, size_buffer); - - // Issue command - kSATAHba->Ports[kSATAIndex].Ci = (1 << slot); - - timeout = 0UL; - - while (YES) { - if (timeout > kTimeout) { - kout << "ahci: disk-hangup, corrupted-disk.\r"; - err_global_get() = kErrorDiskIsCorrupted; - rtl_dma_free(size_buffer); - - return; - } - - ++timeout; - - if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break; - } - - rtl_dma_flush(ptr, size_buffer); - - if (kSATAHba->Is & kSATAErrTaskFile) { - kout << "ahci: Task File Error during I/O.\r"; - - rtl_dma_free(size_buffer); - err_global_get() = kErrorDiskIsCorrupted; - - return; - } else { - if (!Write) { - rtl_dma_flush(ptr, size_buffer); - rt_copy_memory(ptr, buffer, size_buffer); - rtl_dma_flush(ptr, size_buffer); - } - - if ((kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) == 0) { - goto ahci_io_end; - } else { - kout << "ahci: Disk still busy after command completion!\r"; - while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) - ; - } - - ahci_io_end: - rtl_dma_free(size_buffer); - err_global_get() = kErrorSuccess; - } -} - -/*** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. - */ -STATIC ATTRIBUTE(unused) SizeT drv_get_sector_count_ahci() { - return kSATASectorCount; -} - -/// @brief Get the drive size. -/// @return Disk size in bytes. -STATIC ATTRIBUTE(unused) SizeT drv_get_size_ahci() { - return drv_std_get_sector_count() * kAHCISectorSize; -} - -/// @brief Enable Host and probe using the IDENTIFY command. -STATIC BOOL ahci_enable_and_probe() { - if (kSATAHba->Cap == 0x0) return NO; - - kSATAHba->Ports[kSATAIndex].Cmd &= ~kSATAPxCmdFre; - kSATAHba->Ports[kSATAIndex].Cmd &= ~kSATAPxCmdST; - - while (YES) { - if (kSATAHba->Ports[kSATAIndex].Cmd & kSATAPxCmdCR) continue; - - if (kSATAHba->Ports[kSATAIndex].Cmd & kSATAPxCmdFR) continue; - - break; - } - - // Now we are ready. - - kSATAHba->Ports[kSATAIndex].Cmd |= kSATAPxCmdFre; - kSATAHba->Ports[kSATAIndex].Cmd |= kSATAPxCmdST; - - if (kSATAHba->Bohc & kSATABohcBiosOwned) { - kSATAHba->Bohc |= kSATABohcOSOwned; - - while (kSATAHba->Bohc & kSATABohcBiosOwned) { - ; - } - } - - drv_compute_disk_ahci(); - - return YES; -} - -STATIC Bool drv_init_command_structures_ahci() { - // Allocate 4KiB for Command List (32 headers) - VoidPtr clb_mem = rtl_dma_alloc(4096, 1024); - if (!clb_mem) { - kout << "Failed to allocate CLB memory!\r"; - return NO; - } - - UIntPtr clb_phys = HAL::mm_get_page_addr(clb_mem); - - kSATAHba->Ports[kSATAIndex].Clb = (UInt32) (clb_phys & 0xFFFFFFFF); - kSATAHba->Ports[kSATAIndex].Clbu = (UInt32) (clb_phys >> 32); - - // Clear it - rt_set_memory(clb_mem, 0, kib_cast(4)); - - // For each command slot (up to 32) - volatile HbaCmdHeader* header = (volatile HbaCmdHeader*) clb_mem; - - for (Int32 i = 0; i < 32; ++i) { - // Allocate 4KiB for Command Table - VoidPtr ct_mem = rtl_dma_alloc(4096, 128); - if (!ct_mem) { - (Void)(kout << "Failed to allocate CTB memory for slot " << hex_number(i)); - kout << "!\r"; - return NO; - } - - UIntPtr ct_phys = HAL::mm_get_page_addr(ct_mem); - - header[i].Ctba = (UInt32) (ct_phys & 0xFFFFFFFF); - header[i].Ctbau = (UInt32) (ct_phys >> 32); - - // Clear the command table - rt_set_memory((VoidPtr) ct_mem, 0, 4096); - } - - return YES; -} - -/// @brief Initializes an AHCI disk. -/// @param pi the amount of ports that have been detected. -/// @param atapi reference value, tells whether we should detect ATAPI instead of SATA. -/// @return if the disk was successfully initialized or not. -STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi) { - /// AMLALE: TODO: Iterator is good enough, but we need to expand it. - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController, 0x00); - - for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { - kSATADev = iterator[device_index].Leak(); // Leak device. - - if (kSATADev.Subclass() == kSATASubClass && kSATADev.ProgIf() == kSATAProgIfAHCI) { - kSATADev.EnableMmio(); - kSATADev.BecomeBusMaster(); - - HbaMem* mem_ahci = (HbaMem*) kSATADev.Bar(kSATABar5); - - HAL::mm_map_page( - (VoidPtr) mem_ahci, (VoidPtr) mem_ahci, - HAL::kMMFlagsPresent | HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt); - - UInt32 ports_implemented = mem_ahci->Pi; - UInt16 ahci_index = 0; - - pi = ports_implemented; - - const UInt16 kSATAMaxPortsImplemented = ports_implemented; - const UInt32 kSATASignature = kSATASig; - const UInt32 kSATAPISignature = kSATAPISig; - const UInt8 kSATAPresent = 0x03; - const UInt8 kSATAIPMActive = 0x01; - - if (kSATAMaxPortsImplemented < 1) continue; - - while (ports_implemented) { - UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; - UInt8 det = (mem_ahci->Ports[ahci_index].Ssts & 0x0F); - - if (det != kSATAPresent || ipm != kSATAIPMActive) continue; - - if ((mem_ahci->Ports[ahci_index].Sig == kSATASignature) || - (atapi && kSATAPISignature == mem_ahci->Ports[ahci_index].Sig)) { - kSATAIndex = ahci_index; - kSATAHba = mem_ahci; - - if (!drv_init_command_structures_ahci()) { - err_global_get() = kErrorDisk; - } - - goto success_hba_fetch; - } - - ports_implemented >>= 1; - ++ahci_index; - } - } - } - - err_global_get() = kErrorDisk; - - return NO; - -success_hba_fetch: - if (ahci_enable_and_probe()) { - err_global_get() = kErrorSuccess; - } - - return err_global_get() == kErrorSuccess; -} - -/// @brief Checks if an AHCI device is detected. -/// @return Either if detected, or not found. -Bool drv_std_detected_ahci() { - return kSATADev.DeviceId() != (UShort) PCI::PciConfigKind::Invalid && - kSATADev.Bar(kSATABar5) != 0; -} - -// ================================================================================================ - -// -/// @note This applies only if we compile with AHCI as a default disk driver. -// - -// ================================================================================================ - -#ifdef __AHCI__ - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { - drv_std_input_output_ahci<YES, YES, NO>(lba, reinterpret_cast<UInt8*>(buffer), sector_sz, - size_buffer); -} - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { - drv_std_input_output_ahci<NO, YES, NO>(lba, reinterpret_cast<UInt8*>(buffer), sector_sz, - size_buffer); -} - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Bool drv_std_init(UInt16& pi) { - BOOL atapi = NO; - return drv_std_init_ahci(pi, atapi); -} - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Bool drv_std_detected(Void) { - return drv_std_detected_ahci(); -} - -//////////////////////////////////////////////////// -/** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. - */ -//////////////////////////////////////////////////// -SizeT drv_std_get_sector_count() { - return drv_get_sector_count_ahci(); -} - -//////////////////////////////////////////////////// -/// @brief Get the drive size. -/// @return Disk size in bytes. -//////////////////////////////////////////////////// -SizeT drv_std_get_size() { - return drv_get_size_ahci(); -} - -#endif // ifdef __AHCI__ - -namespace Kernel { -/// @brief Initialize an AHCI device (StorageKit) -UInt16 sk_init_ahci_device(BOOL atapi) { - UInt16 pi = 0; - - if (drv_std_init_ahci(pi, atapi)) kSATAPortsImplemented = pi; - - return pi; -} - -/// @brief Implementation details namespace. -namespace Detail { - /// @brief Read AHCI device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_read_ahci(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) { - AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_std_input_output_ahci<NO, YES, NO>(disk->fPacket.fPacketLba / kAHCISectorSize, - (UInt8*) disk->fPacket.fPacketContent, kAHCISectorSize, - disk->fPacket.fPacketSize); - } - - /// @brief Write AHCI device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_write_ahci(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) { - AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_std_input_output_ahci<YES, YES, NO>(disk->fPacket.fPacketLba / kAHCISectorSize, - (UInt8*) disk->fPacket.fPacketContent, kAHCISectorSize, - disk->fPacket.fPacketSize); - } -} // namespace Detail - -/// @brief Acquires a new AHCI device with drv_index in mind. -/// @param drv_index The drive index to assign. -/// @return A wrapped device interface if successful, or error code. -ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(UInt32 drv_index) { - if (!drv_std_detected_ahci()) return ErrorOr<AHCIDeviceInterface>(kErrorDisk); - - AHCIDeviceInterface device(Detail::sk_io_read_ahci, Detail::sk_io_write_ahci); - - device.SetPortsImplemented(kSATAPortsImplemented); - device.SetIndex(drv_index); - - return ErrorOr<AHCIDeviceInterface>(device); -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc deleted file mode 100644 index cf6147d9..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc +++ /dev/null @@ -1,199 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @file DMA+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver (DMA mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/PCI/Iterator.h> -#include <modules/ATA/ATA.h> - -#if defined(__ATA_DMA__) - -#define kATADataLen (256) - -using namespace Kernel; -using namespace Kernel::HAL; - -/// BUGS: 0 - -STATIC Boolean kATADetected = false; -STATIC Int32 kATADeviceType ATTRIBUTE(unused) = kATADeviceCount; -STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; -STATIC Kernel::PCI::Device kATADevice; -STATIC Char kATADiskModel[50] ATTRIBUTE(unused) = {"GENERIC DMA"}; - -Boolean drv_std_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (status_rdy & ATA_SR_ERR) return false; - - if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -Void drv_std_select(UInt16 Bus) { - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - NE_UNUSED(Bus); - NE_UNUSED(Drive); - NE_UNUSED(OutBus); - NE_UNUSED(OutMaster); - - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - - for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { - kATADevice = iterator[device_index].Leak(); // And then leak the reference. - - /// IDE interface - if (kATADevice.Subclass() == 0x01) { - break; - } - } - - return NO; -} - -namespace Kernel::Detail { -struct PRDEntry final { - UInt32 mAddress; - UInt16 mByteCount; - UInt16 mFlags; /// @param PRD flags, set to 0x8000 to indicate end of prd. -}; -} // namespace Kernel::Detail - -static UIntPtr kReadAddr = mib_cast(2); -static UIntPtr kWriteAddr = mib_cast(2) + kib_cast(64); - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - if (Size > kib_cast(64)) return; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - rt_copy_memory((VoidPtr) Buf, (VoidPtr) kReadAddr, Size); - - drv_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz - 1) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - Kernel::Detail::PRDEntry* prd = - (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct. - - prd->mAddress = (UInt32) (UIntPtr) kReadAddr; - prd->mByteCount = Size - 1; - prd->mFlags = 0x8000; // indicate the end of prd. - - rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32) (UIntPtr) prd); - - rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_READ_DMA); - - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine - - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; - - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine - - rt_copy_memory((VoidPtr) kReadAddr, (VoidPtr) Buf, Size); - - delete prd; - prd = nullptr; -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - if (Size > kib_cast(64)) return; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - rt_copy_memory((VoidPtr) Buf, (VoidPtr) kWriteAddr, Size); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz - 1)) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - Kernel::Detail::PRDEntry* prd = (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4); - - prd->mAddress = (UInt32) (UIntPtr) kWriteAddr; - prd->mByteCount = Size - 1; - prd->mFlags = 0x8000; - - rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32) (UIntPtr) prd); - rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA); - - rt_out8(IO + 0x00, 0x09); // Start DMA engine - - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; - - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine - - delete prd; - prd = nullptr; -} - -/***********************************************************************************/ -/// @brief Is ATA detected? -/***********************************************************************************/ -Boolean drv_std_detected(Void) { - return kATADetected; -} - -/***********************************************************************************/ -/*** - @brief Gets the number of sectors inside the drive. - @return Number of sectors, or zero. -*/ -/***********************************************************************************/ -Kernel::SizeT drv_std_get_sector_count() { - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; -} - -/***********************************************************************************/ -/// @brief Get the size of the current drive. -/***********************************************************************************/ -Kernel::SizeT drv_std_get_size() { - return (drv_std_get_sector_count()) * kATASectorSize; -} - -#endif /* ifdef __ATA_DMA__ */ diff --git a/dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc deleted file mode 100644 index 88f95a86..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <modules/NVME/NVME.h> - -using namespace Kernel; diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc deleted file mode 100644 index 0516be39..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ /dev/null @@ -1,278 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @file PIO+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver (PIO mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DriveMgr.h> -#include <StorageKit/ATA.h> -#include <modules/ATA/ATA.h> - -using namespace Kernel; -using namespace Kernel::HAL; - -/// BUGS: 0 - -#define kATADataLen 256 - -STATIC Boolean kATADetected = false; -STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; -STATIC Char kATADiskModel[50] = {"GENERIC PIO"}; - -static Boolean drv_pio_std_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((stat_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (stat_rdy & ATA_SR_ERR) return false; - - if (!(stat_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -STATIC Void drv_pio_std_select(UInt16 Bus) { - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_pio_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - UInt16 IO = Bus; - - NE_UNUSED(Drive); - - drv_pio_std_select(IO); - - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (stat_rdy & ATA_SR_ERR) { - return false; - } - - if ((stat_rdy & ATA_SR_BSY)) goto ATAInit_Retry; - - OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - drv_pio_std_select(IO); - - rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; - - /// fetch serial info - /// model, speed, number of sectors... - - for (SizeT i = 0ul; i < kATADataLen; ++i) { - kATAIdentifyData[i] = rt_in16(OutBus + ATA_REG_DATA); - } - - for (Int32 i = 0; i < 20; i++) { - kATADiskModel[i * 2] = (kATAIdentifyData[27 + i] >> 8) & 0xFF; - kATADiskModel[i * 2 + 1] = kATAIdentifyData[27 + i] & 0xFF; - } - - kATADiskModel[40] = '\0'; - - (Void)(kout << "Drive Model: " << kATADiskModel << kendl); - - return true; -} - -Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - drv_pio_std_wait_io(IO); - - auto in = rt_in16(IO + ATA_REG_DATA); - - Buf[IndexOff] = in & 0xFF; - Buf[IndexOff + 1] = (in >> 8) & 0xFF; - } -} - -Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)) - ; - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - drv_pio_std_wait_io(IO); - - UInt8 low = (UInt8) Buf[IndexOff]; - UInt8 high = (IndexOff + 1 < Size) ? (UInt8) Buf[IndexOff + 1] : 0; - UInt16 packed = (high << 8) | low; - - rt_out16(IO + ATA_REG_DATA, packed); - } -} - -/// @brief is ATA detected? -Boolean drv_pio_std_detected(Void) { - return kATADetected; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. - */ -SizeT drv_pio_get_sector_count() { - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; -} - -/// @brief Get the drive size. -SizeT drv_pio_get_size() { - return (drv_pio_get_sector_count()) * kATASectorSize; -} - -namespace Kernel { -/// @brief Initialize an PIO device (StorageKit function) -/// @param is_master is the current PIO master? -/// @return [io:master] for PIO device. -BOOL sk_init_ata_device(BOOL is_master, UInt16& io, UInt8& master) { - return drv_pio_std_init(ATA_SECONDARY_IO, is_master, io, master); -} - -/// @brief Implementation details namespace. -namespace Detail { - /// @brief Read PIO device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_read_pio(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) { - ATADeviceInterface* dev = (ATADeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_pio_std_read(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), - (Char*) disk->fPacket.fPacketContent, kATASectorSize, - disk->fPacket.fPacketSize); - } - - /// @brief Write PIO device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_write_pio(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) { - ATADeviceInterface* dev = (ATADeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_pio_std_write(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), - (Char*) disk->fPacket.fPacketContent, kATASectorSize, - disk->fPacket.fPacketSize); - } -} // namespace Detail - -/// @brief Acquires a new PIO device with drv_index in mind. -/// @param drv_index The drive index to assign. -/// @return A wrapped device interface if successful, or error code. -ErrorOr<ATADeviceInterface> sk_acquire_ata_device(Int32 drv_index) { - /// here we don't check if we probed ATA, since we'd need to grab IO after that. - ATADeviceInterface device(Detail::sk_io_read_pio, Detail::sk_io_write_pio); - - device.SetIndex(drv_index); - - return ErrorOr<ATADeviceInterface>(device); -} -} // namespace Kernel - -#ifdef __ATA_PIO__ - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - drv_pio_std_read(Lba, IO, Master, Buf, SectorSz, Size); -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - drv_pio_std_write(Lba, IO, Master, Buf, SectorSz, Size); -} - -SizeT drv_std_get_size() { - return drv_pio_get_size(); -} - -SizeT drv_std_get_sector_count() { - return drv_pio_get_sector_count(); -} - -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - return drv_pio_std_init(Bus, Drive, OutBus, OutMaster); -} - -#endif
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc deleted file mode 100644 index 0200ec5a..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <modules/SCSI/SCSI.h> - -using namespace Kernel; - -///! @brief ATAPI SCSI packet. -const ATTRIBUTE(unused) scsi_packet_type_12 kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; diff --git a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc deleted file mode 100644 index c4d0154b..00000000 --- a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/KPC.h> -#include <modules/APM/APM.h> - -using namespace Kernel; - -/// @brief Send APM command to its IO space. -/// @param base_dma the IO base port. -/// @param cmd the command. -/// @return status code. -EXTERN_C Int32 apm_send_io_command(UInt16 cmd) { - switch (cmd) { - case kAPMPowerCommandReboot: { - asm volatile( - "ldr x0, =0x84000004\n" - "svc #0\n"); - - return kErrorSuccess; - } - case kAPMPowerCommandShutdown: { - asm volatile( - "ldr x0, =0x84000008\n" - "svc #0\n"); - - return kErrorSuccess; - } - default: - return kErrorInvalidData; - } -} diff --git a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h deleted file mode 100644 index 208bf82e..00000000 --- a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h +++ /dev/null @@ -1,19 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <HALKit/ARM64/Processor.h> -#include <NeKit/Defines.h> - -/************************************************** */ -/* INITIALIZE THE GIC ON THE CURRENT CORE. */ -/* WITH AN EXECUTION LEVEL IN MIND. */ -/************************************************** */ - -namespace Kernel { -Void mp_init_cores(Void) noexcept; -}
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/CxxAbi.cc b/dev/kernel/HALKit/ARM64/CxxAbi.cc deleted file mode 100644 index 7b4eca20..00000000 --- a/dev/kernel/HALKit/ARM64/CxxAbi.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DebugOutput.h> -#include <KernelKit/KPC.h> -#include <NeKit/CxxAbi.h> - -atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; - -uarch_t __atexit_func_count; - -/// @brief dynamic shared object Handle. -Kernel::UIntPtr __dso_handle; - -EXTERN_C void __chkstk(void) {} - -EXTERN_C int atexit(void (*f)(), void* arg, void* dso) { - if (__atexit_func_count >= kAtExitMacDestructors) return 1; - - __atexit_funcs[__atexit_func_count].destructor_func = f; - __atexit_funcs[__atexit_func_count].obj_ptr = arg; - __atexit_funcs[__atexit_func_count].dso_handle = dso; - - __atexit_func_count++; - - return 0; -} - -EXTERN_C void __cxa_finalize(void* f) { - uarch_t i = __atexit_func_count; - if (!f) { - while (i--) { - if (__atexit_funcs[i].destructor_func) { - (*__atexit_funcs[i].destructor_func)(); - __atexit_funcs[i].destructor_func = 0; - }; - } - - return; - } - - while (i--) { - if (__atexit_funcs[i].destructor_func) { - (*__atexit_funcs[i].destructor_func)(); - __atexit_funcs[i].destructor_func = 0; - }; - } -} - -namespace cxxabiv1 { -EXTERN_C int __cxa_guard_acquire(__guard* g) { - (void) g; - return 0; -} - -EXTERN_C int __cxa_guard_release(__guard* g) { - *(char*) g = 1; - return 0; -} - -EXTERN_C void __cxa_guard_abort(__guard* g) { - (void) g; -} -} // namespace cxxabiv1 - -EXTERN_C Kernel::Void _purecall(void* self) { - (Kernel::Void)(Kernel::kout << "object: " - << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self))); - (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); -} - -EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) { - NE_UNUSED(thread_obj); -} - -EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void) { - NE_UNUSED(0); -} - -EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) { - NE_UNUSED(0); -} - -EXTERN_C Kernel::Int _tls_index = 0UL; diff --git a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc deleted file mode 100644 index 9a8661cd..00000000 --- a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/HeapMgr.h> -#include <NeKit/KString.h> -#include <modules/ACPI/ACPIFactoryInterface.h> -#include <modules/APM/APM.h> - -namespace Kernel { -ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {} - -BOOL ACPIFactoryInterface::Shutdown() { - apm_send_io_command(kAPMPowerCommandShutdown); - return NO; -} - -/// @brief Reboot machine in either ACPI or by triple faulting. -/// @return nothing it's a reboot. -Void ACPIFactoryInterface::Reboot() { - apm_send_io_command(kAPMPowerCommandReboot); -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc deleted file mode 100644 index 2a3c73e5..00000000 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#define GICD_BASE 0x08000000
-#define GICC_BASE 0x08010000
-
-#define GICD_CTLR 0x000
-#define GICD_ISENABLER 0x100
-#define GICD_ICENABLER 0x180
-#define GICD_ISPENDR 0x200
-#define GICD_ICPENDR 0x280
-#define GICD_IPRIORITYR 0x400
-#define GICD_ITARGETSR 0x800
-#define GICD_ICFGR 0xC00
-
-#define GICC_CTLR 0x000
-#define GICC_PMR 0x004
-#define GICC_IAR 0x00C
-#define GICC_EOIR 0x010
-
-#include <HALKit/ARM64/ApplicationProcessor.h>
-#include <HALKit/ARM64/Processor.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/HardwareThreadScheduler.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <KernelKit/Timer.h>
-
-// ================================================================= //
-
-namespace Kernel {
-struct HAL_HARDWARE_THREAD final {
- HAL::StackFramePtr mFramePtr;
- ProcessID mThreadID{0};
-};
-
-STATIC HAL_HARDWARE_THREAD kHWThread[kMaxAPInsideSched] = {{nullptr}};
-
-namespace Detail {
- STATIC BOOL kGICEnabled = NO;
-
- /***********************************************************************************/
- /// @brief Enables the GIC with EL0 configuration.
- /// @internal
- /***********************************************************************************/
- STATIC Void mp_setup_gic_el0(Void) {
- ke_dma_write<UInt32>(GICD_BASE, GICD_CTLR, YES);
-
- UInt32 gicc_ctlr = ke_dma_read<UInt32>(GICC_BASE, GICC_CTLR);
-
- const UInt8 kEnableSignalInt = 0x1;
-
- gicc_ctlr |= kEnableSignalInt;
- gicc_ctlr |= (kEnableSignalInt << 0x1);
-
- ke_dma_write<UInt32>(GICC_BASE, GICC_CTLR, gicc_ctlr);
-
- ke_dma_write<UInt32>(GICC_BASE, GICC_PMR, 0xFF);
-
- UInt32 icfgr = ke_dma_read<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4);
-
- icfgr |= (0x2 << ((32 % 16) * 2));
-
- ke_dma_write<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr);
- ke_dma_write<UInt32>(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8));
- ke_dma_write<UInt32>(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8));
- ke_dma_write<UInt32>(GICD_BASE, GICD_ISENABLER + 4, 0x01);
- }
-
- EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void) {
- UInt32 interrupt_id = ke_dma_read<UInt32>(GICC_BASE, GICC_IAR);
-
- if ((interrupt_id & 0x3FF) < 1020) {
- auto interrupt = interrupt_id & 0x3FF;
-
- const UInt16 kInterruptScheduler = 0x20;
-
- (Void)(kout << "SMP: AP: " << hex_number(interrupt) << kendl);
-
- switch (interrupt) {
- case kInterruptScheduler: {
- ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
- UserProcessHelper::StartScheduling();
- break;
- }
- default: {
- ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
- break;
- }
- }
-
- return YES;
- }
-
- return NO;
- }
-} // namespace Detail
-
-/***********************************************************************************/
-/// @brief Get current stack frame for a thread.
-/// @param thrdid The thread ID.
-/***********************************************************************************/
-
-EXTERN_C HAL::StackFramePtr mp_get_current_task(ProcessID thrdid) {
- return kHWThread[thrdid].mFramePtr;
-}
-
-/***********************************************************************************/
-/// @brief Register current stack frame for a thread.
-/// @param stack_frame The current stack frame.
-/// @param thrdid The thread ID.
-/***********************************************************************************/
-
-EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) {
- MUST_PASS(Detail::kGICEnabled);
-
- if (!stack_frame) return NO;
- if (thrdid > kMaxAPInsideSched) return NO;
-
- const auto process_index = thrdid;
-
- kHWThread[process_index].mFramePtr = stack_frame;
- kHWThread[process_index].mThreadID = thrdid;
-
- return YES;
-}
-
-/***********************************************************************************/
-/// @brief Initialize the Global Interrupt Controller.
-/// @internal
-/***********************************************************************************/
-Void mp_init_cores(Void) noexcept {
- if (!Detail::kGICEnabled) {
- Detail::kGICEnabled = YES;
- Detail::mp_setup_gic_el0();
- }
-}
-} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s b/dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s deleted file mode 100644 index dca52571..00000000 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessorStartup.s +++ /dev/null @@ -1,12 +0,0 @@ -.text - -.global hal_ap_blob_start -.global hal_ap_blob_length - -hal_ap_blob_start: - ret - -.data - -hal_ap_blob_length: - .long 4 diff --git a/dev/kernel/HALKit/ARM64/HalCommonAPI.s b/dev/kernel/HALKit/ARM64/HalCommonAPI.s deleted file mode 100644 index f0c69368..00000000 --- a/dev/kernel/HALKit/ARM64/HalCommonAPI.s +++ /dev/null @@ -1,9 +0,0 @@ -/* (c) 2024-2025 Amlal El Mahrouss */ - -.text - -.global hal_flush_tlb - -hal_flush_tlb: - tlbi vmalle1 - ret diff --git a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc deleted file mode 100644 index b89f68bd..00000000 --- a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc +++ /dev/null @@ -1,159 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr.h> -#include <NeKit/KString.h> -#include <SignalKit/Signals.h> - -EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip); -EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void); - -EXTERN_C BOOL kEndOfInterrupt; -EXTERN_C UInt8 kEndOfInterruptVector; - -STATIC BOOL kIsRunning = NO; - -/// @note This is managed by the system software. -STATIC void hal_int_send_eoi(UInt8 vector) { - kEndOfInterrupt = YES; - kEndOfInterruptVector = vector; -} - -/// @brief Handle GPF fault. -/// @param rsp -EXTERN_C Kernel::Void int_handle_gpf(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_int_send_eoi(13); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Handle page fault. -/// @param rsp -EXTERN_C void int_handle_pf(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_int_send_eoi(14); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Handle scheduler interrupt. -EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) { - NE_UNUSED(rsp); - - hal_int_send_eoi(32); - - while (kIsRunning) - ; - - kIsRunning = YES; - - mp_handle_gic_interrupt_el0(); - - kIsRunning = NO; -} - -/// @brief Handle math fault. -/// @param rsp -EXTERN_C void int_handle_math(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_int_send_eoi(8); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Handle any generic fault. -/// @param rsp -EXTERN_C void int_handle_generic(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_int_send_eoi(30); - - Kernel::kout << "Kernel: Generic Process Fault.\r"; - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; - - Kernel::kout << "Kernel: SIGKILL status.\r"; -} - -EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - - hal_int_send_eoi(3); - - process.Leak().Signal.SignalArg = rip; - process.Leak().Signal.SignalID = SIGTRAP; - - process.Leak().Signal.Status = process.Leak().Status; - - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; -} - -/// @brief Handle #UD fault. -/// @param rsp -EXTERN_C void int_handle_ud(Kernel::UIntPtr rsp) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); - - hal_int_send_eoi(6); - - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; -} - -/// @brief Enter syscall from assembly (libSystem only) -/// @param stack the stack pushed from assembly routine. -/// @return nothing. -EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash, - Kernel::UIntPtr rdx_syscall_arg) { - hal_int_send_eoi(50); - - if (!Kernel::kCurrentUser) return; - - for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { - if (kSysCalls[i].fHooked && rcx_hash == kSysCalls[i].fHash) { - if (kSysCalls[i].fProc) { - (kSysCalls[i].fProc)((Kernel::VoidPtr) rdx_syscall_arg); - } - } - } -} - -/// @brief Enter Kernel call from assembly (libDDK only). -/// @param stack the stack pushed from assembly routine. -/// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt, - Kernel::UIntPtr arg, Kernel::SizeT sz) { - if (!Kernel::kRootUser) return; - if (Kernel::kCurrentUser != Kernel::kRootUser) return; - if (!Kernel::kCurrentUser->IsSuperUser()) return; - - for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { - if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) { - if (kKernCalls[i].fProc) { - (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz); - } - } - } -} diff --git a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc deleted file mode 100644 index c0da9c3a..00000000 --- a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc +++ /dev/null @@ -1,71 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DebugOutput.h> -#include <NeKit/New.h> -#include <NeKit/Utils.h> - -namespace Kernel { -EXTERN_C void ke_io_write(DeviceInterface<const Char*>* self, const Char* bytes) { -#ifdef __DEBUG__ - if (*bytes == 0) return; - - SizeT index = 0; - SizeT len = 0; - - index = 0; - len = rt_string_len(bytes, 256U); - - volatile UInt8* uart_ptr = (UInt8*) 0x09000000; - - while (index < len) { - if (bytes[index] == '\r') *uart_ptr = '\r'; - - *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index]; - ++index; - } -#endif // __DEBUG__ -} - -TerminalDevice::~TerminalDevice() = default; - -EXTERN_C void ke_io_read(DeviceInterface<const Char*>* self, const Char* bytes) { -#ifdef __DEBUG__ - SizeT index = 0; - - volatile UInt8* uart_ptr = (UInt8*) 0x09000000; - - ///! TODO: Look on how to wait for the UART to complete. - while (Yes) { - auto in = *uart_ptr; - - ///! If enter pressed then break. - if (in == 0xD) { - break; - } - - if (in < '0' || in < 'A' || in < 'a') { - if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') { - continue; - } - } - - ((char*) bytes)[index] = in; - - ++index; - } - - ((char*) bytes)[index] = 0; -#endif // __DEBUG__ -} - -TerminalDevice TerminalDevice::The() noexcept { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; -} - -} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalHandoverStub.s b/dev/kernel/HALKit/ARM64/HalHandoverStub.s deleted file mode 100644 index 5d5647c4..00000000 --- a/dev/kernel/HALKit/ARM64/HalHandoverStub.s +++ /dev/null @@ -1,19 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. -;; * -;; * ======================================================== -;; */ - -.section .ldr - - ;; // MAGIC -.quad 0xDAB4 - ;; // VERSION (1.0.0) -.word 100 - ;; // CPU (ARM64) -.word 0 - ;; // TYPE (KERNEL) -.word 122 diff --git a/dev/kernel/HALKit/ARM64/HalInterruptAPI.s b/dev/kernel/HALKit/ARM64/HalInterruptAPI.s deleted file mode 100644 index cafebb7d..00000000 --- a/dev/kernel/HALKit/ARM64/HalInterruptAPI.s +++ /dev/null @@ -1,3 +0,0 @@ -/* (c) 2024-2025 Amlal El Mahrouss */ - -.text diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc deleted file mode 100644 index e36535c3..00000000 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <CFKit/Property.h> -#include <FirmwareKit/Handover.h> -#include <HALKit/ARM64/ApplicationProcessor.h> -#include <HALKit/ARM64/Processor.h> -#include <KernelKit/CodeMgr.h> -#include <KernelKit/FileMgr.h> -#include <KernelKit/HardwareThreadScheduler.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/PEFCodeMgr.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/Json.h> -#include <NetworkKit/IPC.h> -#include <modules/ACPI/ACPIFactoryInterface.h> -#include <modules/CoreGfx/CoreGfx.h> - -#ifndef __NE_MODULAR_KERNEL_COMPONENTS__ -EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { - using namespace Kernel; - - /************************************************** */ - /* INITIALIZE AND VALIDATE HEADER. */ - /************************************************** */ - - kHandoverHeader = handover_hdr; - - if (kHandoverHeader->f_Magic != kHandoverMagic && - kHandoverHeader->f_Version != kHandoverVersion) { - return; - } - -#ifdef __NE_ARM64_EFI__ - fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]); - - Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, - handover_hdr->f_HardwareTables.f_ImageHandle); -#endif - - FB::cg_clear_video(); - - /************************************** */ - /* INITIALIZE BIT MAP. */ - /************************************** */ - - kBitMapCursor = 0UL; - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>( - reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart)); - - /// @note do initialize the interrupts after it. - - Kernel::mp_init_cores(); - - while (YES) - ; -} -#endif diff --git a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc deleted file mode 100644 index 6837ba1c..00000000 --- a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc +++ /dev/null @@ -1,54 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <FirmwareKit/Handover.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/FileMgr.h> -#include <KernelKit/Timer.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> -#include <modules/CoreGfx/CoreGfx.h> -#include <modules/CoreGfx/TextGfx.h> - -/* Each error code is attributed with an ID, which will prompt a string onto the - * screen. Wait for debugger... */ - -namespace Kernel { -/// @brief Dumping factory class. -class RecoveryFactory final { - public: - STATIC Void Recover() noexcept; -}; - -/***********************************************************************************/ -/// @brief Stops execution of the kernel. -/// @param id kernel stop ID. -/***********************************************************************************/ -Void ke_panic(const Kernel::Int32& id, const Char* message) { - (Void)(kout << "*** STOP ***\r"); - (Void)(kout << "Kernel_Panic_MSG: " << message << kendl); - (Void)(kout << "Kernel_Panic_ID: " << hex_number(id) << kendl); - - RecoveryFactory::Recover(); -} - -Void RecoveryFactory::Recover() noexcept { - while (YES) { - HAL::rt_halt(); - } -} - -void ke_runtime_check(bool expr, const Char* file, const Char* line) { - if (!expr) { - (Void)(kout << "Kernel_Panic_FILE: " << file << kendl); - (Void)(kout << "Kernel_Panic_LINE: " << line << kendl); - - ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed - } -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc deleted file mode 100644 index d597ccce..00000000 --- a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: HalPagingMgr.cc - Purpose: Platform Paging Manager. - -======================================== */ - -#include <HALKit/ARM64/Paging.h> -#include <HALKit/ARM64/Processor.h> - -namespace Kernel::HAL { -typedef UInt32 PageTableIndex; - -EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address) { - if (!virtual_address) return 0; - - UInt64 ttbr0_val = 0; - - asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val)); - volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val); - - UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF; - UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF; - UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF; - - if (!l1_table[l1_idx]) return 0; - - volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL); - - if (!l2_table[l2_idx]) return 0; - - volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL); - - if (!l3_table[l3_idx]) return 0; - - return (l3_table[l3_idx] & ~0xFFFUL); -} - -/// @brief Maps or allocates a page from virtual_address. -/// @param virtual_address a valid virtual address. -/// @param phys_addr point to physical address. -/// @param flags the flags to put on the page. -/// @return Status code of page manipulation process. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, - UInt32 level) { - if (!virtual_address || !flags || !physical_address) return kErrorInvalidData; - - UInt64 ttbr0_val = 0; - - asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val)); - volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val); - - UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF; - UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF; - UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF; - - if (!l1_table[l1_idx]) return kErrorInvalidData; - - volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL); - - if (!l2_table[l2_idx]) return kErrorInvalidData; - - volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL); - - l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; - - switch (level) { - case 2: { - l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; - return kErrorSuccess; - } - case 1: { - l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; - return kErrorSuccess; - } - case 0: { - l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; - return kErrorSuccess; - } - } - - return kErrorInvalidData; -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCore.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCore.cc deleted file mode 100644 index 467547b0..00000000 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCore.cc +++ /dev/null @@ -1,21 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/ProcessScheduler.h> - -namespace Kernel { -/// @brief Wakes up thread. -/// Wakes up thread from the hang state. -Void mp_wakeup_thread(HAL::StackFrame* stack) { - NE_UNUSED(stack); -} - -/// @brief makes the thread sleep on a loop. -/// hooks and hangs thread to prevent code from executing. -Void mp_hang_thread(HAL::StackFrame* stack) { - NE_UNUSED(stack); -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc deleted file mode 100644 index b1728bac..00000000 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitives.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <HALKit/ARM64/Processor.h>
-#include <KernelKit/ProcessScheduler.h>
-
-namespace Kernel {
-/***********************************************************************************/
-/// @brief Unimplemented function (crashes by default)
-/// @param process The process handle.
-/***********************************************************************************/
-
-EXTERN_C Void __ne_pure_call(USER_PROCESS* process) {
- if (process) process->Crash();
-}
-
-/***********************************************************************************/
-/// @brief Validate user stack.
-/// @param stack_ptr the frame pointer.
-/***********************************************************************************/
-
-EXTERN_C Bool hal_check_task(HAL::StackFramePtr stack_ptr) {
- if (!stack_ptr) return No;
-
- return stack_ptr->SP != 0 && stack_ptr->IP != 0;
-}
-} // namespace Kernel
diff --git a/dev/kernel/HALKit/ARM64/HalTimer.cc b/dev/kernel/HALKit/ARM64/HalTimer.cc deleted file mode 100644 index 2f524a1b..00000000 --- a/dev/kernel/HALKit/ARM64/HalTimer.cc +++ /dev/null @@ -1,15 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: HalTimer.cc - Purpose: HAL timer - - Revision History: - - 07/07/24: Added file (amlel) - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/Timer.h>
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h deleted file mode 100644 index 766210b3..00000000 --- a/dev/kernel/HALKit/ARM64/Paging.h +++ /dev/null @@ -1,107 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -/** --------------------------------------------------- - - * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. - -------------======================================== */ - -#ifdef __NE_ARM64__ - -#include <NeKit/Defines.h> - -#ifndef kPageMax -#define kPageMax (0x200) -#endif //! kPageMax - -#ifndef kPageAlign -#define kPageAlign (0x1000) -#endif //! kPageAlign - -#ifndef kPageSize -#define kPageSize (0x1000) -#endif // !kPageSize - -//! short format address range - -#define c16KBPage 0b000 -#define c8KBPage 0b001 -#define c4KBPage 0b010 -#define c2KBPage 0b011 -#define c1KBPage 0b100 -#define c512BPage 0b101 -#define c256BPage 0b110 -#define c128BPage 0b111 - -/// Long format address range - -#define cPageMAll \ - { 0b000, 0b000 } -#define cPageMToMax(M) \ - { M, 0b000 } -#define cPageMaxToM(M) \ - { 0b000, M } -#define cPageMToN(M, N) \ - { M, N } - -namespace Kernel::HAL { -struct PACKED PTE_4KB final { - UInt64 Valid : 1; - UInt64 Table : 1; - UInt64 AttrIndex : 3; - UInt64 NS : 1; - UInt64 AP : 2; - UInt64 SH : 2; - UInt64 AF : 1; - UInt64 NG : 1; - UInt64 Reserved1 : 1; - UInt64 Contiguous : 1; - UInt64 Dirty : 1; - UInt64 Reserved : 2; - UInt64 PhysicalAddress : 36; - UInt64 Reserved3 : 4; - UInt64 PXN : 1; - UInt64 XN : 1; - UInt64 Reserved4 : 9; -}; - -namespace Detail { - enum class ControlRegisterBits { - ProtectedModeEnable = 0, - MonitorCoProcessor = 1, - Emulation = 2, - TaskSwitched = 3, - ExtensionType = 4, - NumericError = 5, - WriteProtect = 16, - AlignementMask = 18, - NotWriteThrough = 29, - CacheDisable = 30, - PageEnable = 31, - }; - - inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); } -} // namespace Detail - -struct PDE_4KB final { - PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax]; -}; - -auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr; -auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; -} // namespace Kernel::HAL - -namespace Kernel { -typedef HAL::PTE_4KB PTE; -typedef HAL::PDE_4KB PDE; -} // namespace Kernel - -EXTERN_C void hal_flush_tlb(); - -#endif // __NE_ARM64__
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h deleted file mode 100644 index 716d317b..00000000 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ /dev/null @@ -1,78 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#ifdef __NE_ARM64__ - -#include <FirmwareKit/Handover.h> -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/Utils.h> - -#define kCPUBackendName "aarch64" - -namespace Kernel::HAL { -struct PACKED Register64 final { - UShort Limit; - UIntPtr Base; -}; - -/// @brief Memory Manager mapping flags. -enum { - kMMFlagsInvalid = 1 << 0, - kMMFlagsPresent = 1 << 1, - kMMFlagsWr = 1 << 2, - kMMFlagsUser = 1 << 3, - kMMFlagsNX = 1 << 4, - kMMFlagsCount = 4, -}; - -/// @brief Set a PTE from pd_base. -/// @param virt_addr a valid virtual address. -/// @param phys_addr point to physical address. -/// @param flags the flags to put on the page. -/// @return Status code of page manip. -EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, - UInt32 level = 2); - -EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address); - -typedef UIntPtr Reg; -typedef Register64 Register; - -/// @note let's keep the same name as AMD64 HAL. -struct PACKED StackFrame { - Reg IP; - Reg SP; - Reg R8; - Reg R9; - Reg R10; - Reg R11; - Reg R12; - Reg R13; - Reg R14; - Reg R15; -}; - -typedef StackFrame* StackFramePtr; - -inline Void rt_halt() noexcept { - while (Yes) { - } -} - -inline Void hal_wfi(Void) { - asm volatile("wfi"); -} -} // namespace Kernel::HAL - -inline Kernel::VoidPtr kKernelBitMpStart = nullptr; -inline Kernel::UIntPtr kKernelBitMpSize = 0UL; - -#include <HALKit/ARM64/Paging.h> - -#endif // __NE_ARM64__
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc b/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc deleted file mode 100644 index 0200ec5a..00000000 --- a/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <modules/SCSI/SCSI.h> - -using namespace Kernel; - -///! @brief ATAPI SCSI packet. -const ATTRIBUTE(unused) scsi_packet_type_12 kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; diff --git a/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc b/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc deleted file mode 100644 index 9971b2a8..00000000 --- a/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc +++ /dev/null @@ -1,8 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/// @file UFS.cc -/// @brief UFS Flash Memory support. diff --git a/dev/kernel/HALKit/POWER/.gitkeep b/dev/kernel/HALKit/POWER/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/POWER/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/POWER/AP.h b/dev/kernel/HALKit/POWER/AP.h deleted file mode 100644 index efe4ceff..00000000 --- a/dev/kernel/HALKit/POWER/AP.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: AP.h - Purpose: POWER hardware threads. - - Revision History: - - 14/04/24: Added file (amlel) - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -struct HAL_HARDWARE_THREAD; - -/// @brief hardware thread indentification type. -typedef Kernel::Int32 hal_ap_kind; - -/// @brief Hardware thread information structure. -typedef struct HAL_HARDWARE_THREAD { - Kernel::UIntPtr fStartAddress; - Kernel::UIntPtr fStackPtr; - Kernel::UIntPtr fFramePtr; - Kernel::UInt8 fPrivileged : 1; - Kernel::UInt32 fPageMemoryFlags; - hal_ap_kind fIdentNumber; -} HAL_HARDWARE_THREAD; - -/// @brief Set PC to specific hart. -/// @param hart the hart -/// @param epc the pc. -/// @return -EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); -} // namespace Kernel diff --git a/dev/kernel/HALKit/POWER/APM/.gitkeep b/dev/kernel/HALKit/POWER/APM/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/POWER/APM/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc deleted file mode 100644 index 84d9b1c1..00000000 --- a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <HALKit/POWER/AP.h> -#include <HALKit/POWER/Processor.h> -#include <KernelKit/DebugOutput.h> - -/// @note This part of the HAL needs an owner. - -namespace Kernel::Detail { -STATIC void mp_hang_fn(void) { - while (YES) - ; -} -} // namespace Kernel::Detail - -namespace Kernel { -/// @brief wakes up thread. -/// wakes up thread from hang. -void mp_wakeup_thread(HAL::StackFramePtr stack) { - if (!stack) return; - - MUST_PASS(stack->R15 > 0); - MUST_PASS(stack->IP > 0); - - hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), - reinterpret_cast<VoidPtr>(stack->IP)); -} - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -void mp_hang_thread(HAL::StackFramePtr stack) { - if (!stack) return; - - MUST_PASS(stack->R15 > 0); - - hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), - reinterpret_cast<VoidPtr>(Kernel::Detail::mp_hang_fn)); -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/POWER/HalDebugOutput.cc b/dev/kernel/HALKit/POWER/HalDebugOutput.cc deleted file mode 100644 index 0c4be809..00000000 --- a/dev/kernel/HALKit/POWER/HalDebugOutput.cc +++ /dev/null @@ -1,24 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <HALKit/POWER/Processor.h> -#include <KernelKit/DebugOutput.h> - -using namespace Kernel; - -/// @brief Writes to COM1. -/// @param bytes -void ke_io_write(const Char* bytes) { - if (!bytes) return; - - SizeT index = 0; - SizeT len = rt_string_len(bytes, 256U); - - while (index < len) { - // TODO - ++index; - } -} diff --git a/dev/kernel/HALKit/POWER/HalHardwareThread.cc b/dev/kernel/HALKit/POWER/HalHardwareThread.cc deleted file mode 100644 index c77040f7..00000000 --- a/dev/kernel/HALKit/POWER/HalHardwareThread.cc +++ /dev/null @@ -1,8 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <HALKit/POWER/Processor.h> -#include <KernelKit/DebugOutput.h> diff --git a/dev/kernel/HALKit/POWER/HalStartSequence.s b/dev/kernel/HALKit/POWER/HalStartSequence.s deleted file mode 100644 index 194e220e..00000000 --- a/dev/kernel/HALKit/POWER/HalStartSequence.s +++ /dev/null @@ -1,14 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -.globl __ImageStart -.extern hal_init_platform -.align 4 -.text - -__ImageStart: - bl hal_init_platform - blr diff --git a/dev/kernel/HALKit/POWER/HalVirtualMemory.cc b/dev/kernel/HALKit/POWER/HalVirtualMemory.cc deleted file mode 100644 index cd9511c9..00000000 --- a/dev/kernel/HALKit/POWER/HalVirtualMemory.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <HALKit/POWER/MMU.h> -#include <HALKit/POWER/Processor.h> -#include <KernelKit/DebugOutput.h> - -/// @note Refer to SoC documentation. - -using namespace Kernel; - -EXTERN_C Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7) { - hal_mtspr(MAS0, mas0); - hal_mtspr(MAS1, mas1); - hal_mtspr(MAS2, mas2); - hal_mtspr(MAS3, mas3); - hal_mtspr(MAS7, mas7); - - hal_flush_tlb(); -} - -EXTERN_C Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts, - UInt8 esel, UInt8 tsize, UInt8 iprot) { - if ((hal_mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1)) { - // this MMU does not allow odd tsize values - return false; - } - - UInt32 mas0 = FSL_BOOKE_MAS0(tlb, esel, 0); - UInt32 mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize); - UInt32 mas2 = FSL_BOOKE_MAS2(epn, wimge); - UInt32 mas3 = FSL_BOOKE_MAS3(rpn, 0, perms); - UInt32 mas7 = FSL_BOOKE_MAS7(rpn); - - hal_write_tlb(mas0, mas1, mas2, mas3, mas7); - - return true; -} - -/// @brief Flush TLB -EXTERN_C void hal_flush_tlb() { - asm volatile("isync;tlbwe;msync;isync"); -} diff --git a/dev/kernel/HALKit/POWER/Processor.h b/dev/kernel/HALKit/POWER/Processor.h deleted file mode 100644 index 46cda33e..00000000 --- a/dev/kernel/HALKit/POWER/Processor.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - Purpose: POWER processor header. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/Utils.h> - -#define rtl_nop_op() asm volatile("mr 0, 0") -#define kHalPPCAlignment __attribute__((aligned(4))) - -namespace Kernel::HAL { -typedef UIntPtr Reg; - -/// @brief Stack frame (as retrieved from assembly.) -struct PACKED StackFrame final { - Reg R8{0}; - Reg R9{0}; - Reg R10{0}; - Reg R11{0}; - Reg R12{0}; - Reg R13{0}; - Reg R14{0}; - Reg R15{0}; - Reg SP{0}; - Reg IP{0}; -}; - -typedef StackFrame* StackFramePtr; - -inline void rt_halt() { - while (true) { - NoOp(); // no oop. - } -} - -inline void rt_cli() { - NoOp(); // no oop -} -} // namespace Kernel::HAL - -EXTERN_C Kernel::Void int_handle_math(Kernel::UIntPtr sp); -EXTERN_C Kernel::Void int_handle_pf(Kernel::UIntPtr sp); - -/// @brief Set TLB. -Kernel::Bool hal_set_tlb(Kernel::UInt8 tlb, Kernel::UInt32 epn, Kernel::UInt64 rpn, - Kernel::UInt8 perms, Kernel::UInt8 wimge, Kernel::UInt8 ts, - Kernel::UInt8 esel, Kernel::UInt8 tsize, Kernel::UInt8 iprot); - -/// @brief Write TLB. -Kernel::Void hal_write_tlb(Kernel::UInt32 mas0, Kernel::UInt32 mas1, Kernel::UInt32 mas2, - Kernel::UInt32 mas3, Kernel::UInt32 mas7); - -/// @brief Flush TLB. -EXTERN_C Kernel::Void hal_flush_tlb(); diff --git a/dev/kernel/HALKit/RISCV/.keep b/dev/kernel/HALKit/RISCV/.keep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/RISCV/.keep +++ /dev/null diff --git a/dev/kernel/HALKit/RISCV/AP.h b/dev/kernel/HALKit/RISCV/AP.h deleted file mode 100644 index 1061b637..00000000 --- a/dev/kernel/HALKit/RISCV/AP.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: AP.h - Purpose: RISC-V hardware threads. - - Revision History: - - 30/01/24: Added file (amlel) - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -typedef Int64 hal_ap_kind; - -typedef struct HAL_HARDWARE_THREAD { - Kernel::UIntPtr fStartAddress; - Kernel::UIntPtr fStackPtr; - Kernel::UIntPtr fFramePtr; - Kernel::UInt8 fPrivileged : 1; - Kernel::UInt32 fPageMemoryFlags; - hal_ap_kind fIdentNumber; -} HAL_HARDWARE_THREAD; - -/// @brief Set PC to specific hart. -/// @param hart the hart -/// @param epc the pc. -/// @return -EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); -} // namespace Kernel diff --git a/dev/kernel/HALKit/RISCV/APM/.gitkeep b/dev/kernel/HALKit/RISCV/APM/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/RISCV/APM/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc deleted file mode 100644 index 520481d1..00000000 --- a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
-
-======================================== */
-
-#include <HALKit/RISCV/AP.h>
-#include <HALKit/RISCV/Processor.h>
-#include <KernelKit/DebugOutput.h>
-
-using namespace Kernel;
-
-namespace Kernel {
-namespace Detail {
- STATIC void mp_hang_fn(void) {
- while (YES)
- ;
- }
-
-} // namespace Detail
-
-/// @brief wakes up thread.
-/// wakes up thread from hang.
-void mp_wakeup_thread(HAL::StackFramePtr stack) {
- if (!stack) return;
-
- hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
- reinterpret_cast<VoidPtr>(stack->IP));
-}
-
-/// @brief makes thread sleep.
-/// hooks and hangs thread to prevent code from executing.
-void mp_hang_thread(HAL::StackFramePtr stack) {
- if (!stack) return;
-
- hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15),
- reinterpret_cast<VoidPtr>(Kernel::Detail::mp_hang_fn));
-}
-
-} // namespace Kernel
diff --git a/dev/kernel/HALKit/RISCV/Storage/.gitkeep b/dev/kernel/HALKit/RISCV/Storage/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/RISCV/Storage/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/X86S/.gitkeep b/dev/kernel/HALKit/X86S/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/X86S/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/X86S/ACPI/.gitkeep b/dev/kernel/HALKit/X86S/ACPI/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/X86S/ACPI/.gitkeep +++ /dev/null diff --git a/dev/kernel/HALKit/X86S/Storage/.gitkeep b/dev/kernel/HALKit/X86S/Storage/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/HALKit/X86S/Storage/.gitkeep +++ /dev/null diff --git a/dev/kernel/KernelKit/BinaryMutex.h b/dev/kernel/KernelKit/BinaryMutex.h deleted file mode 100644 index 5431ab72..00000000 --- a/dev/kernel/KernelKit/BinaryMutex.h +++ /dev/null @@ -1,39 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/Timer.h> -#include <NeKit/Defines.h> - -namespace Kernel { -class USER_PROCESS; - -/// @brief Access control class, which locks a task until one is done. -class BinaryMutex final { - public: - explicit BinaryMutex() = default; - ~BinaryMutex() = default; - - public: - bool IsLocked() const; - bool Unlock() noexcept; - - public: - BOOL WaitForProcess(const UInt32& sec) noexcept; - - public: - bool Lock(USER_PROCESS* process); - bool LockAndWait(USER_PROCESS* process, TimerInterface* timer); - - public: - NE_COPY_DEFAULT(BinaryMutex) - - private: - USER_PROCESS* fLockingProcess{nullptr}; -}; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/CodeMgr.h b/dev/kernel/KernelKit/CodeMgr.h deleted file mode 100644 index e537b26d..00000000 --- a/dev/kernel/KernelKit/CodeMgr.h +++ /dev/null @@ -1,49 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: CodeMgr.h - Purpose: Code Mgr. - - Revision History: - - 30/01/24: Added file (amlel) - 3/8/24: Add UPP struct. - -======================================== */ - -#pragma once - -#include <KernelKit/CoreProcessScheduler.h> -#include <KernelKit/IPEFDylibObject.h> -#include <KernelKit/PE32CodeMgr.h> -#include <KernelKit/PEFCodeMgr.h> - -/// @file CodeMgr.h -/// @brief Code Manager header file. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -namespace Kernel { -/// @brief Main process entrypoint. -typedef void (*rtl_main_kind)(void); - -/// @brief C++ Constructor entrypoint. -typedef void (*rtl_cxx_ctor_kind)(void); - -/// @brief C++ Destructor entrypoint. -typedef void (*rtl_cxx_dtor_kind)(void); - -/// @brief Executes a new process from a function. Kernel code only. -/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be -/// accessible. -/// @param main the start of the process. -/// @return The team's process id. -BOOL rtl_create_kernel_task(HAL::StackFramePtr main, const KID kid) noexcept; - -/// @brief Executes a new process from a function. User code only. -/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be -/// accessible. -/// @param main the start of the process. -/// @return The team's process id. -ProcessID rtl_create_user_process(rtl_main_kind main, const Char* process_name) noexcept; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h deleted file mode 100644 index 54a0614a..00000000 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ /dev/null @@ -1,273 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> - -/// @file CoreProcessScheduler.h -/// @brief Core Process Scheduler header file. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -#define kSchedMinMicroTime (AffinityKind::kStandard) -#define kSchedInvalidPID (-1) -#define kSchedProcessLimitPerTeam (32U) -#define kSchedTeamCount (256U) - -#define kSchedMaxMemoryLimit (gib_cast(128)) /* max physical memory limit */ -#define kSchedMaxStackSz (kib_cast(8)) /* maximum stack size */ - -#define kSchedNameLen (128U) - -EXTERN_C void sched_idle_task(void); - -namespace Kernel { -class USER_PROCESS; -class KERNEL_TASK; -class KernelTaskScheduler; -class UserProcessScheduler; -class UserProcessTeam; - -template <typename T> -struct PROCESS_HEAP_TREE; - -template <typename T> -struct PROCESS_SPECIAL_TREE; - -template <typename T> -struct PROCESS_FILE_TREE; - -enum { - kInvalidTreeKind = 0U, - kRedTreeKind = 100U, - kBlackTreeKind = 101U, - kTreeKindCount = 3U, -}; - -template <typename T> -struct PROCESS_HEAP_TREE { - static constexpr auto kHeap = true; - static constexpr auto kFile = false; - static constexpr auto kSpecial = false; - - T Entry{nullptr}; - SizeT EntrySize{0UL}; - SizeT EntryPad{0UL}; - - UInt32 Color{kBlackTreeKind}; - - struct PROCESS_HEAP_TREE<T>* Parent { - nullptr - }; - struct PROCESS_HEAP_TREE<T>* Child { - nullptr - }; - - struct PROCESS_HEAP_TREE<T>* Prev { - nullptr - }; - struct PROCESS_HEAP_TREE<T>* Next { - nullptr - }; -}; - -template <typename T> -struct PROCESS_FILE_TREE { - static constexpr auto kHeap = false; - static constexpr auto kFile = true; - static constexpr auto kSpecial = false; - - T Entry{nullptr}; - SizeT EntrySize{0UL}; - SizeT EntryPad{0UL}; - - UInt32 Color{kBlackTreeKind}; - - struct PROCESS_FILE_TREE<T>* Parent { - nullptr - }; - - struct PROCESS_FILE_TREE<T>* Child { - nullptr - }; - - struct PROCESS_FILE_TREE<T>* Prev { - nullptr - }; - - struct PROCESS_FILE_TREE<T>* Next { - nullptr - }; -}; - -using ProcessCtx = UInt32; - -template <typename T> -struct PROCESS_SPECIAL_TREE { - static constexpr auto kHeap = false; - static constexpr auto kFile = false; - static constexpr auto kSpecial = true; - - T Entry{nullptr}; - SizeT EntrySize{0UL}; - SizeT EntryPad{0UL}; - - /// @brief a context is where the resource comes from. - ProcessCtx EntryContext{0UL}; // could be a socket, printer, device... - - UInt32 Color{kBlackTreeKind}; - - struct PROCESS_SPECIAL_TREE<T>* Parent { - nullptr - }; - - struct PROCESS_SPECIAL_TREE<T>* Child { - nullptr - }; - - struct PROCESS_SPECIAL_TREE<T>* Prev { - nullptr - }; - - struct PROCESS_SPECIAL_TREE<T>* Next { - nullptr - }; -}; - -/***********************************************************************************/ -/// @brief Subsystem enum type. -/***********************************************************************************/ - -enum class ProcessSubsystem : Int32 { - kProcessSubsystemSecurity = 100, - kProcessSubsystemUser, - kProcessSubsystemService, - kProcessSubsystemDriver, - kProcessSubsystemKernel, - kProcessSubsystemCount = kProcessSubsystemKernel - kProcessSubsystemSecurity + 1, - kProcessSubsystemInvalid = 0xFFFFFFF, -}; - -/***********************************************************************************/ -//! @brief Local Process status enum. -/***********************************************************************************/ -enum class ProcessStatusKind : Int32 { - kInvalid = 0, - kStarting = 100, - kRunning, - kKilled, - kFrozen, - kFinished, - kCount = kFinished - kStarting + 1, -}; - -/***********************************************************************************/ -//! @brief Affinity is the amount of nano-seconds this process is going to run. -/***********************************************************************************/ -enum class AffinityKind : Int32 { - kInvalid = 0, - kRealTime = 100, - kVeryHigh = 150, - kHigh = 200, - kStandard = 1000, - kLowUsage = 1500, - kVeryLowUsage = 2000, -}; - -/***********************************************************************************/ -//! Operators for AffinityKind -/***********************************************************************************/ - -inline bool operator<(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int32>(lhs); - Int32 rhs_int = static_cast<Int32>(rhs); - - return lhs_int < rhs_int; -} - -inline bool operator>(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int32>(lhs); - Int32 rhs_int = static_cast<Int32>(rhs); - - return lhs_int > rhs_int; -} - -inline bool operator<=(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int>(lhs); - Int32 rhs_int = static_cast<Int32>(rhs); - - return lhs_int <= rhs_int; -} - -inline bool operator>=(AffinityKind lhs, AffinityKind rhs) { - Int32 lhs_int = static_cast<Int32>(lhs); - Int32 rhs_int = static_cast<Int32>(rhs); - - return lhs_int >= rhs_int; -} - -using PTime = UInt64; -using ProcessTime = PTime; - -/***********************************************************************************/ -//! @brief Local Process Identifier type. -/***********************************************************************************/ -using ProcessID = Int64; - -/***********************************************************************************/ -/// @note For User manager, tells where we run the code. -/***********************************************************************************/ -enum class ProcessLevelRing : Int32 { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 3, -}; - -/***********************************************************************************/ -/// @brief Helper type to describe a code image. -/***********************************************************************************/ -using ImagePtr = VoidPtr; - -/***********************************************************************************/ -/// @brief Helper class to contain a process's image and blob. -/***********************************************************************************/ -struct ProcessImage final { - explicit ProcessImage() = default; - - private: - friend USER_PROCESS; - friend KERNEL_TASK; - - friend UserProcessScheduler; - friend KernelTaskScheduler; - - ImagePtr fCode{}; - ImagePtr fBlob{}; - - public: - Bool HasCode() const { return this->fCode != nullptr; } - - Bool HasImage() const { return this->fBlob != nullptr; } - - ErrorOr<ImagePtr> LeakImage() { - if (this->fCode) { - return ErrorOr<ImagePtr>{this->fCode}; - } - - return ErrorOr<ImagePtr>{kErrorInvalidData}; - } - - ErrorOr<ImagePtr> LeakBlob() { - if (this->fBlob) { - return ErrorOr<ImagePtr>{this->fBlob}; - } - - return ErrorOr<ImagePtr>{kErrorInvalidData}; - } -}; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/DebugOutput.h b/dev/kernel/KernelKit/DebugOutput.h deleted file mode 100644 index 3f9b5125..00000000 --- a/dev/kernel/KernelKit/DebugOutput.h +++ /dev/null @@ -1,207 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/DeviceMgr.h> -#include <NeKit/OwnPtr.h> -#include <NeKit/Stream.h> -#include <NeKit/Utils.h> - -namespace Kernel { -class TerminalDevice; -class DTraceDevice; -class NeTraceDevice; -class Utf8TerminalDevice; - -inline TerminalDevice end_line(); -inline TerminalDevice number(const Long& x); -inline TerminalDevice hex_number(const Long& x); - -// @brief Emulates a VT100 terminal. -class TerminalDevice final NE_DEVICE<const Char*> { - public: - TerminalDevice(void (*print)(DeviceInterface*, const Char*), - void (*gets)(DeviceInterface*, const Char*)) - : DeviceInterface<const Char*>(print, gets) {} - - ~TerminalDevice() override; - - /// @brief returns device name (terminal name) - /// @return string type (const Char*) - const Char* Name() const override { return ("TerminalDevice"); } - - NE_COPY_DEFAULT(TerminalDevice) - - STATIC TerminalDevice The() noexcept; -}; - -class Utf8TerminalDevice final NE_DEVICE<const Utf8Char*> { - public: - Utf8TerminalDevice(void (*print)(DeviceInterface*, const Utf8Char*), - void (*gets)(DeviceInterface*, const Utf8Char*)) - : DeviceInterface<const Utf8Char*>(print, gets) {} - - ~Utf8TerminalDevice() override; - - /// @brief returns device name (terminal name) - /// @return string type (const Char*) - const Char* Name() const override { return ("Utf8TerminalDevice"); } - - NE_COPY_DEFAULT(Utf8TerminalDevice) - - STATIC Utf8TerminalDevice The() noexcept; -}; - -inline TerminalDevice end_line() { - TerminalDevice self = TerminalDevice::The(); - - self.operator<<("\r"); - return self; -} - -inline Utf8TerminalDevice utf_end_line() { - Utf8TerminalDevice self = Utf8TerminalDevice::The(); - - self.operator<<(u8"\r"); - return self; -} - -inline TerminalDevice carriage_return() { - TerminalDevice self = TerminalDevice::The(); - - self.operator<<("\r"); - return self; -} - -inline TerminalDevice tabulate() { - TerminalDevice self = TerminalDevice::The(); - - self.operator<<("\t"); - return self; -} - -/// @brief emulate a terminal bell, like the VT100 does. -inline TerminalDevice bell() { - TerminalDevice self = TerminalDevice::The(); - - self.operator<<("\a"); - return self; -} - -namespace Detail { - inline TerminalDevice _write_number(const Long& x, TerminalDevice& term) { - UInt64 y = (x > 0 ? x : -x) / 10; - UInt64 h = (x > 0 ? x : -x) % 10; - - if (y) _write_number(y, term); - - /* fail if the number is not base-10 */ - if (h > 10) { - _write_number('?', term); - return term; - } - - if (y == ~0UL) y = -y; - - const Char kNumbers[11] = "0123456789"; - - Char buf[2]; - buf[0] = kNumbers[h]; - buf[1] = 0; - - term.operator<<(buf); - return term; - } - - inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term) { - UInt64 y = (x > 0 ? x : -x) / 16; - UInt64 h = (x > 0 ? x : -x) % 16; - - if (y) _write_number_hex(y, term); - - /* fail if the hex number is not base-16 */ - if (h > 16) { - _write_number_hex('?', term); - return term; - } - - if (y == ~0UL) y = -y; - - const Char kNumbers[17] = "0123456789ABCDEF"; - - Char buf[2]; - buf[0] = kNumbers[h]; - buf[1] = 0; - - term.operator<<(buf); - return term; - } -} // namespace Detail - -inline TerminalDevice hex_number(const Long& x) { - TerminalDevice self = TerminalDevice::The(); - - self << "0x"; - Detail::_write_number_hex(x, self); - - return self; -} - -inline TerminalDevice number(const Long& x) { - TerminalDevice self = TerminalDevice::The(); - - Detail::_write_number(x, self); - - return self; -} - -inline TerminalDevice get_console_in(Char* buf) { - TerminalDevice self = TerminalDevice::The(); - - self >> buf; - - return self; -} - -inline constexpr auto kDebugPort = 51820; -inline constexpr auto kDebugMagic = "VMK1.0.0;"; -inline constexpr auto kDebugVersion = 0x0100; - -inline constexpr SizeT kDebugCmdLen = 256U; - -typedef Char rt_debug_cmd[kDebugCmdLen]; - -inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) { - src = number(num); - return src; -} -} // namespace Kernel - -#ifdef kout -#undef kout -#endif // ifdef kout - -#define kout TerminalDevice::The() - -#ifdef kendl -#undef kendl -#endif // ifdef kendl - -#define kendl end_line() - -#ifdef kout8 -#undef kout8 -#endif // ifdef kout8 - -#define kout8 Utf8TerminalDevice::The() - -#ifdef kendl8 -#undef kendl8 -#endif // ifdef kendl8 - -#define kendl8 utf_end_line() diff --git a/dev/kernel/KernelKit/Defines.h b/dev/kernel/KernelKit/Defines.h deleted file mode 100644 index e88441d2..00000000 --- a/dev/kernel/KernelKit/Defines.h +++ /dev/null @@ -1,19 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -#define KERNELKIT_VERSION "0.0.1-kernelkit" -#define KERNELKIT_VERSION_BCD 0x0001 - -namespace Kernel { -class UserProcessScheduler; -class IDylibObject; -class USER_PROCESS; -class KERNEL_TASK; -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/DeviceMgr.h b/dev/kernel/KernelKit/DeviceMgr.h deleted file mode 100644 index 1dbad161..00000000 --- a/dev/kernel/KernelKit/DeviceMgr.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/* ======================================== - - Revision History: - - 31/01/24: Add kDeviceCnt (amlel) - 15/11/24: Add NE_DEVICE macro, to inherit from device object. - - ======================================== */ - -#pragma once - -/* @note Device Mgr. */ -/* @file KernelKit/DeviceMgr.h */ -/* @brief Device abstraction and I/O buffer. */ - -#include <NeKit/ErrorOr.h> -#include <NeKit/Ref.h> - -#define kDeviceMgrRootDirPath "/devices/" - -#define NE_DEVICE : public ::Kernel::DeviceInterface - -// Last Rev: Wed, May 27, 2025 6:22 PM - -namespace Kernel { -template <typename T> -class DeviceInterface; - -template <typename T> -class IOBuf; - -/***********************************************************************************/ -/// @brief Device contract interface, represents an HW device. -/***********************************************************************************/ -template <typename T> -class DeviceInterface { - public: - DeviceInterface() = default; - - explicit DeviceInterface(void (*Out)(DeviceInterface<T>*, T), void (*In)(DeviceInterface<T>*, T)) - : fOut(Out), fIn(In) {} - - virtual ~DeviceInterface() = default; - - public: - DeviceInterface& operator=(const DeviceInterface<T>&) = default; - DeviceInterface(const DeviceInterface<T>&) = default; - - public: - virtual DeviceInterface<T>& operator<<(T Data) { - fOut(this, Data); - return *this; - } - - virtual DeviceInterface<T>& operator>>(T Data) { - fIn(this, Data); - return *this; - } - - virtual const char* Name() const { return "/devices/null"; } - - operator bool() { return fOut && fIn; } - - Bool operator!() { return !fOut || !fIn; } - - protected: - Void (*fOut)(DeviceInterface<T>*, T Data) = {nullptr}; - Void (*fIn)(DeviceInterface<T>*, T Data) = {nullptr}; -}; - -/// -/// @brief Input Output abstract class. -/// Used mainly to communicate between OS to hardware. -/// -template <typename T> -class IOBuf final { - public: - explicit IOBuf(T dma_addr) : fData(dma_addr) { - // At least pass something valid when instancating this struct. - MUST_PASS(fData); - } - - IOBuf& operator=(const IOBuf<T>&) = default; - IOBuf(const IOBuf<T>&) = default; - - ~IOBuf() = default; - - public: - template <typename R> - R operator->() const { - return fData; - } - - template <typename R> - R& operator[](Size index) const { - return fData[index]; - } - - private: - T fData; -}; - -///! @brief Device enum types. -enum { - kDeviceTypeInvalid = 0, - kDeviceTypeIDE = 100, - kDeviceTypeEthernet, - kDeviceTypeWiFi, - kDeviceTypeFW, - kDeviceTypeBT, - kDeviceTypeRS232, - kDeviceTypeSCSI, - kDeviceTypeAHCI, - kDeviceTypeMBCI, - kDeviceTypeATA, - kDeviceTypeUSB, - kDeviceTypeAPM, // Adv. Pwr. Mgmt. - kDeviceTypePCI, - kDeviceTypeVGA, - kDeviceTypeGPU, - kDeviceTypeCount, -}; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h deleted file mode 100644 index daf93b89..00000000 --- a/dev/kernel/KernelKit/DriveMgr.h +++ /dev/null @@ -1,175 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef INC_DRIVE_MANAGER_H -#define INC_DRIVE_MANAGER_H - -/// @file DriveMgr.h -/// @brief Drive Manager. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/KPC.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <NeKit/Ref.h> - -#define kDriveMaxCount (4U) -#define kDriveSectorSz (512U) -#define kDriveInvalidID (-1) -#define kDriveNameLen (32) - -#define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ)) - -#define kDriveHiddenPrefix '~' - -namespace Kernel { -enum { - kInvalidDrive = -1, - - /// Storage types, combine with flags. - kBlockDevice = 0xAD, - kMassStorageDrive = 0xDA, - kFloppyDrive = 0xCD, - kOpticalDrive = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray - kTapeDrive = 0xD7, - - /// Storage flags, combine with types. - kReadOnlyDrive = 0x10, // Read only drive - kEPMDrive = 0x11, // Explicit Partition Map. - kVEPMDrive = 0x12, // ESP w/ EPM partition. - kMBRDrive = 0x13, // PC classic partition scheme - kGPTDrive = 0x14, // PC new partition scheme - kUnformattedDrive = 0x15, - kStorageCount = 9, -}; - -/// @brief Media drive trait type. -struct DriveTrait final { - Char fName[kDriveNameLen] = "/media/null"; // /System, /boot, //./Devices/USB... - UInt32 fKind{}; // fMassStorage, fFloppy, fOpticalDrive. - UInt32 fFlags{}; // fReadOnly, fEPMDrive... - - /// @brief Packet drive (StorageKit compilant.) - struct DrivePacket final { - VoidPtr fPacketContent{nullptr}; //! packet body. - Char fPacketMime[kDriveNameLen] = "*/*"; //! identify what we're sending. - SizeT fPacketSize{0UL}; //! packet size - UInt32 fPacketCRC32{0UL}; //! sanity crc, in case if good is set to false - Boolean fPacketGood{YES}; - Lba fPacketLba{0UL}; - Boolean fPacketReadOnly{NO}; - } fPacket; - - Lba fLbaStart{0}, fLbaEnd{0}; - SizeT fSectorSz{kDriveSectorSz}; - - Void (*fInput)(DrivePacket& packet){nullptr}; - Void (*fOutput)(DrivePacket& packet){nullptr}; - Void (*fVerify)(DrivePacket& packet){nullptr}; - Void (*fInit)(DrivePacket& packet){nullptr}; - const Char* (*fProtocol)(Void){nullptr}; -}; - -namespace Probe { - Void io_detect_drive(DriveTrait& trait); -} - -///! drive as a device. -typedef DriveTrait* DriveTraitPtr; - -/** - * @brief Mounted drives interface. - * @note This class has all of it's drive set to nullptr, allocate them using - * GetAddressOf(index). - */ -class IMountpoint final { - public: - explicit IMountpoint() = default; - ~IMountpoint() = default; - - NE_COPY_DEFAULT(IMountpoint) - - public: - DriveTrait& A() { return mA; } - - DriveTrait& B() { return mB; } - - DriveTrait& C() { return mC; } - - DriveTrait& D() { return mD; } - - enum { - kDriveIndexA = 0, - kDriveIndexB, - kDriveIndexC, - kDriveIndexD, - kDriveIndexInvalid, - }; - - DriveTraitPtr GetAddressOf(const Int32& index) { - err_local_get() = kErrorSuccess; - - switch (index) { - case kDriveIndexA: - return &mA; - case kDriveIndexB: - return &mB; - case kDriveIndexC: - return &mC; - case kDriveIndexD: - return &mD; - default: { - err_local_get() = kErrorNoSuchDisk; - kout << "No such disc letter.\n"; - - break; - } - } - - return nullptr; - } - - private: - DriveTrait mA, mB, mC, mD; -}; - -/// @brief Unimplemented drive. -/// @param pckt the packet to read. -/// @return -Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) noexcept; - -/// @brief Gets the drive kind (ATA, SCSI, AHCI...) -/// @param void none. -/// @return the drive kind (ATA, Flash, NVM) -const Char* io_drv_kind(Void); - -/// @brief Makes a new drive. -/// @return the new drive as a trait. -DriveTrait io_construct_blank_drive(Void) noexcept; - -/// @brief Fetches the main drive. -/// @param trait the new drive as a trait. -Void io_construct_main_drive(DriveTrait& trait) noexcept; - -/// @brief Fetches the main drive. -/// @return the new drive as a trait. -/// @deprecated use io_construct_main_drive(DriveTrait& trait) instead. -DriveTrait io_construct_main_drive(Void) noexcept; - -namespace Detect { - Void io_detect_drive(DriveTrait& trait); -} - -Void io_drv_input(DriveTrait::DrivePacket pckt); - -Void io_drv_output(DriveTrait::DrivePacket pckt); -} // namespace Kernel - -#endif /* ifndef INC_DRIVE_MANAGER_H */ diff --git a/dev/kernel/KernelKit/FileMgr.h b/dev/kernel/KernelKit/FileMgr.h deleted file mode 100644 index 93d5f580..00000000 --- a/dev/kernel/KernelKit/FileMgr.h +++ /dev/null @@ -1,445 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss , licensed under the Apache 2.0 license. - - File: FileMgr.h - Purpose: Kernel file manager. - Author: Amlal El Mahrouss (amlal@nekernel.org) - -======================================== */ - -/* ======================================== - - Revision History: - - 31/01/24: Update documentation (amlel) - 05/07/24: NeFS support, and fork support, updated constants and specs - as well. - 18/01/25: Patches to FileStream class. - - ======================================== */ - -#ifndef INC_FILEMGR_H -#define INC_FILEMGR_H - -/// @file FileMgr.h -/// @brief File Manager System. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -//! Include filesystems that NeKernel supports. -#include <FSKit/Ext2+IFS.h> -#include <FSKit/NeFS.h> -#include <FSKit/OpenHeFS.h> - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/KPC.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/Ref.h> -#include <NeKit/Stream.h> -#include <hint/CompilerHint.h> - -/// @brief Filesystem manager, abstraction over mounted filesystem. -/// Works like an VFS (Virtual File System) or IFS subsystem on NT/OS 2. - -#define kRestrictR "r" -#define kRestrictRB "rb" -#define kRestrictW "w" -#define kRestrictWR "rw" -#define kRestrictWRB "rwb" - -#define kRestrictMax (5U) - -#define rtl_node_cast(PTR) reinterpret_cast<Kernel::NodePtr>(PTR) - -#define kFileMimeGeneric "ne-application-kind/all" - -/** @brief invalid position. (n-pos) */ -#define kFileMgrNPos (~0UL) - -namespace Kernel { -enum { - kFileIOInvalid = 0, - kFileWriteAll = 100, - kFileReadAll = 101, - kFileReadChunk = 102, - kFileWriteChunk = 103, - // File flags (HFS+, NeFS specific) - kFileFlagRsrc = 104, - kFileFlagData = 105, - kFileIOCnt = (kFileFlagData - kFileWriteAll) + 1, -}; - -using NodePtr = VoidPtr; - -/** -@brief Filesystem Mgr Interface class -@brief Used to provide common I/O for a specific filesystem. -*/ -class IFilesystemMgr { - public: - explicit IFilesystemMgr() = default; - virtual ~IFilesystemMgr() = default; - - public: - NE_COPY_DEFAULT(IFilesystemMgr) - - public: - /// @brief Mounts a new filesystem into an active state. - /// @param interface the filesystem interface - /// @return - static bool Mount(IFilesystemMgr* interface); - - /// @brief Unmounts the active filesystem - /// @return - static IFilesystemMgr* Unmount(); - - /// @brief Getter, gets the active filesystem. - /// @return - static IFilesystemMgr* GetMounted(); - - public: - virtual NodePtr Create(_Input const Char* path) = 0; - virtual NodePtr CreateAlias(_Input const Char* path) = 0; - virtual NodePtr CreateDirectory(_Input const Char* path) = 0; - virtual NodePtr CreateSwapFile(const Char* path) = 0; - - public: - virtual bool Remove(_Input const Char* path) = 0; - - public: - virtual NodePtr Open(_Input const Char* path, _Input const Char* r) = 0; - - public: - virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT size) = 0; - - virtual _Output VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) = 0; - - virtual Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, - _Input Int32 flags, _Input SizeT size) = 0; - - virtual _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags, - _Input SizeT sz) = 0; - - public: - virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0; - - public: - virtual SizeT Tell(_Input NodePtr node) = 0; - virtual bool Rewind(_Input NodePtr node) = 0; -}; - -#ifdef __FSKIT_INCLUDES_NEFS__ -/** - * @brief Based of IFilesystemMgr, takes care of managing NeFS - * disks. - */ -class NeFileSystemMgr final : public IFilesystemMgr { - public: - explicit NeFileSystemMgr(); - ~NeFileSystemMgr() override; - - public: - NE_COPY_DEFAULT(NeFileSystemMgr) - - public: - NodePtr Create(const Char* path) override; - NodePtr CreateAlias(const Char* path) override; - NodePtr CreateDirectory(const Char* path) override; - NodePtr CreateSwapFile(const Char* path) override; - - public: - bool Remove(_Input const Char* path) override; - NodePtr Open(_Input const Char* path, _Input const Char* r) override; - Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT sz) override; - VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override; - bool Seek(_Input NodePtr node, _Input SizeT off) override; - SizeT Tell(_Input NodePtr node) override; - bool Rewind(_Input NodePtr node) override; - - Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT size) override; - - _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags, - _Input SizeT sz) override; - - public: - /// @brief Get NeFS parser class. - /// @return The filesystem parser class. - NeFileSystemParser* GetParser() noexcept; - - private: - NeFileSystemParser* mParser{nullptr}; -}; - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ - -#ifdef __FSKIT_INCLUDES_EXT2__ -/** - * @brief Based of IFilesystemMgr, takes care of managing NeFS - * disks. - */ -class Ext2FileSystemMgr final : public IFilesystemMgr { - public: - explicit Ext2FileSystemMgr(); - ~Ext2FileSystemMgr() override; - - public: - NE_COPY_DEFAULT(Ext2FileSystemMgr) - - public: - NodePtr Create(const Char* path) override; - NodePtr CreateAlias(const Char* path) override; - NodePtr CreateDirectory(const Char* path) override; - NodePtr CreateSwapFile(const Char* path) override; - - public: - bool Remove(_Input const Char* path) override; - NodePtr Open(_Input const Char* path, _Input const Char* r) override; - Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT sz) override; - VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override; - bool Seek(_Input NodePtr node, _Input SizeT off) override; - SizeT Tell(_Input NodePtr node) override; - bool Rewind(_Input NodePtr node) override; - - Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT size) override; - - _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags, - _Input SizeT sz) override; - - public: - /// @brief Get NeFS parser class. - /// @return The filesystem parser class. - Ext2FileSystemParser* GetParser() noexcept; - - private: - Ext2FileSystemParser* mParser{nullptr}; -}; - -#endif // ifdef __FSKIT_INCLUDES_EXT2__ - -#ifdef __FSKIT_INCLUDES_OPENHEFS__ -/** - * @brief Based of IFilesystemMgr, takes care of managing NeFS - * disks. - */ -class HeFileSystemMgr final : public IFilesystemMgr { - public: - explicit HeFileSystemMgr(); - ~HeFileSystemMgr() override; - - public: - NE_COPY_DEFAULT(HeFileSystemMgr) - - public: - NodePtr Create(const Char* path) override; - NodePtr CreateAlias(const Char* path) override; - NodePtr CreateDirectory(const Char* path) override; - NodePtr CreateSwapFile(const Char* path) override; - - public: - bool Remove(_Input const Char* path) override; - NodePtr Open(_Input const Char* path, _Input const Char* r) override; - Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT sz) override; - VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override; - bool Seek(_Input NodePtr node, _Input SizeT off) override; - SizeT Tell(_Input NodePtr node) override; - bool Rewind(_Input NodePtr node) override; - - Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT size) override; - - _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags, - _Input SizeT sz) override; - - public: - /// @brief Get NeFS parser class. - /// @return The filesystem parser class. - HeFileSystemParser* GetParser() noexcept; - - private: - HeFileSystemParser* mParser{nullptr}; -}; - -#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__ - -/** - * FileStream class. - * @tparam Encoding file encoding (char, wchar_t...) - * @tparam FSClass Filesystem contract who takes care of it. - */ -template <typename Encoding = Char, typename FSClass = IFilesystemMgr> -class FileStream final { - public: - explicit FileStream(const Encoding* path, const Encoding* restrict_type); - ~FileStream(); - - public: - FileStream& operator=(const FileStream&); - FileStream(const FileStream&); - - public: - ErrorOr<Int64> Write(SizeT offset, const VoidPtr data, SizeT len) noexcept { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictWrite && - this->fFileRestrict != kFileMgrRestrictWriteBinary) - return ErrorOr<Int64>(kErrorInvalidData); - - if (data == nullptr) return ErrorOr<Int64>(kErrorInvalidData); - - auto man = FSClass::GetMounted(); - - if (man) { - man->Write(offset, fFile, data, len); - return ErrorOr<Int64>(kErrorSuccess); - } - - return ErrorOr<Int64>(kErrorInvalidData); - } - - ErrorOr<Int64> Write(const Char* name, const VoidPtr data, SizeT len) noexcept { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictWrite && - this->fFileRestrict != kFileMgrRestrictWriteBinary) - return ErrorOr<Int64>(kErrorInvalidData); - - if (data == nullptr) return ErrorOr<Int64>(kErrorInvalidData); - - auto man = FSClass::GetMounted(); - - if (man) { - man->Write(name, fFile, data, 0, len); - return ErrorOr<Int64>(kErrorSuccess); - } - - return ErrorOr<Int64>(kErrorInvalidData); - } - - VoidPtr Read(const Char* name, SizeT sz) noexcept { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictRead && - this->fFileRestrict != kFileMgrRestrictReadBinary) - return nullptr; - - auto man = FSClass::GetMounted(); - - if (man) { - VoidPtr ret = man->Read(name, fFile, kFileReadAll, sz); - return ret; - } - - return nullptr; - } - - VoidPtr Read(SizeT offset, SizeT sz) { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictRead && - this->fFileRestrict != kFileMgrRestrictReadBinary) - return nullptr; - - auto man = FSClass::GetMounted(); - - if (man) { - man->Seek(fFile, offset); - auto ret = man->Read(fFile, kFileReadChunk, sz); - - return ret; - } - - return nullptr; - } - - public: - /// @brief Leak node pointer. - /// @return The node pointer. - NodePtr Leak() { return fFile; } - - /// @brief Leak MIME. - /// @return The MIME. - Char* MIME() noexcept { return const_cast<Char*>(fMime); } - - enum { - kFileMgrRestrictRead = 100, - kFileMgrRestrictReadBinary, - kFileMgrRestrictWrite, - kFileMgrRestrictWriteBinary, - kFileMgrRestrictReadWrite, - kFileMgrRestrictReadWriteBinary, - }; - - private: - NodePtr fFile{nullptr}; - Int32 fFileRestrict{kFileMgrRestrictReadBinary}; - const Char* fMime{kFileMimeGeneric}; -}; - -using FileStreamASCII = FileStream<Char>; -using FileStreamUTF8 = FileStream<Utf8Char>; -using FileStreamUTF16 = FileStream<WideChar>; - -typedef UInt64 CursorType; - -inline STATIC const auto kRestrictStrLen = 8U; - -/// @brief restrict information about the file descriptor. -struct FILEMGR_RESTRICT final { - Char fRestrict[kRestrictStrLen]; - Int32 fMappedTo; -}; - -/// @brief constructor -template <typename Encoding, typename Class> -inline FileStream<Encoding, Class>::FileStream(const Encoding* path, const Encoding* restrict_type) - : fFile(Class::GetMounted()->Open(path, restrict_type)) { - SizeT kRestrictCount = kRestrictMax; - const FILEMGR_RESTRICT kRestrictList[] = {{ - .fRestrict = kRestrictR, - .fMappedTo = kFileMgrRestrictRead, - }, - { - .fRestrict = kRestrictRB, - .fMappedTo = kFileMgrRestrictReadBinary, - }, - { - .fRestrict = kRestrictWRB, - .fMappedTo = kFileMgrRestrictReadWriteBinary, - }, - { - .fRestrict = kRestrictW, - .fMappedTo = kFileMgrRestrictWrite, - }, - { - .fRestrict = kRestrictWR, - .fMappedTo = kFileMgrRestrictReadWrite, - }}; - - for (SizeT index = 0; index < kRestrictCount; ++index) { - if (rt_string_cmp(restrict_type, kRestrictList[index].fRestrict, - rt_string_len(kRestrictList[index].fRestrict)) == 0) { - fFileRestrict = kRestrictList[index].fMappedTo; - break; - } - } - - kout << "FileMgr: Open file at: " << path << ".\r"; -} - -/// @brief destructor of the file stream. -template <typename Encoding, typename Class> -inline FileStream<Encoding, Class>::~FileStream() { - mm_free_ptr(fFile); - fFile = nullptr; -} -} // namespace Kernel - -#endif // ifndef INC_FILEMGR_H diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h deleted file mode 100644 index 36a870ba..00000000 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ /dev/null @@ -1,135 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __INC_MP_MANAGER_H__ -#define __INC_MP_MANAGER_H__ - -#include <ArchKit/ArchKit.h> -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Ref.h> - -/// @note Last Rev Sun 28 Jul CET 2024 -/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM - -#define kMaxAPInsideSched (4U) - -namespace Kernel { -class HardwareThread; -class HardwareThreadScheduler; - -using ThreadID = UInt32; - -enum ThreadKind { - kAPInvalid = 0, - kAPSystemReserved = 100, // System reserved thread, well user can't use it - kAPStandard, // user thread, cannot be used by Kernel - kAPRealTime, // fallback thread, cannot be used by user if not clear or - // used by Kernel. - kAPBoot, // The core we booted from, the mama. - kAPCount, -}; - -typedef enum ThreadKind ThreadKind; -typedef ThreadID ThreadID; - -/***********************************************************************************/ -/// -/// \name HardwareThread -/// \brief Abstraction over the CPU's core, used to run processes or threads. -/// -/***********************************************************************************/ - -class HardwareThread final { - public: - explicit HardwareThread(); - ~HardwareThread(); - - public: - NE_COPY_DEFAULT(HardwareThread) - - public: - operator bool(); - - public: - void Wake(const BOOL wakeup = false) noexcept; - void Busy(const BOOL busy = false) noexcept; - - public: - BOOL Switch(HAL::StackFramePtr frame); - BOOL IsWakeup() noexcept; - - public: - HAL::StackFramePtr StackFrame() noexcept; - ThreadKind& Kind() noexcept; - BOOL IsBusy() noexcept; - ThreadID& ID() noexcept; - - private: - HAL::StackFramePtr fStack{nullptr}; - ThreadKind fKind{ThreadKind::kAPStandard}; - ThreadID fID{0}; - Bool fWakeup{NO}; - Bool fBusy{NO}; - UInt64 fPTime{0}; - - private: - friend class HardwareThreadScheduler; - friend class UserProcessHelper; -}; - -/// -/// \name HardwareThreadScheduler -/// \brief Class to manage the thread scheduling. -/// - -class HardwareThreadScheduler final : public ISchedulable { - private: - friend class UserProcessHelper; - - public: - explicit HardwareThreadScheduler(); - ~HardwareThreadScheduler(); - NE_COPY_DEFAULT(HardwareThreadScheduler) - - public: - HAL::StackFramePtr Leak() noexcept; - - public: - Ref<HardwareThread*> operator[](SizeT idx); - bool operator!() noexcept; - operator bool() noexcept; - - Bool IsUser() override { return Yes; } - - Bool IsKernel() override { return No; } - - Bool HasMP() override { return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; } - - public: - /// @brief Shared instance of the MP Mgr. - /// @return the reference to the mp manager class. - STATIC HardwareThreadScheduler& The(); - - public: - /// @brief Returns the amount of threads present in the system. - /// @returns SizeT the amount of cores present. - SizeT Capacity() noexcept; - - private: - Array<HardwareThread, kMaxAPInsideSched> fThreadList; - ThreadID fCurrentThreadIdx{0}; -}; - -/// @brief wakes up thread. -/// wakes up thread from hang. -Void mp_wakeup_thread(HAL::StackFramePtr stack); - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -Void mp_hang_thread(HAL::StackFramePtr stack); -} // namespace Kernel - -#endif // !__INC_MP_MANAGER_H__ diff --git a/dev/kernel/KernelKit/HeapMgr.h b/dev/kernel/KernelKit/HeapMgr.h deleted file mode 100644 index 58bac7a5..00000000 --- a/dev/kernel/KernelKit/HeapMgr.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef INC_KERNEL_HEAP_H -#define INC_KERNEL_HEAP_H - -/// @date 30/01/24 -/// @file: HeapMgr.h -/// @brief: Memory allocation support for the NeKernel. - -#include <KernelKit/KPC.h> -#include <NeKit/KernelPanic.h> -#include <hint/CompilerHint.h> - -namespace Kernel { -/// @brief Declare pointer as free. -/// @param heap_ptr the pointer. -/// @return a status code regarding the deallocation. -Int32 mm_free_ptr(VoidPtr heap_ptr); - -/// @brief Check if pointer is a valid Kernel pointer. -/// @param heap_ptr the pointer -/// @return if it exists it returns true. -Boolean mm_is_valid_ptr(VoidPtr heap_ptr); - -/// @brief Allocate chunk of memory. -/// @param sz Size of pointer -/// @param wr Read Write bit. -/// @param user User enable bit. -/// @return The newly allocated pointer, or nullptr. -VoidPtr mm_alloc_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount = 0); - -/// @brief Protect the heap with a CRC value. -/// @param heap_ptr pointer. -/// @return if it valid: point has crc now., otherwise fail. -Boolean mm_protect_ptr(VoidPtr heap_ptr); - -/// @brief Makes a Kernel page. -/// @param heap_ptr the page pointer. -/// @return status code -Int32 mm_make_page(VoidPtr heap_ptr); - -/// @brief Overwrites and set the flags of a heap header. -/// @param heap_ptr the pointer to update. -/// @param flags the flags to set. -Int32 mm_set_ptr_flags(VoidPtr heap_ptr, UInt64 flags); - -/// @brief Gets the flags of a heap header. -/// @param heap_ptr the pointer to get. -UInt64 mm_get_ptr_flags(VoidPtr heap_ptr); -} // namespace Kernel - -#include <KernelKit/HeapMgr.inl> - -#endif // !INC_KERNEL_HEAP_H diff --git a/dev/kernel/KernelKit/HeapMgr.inl b/dev/kernel/KernelKit/HeapMgr.inl deleted file mode 100644 index 3231d33c..00000000 --- a/dev/kernel/KernelKit/HeapMgr.inl +++ /dev/null @@ -1,35 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#ifndef INC_KERNEL_HEAP_H -#include <KernelKit/HeapMgr.h> -#endif // !INC_KERNEL_HEAP_H - -namespace Kernel { -/// @brief Allocate C++ class. -/// @param cls The class to allocate. -/// @param args The args to pass. -template <typename T, typename... Args> -inline BOOL mm_new_class(_Input _Output T** cls, _Input Args&&... args) { - if (*cls) { - err_global_get() = Kernel::kErrorInvalidData; - return NO; - } - - *cls = new T(move(args)...); - return *cls; -} - -/// @brief Delete and nullify C++ class. -/// @param cls The class to delete. -template <typename T> -inline Void mm_delete_class(_Input _Output T** cls) { - delete *cls; - *cls = nullptr; -} -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/IDylibObject.h b/dev/kernel/KernelKit/IDylibObject.h deleted file mode 100644 index ef6b96db..00000000 --- a/dev/kernel/KernelKit/IDylibObject.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ======================================================== - * - * Kernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Defines.h> - -#define NE_DYLIB_OBJECT : public IDylibObject - -namespace Kernel { -class IDylibObject; - -/// @brief Dylib class object. A handle to a shared library. -class IDylibObject { - public: - explicit IDylibObject() = default; - virtual ~IDylibObject() = default; - - struct DylibTraits final { - VoidPtr ImageObject{nullptr}; - VoidPtr ImageEntrypointOffset{nullptr}; - - VoidPtr Image() const { return ImageObject; } - Bool IsValid() const { return ImageObject && ImageEntrypointOffset; } - }; - - NE_COPY_DEFAULT(IDylibObject) - - virtual DylibTraits** GetAddressOf() = 0; - virtual DylibTraits* Get() = 0; - - virtual Void Mount(DylibTraits* to_mount) = 0; - virtual Void Unmount() = 0; -}; - -/// @brief Pure implementation, missing method/function handler. -EXTERN_C void __ne_pure_call(void); -} // namespace Kernel diff --git a/dev/kernel/KernelKit/IFS.h b/dev/kernel/KernelKit/IFS.h deleted file mode 100644 index 7118a935..00000000 --- a/dev/kernel/KernelKit/IFS.h +++ /dev/null @@ -1,25 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DriveMgr.h> - -namespace Kernel { -/// @brief Read from IFS disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_ifs_read(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex); - -/// @brief Write to IFS disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_ifs_write(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex); -} // namespace Kernel diff --git a/dev/kernel/KernelKit/ILoader.h b/dev/kernel/KernelKit/ILoader.h deleted file mode 100644 index 28dd1ed9..00000000 --- a/dev/kernel/KernelKit/ILoader.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> -#include <hint/CompilerHint.h> - -namespace Kernel { -/// @brief This interface is used to make loader contracts (MSCOFF, PEF). -/// @author @Amlal-El-Mahrouss -class ILoader { - public: - explicit ILoader() = default; - virtual ~ILoader() = default; - - NE_COPY_DEFAULT(ILoader) - - public: - virtual _Output ErrorOr<VoidPtr> GetBlob() = 0; - virtual _Output const Char* AsString() = 0; - virtual _Output const Char* MIME() = 0; - virtual _Output const Char* Path() = 0; - virtual _Output ErrorOr<VoidPtr> FindStart() = 0; - virtual _Output ErrorOr<VoidPtr> FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; -}; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h deleted file mode 100644 index 17ef02d5..00000000 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * ======================================================== - * - * Kernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#ifndef __KERNELKIT_PEF_SHARED_OBJECT_H__ -#define __KERNELKIT_PEF_SHARED_OBJECT_H__ - -#include <KernelKit/IDylibObject.h> -#include <KernelKit/PEF.h> -#include <KernelKit/PEFCodeMgr.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/Defines.h> - -namespace Kernel { -/** - * @brief Shared Library class - * Load library from this class - */ -class IPEFDylibObject final NE_DYLIB_OBJECT { - public: - explicit IPEFDylibObject() = default; - ~IPEFDylibObject() = default; - - public: - NE_COPY_DEFAULT(IPEFDylibObject) - - private: - DylibTraits* fMounted{nullptr}; - - public: - DylibTraits** GetAddressOf() { return &fMounted; } - - DylibTraits* Get() { return fMounted; } - - public: - void Mount(DylibTraits* to_mount) noexcept { - if (!to_mount || !to_mount->ImageObject) return; - - fMounted = to_mount; - - if (fLoader && to_mount) { - delete fLoader; - fLoader = nullptr; - } - - if (!fLoader) { - fLoader = new PEFLoader(fMounted->ImageObject); - } - } - - void Unmount() noexcept { - if (fMounted) fMounted = nullptr; - }; - - template <typename SymbolType> - SymbolType Load(const Char* symbol_name, const SizeT& len, const UInt32& kind) { - if (symbol_name == nullptr || *symbol_name == 0) return nullptr; - if (len > kPathLen || len < 1) return nullptr; - - auto ret = reinterpret_cast<SymbolType>(fLoader->FindSymbol(symbol_name, kind).Leak().Leak()); - - if (!ret) { - if (kind == kPefCode) return (VoidPtr) &__ne_pure_call; - - return nullptr; - } - - return ret; - } - - private: - PEFLoader* fLoader{nullptr}; -}; - -typedef IPEFDylibObject* IDylibRef; - -EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& header); -EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& header, IDylibRef lib, Bool* successful); -} // namespace Kernel - -#endif /* ifndef __KERNELKIT_PEF_SHARED_OBJECT_H__ */ diff --git a/dev/kernel/KernelKit/KPC.h b/dev/kernel/KernelKit/KPC.h deleted file mode 100644 index dbdc2a93..00000000 --- a/dev/kernel/KernelKit/KPC.h +++ /dev/null @@ -1,78 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -/// @file KPC.h -/// @brief Kernel Procedure Code. - -#define err_local_ok() \ - (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode() == \ - Kernel::kErrorSuccess) -#define err_local_fail() \ - (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode() != \ - Kernel::kErrorSuccess) -#define err_local_get() \ - (Kernel::UserProcessScheduler::The().TheCurrentProcess().Leak().GetLocalCode()) - -#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess) -#define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess) -#define err_global_get() (Kernel::kErrorLocalNumber) - -namespace Kernel { -typedef Int32 KPCError; - -inline KPCError kErrorLocalNumber = 0UL; - -inline constexpr KPCError kErrorSuccess = 0; -inline constexpr KPCError kErrorExecutable = 33; -inline constexpr KPCError kErrorExecutableLib = 34; -inline constexpr KPCError kErrorFileNotFound = 35; -inline constexpr KPCError kErrorDirectoryNotFound = 36; -inline constexpr KPCError kErrorDiskReadOnly = 37; -inline constexpr KPCError kErrorDiskIsFull = 38; -inline constexpr KPCError kErrorProcessFault = 39; -inline constexpr KPCError kErrorSocketHangUp = 40; -inline constexpr KPCError kErrorThreadLocalStorage = 41; -inline constexpr KPCError kErrorMath = 42; -inline constexpr KPCError kErrorNoNetwork = 43; -inline constexpr KPCError kErrorHeapOutOfMemory = 44; -inline constexpr KPCError kErrorNoSuchDisk = 45; -inline constexpr KPCError kErrorFileExists = 46; -inline constexpr KPCError kErrorFormatFailed = 47; -inline constexpr KPCError kErrorNetworkTimeout = 48; -inline constexpr KPCError kErrorInternal = 49; -inline constexpr KPCError kErrorForkAlreadyExists = 50; -inline constexpr KPCError kErrorOutOfTeamSlot = 51; -inline constexpr KPCError kErrorHeapNotPresent = 52; -inline constexpr KPCError kErrorNoEntrypoint = 53; -inline constexpr KPCError kErrorDiskIsCorrupted = 54; -inline constexpr KPCError kErrorDisk = 55; -inline constexpr KPCError kErrorInvalidData = 56; -inline constexpr KPCError kErrorAsync = 57; -inline constexpr KPCError kErrorNonBlocking = 58; -inline constexpr KPCError kErrorIPC = 59; -inline constexpr KPCError kErrorSign = 60; -inline constexpr KPCError kErrorInvalidCreds = 61; -inline constexpr KPCError kErrorCDTrayBroken = 62; -inline constexpr KPCError kErrorUnrecoverableDisk = 63; -inline constexpr KPCError kErrorFileLocked = 64; -inline constexpr KPCError kErrorDiskIsTooTiny = 65; -inline constexpr KPCError kErrorDmaExhausted = 66; -inline constexpr KPCError kErrorOutOfBitMapMemory = 67; -inline constexpr KPCError kErrorTimeout = 68; -inline constexpr KPCError kErrorAccessDenied = 69; -inline constexpr KPCError kErrorUnavailable = 70; -/// Generic errors. -inline constexpr KPCError kErrorUnimplemented = -1; - -/// @brief Does a system wide bug check. -/// @param void no params are needed. -/// @return if error-free: false, otherwise true. -Boolean err_bug_check_raise(Void) noexcept; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h deleted file mode 100644 index 9bfce1d6..00000000 --- a/dev/kernel/KernelKit/KernelTaskScheduler.h +++ /dev/null @@ -1,47 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -/// @file KernelTaskScheduler.h -/// @brief Kernel Task Scheduler header file. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -#include <ArchKit/ArchKit.h> -#include <KernelKit/CoreProcessScheduler.h> -#include <KernelKit/LockDelegate.h> - -namespace Kernel { -class KernelTaskHelper; - -typedef ProcessID KID; - -/// @brief Equivalent of USER_PROCESS, but for kernel tasks. -/// @author Amlal -class KERNEL_TASK final { - public: - Char Name[kSchedNameLen] = {"KERNEL_TASK"}; - ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemKernel}; - HAL::StackFramePtr StackFrame{nullptr}; - UInt8* StackReserve{nullptr}; - SizeT StackSize{kSchedMaxStackSz}; - ProcessImage Image{}; - /// @brief a KID is a Kernel ID, it is used to find a task running within - /// the kernel. - KID Kid{0}; -}; - -/// @brief Equivalent of UserProcessHelper, but for kernel tasks. -/// @author Amlal -class KernelTaskHelper final { - public: - STATIC Bool Add(HAL::StackFramePtr frame_ptr, ProcessID new_kid); - STATIC Bool Remove(const KID kid); - STATIC Bool CanBeScheduled(const KERNEL_TASK& process); - STATIC ErrorOr<KID> TheCurrentKID(); - STATIC SizeT StartScheduling(); -}; -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/LockDelegate.h b/dev/kernel/KernelKit/LockDelegate.h deleted file mode 100644 index 8ff67f19..00000000 --- a/dev/kernel/KernelKit/LockDelegate.h +++ /dev/null @@ -1,58 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Atom.h> -#include <NeKit/Defines.h> - -namespace Kernel { -enum { - kLockInvalid = 0, - kLockDone = 200, - kLockTimedOut = 300, - kLockCount = 3, -}; - -/// @brief Lock condition pointer. -typedef Boolean* LockPtr; - -/// @brief Locking delegate class, hangs until limit. -/// @tparam N the amount of cycles to wait. -template <SizeT N> -class LockDelegate final { - public: - LockDelegate() = delete; - - public: - explicit LockDelegate(LockPtr expr) { - auto spin = 0U; - - while (spin < N) { - if (*expr) { - fLockStatus | kLockDone; - break; - } - - ++spin; - } - - if (spin > N) fLockStatus | kLockTimedOut; - } - - ~LockDelegate() = default; - - LockDelegate& operator=(const LockDelegate&) = delete; - LockDelegate(const LockDelegate&) = delete; - - bool Done() { return fLockStatus[kLockDone] == kLockDone; } - - bool HasTimedOut() { return fLockStatus[kLockTimedOut] != kLockTimedOut; } - - private: - Atom<UInt> fLockStatus; -}; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/MSDOS.h b/dev/kernel/KernelKit/MSDOS.h deleted file mode 100644 index 8c58b65b..00000000 --- a/dev/kernel/KernelKit/MSDOS.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: MSDOS.h - Purpose: MS-DOS header for Kernel. - - Revision History: - - 30/01/24: Added file (amlel) - -======================================== */ - -#ifndef __MSDOS_EXEC__ -#define __MSDOS_EXEC__ - -#include <KernelKit/PE.h> -#include <NeKit/Defines.h> - -// Last Rev -// Sat Feb 24 CET 2024 - -#define kMagMz0 'M' -#define kMagMz1 'Z' - -typedef Kernel::UInt32 DosWord; -typedef Kernel::Long DosLong; - -typedef struct _DosHeader { - Kernel::UInt8 eMagic[2]; - DosWord eMagLen; - DosWord ePagesCount; - DosWord eCrlc; - DosWord eCParHdr; - DosWord eMinAlloc; - DosWord eMaxAlloc; - DosWord eStackSeg; - DosWord eStackPtr; - DosWord eChksum; - DosWord eIp; - DosWord eCs; - DosWord eLfarlc; - DosWord eOvno; - DosWord eRes[4]; - DosWord eOemid; - DosWord eOeminfo; - DosWord eRes2[10]; - DosLong eLfanew; -} DosHeader, *DosHeaderPtr; - -#endif /* ifndef __MSDOS_EXEC__ */ diff --git a/dev/kernel/KernelKit/PCI/DMA.h b/dev/kernel/KernelKit/PCI/DMA.h deleted file mode 100644 index 80103dab..00000000 --- a/dev/kernel/KernelKit/PCI/DMA.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/PCI/Device.h> -#include <NeKit/Array.h> -#include <NeKit/OwnPtr.h> -#include <NeKit/Ref.h> - -namespace Kernel { -enum class DmaKind { - PCI = 10, // Bus mastering is required to be turned on. Basiaclly a request - // control system. 64-Bit access depends on the PAE bit and the device - // (if Double Address Cycle is available) - ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM. - Count = 2, - Invalid = 0, -}; - -class DMAWrapper final { - public: - explicit DMAWrapper() = delete; - - public: - explicit DMAWrapper(nullPtr) = delete; - explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) : fAddress(Ptr), fKind(Kind) {} - - public: - DMAWrapper& operator=(voidPtr Ptr); - - public: - DMAWrapper& operator=(const DMAWrapper&) = default; - DMAWrapper(const DMAWrapper&) = default; - - public: - ~DMAWrapper() = default; - - template <class T> - T* operator->(); - - template <class T> - T* Get(UIntPtr off = 0); - - public: - operator bool(); - bool operator!(); - - public: - bool Write(UIntPtr& bit, const UInt32& offset); - UIntPtr Read(const UInt32& offset); - Boolean Check(UIntPtr offset) const; - - public: - UIntPtr operator[](UIntPtr& offset); - - private: - voidPtr fAddress{nullptr}; - DmaKind fKind{DmaKind::Invalid}; - - private: - friend class DMAFactory; -}; - -class DMAFactory final { - public: - static OwnPtr<IOBuf<Char*>> Construct(OwnPtr<DMAWrapper>& dma); -}; -} // namespace Kernel - -#include <KernelKit/PCI/DMA.inl> diff --git a/dev/kernel/KernelKit/PCI/DMA.inl b/dev/kernel/KernelKit/PCI/DMA.inl deleted file mode 100644 index d81a632e..00000000 --- a/dev/kernel/KernelKit/PCI/DMA.inl +++ /dev/null @@ -1,17 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -namespace Kernel { -template <class T> -T* DMAWrapper::operator->() { - return this->fAddress; -} - -template <class T> -T* DMAWrapper::Get(UIntPtr offset) { - return reinterpret_cast<T*>((UIntPtr) this->fAddress + offset); -} -} // namespace Kernel diff --git a/dev/kernel/KernelKit/PCI/Database.h b/dev/kernel/KernelKit/PCI/Database.h deleted file mode 100644 index 463fde38..00000000 --- a/dev/kernel/KernelKit/PCI/Database.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ -#pragma once - -#include <KernelKit/PCI/Device.h> -#include <NeKit/Defines.h> - -namespace Kernel { -namespace Types { - // https://wiki.osdev.org/PCI - enum class PciDeviceKind : UChar { - MassStorageController = 0x1, - NetworkController = 0x2, - DisplayController = 0x3, - MultimediaController = 0x4, - MemoryController = 0x5, - Bridge = 0x6, - CommunicationController = 0x7, - GenericSystemPeripheral = 0x8, - InputDeviceController = 0x9, - DockingStation = 0xa, - Processor = 0xb, - SerialBusController = 0xc, - WirelessController = 0xd, - IntelligentController = 0xe, - SatelliteCommunicationsController = 0xf, - CoProcessor = 0x40, - Unassgined = 0xf, - Invalid = Unassgined, - }; -} // namespace Types -} // namespace Kernel - -inline BOOL operator!=(const Kernel::Types::PciDeviceKind& lhs, Kernel::UChar rhs) { - return rhs != (Kernel::UChar) lhs; -} - -inline BOOL operator==(const Kernel::Types::PciDeviceKind& lhs, Kernel::UChar rhs) { - return rhs == (Kernel::UChar) lhs; -} - -inline BOOL operator!=(Kernel::UChar lhs, const Kernel::Types::PciDeviceKind& rhs) { - return lhs != (Kernel::UChar) rhs; -} - -inline BOOL operator==(Kernel::UChar lhs, const Kernel::Types::PciDeviceKind& rhs) { - return lhs == (Kernel::UChar) rhs; -}
\ No newline at end of file diff --git a/dev/kernel/KernelKit/PCI/Device.h b/dev/kernel/KernelKit/PCI/Device.h deleted file mode 100644 index f2111e40..00000000 --- a/dev/kernel/KernelKit/PCI/Device.h +++ /dev/null @@ -1,73 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel::PCI { -enum class PciConfigKind : UShort { - ConfigAddress = 0xCF8, - ConfigData = 0xCFC, - CommandReg = 0x0004, - Invalid = 0xFFFF, -}; - -/// @brief Device interface class -class Device final { - public: - Device() = default; - - public: - Device(UShort bus, UShort device, UShort function, UInt32 bar); - - Device& operator=(const Device&) = default; - Device(const Device&) = default; - - ~Device(); - - public: - UInt Read(UInt bar, Size szData); - void Write(UInt bar, UIntPtr data, Size szData); - - public: - operator bool(); - - public: - template <typename T> - UInt Read(UInt bar) { - static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported"); - return Read(bar, sizeof(T)); - } - - template <typename T> - void Write(UInt bar, UIntPtr data) { - static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported"); - Write(bar, data, sizeof(T)); - } - - public: - UShort DeviceId(); - UShort VendorId(); - UShort InterfaceId(); - UChar Class(); - UChar Subclass(); - UChar ProgIf(); - UChar HeaderType(); - UIntPtr Bar(UInt32 bar_in); - - public: - void EnableMmio(); - void BecomeBusMaster(); // for PCI-DMA, PC-DMA does not need that. - - UShort Vendor(); - - private: - UShort fBus; - UShort fDevice; - UShort fFunction; - UInt32 fBar; -}; -} // namespace Kernel::PCI diff --git a/dev/kernel/KernelKit/PCI/Express.h b/dev/kernel/KernelKit/PCI/Express.h deleted file mode 100644 index 484739ec..00000000 --- a/dev/kernel/KernelKit/PCI/Express.h +++ /dev/null @@ -1,12 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/PCI/PCI.h> -#include <NeKit/Defines.h> - -#define PCI_EXPRESS_BUS_COUNT (4096) diff --git a/dev/kernel/KernelKit/PCI/IO.h b/dev/kernel/KernelKit/PCI/IO.h deleted file mode 100644 index 2ab72269..00000000 --- a/dev/kernel/KernelKit/PCI/IO.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <ArchKit/ArchKit.h> -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/Ref.h> - -namespace Kernel { -template <SizeT Sz> -class IOArray final { - public: - IOArray() = delete; - - IOArray(nullPtr) = delete; - - explicit IOArray(Array<UShort, Sz>& ports) : fPorts(ports) {} - - ~IOArray() {} - - IOArray& operator=(const IOArray&) = default; - - IOArray(const IOArray&) = default; - - operator bool() { return !fPorts.Empty(); } - - public: - template <typename T> - T In(SizeT index); - - template <typename T> - void Out(SizeT index, T value); - - private: - Array<UShort, Sz> fPorts; -}; - -inline constexpr UInt16 kMaxPorts = 16; - -using IOArray16 = IOArray<kMaxPorts>; - -template <SizeT Sz> -inline Array<UShort, Sz> make_ports(UShort base) { - Array<UShort, Sz> ports; - - for (UShort i = 0; i < Sz; ++i) { - ports[i] = base + i; - } - - return ports; -} -} // namespace Kernel - -#ifdef __NE_AMD64__ -#include <KernelKit/PCI/IOArray+AMD64.inl> -#else -#error Please provide platform specific code for the I/O -#endif // ifdef __NE_AMD64__ diff --git a/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl b/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl deleted file mode 100644 index 2b9125e0..00000000 --- a/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl +++ /dev/null @@ -1,49 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: IO-Impl-AMD64.h - Purpose: I/O for AMD64. - - Revision History: - - 30/01/24: Add file. (amlel) - 02/02/24: Update I/O routines. (amlel) - -======================================== */ - -namespace Kernel { -template <SizeT Sz> -template <typename T> -T IOArray<Sz>::In(SizeT index) { - switch (sizeof(T)) { -#ifdef __NE_AMD64__ - case 4: - return HAL::rt_in32(fPorts[index].Leak()); - case 2: - return HAL::rt_in16(fPorts[index].Leak()); - case 1: - return HAL::rt_in8(fPorts[index].Leak()); -#endif - default: - return 0xFFFF; - } -} - -template <SizeT Sz> -template <typename T> -void IOArray<Sz>::Out(SizeT index, T value) { - switch (sizeof(T)) { -#ifdef __NE_AMD64__ - case 4: - HAL::rt_out32(fPorts[index].Leak(), value); - case 2: - HAL::rt_out16(fPorts[index].Leak(), value); - case 1: - HAL::rt_out8(fPorts[index].Leak(), value); -#endif - default: - break; - } -} -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/PCI/Iterator.h b/dev/kernel/KernelKit/PCI/Iterator.h deleted file mode 100644 index 5926049b..00000000 --- a/dev/kernel/KernelKit/PCI/Iterator.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __PCI_ITERATOR_H__ -#define __PCI_ITERATOR_H__ - -#include <KernelKit/PCI/Database.h> -#include <KernelKit/PCI/Device.h> -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/Ref.h> - -#define NE_BUS_COUNT (256) -#define NE_DEVICE_COUNT (33) -#define NE_FUNCTION_COUNT (8) - -namespace Kernel::PCI { -class Iterator final { - public: - Iterator() = delete; - - public: - explicit Iterator(const Types::PciDeviceKind deviceType, UInt32 bar); - - Iterator& operator=(const Iterator&) = default; - Iterator(const Iterator&) = default; - - ~Iterator(); - - public: - Ref<PCI::Device> operator[](const Size& sz); - - private: - Array<PCI::Device, NE_BUS_COUNT> fDevices; -}; -} // namespace Kernel::PCI - -#endif // __PCI_ITERATOR_H__ diff --git a/dev/kernel/KernelKit/PCI/PCI.h b/dev/kernel/KernelKit/PCI/PCI.h deleted file mode 100644 index f76270da..00000000 --- a/dev/kernel/KernelKit/PCI/PCI.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -#define kPCIConfigAddressPort (0xCF8) -#define kPCIConfigDataPort (0xCFC) - -#define kPCIDeviceCount (32) -#define kPCIFuncCount (8) -#define kPCIBusCount (256U) - -namespace Kernel::PCI { -// model -struct DeviceHeader { - UInt16 VendorId; - UInt16 DeviceId; - UInt8 Command; - UInt8 Status; - UInt8 RevisionId; - UInt8 ProgIf; - UInt8 SubClass; - UInt8 Class; - UInt8 CacheLineSz; - UInt8 LatencyTimer; - UInt8 HeaderType; - UInt8 Bist; - UInt8 Bus; - UInt8 Device; - UInt8 Function; -}; - -namespace Detail { - class BAR { - public: - UIntPtr BAR; - SizeT Size; - }; -} // namespace Detail - -class BAR { - public: - Detail::BAR BAR1; - Detail::BAR BAR2; - Detail::BAR BAR3; - Detail::BAR BAR4; - Detail::BAR BAR5; -}; -} // namespace Kernel::PCI diff --git a/dev/kernel/KernelKit/PE.h b/dev/kernel/KernelKit/PE.h deleted file mode 100644 index b4b4576e..00000000 --- a/dev/kernel/KernelKit/PE.h +++ /dev/null @@ -1,130 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: PE.h - Purpose: Portable Executable for Kernel. - - Revision History: - - 30/01/24: Added file (amlel) - -======================================== */ - -#ifndef __KERNELKIT_INC_PE_H__ -#define __KERNELKIT_INC_PE_H__ - -#include <NeKit/Defines.h> - -#define kPeSignature (0x00004550) - -#define kPeMagic32 (0x010b) -#define kPeMagic64 (0x020b) - -#define kPeMachineAMD64 (0x8664) -#define kPeMachineARM64 (0xaa64) - -typedef struct LDR_EXEC_HEADER final { - Kernel::UInt32 Signature; - Kernel::UInt16 Machine; - Kernel::UInt16 NumberOfSections; - Kernel::UInt32 TimeDateStamp; - Kernel::UInt32 PointerToSymbolTable; - Kernel::UInt32 NumberOfSymbols; - Kernel::UInt16 SizeOfOptionalHeader; - Kernel::UInt16 Characteristics; -} LDR_EXEC_HEADER, *LDR_EXEC_HEADER_PTR; - -typedef struct LDR_OPTIONAL_HEADER final { - Kernel::UInt16 Magic; // 0x010b - PE32, 0x020b - PE32+ (64 bit) - Kernel::UInt8 MajorLinkerVersion; - Kernel::UInt8 MinorLinkerVersion; - Kernel::UInt32 SizeOfCode; - Kernel::UInt32 SizeOfInitializedData; - Kernel::UInt32 SizeOfUninitializedData; - Kernel::UInt32 AddressOfEntryPoint; - Kernel::UInt32 BaseOfCode; - Kernel::UInt64 ImageBase; - Kernel::UInt32 SectionAlignment; - Kernel::UInt32 FileAlignment; - Kernel::UInt16 MajorOperatingSystemVersion; - Kernel::UInt16 MinorOperatingSystemVersion; - Kernel::UInt16 MajorImageVersion; - Kernel::UInt16 MinorImageVersion; - Kernel::UInt16 MajorSubsystemVersion; - Kernel::UInt16 MinorSubsystemVersion; - Kernel::UInt32 Win32VersionValue; - Kernel::UInt32 SizeOfImage; - Kernel::UInt32 SizeOfHeaders; - Kernel::UInt32 CheckSum; - Kernel::UInt16 Subsystem; - Kernel::UInt16 DllCharacteristics; - Kernel::UInt32 SizeOfStackReserve; - Kernel::UInt32 SizeOfStackCommit; - Kernel::UInt32 SizeOfHeapReserve; - Kernel::UInt32 SizeOfHeapCommit; - Kernel::UInt32 LoaderFlags; - Kernel::UInt32 NumberOfRvaAndSizes; -} LDR_OPTIONAL_HEADER, *LDR_OPTIONAL_HEADER_PTR; - -typedef struct LDR_SECTION_HEADER final { - Kernel::Char Name[8]; - Kernel::UInt32 VirtualSize; - Kernel::UInt32 VirtualAddress; - Kernel::UInt32 SizeOfRawData; - Kernel::UInt32 PointerToRawData; - Kernel::UInt32 PointerToRelocations; - Kernel::UInt32 PointerToLineNumbers; - Kernel::UInt16 NumberOfRelocations; - Kernel::UInt16 NumberOfLinenumbers; - Kernel::UInt32 Characteristics; -} LDR_SECTION_HEADER, *LDR_SECTION_HEADER_PTR; - -enum kExecDataDirParams { - kExecExport, - kExecImport, - kExecInvalid, - kExecCount, -}; - -typedef struct LDR_EXPORT_DIRECTORY { - Kernel::UInt32 Characteristics; - Kernel::UInt32 TimeDateStamp; - Kernel::UInt16 MajorVersion; - Kernel::UInt16 MinorVersion; - Kernel::UInt32 Name; - Kernel::UInt32 Base; - Kernel::UInt32 NumberOfFunctions; - Kernel::UInt32 NumberOfNames; - Kernel::UInt32 AddressOfFunctions; // export table rva - Kernel::UInt32 AddressOfNames; - Kernel::UInt32 AddressOfNameOrdinal; // ordinal table rva -} LDR_EXPORT_DIRECTORY, *LDR_EXPORT_DIRECTORY_PTR; - -typedef struct LDR_IMPORT_DIRECTORY { - union { - Kernel::UInt32 Characteristics; - Kernel::UInt32 OriginalFirstThunk; - }; - Kernel::UInt32 TimeDateStamp; - Kernel::UInt32 ForwarderChain; - Kernel::UInt32 NameRva; - Kernel::UInt32 ThunkTableRva; -} LDR_IMPORT_DIRECTORY, *LDR_IMPORT_DIRECTORY_PTR; - -typedef struct LDR_DATA_DIRECTORY { - Kernel::UInt32 VirtualAddress; - Kernel::UInt32 Size; -} LDR_DATA_DIRECTORY, *LDR_DATA_DIRECTORY_PTR; - -typedef struct LDR_IMAGE_HEADER { - LDR_EXEC_HEADER Header; - LDR_OPTIONAL_HEADER OptHdr; -} LDR_IMAGE_HEADER, *LDR_IMAGE_HEADER_PTR; - -enum { - kUserSection = 0x00000020, - kPEResourceId = 0xFFaadd00, -}; - -#endif /* ifndef __KERNELKIT_INC_PE_H__ */ diff --git a/dev/kernel/KernelKit/PE32CodeMgr.h b/dev/kernel/KernelKit/PE32CodeMgr.h deleted file mode 100644 index 52bc22b4..00000000 --- a/dev/kernel/KernelKit/PE32CodeMgr.h +++ /dev/null @@ -1,91 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: PE32CodeMgr.h - Purpose: PE32+ Code Mgr and Dylib mgr. - - Revision History: - - 12/02/24: Added file (amlel) - -======================================== */ - -#pragma once - -//////////////////////////////////////////////////// - -// LAST REV: Mon Feb 12 13:52:01 CET 2024 - -//////////////////////////////////////////////////// - -#include <KernelKit/FileMgr.h> -#include <KernelKit/ILoader.h> -#include <KernelKit/PE.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/KString.h> - -#ifndef INC_PROCESS_SCHEDULER_H -#include <KernelKit/ProcessScheduler.h> -#endif - -#define kPeStackSizeSymbol "__NESizeOfReserveStack" -#define kPeHeapSizeSymbol "__NESizeOfReserveHeap" -#define kPeNameSymbol "__NEProgramName" - -#define kPeApplicationMime "application/vnd-portable-executable" - -#define kPeImageStart "__ImageStart" - -namespace Kernel { -/// -/// \name PE32Loader -/// \brief PE32+ loader class. -/// -class PE32Loader : public ILoader { - private: - explicit PE32Loader() = delete; - - public: - explicit PE32Loader(const VoidPtr blob); - explicit PE32Loader(const Char* path); - ~PE32Loader() override; - - public: - NE_COPY_DEFAULT(PE32Loader) - - public: - const Char* Path() override; - const Char* AsString() override; - const Char* MIME() override; - - public: - ErrorOr<VoidPtr> FindStart() override; - ErrorOr<VoidPtr> FindSectionByName(const Char* name); - ErrorOr<VoidPtr> FindSymbol(const Char* name, Int32 kind) override; - ErrorOr<VoidPtr> GetBlob() override; - - public: - bool IsLoaded() noexcept; - - private: -#ifdef __FSKIT_INCLUDES_NEFS__ - OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile; -#elif defined(__FSKIT_INCLUDES_OPENHEFS__) - OwnPtr<FileStream<Char, HeFileSystemMgr>> fFile; -#else - OwnPtr<FileStream<Char>> fFile; -#endif // __FSKIT_INCLUDES_NEFS__ - - Ref<KString> fPath; - VoidPtr fCachedBlob; - BOOL fBad; -}; - -enum { kPEPlatformInvalid, kPEPlatformAMD64 = 100, kPEPlatformARM64 }; -enum { kPETypeInvalid, kPETypeText = 100, kPETypeData, kPETypeBSS }; - -typedef LDR_SECTION_HEADER PE_SECTION_INFO; - -ProcessID rtl_create_user_process(PE32Loader& exec, const Int32& process_kind) noexcept; -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/PEF.h b/dev/kernel/KernelKit/PEF.h deleted file mode 100644 index 94284c98..00000000 --- a/dev/kernel/KernelKit/PEF.h +++ /dev/null @@ -1,117 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: PEF.h - Purpose: Preferred Executable Format for Kernel. - - Revision History: - - ?/?/23: Added file (amlel) - -======================================== */ - -#ifndef __KERNELKIT_PEF_H__ -#define __KERNELKIT_PEF_H__ - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/ILoader.h> -#include <NeKit/Defines.h> - -#define kPefMagic "Open" -#define kPefMagicFat "nepO" - -#define kPefMagicLen (5) - -#define kPefVersion (0x0500) -#define kPefNameLen (256U) - -/* not mandatory, only for non fork based filesystems. */ -#define kPefExt ".exec" -#define kPefDylibExt ".dylib" -#define kPefLibExt ".lib" -#define kPefObjectExt ".obj" -#define kPefDebugExt ".dbg" -#define kPefDriverExt ".sys" - -// Kernel System Binary Interface. -#define kPefAbi (0x5046) - -#define kPefBaseOrigin (0x40000000) - -#define kPefStart "__ImageStart" -#define kPefMainSymbol "_NeMain" - -#define kPefForkKind kPefMagic -#define kPefForkKindFAT kPefMagicFat - -namespace Kernel { -enum { - kPefArchIntel86S, - kPefArchAMD64, - kPefArchRISCV, - kPefArch64x0, /* 64x0. ISA */ - kPefArch32x0, /* 32x0. ISA */ - kPefArchPowerPC, - kPefArchARM64, - kPefArchCount = (kPefArchARM64 - kPefArchIntel86S) + 1, - kPefArchInvalid = 0xFF, -}; - -enum { - kPefSubArchGeneric = 0, - kPefSubArchAMD = 200, - kPefSubArchIntel, - kPefSubArchARM, - kPefSubArchIBM, -}; - -enum { - kPefKindInvalid = 0, - kPefKindExec = 1, /* .exec */ - kPefKindDylib = 2, /* .dylib */ - kPefKindObject = 4, /* .obj */ - kPefKindDebug = 5, /* .dbg */ - kPefKindDriver = 6, - kPefKindCount, -}; - -typedef struct PEFContainer final { - Char Magic[kPefMagicLen]; - UInt32 Linker; - UInt32 Version; - UInt32 Kind; - UInt32 Abi; - UInt32 Cpu; - UInt32 SubCpu; /* Cpu specific information */ - UIntPtr Start; - SizeT HdrSz; /* Size of header */ - SizeT Count; /* container header count */ - UInt32 Checksum; -} PACKED PEFContainer; - -/* First PEFCommandHeader starts after PEFContainer */ - -typedef struct PEFCommandHeader final { - Char Name[kPefNameLen]; /* container name */ - UInt32 Cpu; /* container cpu */ - UInt32 SubCpu; /* container sub-cpu */ - UInt32 Flags; /* container flags */ - UInt16 Kind; /* container kind */ - UIntPtr Offset; /* content offset */ - SizeT OffsetSize; /* offset size (physical size inside the file) */ - UIntPtr VMAddress; /* Virtual Address */ - SizeT VMSize; /* Virtual Size */ -} PACKED PEFCommandHeader; - -enum { - kPefInvalid = 0x0, - kPefCode = 0xC, - kPefData = 0xD, - kPefZero = 0xE, - kPefLinkerID = 0x1, - kPefCount = 4, -}; -} // namespace Kernel - -#endif /* ifndef __KERNELKIT_PEF_H__ */ diff --git a/dev/kernel/KernelKit/PEFCodeMgr.h b/dev/kernel/KernelKit/PEFCodeMgr.h deleted file mode 100644 index 41b135e0..00000000 --- a/dev/kernel/KernelKit/PEFCodeMgr.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef _INC_CODE_MANAGER_PEF_H_ -#define _INC_CODE_MANAGER_PEF_H_ - -/// @file PEFCodeMgr.h -/// @brief PEF Code Manager header file. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -#include <KernelKit/FileMgr.h> -#include <KernelKit/PEF.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/KString.h> - -#ifndef INC_PROCESS_SCHEDULER_H -#include <KernelKit/ProcessScheduler.h> -#endif - -#define kPefApplicationMime "application/vnd-nekernel-executable" - -namespace Kernel { -/// -/// \name PEFLoader -/// \brief PEF loader class. -/// -class PEFLoader : public ILoader { - private: - explicit PEFLoader() = delete; - - public: - explicit PEFLoader(const VoidPtr blob); - explicit PEFLoader(const Char* path); - ~PEFLoader() override; - - public: - NE_COPY_DEFAULT(PEFLoader) - - public: - const Char* Path() override; - const Char* AsString() override; - const Char* MIME() override; - - public: - ErrorOr<VoidPtr> FindStart() override; - ErrorOr<VoidPtr> FindSymbol(const Char* name, Int32 kind) override; - ErrorOr<VoidPtr> GetBlob() override; - - public: - bool IsLoaded() noexcept; - - private: -#ifdef __FSKIT_INCLUDES_NEFS__ - OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile; -#elif defined(__FSKIT_INCLUDES_OPENHEFS__) - OwnPtr<FileStream<Char, HeFileSystemMgr>> fFile; -#else - OwnPtr<FileStream<Char>> fFile; -#endif // __FSKIT_INCLUDES_NEFS__ - - Ref<KString> fPath; - VoidPtr fCachedBlob; - BOOL fFatBinary{}; - BOOL fBad{}; -}; - -namespace Utils { - ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& procKind) noexcept; -} // namespace Utils -} // namespace Kernel - -#endif // ifndef _INC_CODE_MANAGER_PEF_H_ diff --git a/dev/kernel/KernelKit/ProcessScheduler.h b/dev/kernel/KernelKit/ProcessScheduler.h deleted file mode 100644 index 7414e4fe..00000000 --- a/dev/kernel/KernelKit/ProcessScheduler.h +++ /dev/null @@ -1,18 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/KernelTaskScheduler.h> -#include <KernelKit/UserProcessScheduler.h> - -#ifdef __NEOSKRNL__ -namespace Kernel { -inline UserProcessTeam kLowUserTeam; -inline UserProcessTeam kHighUserTeam; -inline UserProcessTeam kMidUserTeam; -} // namespace Kernel -#endif
\ No newline at end of file diff --git a/dev/kernel/KernelKit/Semaphore.h b/dev/kernel/KernelKit/Semaphore.h deleted file mode 100644 index 831774a5..00000000 --- a/dev/kernel/KernelKit/Semaphore.h +++ /dev/null @@ -1,110 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -/// @author Amlal El Mahrouss -/// @file Semaphore.h -/// @brief Semaphore structure and functions for synchronization in the kernel. - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/Timer.h> -#include <NeKit/Defines.h> - -#define kSemaphoreOwnerIndex (0U) -#define kSemaphoreCountIndex (1U) - -#define kSemaphoreCount (2U) - -#define kSemaphoreIncrementOwner(sem) (sem[kSemaphoreOwnerIndex]++) -#define kSemaphoreDecrementOwner(sem) (sem[kSemaphoreOwnerIndex]--) - -namespace Kernel { -/// @brief Semaphore structure used for synchronization. -typedef UInt64 SemaphoreArr[kSemaphoreCount]; - -/// @brief Checks if the semaphore is valid. -inline BOOL rtl_sem_is_valid(const SemaphoreArr& sem, UInt64 owner = 0) { - return sem[kSemaphoreOwnerIndex] == owner && sem[kSemaphoreCountIndex] > 0; -} - -/// @brief Releases the semaphore, resetting its owner and count. -/// @param sem -/// @return -inline BOOL rtl_sem_release(SemaphoreArr& sem) { - sem[kSemaphoreOwnerIndex] = 0; - sem[kSemaphoreCountIndex] = 0; - - return TRUE; -} - -/// @brief Initializes the semaphore with an owner and a count of zero. -/// @param sem the semaphore array to use. -/// @param owner the owner to set, could be anything identifitable. -/// @return -inline BOOL rtl_sem_acquire(SemaphoreArr& sem, UInt64 owner) { - if (!owner) { - err_global_get() = kErrorInvalidData; - return FALSE; // Invalid owner - } - - sem[kSemaphoreOwnerIndex] = owner; - sem[kSemaphoreCountIndex] = 0; - - return TRUE; -} - -/// @brief Waits for the semaphore to be available, blocking until it is. -/// @param sem -/// @param timeout -/// @param condition condition pointer. -/// @return -inline BOOL rtl_sem_wait(SemaphoreArr& sem, UInt64 owner, UInt64 timeout, - BOOL* condition = nullptr) { - if (!rtl_sem_is_valid(sem, owner)) { - return FALSE; - } - - if (timeout <= 0) { - err_global_get() = kErrorTimeout; - - return FALSE; - } - - if (!condition || *condition) { - if (sem[kSemaphoreCountIndex] == 0) { - err_global_get() = kErrorUnavailable; - return FALSE; - } - - err_global_get() = kErrorSuccess; - sem[kSemaphoreCountIndex]--; - - return TRUE; - } - - HardwareTimer timer(timeout); - BOOL ret = timer.Wait(); - - if (ret) { - if (!condition || *condition) { - if (sem[kSemaphoreCountIndex] == 0) { - err_global_get() = kErrorUnavailable; - return FALSE; - } - - err_global_get() = kErrorSuccess; - sem[kSemaphoreCountIndex]--; - - return TRUE; - } - } - - err_global_get() = kErrorTimeout; - - return FALSE; // Failed to acquire semaphore -} -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/ThreadLocalStorage.h b/dev/kernel/KernelKit/ThreadLocalStorage.h deleted file mode 100644 index 205d6df9..00000000 --- a/dev/kernel/KernelKit/ThreadLocalStorage.h +++ /dev/null @@ -1,68 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef KERNELKIT_TLS_H -#define KERNELKIT_TLS_H - -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> - -///! @brief Thread Local Storage for NeKernel. - -#define kCookieMag0Idx (0U) -#define kCookieMag1Idx (1U) -#define kCookieMag2Idx (2U) - -#define kCookieMag0 'N' -#define kCookieMag1 'K' -#define kCookieMag2 'O' - -#define kCookieMagLen (3U) - -struct THREAD_INFORMATION_BLOCK; - -/// @brief Thread Information Block. -/// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64) -struct PACKED THREAD_INFORMATION_BLOCK final { - Kernel::Char Cookie[kCookieMagLen]{0}; //! Thread Magic Number. - Kernel::VoidPtr UserData{nullptr}; //! Thread Information Record (User defined canary structure) -}; - -///! @brief Cookie Sanity check. -Kernel::Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* the_tib); - -///! @brief new ptr syscall. -template <typename T> -T* tls_new_ptr(void) noexcept; - -///! @brief delete ptr syscall. -template <typename T> -Kernel::Boolean tls_delete_ptr(T* ptr) noexcept; - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template <typename T> -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept; - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template <typename T> -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept; - -template <typename T, typename... Args> -T* tls_new_class(Args&&... args); - -/// @brief TLS install TIB and PIB. (syscall) -EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB); - -/// @brief TLS check (syscall) -EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept; - -#include <KernelKit/ThreadLocalStorage.inl> - -// last rev 7/7/24 - -#endif /* ifndef KERNELKIT_TLS_H */ diff --git a/dev/kernel/KernelKit/ThreadLocalStorage.inl b/dev/kernel/KernelKit/ThreadLocalStorage.inl deleted file mode 100644 index 66a3d282..00000000 --- a/dev/kernel/KernelKit/ThreadLocalStorage.inl +++ /dev/null @@ -1,89 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -//! @file ThreadLocalStorage.inl -//! @brief Allocate resources from the process's heap storage. - -#ifndef INC_PROCESS_SCHEDULER_H -#include <KernelKit/ProcessScheduler.h> -#endif - -template <typename T> -inline T* tls_new_ptr(void) noexcept { - using namespace Kernel; - - auto ref_process = UserProcessScheduler::The().TheCurrentProcess(); - MUST_PASS(ref_process); - - auto pointer = ref_process.Leak().New(sizeof(T)); - - if (pointer.Error()) return nullptr; - - return reinterpret_cast<T*>(pointer.Leak().Leak()); -} - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template <typename T> -inline Kernel::Bool tls_delete_ptr(T* obj) noexcept { - using namespace Kernel; - - if (!obj) return No; - - auto ref_process = UserProcessScheduler::The().TheCurrentProcess(); - MUST_PASS(ref_process); - - ErrorOr<T*> obj_wrapped{obj}; - - return ref_process.Leak().Delete(obj_wrapped); -} - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template <typename T> -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept { - return tls_delete_ptr(obj.Leak()); -} - -//! @brief Delete process pointer. -//! @param obj The pointer to delete. -template <typename T> -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept { - return tls_delete_ptr(obj->Leak()); -} - -/// @brief Allocate a C++ class, and then call the constructor of it. -/// @tparam T class type. -/// @tparam ...Args varg class type. -/// @param args arguments list. -/// @return Class instance. -template <typename T, typename... Args> -T* tls_new_class(Args&&... args) { - using namespace Kernel; - - T* obj = tls_new_ptr<T>(); - - if (obj) { - *obj = T(forward(args)...); - return obj; - } - - return nullptr; -} - -/// @brief Delete a C++ class (call constructor first.) -/// @tparam T -/// @param obj -/// @return -template <typename T> -inline Kernel::Bool tls_delete_class(T* obj) { - using namespace Kernel; - - if (!obj) return No; - - obj->~T(); - return tls_delete_ptr(obj); -} diff --git a/dev/kernel/KernelKit/Timer.h b/dev/kernel/KernelKit/Timer.h deleted file mode 100644 index 46db5671..00000000 --- a/dev/kernel/KernelKit/Timer.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <ArchKit/ArchKit.h> -#include <KernelKit/KPC.h> - -namespace Kernel { -class SoftwareTimer; -class TimerInterface; - -inline constexpr Int16 kTimeUnit = 1000; - -class TimerInterface { - public: - /// @brief Default constructor - explicit TimerInterface() = default; - virtual ~TimerInterface() = default; - - public: - NE_COPY_DEFAULT(TimerInterface) - - public: - virtual BOOL Wait() noexcept; -}; - -class SoftwareTimer final : public TimerInterface { - public: - explicit SoftwareTimer(Int64 seconds); - ~SoftwareTimer() override; - - public: - NE_COPY_DEFAULT(SoftwareTimer) - - public: - BOOL Wait() noexcept override; - - private: - UIntPtr* fDigitalTimer{nullptr}; - Int64 fWaitFor{0}; -}; - -class HardwareTimer final : public TimerInterface { - public: - explicit HardwareTimer(UInt64 seconds); - ~HardwareTimer() override; - - public: - NE_COPY_DEFAULT(HardwareTimer) - - public: - BOOL Wait() noexcept override; - - private: - volatile UInt8* fDigitalTimer{nullptr}; - Int64 fWaitFor{0}; -}; - -inline UInt64 rtl_microseconds(UInt64 time) { - if (time < 1) return 0; - - // TODO: nanoseconds maybe? - return time / kTimeUnit; -} - -inline UInt64 rtl_milliseconds(UInt64 time) { - if (time < 1) return 0; - - return time; -} -} // namespace Kernel diff --git a/dev/kernel/KernelKit/TraceSrv.h b/dev/kernel/KernelKit/TraceSrv.h deleted file mode 100644 index df188ea2..00000000 --- a/dev/kernel/KernelKit/TraceSrv.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - NeKernel is licensed under the Apache License 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> - -namespace Kernel { -namespace Detail { - inline constexpr auto kDebugCmdLen = 256U; - inline constexpr auto kDebugPort = 51820; - inline constexpr auto kDebugMagic = "NE1.0.0;"; - inline constexpr auto kDebugVersion = 0x0100; - inline constexpr auto kDebugDelim = ';'; - inline constexpr auto kDebugEnd = '\r'; - typedef UInt64 dk_socket_type; -} // namespace Detail -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/KernelKit/UserMgr.h b/dev/kernel/KernelKit/UserMgr.h deleted file mode 100644 index 3ce6254d..00000000 --- a/dev/kernel/KernelKit/UserMgr.h +++ /dev/null @@ -1,95 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef INC_USER_H -#define INC_USER_H - -/* ======================================== - - Revision History: - - 04/03/25: Set users directory as /libSystem/ instead of /usr/ - - ======================================== */ - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/KPC.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> - -///! We got the MGMT, STD (%s format) and GUEST users, -///! all are used to make authorized operations. -#define kMgmtUser "NEKERNEL/MGMT/%s" -#define kGuestUser "NEKERNEL/GUEST/%s" -#define kStdUser "NEKERNEL/STD/%s" - -#define kUsersDir "/users/" - -#define kMaxUserNameLen (256U) -#define kMaxUserTokenLen (256U) - -namespace Kernel { -class User; - -enum class UserRingKind : Int32 { - kRingInvalid = 0, - kRingStdUser = 444, - kRingSuperUser = 666, - kRingGuestUser = 777, - kRingCount = 3, -}; - -typedef Char* UserPublicKey; -typedef Char UserPublicKeyType; - -/// @brief System User class. -class User final { - public: - User() = delete; - - User(const Int32& sel, const Char* username); - User(const UserRingKind& kind, const Char* username); - - ~User(); - - public: - NE_COPY_DEFAULT(User) - - public: - bool operator==(const User& lhs); - bool operator!=(const User& lhs); - - public: - /// @brief Get software ring - const UserRingKind& Ring() noexcept; - - /// @brief Get user name - Char* Name() noexcept; - - /// @brief Is he a standard user? - Bool IsStdUser() noexcept; - - /// @brief Is she a super user? - Bool IsSuperUser() noexcept; - - /// @brief Saves a password from the public key. - Bool Save(const UserPublicKey password) noexcept; - - /// @brief Checks if a password matches the **password**. - /// @param password the password to check. - Bool Login(const UserPublicKey password) noexcept; - - private: - UserRingKind mUserRing{UserRingKind::kRingStdUser}; - Char mUserName[kMaxUserNameLen] = {0}; - UInt64 mUserFNV{0UL}; -}; - -inline User* kCurrentUser = nullptr; -inline User* kRootUser = nullptr; -} // namespace Kernel - -#endif /* ifndef INC_USER_H */ diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h deleted file mode 100644 index b2ab7dc2..00000000 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ /dev/null @@ -1,243 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef INC_PROCESS_SCHEDULER_H -#define INC_PROCESS_SCHEDULER_H - -/// @file UserProcessScheduler.h -/// @brief User Process Scheduler header file. -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -#include <ArchKit/ArchKit.h> -#include <KernelKit/CoreProcessScheduler.h> -#include <KernelKit/LockDelegate.h> -#include <KernelKit/UserMgr.h> -#include <NeKit/MutableArray.h> - -//////////////////////////////////////////////////// -// Last revision date is: Fri Mar 28 2025 // -//////////////////////////////////////////////////// - -namespace Kernel { -//! @brief Forward declarations. - -class IDylibObject; -class UserProcessScheduler; -class UserProcessHelper; - -/***********************************************************************************/ -/// @name USER_PROCESS -/// @brief USER_PROCESS class, holds information about the running process/thread. -/***********************************************************************************/ -class USER_PROCESS final { - public: - explicit USER_PROCESS(); - ~USER_PROCESS(); - - public: - NE_COPY_DEFAULT(USER_PROCESS) - - public: - Char Name[kSchedNameLen] = {"USER_PROCESS"}; - ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemUser}; - User* Owner{nullptr}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity{AffinityKind::kStandard}; - ProcessStatusKind Status{ProcessStatusKind::kKilled}; - UInt8 StackReserve[kSchedMaxStackSz]; - ProcessImage Image{}; - SizeT StackSize{kSchedMaxStackSz}; - IDylibObject* DylibDelegate{nullptr}; - SizeT MemoryCursor{0UL}; - SizeT MemoryLimit{kSchedMaxMemoryLimit}; - SizeT UsedMemory{0UL}; - - struct USER_PROCESS_SIGNAL final { - UIntPtr SignalArg{0}; - ProcessStatusKind Status{ProcessStatusKind::kKilled}; - UIntPtr SignalID{0}; - }; - - USER_PROCESS_SIGNAL Signal; - PROCESS_FILE_TREE<VoidPtr>* FileTree{nullptr}; - PROCESS_HEAP_TREE<VoidPtr>* HeapTree{nullptr}; - UserProcessTeam* ParentTeam; - - VoidPtr VMRegister{0UL}; - - enum { - kInvalidExecutableKind, - kExecutableKind, - kExecutableDylibKind, - kExecutableKindCount, - }; - - ProcessTime PTime{0}; //! @brief Process allocated tine. - ProcessTime RTime{0}; //! @brief Process run time. - ProcessTime UTime{0}; //! #brief Process used time. - - ProcessID ProcessId{kSchedInvalidPID}; - Int32 Kind{kExecutableKind}; - - public: - /***********************************************************************************/ - //! @brief boolean operator, check status. - /***********************************************************************************/ - explicit operator bool(); - - /***********************************************************************************/ - ///! @brief Crashes the app, exits with code ~0. - /***********************************************************************************/ - Void Crash(); - - /***********************************************************************************/ - ///! @brief Spawns a dynamic library handle if dylib. - /***********************************************************************************/ - Bool InitDylib(); - - /***********************************************************************************/ - ///! @brief Exits the app. - /***********************************************************************************/ - Void Exit(const Int32& exit_code = 0); - - /***********************************************************************************/ - ///! @brief TLS allocate. - ///! @param sz size of data structure. - ///! @param pad_amount amount to add after pointer. - ///! @return A wrapped pointer, or error code. - /***********************************************************************************/ - ErrorOr<VoidPtr> New(SizeT sz, SizeT pad_amount = 0); - - /***********************************************************************************/ - ///! @brief TLS free. - ///! @param ptr the pointer to free. - ///! @param sz the size of it. - /***********************************************************************************/ - template <typename T> - Boolean Delete(ErrorOr<T*> ptr); - - /***********************************************************************************/ - ///! @brief Wakes up thread. - /***********************************************************************************/ - Void Wake(Bool wakeup = false); - - public: - /***********************************************************************************/ - //! @brief Gets the local exit code. - /***********************************************************************************/ - KPCError& GetExitCode() noexcept; - - /***********************************************************************************/ - ///! @brief Get the process's name - ///! @example 'C Runtime Library' - /***********************************************************************************/ - const Char* GetName() noexcept; - - /***********************************************************************************/ - //! @brief return local error code of process. - //! @return Int32 local error code. - /***********************************************************************************/ - KPCError& GetLocalCode() noexcept; - - const User* GetOwner() noexcept; - const ProcessStatusKind& GetStatus() noexcept; - const AffinityKind& GetAffinity() noexcept; - - private: - KPCError LastExitCode{0}; - KPCError LocalCode{0}; - - friend UserProcessScheduler; - friend UserProcessHelper; -}; - -typedef Array<USER_PROCESS, kSchedProcessLimitPerTeam> USER_PROCESS_ARRAY; -typedef Ref<USER_PROCESS> USER_PROCESS_REF; - -/// \brief Processs Team (contains multiple processes inside it.) -/// Equivalent to a process batch -class UserProcessTeam final { - public: - explicit UserProcessTeam(); - ~UserProcessTeam() = default; - - NE_COPY_DEFAULT(UserProcessTeam) - - Array<USER_PROCESS, kSchedProcessLimitPerTeam>& AsArray(); - Ref<USER_PROCESS>& AsRef(); - ProcessID& Id() noexcept; - - public: - USER_PROCESS_ARRAY mProcessList; - USER_PROCESS_REF mCurrentProcess; - ProcessID mTeamId{0}; - ProcessID mProcessCur{0}; -}; - -/***********************************************************************************/ -/// @brief USER_PROCESS scheduler class. -/// The main class which you call to schedule user processes. -/***********************************************************************************/ -class UserProcessScheduler final : public ISchedulable { - friend class UserProcessHelper; - - public: - explicit UserProcessScheduler() = default; - ~UserProcessScheduler() override = default; - - NE_COPY_DELETE(UserProcessScheduler) - NE_MOVE_DELETE(UserProcessScheduler) - - public: - explicit operator bool(); - bool operator!(); - - public: - UserProcessTeam& TheCurrentTeam(); - BOOL SwitchTeam(UserProcessTeam& team); - - public: - ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); - Void Remove(ProcessID process_id); - - Bool IsUser() override; - Bool IsKernel() override; - Bool HasMP() override; - - public: - USER_PROCESS_REF& TheCurrentProcess(); - SizeT Run() noexcept; - - public: - STATIC UserProcessScheduler& The(); - - private: - UserProcessTeam mTeam{}; -}; - -/***********************************************************************************/ -/** - * \brief USER_PROCESS helper class, which contains needed utilities for the scheduler. - */ -/***********************************************************************************/ - -class UserProcessHelper final { - public: - STATIC Bool Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid); - STATIC Bool CanBeScheduled(const USER_PROCESS& process); - STATIC ErrorOr<ProcessID> TheCurrentPID(); - STATIC SizeT StartScheduling(); -}; -} // namespace Kernel - -#include <KernelKit/ThreadLocalStorage.h> -#include <KernelKit/UserProcessScheduler.inl> - -//////////////////////////////////////////////////// -// END -//////////////////////////////////////////////////// - -#endif /* ifndef INC_PROCESS_SCHEDULER_H */ diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl deleted file mode 100644 index 3d3659d6..00000000 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ /dev/null @@ -1,64 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - FILE: UserProcessScheduler.inl - PURPOSE: Low level/Ring-3 process scheduler. - -======================================== */ - -/// @brief USER_PROCESS inline definitions. -/// @author Amlal El Mahrouss (amlal@nekernel.org) -/// @date Tue Apr 22 22:01:07 CEST 2025 - -#ifndef INC_PROCESS_SCHEDULER_H -#include <KernelKit/UserProcessScheduler.h> -#endif // INC_PROCESS_SCHEDULER_H - -namespace Kernel { -/***********************************************************************************/ -/** @brief Free pointer/file from usage. */ -/***********************************************************************************/ - -template <typename T> -BOOL USER_PROCESS::Delete(ErrorOr<T*> ptr) { - if (!ptr) return No; - - if (!this->HeapTree) { - kout << "USER_PROCESS's heap is empty.\r"; - return No; - } - - PROCESS_HEAP_TREE<VoidPtr>* entry = this->HeapTree; - - while (entry != nullptr) { - if (entry->Entry == ptr.Leak().Leak()) { - this->UsedMemory -= entry->EntrySize; - -#ifdef __NE_AMD64__ - auto pd = hal_read_cr3(); - - hal_write_cr3(this->VMRegister); - - auto ret = mm_free_ptr(entry->Entry); - - hal_write_cr3(pd); - - return ret == kErrorSuccess; -#else - Bool ret = mm_free_ptr(ptr.Leak().Leak()); - - return ret == kErrorSuccess; -#endif - } - - entry = entry->Next; - } - - kout << "USER_PROCESS: Trying to free a pointer which doesn't exist.\r"; - - this->Crash(); - - return No; -} -} // namespace Kernel diff --git a/dev/kernel/KernelKit/XCOFF.h b/dev/kernel/KernelKit/XCOFF.h deleted file mode 100644 index cbee6100..00000000 --- a/dev/kernel/KernelKit/XCOFF.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: XCOFF.h - Purpose: XCOFF for Kernel. - - Revision History: - - 04/07/24: Added file (amlel) - -======================================== */ - -#ifndef INC_XOCFF_H -#define INC_XOCFF_H - -#include <NeKit/Defines.h> - -#define kXCOFF64Magic (0x01F7) -#define kXCOFF64ForkNameLen (256U) - -#define kXCOFFRelFlg (0x0001) -#define kXCOFFExecutable (0x0002) -#define kXCOFFLnno (0x0004) -#define kXCOFFLSyms (0x0008) - -struct XCOFF_FILE_HEADER; -struct XCOFF_FORK_HEADER; - -/// @brief XCoff file header, meant for POWER apps. -typedef struct XCOFF_FILE_HEADER { - Kernel::UInt16 fMagic; - Kernel::UInt16 fTarget; - Kernel::UInt16 fNumSecs; - Kernel::UInt32 fTimeDat; - Kernel::UIntPtr fSymPtr; - Kernel::UInt32 fNumSyms; - Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header -} XCOFF_FILE_HEADER, XCOFF_FILE_HEADER32, XCOFF_FILE_HEADER64; - -/// @brief This the executable's manifest fork, designed for NeFS. -/// @param fPropertiesXMLFork The XML fork of the executable. -/// @param fDynamicLoaderFork The DYLD fork metadata. -/// @param fCodeSignFork Executable's certificate contained in a fork. -typedef struct XCOFF_FORK_HEADER { - Kernel::Char fPropertiesXMLFork[kXCOFF64ForkNameLen]; - Kernel::Char fDynamicLoaderFork[kXCOFF64ForkNameLen]; - Kernel::Char fCodeSignFork[kXCOFF64ForkNameLen]; -} XCOFF_FORK_HEADER; - -#endif // ifndef INC_XOCFF_H diff --git a/dev/kernel/KernelKit/ZXD.h b/dev/kernel/KernelKit/ZXD.h deleted file mode 100644 index a4b07bfa..00000000 --- a/dev/kernel/KernelKit/ZXD.h +++ /dev/null @@ -1,53 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -#define kZXDMagicNumber (0x2010AF) -#define kZXDVersion (0x0001) - -namespace Kernel { -struct ZXD_EXEC_HEADER; -struct ZXD_STUB_HEADER; - -enum ZXD_FLAGS { - kZXDFlagsInvalid, - kZXDFlagsDriver, - kZXDFlagsCount, -}; - -/// @brief ZXD executable header -/// @details This header is used to identify ZXD executable files. -struct PACKED ZXD_EXEC_HEADER final { - UInt32 fMagic; - UInt32 fVersion; - UInt32 fFlags; - UInt32 fHdrSize; - UInt32 fCRC32; - UInt32 fAssigneeSignature; - UInt32 fIssuerSingature; - UIntPtr fExecOffset; - SizeT fExecSize; - UIntPtr fStubOffset; - SizeT fStubSize; - SizeT fStubAlign; - SizeT fStubCount; -}; - -/// @brief ZXD stub header -/// @details This header is used to identify ZXD stub files. It contains the size of the stub, the -/// offset of the stub, and the CRC32 checksum of the stub. -struct PACKED ZXD_STUB_HEADER final { - UInt32 fStubSize; - UInt32 fStubOffset; - UInt32 fStubCRC32; -}; - -using ZXD_EXEC_HEADER_PTR = ZXD_EXEC_HEADER*; -using ZXD_STUB_HEADER_PTR = ZXD_STUB_HEADER*; -} // namespace Kernel diff --git a/dev/kernel/NeKit/Array.h b/dev/kernel/NeKit/Array.h deleted file mode 100644 index 5b8371db..00000000 --- a/dev/kernel/NeKit/Array.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DebugOutput.h> -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> - -namespace Kernel { -template <typename T, SizeT N> -class Array final { - public: - explicit Array() = default; - ~Array() = default; - - Array& operator=(const Array&) = default; - Array(const Array&) = default; - - T& operator[](SizeT at) { return fArray[at]; } - - Boolean Empty() { return this->Count() > 0; } - - SizeT Capacity() { return N; } - - SizeT Count() { - const static SizeT kArrCnt = N; - return kArrCnt; // avoid constexpr error. - } - - const T* CData() { return fArray; } - - operator bool() { return !Empty(); } - - private: - T fArray[N]; -}; - -template <typename ValueType> -auto make_list(ValueType val) { - return Array<ValueType, ARRAY_SIZE(val)>{val}; -} -} // namespace Kernel diff --git a/dev/kernel/NeKit/ArrayList.h b/dev/kernel/NeKit/ArrayList.h deleted file mode 100644 index 54613b67..00000000 --- a/dev/kernel/NeKit/ArrayList.h +++ /dev/null @@ -1,44 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -template <typename T> -class ArrayList final { - public: - explicit ArrayList(T* list, SizeT length) : fList(reinterpret_cast<T>(list)), fLen(length) {} - - ~ArrayList() = default; - - ArrayList& operator=(const ArrayList&) = default; - ArrayList(const ArrayList&) = default; - - T* Data() { return fList; } - - const T* CData() { return fList; } - - T& operator[](SizeT index) const { - MUST_PASS(index < this->Count()); - return fList[index]; - } - - operator bool() { return fList; } - - SizeT Count() const { return fLen; } - - private: - T* fList{nullptr}; - SizeT fLen{0}; -}; - -template <typename ValueType> -ArrayList<ValueType> make_list(ValueType val) { - return ArrayList<ValueType>{val}; -} -} // namespace Kernel diff --git a/dev/kernel/NeKit/Atom.h b/dev/kernel/NeKit/Atom.h deleted file mode 100644 index 0f8eefbc..00000000 --- a/dev/kernel/NeKit/Atom.h +++ /dev/null @@ -1,33 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -template <typename T> -class Atom final { - public: - explicit Atom() = default; - ~Atom() = default; - - public: - Atom& operator=(const Atom&) = delete; - Atom(const Atom&) = delete; - - public: - T operator[](Size bit) { return (fArrayOfAtoms & (1 << bit)); } - - void operator|(Size bit) { fArrayOfAtoms |= (1 << bit); } - - friend Boolean operator==(Atom<T>& atomic, const T& idx) { return atomic[idx] == idx; } - - friend Boolean operator!=(Atom<T>& atomic, const T& idx) { return atomic[idx] == idx; } - - private: - T fArrayOfAtoms; -}; -} // namespace Kernel diff --git a/dev/kernel/NeKit/Crc32.h b/dev/kernel/NeKit/Crc32.h deleted file mode 100644 index 3c6a904f..00000000 --- a/dev/kernel/NeKit/Crc32.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * ======================================================== - * - * NeKernel - * Date Added: 13/02/2023 - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#ifndef NEKIT_CRC32_H -#define NEKIT_CRC32_H - -#include <NeKit/Defines.h> - -namespace Kernel { -UInt32 ke_calculate_crc32(const VoidPtr crc, Int32 len) noexcept; -} // namespace Kernel - -#endif // !NEKIT_CRC32_H diff --git a/dev/kernel/NeKit/CxxAbi.h b/dev/kernel/NeKit/CxxAbi.h deleted file mode 100644 index 7b13d6b3..00000000 --- a/dev/kernel/NeKit/CxxAbi.h +++ /dev/null @@ -1,26 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ -#pragma once - -#include <NeKit/Defines.h> - -#ifndef __NECTI__ - -#define kAtExitMacDestructors (128) - -struct atexit_func_entry_t { - void (*destructor_func)(); - void* obj_ptr; - void* dso_handle; -}; - -typedef Kernel::UInt32 uarch_t; - -namespace cxxabiv1 { -typedef Kernel::SizeT* __guard; -} - -#endif // !__NECTI__ diff --git a/dev/kernel/NeKit/Defines.h b/dev/kernel/NeKit/Defines.h deleted file mode 100644 index 1a6a2cf6..00000000 --- a/dev/kernel/NeKit/Defines.h +++ /dev/null @@ -1,179 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Macros.h> - -#define NEKIT_VERSION_STR "0.0.1" -#define NEKIT_VERSION_BCD 0x0001 - -#ifndef __cplusplus -#error !!! Kernel compiles only with a C++ compiler. !!! -#endif - -#if __cplusplus <= 201703L -#define char8_t char -#endif - -#ifdef __has_feature -#if !__has_feature(cxx_nullptr) -#if !__has_nullptr -#error !!! You must at least have nullptr featured on your C++ compiler. !!! -#endif -#endif -#endif - -/// @brief The **Kernel** namespace. -namespace Kernel { -using voidPtr = void*; -using VoidPtr = void*; -using nullPtr = decltype(nullptr); -using NullPtr = decltype(nullptr); - -using Int = int; -using Int32 = __INT32_TYPE__; -using UShort = __UINT16_TYPE__; -using UInt16 = __UINT16_TYPE__; -using Short = short; -using Int16 = __INT16_TYPE__; -using UInt = __UINT32_TYPE__; -using UInt32 = __UINT32_TYPE__; -using Long = __INT64_TYPE__; -using Int64 = __INT64_TYPE__; -using ULong = __UINT64_TYPE__; -using UInt64 = __UINT64_TYPE__; -using Boolean = bool; -using Bool = bool; -using Char = char; -using Int8 = __INT8_TYPE__; -using Char8 = char8_t; -using UChar = __UINT8_TYPE__; -using UInt8 = __UINT8_TYPE__; - -using SSize = long; -using SSizeT = long; -using Size = __SIZE_TYPE__; -using SizeT = __SIZE_TYPE__; -using IntPtr = __INTPTR_TYPE__; -using UIntPtr = __UINTPTR_TYPE__; -using IntFast = __INT_FAST32_TYPE__; -using IntFast64 = __INT_FAST64_TYPE__; -using PtrDiff = __PTRDIFF_TYPE__; - -using SInt16 = Int16; -using SInt32 = Int32; -using SInt64 = Int64; - -typedef UIntPtr* Ptr64; -typedef UInt32* Ptr32; -typedef UInt8* Ptr8; - -using Utf8Char = char8_t; -using Utf16Char = char16_t; -using WideChar = wchar_t; -using Utf32Char = char32_t; - -using LongDouble = long double; -using Double = double; -using Float = float; - -typedef UInt32 PhysicalAddressKind; -typedef UIntPtr VirtualAddressKind; - -using Void = void; -using Any = void*; - -using Lba = UInt64; - -using Char16 = char16_t; - -enum class Endian : UInt8 { kEndianInvalid, kEndianBig, kEndianLittle, kEndianMixed, kEndianCount }; - -/// @brief Forward object. -/// @tparam Args the object type. -/// @param arg the object. -/// @return object's rvalue -template <typename Args> -inline Args&& forward(Args& arg) { - return static_cast<Args&&>(arg); -} - -/// @brief Move object. -/// @tparam Args the object type. -/// @param arg the object. -/// @return object's rvalue -template <typename Args> -inline Args&& move(Args&& arg) { - return static_cast<Args&&>(arg); -} - -/// @brief Encoding interface, used as a proxy to convert T to Char* -/// Used to cast A to B or B to A. -class ICodec { - public: - explicit ICodec() = default; - virtual ~ICodec() = default; - - ICodec& operator=(const ICodec&) = default; - ICodec(const ICodec&) = default; - - public: - /// @brief Convert type to bytes. - /// @tparam T the type. - /// @param type (a1) the data. - /// @return a1 as Char* - template <typename T> - const Char* AsBytes(T type) noexcept { - NE_UNUSED(type); - return nullptr; - } - - /// @brief Construct from type to class. - /// @tparam T the type to convert. - /// @param type (a1) the data. - /// @return a1 as Char* - template <typename OutputClass, typename FactoryClass> - OutputClass* Construct(Char* type) noexcept { - FactoryClass class_fac; - return class_fac.template From<OutputClass>(type); - } - - /// @brief Convert T class to Y class. - /// @tparam T the class type of type. - /// @tparam Y the result class. - /// @param type the class to cast. - /// @return the class as Y. - template <typename T, typename Y> - Y As(T type) noexcept { - if (type.template IsSerializable()) { - return reinterpret_cast<Char*>(type); - } - - return type.template As<Y>(); - } -}; - -/// \brief Scheduler interface, represents a scheduler object. -/// @note This is used to schedule tasks, such as threads, drivers, user threads, etc. -class ISchedulable { - public: - explicit ISchedulable() = default; - virtual ~ISchedulable() = default; - - ISchedulable& operator=(const ISchedulable&) = default; - ISchedulable(const ISchedulable&) = default; - - /// @brief Is this object only accepting user tasks? - virtual Bool IsUser() { return NO; } - - /// @brief Is this object only accepting kernel tasks? - virtual Bool IsKernel() { return NO; } - - /// @brief Is this object offloading to another CPU? - virtual Bool HasMP() { return NO; } -}; -} // namespace Kernel diff --git a/dev/kernel/NeKit/ErrorOr.h b/dev/kernel/NeKit/ErrorOr.h deleted file mode 100644 index d930fe17..00000000 --- a/dev/kernel/NeKit/ErrorOr.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ======================================================== - * - * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/Ref.h> - -namespace Kernel { -using ErrorT = Int32; - -/// ================================================================================ -/// @brief ErrorOr class for error handling. -/// ================================================================================ -template <typename T> -class ErrorOr final { - public: - explicit ErrorOr() = default; - ~ErrorOr() = default; - - public: - explicit ErrorOr(ErrorT err) : mRef((T*) RTL_ALLOCA(sizeof(T))), mId(err) {} - - explicit ErrorOr(nullPtr) {} - - explicit ErrorOr(T* Class) : mRef(Class) {} - - explicit ErrorOr(T Class) : mRef(Class) {} - - ErrorOr& operator=(const ErrorOr&) = default; - ErrorOr(const ErrorOr&) = default; - - ErrorOr& operator=(const Ref<T>& refErr) { - mRef = refErr; - return *this; - } - - const T& Value() { return mRef.TryLeak(); } - - Ref<T>& Leak() { return mRef; } - - ErrorT Error() { return mId; } - - /// @note DO NOT MAKE THIS EXPLICIT! IT WILL BREAK THE COMPILATION. - operator bool() { return mRef; } - - BOOL HasError() { return this->mId < 0; } - - private: - Ref<T> mRef; - ErrorT mId{0}; -}; - -using ErrorOrAny = ErrorOr<voidPtr>; - -} // namespace Kernel diff --git a/dev/kernel/NeKit/Function.h b/dev/kernel/NeKit/Function.h deleted file mode 100644 index 70242bc3..00000000 --- a/dev/kernel/NeKit/Function.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> - -namespace Kernel { -/// ================================================================================ -/// @brief Function wrapper class. -/// ================================================================================ -template <typename T, typename... Args> -class Function final { - public: - Function() = default; - - public: - explicit Function(T (*Fn)(Args... args)) : fFn(Fn) {} - - ~Function() = default; - - Function& operator=(const Function&) = default; - Function(const Function&) = default; - - template <typename... XArgs> - T operator()(Args&&... args) { - return fFn(args...); - } - - template <typename... XArgs> - T Call(Args&&... args) { - return fFn(args...); - } - - operator bool() { return fFn; } - - bool operator!() { return !fFn; } - - private: - T(*fFn) - (Args... args){nullptr}; -}; - -template <typename T, typename... Args> -using FunctionOr = ErrorOr<Function<T, Args...>>; -} // namespace Kernel - diff --git a/dev/kernel/NeKit/Json.h b/dev/kernel/NeKit/Json.h deleted file mode 100644 index 1e804354..00000000 --- a/dev/kernel/NeKit/Json.h +++ /dev/null @@ -1,146 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -/// @brief Kernel JSON API. - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <NeKit/Stream.h> -#include <NeKit/Utils.h> - -#define kNeJsonMaxLen (8196) -#define kNeJsonLen (256) -#define kNeJsonNullArr "[]" -#define kNeJsonNullObj "{}" -#define kNeJsonNullKey "null" -#define kNeJsonNullValue kNeJsonNullKey - -namespace Kernel { -/// ================================================================================ -/// @brief JSON object representation. -/// ================================================================================ -template <typename CharKind = Char> -class JsonObject final { - public: - explicit JsonObject() { - KBasicString<CharKind> key = KString(kNeJsonMaxLen); - key += kNeJsonNullValue; - - this->AsKey() = key; - this->AsValue() = key; - } - - explicit JsonObject(SizeT lhsLen, SizeT rhsLen) : fKey(lhsLen), fValue(rhsLen) { - - KBasicString<CharKind> key = KString(lhsLen); - this->AsKey() = key; - - KBasicString<CharKind> value = KString(rhsLen); - this->AsValue() = value; - } - - ~JsonObject() = default; - - NE_COPY_DEFAULT(JsonObject) - NE_MOVE_DEFAULT(JsonObject) - - Bool& IsUndefined() { return fUndefined; } - - private: - Bool fUndefined; // is this instance undefined? - KBasicString<CharKind> fKey; - KBasicString<CharKind> fValue; - - public: - /// @brief returns the key of the json - /// @return the key as string view. - KBasicString<CharKind>& AsKey() { return fKey; } - - /// @brief returns the value of the json. - /// @return the key as string view. - KBasicString<CharKind>& AsValue() { return fValue; } - - STATIC JsonObject<CharKind> kNull; -}; - -/// ================================================================================ -/// @brief JsonObject stream reader helper for ASCII. -/// ================================================================================ -struct AsciiJsonStreamReader final { - STATIC JsonObject<Char> In(const Char* full_array) { - auto start_val = '{'; - auto end_val = '}'; - Boolean probe_value = false; - - if (full_array[0] != start_val) { - if (full_array[0] != '[') return JsonObject<Char>{0, 0}; - - start_val = '['; - end_val = ']'; - - probe_value = true; - } - - SizeT len = rt_string_len(full_array); - - SizeT key_len = 0; - SizeT value_len = 0; - - JsonObject<Char> type(kNeJsonMaxLen, kNeJsonMaxLen); - - for (SizeT i = 1; i < len; ++i) { - if (full_array[i] == '\r' || full_array[i] == '\n') continue; - - if (probe_value) { - if (full_array[i] == end_val || full_array[i] == ',') { - probe_value = false; - - ++value_len; - } else { - if (full_array[i] == '\'') { - type.AsValue().Data()[value_len] = 0; - break; - } - - type.AsValue().Data()[value_len] = full_array[i]; - - ++value_len; - } - } else { - if (start_val == '[') continue; - - if (full_array[i] == ':') { - type.AsKey().Data()[key_len] = 0; - ++key_len; - - ++i; - - while (full_array[i] == ' ' || full_array[i] == '\t') ++i; - - probe_value = true; - } else { - type.AsKey().Data()[key_len] = full_array[i]; - - ++key_len; - } - } - } - - type.AsValue().Data()[value_len] = 0; - - return type; - } -}; - -/// ================================================================================ -/// @brief AsciiJsonStream type definition. -/// ================================================================================ -using AsciiJsonStream = Stream<AsciiJsonStreamReader, JsonObject<Char>>; -} // namespace Kernel diff --git a/dev/kernel/NeKit/KString.h b/dev/kernel/NeKit/KString.h deleted file mode 100644 index fa83fed4..00000000 --- a/dev/kernel/NeKit/KString.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> - -namespace Kernel { -inline auto kMinimumStringSize = 8196; - -/// @brief Kernel string class, not dynamic. -template <typename CharKind = Char> -class KBasicString final { - public: - explicit KBasicString() { - fDataSz = kMinimumStringSize; - - fData = new CharKind[fDataSz]; - MUST_PASS(fData); - - rt_set_memory(fData, 0, fDataSz); - } - - explicit KBasicString(SizeT Sz) : fDataSz(Sz) { - MUST_PASS(Sz > 1); - - fData = new CharKind[Sz]; - MUST_PASS(fData); - - rt_set_memory(fData, 0, Sz); - } - - ~KBasicString() { - if (fData) { - delete[] fData; - fData = nullptr; - } - } - - NE_COPY_DEFAULT(KBasicString) - - CharKind* Data(); - const CharKind* CData() const; - Size Length() const; - - bool operator==(const CharKind* rhs) const; - bool operator!=(const CharKind* rhs) const; - - bool operator==(const KBasicString<CharKind>& rhs) const; - bool operator!=(const KBasicString<CharKind>& rhs) const; - - KBasicString<CharKind>& operator+=(const CharKind* rhs); - KBasicString<CharKind>& operator+=(const KBasicString<CharKind>& rhs); - - operator const char*() { return fData; } - - operator bool() { return fData; } - - bool operator!() { return fData; } - - private: - CharKind* fData{nullptr}; - Size fDataSz{0}; - Size fCur{0}; - - friend class KStringBuilder; -}; - -using KString = KBasicString<>; -using KStringOr = ErrorOr<KString>; - -class KStringBuilder final { - public: - template <typename CharKind = Char> - static ErrorOr<KBasicString<CharKind>> Construct(const CharKind* data); - template <typename CharKind = Char> - static const CharKind* FromBool(const CharKind* fmt, bool n); - template <typename CharKind = Char> - static const CharKind* Format(const CharKind* fmt, const CharKind* from); - template <typename CharKind = Char> - static bool Equals(const CharKind* lhs, const CharKind* rhs); -}; -} // namespace Kernel - -#include <NeKit/KString.inl> diff --git a/dev/kernel/NeKit/KString.inl b/dev/kernel/NeKit/KString.inl deleted file mode 100644 index 3a73e90f..00000000 --- a/dev/kernel/NeKit/KString.inl +++ /dev/null @@ -1,174 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/// @file KBasicString.inl -/// @brief Kernel String manipulation file. - -namespace Kernel { -template <typename CharKind> -inline void ort_string_append(CharKind* lhs, const CharKind* rhs, Int32 cur) { - SizeT sz_rhs = oe_string_len<CharKind>(rhs); - SizeT rhs_i = 0; - - for (; rhs_i < sz_rhs; ++rhs_i) { - lhs[rhs_i + cur] = rhs[rhs_i]; - } -} - -template <typename CharKind> -inline CharKind* KBasicString<CharKind>::Data() { - return this->fData; -} - -template <typename CharKind> -inline const CharKind* KBasicString<CharKind>::CData() const { - return const_cast<const CharKind*>(this->fData); -} - -template <typename CharKind> -inline SizeT KBasicString<CharKind>::Length() const { - return this->fDataSz; -} - -template <typename CharKind> -inline bool KBasicString<CharKind>::operator==(const KBasicString<CharKind>& rhs) const { - if (rhs.Length() != this->Length()) return false; - - for (Size index = 0; index < this->Length(); ++index) { - if (rhs.fData[index] != this->fData[index]) return false; - } - - return true; -} - -template <typename CharKind> -inline bool KBasicString<CharKind>::operator==(const CharKind* rhs) const { - if (oe_string_len<CharKind>(rhs) != this->Length()) return false; - - for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) { - if (rhs[index] != this->fData[index]) return false; - } - - return true; -} - -template <typename CharKind> -inline bool KBasicString<CharKind>::operator!=(const KBasicString<CharKind>& rhs) const { - if (rhs.Length() != this->Length()) return false; - - for (Size index = 0; index < rhs.Length(); ++index) { - if (rhs.fData[index] == this->fData[index]) return false; - } - - return true; -} - -template <typename CharKind> -inline bool KBasicString<CharKind>::operator!=(const CharKind* rhs) const { - if (oe_string_len<CharKind>(rhs) != this->Length()) return false; - - for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) { - if (rhs[index] == this->fData[index]) return false; - } - - return true; -} - -template <typename CharKind> -inline KBasicString<CharKind>& KBasicString<CharKind>::operator+=( - const KBasicString<CharKind>& rhs) { - if (oe_string_len<CharKind>(rhs.fData) > this->Length()) return *this; - - ort_string_append(this->fData, const_cast<CharKind*>(rhs.fData), this->fCur); - this->fCur += oe_string_len<CharKind>(const_cast<CharKind*>(rhs.fData)); - - return *this; -} - -template <typename CharKind> -inline KBasicString<CharKind>& KBasicString<CharKind>::operator+=(const CharKind* rhs) { - ort_string_append(this->fData, const_cast<CharKind*>(rhs), this->fCur); - this->fCur += oe_string_len<CharKind>(const_cast<CharKind*>(rhs)); - - return *this; -} - -template <typename CharKind> -inline ErrorOr<KBasicString<CharKind>> KStringBuilder::Construct(const CharKind* data) { - if (!data || *data == 0) return ErrorOr<KBasicString<CharKind>>(nullptr); - - KBasicString<CharKind>* view = new KBasicString<CharKind>(oe_string_len<CharKind>(data)); - (*view) += data; - - return ErrorOr<KBasicString<CharKind>>(*view); -} -template <typename CharKind> -inline const CharKind* KStringBuilder::FromBool(const CharKind* fmt, bool i) { - if (!fmt) return ("?"); - - const CharKind* boolean_expr = i ? "YES" : "NO"; - CharKind* ret = - (CharKind*) RTL_ALLOCA(oe_string_len<CharKind>(boolean_expr) + oe_string_len<CharKind>(fmt)); - - if (!ret) return ("?"); - - const auto fmt_len = oe_string_len<CharKind>(fmt); - const auto res_len = oe_string_len<CharKind>(boolean_expr); - - for (Size idx = 0; idx < fmt_len; ++idx) { - if (fmt[idx] == '%') { - SizeT result_cnt = idx; - - for (auto y_idx = idx; y_idx < res_len; ++y_idx) { - ret[result_cnt] = boolean_expr[y_idx]; - ++result_cnt; - } - - break; - } - - ret[idx] = fmt[idx]; - } - - return ret; -} -template <typename CharKind> -inline bool KStringBuilder::Equals(const CharKind* lhs, const CharKind* rhs) { - if (oe_string_len<CharKind>(rhs) != oe_string_len<CharKind>(lhs)) return false; - - for (Size index = 0; index < oe_string_len<CharKind>(rhs); ++index) { - if (rhs[index] != lhs[index]) return false; - } - - return true; -} -template <typename CharKind> -inline const CharKind* KStringBuilder::Format(const CharKind* fmt, const CharKind* fmt2) { - if (!fmt || !fmt2) return ("?"); - - CharKind* ret = (CharKind*) RTL_ALLOCA( - sizeof(char) * (oe_string_len<CharKind>(fmt2) + oe_string_len<CharKind>(fmt))); - - if (!ret) return ("?"); - - const auto len = oe_string_len<CharKind>(fmt); - - for (Size idx = 0; idx < len; ++idx) { - if (fmt[idx] == '%' && idx < oe_string_len<CharKind>(fmt) && fmt[idx] == 's') { - Size result_cnt = idx; - - for (Size y_idx = 0; y_idx < oe_string_len<CharKind>(fmt2); ++y_idx) { - ret[result_cnt] = fmt2[y_idx]; - ++result_cnt; - } - } - - ret[idx] = fmt[idx]; - } - - return ret; -} -} // namespace Kernel diff --git a/dev/kernel/NeKit/KernelPanic.h b/dev/kernel/NeKit/KernelPanic.h deleted file mode 100644 index f716e6de..00000000 --- a/dev/kernel/NeKit/KernelPanic.h +++ /dev/null @@ -1,69 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -void ke_runtime_check(bool expr, const Char* file, const Char* line); -} - -#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG) - -#ifdef TRY -#undef TRY -#endif - -#define TRY(X) \ - { \ - auto fn = X; \ - if ((fn()) == NO) { \ - MUST_PASS(NO); \ - } \ - } - -#ifdef __MUST_PASS -#undef __MUST_PASS -#endif - -#define __MUST_PASS(EXPR, FILE, LINE) Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE)) - -#ifdef __DEBUG__ -#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__) -#define assert(EXPR) MUST_PASS(EXPR) -#else -#define MUST_PASS(EXPR) (Kernel::Void)(EXPR) -#define assert(EXPR) (Kernel::Void)(EXPR) -#endif - -enum RUNTIME_CHECK { - RUNTIME_CHECK_FAILED = 1111, - RUNTIME_CHECK_POINTER, - RUNTIME_CHECK_EXPRESSION, - RUNTIME_CHECK_FILE, - RUNTIME_CHECK_IPC, - RUNTIME_CHECK_TLS, - RUNTIME_CHECK_HANDSHAKE, - RUNTIME_CHECK_ACPI, - RUNTIME_CHECK_INVALID_PRIVILEGE, - RUNTIME_CHECK_PROCESS, - RUNTIME_CHECK_BAD_BEHAVIOR, - RUNTIME_CHECK_BOOTSTRAP, - RUNTIME_CHECK_UNEXCPECTED, - RUNTIME_CHECK_FILESYSTEM, - RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, - RUNTIME_CHECK_PAGE, - RUNTIME_CHECK_INVALID, - RUNTIME_CHECK_COUNT, -}; - -typedef enum RUNTIME_CHECK RTL_RUNTIME_CHECK; - -namespace Kernel { -void ke_panic(const Int32& id, const Char* message = nullptr); -} // namespace Kernel diff --git a/dev/kernel/NeKit/Macros.h b/dev/kernel/NeKit/Macros.h deleted file mode 100644 index 5949b414..00000000 --- a/dev/kernel/NeKit/Macros.h +++ /dev/null @@ -1,151 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -/***********************************************************************************/ -/// @file NeKit/Macros.h -/// @brief Core Types and Macros. -/***********************************************************************************/ - -#ifndef KIB -#define KIB(X) (Kernel::UInt64)((X) / 1024) -#endif - -#ifndef kib_cast -#define kib_cast(X) (Kernel::UInt64)((X) *1024) -#endif - -#ifndef MIB -#define MIB(X) (Kernel::UInt64)((Kernel::UInt64) KIB(X) / 1024) -#endif - -#ifndef mib_cast -#define mib_cast(X) (Kernel::UInt64)((Kernel::UInt64) kib_cast(X) * 1024) -#endif - -#ifndef GIB -#define GIB(X) (Kernel::UInt64)((Kernel::UInt64) MIB(X) / 1024) -#endif - -#ifndef gib_cast -#define gib_cast(X) (Kernel::UInt64)((Kernel::UInt64) mib_cast(X) * 1024) -#endif - -#ifndef TIB -#define TIB(X) (Kernel::UInt64)((Kernel::UInt64) GIB(X) / 1024) -#endif - -#ifndef tib_cast -#define tib_cast(X) ((Kernel::UInt64) gib_cast(X) * 1024) -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ - (((sizeof(a) / sizeof(*(a))) / (static_cast<Kernel::Size>(!(sizeof(a) % sizeof(*(a))))))) -#endif - -#define DEPRECATED ATTRIBUTE(deprecated) - -#ifndef ALIGN -#define ALIGN(X) __attribute__((aligned(X))) -#endif // #ifndef ALIGN - -#ifndef ATTRIBUTE -#define ATTRIBUTE(...) __attribute__((__VA_ARGS__)) -#endif // #ifndef ATTRIBUTE - -#ifndef __NE_VER__ -#define __NE_VER__ (2024) -#endif // !__NE_VER__ - -#ifndef EXTERN -#define EXTERN extern -#endif - -#ifndef EXTERN_C -#define EXTERN_C extern "C" -#endif - -#ifndef MAKE_ENUM -#define MAKE_ENUM(NAME) enum NAME { -#endif - -#ifndef END_ENUM -#define END_ENUM() \ - } \ - ; -#endif - -#ifndef MAKE_STRING_ENUM -#define MAKE_STRING_ENUM(NAME) namespace NAME { -#endif - -#ifndef ENUM_STRING -#define ENUM_STRING(NAME, VAL) inline constexpr const char* e##NAME = VAL -#endif - -#ifndef END_STRING_ENUM -#define END_STRING_ENUM() } -#endif - -#ifndef RTL_ALLOCA -#define RTL_ALLOCA(sz) __builtin_alloca(sz) -#endif // #ifndef RTL_ALLOCA - -#ifndef CANT_REACH -#define CANT_REACH() __builtin_unreachable() -#endif - -#define kInvalidAddress 0xFBFBFBFBFBFBFBFB -#define kBadAddress 0x0000000000000000 -#define kMaxAddr 0xFFFFFFFFFFFFFFFF -#define kPathLen 0x100 - -#define PACKED ATTRIBUTE(packed) -#define NO_EXEC ATTRIBUTE(noexec) - -#define EXTERN extern -#define STATIC static - -#define CONST const - -#define STRINGIFY(X) #X -#define NE_UNUSED(X) ((Kernel::Void) X) - -#ifndef RGB -#define RGB(R, G, B) ((Kernel::UInt32)((0xFF << 24) | ((R) << 16) | ((G) << 8) | (B))) -#endif // !RGB - -#ifdef __NE_AMD64__ -#define DBG_TRAP() asm volatile("int $3") -#else -#define DBG_TRAP() ((Kernel::Void) 0) -#endif - -#define LIKELY(ARG) ((ARG) ? MUST_PASS(NO) : ((Kernel::Void) 0)) -#define UNLIKELY(ARG) LIKELY(!(ARG)) - -#define RTL_ENDIAN(address, value) \ - (((reinterpret_cast<Kernel::Char*>(address)[0]) == (value)) ? (Kernel::Endian::kEndianBig) \ - : (Kernel::Endian::kEndianLittle)) - -#define Yes true -#define No false - -#define YES true -#define NO false - -#define TRUE true -#define FALSE false - -#define BOOL Kernel::Boolean - -#ifdef RTL_INIT_OBJECT -#undef RTL_INIT_OBJECT -#endif // ifdef RTL_INIT_OBJECT - -#define RTL_INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/dev/kernel/NeKit/MutableArray.h b/dev/kernel/NeKit/MutableArray.h deleted file mode 100644 index e1138b3b..00000000 --- a/dev/kernel/NeKit/MutableArray.h +++ /dev/null @@ -1,203 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Array.h> -#include <NeKit/Defines.h> - -#define RTL_TRY_FIND_NODE(NAME, NODE) \ - auto* NAME = NODE; \ - while (NAME) { \ - if (NAME->fIndex == Index) return NAME->fVal; \ - NAME = NAME->fNext; \ - } - -#define RTL_TRY_FIND_NODE2(NAME, NODE) \ - auto* NAME = NODE; \ - while (NAME) { \ - if (NAME->fIndex == Index) return Ref<T>{NAME->fVal}; \ - NAME = NAME->fNext; \ - } - -#define RTL_TRY_REMOVE_NODE(NODE) \ - if (NODE && NODE->fIndex == Index) { \ - NODE->fUsed = false; \ - NODE->fIndex = 0; \ - \ - return true; \ - } - -// FIXME: this is a shitty algorithm, because it is memory heavy. -// Remove and occurences of that, and remove that class. -namespace Kernel { -template <typename T> -class MutableArray; - -template <typename T, T _PlaceHolderValue> -class NullableMutableArray; - -template <typename T> -class MutableLinkedList { - public: - T fVal; - SizeT fIndex{0}; - Boolean fUsed{false}; - - MutableLinkedList* fPrev{nullptr}; - MutableLinkedList* fNext{nullptr}; -}; - -template <typename T, T _PlaceHolderValue> -class NullableMutableArray { - public: - // explicit this. - explicit NullableMutableArray() : fFirstNode(new MutableLinkedList<T>()) {} - - /* - * We free all the nodes allocated by the array - * and store the next one inside "NextIt" - */ - - virtual ~NullableMutableArray() { - auto* It = fFirstNode; - MutableLinkedList<T>* NextIt = nullptr; - - while (It) { - NextIt = It->fNext; - delete It; - - It = NextIt; - } - } - - NullableMutableArray& operator=(const NullableMutableArray&) = default; - NullableMutableArray(const NullableMutableArray&) = default; - - operator bool() { return Count() > 1; } - - public: - T operator[](SizeT Index) const { - RTL_TRY_FIND_NODE(first, fFirstNode); - RTL_TRY_FIND_NODE(last, fLastNode); - - return _PlaceHolderValue; - } - - SizeT Count() const { return fNodeCount; } - - public: - Boolean Remove(SizeT Index) { - RTL_TRY_REMOVE_NODE(fFirstNode); - RTL_TRY_REMOVE_NODE(fLastNode); - - return false; - } - - Boolean Add(const T val) { - auto* iterationNode = fFirstNode; - MUST_PASS(iterationNode); - - while (iterationNode) { - if (!iterationNode->fUsed) { - iterationNode->fVal = val; - iterationNode->fIndex = 0; - - iterationNode->fUsed = true; - - ++fNodeCount; - - return true; - } - - iterationNode = iterationNode->fNext; - } - - return false; - } - - private: - /* Avoid useless lookups */ - MutableLinkedList<T>* fLastNode{nullptr}; - MutableLinkedList<T>* fFirstNode{nullptr}; - - /* Number of nodes inside of this dynamic array. */ - Kernel::SizeT fNodeCount{0}; - - private: - // don't remove that - friend MutableArray<T>; -}; - -template <typename T> -class MutableArray : public NullableMutableArray<voidPtr, nullptr> { - public: - // explicit this. - explicit MutableArray() = default; - virtual ~MutableArray() = default; - - NE_COPY_DEFAULT(MutableArray) - - public: - Boolean Add(const T val) { - auto* iterationNode = fFirstNode; - - if (!iterationNode) { - fFirstNode = new MutableLinkedList<T>(); - iterationNode = fFirstNode; - } - - MUST_PASS(iterationNode); - - while (iterationNode) { - if (!iterationNode->fUsed) { - iterationNode->fVal = val; - iterationNode->fIndex = 0; - - iterationNode->fUsed = true; - - ++fNodeCount; - - return true; - } - - iterationNode = iterationNode->fNext; - } - - return false; - } - - public: - Ref<T> operator[](SizeT Index) const { - RTL_TRY_FIND_NODE2(first, fFirstNode); - RTL_TRY_FIND_NODE2(last, fLastNode); - - return {}; - } - - SizeT Count() const { return fNodeCount; } - - bool Contains(T& value) noexcept { - MutableLinkedList<T>* first = fFirstNode; - - while (first) { - if (first->fVal == value && first->fUsed) return true; - - first = first->fNext; - } - - return false; - } - - private: - /* Avoid useless lookups */ - MutableLinkedList<T>* fLastNode{nullptr}; - MutableLinkedList<T>* fFirstNode{nullptr}; - - /* Number of nodes inside of this dynamic array. */ - Kernel::SizeT fNodeCount{0}; -}; -} // namespace Kernel diff --git a/dev/kernel/NeKit/NeKit.h b/dev/kernel/NeKit/NeKit.h deleted file mode 100644 index 4b1e64ca..00000000 --- a/dev/kernel/NeKit/NeKit.h +++ /dev/null @@ -1,20 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Array.h> -#include <NeKit/ArrayList.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/Json.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/MutableArray.h> -#include <NeKit/New.h> -#include <NeKit/OwnPtr.h> -#include <NeKit/Ref.h> -#include <NeKit/Stream.h> -#include <NeKit/Utils.h> diff --git a/dev/kernel/NeKit/New.h b/dev/kernel/NeKit/New.h deleted file mode 100644 index 36830129..00000000 --- a/dev/kernel/NeKit/New.h +++ /dev/null @@ -1,20 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/HeapMgr.h> - -/// @note compatible with tk too. -typedef __SIZE_TYPE__ size_t; - -void* operator new(size_t); -void* operator new[](size_t); - -void operator delete(void*) noexcept; -void operator delete(void*, unsigned long); -void operator delete[](void*) noexcept; diff --git a/dev/kernel/NeKit/OwnPtr.h b/dev/kernel/NeKit/OwnPtr.h deleted file mode 100644 index c8ceb1a2..00000000 --- a/dev/kernel/NeKit/OwnPtr.h +++ /dev/null @@ -1,67 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Ref.h> - -namespace Kernel { -template <typename T> -class OwnPtr; - -template <typename T> -class NonNullRefPtr; - -template <typename T> -class OwnPtr final { - public: - OwnPtr() {} - ~OwnPtr() { this->Delete(); } - - OwnPtr& operator=(const OwnPtr&) = default; - OwnPtr(const OwnPtr&) = default; - - public: - template <typename... Args> - bool New(Args&&... arg) { - if (fCls) { - return false; - } - - fCls = new T(arg...); - return fCls; - } - - void Delete() { - if (fCls) delete fCls; - - fCls = nullptr; - } - - T* operator->() const { return fCls; } - - T* Raw() { return fCls; } - - Ref<T> AsRef() { return Ref<T>(fCls); } - - operator bool() { return fCls; } - bool operator!() { return !fCls; } - - private: - T* fCls; -}; - -template <typename T, typename... Args> -inline OwnPtr<T> mm_make_own_ptr(Args... args) { - OwnPtr<T> ret; - ret.template New<Args...>(forward(args)...); - - return ret; -} -} // namespace Kernel diff --git a/dev/kernel/NeKit/PageMgr.h b/dev/kernel/NeKit/PageMgr.h deleted file mode 100644 index 6cdd5a5c..00000000 --- a/dev/kernel/NeKit/PageMgr.h +++ /dev/null @@ -1,76 +0,0 @@ -// a way to create and find our pages. -// I'm thinking about a separate way of getting a paged area. - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/Ref.h> - -namespace Kernel { -class PageMgr; - -class PTEWrapper final { - public: - explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false, - UIntPtr Address = 0); - - ~PTEWrapper(); - - PTEWrapper& operator=(const PTEWrapper&) = default; - PTEWrapper(const PTEWrapper&) = default; - - public: - UIntPtr VirtualAddress(); - - Void NoExecute(const bool enable = false); - Bool NoExecute(); - - operator bool() { return fVirtAddr; } - - bool Reclaim(); - bool Shareable(); - bool Present(); - bool Access(); - - private: - Boolean fRw; - Boolean fUser; - Boolean fExecDisable; - UIntPtr fVirtAddr; - Boolean fCache; - Boolean fShareable; - Boolean fWt; - Boolean fPresent; - Boolean fAccessed; - - private: - friend class PageMgr; - friend class Pmm; -}; - -struct PageMgr final { - public: - PageMgr() = default; - ~PageMgr() = default; - - PageMgr& operator=(const PageMgr&) = default; - PageMgr(const PageMgr&) = default; - - public: - PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad); - bool Free(Ref<PTEWrapper>& wrapper); - - private: - void FlushTLB(); - - private: - friend PTEWrapper; - friend class Pmm; -}; -} // namespace Kernel diff --git a/dev/kernel/NeKit/Pair.h b/dev/kernel/NeKit/Pair.h deleted file mode 100644 index c8914ec6..00000000 --- a/dev/kernel/NeKit/Pair.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Defines.h> -#include <NeKit/ErrorOr.h> - -namespace Kernel { -template <typename T1, typename T2> -class Pair; - -class PairBuilder; - -template <typename T1, typename T2> -class Pair final { - T1 fFirst{nullptr}; - T2 fSecond{nullptr}; - - friend PairBuilder; - - public: - explicit Pair() = default; - ~Pair() = default; - - NE_COPY_DEFAULT(Pair) - - T1& First() { return fFirst; } - T2& Second() { return fSecond; } - - const T1& First() const { return *fFirst; } - const T2& Second() const { return *fSecond; } - - private: - Pair(T1 first, T2 second) : fFirst(first), fSecond(second) {} -}; - -class PairBuilder final { - template <typename T1, typename T2> - STATIC Pair<T1, T2> Construct(T1 first, T2 second) { - return Pair(first, second); - } -}; - -template <typename T1, typename T2> -using PairOr = ErrorOr<Pair<T1, T2>>; -} // namespace Kernel diff --git a/dev/kernel/NeKit/Pmm.h b/dev/kernel/NeKit/Pmm.h deleted file mode 100644 index 8c117a67..00000000 --- a/dev/kernel/NeKit/Pmm.h +++ /dev/null @@ -1,39 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/PageMgr.h> -#include <NeKit/Ref.h> - -namespace Kernel { -class Pmm; -class PTEWrapper; - -class Pmm final { - public: - explicit Pmm(); - ~Pmm(); - - Pmm& operator=(const Pmm&) = delete; - Pmm(const Pmm&) = default; - - Ref<PTEWrapper> RequestPage(Boolean user = false, Boolean readWrite = false); - Boolean FreePage(Ref<PTEWrapper> refPage); - - Boolean ToggleRw(Ref<PTEWrapper> refPage, Boolean enable = true); - Boolean TogglePresent(Ref<PTEWrapper> refPage, Boolean enable = true); - Boolean ToggleUser(Ref<PTEWrapper> refPage, Boolean enable = true); - Boolean ToggleShare(Ref<PTEWrapper> refPage, Boolean enable = true); - - /// @brief Get the page manager of this. - Ref<PageMgr>& Leak() { return fPageMgr; } - - private: - Ref<PageMgr> fPageMgr; -}; -} // namespace Kernel diff --git a/dev/kernel/NeKit/Ref.h b/dev/kernel/NeKit/Ref.h deleted file mode 100644 index dac701e0..00000000 --- a/dev/kernel/NeKit/Ref.h +++ /dev/null @@ -1,77 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef _NEKIT_REF_H_ -#define _NEKIT_REF_H_ - -#include <CompilerKit/CompilerKit.h> -#include <KernelKit/HeapMgr.h> -#include <NeKit/Defines.h> -#include <NeKit/KernelPanic.h> - -namespace Kernel { -/// =========================================================== /// -/// @brief Reference wrapper class. /// -/// =========================================================== /// -template <typename T> -class Ref final { - public: - explicit Ref() = default; - ~Ref() = default; - - public: - Ref(T* cls) : fClass(*cls) {} - Ref(T cls) : fClass(cls) {} - - Ref& operator=(T ref) { - fClass = ref; - return *this; - } - - NE_COPY_DEFAULT(Ref) - - public: - T operator->() const { return fClass; } - - T& Leak() noexcept { return fClass; } - - T& TryLeak() noexcept { return fClass; } - - T operator*() { return fClass; } - - operator bool() noexcept { return true; } - - private: - T fClass; -}; - -template <typename T> -class NonNullRef final { - public: - NonNullRef() = delete; - NonNullRef(nullPtr) = delete; - - NonNullRef(T* ref) : fRef(ref) { MUST_PASS(ref); } - NonNullRef(Ref<T> ref) : fRef(ref) { MUST_PASS(ref); } - - Ref<T>& operator->() { - MUST_PASS(fRef); - return fRef; - } - - NonNullRef& operator=(const NonNullRef<T>& ref) = delete; - NonNullRef(const NonNullRef<T>& ref) = default; - - private: - Ref<T> fRef{}; -}; - -using RefAny = Ref<Any>; -using NonNullRefAny = NonNullRef<Any>; -} // namespace Kernel - -#endif // ifndef _NEKIT_REF_H_ diff --git a/dev/kernel/NeKit/Stream.h b/dev/kernel/NeKit/Stream.h deleted file mode 100644 index 1a53e7f0..00000000 --- a/dev/kernel/NeKit/Stream.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/Ref.h> - -namespace Kernel { -template <typename StreamTrait, typename Kind> -class Stream final { - public: - explicit Stream(Ref<Stream> ref) : fStream(ref) {} - - ~Stream() = default; - - Stream& operator=(const Stream&) = default; - Stream(const Stream&) = default; - - template <typename Data> - friend Stream<StreamTrait, Kind>& operator>>(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf) { - Ks.fKind = Ks.fStream->In(Buf); - return *Ks; - } - - template <typename Data> - friend Stream<StreamTrait, Kind>& operator<<(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf) { - Ks.fKind = Buf; - Ks.fStream->Out(Buf.Leak()); - return *Ks; - } - - Ref<StreamTrait>& AsStreamTrait() { return fStream; } - - Ref<Kind>& AsType() { return fKind; } - - private: - Ref<StreamTrait> fStream; - Ref<Kind> fKind; -}; -} // namespace Kernel diff --git a/dev/kernel/NeKit/TOML.h b/dev/kernel/NeKit/TOML.h deleted file mode 100644 index dee273ad..00000000 --- a/dev/kernel/NeKit/TOML.h +++ /dev/null @@ -1,15 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -namespace Kernel { -class TOMLObject final { - public: - explicit TOMLObject() = delete; - ~TOMLObject() = default; -}; -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/NeKit/Utils.h b/dev/kernel/NeKit/Utils.h deleted file mode 100644 index caabd2af..00000000 --- a/dev/kernel/NeKit/Utils.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -namespace Kernel { -/// =========================================================== /// -/// @brief ASCII API -/// =========================================================== /// - -Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len); -Int rt_move_memory(const voidPtr src, voidPtr dst, Size len); -voidPtr rt_set_memory(voidPtr dst, UInt32 val, Size len); -void rt_zero_memory(voidPtr pointer, Size len); -Int rt_string_cmp(const Char* src, const Char* cmp, Size len); -const Char* rt_alloc_string(const Char* text); -Size rt_string_len(const Char* str); -Size rt_string_len(const Char* str, SizeT _len); -Boolean rt_to_string(Char* str_out, UInt64 base, Int32 limit); -Boolean rt_is_newln(Int chr); -Boolean rt_is_space(Int chr); -Int32 rt_is_alnum(Int character); -Int rt_to_uppercase(Int c); -Int rt_to_lower(Int c); -voidPtr rt_string_in_string(const Char* in, const Char* needle); -char* rt_string_has_char(Char* str, Char chr); - -/// =========================================================== /// -/// @brief Safe memory functions API -/// =========================================================== /// - -Int rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size); -voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size); - -/// =========================================================== /// -/// @brief UNICODE API -/// =========================================================== /// - -Int urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size len); -Void urt_set_memory(const voidPtr src, UInt32 dst, Size len); -Int urt_copy_memory(const voidPtr src, voidPtr dst, Size len); -Size urt_string_len(const Utf8Char* str); - -/// =========================================================== /// -/// @brief OpenEncoding API -/// =========================================================== /// - -template <typename CharType = Char> -inline SizeT oe_string_len(const CharType* str) { - if (!str) return 0; - - SizeT len{0}; - - while (str[len] != 0) ++len; - return len; -} -} // namespace Kernel diff --git a/dev/kernel/NeKit/Variant.h b/dev/kernel/NeKit/Variant.h deleted file mode 100644 index 7bcd0dff..00000000 --- a/dev/kernel/NeKit/Variant.h +++ /dev/null @@ -1,71 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> -#include <NeKit/Json.h> -#include <NeKit/TOML.h> -#include <NeKit/KString.h> -#include <SwapKit/DiskSwap.h> - -namespace Kernel { -class Variant final { - public: - enum class VariantKind { - kInvalid = 0, - kString = 200, - kBlob, - kNull, - kJson, - kTOML, - kSwap, - }; - - public: - explicit Variant() = delete; - - public: - NE_COPY_DEFAULT(Variant) - - ~Variant() = default; - - public: - template <typename CharKind> - explicit Variant(KBasicString<CharKind>* stringView) - : fPtr((VoidPtr) stringView), fKind(VariantKind::kString) {} - - explicit Variant(JsonObject<>* json) : fPtr((VoidPtr) json), fKind(VariantKind::kJson) {} - - explicit Variant(TOMLObject* toml) : fPtr((VoidPtr) toml), fKind(VariantKind::kTOML) {} - - explicit Variant(nullPtr ptr) : fPtr(ptr), fKind(VariantKind::kNull) {} - - explicit Variant(SWAP_DISK_HEADER* ptr) : fPtr(ptr), fKind(VariantKind::kSwap) {} - - explicit Variant(VoidPtr ptr) : fPtr(ptr), fKind(VariantKind::kBlob) {} - - public: - const Char* ToString(); - - /// ======================================================================== - /// @brief Returns the underlying pointer. - /// @return the underlying pointer. - /// ======================================================================== - VoidPtr Leak(); - - template <typename T> - T* As() noexcept { - return reinterpret_cast<T*>(fPtr); - } - - VariantKind& Kind(); - - private: - VoidPtr fPtr{nullptr}; - VariantKind fKind{VariantKind::kNull}; -}; -} // namespace Kernel diff --git a/dev/kernel/NetworkKit/IP.h b/dev/kernel/NetworkKit/IP.h deleted file mode 100644 index b19d132f..00000000 --- a/dev/kernel/NetworkKit/IP.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DebugOutput.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <NeKit/Ref.h> - -namespace Kernel { -class RawIPAddress6; -class RawIPAddress; -class IPFactory; - -class RawIPAddress final { - private: - explicit RawIPAddress(UInt8 bytes[4]); - ~RawIPAddress() = default; - - RawIPAddress& operator=(const RawIPAddress&) = delete; - RawIPAddress(const RawIPAddress&) = default; - - public: - UInt8* Address(); - - UInt8& operator[](const Size& index); - - BOOL operator==(const RawIPAddress& ipv6); - BOOL operator!=(const RawIPAddress& ipv6); - - private: - UInt8 fAddr[4]; - - friend IPFactory; // it is the one creating these addresses, thus this - // is why the constructors are private. -}; - -/** - * @brief IPv6 address. - */ -class RawIPAddress6 final { - private: - explicit RawIPAddress6(UInt8 Bytes[16]); - ~RawIPAddress6() = default; - - RawIPAddress6& operator=(const RawIPAddress6&) = delete; - RawIPAddress6(const RawIPAddress6&) = default; - - public: - UInt8* Address() { return fAddr; } - - UInt8& operator[](const Size& index); - - bool operator==(const RawIPAddress6& ipv6); - bool operator!=(const RawIPAddress6& ipv6); - - private: - UInt8 fAddr[16]; - - friend IPFactory; -}; - -/** - * @brief IP Creation helpers - */ -class IPFactory final { - public: - static ErrorOr<KString> ToKString(Ref<RawIPAddress6>& ipv6); - static ErrorOr<KString> ToKString(Ref<RawIPAddress>& ipv4); - static bool IpCheckVersion4(const Char* ip); -}; -} // namespace Kernel diff --git a/dev/kernel/NetworkKit/IPC.h b/dev/kernel/NetworkKit/IPC.h deleted file mode 100644 index c08a9457..00000000 --- a/dev/kernel/NetworkKit/IPC.h +++ /dev/null @@ -1,90 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.. - - File: IPC.h. - Purpose: IPC protocol. - -======================================== */ - -#ifndef INC_IPC_H -#define INC_IPC_H - -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <hint/CompilerHint.h> - -/// @file IPC.h -/// @brief IPC comm. protocol. - -/// IA separator. -#define kIPCRemoteSeparator ":" - -/// Interchange address, consists of ProcessID:TEAM. -#define kIPCRemoteInvalid "00:00" - -#define kIPCHeaderMagic (0x4950434) - -namespace Kernel { -struct IPC_ADDR; -struct IPC_MSG; - -/// @brief 128-bit IPC address. -struct PACKED IPC_ADDR final { - UInt64 UserProcessID; - UInt64 UserProcessTeam; - - //////////////////////////////////// - // some operators. - //////////////////////////////////// - - BOOL operator==(const IPC_ADDR& addr) noexcept; - BOOL operator==(IPC_ADDR& addr) noexcept; - BOOL operator!=(const IPC_ADDR& addr) noexcept; - BOOL operator!=(IPC_ADDR& addr) noexcept; -}; - -typedef struct IPC_ADDR IPC_ADDR; - -enum { - kIPCLittleEndian = 0, - kIPCBigEndian = 1, - kIPCMixedEndian = 2, -}; - -constexpr inline auto kIPCMsgSize = 6094U; - -enum { - kIPCLockInvalid = 0, - kIPCLockFree = 1, - kIPCLockUsed = 2, -}; - -/// @brief IPC connection header, message cannot be greater than 6K. -typedef struct IPC_MSG final { - UInt32 IpcHeaderMagic; // cRemoteHeaderMagic - UInt8 IpcEndianess; // 0 : LE, 1 : BE - SizeT IpcPacketSize; - IPC_ADDR IpcFrom; - IPC_ADDR IpcTo; - UInt32 IpcCRC32; - UInt32 IpcMsg; - UInt32 IpcMsgSz; - UInt8 IpcData[kIPCMsgSize]; - UInt32 IpcLock; - /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever. - static Bool Pass(IPC_MSG* self, IPC_MSG* target) noexcept; -} PACKED ALIGN(8) IPC_MSG; - -/// @brief Sanitize packet function -/// @retval true packet is correct. -/// @retval false packet is incorrect and process has crashed. -BOOL ipc_sanitize_packet(_Input IPC_MSG* pckt_in); - -/// @brief Construct packet function -/// @retval true packet is correct. -/// @retval false packet is incorrect and process has crashed. -BOOL ipc_construct_packet(_Output _Input IPC_MSG** pckt_in); -} // namespace Kernel - -#endif // INC_IPC_H diff --git a/dev/kernel/NetworkKit/LTE.h b/dev/kernel/NetworkKit/LTE.h deleted file mode 100644 index c29f1687..00000000 --- a/dev/kernel/NetworkKit/LTE.h +++ /dev/null @@ -1,16 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.. - - File: LTE.h. - Purpose: LTE protocol classes. - -======================================== */ - -#ifndef _INC_NETWORK_LTE_H_ -#define _INC_NETWORK_LTE_H_ - -#include <NeKit/Defines.h> -#include <NeKit/KString.h> - -#endif // ifndef _INC_NETWORK_LTE_H_ diff --git a/dev/kernel/NetworkKit/MAC.h b/dev/kernel/NetworkKit/MAC.h deleted file mode 100644 index 382eca77..00000000 --- a/dev/kernel/NetworkKit/MAC.h +++ /dev/null @@ -1,34 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Array.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> - -#define kMACAddrLen (32U) - -namespace Kernel { -class MacAddressGetter; - -/// \brief This retrieves the MAC address of the device. -/// \note Listens for the current NIC. -class MacAddressGetter final { - public: - MacAddressGetter() = default; - ~MacAddressGetter() = default; - - NE_COPY_DEFAULT(MacAddressGetter) - - public: - Array<UInt8, kMACAddrLen>& AsBytes(); - - private: - Array<UInt8, kMACAddrLen> fMacAddress; -}; - -} // namespace Kernel diff --git a/dev/kernel/NetworkKit/NetworkDevice.h b/dev/kernel/NetworkKit/NetworkDevice.h deleted file mode 100644 index 3afa8484..00000000 --- a/dev/kernel/NetworkKit/NetworkDevice.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __INC_NETWORK_DEVICE_H__ -#define __INC_NETWORK_DEVICE_H__ - -#include <KernelKit/DeviceMgr.h> -#include <NetworkKit/IP.h> - -/// @note Can either work with: Ethernet, GPRS, WiFi - -namespace Kernel { -struct NetworkDeviceCommand; -class NetworkDevice; - -/** - * \brief Network device interface, establishes a connection to the NIC. - */ -class NetworkDevice final NE_DEVICE<NetworkDeviceCommand> { - public: - NetworkDevice(void (*out)(DeviceInterface<NetworkDeviceCommand>*, NetworkDeviceCommand), - void (*in)(DeviceInterface<NetworkDeviceCommand>*, NetworkDeviceCommand), - void (*cleanup)(void) = nullptr); - - ~NetworkDevice() override; - - public: - NetworkDevice& operator=(const NetworkDevice&) = default; - NetworkDevice(const NetworkDevice&) = default; - - public: - const Char* Name() const override; - Boolean Name(const Char* newStr); - - private: - Void (*fCleanup)(void); -}; - -struct NetworkDeviceCommand final { - UInt32 CommandName; - UInt32 CommandType; - UInt32 CommandFlags; - VoidPtr CommandBuffer; - SizeT CommandSizeBuffer; -}; - -/// @brief TCP device. -using TCPNetworkDevice = NetworkDevice; - -/// @brief UDP device. -using UDPNetworkDevice = NetworkDevice; - -/// @brief PPP device. -using PPPNetworkDevice = NetworkDevice; - -/// @brief IPC device. -using IPCNetworkDevice = NetworkDevice; - -/// @brief GRPS device. -using GPRSNetworkDevice = NetworkDevice; - -/// @brief GSM device. -using GSMNetworkDevice = NetworkDevice; - -/// @brief Bluetooth device. -using BTNetworkDevice = NetworkDevice; - -/// @brief Printer device. -using PrinterNetworkDevice = NetworkDevice; - -/// @brief Debug device. -using DBGNetworkDevice = NetworkDevice; - -/// @brief LTE device. -using LTENetworkDevice = NetworkDevice; -} // namespace Kernel - -#include <NetworkKit/NetworkDevice.inl> - -#endif // !__INC_NETWORK_DEVICE_H__ diff --git a/dev/kernel/NetworkKit/NetworkDevice.inl b/dev/kernel/NetworkKit/NetworkDevice.inl deleted file mode 100644 index a86d7e56..00000000 --- a/dev/kernel/NetworkKit/NetworkDevice.inl +++ /dev/null @@ -1,32 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/*** - Dtor and ctors. -*/ - -#ifndef __INC_NETWORK_DEVICE_H__ -#include <NetworkKit/NetworkDevice.h> -#endif // __INC_NETWORK_DEVICE_H__ - -namespace Kernel { -inline NetworkDevice::NetworkDevice(void (*out)(DeviceInterface<NetworkDeviceCommand>*, - NetworkDeviceCommand), - void (*in)(DeviceInterface<NetworkDeviceCommand>*, - NetworkDeviceCommand), - void (*on_cleanup)(void)) - : DeviceInterface<NetworkDeviceCommand>(out, in), fCleanup(on_cleanup) { - kout << "NetworkDevice initialized.\r"; - - MUST_PASS(out && in && on_cleanup); -} - -inline NetworkDevice::~NetworkDevice() { - kout << "NetworkDevice cleanup.\r"; - - if (fCleanup) fCleanup(); -} -} // namespace Kernel diff --git a/dev/kernel/SignalKit/Signals.h b/dev/kernel/SignalKit/Signals.h deleted file mode 100644 index b4e72fc4..00000000 --- a/dev/kernel/SignalKit/Signals.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <NeKit/Defines.h> - -#define SIGKILL 1 /* kill */ -#define SIGPAUS 2 /* pause */ -#define SIGEXEC 3 /* execute */ -#define SIGTRAP 4 /* trap */ -#define SIGABRT 5 /* abort */ -#define SIGCONT 6 /* continue */ -#define SIGSEG 7 /* process fault */ -#define SIGBREK 8 -#define SIGATCH 9 -#define SIGDTCH 10 - -/// @author Amlal El Mahrouss -/// @brief Signal Generation API. - -namespace Kernel { -typedef SizeT rt_signal_kind; - -/// @brief Standard signal seed for general purpose usage. -inline constexpr auto kUserSignalSeed = 0x0895034fUL; - -/// @brief Special signal seed for kernel usage. -inline constexpr auto kKernelSignalSeed = 0x0895034f9fUL; - -/// @brief Generate signal from **Sig** -template <rt_signal_kind Sig, SizeT Seed = kUserSignalSeed> -inline rt_signal_kind sig_generate_unique() { - static_assert(Sig > 0, "Signal is zero (invalid)"); - return Sig ^ Seed; -} - -/// @brief Checks if the signal matches the seed (user_seed or kernel_seed) -template <SizeT Seed> -inline BOOL sig_matches_seed(rt_signal_kind sig) { - return (sig & 0xFF000000) == (Seed & 0xFF000000); -} - -/// @brief Validate signal from **sig** -inline BOOL sig_validate_unique(rt_signal_kind sig) { - return sig > 0; -} -} // namespace Kernel diff --git a/dev/kernel/StorageKit/AHCI.h b/dev/kernel/StorageKit/AHCI.h deleted file mode 100644 index 82bd9747..00000000 --- a/dev/kernel/StorageKit/AHCI.h +++ /dev/null @@ -1,49 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/DriveMgr.h> -#include <NeKit/OwnPtr.h> - -namespace Kernel { -/// @brief AHCIDeviceInterface class -/// @details This class is used to send and receive data from the AHCI device. -/// @note The class is derived from the DeviceInterface class. -class AHCIDeviceInterface NE_DEVICE<IMountpoint*> { - public: - explicit AHCIDeviceInterface(void (*out)(DeviceInterface* self, IMountpoint* out), - void (*in)(DeviceInterface* self, IMountpoint* in)); - - virtual ~AHCIDeviceInterface() override; - - public: - AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default; - AHCIDeviceInterface(const AHCIDeviceInterface&) = default; - - const Char* Name() const override; - - const UInt16& GetPortsImplemented(); - - Void SetPortsImplemented(const UInt16& pi); - - const UInt32& GetIndex(); - - Void SetIndex(const UInt32& drv); - - public: - AHCIDeviceInterface& operator<<(IMountpoint* Data) override; - AHCIDeviceInterface& operator>>(IMountpoint* Data) override; - - private: - UInt16 fPortsImplemented{0U}; - UInt32 fDriveIndex{0U}; -}; - -UInt16 sk_init_ahci_device(BOOL atapi); -ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(UInt32 drv_index); -} // namespace Kernel diff --git a/dev/kernel/StorageKit/ATA.h b/dev/kernel/StorageKit/ATA.h deleted file mode 100644 index f92e09d3..00000000 --- a/dev/kernel/StorageKit/ATA.h +++ /dev/null @@ -1,56 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/DriveMgr.h> -#include <NeKit/OwnPtr.h> -#include <NeKit/Utils.h> - -namespace Kernel { -/// @brief ATA device interface class. -class ATADeviceInterface : public DeviceInterface<IMountpoint*> { - public: - explicit ATADeviceInterface(void (*Out)(DeviceInterface*, IMountpoint* outpacket), - void (*In)(DeviceInterface*, IMountpoint* inpacket)); - - virtual ~ATADeviceInterface(); - - public: - ATADeviceInterface& operator<<(IMountpoint* Data) override; - ATADeviceInterface& operator>>(IMountpoint* Data) override; - - public: - ATADeviceInterface& operator=(const ATADeviceInterface&) = default; - ATADeviceInterface(const ATADeviceInterface&) = default; - - const Char* Name() const override; - - const UInt16& GetIO(); - Void SetIO(const UInt16& io); - - const UInt16& GetMaster(); - Void SetMaster(const UInt16& master); - - const UInt32& GetIndex(); - Void SetIndex(const UInt32& drv); - - private: - UInt32 fDriveIndex{0U}; - UInt16 fIO, fMaster{0U}; -}; - -/// @brief Initialize an PIO device (StorageKit function) -/// @param is_master is the current PIO master? -/// @return [io:master] for PIO device. -BOOL sk_init_ata_device(BOOL is_master, UInt16& io, UInt8& master); - -/// @brief Acquires a new PIO device with drv_index in mind. -/// @param drv_index The drive index to assign. -/// @return A wrapped device interface if successful, or error code. -ErrorOr<ATADeviceInterface> sk_acquire_ata_device(Int32 drv_index); -} // namespace Kernel diff --git a/dev/kernel/StorageKit/NVME.h b/dev/kernel/StorageKit/NVME.h deleted file mode 100644 index d1c036ab..00000000 --- a/dev/kernel/StorageKit/NVME.h +++ /dev/null @@ -1,32 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/DriveMgr.h> - -namespace Kernel { -class NVMEDeviceInterface final NE_DEVICE<IMountpoint*> { - public: - explicit NVMEDeviceInterface(Void (*out)(DeviceInterface*, IMountpoint* out_packet), - Void (*in)(DeviceInterface*, IMountpoint* in_packet), - Void (*cleanup)(Void)); - - ~NVMEDeviceInterface() override; - - public: - NE_COPY_DEFAULT(NVMEDeviceInterface) - - const Char* Name() const override; - - public: - OwnPtr<IMountpoint*> operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz); - - private: - Void (*fCleanup)(Void) = {nullptr}; -}; -} // namespace Kernel diff --git a/dev/kernel/StorageKit/PRDT.h b/dev/kernel/StorageKit/PRDT.h deleted file mode 100644 index 44eb11be..00000000 --- a/dev/kernel/StorageKit/PRDT.h +++ /dev/null @@ -1,33 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <KernelKit/PCI/DMA.h> -#include <KernelKit/PCI/Iterator.h> -#include <NeKit/Ref.h> - -#define kPrdtTransferSize (sizeof(Kernel::UShort)) - -namespace Kernel { -/// @brief Tranfer information about PRD. -enum { - kPRDTTransferInProgress, - kPRDTTransferIsDone, - kPRDTTransferCount, -}; - -/// @brief Physical Region Descriptor Table. -struct PRDT final { - UInt32 fPhysAddress; - UInt32 fSectorCount; - UInt8 fEndBit; -}; - -void construct_prdt(Ref<PRDT>& prd); - -EXTERN_C Int32 kPRDTTransferStatus; -} // namespace Kernel diff --git a/dev/kernel/StorageKit/SCSI.h b/dev/kernel/StorageKit/SCSI.h deleted file mode 100644 index 4dad00ad..00000000 --- a/dev/kernel/StorageKit/SCSI.h +++ /dev/null @@ -1,11 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <modules/SCSI/SCSI.h> - -namespace Kernel {} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/StorageKit/StorageKit.h b/dev/kernel/StorageKit/StorageKit.h deleted file mode 100644 index c9633392..00000000 --- a/dev/kernel/StorageKit/StorageKit.h +++ /dev/null @@ -1,21 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#define kDriveSectorSizeHDD (512U) -#define kDriveSectorSizeSSD (512U) -#define kDriveSectorSizeOptical (2048U) - -namespace Kernel { -template <typename T> -class DeviceInterface; - -class NVMEDeviceInterface; -class AHCIDeviceInterface; -class ATADeviceInterface; -class SCSIDeviceInterface; -} // namespace Kernel diff --git a/dev/kernel/SwapKit/DiskSwap.h b/dev/kernel/SwapKit/DiskSwap.h deleted file mode 100644 index cd81b13a..00000000 --- a/dev/kernel/SwapKit/DiskSwap.h +++ /dev/null @@ -1,72 +0,0 @@ - -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss , licensed under the Apache 2.0 license. - -======================================== */ - -#pragma once - -#include <CompilerKit/CompilerKit.h> -#include <NeKit/Defines.h> -#include <hint/CompilerHint.h> - -#define kSwapBlockMaxSize (mib_cast(16)) -#define kSwapPageFilePath "/boot/pagefile.sys" - -/// @file SwapDisk.h -/// @brief Virtual memory swap disk. - -namespace Kernel { -struct SWAP_DISK_HEADER; -class DiskSwapInterface; - -/// @brief Virtual memory interface to swap memory chunks onto disk. -/// @note The class only supports the NeFS as of right now, as it is using forks to write data into -/// disk. -class DiskSwapInterface final { - public: - explicit DiskSwapInterface() = default; - ~DiskSwapInterface() = default; - - NE_COPY_DELETE(DiskSwapInterface) - NE_MOVE_DELETE(DiskSwapInterface) - - public: - /***********************************************************************************/ - /// @brief Write memory chunk onto disk. - /// @param name The swap name to recognize this memory region. - /// @param name_len length of fork name. - /// @param data the data packet. - /// @return Whether the swap was written to disk, or not. - /***********************************************************************************/ - BOOL Write(const Char* name, SizeT name_len, SWAP_DISK_HEADER* data); - - /***********************************************************************************/ - /// @brief Read memory chunk from disk. - /// @param name The swap name to recognize this memory region. - /// @param name_len length of fork name. - /// @param data the data packet length. - /// @return Whether the swap was fetched to disk, or not. - /***********************************************************************************/ - _Output SWAP_DISK_HEADER* Read(const Char* name, SizeT name_len, SizeT data_len); -}; - -/// @brief Swap disk header, containing information about the held virtual memory. -/// @param fMagic Ident number. -/// @param fHeaderSz This header size. -/// @param fTeamID Process Team ID. -/// @param fProcessID Process ID. -/// @param fVirtualAddress Virtual address pointed by data. -/// @param fBlobSz Blob's size. -/// @param fBlob Data blob. -typedef struct SWAP_DISK_HEADER { - UInt32 fMagic; - SizeT fHeaderSz; - UInt64 fTeamID; - UInt64 fProcessID; - UInt64 fVirtualAddress; - SizeT fBlobSz; - UInt8 fBlob[1]; -} PACKED ALIGN(8) SWAP_DISK_HEADER; -} // namespace Kernel diff --git a/dev/kernel/amd64-ci.make b/dev/kernel/amd64-ci.make deleted file mode 100644 index 203d0dc9..00000000 --- a/dev/kernel/amd64-ci.make +++ /dev/null @@ -1,77 +0,0 @@ -################################################## -# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license. -# This is the NeKernel's makefile. -################################################## - -CXX = x86_64-w64-mingw32-g++ -LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Werror -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEKERNEL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot - -ASM = nasm - -DISK_DRV = - -ifneq ($(ATA_PIO_SUPPORT), ) -DISK_DRV = -D__ATA_PIO__ -endif - -ifneq ($(ATA_DMA_SUPPORT), ) -DISK_DRV = -D__ATA_DMA__ -endif - -ifneq ($(AHCI_SUPPORT), ) -DISK_DRV = -D__AHCI__ -endif - -DEBUG_MACRO = -D__DEBUG__ - -COPY = cp - -# Add assembler, linker, and object files variables. -ASMFLAGS = -f win64 - -# Kernel subsystem is 17 and entrypoint is hal_init_platform -LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x4000000 -LDOBJ = obj/*.obj - -# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management. -KERNEL_IMG = ne_kernel - -.PHONY: error -error: - @echo "=== ERROR ===" - @echo "=> Use a specific target." - -MOVEALL=./move-all-x64.sh -WINDRES=x86_64-w64-mingw32-windres - -.PHONY: nekernel-amd64-epm -nekernel-amd64-epm: clean - $(WINDRES) kernel_rsrc.rsrc -O coff -o kernel_rsrc.obj - $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s) - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalHandoverStub.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtilsAPI.asm - $(MOVEALL) - -OBJCOPY=x86_64-w64-mingw32-objcopy - -.PHONY: link-amd64-epm -link-amd64-epm: - $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG) - -.PHONY: all -all: nekernel-amd64-epm link-amd64-epm - @echo "Kernel => OK." - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "all: Build Kernel and link it." - @echo "link-amd64-epm: Link Kernel for EPM based disks." - @echo "nekernel-amd64-epm: Build Kernel for EPM based disks." - -.PHONY: clean -clean: - rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG) diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make deleted file mode 100644 index 081bf75b..00000000 --- a/dev/kernel/amd64-desktop.make +++ /dev/null @@ -1,79 +0,0 @@ -################################################## -# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license. -# This is the NeKernel's makefile. -################################################## - -CXX = x86_64-w64-mingw32-g++ -LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_OPENHEFS__ -D__FSKIT_INCLUDES_EXT2__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__NEKERNEL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot - -ASM = nasm - -DISK_DRV = - -ifneq ($(ATA_PIO_SUPPORT), ) -DISK_DRV = -D__ATA_PIO__ -endif - -ifneq ($(ATA_DMA_SUPPORT), ) -DISK_DRV = -D__ATA_DMA__ -endif - -ifneq ($(AHCI_SUPPORT), ) -DISK_DRV = -D__AHCI__ -endif - -ifneq ($(DEBUG_SUPPORT), ) -DEBUG_MACRO = -D__DEBUG__ -endif - -COPY = cp - -# Add assembler, linker, and object files variables. -ASMFLAGS = -f win64 - -# Kernel subsystem is 17 and entrypoint is hal_init_platform -LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x10000000 -LDOBJ = obj/*.obj - -# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management. -KERNEL_IMG = ne_kernel - -.PHONY: error -error: - @echo "=== ERROR ===" - @echo "=> Use a specific target." - -MOVEALL=./move-all-x64.sh -WINDRES=x86_64-w64-mingw32-windres - -.PHONY: nekernel-amd64-epm -nekernel-amd64-epm: clean - $(WINDRES) kernel_rsrc.rsrc -O coff -o kernel_rsrc.obj - $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/Network/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s) - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalHandoverStub.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtilsAPI.asm - $(MOVEALL) - -OBJCOPY=x86_64-w64-mingw32-objcopy - -.PHONY: link-amd64-epm -link-amd64-epm: - $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG) - -.PHONY: all -all: nekernel-amd64-epm link-amd64-epm - @echo "Kernel => OK." - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "all: Build Kernel and link it." - @echo "link-amd64-epm: Link Kernel for EPM based disks." - @echo "nekernel-amd64-epm: Build Kernel for EPM based disks." - -.PHONY: clean -clean: - rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG) diff --git a/dev/kernel/arm64-desktop.make b/dev/kernel/arm64-desktop.make deleted file mode 100644 index f5228d6b..00000000 --- a/dev/kernel/arm64-desktop.make +++ /dev/null @@ -1,64 +0,0 @@ -################################################## -# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license. -# This is the microKernel makefile. -################################################## - -CC = clang++ -LD = lld-link -CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__NE_ARM64__ -fno-rtti -fno-exceptions -I./ \ - -target aarch64-unknown-windows \ - -std=c++20 -O3 -D__NEKERNEL__ -D__NEOSKRNL__ -D__NE_VEPM__ -D__NE_MINIMAL_OS__ -D__NE_NO_BUILTIN__ -D__HAVE_NE_APIS__ -D__NE__ -I../ - -ASM = clang++ - -DISKDRIVER = -D__USE_FLASH_MEM__ - -ifneq ($(DEBUG_SUPPORT), ) -DEBUG = -D__DEBUG__ -endif - -COPY = cp - -LDFLAGS = -subsystem:efi_application -entry:hal_init_platform /nodefaultlib -LDOBJ = obj/*.obj - -# This file is the Kernel, responsible of task management and memory. -KERNEL = ne_kernel - -.PHONY: error -error: - @echo "=== ERROR ===" - @echo "=> Use a specific target." - -MOVEALL=./move-all-aarch64.sh - -.PHONY: nekernel-arm64-epm -nekernel-arm64-epm: clean - $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard src/*.cc) \ - $(wildcard src/FS/*.cc) $(wildcard HALKit/ARM64/Storage/*.cc) \ - $(wildcard HALKit/ARM64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \ - $(wildcard HALKit/ARM64/*.cc) $(wildcard HALKit/ARM64/*.cc) \ - $(wildcard HALKit/ARM64/*.s) $(wildcard HALKit/ARM64/APM/*.cc) - - $(MOVEALL) - -OBJCOPY=x86_64-w64-mingw32-objcopy - -.PHONY: link-arm64-epm -link-arm64-epm: - $(LD) $(LDFLAGS) $(LDOBJ) /out:$(KERNEL) - -.PHONY: all -all: nekernel-arm64-epm link-arm64-epm - @echo "Kernel => OK." - -.PHONY: help -help: - @echo "=== HELP ===" - @echo "all: Build Kernel and link it." - @echo "link-arm64-epm: Link Kernel for EPM based disks." - @echo "nekernel-arm64-epm: Build Kernel for EPM based disks." - -.PHONY: clean -clean: - rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL) diff --git a/dev/kernel/kernel_rsrc.rsrc b/dev/kernel/kernel_rsrc.rsrc deleted file mode 100644 index 0a43086e..00000000 --- a/dev/kernel/kernel_rsrc.rsrc +++ /dev/null @@ -1,25 +0,0 @@ -#include "CompilerKit/Version.h" - -1 VERSIONINFO -FILEVERSION 1,0,0,0 -PRODUCTVERSION 1,0,0,0 -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904E4" - BEGIN - VALUE "CompanyName", "Amlal El Mahrouss" - VALUE "FileDescription", "NeKernel" - VALUE "FileVersion", KERNEL_VERSION - VALUE "InternalName", "ne_kernel" - VALUE "LegalCopyright", "(c) 2024-2025 Amlal El Mahrouss, licensed under the Apache 2.0 license." - VALUE "OriginalFilename", "ne_kernel" - VALUE "ProductName", "NeKernel" - VALUE "ProductVersion", KERNEL_VERSION - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x809, 1252 - END -END diff --git a/dev/kernel/move-all-aarch64.sh b/dev/kernel/move-all-aarch64.sh deleted file mode 100755 index 35e0909e..00000000 --- a/dev/kernel/move-all-aarch64.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh - -for file in *.o; do - mv -- "$file" "${file%.o}.obj" -done - -mv *.obj obj/ diff --git a/dev/kernel/move-all-x64.sh b/dev/kernel/move-all-x64.sh deleted file mode 100755 index 1c135d06..00000000 --- a/dev/kernel/move-all-x64.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh - -for file in *.o; do - mv -- "$file" "${file%.o}.obj" -done - -mv *.obj HALKit/AMD64/*.obj obj/ diff --git a/dev/kernel/obj/.gitkeep b/dev/kernel/obj/.gitkeep deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/obj/.gitkeep +++ /dev/null diff --git a/dev/kernel/power64-cb.make b/dev/kernel/power64-cb.make deleted file mode 100644 index c46a00d0..00000000 --- a/dev/kernel/power64-cb.make +++ /dev/null @@ -1,4 +0,0 @@ -################################################## -# (c) Amlal El Mahrouss, licensed under the Apache 2.0 license. -# This is the microKernel makefile. -################################################## diff --git a/dev/kernel/riscv64-cb.make b/dev/kernel/riscv64-cb.make deleted file mode 100644 index e69de29b..00000000 --- a/dev/kernel/riscv64-cb.make +++ /dev/null diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc deleted file mode 100644 index 42819b7e..00000000 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/HeapMgr.h> -#include <NeKit/KString.h> -#include <modules/ACPI/ACPIFactoryInterface.h> - -namespace Kernel { -constexpr STATIC const auto kMinACPIVer = 1U; - -/// @brief Finds a descriptor table inside ACPI XSDT. -ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) { - if (this->fRsdp) return ErrorOr<voidPtr>{-kErrorInvalidData}; - if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData}; - if (*signature == 0) return ErrorOr<voidPtr>{-kErrorInvalidData}; - - RSDP* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp); - - if (rsp_ptr->Revision < kMinACPIVer) return ErrorOr<voidPtr>{-kErrorInvalidData}; - - RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress); - - Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64); - - /*** - crucial to avoid underflows. - */ - if (num < 1) { - /// stop here, we should have entries... - ke_panic(RUNTIME_CHECK_ACPI); - return ErrorOr<voidPtr>{-kErrorInvalidData}; - } - - this->fEntries = num; - - (Void)(kout << "ACPI: Number of entries: " << number(this->fEntries) << kendl); - (Void)(kout << "ACPI: Revision: " << number(xsdt->Revision) << kendl); - (Void)(kout << "ACPI: Signature: " << xsdt->Signature << kendl); - (Void)(kout << "ACPI: Address of XSDT: " << hex_number((UIntPtr) xsdt) << kendl); - - static constexpr const UInt16 cAcpiSignatureLength = 4U; - - for (Size index = 0; index < this->fEntries; ++index) { - SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]); - - (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); - (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); - - for (UInt16 signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) { - if (sdt->Signature[signature_index] != signature[signature_index]) break; - - if (signature_index == (cAcpiSignatureLength - 1)) { - (Void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl); - (Void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl); - return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index])); - } - } - } - - return ErrorOr<voidPtr>{-kErrorInvalidData}; -} - -/*** -@brief Checksum on SDT header. -@param checksum the header to checksum -@param len the length of it. -*/ -bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) { - if (len == 0 || !checksum) return NO; - - Char chr = 0; - - for (SSizeT index = 0L; index < len; ++index) { - chr += checksum[index]; - } - - return chr == 0; -} - -ErrorOr<voidPtr> ACPIFactoryInterface::operator[](const Char* signature) { - if (!signature) return ErrorOr<voidPtr>{-kErrorInvalidData}; - return this->Find(signature); -} -} // namespace Kernel diff --git a/dev/kernel/src/Array.cc b/dev/kernel/src/Array.cc deleted file mode 100644 index c792ef93..00000000 --- a/dev/kernel/src/Array.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Array.h> diff --git a/dev/kernel/src/ArrayList.cc b/dev/kernel/src/ArrayList.cc deleted file mode 100644 index 37042320..00000000 --- a/dev/kernel/src/ArrayList.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/ArrayList.h> diff --git a/dev/kernel/src/AsciiUtils.cc b/dev/kernel/src/AsciiUtils.cc deleted file mode 100644 index 1f1ab0f6..00000000 --- a/dev/kernel/src/AsciiUtils.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Utils.h> - -namespace Kernel { -Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) { - for (Size i = 0; i < size; ++i) { - if (src[i] != cmp[i]) return static_cast<Int32>(src[i]) - static_cast<Int32>(cmp[i]); - } - return 0; -} - -SizeT rt_string_len(const Char* str, SizeT max_len) { - SizeT len = 0; - while (len < max_len && str[len] != '\0') ++len; - return len; -} - -Size rt_string_len(const Char* ptr) { - Size cnt = 0; - while (ptr[cnt] != '\0') ++cnt; - return cnt; -} - -const Char* rt_alloc_string(const Char* src) { - SizeT slen = rt_string_len(src); - Char* buffer = new Char[slen + 1]; - if (!buffer) return nullptr; - - if (rt_copy_memory_safe(reinterpret_cast<voidPtr>(const_cast<Char*>(src)), - reinterpret_cast<voidPtr>(buffer), slen, slen + 1) < 0) { - delete[] buffer; - return nullptr; - } - - buffer[slen] = '\0'; - return buffer; -} - -Int32 rt_copy_memory_safe(const voidPtr src, voidPtr dst, Size len, Size dst_size) { - if (!src || !dst || len > dst_size) { - if (dst && dst_size) { - rt_set_memory_safe(dst, 0, dst_size, dst_size); - } - return -1; - } - - auto s = reinterpret_cast<const UInt8*>(src); - auto d = reinterpret_cast<UInt8*>(dst); - - for (Size i = 0; i < len; ++i) d[i] = s[i]; - - return static_cast<Int>(len); -} - -voidPtr rt_set_memory_safe(voidPtr dst, UInt32 value, Size len, Size dst_size) { - if (!dst || len > dst_size) return nullptr; - auto p = reinterpret_cast<UInt8*>(dst); - UInt8 v = static_cast<UInt8>(value & 0xFF); - for (Size i = 0; i < len; ++i) p[i] = v; - return dst; -} - -Void rt_zero_memory(voidPtr pointer, Size len) { - rt_set_memory_safe(pointer, 0, len, len); -} - -#ifdef __NE_ENFORCE_DEPRECATED_WARNINGS -[[deprecated("Use rt_set_memory_safe instead")]] -#endif -voidPtr -rt_set_memory(voidPtr src, UInt32 value, Size len) { - if (!src) return nullptr; - auto p = reinterpret_cast<UInt8*>(src); - UInt8 v = static_cast<UInt8>(value & 0xFF); - for (Size i = 0; i < len; ++i) p[i] = v; - return src; -} - -#ifdef __NE_ENFORCE_DEPRECATED_WARNINGS -[[deprecated("Use rt_copy_memory_safe instead")]] -#endif -Int32 rt_copy_memory(const voidPtr src, voidPtr dst, Size len) { - if (!src || !dst) return -1; - auto s = reinterpret_cast<const UInt8*>(src); - auto d = reinterpret_cast<UInt8*>(dst); - - for (Size i = 0; i < len; ++i) d[i] = s[i]; - - return static_cast<Int>(len); -} - -Int32 rt_to_uppercase(Int ch) { - return (ch >= 'a' && ch <= 'z') ? ch - 0x20 : ch; -} - -Int32 rt_to_lower(Int ch) { - return (ch >= 'A' && ch <= 'Z') ? ch + 0x20 : ch; -} - -Int32 rt_is_alnum(Int ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'); -} - -Boolean rt_is_space(Int ch) { - return ch == ' '; -} - -Boolean rt_is_newln(Int ch) { - return ch == '\n'; -} - -Char rt_to_char(UInt64 value, Int32 base) { - static constexpr Char kDigits[] = "0123456789ABCDEF"; - return kDigits[value % base]; -} - -Bool rt_to_string(Char* str, UInt64 value, Int32 base) { - if (!str || base < 2 || base > 16) return NO; - - Int i = 0; - do { - str[i++] = rt_to_char(value, base); - value /= base; - } while (value); - str[i] = '\0'; - // in-place - for (Int j = 0; j < i / 2; ++j) { - Char tmp = str[j]; - str[j] = str[i - j - 1]; - str[i - j - 1] = tmp; - } - - return YES; -} - -VoidPtr rt_string_in_string(const Char* haystack, const Char* needle) { - if (!haystack || !needle) return nullptr; - - SizeT needle_len = rt_string_len(needle); - SizeT hay_len = rt_string_len(haystack); - - if (needle_len > hay_len) return nullptr; - for (SizeT i = 0; i <= hay_len - needle_len; ++i) { - if (rt_string_cmp(haystack + i, needle, needle_len) == 0) { - return reinterpret_cast<voidPtr>(const_cast<Char*>(haystack + i)); - } - } - return nullptr; -} - -Char* rt_string_has_char(Char* str, Char ch) { - if (!str) return nullptr; - while (*str && *str != ch) ++str; - return (*str == ch) ? str : nullptr; -} -} // namespace Kernel diff --git a/dev/kernel/src/Atom.cc b/dev/kernel/src/Atom.cc deleted file mode 100644 index c6c1dd40..00000000 --- a/dev/kernel/src/Atom.cc +++ /dev/null @@ -1,10 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Atom.h> - -// @file Atom.cc -// @brief Atomic primitives diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc deleted file mode 100644 index 3c332b33..00000000 --- a/dev/kernel/src/BinaryMutex.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/BinaryMutex.h> -#include <KernelKit/ProcessScheduler.h> - -namespace Kernel { -/***********************************************************************************/ -/// @brief Unlocks the binary mutex. -/***********************************************************************************/ - -Bool BinaryMutex::Unlock() noexcept { - if (fLockingProcess->Status == ProcessStatusKind::kRunning) { - fLockingProcess = nullptr; - - return Yes; - } - - return No; -} - -/***********************************************************************************/ -/// @brief Locks process in the binary mutex. -/***********************************************************************************/ - -Bool BinaryMutex::Lock(USER_PROCESS* process) { - if (!process || this->IsLocked()) return No; - - this->fLockingProcess = process; - - return Yes; -} - -/***********************************************************************************/ -/// @brief Checks if process is locked. -/***********************************************************************************/ - -Bool BinaryMutex::IsLocked() const { - return this->fLockingProcess->Status == ProcessStatusKind::kRunning; -} - -/***********************************************************************************/ -/// @brief Try lock or wait. -/***********************************************************************************/ - -Bool BinaryMutex::LockAndWait(USER_PROCESS* process, TimerInterface* timer) { - if (timer == nullptr) return No; - - this->Lock(process); - - timer->Wait(); - - return this->Lock(process); -} - -/***********************************************************************************/ -/// @brief Wait for process **sec** until we check if it's free. -/// @param sec seconds. -/***********************************************************************************/ - -BOOL BinaryMutex::WaitForProcess(const UInt32& sec) noexcept { - HardwareTimer hw_timer(rtl_milliseconds(sec)); - hw_timer.Wait(); - - return !this->IsLocked(); -} -} // namespace Kernel diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc deleted file mode 100644 index d7ecb810..00000000 --- a/dev/kernel/src/BitMapMgr.cc +++ /dev/null @@ -1,206 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifdef __NE_AMD64__ -#include <HALKit/AMD64/Paging.h> -#elif defined(__NE_ARM64__) -#include <HALKit/ARM64/Paging.h> -#endif - -#include <ArchKit/ArchKit.h> -#include <NeKit/KernelPanic.h> - -#define kBitMapMagic (0x10210U) - -#define kBitMapMagIdx (0U) -#define kBitMapSizeIdx (1U) -#define kBitMapUsedIdx (2U) - -///! @author Amlal El Mahrouss (amlal@nekernel.org) - -namespace Kernel { -namespace HAL { - namespace Detail { - /***********************************************************************************/ - /// \brief Proxy Interface to manage a bitmap allocator. - /***********************************************************************************/ - class IBitMapProxy final { - public: - explicit IBitMapProxy() = default; - ~IBitMapProxy() = default; - - NE_COPY_DELETE(IBitMapProxy) - - auto IsBitMap(VoidPtr page_ptr) -> Bool { - if (!page_ptr) return No; - - UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr); - - if (!ptr_bit_set[kBitMapMagIdx] || ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) return No; - - return Yes; - } - - auto FreeBitMap(VoidPtr page_ptr) -> Bool { - if (this->IsBitMap(page_ptr) == No) return No; - - UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr); - - kBitMapCursor += ptr_bit_set[kBitMapSizeIdx]; - - ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[kBitMapUsedIdx] = No; - - this->GetBitMapStatus(ptr_bit_set); - - return Yes; - } - - UInt32 MakeMMFlags(Bool wr, Bool user) { - UInt32 flags = kMMFlagsPresent; - - if (wr) flags |= kMMFlagsWr; - if (user) flags |= kMMFlagsUser; - - return flags; - } - - /***********************************************************************************/ - /// @brief Iterate over availables bitmap, until we find a free entry. - /// @param base_ptr base pointer to look on. - /// @param size the size of the requested data structure. - /// @param wr is writable flag? - /// @param user is user flag? - /// @param pad additional padding added to **size** - /// @return The new free address, or nullptr. - /***********************************************************************************/ - auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user, SizeT pad) -> VoidPtr { - if (!size) return nullptr; - - if (kBitMapCursor > kKernelBitMpSize) { - err_global_get() = kErrorOutOfBitMapMemory; - - (Void)(kout << "Bitmap limit reached, can't allocate more bitmaps." << kendl); - return nullptr; - } - - VoidPtr base = reinterpret_cast<VoidPtr>((UIntPtr) base_ptr); - MUST_PASS(base); - - if (!base) return nullptr; - - STATIC SizeT biggest = 0UL; - - while (YES) { - UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base); - - if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic && - ptr_bit_set[kBitMapSizeIdx] == (size + pad)) { - if (ptr_bit_set[kBitMapUsedIdx] == No) { - ptr_bit_set[kBitMapSizeIdx] = size + pad; - ptr_bit_set[kBitMapUsedIdx] = Yes; - - this->GetBitMapStatus(ptr_bit_set); - - UInt32 flags = this->MakeMMFlags(wr, user); - mm_map_page(ptr_bit_set, (VoidPtr)mm_get_page_addr(ptr_bit_set), flags); - - if (biggest < (size + pad)) biggest = size + pad; - - kBitMapCursor += size + pad; - - return (VoidPtr) ptr_bit_set; - } - } else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) { - ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[kBitMapSizeIdx] = (size + pad); - ptr_bit_set[kBitMapUsedIdx] = Yes; - - this->GetBitMapStatus(ptr_bit_set); - - UInt32 flags = this->MakeMMFlags(wr, user); - mm_map_page(ptr_bit_set, (VoidPtr)mm_get_page_addr(ptr_bit_set), flags); - - if (biggest < (size + pad)) biggest = (size + pad); - - kBitMapCursor += size + pad; - - return (VoidPtr) ptr_bit_set; - } - - UIntPtr raw_base = reinterpret_cast<UIntPtr>(base); - UIntPtr offset = (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) - ? (size + pad) - : ptr_bit_set[kBitMapSizeIdx]; - - base = reinterpret_cast<VoidPtr>(raw_base + offset); - if (base == nullptr) return nullptr; - } - - return nullptr; - } - - /// @brief Print Bitmap status - auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void { - if (!this->IsBitMap(ptr_bit_set)) { - (Void)(kout << "Not a BitMap: " << hex_number((UIntPtr) ptr_bit_set) << kendl); - return; - } - - (Void)(kout << "Magic: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << kendl); - (Void)(kout << "Is Allocated? " << (ptr_bit_set[kBitMapUsedIdx] ? "YES" : "NO") << kendl); - (Void)(kout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << kendl); - (Void)(kout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx])) - << kendl); - (Void)(kout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx])) - << kendl); - (Void)(kout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx])) - << kendl); - (Void)(kout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx])) - << kendl); - (Void)(kout << "BitMap Address: " << hex_number((UIntPtr) ptr_bit_set) << kendl); - } - }; - } // namespace Detail - - STATIC Detail::IBitMapProxy kBitMapMgr; - - auto mm_is_bitmap(VoidPtr ptr) -> BOOL { - return kBitMapMgr.IsBitMap(ptr); - } - - /***********************************************************************************/ - /// @brief Allocate a new page to be used by the OS. - /// @param wr read/write bit. - /// @param user user bit. - /// @return a new bitmap allocated pointer. - /***********************************************************************************/ - auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad) -> VoidPtr { - VoidPtr ptr_new = nullptr; - if (is_page) return nullptr; - - ptr_new = kBitMapMgr.FindBitMap(kKernelBitMpStart, size, wr, user, pad); - - if (!ptr_new) { - ke_panic(RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM, "Out of memory bitmap"); - return nullptr; - } - - return ptr_new; - } - - /***********************************************************************************/ - /// @brief Free Bitmap, and mark it as absent. - /// @param ptr the pointer to free. - /***********************************************************************************/ - auto mm_free_bitmap(VoidPtr ptr) -> Bool { - if (!ptr) return No; - - Bool ret = kBitMapMgr.FreeBitMap(ptr); - return ret; - } -} // namespace HAL -} // namespace Kernel diff --git a/dev/kernel/src/CRuntimeOverrides.cc b/dev/kernel/src/CRuntimeOverrides.cc deleted file mode 100644 index a773d4f9..00000000 --- a/dev/kernel/src/CRuntimeOverrides.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Utils.h> - -using namespace Kernel; - -/// =========================================================== /// -/// @brief C Standard Library overrides. /// -/// =========================================================== /// - -EXTERN_C void* memset(void* dst, int c, long long unsigned int len) { - return Kernel::rt_set_memory_safe(dst, c, static_cast<Size>(len), static_cast<Size>(len)); -} - -EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) { - Kernel::rt_copy_memory_safe(const_cast<void*>(src), dst, static_cast<Size>(len), - static_cast<Size>(len)); - return dst; -} - -EXTERN_C Int32 strcmp(const char* a, const char* b) { - return Kernel::rt_string_cmp(a, b, rt_string_len(a)); -} diff --git a/dev/kernel/src/CodeMgr.cc b/dev/kernel/src/CodeMgr.cc deleted file mode 100644 index 7b7add6d..00000000 --- a/dev/kernel/src/CodeMgr.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/CodeMgr.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/Utils.h> - -namespace Kernel { - -/// @brief Executes a new process from a function. Kernel code only. -/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be -/// accessible. -/// @param main the start of the process. -/// @return The team's process id. -BOOL rtl_create_kernel_task(HAL::StackFramePtr task, const KID kid) noexcept { - if (!kid || task == nullptr) return FALSE; - return KernelTaskHelper::Add(task, kid); -} - -/***********************************************************************************/ -/// @brief Executes a new process from a function. Kernel code only. -/// @note This sets up a new stack, anything on the main function that calls the Kernel will not be -/// accessible. -/// @param main the start of the process. -/// @return if the process was started or not. -/***********************************************************************************/ - -ProcessID rtl_create_user_process(rtl_main_kind main, const Char* process_name) noexcept { - if (!process_name || *process_name == 0) return kSchedInvalidPID; - return UserProcessScheduler::The().Spawn(process_name, reinterpret_cast<VoidPtr>(main), nullptr); -} -} // namespace Kernel diff --git a/dev/kernel/src/Crc32.cc b/dev/kernel/src/Crc32.cc deleted file mode 100644 index 88a9b73a..00000000 --- a/dev/kernel/src/Crc32.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Crc32.h> - -#define kCrcCnt (256) - -// @file CRC32.cc -// @brief Check sequence implementation. - -namespace Kernel { -/// @brief The CRC32 seed table. -UInt32 kChecksumPolys[kCrcCnt] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; - -/// @brief Calculate CRC32 of p -/// @param in the data to compute. -/// @param len the length of the data. -/// @return CRC32 of **in**. -UInt32 ke_calculate_crc32(const VoidPtr inp, Int32 len) noexcept { - if (!inp) return ~0; - - UInt32 crc = 0xffffffff; - - Char* in = static_cast<Char*>(inp); - - while ((len--) > 0) crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF]; - - return ~crc; -} -} // namespace Kernel diff --git a/dev/kernel/src/Defines.cc b/dev/kernel/src/Defines.cc deleted file mode 100644 index 1ae6f12f..00000000 --- a/dev/kernel/src/Defines.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Defines.h> diff --git a/dev/kernel/src/DeviceMgr.cc b/dev/kernel/src/DeviceMgr.cc deleted file mode 100644 index b392a4ee..00000000 --- a/dev/kernel/src/DeviceMgr.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DeviceMgr.h> - -namespace Kernel {} // namespace Kernel diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc deleted file mode 100644 index 8f2611a4..00000000 --- a/dev/kernel/src/DriveMgr.cc +++ /dev/null @@ -1,254 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <FirmwareKit/GPT.h> -#include <FirmwareKit/VEPM.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/DriveMgr.h> -#include <NeKit/Utils.h> -#include <modules/AHCI/AHCI.h> -#include <modules/ATA/ATA.h> -#include <modules/NVME/NVME.h> - -/***********************************************************************************/ -/// @file DriveMgr.cc -/// @brief Drive Manager of NeKernel. -///! @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -namespace Kernel { -#if defined(__ATA_PIO__) || defined(__ATA_DMA__) -STATIC UInt16 kATAIO = 0U; -STATIC UInt8 kATAMaster = 0U; -#endif - -#if defined(__AHCI__) -STATIC UInt16 kAHCIPortsImplemented [[maybe_unused]] = 0UL; -#endif - -/// @brief reads from an ATA drive. -/// @param pckt Packet structure (fPacketContent must be non null) -/// @return -Void io_drv_input(DriveTrait::DrivePacket& pckt) { -#ifdef __AHCI__ - drv_std_read(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize); - - if (err_global_get() != kErrorSuccess) pckt.fPacketGood = NO; -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_read(pckt.fPacketLba, kATAIO, kATAMaster, (Char*) pckt.fPacketContent, kATASectorSize, - pckt.fPacketSize); -#endif -} - -/// @brief Writes to an ATA drive. -/// @param pckt the packet to write. -/// @return -Void io_drv_output(DriveTrait::DrivePacket& pckt) { - if (pckt.fPacketReadOnly) { - pckt.fPacketGood = NO; - return; - } - - // nothing starts before 512 anyways, even an EPM partition. - if (!pckt.fPacketReadOnly && pckt.fPacketLba == 0) { - pckt.fPacketGood = NO; - return; - } - -#ifdef __AHCI__ - drv_std_write(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize); - - if (err_global_get() != kErrorSuccess) pckt.fPacketGood = NO; -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_write(pckt.fPacketLba, kATAIO, kATAMaster, (Char*) pckt.fPacketContent, kATASectorSize, - pckt.fPacketSize); -#endif -} - -/// @brief Executes a disk check on the ATA drive. -/// @param pckt the packet to read. -/// @return -Void io_drv_init(DriveTrait::DrivePacket& pckt) { -#if defined(__ATA_PIO__) || defined(__ATA_DMA__) - kATAMaster = 0; - kATAIO = 0; - - kATAMaster = YES; - kATAIO = ATA_PRIMARY_IO; - - if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) { - pckt.fPacketGood = YES; - return; - } - - kATAMaster = NO; - kATAIO = ATA_SECONDARY_IO; - - if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) { - pckt.fPacketGood = YES; - return; - } - - pckt.fPacketGood = YES; -#elif defined(__AHCI__) - kAHCIPortsImplemented = 0; - drv_std_init(kAHCIPortsImplemented); - - pckt.fPacketGood = kAHCIPortsImplemented > 0; -#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) -} - -/// @brief Gets the drive kind (ATA, SCSI, AHCI...) -/// @param void no arguments. -/// @return no arguments. -#ifdef __ATA_PIO__ -const Char* io_drv_kind(Void) { - return "ATA-PIO"; -} -#elif defined(__ATA_DMA__) -const Char* io_drv_kind(Void) { - return "ATA-DMA"; -} -#elif defined(__AHCI__) -const Char* io_drv_kind(Void) { - return "AHCI"; -} -#else -const Char* io_drv_kind(Void) { - return "null"; -} -#endif - -/// @brief Unimplemented drive function. -/// @param pckt the packet to read. -Void io_drv_unimplemented(DriveTrait::DrivePacket& pckt) noexcept { - NE_UNUSED(pckt); -} - -/// @brief Makes a new drive. -/// @return the new blank drive. -DriveTrait io_construct_blank_drive() noexcept { - DriveTrait trait; - - constexpr auto kBlankDrive = "/media/blank/"; - - rt_copy_memory((VoidPtr) kBlankDrive, trait.fName, rt_string_len(kBlankDrive)); - trait.fKind = kInvalidDrive; - - trait.fInput = io_drv_unimplemented; - trait.fOutput = io_drv_unimplemented; - trait.fVerify = io_drv_unimplemented; - trait.fInit = io_drv_unimplemented; - trait.fProtocol = io_drv_kind; - - kout << "DriveMgr: Construct: " << trait.fName << "\r"; - - return trait; -} - -namespace Probe { - Void io_detect_drive(DriveTrait& trait) { - trait.fInit(trait.fPacket); - - EPM_PART_BLOCK block_struct; - - trait.fPacket.fPacketLba = kEPMBootBlockLba; - trait.fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); - trait.fPacket.fPacketContent = &block_struct; - - rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime, - rt_string_len("fs/detect-packet")); - - trait.fInput(trait.fPacket); - - if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) { - trait.fPacket.fPacketReadOnly = NO; - trait.fKind = kMassStorageDrive | kEPMDrive; - - kout << "DriveMgr: Disk is EPM formatted.\r"; - - trait.fSectorSz = block_struct.SectorSz; - trait.fLbaEnd = block_struct.LbaEnd; - trait.fLbaStart = block_struct.LbaStart; - } else { - GPT_PARTITION_TABLE gpt_struct; - - trait.fPacket.fPacketLba = kEPMBootBlockLba; - trait.fPacket.fPacketSize = sizeof(GPT_PARTITION_TABLE); - trait.fPacket.fPacketContent = &gpt_struct; - - rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime, - rt_string_len("fs/detect-packet")); - - trait.fInput(trait.fPacket); - - if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0) { - trait.fPacket.fPacketReadOnly = NO; - trait.fKind = kMassStorageDrive | kGPTDrive; - - kout << "DriveMgr: Disk is GPT formatted.\r"; - - trait.fSectorSz = gpt_struct.SizeOfEntries; - trait.fLbaEnd = gpt_struct.LastGPTEntry; - trait.fLbaStart = gpt_struct.FirstGPTEntry; - } else { - kout << "DriveMgr: Disk is unformatted.\r"; - - trait.fPacket.fPacketReadOnly = YES; - trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive; - - trait.fSectorSz = 512; - trait.fLbaEnd = drv_std_get_sector_count() - 1; - trait.fLbaStart = 0x400; - } - } - - rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime, rt_string_len("*/*")); - - trait.fPacket.fPacketLba = 0; - trait.fPacket.fPacketSize = 0UL; - trait.fPacket.fPacketContent = nullptr; - } -} // namespace Probe - -/// @brief Fetches the main drive. -/// @return the new drive. (returns kEPMDrive if EPM formatted) -DriveTrait io_construct_main_drive() noexcept { - constexpr auto kMainDrive = "/media/main/"; - - DriveTrait trait; - - rt_copy_memory((VoidPtr) kMainDrive, trait.fName, rt_string_len(kMainDrive)); - MUST_PASS(trait.fName[0] != 0); - - trait.fVerify = io_drv_unimplemented; - trait.fOutput = io_drv_output; - trait.fInput = io_drv_input; - trait.fInit = io_drv_init; - trait.fProtocol = io_drv_kind; - - Probe::io_detect_drive(trait); - - return trait; -} - -/// @brief Replacement for io_construct_main_drive that works with IMountpoint. -/// @return the new drive. (returns kEPMDrive if EPM formatted) -Void io_construct_main_drive(DriveTrait& trait) noexcept { - constexpr auto kMainDrive = "/media/main/"; - - rt_copy_memory((VoidPtr) kMainDrive, trait.fName, rt_string_len(kMainDrive)); - MUST_PASS(trait.fName[0] != 0); - - trait.fVerify = io_drv_unimplemented; - trait.fOutput = io_drv_output; - trait.fInput = io_drv_input; - trait.fInit = io_drv_init; - trait.fProtocol = io_drv_kind; - - Probe::io_detect_drive(trait); -} -} // namespace Kernel diff --git a/dev/kernel/src/ErrorOr.cc b/dev/kernel/src/ErrorOr.cc deleted file mode 100644 index 9f1b550b..00000000 --- a/dev/kernel/src/ErrorOr.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/ErrorOr.h> - -/***********************************************************************************/ -/// @file ErrorOr.cc /// -/// @brief ErrorOr container class. /// -/***********************************************************************************/ diff --git a/dev/kernel/src/FS/Ext2+IFS.cc b/dev/kernel/src/FS/Ext2+IFS.cc deleted file mode 100644 index 106229f7..00000000 --- a/dev/kernel/src/FS/Ext2+IFS.cc +++ /dev/null @@ -1,1555 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __NE_MINIMAL_OS__ -#ifdef __FSKIT_INCLUDES_EXT2__ - -#include <FSKit/Ext2+IFS.h> -#include <FSKit/Ext2.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/FileMgr.h> -#include <KernelKit/HeapMgr.h> -#include <NeKit/ErrorOr.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> - -constexpr static UInt32 EXT2_DIRECT_BLOCKS = 12; -constexpr static UInt32 EXT2_SINGLE_INDIRECT_INDEX = 12; -constexpr static UInt32 EXT2_DOUBLE_INDIRECT_INDEX = 13; -constexpr ATTRIBUTE(unused) static UInt32 EXT2_TRIPLE_INDIRECT_INDEX = 14; -constexpr static UInt32 EXT2_ROOT_INODE = 2; -constexpr ATTRIBUTE(unused) static UInt32 EXT2_SUPERBLOCK_BLOCK = 1; -constexpr static UInt32 EXT2_GROUP_DESC_BLOCK_SMALL = 2; -constexpr static UInt32 EXT2_GROUP_DESC_BLOCK_LARGE = 1; - -static inline SizeT ext2_min(SizeT a, SizeT b) { - return a < b ? a : b; -} - -struct Ext2GroupInfo { - EXT2_GROUP_DESCRIPTOR* groupDesc; - UInt32 groupDescriptorBlock; - UInt32 offsetInGroupDescBlock; - UInt8* blockBuffer; -}; - -// Convert EXT2 block number -> LBA (sector index) for Drive I/O. -static inline UInt32 ext2_block_to_lba(Ext2Context* ctx, UInt32 blockNumber) { - if (!ctx || !ctx->drive) return 0; - UInt32 blockSize = ctx->BlockSize(); - UInt32 sectorSize = ctx->drive->fSectorSz; - UInt32 sectorsPerBlock = blockSize / sectorSize; - return blockNumber * sectorsPerBlock; -} - -// Read a block and return a pointer to its content -static ErrorOr<UInt32*> ext2_read_block_ptr(Ext2Context* ctx, UInt32 blockNumber) { - if (!ctx || !ctx->drive || !ctx->superblock) return ErrorOr<UInt32*>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - auto buf = (UInt32*) mm_alloc_ptr(blockSize, true, false); - if (!buf) return ErrorOr<UInt32*>(kErrorHeapOutOfMemory); - - UInt32 lba = ext2_block_to_lba(ctx, blockNumber); - if (!ext2_read_block(ctx->drive, lba, buf, blockSize)) { - mm_free_ptr(buf); - return ErrorOr<UInt32*>(kErrorDisk); - } - return ErrorOr<UInt32*>(buf); -} - -// Get the block address for a given logical block index -static ErrorOr<UInt32> ext2_get_block_address(Ext2Context* ctx, Ext2Node* node, - UInt32 logicalIndex) { - if (!ctx || !node || !ctx->drive) return ErrorOr<UInt32>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - UInt32 pointersPerBlock = blockSize / sizeof(UInt32); - - // Direct blocks - if (logicalIndex < EXT2_DIRECT_BLOCKS) { - UInt32 bn = node->inode.fBlock[logicalIndex]; - if (bn == 0) return ErrorOr<UInt32>(kErrorInvalidData); - return ErrorOr<UInt32>(bn); - } - - // Single indirect blocks - if (logicalIndex < (EXT2_DIRECT_BLOCKS + pointersPerBlock)) { - UInt32 iblock = node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]; - if (iblock == 0) return ErrorOr<UInt32>(kErrorInvalidData); - - auto res = ext2_read_block_ptr(ctx, iblock); - if (!res) return ErrorOr<UInt32>(res.Error()); - - // Using dereference operator - UInt32* ptr = *res.Leak(); // operator* returns T (UInt32*) - - UInt32 val = ptr[logicalIndex - EXT2_DIRECT_BLOCKS]; - mm_free_ptr(ptr); - - if (val == 0) return ErrorOr<UInt32>(kErrorInvalidData); - return ErrorOr<UInt32>(val); - } - - // Double indirect blocks - UInt32 doubleStart = EXT2_DIRECT_BLOCKS + pointersPerBlock; - UInt32 doubleSpan = pointersPerBlock * pointersPerBlock; - if (logicalIndex < (doubleStart + doubleSpan)) { - UInt32 db = node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]; - if (db == 0) return ErrorOr<UInt32>(kErrorInvalidData); - - auto dblRes = ext2_read_block_ptr(ctx, db); - if (!dblRes) return ErrorOr<UInt32>(dblRes.Error()); - - UInt32* dblPtr = *dblRes.Leak(); - - UInt32 idxWithin = logicalIndex - doubleStart; - UInt32 firstIdx = idxWithin / pointersPerBlock; - UInt32 secondIdx = idxWithin % pointersPerBlock; - UInt32 singleBlockNum = dblPtr[firstIdx]; - - mm_free_ptr(dblPtr); - if (singleBlockNum == 0) return ErrorOr<UInt32>(kErrorInvalidData); - - auto singleRes = ext2_read_block_ptr(ctx, singleBlockNum); - if (!singleRes) return ErrorOr<UInt32>(singleRes.Error()); - - UInt32* singlePtr = *singleRes.Leak(); - UInt32 val = singlePtr[secondIdx]; - mm_free_ptr(singlePtr); - - if (val == 0) return ErrorOr<UInt32>(kErrorInvalidData); - return ErrorOr<UInt32>(val); - } - - return ErrorOr<UInt32>(kErrorUnimplemented); -} - -static ErrorOr<voidPtr> ext2_read_inode_data(Ext2Context* ctx, Ext2Node* node, SizeT size) { - if (!ctx || !ctx->drive || !node || size == 0) return ErrorOr<voidPtr>(1); - - auto blockSize = ctx->BlockSize(); - SizeT available = (node->inode.fSize > node->cursor) ? (node->inode.fSize - node->cursor) : 0; - SizeT bytesToRead = (size < available) ? size : available; - if (bytesToRead == 0) return ErrorOr<voidPtr>(2); // nothing to read - - auto buffer = mm_alloc_ptr(bytesToRead, true, false); - if (!buffer) return ErrorOr<voidPtr>(3); // allocation failed - - UInt32 currentOffset = node->cursor; - SizeT remaining = bytesToRead; - UInt8* dest = reinterpret_cast<UInt8*>(buffer); - - while (remaining > 0) { - UInt32 logicalIndex = currentOffset / blockSize; - UInt32 offsetInBlock = currentOffset % blockSize; - - auto phys = ext2_get_block_address(ctx, node, logicalIndex); - if (phys.HasError()) { - mm_free_ptr(buffer); - return ErrorOr<voidPtr>(phys.Error()); - } - - auto blockNumber = phys.Value(); - UInt32 lba = ext2_block_to_lba(ctx, blockNumber); - - auto blockBuf = mm_alloc_ptr(blockSize, true, false); - if (!blockBuf) { - mm_free_ptr(buffer); - return ErrorOr<voidPtr>(4); // block buffer allocation failed - } - - if (!ext2_read_block(ctx->drive, lba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - mm_free_ptr(buffer); - return ErrorOr<voidPtr>(5); // block read failed - } - - SizeT chunk = ext2_min(remaining, blockSize - offsetInBlock); - rt_copy_memory_safe(static_cast<void*>(static_cast<UInt8*>(blockBuf) + offsetInBlock), - static_cast<void*>(dest), chunk, chunk); - - mm_free_ptr(blockBuf); - - currentOffset += static_cast<UInt32>(chunk); - dest += chunk; - remaining -= chunk; - } - - node->cursor += static_cast<UInt32>(bytesToRead); - return ErrorOr<voidPtr>(buffer); -} - -// Get group descriptor information for a given block/inode number -static ErrorOr<Ext2GroupInfo*> ext2_get_group_descriptor_info(Ext2Context* ctx, - UInt32 targetBlockOrInode) { - if (!ctx || !ctx->superblock || !ctx->drive) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - UInt32 blocksPerGroup = ctx->superblock->fBlocksPerGroup; - UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup; - UInt32 totalBlocks = ctx->superblock->fBlockCount; - UInt32 totalInodes = ctx->superblock->fInodeCount; - - if (blocksPerGroup == 0 || inodesPerGroup == 0) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData); - - // block group index - UInt32 groupIndex = 0; - if (targetBlockOrInode == 0) { - groupIndex = 0; - } else if (targetBlockOrInode <= totalInodes) { - // 1-based - groupIndex = (targetBlockOrInode - 1) / inodesPerGroup; - } else { - // EXT2 block number - if (targetBlockOrInode < ctx->superblock->fFirstDataBlock) { - groupIndex = 0; - } else { - groupIndex = (targetBlockOrInode - ctx->superblock->fFirstDataBlock) / blocksPerGroup; - } - } - - // Calculate number of block groups - UInt32 groupsCount = static_cast<UInt32>((totalBlocks + blocksPerGroup - 1) / blocksPerGroup); - if (groupIndex >= groupsCount) return ErrorOr<Ext2GroupInfo*>(kErrorInvalidData); - - // Determine GDT start block - UInt32 gdtStartBlock = - (blockSize == 1024) ? EXT2_GROUP_DESC_BLOCK_SMALL : EXT2_GROUP_DESC_BLOCK_LARGE; - - // Compute byte offset of descriptor within the GDT - const UInt32 descSize = sizeof(EXT2_GROUP_DESCRIPTOR); - UInt64 descByteOffset = static_cast<UInt64>(groupIndex) * descSize; - - // Which EXT2 block contains that descriptor? - UInt32 blockOffsetWithinGdt = static_cast<UInt32>(descByteOffset / blockSize); - UInt32 offsetInGroupDescBlock = static_cast<UInt32>(descByteOffset % blockSize); - UInt32 groupDescriptorBlock = gdtStartBlock + blockOffsetWithinGdt; - - // Allocate buffer and read the block containing the descriptor - auto blockBuffer = mm_alloc_ptr(blockSize, true, false); - if (!blockBuffer) return ErrorOr<Ext2GroupInfo*>(kErrorHeapOutOfMemory); - - UInt32 groupDescriptorLba = ext2_block_to_lba(ctx, groupDescriptorBlock); - if (!ext2_read_block(ctx->drive, groupDescriptorLba, blockBuffer, blockSize)) { - mm_free_ptr(blockBuffer); - return ErrorOr<Ext2GroupInfo*>(kErrorDisk); - } - - auto groupInfo = (Ext2GroupInfo*) mm_alloc_ptr(sizeof(Ext2GroupInfo), true, false); - if (!groupInfo) { - mm_free_ptr(blockBuffer); - return ErrorOr<Ext2GroupInfo*>(kErrorHeapOutOfMemory); - } - - groupInfo->groupDesc = reinterpret_cast<EXT2_GROUP_DESCRIPTOR*>( - reinterpret_cast<UInt8*>(blockBuffer) + offsetInGroupDescBlock); - groupInfo->groupDescriptorBlock = groupDescriptorBlock; - groupInfo->offsetInGroupDescBlock = offsetInGroupDescBlock; - groupInfo->blockBuffer = reinterpret_cast<UInt8*>(blockBuffer); - - return ErrorOr<Ext2GroupInfo*>(groupInfo); -} - -// Allocate a new block -inline ErrorOr<UInt32> ext2_alloc_block(Ext2Context* ctx, EXT2_GROUP_DESCRIPTOR* groupDesc) { - if (!ctx || !ctx->superblock || !groupDesc) return ErrorOr<UInt32>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - - // for the bitmap - auto bitmap = mm_alloc_ptr(blockSize, true, false); - if (!bitmap) return ErrorOr<UInt32>(kErrorHeapOutOfMemory); - - // Read block bitmap - if (!ext2_read_block(ctx->drive, groupDesc->fBlockBitmap, bitmap, blockSize)) { - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(kErrorDisk); - } - - // bit = 0 - for (UInt32 byteIdx = 0; byteIdx < blockSize; ++byteIdx) { - auto byte = reinterpret_cast<unsigned char*>(bitmap)[byteIdx]; - if (byte != 0xFF) { - for (int bit = 0; bit < 8; ++bit) { - if (!(byte & (1 << bit))) { - // Mark bit as used - reinterpret_cast<unsigned char*>(bitmap)[byteIdx] |= (1 << bit); - - // Compute block number - UInt32 blockNumber = byteIdx * 8 + bit; - - // Write bitmap back - if (!ext2_write_block(ctx->drive, groupDesc->fBlockBitmap, bitmap, blockSize)) { - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(kErrorDisk); - } - - // Update group descriptor free count - groupDesc->fFreeBlocksCount--; - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(blockNumber); - } - } - } - } - - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(kErrorDiskIsFull); -} - -// Indirect blocks -static ErrorOr<Void*> ext2_set_block_address(Ext2Context* ctx, Ext2Node* node, - UInt32 logicalBlockIndex, UInt32 physicalBlockNumber) { - using namespace Kernel; - - if (!ctx || !ctx->drive || !node) return ErrorOr<Void*>(kErrorInvalidData); - - auto blockSize = ctx->BlockSize(); - UInt32 blocksPerPointerBlock = blockSize / sizeof(UInt32); - - // Direct blocks - if (logicalBlockIndex < EXT2_DIRECT_BLOCKS) { - node->inode.fBlock[logicalBlockIndex] = physicalBlockNumber; - return ErrorOr<Void*>(nullptr); - } - - // Single indirect blocks - if (logicalBlockIndex < EXT2_DIRECT_BLOCKS + blocksPerPointerBlock) { - if (node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX] == 0) { - auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber); - if (groupInfoRes.HasError()) return ErrorOr<Void*>(groupInfoRes.Error()); - - auto groupInfo = groupInfoRes.Leak().Leak(); // Ref<Ext2GroupInfo*> - auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc); - if (newBlockRes.HasError()) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(newBlockRes.Error()); - } - - node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX] = newBlockRes.Leak(); - - UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - // Zero out new indirect block - auto zeroBuf = mm_alloc_ptr(blockSize, true, false); - if (!zeroBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory); - - rt_zero_memory(zeroBuf, blockSize); - UInt32 indirectLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]); - if (!ext2_write_block(ctx->drive, indirectLba, zeroBuf, blockSize)) { - mm_free_ptr(zeroBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(zeroBuf); - } - - // Read, modify, and write single indirect block - auto indirectRes = ext2_read_block_ptr(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]); - if (indirectRes.HasError()) return ErrorOr<Void*>(indirectRes.Error()); - - UInt32* indirectPtr = indirectRes.Leak().Leak(); // Ref<UInt32*> - indirectPtr[logicalBlockIndex - EXT2_DIRECT_BLOCKS] = physicalBlockNumber; - - UInt32 indirectLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_SINGLE_INDIRECT_INDEX]); - if (!ext2_write_block(ctx->drive, indirectLba, indirectPtr, blockSize)) { - mm_free_ptr(indirectPtr); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(indirectPtr); - return ErrorOr<Void*>(nullptr); - } - - // Double - UInt32 doubleStart = EXT2_DIRECT_BLOCKS + blocksPerPointerBlock; - UInt32 doubleSpan = blocksPerPointerBlock * blocksPerPointerBlock; - if (logicalBlockIndex < doubleStart + doubleSpan) { - if (node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX] == 0) { - auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber); - if (groupInfoRes.HasError()) return ErrorOr<Void*>(groupInfoRes.Error()); - - auto groupInfo = groupInfoRes.Leak().Leak(); - auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc); - if (newBlockRes.HasError()) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(newBlockRes.Error()); - } - - node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX] = newBlockRes.Leak(); - - UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - // Zero new double-indirect block - auto zeroBuf = mm_alloc_ptr(blockSize, true, false); - if (!zeroBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory); - - rt_zero_memory(zeroBuf, blockSize); - UInt32 dblLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]); - if (!ext2_write_block(ctx->drive, dblLba, zeroBuf, blockSize)) { - mm_free_ptr(zeroBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(zeroBuf); - } - - // Compute indices - UInt32 idxWithin = logicalBlockIndex - doubleStart; - UInt32 firstIdx = idxWithin / blocksPerPointerBlock; - UInt32 secondIdx = idxWithin % blocksPerPointerBlock; - - auto doubleRes = ext2_read_block_ptr(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]); - if (doubleRes.HasError()) return ErrorOr<Void*>(doubleRes.Error()); - - UInt32* doublePtr = doubleRes.Leak().Leak(); - UInt32 singleIndirectBlock = doublePtr[firstIdx]; - - // Allocate single-indirect if missing - if (singleIndirectBlock == 0) { - auto groupInfoRes = ext2_get_group_descriptor_info(ctx, node->inodeNumber); - if (groupInfoRes.HasError()) { - mm_free_ptr(doublePtr); - return ErrorOr<Void*>(groupInfoRes.Error()); - } - - auto groupInfo = groupInfoRes.Leak().Leak(); - auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc); - if (newBlockRes.HasError()) { - mm_free_ptr(doublePtr); - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(newBlockRes.Error()); - } - - singleIndirectBlock = newBlockRes.Leak(); - doublePtr[firstIdx] = singleIndirectBlock; - - // Write back GDT - UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) { - mm_free_ptr(doublePtr); - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - // Zero single-indirect block - auto zeroBuf = mm_alloc_ptr(blockSize, true, false); - if (!zeroBuf) { - mm_free_ptr(doublePtr); - return ErrorOr<Void*>(kErrorHeapOutOfMemory); - } - - rt_zero_memory(zeroBuf, blockSize); - UInt32 singleLba = ext2_block_to_lba(ctx, singleIndirectBlock); - if (!ext2_write_block(ctx->drive, singleLba, zeroBuf, blockSize)) { - mm_free_ptr(zeroBuf); - mm_free_ptr(doublePtr); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(zeroBuf); - - // Write double-indirect back to disk - UInt32 dblLba = ext2_block_to_lba(ctx, node->inode.fBlock[EXT2_DOUBLE_INDIRECT_INDEX]); - if (!ext2_write_block(ctx->drive, dblLba, doublePtr, blockSize)) { - mm_free_ptr(doublePtr); - return ErrorOr<Void*>(kErrorDisk); - } - } - - mm_free_ptr(doublePtr); - - // Write to single-indirect block - auto singleRes = ext2_read_block_ptr(ctx, singleIndirectBlock); - if (singleRes.HasError()) return ErrorOr<Void*>(singleRes.Error()); - - UInt32* singlePtr = singleRes.Leak().Leak(); - singlePtr[secondIdx] = physicalBlockNumber; - - UInt32 singleLba = ext2_block_to_lba(ctx, singleIndirectBlock); - if (!ext2_write_block(ctx->drive, singleLba, singlePtr, blockSize)) { - mm_free_ptr(singlePtr); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(singlePtr); - return ErrorOr<Void*>(nullptr); - } - - // Triple indirect blocks not implemented - return ErrorOr<Void*>(kErrorUnimplemented); -} - -// Find a directory entry by name within a directory inode -static ErrorOr<EXT2_DIR_ENTRY*> ext2_find_dir_entry(Ext2Context* ctx, Ext2Node* dirNode, - const char* name) { - if (!ctx || !ctx->drive || !dirNode || !name) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorInvalidData); - - // Check directory type - auto type = (dirNode->inode.fMode >> 12) & 0xF; - if (type != kExt2FileTypeDirectory) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - auto blockBuf = mm_alloc_ptr(blockSize, true, false); - if (!blockBuf) return ErrorOr<EXT2_DIR_ENTRY*>(kErrorHeapOutOfMemory); - - SizeT nameLen = rt_string_len(name); - for (UInt32 i = 0; i < EXT2_DIRECT_BLOCKS; ++i) { - UInt32 blockNum = dirNode->inode.fBlock[i]; - if (blockNum == 0) continue; - - UInt32 lba = ext2_block_to_lba(ctx, blockNum); - if (!ext2_read_block(ctx->drive, lba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return ErrorOr<EXT2_DIR_ENTRY*>(kErrorDisk); - } - - UInt32 offset = 0; - while (offset + sizeof(UInt32) + sizeof(UInt16) <= blockSize) { - auto onDiskEntry = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + offset); - if (onDiskEntry->fRecordLength == 0) break; // corrupted - - if (onDiskEntry->fInode != 0 && onDiskEntry->fNameLength == nameLen) { - // Compare names - if (rt_string_cmp(name, onDiskEntry->fName, nameLen) == 0) { - // Allocate a result sized to hold the name + metadata - SizeT recSize = sizeof(EXT2_DIR_ENTRY); - auto found = (EXT2_DIR_ENTRY*) mm_alloc_ptr(recSize, true, false); - if (!found) { - mm_free_ptr(blockBuf); - return ErrorOr<EXT2_DIR_ENTRY*>(kErrorHeapOutOfMemory); - } - - // Copy only record-length bytes - rt_copy_memory_safe(onDiskEntry, found, onDiskEntry->fRecordLength, recSize); - mm_free_ptr(blockBuf); - return ErrorOr<EXT2_DIR_ENTRY*>(found); - } - } - offset += onDiskEntry->fRecordLength; - } - } - - mm_free_ptr(blockBuf); - return ErrorOr<EXT2_DIR_ENTRY*>(kErrorFileNotFound); -} - -// Compute ideal record length for a directory name -static inline UInt16 ext2_dir_entry_ideal_len(UInt8 nameLen) { - UInt16 raw = - static_cast<UInt16>(8 + nameLen); // 8 = inode(4)+rec_len(2)+name_len(1)+file_type(1) - return static_cast<UInt16>((raw + 3) & ~3u); // align up to 4 -} - -static ErrorOr<Void*> ext2_add_dir_entry(Ext2Context* ctx, Ext2Node* parentDirNode, - const char* name, UInt32 inodeNumber, UInt8 fileType) { - using namespace Kernel; - - if (!ctx || !ctx->drive || !parentDirNode || !name) return ErrorOr<Void*>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - SizeT nameLen = rt_string_len(name); - if (nameLen == 0 || nameLen > 255) return ErrorOr<Void*>(kErrorInvalidData); - - UInt16 newRecIdeal = ext2_dir_entry_ideal_len(static_cast<UInt8>(nameLen)); - - auto blockBuf = mm_alloc_ptr(blockSize, true, false); - if (!blockBuf) return ErrorOr<Void*>(kErrorHeapOutOfMemory); - - for (UInt32 bi = 0; bi < EXT2_DIRECT_BLOCKS; ++bi) { - UInt32 blockNum = parentDirNode->inode.fBlock[bi]; - - if (blockNum == 0) { - // Allocate new block - auto groupInfoRes = ext2_get_group_descriptor_info(ctx, parentDirNode->inodeNumber); - if (!groupInfoRes) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(groupInfoRes.Error()); - } - - auto groupInfo = *groupInfoRes.Leak(); // Dereference to get Ext2GroupInfo* - auto allocBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc); - if (!allocBlockRes) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(allocBlockRes.Error()); - } - - UInt32 newBlock = *allocBlockRes.Leak(); // Dereference to get UInt32 - UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock); - - if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - // Zero block & insert entry - rt_zero_memory(blockBuf, blockSize); - auto entry = reinterpret_cast<EXT2_DIR_ENTRY*>(blockBuf); - entry->fInode = inodeNumber; - entry->fNameLength = static_cast<UInt8>(nameLen); - entry->fFileType = fileType; - entry->fRecordLength = static_cast<UInt16>(blockSize); - rt_copy_memory_safe(const_cast<char*>(name), entry->fName, nameLen, blockSize); - - UInt32 blockLba = ext2_block_to_lba(ctx, newBlock); - if (!ext2_write_block(ctx->drive, blockLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - auto setRes = ext2_set_block_address(ctx, parentDirNode, bi, newBlock); - if (!setRes) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(setRes.Error()); - } - - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(nullptr); - } - - // read it - UInt32 blockLba = ext2_block_to_lba(ctx, blockNum); - if (!ext2_read_block(ctx->drive, blockLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - UInt32 offset = 0; - EXT2_DIR_ENTRY* lastEntry = nullptr; - UInt32 lastOffset = 0; - - while (offset < blockSize) { - if (offset + 8 > blockSize) break; - auto e = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + offset); - if (e->fRecordLength == 0) break; - lastEntry = e; - lastOffset = offset; - offset += e->fRecordLength; - } - - if (!lastEntry) continue; - - UInt16 lastIdeal = ext2_dir_entry_ideal_len(lastEntry->fNameLength); - - if (lastEntry->fRecordLength >= (UInt16) (lastIdeal + newRecIdeal)) { - UInt16 origRec = lastEntry->fRecordLength; - lastEntry->fRecordLength = lastIdeal; - - UInt32 newOffset = lastOffset + lastIdeal; - auto newEntry = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) blockBuf + newOffset); - newEntry->fInode = inodeNumber; - newEntry->fNameLength = static_cast<UInt8>(nameLen); - newEntry->fFileType = fileType; - newEntry->fRecordLength = static_cast<UInt16>(origRec - lastIdeal); - rt_copy_memory_safe(const_cast<char*>(name), newEntry->fName, nameLen, - newEntry->fRecordLength); - - if (!ext2_write_block(ctx->drive, blockLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(nullptr); - } - } - - // No space in direct blocks -> allocate new block - int targetIndex = -1; - for (UInt32 i = 0; i < EXT2_DIRECT_BLOCKS; ++i) { - if (parentDirNode->inode.fBlock[i] == 0) { - targetIndex = i; - break; - } - } - if (targetIndex == -1) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorUnimplemented); - } - - auto groupInfoResult = ext2_get_group_descriptor_info(ctx, parentDirNode->inodeNumber); - if (!groupInfoResult) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(groupInfoResult.Error()); - } - - auto groupInfo = *groupInfoResult.Leak(); // Dereference to get Ext2GroupInfo* - auto newBlockRes = ext2_alloc_block(ctx, groupInfo->groupDesc); - if (!newBlockRes) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(newBlockRes.Error()); - } - - UInt32 newBlockNum = *newBlockRes.Leak(); // Dereference to get UInt32 - UInt32 gdtLba = ext2_block_to_lba(ctx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(ctx->drive, gdtLba, groupInfo->blockBuffer, blockSize)) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - rt_zero_memory(blockBuf, blockSize); - auto entry = reinterpret_cast<EXT2_DIR_ENTRY*>(blockBuf); - entry->fInode = inodeNumber; - entry->fNameLength = static_cast<UInt8>(nameLen); - entry->fFileType = fileType; - entry->fRecordLength = static_cast<UInt16>(blockSize); - rt_copy_memory_safe(const_cast<char*>(name), entry->fName, nameLen, blockSize); - - UInt32 newBlockLba = ext2_block_to_lba(ctx, newBlockNum); - if (!ext2_write_block(ctx->drive, newBlockLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(kErrorDisk); - } - - auto setRes = ext2_set_block_address(ctx, parentDirNode, targetIndex, newBlockNum); - if (!setRes) { - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(setRes.Error()); - } - - mm_free_ptr(blockBuf); - return ErrorOr<Void*>(nullptr); -} - -// Soon -static ErrorOr<UInt32> ext2_alloc_inode(Ext2Context* ctx, EXT2_GROUP_DESCRIPTOR* groupDesc) { - if (!ctx || !ctx->superblock || !groupDesc) return ErrorOr<UInt32>(kErrorInvalidData); - - UInt32 blockSize = ctx->BlockSize(); - - // buffer for the inode bitmap - auto bitmap = mm_alloc_ptr(blockSize, true, false); - if (!bitmap) return ErrorOr<UInt32>(kErrorHeapOutOfMemory); - - // Read inode bitmap - if (!ext2_read_block(ctx->drive, groupDesc->fInodeBitmap, bitmap, blockSize)) { - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(kErrorDisk); - } - - // Find first free inode (bit = 0) - for (UInt32 byteIdx = 0; byteIdx < blockSize; ++byteIdx) { - auto byte = reinterpret_cast<unsigned char*>(bitmap)[byteIdx]; - if (byte != 0xFF) { - for (int bit = 0; bit < 8; ++bit) { - if (!(byte & (1 << bit))) { - // Mark bit as used - reinterpret_cast<unsigned char*>(bitmap)[byteIdx] |= (1 << bit); - - // Compute inode number - UInt32 inodeNumber = byteIdx * 8 + bit + 1; // Inodes are 1-based - - // Write bitmap back - if (!ext2_write_block(ctx->drive, groupDesc->fInodeBitmap, bitmap, blockSize)) { - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(kErrorDisk); - } - - // Update group descriptor free count - groupDesc->fFreeInodesCount--; - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(inodeNumber); - } - } - } - } - - mm_free_ptr(bitmap); - return ErrorOr<UInt32>(kErrorDiskIsFull); -} - -// to write an inode to its correct location on disk -static ErrorOr<Void*> ext2_write_inode(Ext2Context* ctx, Ext2Node* node) { - using namespace Kernel; - - if (!ctx || !ctx->superblock || !ctx->drive || !node) return ErrorOr<Void*>(kErrorInvalidData); - - auto blockSize = ctx->BlockSize(); - UInt32 inodesPerGroup = ctx->superblock->fInodesPerGroup; - - if (inodesPerGroup == 0) return ErrorOr<Void*>(kErrorInvalidData); - - // Calculate which group this inode belongs to - UInt32 groupIndex = (node->inodeNumber - 1) / inodesPerGroup; - NE_UNUSED(groupIndex); - UInt32 inodeIndexInGroup = (node->inodeNumber - 1) % inodesPerGroup; - - // Get group descriptor - auto groupInfoResult = ext2_get_group_descriptor_info(ctx, node->inodeNumber); - if (!groupInfoResult) return ErrorOr<Void*>(groupInfoResult.Error()); - - auto groupInfo = *groupInfoResult.Leak(); // Dereference to get Ext2GroupInfo* - - // Calculate inode table position - UInt32 inodeTableBlock = groupInfo->groupDesc->fInodeTable; - UInt32 inodeSize = ctx->superblock->fInodeSize; - UInt32 inodesPerBlock = blockSize / inodeSize; - - UInt32 blockOffset = inodeIndexInGroup / inodesPerBlock; - UInt32 offsetInBlock = (inodeIndexInGroup % inodesPerBlock) * inodeSize; - - UInt32 inodeBlock = inodeTableBlock + blockOffset; - UInt32 inodeLba = ext2_block_to_lba(ctx, inodeBlock); - - // Read the block containing the inode - auto blockBuf = mm_alloc_ptr(blockSize, true, false); - if (!blockBuf) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(kErrorHeapOutOfMemory); - } - - if (!ext2_read_block(ctx->drive, inodeLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(kErrorDisk); - } - - // Copy the updated inode into the block buffer - rt_copy_memory_safe(&node->inode, static_cast<void*>((UInt8*) blockBuf + offsetInBlock), - sizeof(EXT2_INODE), blockSize - offsetInBlock); - - // Write the block back - if (!ext2_write_block(ctx->drive, inodeLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return ErrorOr<Void*>(kErrorDisk); - } - - mm_free_ptr(blockBuf); - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - return ErrorOr<Void*>(nullptr); -} - -namespace { -// new -struct PathComponents { - const char** components; - int count; - Char* buffer; - - PathComponents(const char* path) : components(nullptr), count(0), buffer(nullptr) { - if (!path || *path == '\0') return; - - SizeT pathLen = rt_string_len(path); - buffer = (Char*) mm_alloc_ptr(pathLen + 1, true, false); - if (!buffer) return; - - rt_copy_memory_safe((void*) path, buffer, pathLen, pathLen + 1); - buffer[pathLen] = '\0'; - - // temp array - const char** temp = (const char**) mm_alloc_ptr(sizeof(char*) * (pathLen + 1), true, false); - if (!temp) { - mm_free_ptr(buffer); - buffer = nullptr; - return; - } - - UInt32 compCount = 0; - Char* p = buffer; - - while (*p != '\0') { - // skip slashes - while (*p == '/') p++; - if (*p == '\0') break; - - Char* start = p; - while (*p != '/' && *p != '\0') p++; - Char saved = *p; - *p = '\0'; - - // handle ".", "..", or normal - if (rt_string_cmp(start, ".", 1) == 0) { - // ignore - } else if (rt_string_cmp(start, "..", 2) == 0) { - if (compCount > 0) compCount--; // go up one level - } else { - temp[compCount++] = start; - } - - *p = saved; - } - - if (compCount == 0) { - mm_free_ptr(temp); - return; - } - - components = (const char**) mm_alloc_ptr(sizeof(char*) * compCount, true, false); - if (!components) { - mm_free_ptr(temp); - return; - } - - for (UInt32 i = 0; i < compCount; i++) components[i] = temp[i]; - count = compCount; - - mm_free_ptr(temp); - } - - ~PathComponents() { - if (components) mm_free_ptr(components); - if (buffer) mm_free_ptr(buffer); - } -}; -} // anonymous namespace - -// The Ext2FileSystemParser (not manager!) -Ext2FileSystemParser::Ext2FileSystemParser(DriveTrait* drive) : fCtx(drive) { - MUST_PASS(fCtx); -} - -NodePtr Ext2FileSystemParser::Open(const char* path, const char* restrict_type) { - NE_UNUSED(restrict_type); - if (!path || *path == '\0' || !this->fCtx.drive) { - return nullptr; - } - - // Root ("/") - if (rt_string_len(path) == 1 && rt_string_cmp(path, "/", 1) == 0) { - auto inodeResult = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE); - if (!inodeResult) { - return nullptr; - } - - auto heapNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false); - if (!heapNode) return nullptr; - - *heapNode = *inodeResult.Leak().Leak(); - heapNode->cursor = 0; - return reinterpret_cast<NodePtr>(heapNode); - } - - PathComponents pathComponents(path); - if (pathComponents.count == 0) { - return nullptr; - } - - UInt32 currentInodeNumber = EXT2_ROOT_INODE; - Ext2Node* currentDirNode = nullptr; - - for (UInt32 i = 0; i < (UInt32) pathComponents.count; ++i) { - auto inodeResult = ext2_load_inode(&this->fCtx, currentInodeNumber); - if (!inodeResult) { - if (currentDirNode) mm_free_ptr(currentDirNode); - return nullptr; - } - - if (currentDirNode) { - mm_free_ptr(currentDirNode); - currentDirNode = nullptr; - } - - currentDirNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false); - if (!currentDirNode) { - return nullptr; - } - - *currentDirNode = *inodeResult.Leak().Leak(); - currentDirNode->cursor = 0; - - if (i < pathComponents.count - 1U) { - UInt32 type = (currentDirNode->inode.fMode >> 12) & 0xF; - if (type != kExt2FileTypeDirectory) { - mm_free_ptr(currentDirNode); - return nullptr; - } - } - - auto dirEntryResult = - ext2_find_dir_entry(&this->fCtx, currentDirNode, pathComponents.components[i]); - if (!dirEntryResult) { - mm_free_ptr(currentDirNode); - return nullptr; - } - - EXT2_DIR_ENTRY* entryPtr = *dirEntryResult.Leak(); - currentInodeNumber = entryPtr->fInode; - mm_free_ptr(entryPtr); - } - - auto finalInodeResult = ext2_load_inode(&this->fCtx, currentInodeNumber); - if (!finalInodeResult) { - if (currentDirNode) mm_free_ptr(currentDirNode); - return nullptr; - } - - if (currentDirNode) { - mm_free_ptr(currentDirNode); - } - - auto resultNode = (Ext2Node*) mm_alloc_ptr(sizeof(Ext2Node), true, false); - if (!resultNode) { - return nullptr; - } - - *resultNode = *finalInodeResult.Leak().Leak(); - resultNode->cursor = 0; - return reinterpret_cast<NodePtr>(resultNode); -} - -void* Ext2FileSystemParser::Read(NodePtr node, Int32 flags, SizeT size) { - if (!node) return nullptr; - - NE_UNUSED(flags); - - auto extNode = reinterpret_cast<Ext2Node*>(node); - auto dataResult = ext2_read_inode_data(&this->fCtx, extNode, size); - - if (!dataResult) { - return nullptr; // error, nothing to return - } - - void* data = *dataResult.Leak(); - if (data) { - extNode->cursor += static_cast<UInt32>(size); - } - - return data; -} - -void Ext2FileSystemParser::Write(NodePtr node, void* data, Int32 flags, SizeT size) { - if (!node || !data || size == 0) return; - - NE_UNUSED(flags); - - auto extNode = reinterpret_cast<Ext2Node*>(node); - auto blockSize = this->fCtx.BlockSize(); - SizeT bytesWritten = 0; - - UInt32 currentOffset = extNode->cursor; - UInt8* src = reinterpret_cast<UInt8*>(data); - - while (bytesWritten < size) { - UInt32 logicalBlockIndex = currentOffset / blockSize; - UInt32 offsetInBlock = currentOffset % blockSize; - - auto physBlockResult = ext2_get_block_address(&this->fCtx, extNode, logicalBlockIndex); - UInt32 physicalBlock = 0; - - if (!physBlockResult) { - auto err = physBlockResult.Error(); - if (err == kErrorInvalidData || err == kErrorUnimplemented) { - auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, extNode->inodeNumber); - if (!groupInfoResult) { - return; - } - - auto groupInfo = *groupInfoResult.Leak(); - auto allocResult = ext2_alloc_block(&this->fCtx, groupInfo->groupDesc); - if (!allocResult) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return; - } - - physicalBlock = *allocResult.Leak(); - - auto setRes = - ext2_set_block_address(&this->fCtx, extNode, logicalBlockIndex, physicalBlock); - if (!setRes) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return; - } - - UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, blockSize)) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - return; - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - } else { - return; - } - } else { - physicalBlock = physBlockResult.Value(); - } - - UInt32 physicalLba = ext2_block_to_lba(&this->fCtx, physicalBlock); - - auto blockBuf = mm_alloc_ptr(blockSize, true, false); - if (!blockBuf) return; - - if (offsetInBlock > 0 || (size - bytesWritten) < blockSize) { - if (!ext2_read_block(this->fCtx.drive, physicalLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return; - } - } else { - rt_zero_memory(blockBuf, blockSize); - } - - UInt32 bytesInCurrentBlock = - static_cast<UInt32>(ext2_min(size - bytesWritten, blockSize - offsetInBlock)); - rt_copy_memory_safe(src, static_cast<void*>((UInt8*) blockBuf + offsetInBlock), - bytesInCurrentBlock, blockSize - offsetInBlock); - - if (!ext2_write_block(this->fCtx.drive, physicalLba, blockBuf, blockSize)) { - mm_free_ptr(blockBuf); - return; - } - - mm_free_ptr(blockBuf); - - currentOffset += bytesInCurrentBlock; - src += bytesInCurrentBlock; - bytesWritten += bytesInCurrentBlock; - } - - if (currentOffset > extNode->inode.fSize) { - extNode->inode.fSize = currentOffset; - } - - extNode->inode.fBlocks = (extNode->inode.fSize + blockSize - 1) / blockSize; - extNode->inode.fModifyTime = 0; - - auto writeInodeRes = ext2_write_inode(&this->fCtx, extNode); - if (!writeInodeRes) { - // Failed to persist inode - } - - extNode->cursor = currentOffset; -} - -bool Ext2FileSystemParser::Seek(NodePtr node, SizeT offset) { - if (!node) return false; - auto extNode = reinterpret_cast<Ext2Node*>(node); - extNode->cursor = static_cast<UInt32>(offset); - return true; -} - -SizeT Ext2FileSystemParser::Tell(NodePtr node) { - if (!node) return 0; - auto extNode = reinterpret_cast<Ext2Node*>(node); - return extNode->cursor; -} - -bool Ext2FileSystemParser::Rewind(NodePtr node) { - if (!node) return false; - auto extNode = reinterpret_cast<Ext2Node*>(node); - extNode->cursor = 0; - return true; -} - -void* Ext2FileSystemParser::Read(const char* name, NodePtr node, Int32 flags, SizeT size) { - NE_UNUSED(name); - return Read(node, flags, size); -} - -void Ext2FileSystemParser::Write(const char* name, NodePtr node, void* data, Int32 flags, - SizeT size) { - NE_UNUSED(name); - Write(node, data, flags, size); -} - -NodePtr Ext2FileSystemParser::Create(const char* path) { - if (!path || *path == '\0') return nullptr; - - PathComponents pathComponents(path); - if (pathComponents.count == 0) return nullptr; - - const char* filename = pathComponents.components[pathComponents.count - 1]; - if (rt_string_len(filename) > kExt2FSMaxFileNameLen) return nullptr; - - // Build parent path - Char parentPathBuf[256] = {0}; - SizeT currentPathLen = 0; - for (UInt32 i = 0; (i < pathComponents.count - 1U); ++i) { - SizeT componentLen = rt_string_len(pathComponents.components[i]); - if (currentPathLen + componentLen + 1 >= sizeof(parentPathBuf)) return nullptr; - if (i > 0) parentPathBuf[currentPathLen++] = '/'; - rt_copy_memory_safe(const_cast<char*>(pathComponents.components[i]), - parentPathBuf + currentPathLen, componentLen, - sizeof(parentPathBuf) - currentPathLen); - currentPathLen += componentLen; - } - parentPathBuf[currentPathLen] = '\0'; - - // Open parent directory - NodePtr parentDirNodePtr = nullptr; - if (currentPathLen == 0) { - // root - auto inodeRes = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE); - if (!inodeRes) return nullptr; - parentDirNodePtr = mm_alloc_ptr(sizeof(Ext2Node), true, false); - if (!parentDirNodePtr) return nullptr; - *reinterpret_cast<Ext2Node*>(parentDirNodePtr) = *inodeRes.Leak().Leak(); - reinterpret_cast<Ext2Node*>(parentDirNodePtr)->cursor = 0; - } else { - parentDirNodePtr = Open(parentPathBuf, "r"); - } - - if (!parentDirNodePtr) return nullptr; - - auto parentDirNode = reinterpret_cast<Ext2Node*>(parentDirNodePtr); - - // Ensure parent is a directory - UInt32 type = (parentDirNode->inode.fMode >> 12) & 0xF; - if (type != kExt2FileTypeDirectory) { - mm_free_ptr(parentDirNode); - return nullptr; - } - - // Get group info for allocation - auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, parentDirNode->inodeNumber); - if (!groupInfoResult) { - mm_free_ptr(parentDirNode); - return nullptr; - } - auto groupInfo = *groupInfoResult.Leak(); - - // Allocate new inode - auto newInodeRes = ext2_alloc_inode(&this->fCtx, groupInfo->groupDesc); - if (!newInodeRes) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); // so this works - mm_free_ptr(parentDirNode); - return nullptr; - } - UInt32 newInodeNumber = newInodeRes.Value(); - - UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, this->fCtx.BlockSize())) { - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(parentDirNode); - return nullptr; - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - // Create new Ext2Node - Ext2Node* newFileNode = reinterpret_cast<Ext2Node*>(mm_alloc_ptr(sizeof(Ext2Node), true, false)); - if (!newFileNode) { - mm_free_ptr(parentDirNode); - return nullptr; - } - - newFileNode->inodeNumber = newInodeNumber; - rt_zero_memory(&newFileNode->inode, sizeof(EXT2_INODE)); - - newFileNode->inode.fMode = (kExt2FileTypeRegular << 12); - newFileNode->inode.fUID = 0; - newFileNode->inode.fGID = 0; - newFileNode->inode.fLinksCount = 1; - newFileNode->inode.fSize = 0; - newFileNode->inode.fBlocks = 0; - newFileNode->inode.fCreateTime = 0; - newFileNode->inode.fModifyTime = 0; - - // Persist new inode - auto writeInodeRes = ext2_write_inode(&this->fCtx, newFileNode); - if (!writeInodeRes) { - mm_free_ptr(parentDirNode); - mm_free_ptr(newFileNode); - return nullptr; - } - - // Add directory entry - auto addRes = ext2_add_dir_entry(&this->fCtx, parentDirNode, filename, newInodeNumber, - kExt2FileTypeRegular); - if (!addRes) { - mm_free_ptr(parentDirNode); - mm_free_ptr(newFileNode); - return nullptr; - } - - // Update parent inode - auto parentWriteRes = ext2_write_inode(&this->fCtx, parentDirNode); - // ignore failure - - NE_UNUSED(parentWriteRes); - - mm_free_ptr(parentDirNode); - return reinterpret_cast<NodePtr>(newFileNode); -} - -NodePtr Ext2FileSystemParser::CreateDirectory(const char* path) { - if (!path || *path == '\0') return nullptr; - - PathComponents pathComponents(path); - if (pathComponents.count == 0) { - kout << "EXT2: Failed to parse path for CreateDirectory.\n"; - return nullptr; - } - - const char* dirname = pathComponents.components[pathComponents.count - 1]; - if (rt_string_len(dirname) > kExt2FSMaxFileNameLen) { - kout << "EXT2: Directory name too long: " << dirname << ".\n"; - return nullptr; - } - - // Build parent path - Char parentPathBuf[256]; - SizeT currentPathLen = 0; - for (UInt32 i = 0; (i < pathComponents.count - 1U); ++i) { - SizeT componentLen = rt_string_len(pathComponents.components[i]); - if (currentPathLen + componentLen + 1 >= sizeof(parentPathBuf)) { - kout << "EXT2: Parent path too long for CreateDirectory.\n"; - return nullptr; - } - - if (i > 0) parentPathBuf[currentPathLen++] = '/'; - - rt_copy_memory_safe(static_cast<void*>(const_cast<char*>(pathComponents.components[i])), - static_cast<void*>(parentPathBuf + currentPathLen), componentLen, - sizeof(parentPathBuf) - currentPathLen); - currentPathLen += componentLen; - } - - parentPathBuf[currentPathLen] = '\0'; - - // Open parent directory node - NodePtr parentDirNodePtr = nullptr; - if (currentPathLen == 0) { - auto inodeRes = ext2_load_inode(&this->fCtx, EXT2_ROOT_INODE); - if (!inodeRes) { - return nullptr; - } - - parentDirNodePtr = reinterpret_cast<NodePtr>(mm_alloc_ptr(sizeof(Ext2Node), true, false)); - if (!parentDirNodePtr) return nullptr; - - *reinterpret_cast<Ext2Node*>(parentDirNodePtr) = *inodeRes.Leak().Leak(); - reinterpret_cast<Ext2Node*>(parentDirNodePtr)->cursor = 0; - } else { - parentDirNodePtr = Open(parentPathBuf, "r"); - } - - if (!parentDirNodePtr) { - kout << "EXT2: Failed to open parent directory for CreateDirectory: " << parentPathBuf << ".\n"; - return nullptr; - } - - auto parentDirNode = reinterpret_cast<Ext2Node*>(parentDirNodePtr); - - // Check parent is a directory - UInt32 parentType = (parentDirNode->inode.fMode >> 12) & 0xF; - if (parentType != kExt2FileTypeDirectory) { - kout << "EXT2: Parent is not a directory: " << parentPathBuf << ".\n"; - mm_free_ptr(parentDirNode); - return nullptr; - } - - // Allocate inode - auto groupInfoResult = ext2_get_group_descriptor_info(&this->fCtx, parentDirNode->inodeNumber); - if (!groupInfoResult) { - kout << "EXT2: Failed to get group descriptor info for new dir inode.\n"; - mm_free_ptr(parentDirNode); - return nullptr; - } - - auto groupInfo = *groupInfoResult.Leak(); - auto newInodeRes = ext2_alloc_inode(&this->fCtx, groupInfo->groupDesc); - if (!newInodeRes) { - kout << "EXT2: Failed to allocate inode for new directory.\n"; - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(parentDirNode); - return nullptr; - } - - UInt32 newInodeNumber = *newInodeRes.Leak(); - - // Write back group descriptor block - UInt32 gdtLba = ext2_block_to_lba(&this->fCtx, groupInfo->groupDescriptorBlock); - if (!ext2_write_block(this->fCtx.drive, gdtLba, groupInfo->blockBuffer, this->fCtx.BlockSize())) { - kout << "EXT2: Failed to write group descriptor after inode allocation.\n"; - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - mm_free_ptr(parentDirNode); - return nullptr; - } - - mm_free_ptr(reinterpret_cast<void*>(groupInfo->blockBuffer)); - mm_free_ptr(groupInfo); - - // Create new Ext2Node and initialize inode fields - Ext2Node* newDirNode = reinterpret_cast<Ext2Node*>(mm_alloc_ptr(sizeof(Ext2Node), true, false)); - if (!newDirNode) { - kout << "EXT2: Out of memory for new directory node.\n"; - mm_free_ptr(parentDirNode); - return nullptr; - } - - newDirNode->inodeNumber = newInodeNumber; - rt_zero_memory(&newDirNode->inode, sizeof(EXT2_INODE)); - newDirNode->inode.fMode = (kExt2FileTypeDirectory << 12); - newDirNode->inode.fUID = 0; - newDirNode->inode.fGID = 0; - newDirNode->inode.fLinksCount = 2; // . and .. - newDirNode->inode.fSize = this->fCtx.BlockSize(); - newDirNode->inode.fBlocks = 1; - newDirNode->inode.fCreateTime = 0; - newDirNode->inode.fModifyTime = 0; - - // Allocate a data block for the new directory - auto groupForBlockRes = ext2_get_group_descriptor_info(&this->fCtx, newDirNode->inodeNumber); - if (!groupForBlockRes) { - kout << "EXT2: Failed to get group info for directory block allocation.\n"; - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - auto groupForBlock = *groupForBlockRes.Leak(); - auto newBlockRes = ext2_alloc_block(&this->fCtx, groupForBlock->groupDesc); - if (!newBlockRes) { - kout << "EXT2: Failed to allocate block for new directory contents.\n"; - mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer)); - mm_free_ptr(groupForBlock); - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - UInt32 newDirBlockNum = *newBlockRes.Leak(); - - // Write back GDT - UInt32 gdtLba2 = ext2_block_to_lba(&this->fCtx, groupForBlock->groupDescriptorBlock); - if (!ext2_write_block(this->fCtx.drive, gdtLba2, groupForBlock->blockBuffer, - this->fCtx.BlockSize())) { - kout << "EXT2: Failed to write GDT after directory block allocation.\n"; - mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer)); - mm_free_ptr(groupForBlock); - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - mm_free_ptr(reinterpret_cast<void*>(groupForBlock->blockBuffer)); - mm_free_ptr(groupForBlock); - - // Set the block in newDirNode - auto setBlkRes = ext2_set_block_address(&this->fCtx, newDirNode, 0, newDirBlockNum); - if (!setBlkRes) { - kout << "EXT2: Failed to set data block for new directory.\n"; - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - // Prepare block with '.' and '..' - auto dirBlockBuf = mm_alloc_ptr(this->fCtx.BlockSize(), true, false); - if (!dirBlockBuf) { - kout << "EXT2: Out of memory preparing directory block.\n"; - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - rt_zero_memory(dirBlockBuf, this->fCtx.BlockSize()); - - // '.' entry - auto dot = reinterpret_cast<EXT2_DIR_ENTRY*>(dirBlockBuf); - dot->fInode = newInodeNumber; - dot->fNameLength = 1; - dot->fFileType = kExt2FileTypeDirectory; - dot->fRecordLength = ext2_dir_entry_ideal_len(dot->fNameLength); - dot->fName[0] = '.'; - - // '..' entry occupies rest of block - auto dotdot = reinterpret_cast<EXT2_DIR_ENTRY*>((UInt8*) dirBlockBuf + dot->fRecordLength); - dotdot->fInode = parentDirNode->inodeNumber; - dotdot->fNameLength = 2; - dotdot->fFileType = kExt2FileTypeDirectory; - dotdot->fRecordLength = static_cast<UInt16>(this->fCtx.BlockSize() - dot->fRecordLength); - dotdot->fName[0] = '.'; - dotdot->fName[1] = '.'; - - // Write dir block to disk - UInt32 newDirBlockLba = ext2_block_to_lba(&this->fCtx, newDirBlockNum); - if (!ext2_write_block(this->fCtx.drive, newDirBlockLba, dirBlockBuf, this->fCtx.BlockSize())) { - kout << "EXT2: Failed to write directory block to disk.\n"; - mm_free_ptr(dirBlockBuf); - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - mm_free_ptr(dirBlockBuf); - - // Persist new directory inode - auto writeInodeRes = ext2_write_inode(&this->fCtx, newDirNode); - if (!writeInodeRes) { - kout << "EXT2: Failed to write new directory inode to disk.\n"; - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - // Add directory entry into parent - auto addRes = ext2_add_dir_entry(&this->fCtx, parentDirNode, dirname, newInodeNumber, - kExt2FileTypeDirectory); - if (!addRes) { - kout << "EXT2: Failed to add directory entry for '" << dirname << "' to parent.\n"; - mm_free_ptr(parentDirNode); - mm_free_ptr(newDirNode); - return nullptr; - } - - // Increment parent link count and persist parent inode - parentDirNode->inode.fLinksCount += 1; - auto parentWriteRes = ext2_write_inode(&this->fCtx, parentDirNode); - if (!parentWriteRes) { - kout << "EXT2: Warning: failed to update parent inode after directory creation.\n"; - } - - mm_free_ptr(parentDirNode); - return reinterpret_cast<NodePtr>(newDirNode); -} - -#endif -#endif diff --git a/dev/kernel/src/FS/NeFS+FileMgr.cc b/dev/kernel/src/FS/NeFS+FileMgr.cc deleted file mode 100644 index 0fdabd6f..00000000 --- a/dev/kernel/src/FS/NeFS+FileMgr.cc +++ /dev/null @@ -1,276 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __NE_MINIMAL_OS__ -#ifdef __FSKIT_INCLUDES_NEFS__ - -#include <KernelKit/FileMgr.h> -#include <KernelKit/HeapMgr.h> - -/// @brief NeFS File System Manager. -/// BUGS: 0 - -namespace Kernel { -static inline bool is_valid_nefs_catalog(NodePtr node); - -/// @brief C++ constructor -NeFileSystemMgr::NeFileSystemMgr() { - mParser = new NeFileSystemParser(); - MUST_PASS(mParser); - - kout << "We are done allocating NeFileSystemParser...\n"; -} - -NeFileSystemMgr::~NeFileSystemMgr() { - if (mParser) { - kout << "Destroying NeFileSystemParser...\n"; - delete mParser; - mParser = nullptr; - } -} - -/// @brief Removes a node from the filesystem. -/// @param path The filename -/// @return If it was deleted or not. -bool NeFileSystemMgr::Remove(_Input const Char* path) { - if (path == nullptr || *path == 0) { - kout << "NeFS: Remove called with null or empty path\n"; - return false; - } - return mParser->RemoveCatalog(path); -} - -/// @brief Creates a node with the specified. -/// @param path The filename path. -/// @return The Node pointer. -NodePtr NeFileSystemMgr::Create(_Input const Char* path) { - if (!path || *path == 0) { - kout << "NeFS: Create called with null or empty path\n"; - return nullptr; - } - return rtl_node_cast(mParser->CreateCatalog(path)); -} - -/// @brief Creates a node which is a directory. -/// @param path The filename path. -/// @return The Node pointer. -NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) { - if (!path || *path == 0) { - kout << "NeFS: CreateDirectory called with null or empty path\n"; - return nullptr; - } - return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir)); -} - -/// @brief Creates a node which is an alias. -/// @param path The filename path. -/// @return The Node pointer. -NodePtr NeFileSystemMgr::CreateAlias(const Char* path) { - if (!path || *path == 0) { - kout << "NeFS: CreateAlias called with null or empty path\n"; - return nullptr; - } - return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); -} - -NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) { - if (!path || *path == 0) { - kout << "NeFS: CreateSwapFile called with null or empty path\n"; - return nullptr; - } - return rtl_node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindPage)); -} - -/// @brief Gets the root directory. -/// @return -const Char* NeFileSystemHelper::Root() { - return kNeFSRoot; -} - -/// @brief Gets the up-dir directory. -/// @return -const Char* NeFileSystemHelper::UpDir() { - return kNeFSUpDir; -} - -/// @brief Gets the separator character. -/// @return -Char NeFileSystemHelper::Separator() { - return kNeFSSeparator; -} - -/// @brief Gets the metafile character. -/// @return -Char NeFileSystemHelper::MetaFile() { - return kNeFSMetaFilePrefix; -} - -/// @brief Opens a new file. -/// @param path -/// @param r -/// @return -_Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) { - if (!path || *path == 0) { - kout << "NeFS: Open called with null or empty path\n"; - return nullptr; - } - if (!r || *r == 0) { - kout << "NeFS: Open called with null or empty mode string\n"; - return nullptr; - } - auto catalog = mParser->GetCatalog(path); - if (!catalog) { - kout << "NeFS: Open could not find catalog for path\n"; - return nullptr; - } - return rtl_node_cast(catalog); -} - -Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT size) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Write called with invalid node pointer\n"; - return; - } - if (!data) { - kout << "NeFS: Write called with null data pointer\n"; - return; - } - if (!size || size > kNeFSForkSize) { - (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size)); - kout << "\n"; - return; - } - constexpr auto kDataForkName = kNeFSDataFork; - this->Write(kDataForkName, node, data, flags, size); -} - -_Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Read called with invalid node pointer\n"; - return nullptr; - } - if (!size || size > kNeFSForkSize) { - (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size)); - kout << "\n"; - return nullptr; - } - constexpr auto kDataForkName = kNeFSDataFork; - return this->Read(kDataForkName, node, flags, size); -} - -Void NeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, - _Input Int32 flags, _Input SizeT size) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Write(fork) called with invalid node pointer\n"; - return; - } - if (!name || *name == 0) { - kout << "NeFS: Write(fork) called with null or empty fork name\n"; - return; - } - if (!data) { - kout << "NeFS: Write(fork) called with null data pointer\n"; - return; - } - if (!size || size > kNeFSForkSize) { - (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(size)); - kout << "\n"; - return; - } - NE_UNUSED(flags); - auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node); - if (cat->Kind == kNeFSCatalogKindFile) { - mParser->WriteCatalog(cat->Name, (flags & kFileFlagRsrc ? true : false), data, size, name); - } -} - -_Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr node, - _Input Int32 flags, _Input SizeT sz) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Read(fork) called with invalid node pointer\n"; - return nullptr; - } - if (!name || *name == 0) { - kout << "NeFS: Read(fork) called with null or empty fork name\n"; - return nullptr; - } - if (!sz || sz > kNeFSForkSize) { - (Void)(kout << "NeFS: Write called with invalid size: " << hex_number(sz)); - kout << "\n"; - return nullptr; - } - NE_UNUSED(flags); - auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node); - if (cat->Kind == kNeFSCatalogKindFile) { - return mParser->ReadCatalog(cat, (flags & kFileFlagRsrc ? true : false), sz, name); - } - return nullptr; -} - -_Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Seek called with invalid node pointer\n"; - return false; - } - // Allow off == 0 - return mParser->Seek(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node), off); -} - -/// @brief Tell current offset within catalog. -/// @param node -/// @return kFileMgrNPos if invalid, else current offset. -_Output SizeT NeFileSystemMgr::Tell(NodePtr node) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Tell called with invalid node pointer\n"; - return kFileMgrNPos; - } - return mParser->Tell(reinterpret_cast<NEFS_CATALOG_STRUCT*>(node)); -} - -/// @brief Rewinds the catalog -/// @param node -/// @return False if invalid, nah? calls Seek(node, 0). -_Output Bool NeFileSystemMgr::Rewind(NodePtr node) { - if (!is_valid_nefs_catalog(node)) { - kout << "NeFS: Rewind called with invalid node pointer\n"; - return false; - } - return this->Seek(node, 0); -} - -/// @brief Returns the parser of NeFS. -_Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept { - return mParser; -} - -static inline bool is_valid_nefs_catalog(NodePtr node) { - if (!node) return false; - auto cat = reinterpret_cast<NEFS_CATALOG_STRUCT*>(node); - switch (cat->Kind) { - case kNeFSCatalogKindFile: - case kNeFSCatalogKindDir: - case kNeFSCatalogKindAlias: - case kNeFSCatalogKindPage: - break; - default: - return false; - } - bool null_found = false; - for (int i = 0; i < kNeFSCatalogNameLen; ++i) { - if (cat->Name[i] == 0) { - null_found = true; - break; - } - } - if (!null_found) return false; - return true; -} - -} // namespace Kernel - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ -#endif // ifndef __NE_MINIMAL_OS__ diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc deleted file mode 100644 index bfb8d63a..00000000 --- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc +++ /dev/null @@ -1,870 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifdef __FSKIT_INCLUDES_NEFS__ - -#include <FSKit/NeFS.h> -#include <FirmwareKit/EPM.h> - -#include <KernelKit/DriveMgr.h> -#include <KernelKit/IFS.h> -#include <KernelKit/KPC.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr.h> -#include <NeKit/Crc32.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> -#include <modules/AHCI/AHCI.h> -#include <modules/ATA/ATA.h> - -using namespace Kernel; - -#ifdef __NE_NO_BUILTIN__ -/***********************************************************************************/ -/** - Define those external symbols, to make the editor shutup -*/ -/***********************************************************************************/ - -/***********************************************************************************/ -/// @brief get sector count. -/***********************************************************************************/ -Kernel::SizeT drv_std_get_sector_count(); - -/***********************************************************************************/ -/// @brief get device size. -/***********************************************************************************/ -Kernel::SizeT drv_std_get_size(); - -#endif - -///! BUGS: 0 - -/***********************************************************************************/ -/// This file implements the New extended File System. -/// New extended File System implements a flat linked-list based algorithm. -/// / -/// /Path1/ /Path2/ -/// /readme.rtf /ListContents.pef /readme.lnk <-- symlink. -/// /Path1/readme.rtf -/***********************************************************************************/ -static inline bool is_valid_size(SizeT size, SizeT max_size) { - return size > 0 && size <= max_size; -} - -static inline bool is_valid_lba(Lba lba, DriveTrait& drive) { - NEFS_ROOT_PARTITION_BLOCK part_block; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part_block); - drive.fInput(drive.fPacket); - - if (!drive.fPacket.fPacketGood) { - return false; - } - - // Compute the maximum LBA (DiskSize / sector size) - SizeT sectorSize = drive.fSectorSz; - Lba maxLba = part_block.DiskSize / sectorSize; - - return (lba >= part_block.StartCatalog) && (lba < maxLba); -} - -STATIC IMountpoint kMountpoint; -/***********************************************************************************/ -/// @brief Creates a new fork inside the New filesystem partition. -/// @param catalog it's catalog -/// @param the_fork the fork itself. -/// @return the fork -/***********************************************************************************/ -_Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) { - if (the_fork.ForkName[0] == 0 || the_fork.CatalogName[0] == 0 || the_fork.DataSize == 0) { - return NO; - } - - auto catalog = this->GetCatalog(the_fork.CatalogName); - if (!catalog) return NO; - - Lba lba = catalog->DataFork; - if (lba < kNeFSCatalogStartAddress) { - delete catalog; - return NO; - } - - auto& drv = kMountpoint.A(); - Lba lba_prev = lba; - NEFS_FORK_STRUCT prev_fork{}; - NEFS_FORK_STRUCT cur_fork{}; - - while (true) { - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&cur_fork); - drv.fInput(drv.fPacket); - if (!drv.fPacket.fPacketGood) { - delete catalog; - return NO; - } - - if (cur_fork.Flags & kNeFSFlagCreated) { - if (KStringBuilder::Equals(cur_fork.ForkName, the_fork.ForkName) && - KStringBuilder::Equals(cur_fork.CatalogName, the_fork.CatalogName)) { - break; - } - lba_prev = lba; - lba = cur_fork.NextSibling; - prev_fork = cur_fork; - } else { - if (lba >= kNeFSCatalogStartAddress) { - prev_fork.NextSibling = lba; - drv.fPacket.fPacketLba = lba_prev; - drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&prev_fork); - drv.fOutput(drv.fPacket); - } - break; - } - } - - SizeT sectorCount = (the_fork.DataSize + kNeFSSectorSz - 1) / kNeFSSectorSz; - the_fork.DataOffset = lba + 1; - the_fork.PreviousSibling = lba_prev; - the_fork.NextSibling = lba + 1 + sectorCount; - the_fork.Flags |= kNeFSFlagCreated; - - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drv.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&the_fork); - drv.fOutput(drv.fPacket); - - fs_ifs_write(&kMountpoint, drv, IMountpoint::kDriveIndexA); - - delete catalog; - return YES; -} - -/***********************************************************************************/ -/// @brief Find fork inside filesystem. -/// @param catalog the catalog. -/// @param name the fork name. -/// @return the newly found fork. -/***********************************************************************************/ -_Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUCT* catalog, - _Input const Char* name, - _Input Boolean is_data) { - if (!catalog || !name) return nullptr; - - auto& drive = kMountpoint.A(); - Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork; - NEFS_FORK_STRUCT local_buf{}; - - while (lba >= kNeFSCatalogStartAddress) { - drive.fPacket.fPacketLba = lba; - drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&local_buf); - - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); - - if (auto res = fs_ifs_read(&kMountpoint, drive, this->mDriveIndex); res) { - switch (res) { - case 1: - err_global_get() = kErrorDiskReadOnly; - break; - case 2: - err_global_get() = kErrorDiskIsFull; - break; - case 3: - err_global_get() = kErrorNoSuchDisk; - break; - default: - break; - } - return nullptr; - } - - if (KStringBuilder::Equals(local_buf.ForkName, name) && - KStringBuilder::Equals(local_buf.CatalogName, catalog->Name)) { - auto result = new NEFS_FORK_STRUCT(); - rt_copy_memory_safe(&local_buf, result, sizeof(NEFS_FORK_STRUCT), sizeof(NEFS_FORK_STRUCT)); - return result; - } - - lba = local_buf.NextSibling; - } - - return nullptr; -} - -/***********************************************************************************/ -/// @brief Simpler factory to create a catalog (assumes you want to create a -/// file.) -/// @param name -/// @return catalog pointer. -/***********************************************************************************/ -_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) { - return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); -} - -/***********************************************************************************/ -/// @brief Creates a new catalog into the disk. -/// @param name the catalog name. -/// @param flags the flags of the catalog. -/// @param kind the catalog kind. -/// @return catalog pointer. -/***********************************************************************************/ -_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name, - _Input const Int32& flags, - _Input const Int32& kind) { - kout << "CreateCatalog(*...*)\r"; - - if (!name) return nullptr; - SizeT nameLen = rt_string_len(name); - if (nameLen == 0) return nullptr; - - Lba out_lba = 0UL; - - kout << "Checking for path separator...\r"; - - /// a directory should have a slash in the end. - if (kind == kNeFSCatalogKindDir && name[nameLen - 1] != NeFileSystemHelper::Separator()) - return nullptr; - - /// a file shouldn't have a slash in the end. - if (kind != kNeFSCatalogKindDir && name[nameLen - 1] == NeFileSystemHelper::Separator()) - return nullptr; - - NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); - - if (catalog_copy) { - kout << "Catalog already exists: " << name << ".\r"; - err_global_get() = kErrorFileExists; - delete catalog_copy; - catalog_copy = nullptr; - return nullptr; - } - - Char* parent_name = (Char*) mm_alloc_ptr(nameLen + 1, Yes, No); - rt_copy_memory_safe(const_cast<Char*>(name), parent_name, nameLen + 1, nameLen + 1); - - if (nameLen < 2) { - mm_free_ptr(parent_name); - err_global_get() = kErrorFileNotFound; - return nullptr; - } - - SizeT index_reverse_copy = nameLen - 1; - if (parent_name[index_reverse_copy] == NeFileSystemHelper::Separator()) { - parent_name[index_reverse_copy] = 0; - --index_reverse_copy; - } - while (index_reverse_copy > 0 && - parent_name[index_reverse_copy] != NeFileSystemHelper::Separator()) { - parent_name[index_reverse_copy] = 0; - --index_reverse_copy; - } - if (index_reverse_copy == 0 && parent_name[0] != NeFileSystemHelper::Separator()) { - mm_free_ptr(parent_name); - err_global_get() = kErrorFileNotFound; - return nullptr; - } - - NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba); - mm_free_ptr(parent_name); - - auto& drive = kMountpoint.A(); - if (catalog && catalog->Kind == kNeFSCatalogKindFile) { - kout << "Parent is a file.\r"; - delete catalog; - return nullptr; - } else if (!catalog) { - Char part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); - - NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*) part_block; - out_lba = blk_nefs->StartCatalog; - } - - if (drive.fPacket.fPacketReadOnly) { - delete catalog; - return nullptr; - } - - NEFS_CATALOG_STRUCT* child_catalog = new NEFS_CATALOG_STRUCT(); - child_catalog->Checksum = 0; - child_catalog->ResourceForkSize = 0UL; - child_catalog->DataForkSize = 0UL; - child_catalog->CatalogFlags = kNeFSStatusUnlocked; - child_catalog->NextSibling = out_lba; - child_catalog->PrevSibling = out_lba; - child_catalog->Kind = kind; - child_catalog->Flags |= kNeFSFlagCreated; - child_catalog->CatalogFlags = flags; - - SizeT i = nameLen; - --i; - if (kind == kNeFSCatalogKindDir) --i; - while (name[i] != '/') --i; - rt_copy_memory_safe((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name) - i, - kNeFSCatalogNameLen); - - NEFS_CATALOG_STRUCT temporary_catalog{}; - Lba start_free = out_lba; - - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); - - Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); - - NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) buf_part_block; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&temporary_catalog); - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; - drive.fInput(drive.fPacket); - - if (part_block->FreeCatalog < 1) { - delete child_catalog; - delete catalog; - return nullptr; - } - - kout << "Start finding catalog to allocate or empty space...\r"; - - SizeT catalogSectors = (sizeof(NEFS_CATALOG_STRUCT) + drive.fSectorSz - 1) / drive.fSectorSz; - while (start_free < part_block->StartCatalog + (part_block->CatalogCount * catalogSectors)) { - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&temporary_catalog); - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; - drive.fInput(drive.fPacket); - - if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0) { - child_catalog->NextSibling = start_free + catalogSectors; - - NEFS_CATALOG_STRUCT placeholder{}; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&placeholder); - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; - drive.fOutput(drive.fPacket); - - child_catalog->DataFork = part_block->DiskSize - start_free; - child_catalog->ResourceFork = child_catalog->DataFork; - - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(child_catalog); - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; - drive.fOutput(drive.fPacket); - - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf_part_block); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); - - part_block->FreeSectors -= catalogSectors; - part_block->CatalogCount += 1; - part_block->FreeCatalog -= 1; - - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fOutput(drive.fPacket); - - delete catalog; - NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT(); - rt_copy_memory_safe(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT), - sizeof(NEFS_CATALOG_STRUCT)); - - delete child_catalog; - return found_catalog; - } else if ((temporary_catalog.Flags & kNeFSFlagCreated) && - KStringBuilder::Equals(temporary_catalog.Name, name)) { - rt_copy_memory_safe(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT), - sizeof(NEFS_CATALOG_STRUCT)); - delete catalog; - return child_catalog; - } - - start_free += catalogSectors; - } - - delete child_catalog; - delete catalog; - return nullptr; -} - -/***********************************************************************************/ -/// @brief Make a EPM+NeFS drive out of the disk. -/// @param drive The drive to write on. -/// @return If it was sucessful, see err_global_get(). -/***********************************************************************************/ -bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, - const Char* part_name) { - if (!part_name || *part_name == 0) return false; - NE_UNUSED(flags); - - // verify disk. - drive->fVerify(drive->fPacket); - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive->fPacket.fPacketMime)); - if (!drive->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; - return false; - } - - Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - Lba start = drive->fLbaStart; - - drive->fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf); - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = start; - drive->fInput(drive->fPacket); - - NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf; - if (rt_string_cmp(kNeFSIdent, part_block->Ident, kNeFSIdentLen) == 0) return true; - - const auto kNeFSUntitledHD = part_name; - rt_copy_memory_safe((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen, - sizeof(part_block->Ident)); - rt_copy_memory_safe((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName, - rt_string_len(kNeFSUntitledHD), sizeof(part_block->PartitionName)); - - SizeT sectorCount = drv_std_get_sector_count(); - SizeT sectorSize = drive->fSectorSz; - SizeT totalBytes = sectorCount * sectorSize; - SizeT catalogEntries = totalBytes / sizeof(NEFS_CATALOG_STRUCT); - SizeT catalogSectors = (sizeof(NEFS_CATALOG_STRUCT) + sectorSize - 1) / sectorSize; - - part_block->Version = kNeFSVersionInteger; - part_block->Kind = kNeFSPartitionTypeStandard; - part_block->StartCatalog = start + catalogSectors; - part_block->Flags = 0UL; - part_block->CatalogCount = catalogEntries; - part_block->FreeCatalog = catalogEntries - 1; - part_block->SectorCount = sectorCount; - part_block->DiskSize = totalBytes; - part_block->SectorSize = sectorSize; - part_block->FreeSectors = sectorCount - catalogSectors; - - drive->fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf); - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = start; - drive->fOutput(drive->fPacket); - - (Void)(kout << "Drive kind: " << drive->fProtocol() << kendl); - (Void)(kout << "Partition name: " << part_block->PartitionName << kendl); - (Void)(kout << "Start catalog: " << hex_number(part_block->StartCatalog) << kendl); - (Void)(kout << "Number of catalogs: " << hex_number(part_block->CatalogCount) << kendl); - (Void)(kout << "Free catalog: " << hex_number(part_block->FreeCatalog) << kendl); - (Void)(kout << "Free sectors: " << hex_number(part_block->FreeSectors) << kendl); - (Void)(kout << "Sector size: " << hex_number(part_block->SectorSize) << kendl); - - return true; -} - -/***********************************************************************************/ -/// @brief Writes the data fork into a specific catalog. -/// @param catalog the catalog itself -/// @param data the data. -/// @return if the catalog wrote the contents successfully. -/***********************************************************************************/ -bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_rsrc_fork, - _Input VoidPtr data, _Input SizeT size_of_data, - _Input const Char* fork_name) { - if (size_of_data < 1) return NO; - - auto catalog = this->GetCatalog(catalog_name); - if (!catalog) { - kout << "NeFS: WriteCatalog failed to find catalog: " << catalog_name << "\n"; - return false; - } - - SizeT maxSize = is_rsrc_fork ? catalog->ResourceForkSize : catalog->DataForkSize; - - if (!is_valid_size(size_of_data, maxSize)) { - (Void)(kout << "NeFS: WriteCatalog called with invalid size: " << hex_number(size_of_data)); - kout << "\n"; - - delete catalog; - return false; - } - - Lba startFork = is_rsrc_fork ? catalog->ResourceFork : catalog->DataFork; - auto& drive = kMountpoint.A(); - - if (!is_valid_lba(startFork, drive)) { - (Void)(kout << "NeFS: WriteCatalog called with invalid LBA: " << hex_number(startFork)); - kout << "\n"; - - delete catalog; - return false; - } - - NEFS_ROOT_PARTITION_BLOCK part_block; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fPacket.fPacketSize = sizeof(part_block); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part_block); - drive.fInput(drive.fPacket); - - auto buf = new UInt8[size_of_data]; - rt_set_memory(buf, 0, size_of_data); - rt_copy_memory_safe(data, buf, size_of_data, size_of_data); - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); - - NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT(); - NEFS_FORK_STRUCT prev_fork{}; - - while (startFork >= part_block.StartCatalog && drive.fPacket.fPacketGood) { - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fork_data_input); - drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drive.fPacket.fPacketLba = startFork; - drive.fInput(drive.fPacket); - - if (!drive.fPacket.fPacketGood) { - break; - } - - if ((fork_data_input->Flags & kNeFSFlagCreated) && - KStringBuilder::Equals(fork_data_input->ForkName, fork_name) && - KStringBuilder::Equals(fork_data_input->CatalogName, catalog_name) && - fork_data_input->DataSize == size_of_data) { - SizeT bytes_left = size_of_data; - SizeT offset = 0; - Lba base_lba = fork_data_input->DataOffset; - - while (bytes_left > 0) { - SizeT chunk = (bytes_left > kNeFSSectorSz) ? kNeFSSectorSz : bytes_left; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(buf + offset); - drive.fPacket.fPacketSize = chunk; - drive.fPacket.fPacketLba = base_lba + (offset / kNeFSSectorSz); - drive.fOutput(drive.fPacket); - offset += chunk; - bytes_left -= chunk; - } - - delete fork_data_input; - delete[] buf; - delete catalog; - return true; - } - - prev_fork = *fork_data_input; - startFork = fork_data_input->NextSibling; - } - - delete fork_data_input; - delete[] buf; - delete catalog; - return false; -} - -/***********************************************************************************/ -/// @brief -/// @param catalog_name the catalog name. -/// @return the newly found catalog. -/***********************************************************************************/ -_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::FindCatalog(_Input const Char* catalog_name, - Lba& out_lba, Bool search_hidden, - Bool local_search) { - if (!catalog_name || *catalog_name == 0) return nullptr; - - NEFS_ROOT_PARTITION_BLOCK part{}; - auto& drive = kMountpoint.A(); - - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&part); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); - - auto start_catalog_lba = kNeFSCatalogStartAddress; - - // Helper lambda to scan from a given LBA - auto scan_from = [&](Lba lba_start, Bool allow_hidden) -> NEFS_CATALOG_STRUCT* { - Lba cursor = lba_start; - NEFS_CATALOG_STRUCT tmp{}; - while (cursor >= part.StartCatalog && drive.fPacket.fPacketGood) { - drive.fPacket.fPacketLba = cursor; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&tmp); - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fInput(drive.fPacket); - - if (KStringBuilder::Equals( - tmp.Name, catalog_name + (rt_string_len(catalog_name) - rt_string_len(tmp.Name)))) { - if (tmp.Status == kNeFSStatusLocked && !allow_hidden) { - err_global_get() = kErrorFileLocked; - return nullptr; - } - if (!(tmp.Flags & kNeFSFlagCreated)) { - err_global_get() = kErrorFileNotFound; - return nullptr; - } - NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT(); - rt_copy_memory_safe(&tmp, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT), - sizeof(NEFS_CATALOG_STRUCT)); - out_lba = cursor; - return catalog_ptr; - } - cursor = tmp.NextSibling; - } - return nullptr; - }; - - if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) { - Char parent_name[kNeFSCatalogNameLen] = {0}; - SizeT nameLen = rt_string_len(catalog_name); - rt_copy_memory_safe(const_cast<Char*>(catalog_name), parent_name, nameLen + 1, - kNeFSCatalogNameLen); - - SizeT indexReverseCopy = nameLen - 1; - if (parent_name[indexReverseCopy] == NeFileSystemHelper::Separator()) { - parent_name[indexReverseCopy] = 0; - --indexReverseCopy; - } - while (indexReverseCopy > 0 && - parent_name[indexReverseCopy] != NeFileSystemHelper::Separator()) { - parent_name[indexReverseCopy] = 0; - --indexReverseCopy; - } - if (indexReverseCopy == 0 && parent_name[0] != NeFileSystemHelper::Separator()) { - return nullptr; - } - - NEFS_CATALOG_STRUCT* parent_catalog = - this->FindCatalog(parent_name, out_lba, search_hidden, NO); - if (parent_catalog) { - start_catalog_lba = parent_catalog->NextSibling; - delete parent_catalog; - NEFS_CATALOG_STRUCT* found = scan_from(start_catalog_lba, search_hidden); - if (found) return found; - } - } - - return scan_from(part.StartCatalog, search_hidden); -} - -/***********************************************************************************/ -/// @brief Get catalog from filesystem. -/// @param name the catalog's name/ -/// @return -/***********************************************************************************/ -_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) { - Lba unused = 0; - return this->FindCatalog(name, unused, YES, YES); -} - -/***********************************************************************************/ -/// @brief Closes a catalog, (frees it). -/// @param catalog the catalog to close. -/// @return -/***********************************************************************************/ -_Output Boolean NeFileSystemParser::CloseCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog) { - if (!catalog) return false; - delete catalog; - catalog = nullptr; - return true; -} - -/***********************************************************************************/ -/// @brief Mark catalog as removed. -/// @param catalog The catalog structure. -/// @return if the catalog was removed or not. -/***********************************************************************************/ -_Output Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_name) { - if (!catalog_name || KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root())) { - err_global_get() = kErrorInternal; - return false; - } - - Lba out_lba = 0; - auto catalog = this->FindCatalog(catalog_name, out_lba, YES, YES); - if (!catalog) return false; - - auto& drive = kMountpoint.A(); - NEFS_FORK_STRUCT fork_buf{}; - Lba fork_lba = catalog->DataFork; - while (fork_lba >= kNeFSCatalogStartAddress) { - drive.fPacket.fPacketLba = fork_lba; - drive.fPacket.fPacketSize = sizeof(fork_buf); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf); - drive.fInput(drive.fPacket); - - fork_buf.Flags &= (~kNeFSFlagCreated); - fork_buf.Flags |= kNeFSFlagDeleted; - - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf); - drive.fPacket.fPacketSize = sizeof(fork_buf); - drive.fPacket.fPacketLba = fork_lba; - drive.fOutput(drive.fPacket); - - fork_lba = fork_buf.NextSibling; - } - - fork_lba = catalog->ResourceFork; - while (fork_lba >= kNeFSCatalogStartAddress) { - drive.fPacket.fPacketLba = fork_lba; - drive.fPacket.fPacketSize = sizeof(fork_buf); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf); - drive.fInput(drive.fPacket); - - fork_buf.Flags &= (~kNeFSFlagCreated); - fork_buf.Flags |= kNeFSFlagDeleted; - - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(&fork_buf); - drive.fPacket.fPacketSize = sizeof(fork_buf); - drive.fPacket.fPacketLba = fork_lba; - drive.fOutput(drive.fPacket); - - fork_lba = fork_buf.NextSibling; - } - - if (out_lba >= kNeFSCatalogStartAddress || (catalog->Flags & kNeFSFlagCreated)) { - catalog->Flags &= (~kNeFSFlagCreated); - catalog->Flags |= kNeFSFlagDeleted; - - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); - drive.fPacket.fPacketLba = out_lba; - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(catalog); - drive.fOutput(drive.fPacket); - - Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(partitionBlockBuf); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fInput(drive.fPacket); - - NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) partitionBlockBuf; - if (part_block->CatalogCount > 0) --part_block->CatalogCount; - ++part_block->FreeSectors; - - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(part_block); - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fOutput(drive.fPacket); - - delete catalog; - catalog = nullptr; - return true; - } - - delete catalog; - catalog = nullptr; - return false; -} - -/// ***************************************************************** /// -/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead. -/// ***************************************************************** /// - -/***********************************************************************************/ -/// @brief Read the catalog data fork. -/// @param catalog -/// @param dataSz -/// @return -/***********************************************************************************/ -VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog, - _Input Bool is_rsrc_fork, _Input SizeT dataSz, - _Input const Char* forkName) { - if (!catalog) { - err_global_get() = kErrorInvalidData; - return nullptr; - } - // Validate size against fork size - SizeT maxSize = is_rsrc_fork ? catalog->ResourceForkSize : catalog->DataForkSize; - if (!is_valid_size(dataSz, maxSize)) { - kout << "NeFS: ReadCatalog called with invalid size: "; - hex_number(dataSz); - kout << "\n"; - return nullptr; - } - - Lba dataForkLba = is_rsrc_fork ? catalog->ResourceFork : catalog->DataFork; - auto& drive = kMountpoint.A(); - if (!is_valid_lba(dataForkLba, drive)) { - kout << "NeFS: ReadCatalog called with invalid LBA: "; - hex_number(dataForkLba); - kout << "\n"; - return nullptr; - } - - auto* fs_buf = new NEFS_FORK_STRUCT(); - rt_copy_memory_safe((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet"), sizeof(drive.fPacket.fPacketMime)); - - NEFS_FORK_STRUCT* fs_fork_data = nullptr; - while (dataForkLba >= kNeFSCatalogStartAddress) { - drive.fPacket.fPacketLba = dataForkLba; - drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drive.fPacket.fPacketContent = reinterpret_cast<VoidPtr>(fs_buf); - drive.fInput(drive.fPacket); - - fs_fork_data = fs_buf; - (Void)(kout << "ForkName: " << fs_fork_data->ForkName << kendl); - (Void)(kout << "CatalogName: " << fs_fork_data->CatalogName << kendl); - - if (KStringBuilder::Equals(forkName, fs_fork_data->ForkName) && - KStringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) { - break; - } - dataForkLba = fs_fork_data->NextSibling; - } - - if (dataForkLba < kNeFSCatalogStartAddress) { - delete fs_buf; - return nullptr; - } - return fs_fork_data; -} - -/***********************************************************************************/ -/// @brief Seek in the data fork. -/// @param catalog the catalog offset. -/// @param off where to seek. -/// @return if the seeking was successful. -/***********************************************************************************/ -bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off) { - NE_UNUSED(catalog); - NE_UNUSED(off); - err_global_get() = kErrorUnimplemented; - return false; -} - -/***********************************************************************************/ -/// @brief Tell where we are inside the data fork. -/// @param catalog -/// @return The position on the file. -/***********************************************************************************/ -SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog) { - NE_UNUSED(catalog); - err_global_get() = kErrorUnimplemented; - return 0; -} - -namespace Kernel::NeFS { -/***********************************************************************************/ -/// @brief Construct NeFS drives. -/***********************************************************************************/ -Boolean fs_init_nefs(Void) noexcept { - kout << "Creating OpenHeFS disk...\r"; - kMountpoint.A() = io_construct_main_drive(); - if (kMountpoint.A().fPacket.fPacketReadOnly == YES) - ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted."); - NeFileSystemParser parser; - return parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName); -} -} // namespace Kernel::NeFS - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ diff --git a/dev/kernel/src/FS/OpenHeFS+FileMgr.cc b/dev/kernel/src/FS/OpenHeFS+FileMgr.cc deleted file mode 100644 index e70e3626..00000000 --- a/dev/kernel/src/FS/OpenHeFS+FileMgr.cc +++ /dev/null @@ -1,191 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifndef __NE_MINIMAL_OS__ -#ifdef __FSKIT_INCLUDES_OPENHEFS__ - -#include <KernelKit/FileMgr.h> -#include <KernelKit/HeapMgr.h> - -/// @brief OpenHeFS File System Manager. -/// BUGS: 0 - -namespace Kernel { -/// @brief C++ constructor -HeFileSystemMgr::HeFileSystemMgr() { - mParser = new HeFileSystemParser(); - MUST_PASS(mParser); - - kout << "We are done allocating HeFileSystemParser...\n"; -} - -HeFileSystemMgr::~HeFileSystemMgr() { - if (mParser) { - kout << "Destroying HeFileSystemParser...\n"; - delete mParser; - mParser = nullptr; - } -} - -/// @brief Removes a node from the filesystem. -/// @param path The filename -/// @return If it was deleted or not. -bool HeFileSystemMgr::Remove(_Input const Char* path) { - if (path == nullptr || *path == 0) { - kout << "OpenHeFS: Remove called with null or empty path\n"; - return false; - } - - return NO; -} - -/// @brief Creates a node with the specified. -/// @param path The filename path. -/// @return The Node pointer. -NodePtr HeFileSystemMgr::Create(_Input const Char* path) { - if (!path || *path == 0) { - kout << "OpenHeFS: Create called with null or empty path\n"; - return nullptr; - } - return nullptr; -} - -/// @brief Creates a node which is a directory. -/// @param path The filename path. -/// @return The Node pointer. -NodePtr HeFileSystemMgr::CreateDirectory(const Char* path) { - if (!path || *path == 0) { - kout << "OpenHeFS: CreateDirectory called with null or empty path\n"; - return nullptr; - } - return nullptr; -} - -/// @brief Creates a node which is an alias. -/// @param path The filename path. -/// @return The Node pointer. -NodePtr HeFileSystemMgr::CreateAlias(const Char* path) { - if (!path || *path == 0) { - kout << "OpenHeFS: CreateAlias called with null or empty path\n"; - return nullptr; - } - return nullptr; -} - -NodePtr HeFileSystemMgr::CreateSwapFile(const Char* path) { - if (!path || *path == 0) { - kout << "OpenHeFS: CreateSwapFile called with null or empty path\n"; - return nullptr; - } - return nullptr; -} - -/// @brief Gets the root directory. -/// @return -const Char* NeFileSystemHelper::Root() { - return kHeFSRootDirectory; -} - -/// @brief Gets the up-dir directory. -/// @return -const Char* NeFileSystemHelper::UpDir() { - return kHeFSUpDir; -} - -/// @brief Gets the separator character. -/// @return -Char NeFileSystemHelper::Separator() { - return kHeFSSeparator; -} - -/// @brief Gets the metafile character. -/// @return -Char NeFileSystemHelper::MetaFile() { - return '\0'; -} - -/// @brief Opens a new file. -/// @param path -/// @param r -/// @return -_Output NodePtr HeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) { - if (!path || *path == 0) { - kout << "OpenHeFS: Open called with null or empty path\n"; - return nullptr; - } - if (!r || *r == 0) { - kout << "OpenHeFS: Open called with null or empty mode string\n"; - return nullptr; - } - return nullptr; -} - -Void HeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, - _Input SizeT size) { - NE_UNUSED(node); - NE_UNUSED(flags); - NE_UNUSED(size); - NE_UNUSED(data); -} - -_Output VoidPtr HeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) { - NE_UNUSED(node); - NE_UNUSED(flags); - NE_UNUSED(size); - - return nullptr; -} - -Void HeFileSystemMgr::Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, - _Input Int32 flags, _Input SizeT size) { - NE_UNUSED(node); - NE_UNUSED(flags); - NE_UNUSED(size); - NE_UNUSED(name); - NE_UNUSED(data); -} - -_Output VoidPtr HeFileSystemMgr::Read(_Input const Char* name, _Input NodePtr node, - _Input Int32 flags, _Input SizeT sz) { - NE_UNUSED(node); - NE_UNUSED(flags); - NE_UNUSED(sz); - NE_UNUSED(name); - - return nullptr; -} - -_Output Bool HeFileSystemMgr::Seek(NodePtr node, SizeT off) { - NE_UNUSED(node); - NE_UNUSED(off); - - return false; -} - -/// @brief Tell current offset within catalog. -/// @param node -/// @return kFileMgrNPos if invalid, else current offset. -_Output SizeT HeFileSystemMgr::Tell(NodePtr node) { - NE_UNUSED(node); - return kFileMgrNPos; -} - -/// @brief Rewinds the catalog -/// @param node -/// @return False if invalid, nah? calls Seek(node, 0). -_Output Bool HeFileSystemMgr::Rewind(NodePtr node) { - NE_UNUSED(node); - return kFileMgrNPos; -} - -/// @brief Returns the parser of OpenHeFS. -_Output HeFileSystemParser* HeFileSystemMgr::GetParser() noexcept { - return mParser; -} -} // namespace Kernel - -#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__ -#endif // ifndef __NE_MINIMAL_OS__ diff --git a/dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc b/dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc deleted file mode 100644 index d8e22f18..00000000 --- a/dev/kernel/src/FS/OpenHeFS+FileSystemParser.cc +++ /dev/null @@ -1,1160 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#ifdef __FSKIT_INCLUDES_OPENHEFS__ - -#include <FSKit/OpenHeFS.h> -#include <FirmwareKit/EPM.h> -#include <FirmwareKit/GPT.h> -#include <KernelKit/KPC.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/UserMgr.h> -#include <NeKit/Crc32.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> -#include <modules/AHCI/AHCI.h> -#include <modules/ATA/ATA.h> - -namespace Kernel { -namespace Detail { - /// @brief Forward declarations of internal functions. - - /***********************************************************************************/ - /// @brief Traverse the RB-Tree of the filesystem. - /// @param dir The directory to traverse. - /// @param start The starting point of the traversal. - /// @note This function is used to traverse the RB-Tree of the filesystem. - /// @internal Internal filesystem use only. - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output Void - hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, const Lba& start_ind, - Lba& start); - - /***********************************************************************************/ - /// @brief Get the index node of a file or directory. - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read from. - /// @param dir_name The name of the directory. - /// @param file_name The name of the file. - /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic - /// link, unknown). - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefsi_fetch_in(HEFS_BOOT_NODE* boot, - DriveTrait* mnt, - const Utf8Char* dir_name, - const Utf8Char* file_name, - UInt8 kind); - - /***********************************************************************************/ - /// @brief Allocate a new index node-> - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read/write from. - /// @param dir_name The name of the parent directory. - /// @return Status, see err_global_get(). - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output BOOL - hefsi_update_in_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, const Utf8Char* dir_name, - HEFS_INDEX_NODE* node, const BOOL create_or_delete); - - /***********************************************************************************/ - /// @brief Balance RB-Tree of the filesystem. - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read/write from. - /// @return Status, see err_global_get(). - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* boot, DriveTrait* mnt); - - /// @brief Alllocate IND from boot node. - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read from. - /// @param dir_name The name of the directory. - /// @param dir_name The parent of the directory. - /// @param flags Directory flags. - /// @param delete_or_create Delete or create directory. - STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, - const Utf8Char* dir_name, UInt16 flags, - const BOOL delete_or_create); - - /// @brief This helper makes it easier for other machines to understand OpenHeFS encoded hashes. - STATIC UInt64 hefsi_to_big_endian_64(UInt64 val) { - return ((val >> 56) & 0x00000000000000FFULL) | ((val >> 40) & 0x000000000000FF00ULL) | - ((val >> 24) & 0x0000000000FF0000ULL) | ((val >> 8) & 0x00000000FF000000ULL) | - ((val << 8) & 0x000000FF00000000ULL) | ((val << 24) & 0x0000FF0000000000ULL) | - ((val << 40) & 0x00FF000000000000ULL) | ((val << 56) & 0xFF00000000000000ULL); - } - - /// @brief Simple algorithm to hash directory entries for INDs. - /// @param path the directory path. - /// @return The hashed path. - template <typename CharT = Utf8Char> - STATIC UInt64 hefsi_hash_64(const CharT* path) { - if (!path || *path == 0) return 0; - - const UInt64 kFnvBaseOffset = 0xcbf29ce484222325ULL; - const UInt64 kFnvPrimeNumber = 0x100000001b3ULL; - - UInt64 hash = kFnvBaseOffset; - - while (*path) { - hash ^= (CharT) (*path++); - hash *= kFnvPrimeNumber; - } - - return hefsi_to_big_endian_64(hash); - } - - /// @brief Traverse the RB-Tree of the filesystem. - /// @param dir The directory to traverse. - /// @param start The starting point of the traversal. - /// @note This function is used to traverse the RB-Tree of the filesystem. - /// @internal Internal filesystem use only. - STATIC ATTRIBUTE(unused) Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, DriveTrait* mnt, - const Lba& ind_start, Lba& start) { - if (!mnt || !dir) return; - - BOOL check_is_good = NO; - HEFS_INDEX_NODE_DIRECTORY* dir_tmp = new HEFS_INDEX_NODE_DIRECTORY(); - - while (YES) { - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_tmp; - mnt->fInput(mnt->fPacket); - - if (!mnt->fPacket.fPacketGood) break; - - if (dir_tmp->fNext != 0) { - if (check_is_good) break; - - start = dir_tmp->fNext; - - check_is_good = YES; - continue; - } else if (dir_tmp->fPrev != 0) { - if (check_is_good) break; - - start = dir_tmp->fPrev; - check_is_good = YES; - continue; - } else { - if (dir_tmp->fParent != 0) { - if (check_is_good) break; - - start = dir_tmp->fParent; - check_is_good = YES; - continue; - } else if (dir_tmp->fPrev != 0) { - if (check_is_good) break; - - start = dir_tmp->fPrev; - check_is_good = YES; - continue; - } else { - if (start == 0) { - start = ind_start; - continue; - } - - start += sizeof(HEFS_INDEX_NODE_DIRECTORY); - break; - } - } - } - - delete dir_tmp; - - start += sizeof(HEFS_INDEX_NODE_DIRECTORY); - if (start == 0) start = ind_start; - } - - /***********************************************************************************/ - /// @brief Rotate the RB-Tree to the left or right. - /// @internal - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_tree(Lba& start, DriveTrait* mnt) { - if (!start || !mnt) return; - - HEFS_INDEX_NODE_DIRECTORY* cur = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = cur; - - mnt->fInput(mnt->fPacket); - - if (cur->fHashPath == 0) return; - - HEFS_INDEX_NODE_DIRECTORY* sibling = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = cur->fPrev; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = sibling; - - mnt->fInput(mnt->fPacket); - - if (sibling->fHashPath == 0) return; - - auto child_sibling = sibling->fChild; - auto child_cur = cur->fChild; - - cur->fChild = child_sibling; - sibling->fChild = child_cur; - - sibling->fChecksum = ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - cur->fChecksum = ke_calculate_crc32((Char*) cur, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = cur->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = sibling; - - mnt->fOutput(mnt->fPacket); - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = cur; - - mnt->fOutput(mnt->fPacket); - - HEFS_INDEX_NODE_DIRECTORY* sibling_child = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = child_sibling; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = sibling_child; - - mnt->fInput(mnt->fPacket); - - sibling_child->fParent = cur->fParent; - - sibling_child->fChecksum = - ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fOutput(mnt->fPacket); - - HEFS_INDEX_NODE_DIRECTORY* cur_child = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = child_cur; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = cur_child; - - mnt->fInput(mnt->fPacket); - - cur_child->fParent = start; - - cur_child->fChecksum = ke_calculate_crc32((Char*) sibling, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fOutput(mnt->fPacket); - - kout << "RB-Tree has been rotated.\r"; - } - - /// @brief Alllocate IND from boot node. - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read from. - /// @param dir_name The name of the directory. - /// @param dir_name The parent of the directory. - /// @param flags Directory flags. - /// @param delete_or_create Delete or create directory. - STATIC _Output BOOL hefsi_update_ind_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, - const Utf8Char* dir_name, UInt16 flags, - const BOOL delete_or_create) { - if (mnt) { - HEFS_INDEX_NODE_DIRECTORY* tmpdir = - (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); - - auto start = boot->fStartIND; - auto prev_location = start; - auto parent_location = 0UL; - - MUST_PASS(boot->fStartIND > mnt->fLbaStart); - - while (YES) { - auto prev_start = start; - - if (start) - mnt->fPacket.fPacketLba = start; - else - mnt->fPacket.fPacketLba = prev_location + sizeof(HEFS_INDEX_NODE_DIRECTORY); - - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = tmpdir; - - mnt->fInput(mnt->fPacket); - - BOOL expr = NO; - - if (!delete_or_create) { - expr = (!tmpdir->fCreated && tmpdir->fDeleted) || tmpdir->fHashPath == 0; - } else { - expr = - tmpdir->fCreated && !tmpdir->fDeleted && hefsi_hash_64(dir_name) == tmpdir->fHashPath; - } - - if (expr) { - HEFS_INDEX_NODE_DIRECTORY* dirent = - (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); - - rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - dirent->fHashPath = delete_or_create ? 0UL : hefsi_hash_64(dir_name); - dirent->fAccessed = 0UL; - dirent->fCreated = delete_or_create ? 0UL : 1UL; - dirent->fDeleted = delete_or_create ? 1UL : 0UL; - dirent->fModified = 0UL; - dirent->fEntryCount = 0UL; - - dirent->fReserved = 0; - dirent->fFlags = flags; - dirent->fChecksum = 0; - - dirent->fEntryCount = 0; - - if (parent_location) { - HEFS_INDEX_NODE_DIRECTORY* tmpend = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = parent_location; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = tmpend; - - mnt->fInput(mnt->fPacket); - - if (tmpend->fChecksum != - ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY))) - ke_panic(RUNTIME_CHECK_FILESYSTEM, "Bad CRC32 value, aborting."); - - if (delete_or_create) - --tmpend->fEntryCount; - else - ++tmpend->fEntryCount; - - tmpend->fChecksum = - ke_calculate_crc32((Char*) tmpend, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fOutput(mnt->fPacket); - - auto child_first = tmpend->fChild; - - while (YES) { - mnt->fPacket.fPacketLba = child_first; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = tmpend; - - mnt->fInput(mnt->fPacket); - - if ((!tmpend->fCreated && tmpend->fDeleted) || tmpend->fHashPath == 0) { - start = child_first; - break; - } - - hefsi_traverse_tree(tmpend, mnt, boot->fStartIND, child_first); - } - } - - dirent->fNext = tmpdir->fNext; - dirent->fPrev = tmpdir->fPrev; - dirent->fParent = tmpdir->fParent; - dirent->fChild = tmpdir->fChild; - dirent->fColor = tmpdir->fColor; - - if (dirent->fColor == 0) { - dirent->fColor = dirent->fNext ? kHeFSRed : kHeFSBlack; - } - - if (dirent->fPrev == 0) { - dirent->fPrev = boot->fStartIND; - } - - if (dirent->fParent == 0) { - dirent->fParent = boot->fStartIND; - } - - if (tmpdir->fChild == 0) { - auto child = dirent->fNext + sizeof(HEFS_INDEX_NODE_DIRECTORY); - - HEFS_INDEX_NODE_DIRECTORY* tmpend = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - while (YES) { - mnt->fPacket.fPacketLba = child; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = tmpend; - - mnt->fInput(mnt->fPacket); - - if ((!tmpend->fCreated && tmpend->fDeleted) || tmpdir->fHashPath == 0) { - break; - } - - child += sizeof(HEFS_INDEX_NODE_DIRECTORY); - if (child > boot->fEndIND) break; - } - - dirent->fColor = kHeFSRed; - dirent->fChild = child; - - if (child > boot->fEndIND) dirent->fChild = boot->fStartIND; - } - - for (SizeT index = 0UL; index < kHeFSSliceCount; ++index) { - dirent->fINSlices[index] = 0UL; - } - - dirent->fChecksum = ke_calculate_crc32((Char*) dirent, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = prev_start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dirent; - - mnt->fOutput(mnt->fPacket); - - err_global_get() = kErrorSuccess; - - mm_free_ptr(dirent); - mm_free_ptr(tmpdir); - - if (!delete_or_create) - ++boot->fINDCount; - else - --boot->fINDCount; - - boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fOutput(mnt->fPacket); - - return YES; - } - - prev_location = start; - - hefsi_traverse_tree(tmpdir, mnt, boot->fStartIND, start); - if (start > boot->fEndIND || start == 0) break; - } - - err_global_get() = kErrorDisk; - mm_free_ptr(tmpdir); - - return NO; - } - - err_global_get() = kErrorDiskIsFull; - return NO; - } - - /// @brief Get the index node of a file or directory. - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read from. - /// @param dir_name The name of the directory. - /// @param file_name The name of the file. - /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic - /// link, unknown). - STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefsi_fetch_in(HEFS_BOOT_NODE* boot, - DriveTrait* mnt, - const Utf8Char* dir_name, - const Utf8Char* file_name, - UInt8 kind) { - if (mnt) { - if (boot->fStartIND > boot->fEndIND) return nullptr; - if (boot->fStartIN > boot->fEndIN) return nullptr; - - auto start = boot->fStartIND; - HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); - - HEFS_INDEX_NODE_DIRECTORY* dir = - (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); - - while (YES) { - if (err_global_get() == kErrorDiskIsCorrupted) { - delete dir; - dir = nullptr; - - delete node; - node = nullptr; - - return nullptr; - } - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fInput(mnt->fPacket); - - (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl); - (Void)(kout << hex_number(dir->fHashPath) << kendl); - - if (dir->fHashPath == 0) break; - - if (hefsi_hash_64(dir_name) == dir->fHashPath) { - for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) { - mnt->fPacket.fPacketLba = dir->fINSlices[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - - mnt->fInput(mnt->fPacket); - - (Void)(kout << hex_number(hefsi_hash_64(file_name)) << kendl); - (Void)(kout << hex_number(node->fHashPath) << kendl); - - if (hefsi_hash_64(file_name) == node->fHashPath && node->fKind == kind) { - delete dir; - dir = nullptr; - - return node; - } - } - } - - hefsi_traverse_tree(dir, mnt, boot->fStartIND, start); - if (start == boot->fStartIND || start == boot->fStartIND) break; - } - - delete node; - node = nullptr; - - delete dir; - dir = nullptr; - } - - kout << "Error: Failed to find IN.\r"; - - err_global_get() = kErrorFileNotFound; - - return nullptr; - } - - STATIC ATTRIBUTE(unused) _Output BOOL - hefsi_update_in_status(HEFS_BOOT_NODE* boot, DriveTrait* mnt, const Utf8Char* dir_name, - HEFS_INDEX_NODE* node, BOOL delete_or_create) { - if (!boot || !mnt) return NO; - - auto start = boot->fStartIND; - - if (start > boot->fEndIND) return NO; - if (boot->fStartIN > boot->fEndIN) return NO; - ; - if (boot->fStartBlock > boot->fEndBlock) return NO; - - if (mnt) { - HEFS_INDEX_NODE_DIRECTORY* dir = - (HEFS_INDEX_NODE_DIRECTORY*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); - - auto hash_file = node->fHashPath; - - while (YES) { - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fInput(mnt->fPacket); - - (Void)(kout << hex_number(hefsi_hash_64(dir_name)) << kendl); - (Void)(kout << hex_number(dir->fHashPath) << kendl); - - if (hefsi_hash_64(dir_name) == dir->fHashPath) { - for (SizeT inode_index = 0UL; inode_index < kHeFSSliceCount; ++inode_index) { - if (dir->fINSlices[inode_index] == 0 && !delete_or_create) { - dir->fINSlices[inode_index] = boot->fStartIN; - - ++dir->fEntryCount; - - dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fOutput(mnt->fPacket); - - auto lba = dir->fINSlices[inode_index]; - - node->fOffsetSliceLow = (UInt32) (boot->fStartBlock); - node->fOffsetSliceHigh = (UInt32) (boot->fStartBlock >> 32); - - node->fChecksum = ke_calculate_crc32((Char*) node, sizeof(HEFS_INDEX_NODE)); - - mnt->fPacket.fPacketLba = lba; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - - mnt->fOutput(mnt->fPacket); - - boot->fStartIN += sizeof(HEFS_INDEX_NODE); - boot->fStartBlock += kHeFSBlockLen; - - boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fOutput(mnt->fPacket); - - mm_free_ptr(dir); - - return YES; - } else if (dir->fINSlices[inode_index] != 0 && delete_or_create) { - auto lba = dir->fINSlices[inode_index]; - - HEFS_INDEX_NODE tmp_node{}; - - mnt->fPacket.fPacketLba = lba; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = &tmp_node; - - mnt->fInput(mnt->fPacket); - - if (tmp_node.fHashPath != hash_file) { - continue; - } - - node->fOffsetSliceLow = 0; - node->fOffsetSliceHigh = 0; - - boot->fStartIN -= sizeof(HEFS_INDEX_NODE); - boot->fStartBlock -= kHeFSBlockLen; - - boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fOutput(mnt->fPacket); - - mnt->fPacket.fPacketLba = lba; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - - mnt->fOutput(mnt->fPacket); - - dir->fINSlices[inode_index] = 0; - - if (dir->fEntryCount) --dir->fEntryCount; - - dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fOutput(mnt->fPacket); - - mm_free_ptr(dir); - - return YES; - } - } - } - - hefsi_traverse_tree(dir, mnt, boot->fStartIND, start); - if (start > boot->fEndIND || start == 0) break; - } - - mm_free_ptr(dir); - err_global_get() = kErrorFileNotFound; - return NO; - } - - err_global_get() = kErrorDiskIsFull; - return NO; - } - - /// @brief Balance RB-Tree of the filesystem. - /// @param boot The boot node of the filesystem. - /// @param mnt The mnt to read/write from. - /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_ind(HEFS_BOOT_NODE* boot, DriveTrait* mnt) { - if (mnt) { - HEFS_INDEX_NODE_DIRECTORY* dir = - (HEFS_INDEX_NODE_DIRECTORY*) RTL_ALLOCA(sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - auto start = boot->fStartIND; - - while (YES) { - if (start == 0UL || start > boot->fEndIND) break; - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fInput(mnt->fPacket); - - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; - - return NO; - } - - if (start == boot->fStartIND) { - dir->fColor = kHeFSBlack; - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fOutput(mnt->fPacket); - } - - if (dir->fColor == kHeFSBlack && dir->fChild != 0UL) { - dir->fColor = kHeFSRed; - hefsi_rotate_tree(start, mnt); - } else if (dir->fColor == kHeFSBlack && dir->fChild == 0UL) { - dir->fColor = kHeFSBlack; - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fOutput(mnt->fPacket); - } - - if (ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)) != dir->fChecksum) { - dir->fChecksum = ke_calculate_crc32((Char*) dir, sizeof(HEFS_INDEX_NODE_DIRECTORY)); - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fOutput(mnt->fPacket); - } - - hefsi_traverse_tree(dir, mnt, boot->fStartIND, start); - } - - err_global_get() = kErrorSuccess; - return YES; - } - - err_global_get() = kErrorDisk; - return NO; - } -} // namespace Detail -} // namespace Kernel - -/// @note OpenHeFS will allocate inodes and ind in advance, to avoid having to allocate them in -/// real-time. -/// @note This is certainly take longer to format a disk with it, but worth-it in the long run. - -namespace Kernel { -/// @brief Make a EPM+OpenHeFS mnt out of the disk. -/// @param mnt The mnt to write on. -/// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* mnt, _Input const Int32 flags, - _Input const Utf8Char* vol_name) { - // Verify Disk. - mnt->fVerify(mnt->fPacket); - - // if disk isn't good, then error out. - if (false == mnt->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; - return NO; - } - - if (drv_std_get_size() < kHeFSMinimumDiskSize) { - (Void)(kout << "OpenHeFS recommends at least 128 GiB of free space." << kendl); - } - - HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fInput(mnt->fPacket); - - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; - - return NO; - } - - // Check if the disk is already formatted. - - if (KStringBuilder::Equals(boot->fMagic, kHeFSMagic) && boot->fVersion == kHeFSVersion) { - if (ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)) != boot->fChecksum && - boot->fChecksum > 0) { - err_global_get() = kErrorDiskIsCorrupted; - return NO; - } - - err_global_get() = kErrorSuccess; - return YES; - } - - if (ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)) != boot->fChecksum && - boot->fChecksum > 0) { - err_global_get() = kErrorDiskIsCorrupted; - return NO; - } - - rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); - - urt_copy_memory((VoidPtr) vol_name, boot->fVolName, urt_string_len(vol_name) + 1); - rt_copy_memory_safe((VoidPtr) kHeFSMagic, boot->fMagic, kHeFSMagicLen - 1, sizeof(boot->fMagic)); - - if (mnt->fLbaStart > mnt->fLbaEnd) { - err_global_get() = kErrorDiskIsCorrupted; - - return NO; - } - - boot->fBadSectors = 0; - - boot->fSectorCount = drv_std_get_sector_count(); - boot->fSectorSize = mnt->fSectorSz; - - MUST_PASS(boot->fSectorSize); - - /// @note all OpenHeFS strucutres are equal to 512, so here it's fine, unless fSectoSize is 2048. - const SizeT max_lba = (drv_std_get_size()) / boot->fSectorSize; - - const SizeT dir_max = max_lba / 300; // 5% for directory inodes - const SizeT inode_max = max_lba / 400; // 5% for inodes - - boot->fStartIND = mnt->fLbaStart + kHeFSINDStartOffset; - boot->fEndIND = boot->fStartIND + dir_max; - - boot->fStartIN = boot->fEndIND; - boot->fEndIN = boot->fStartIN + inode_max; - - boot->fStartBlock = boot->fEndIN; - boot->fEndBlock = drv_std_get_size(); - - boot->fINDCount = 0; - - boot->fDiskSize = drv_std_get_size(); - boot->fDiskStatus = kHeFSStatusUnlocked; - - boot->fDiskFlags = flags; - - if (mnt->fKind & kMassStorageDrive) { - boot->fDiskKind = kHeFSMassStorageDevice; - } else if (mnt->fKind & kHeFSOpticalDrive) { - boot->fDiskKind = kHeFSOpticalDrive; - } else { - boot->fDiskKind = kHeFSUnknown; - } - - boot->fVersion = kHeFSVersion; - - boot->fVID = kHeFSInvalidVID; - - boot->fChecksum = ke_calculate_crc32((Char*) boot, sizeof(HEFS_BOOT_NODE)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fOutput(mnt->fPacket); - - (Void)(kout << "Protocol: " << mnt->fProtocol() << kendl); - (Void)(kout8 << u8"Volume Name: " << boot->fVolName << kendl8); - (Void)(kout << "Start IND: " << hex_number(boot->fStartIND) << kendl); - (Void)(kout << "End IND: " << hex_number(boot->fEndIND) << kendl); - (Void)(kout << "Start IN: " << hex_number(boot->fStartIN) << kendl); - (Void)(kout << "End IN: " << hex_number(boot->fEndIN) << kendl); - (Void)(kout << "Start Block: " << hex_number(boot->fStartBlock) << kendl); - (Void)(kout << "End Block: " << hex_number(boot->fEndBlock) << kendl); - (Void)(kout << "Number of IND: " << hex_number(boot->fINDCount) << kendl); - (Void)(kout << "Sector Size: " << hex_number(boot->fSectorSize) << kendl); - (Void)(kout << "Drive Kind: " << Detail::hefs_drive_kind_to_string(boot->fDiskKind) << kendl); - - if (!mnt->fPacket.fPacketGood) { - err_global_get() = kErrorDiskIsCorrupted; - return NO; - } - - /// AMLALE: Better way to create default directories than before. - const Utf8Char* kFileMap[] = {u8"/", u8"/boot", u8"/system", u8"/network", - u8"/devices", u8"/media", u8"/dev", (Utf8Char*) nullptr}; - - SizeT i = 0; - while (kFileMap[++i] != nullptr) { - this->CreateINodeDirectory(mnt, kHeFSEncodingFlagsUTF8, kFileMap[i]); - } - - err_global_get() = kErrorSuccess; - - return YES; -} - -/// @brief Create a new directory on the disk. -/// @param mnt The mnt to write on. -/// @param flags The flags to use. -/// @param dir The directory to create the file in. -/// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt, - _Input const Int32 flags, - const Utf8Char* dir, - const BOOL delete_or_create) { - if (urt_string_len(dir) > kHeFSFileNameLen) { - err_global_get() = kErrorDisk; - return NO; - } - - HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No); - - rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fInput(mnt->fPacket); - - if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) { - err_global_get() = kErrorDisk; - return YES; - } - - if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) { - err_global_get() = kErrorDiskIsCorrupted; - - kout << "Invalid Boot Node, this can't continue!\r"; - - return NO; - } - - if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) { - kout << "Error: Invalid directory name.\r"; - - err_global_get() = kErrorInvalidData; - - return NO; - } - - if (Detail::hefsi_update_ind_status(boot, mnt, dir, flags, delete_or_create)) { - // todo: make it smarter for high-throughput. - Detail::hefsi_balance_ind(boot, mnt); - - mm_free_ptr((VoidPtr) boot); - return YES; - } - - mm_free_ptr((VoidPtr) boot); - return NO; -} - -_Output Bool HeFileSystemParser::RemoveINodeDirectory(_Input DriveTrait* mnt, - _Input const Int32 flags, - const Utf8Char* dir) { - return this->INodeDirectoryCtlManip(mnt, flags, dir, YES); -} - -_Output Bool HeFileSystemParser::CreateINodeDirectory(_Input DriveTrait* mnt, - _Input const Int32 flags, - const Utf8Char* dir) { - return this->INodeDirectoryCtlManip(mnt, flags, dir, NO); -} - -_Output Bool HeFileSystemParser::DeleteINode(_Input DriveTrait* mnt, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name, - const UInt8 kind) { - return this->INodeCtlManip(mnt, flags, dir, name, YES, kind); -} - -_Output Bool HeFileSystemParser::CreateINode(_Input DriveTrait* mnt, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name, - const UInt8 kind) { - return this->INodeCtlManip(mnt, flags, dir, name, NO, kind); -} - -_Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr block, SizeT block_sz, - const Utf8Char* dir, const Utf8Char* name, - const UInt8 kind, const BOOL is_input) { - if (urt_string_len(dir) > kHeFSFileNameLen) { - err_global_get() = kErrorDisk; - return NO; - } - - if (urt_string_len(name) > kHeFSFileNameLen) { - err_global_get() = kErrorDisk; - return NO; - } - - HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) mm_alloc_ptr(sizeof(HEFS_BOOT_NODE), Yes, No); - - if (!boot) { - err_global_get() = kErrorInvalidData; - return NO; - } - - rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fInput(mnt->fPacket); - - if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) { - (Void)(kout << "Invalid Boot Node, OpenHeFS partition is invalid." << kendl); - mm_free_ptr((VoidPtr) boot); - err_global_get() = kErrorDisk; - return NO; - } - - auto start = Detail::hefsi_fetch_in(boot, mnt, dir, name, kind); - - if (start) { - (Void)(kout << hex_number(start->fHashPath) << kendl); - (Void)(kout << hex_number(start->fOffsetSliceLow) << kendl); - - if (start->fOffsetSliceLow && start->fHashPath) { - mnt->fPacket.fPacketLba = ((UInt64) start->fOffsetSliceHigh << 32) | start->fOffsetSliceLow; - mnt->fPacket.fPacketSize = block_sz; - mnt->fPacket.fPacketContent = block; - - if (is_input) { - mnt->fInput(mnt->fPacket); - } else { - if (start->fFlags & kHeFSFlagsReadOnly) { - mm_free_ptr((VoidPtr) boot); - delete start; - - kout << "Error: File is read-only\r"; - - return NO; - } - - mnt->fOutput(mnt->fPacket); - } - } - } - - mm_free_ptr((VoidPtr) boot); - delete start; - return YES; -} - -/// @brief Create a new file on the disk. -/// @param mnt The mnt to write on. -/// @param flags The flags to use. -/// @param dir The directory to create the file in. -/// @param name The name of the file. -/// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input const Int32 flags, - const Utf8Char* dir, const Utf8Char* name, - const BOOL delete_or_create, const UInt8 kind) { - if (urt_string_len(name) > kHeFSFileNameLen) { - err_global_get() = kErrorDisk; - return NO; - } - - if (urt_string_len(dir) > kHeFSFileNameLen) { - err_global_get() = kErrorDisk; - return NO; - } - - HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) mm_alloc_ptr(sizeof(HEFS_INDEX_NODE), Yes, No); - - if (!node) { - err_global_get() = kErrorInvalidData; - return NO; - } - - rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE)); - - HEFS_BOOT_NODE* boot = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE)); - - if (!boot) { - mm_free_ptr((VoidPtr) node); - err_global_get() = kErrorInvalidData; - - return NO; - } - - rt_copy_memory_safe((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, - rt_string_len("fs/hefs-packet"), sizeof(mnt->fPacket.fPacketMime)); - - mnt->fPacket.fPacketLba = mnt->fLbaStart; - mnt->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); - mnt->fPacket.fPacketContent = boot; - - mnt->fInput(mnt->fPacket); - - if (!KStringBuilder::Equals(boot->fMagic, kHeFSMagic) || boot->fVersion != kHeFSVersion) { - err_global_get() = kErrorDisk; - return YES; - } - - if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) { - kout << "Error: Invalid file name.\r"; - - err_global_get() = kErrorInvalidData; - return NO; - } - - for (SizeT i_name = 0UL; i_name < urt_string_len(name); ++i_name) { - if (name[i_name] == u'/') { - err_global_get() = kErrorInvalidData; - return NO; - } - } - - if (KStringBuilder::Equals(dir, kHeFSSearchAllStr)) { - kout << "Error: Invalid directory name.\r"; - - err_global_get() = kErrorInvalidData; - return NO; - } - - node->fAccessed = 0; - node->fCreated = delete_or_create ? NO : YES; - node->fDeleted = delete_or_create ? 1UL : NO; - node->fModified = 0; - node->fSize = 0; - node->fKind = kind; - node->fFlags = flags; - node->fChecksum = 0; - node->fGID = 0; - node->fUID = 0; - node->fHashPath = Detail::hefsi_hash_64(name); - - if (Detail::hefsi_update_in_status(boot, mnt, dir, node, delete_or_create)) { - mm_free_ptr((VoidPtr) node); - - Detail::hefsi_balance_ind(boot, mnt); - - err_global_get() = kErrorSuccess; - return YES; - } - - mm_free_ptr((VoidPtr) node); - err_global_get() = kErrorDirectoryNotFound; - - return NO; -} - -STATIC IMountpoint kMountpoint; - -/// @brief Initialize the OpenHeFS filesystem. -/// @return To check its status, see err_local_get(). -Boolean OpenHeFS::fs_init_openhefs(Void) noexcept { - io_construct_main_drive(kMountpoint.A()); - - if (kMountpoint.A().fPacket.fPacketReadOnly == YES) { - kout << "Main disk cannot be mounted (read-only media).\r"; - return YES; - } - - return HeFileSystemParser{}.Format(&kMountpoint.A(), kHeFSEncodingFlagsUTF8, kHeFSDefaultVolumeName); -} -} // namespace Kernel - -#endif // ifdef __FSKIT_INCLUDES_OPENHEFS__ diff --git a/dev/kernel/src/FileMgr.cc b/dev/kernel/src/FileMgr.cc deleted file mode 100644 index 88b17470..00000000 --- a/dev/kernel/src/FileMgr.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/FileMgr.h> -#include <NeKit/Utils.h> - -/***********************************************************************************/ -/// @file FileMgr.cc -//! @brief File System Manager API. -///! @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -namespace Kernel { -STATIC IFilesystemMgr* kMountedFilesystem = nullptr; - -/// @brief FilesystemMgr getter. -/// @return The mounted filesystem. -_Output IFilesystemMgr* IFilesystemMgr::GetMounted() { - return kMountedFilesystem; -} - -/// @brief Unmount filesystem. -/// @return The unmounted filesystem. -_Output IFilesystemMgr* IFilesystemMgr::Unmount() { - if (kMountedFilesystem) { - auto mount = kMountedFilesystem; - kMountedFilesystem = nullptr; - - return mount; - } - - return nullptr; -} - -/// @brief Mount filesystem. -/// @param mount_ptr The filesystem to mount. -/// @return if it succeeded true, otherwise false. -_Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr) { - if (mount_ptr != nullptr) { - kMountedFilesystem = mount_ptr; - return Yes; - } - - return No; -} -} // namespace Kernel diff --git a/dev/kernel/src/GUIDWizard.cc b/dev/kernel/src/GUIDWizard.cc deleted file mode 100644 index 2d1218ed..00000000 --- a/dev/kernel/src/GUIDWizard.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: GUIDWizard.cc - Purpose: GUID helper code - - Revision History: - -======================================== */ - -#include <CFKit/GUIDWizard.h> -#include <NeKit/Ref.h> - -// begin of ascii 'readable' characters. (A, C, C, 1, 2) -#define kGUIDAsciiBegin 47 -// @brief Size of UUID. -#define kGUIDSize 37 - -namespace Kernel::CF::XRN::Version1 { -auto cf_make_sequence(const ArrayList<UInt32>& uuidSeq) -> Ref<GUIDSequence*> { - GUIDSequence* seq = new GUIDSequence(); - MUST_PASS(seq); - - Ref<GUIDSequence*> seq_ref{seq}; - - if (!seq) return seq_ref; - - seq_ref.Leak()->fUuid.fMs1 = uuidSeq[0]; - seq_ref.Leak()->fUuid.fMs2 = uuidSeq[1]; - seq_ref.Leak()->fUuid.fMs3 = uuidSeq[2]; - seq_ref.Leak()->fUuid.fMs4[0] = uuidSeq[3]; - seq_ref.Leak()->fUuid.fMs4[1] = uuidSeq[4]; - seq_ref.Leak()->fUuid.fMs4[2] = uuidSeq[5]; - seq_ref.Leak()->fUuid.fMs4[3] = uuidSeq[6]; - seq_ref.Leak()->fUuid.fMs4[4] = uuidSeq[7]; - seq_ref.Leak()->fUuid.fMs4[5] = uuidSeq[8]; - seq_ref.Leak()->fUuid.fMs4[6] = uuidSeq[9]; - seq_ref.Leak()->fUuid.fMs4[7] = uuidSeq[10]; - - return seq_ref; -} - -// @brief Tries to make a guid out of a string. -// This function is not complete for now -auto cf_try_guid_to_string(Ref<GUIDSequence*>& seq) -> ErrorOr<Ref<KString>> { - Char buf[kGUIDSize]; - - for (SizeT index = 0; index < 16; ++index) { - buf[index] = seq.Leak()->fU8[index] + kGUIDAsciiBegin; - } - - for (SizeT index = 16; index < 24; ++index) { - buf[index] = seq.Leak()->fU16[index] + kGUIDAsciiBegin; - } - - for (SizeT index = 24; index < 28; ++index) { - buf[index] = seq.Leak()->fU32[index] + kGUIDAsciiBegin; - } - - auto view = KStringBuilder::Construct(buf); - - if (view) return ErrorOr<Ref<KString>>{view.Leak()}; - - return ErrorOr<Ref<KString>>{kErrorInvalidData}; -} -} // namespace Kernel::CF::XRN::Version1 diff --git a/dev/kernel/src/GUIDWrapper.cc b/dev/kernel/src/GUIDWrapper.cc deleted file mode 100644 index ee29f911..00000000 --- a/dev/kernel/src/GUIDWrapper.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <CFKit/GUIDWrapper.h> - -namespace Kernel::CF::XRN {} diff --git a/dev/kernel/src/Gfx/FBDeviceInterface.cc b/dev/kernel/src/Gfx/FBDeviceInterface.cc deleted file mode 100644 index c5fac330..00000000 --- a/dev/kernel/src/Gfx/FBDeviceInterface.cc +++ /dev/null @@ -1,50 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <GfxKit/FB.h> - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive cleanup. -FBDeviceInterface::FBDeviceInterface(void (*out)(DeviceInterface* self, FBDevicePacket* outpacket), - void (*in)(DeviceInterface* self, FBDevicePacket* inpacket)) - : DeviceInterface(out, in) {} - -/// @brief Class desctructor -FBDeviceInterface::~FBDeviceInterface() = default; - -/// @brief Output operator. -/// @param mnt the disk mountpoint. -/// @return the class itself after operation. -FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) { - if (!pckt) return *this; - - if (pckt->fHeight == 0 || pckt->fWidth == 0) return *this; - - this->fOut(this, pckt); - - return *this; -} - -/// @brief Input operator. -/// @param mnt the disk mountpoint. -/// @return the class itself after operation. -FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) { - if (!pckt) return *this; - - this->fIn(this, pckt); - - return *this; -} - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const Char* FBDeviceInterface::Name() const { - return "/devices/fb{}"; -}
\ No newline at end of file diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc deleted file mode 100644 index 41d927f6..00000000 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <CFKit/Property.h> -#include <KernelKit/HardwareThreadScheduler.h> -#include <KernelKit/ProcessScheduler.h> - -/***********************************************************************************/ -///! @file HardwareThreadScheduler.cc -///! @brief This file handles multi processing in the Kernel. -///! @brief Multi processing is needed for multi-tasking operations. -/***********************************************************************************/ - -namespace Kernel { -/***********************************************************************************/ -/// @note Those symbols are needed in order to switch and validate the stack. -/***********************************************************************************/ - -EXTERN_C Bool hal_check_task(HAL::StackFramePtr frame); -EXTERN_C Bool mp_register_task(HAL::StackFramePtr frame, ProcessID pid); - -STATIC HardwareThreadScheduler kHardwareThreadScheduler; - -///! A HardwareThread class takes care of it's owned hardware thread. -///! It has a stack for it's core. - -/***********************************************************************************/ -///! @brief C++ constructor. -/***********************************************************************************/ -HardwareThread::HardwareThread() = default; - -/***********************************************************************************/ -///! @brief C++ destructor. -/***********************************************************************************/ -HardwareThread::~HardwareThread() = default; - -/***********************************************************************************/ -//! @brief returns the id of the thread. -/***********************************************************************************/ -ThreadID& HardwareThread::ID() noexcept { - return fID; -} - -/***********************************************************************************/ -//! @brief returns the kind of thread we have. -/***********************************************************************************/ -ThreadKind& HardwareThread::Kind() noexcept { - return fKind; -} - -/***********************************************************************************/ -//! @brief is the thread busy? -//! @return whether the thread is busy or not. -/***********************************************************************************/ -Bool HardwareThread::IsBusy() noexcept { - return fBusy; -} - -/***********************************************************************************/ -/// @brief Get processor stack frame. -/***********************************************************************************/ - -HAL::StackFramePtr HardwareThread::StackFrame() noexcept { - MUST_PASS(this->fStack); - return this->fStack; -} - -Void HardwareThread::Busy(Bool busy) noexcept { - this->fBusy = busy; -} - -HardwareThread::operator bool() { - return this->fStack && !this->fBusy; -} - -/***********************************************************************************/ -/// @brief Wakeup the processor. -/***********************************************************************************/ - -Void HardwareThread::Wake(const bool wakeup) noexcept { - this->fWakeup = wakeup; -} - -/***********************************************************************************/ -/// @brief Switch to hardware thread. -/// @param stack the new hardware thread. -/// @retval true stack was changed, code is running. -/// @retval false stack is invalid, previous code is running. -/***********************************************************************************/ -Bool HardwareThread::Switch(HAL::StackFramePtr frame) { - if (!frame) { - return NO; - } - - if (!hal_check_task(frame)) { - return NO; - } - - this->fStack = frame; - return mp_register_task(fStack, this->fID); -} - -/***********************************************************************************/ -///! @brief Tells if processor is waked up. -/***********************************************************************************/ -bool HardwareThread::IsWakeup() noexcept { - return this->fWakeup; -} - -/***********************************************************************************/ -///! @brief Constructor and destructors. -///! @brief Default constructor. -/***********************************************************************************/ - -HardwareThreadScheduler::HardwareThreadScheduler() = default; - -/***********************************************************************************/ -///! @brief Default destructor. -/***********************************************************************************/ -HardwareThreadScheduler::~HardwareThreadScheduler() = default; - -/***********************************************************************************/ -/// @brief Shared singleton function -/***********************************************************************************/ -HardwareThreadScheduler& HardwareThreadScheduler::The() { - return kHardwareThreadScheduler; -} - -/***********************************************************************************/ -/// @brief Get Stack Frame of AP. -/***********************************************************************************/ -HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept { - return fThreadList[fCurrentThreadIdx].fStack; -} - -/***********************************************************************************/ -/** - * Get Hardware thread at index. - * @param idx the index - * @return the reference to the hardware thread. - */ -/***********************************************************************************/ -Ref<HardwareThread*> HardwareThreadScheduler::operator[](SizeT idx) { - if (idx > kMaxAPInsideSched) { - HardwareThread* kFakeThread = nullptr; - return {kFakeThread}; - } - - fCurrentThreadIdx = idx; - return &fThreadList[idx]; -} - -/***********************************************************************************/ -/** - * Check if thread pool isn't empty. - * @return - */ -/***********************************************************************************/ -HardwareThreadScheduler::operator bool() noexcept { - return !fThreadList.Empty(); -} - -/***********************************************************************************/ -/** - * Reverse operator bool - * @return - */ -/***********************************************************************************/ -bool HardwareThreadScheduler::operator!() noexcept { - return fThreadList.Empty(); -} - -/***********************************************************************************/ -/// @brief Returns the amount of core present. -/// @return the number of APs. -/***********************************************************************************/ -SizeT HardwareThreadScheduler::Capacity() noexcept { - return fThreadList.Count(); -} -} // namespace Kernel diff --git a/dev/kernel/src/HeapMgr.cc b/dev/kernel/src/HeapMgr.cc deleted file mode 100644 index 848a0377..00000000 --- a/dev/kernel/src/HeapMgr.cc +++ /dev/null @@ -1,260 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/KPC.h> -#include <NeKit/Crc32.h> -#include <NeKit/PageMgr.h> -#include <NeKit/Utils.h> - -/* ======================================== - - Revision History: - 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field. - 20/10/24: FIX: Fix mm_new_ and mm_delete_ APIs inside HeapMgr.h header. (amlal) - 27/01/25: REFACTOR: Reworked code as the memory manager. - 25/03/25: REFACTOR: Refactor HeapMgr code and log freed address location. - - ======================================== */ - -//! @file HeapMgr.cc -//! @brief Heap system that serves as the main memory manager. - -#define kHeapMgrMagic (0xD4D75) -#define kHeapMgrAlignSz (4U) - -namespace Kernel { -/// @brief Implementation details. -namespace Detail { - struct PACKED MM_INFORMATION_BLOCK; - - /// @brief Kernel heap information block. - /// Located before the address bytes. - /// | HIB | CLASS/STRUCT/DATA TYPES... | - struct PACKED MM_INFORMATION_BLOCK final { - ///! @brief 32-bit value which contains the magic number of the heap. - UInt32 fMagic : 24; - - ///! @brief Is the heap present? - UInt8 fPresent : 1; - - /// @brief Is this value writable? - UInt8 fWriteRead : 1; - - /// @brief Is this value owned by the user? - UInt8 fUser : 1; - - /// @brief Is this a page pointer? - UInt8 fPage : 1; - - /// @brief 32-bit CRC checksum. - UInt32 fCRC32; - - /// @brief 64-bit Allocation flags. - UInt16 fFlags; - - /// @brief 64-bit pointer size. - SizeT fSize; - - /// @brief 64-bit target offset pointer. - UIntPtr fOffset; - - /// @brief Padding. - UInt32 fPad; - - /// @brief Padding bytes for header. - UInt8 fPadding[kHeapMgrAlignSz]; - }; - - /// @brief Check for heap address validity. - /// @param heap_ptr The address_ptr to check. - /// @return Bool if the pointer is valid or not. - _Output auto mm_check_ptr_address(VoidPtr heap_ptr) -> Bool { - if (!heap_ptr) return false; - - IntPtr base_ptr = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK); - - /// Add that check in case we're having an integer underflow. /// - - if (base_ptr < 0) { - return false; - } - - return true; - } - - typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR; -} // namespace Detail - -STATIC PageMgr kPageMgr; - -/// @brief Allocate chunk of memory. -/// @param sz Size of pointer -/// @param wr Read Write bit. -/// @param user User enable bit. -/// @return The newly allocated pointer. -_Output VoidPtr mm_alloc_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { - auto sz_fix = sz; - - if (sz_fix == 0) return nullptr; - - sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK); - - auto wrapper = kPageMgr.Request(wr, user, No, sz_fix, pad_amount); - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>(wrapper.VirtualAddress() + - sizeof(Detail::MM_INFORMATION_BLOCK)); - - heap_info_ptr->fSize = sz_fix; - heap_info_ptr->fMagic = kHeapMgrMagic; - heap_info_ptr->fCRC32 = 0U; // dont fill it for now. - heap_info_ptr->fOffset = - reinterpret_cast<UIntPtr>(heap_info_ptr) + sizeof(Detail::MM_INFORMATION_BLOCK); - heap_info_ptr->fPage = No; - heap_info_ptr->fWriteRead = wr; - heap_info_ptr->fUser = user; - heap_info_ptr->fPresent = Yes; - heap_info_ptr->fPad = pad_amount; - - rt_set_memory(heap_info_ptr->fPadding, 0, kHeapMgrAlignSz); - - auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fOffset); - - (Void)(kout << "HeapMgr: Registered heap address: " - << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl); - - return result; -} - -/// @brief Makes a page heap. -/// @param heap_ptr the pointer to make a page heap. -/// @return kErrorSuccess if successful, otherwise an error code. -_Output Int32 mm_make_page(VoidPtr heap_ptr) { - if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent; - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr - - sizeof(Detail::MM_INFORMATION_BLOCK)); - - if (!heap_info_ptr) return kErrorHeapNotPresent; - - heap_info_ptr->fPage = true; - - (Void)(kout << "HeapMgr: Registered page from heap address: " - << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl); - - return kErrorSuccess; -} - -/// @brief Overwrites and set the flags of a heap header. -/// @param heap_ptr the pointer to update. -/// @param flags the flags to set. -_Output Int32 mm_set_ptr_flags(VoidPtr heap_ptr, UInt64 flags) { - if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent; - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr - - sizeof(Detail::MM_INFORMATION_BLOCK)); - - if (!heap_info_ptr) return kErrorHeapNotPresent; - - heap_info_ptr->fFlags = flags; - - return kErrorSuccess; -} - -/// @brief Gets the flags of a heap header. -/// @param heap_ptr the pointer to get. -_Output UInt64 mm_get_ptr_flags(VoidPtr heap_ptr) { - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr - - sizeof(Detail::MM_INFORMATION_BLOCK)); - - if (!heap_info_ptr) return kErrorHeapNotPresent; - - return heap_info_ptr->fFlags; -} - -/// @brief Declare pointer as free. -/// @param heap_ptr the pointer. -/// @return -_Output Int32 mm_free_ptr(VoidPtr heap_ptr) { - if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent; - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) (heap_ptr) - - sizeof(Detail::MM_INFORMATION_BLOCK)); - - if (heap_info_ptr && heap_info_ptr->fMagic == kHeapMgrMagic) { - if (!heap_info_ptr->fPresent) { - return kErrorHeapNotPresent; - } - - heap_info_ptr->fSize = 0UL; - heap_info_ptr->fPresent = No; - heap_info_ptr->fOffset = 0; - heap_info_ptr->fCRC32 = 0; - heap_info_ptr->fWriteRead = No; - heap_info_ptr->fUser = No; - heap_info_ptr->fMagic = 0; - heap_info_ptr->fPad = 0; - - (Void)(kout << "HeapMgr: Freed heap address: " - << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << kendl); - - PTEWrapper page_wrapper( - No, No, No, - reinterpret_cast<UIntPtr>(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); - - Ref<PTEWrapper> pte_address{page_wrapper}; - - kPageMgr.Free(pte_address); - - return kErrorSuccess; - } - - return kErrorInternal; -} - -/// @brief Check if pointer is a valid Kernel pointer. -/// @param heap_ptr the pointer -/// @return if it exists. -_Output Boolean mm_is_valid_ptr(VoidPtr heap_ptr) { - if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) { - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) (heap_ptr) - - sizeof(Detail::MM_INFORMATION_BLOCK)); - - return (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kHeapMgrMagic); - } - - return No; -} - -/// @brief Protect the heap with a CRC value. -/// @param heap_ptr HIB pointer. -/// @return if it valid: point has crc now., otherwise fail. -_Output Boolean mm_protect_ptr(VoidPtr heap_ptr) { - if (heap_ptr) { - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast<Detail::MM_INFORMATION_BLOCK_PTR>((UIntPtr) heap_ptr - - sizeof(Detail::MM_INFORMATION_BLOCK)); - - /// if valid, present and is heap header, then compute crc32 - if (heap_info_ptr && heap_info_ptr->fPresent && kHeapMgrMagic == heap_info_ptr->fMagic) { - heap_info_ptr->fCRC32 = - ke_calculate_crc32((Char*) heap_info_ptr->fOffset, heap_info_ptr->fSize); - - return Yes; - } - } - - return No; -} -} // namespace Kernel diff --git a/dev/kernel/src/IDylibObject.cc b/dev/kernel/src/IDylibObject.cc deleted file mode 100644 index 61191af1..00000000 --- a/dev/kernel/src/IDylibObject.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* - * ======================================================== - * - * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#include <KernelKit/DebugOutput.h> -#include <KernelKit/IDylibObject.h> - -using namespace Kernel; diff --git a/dev/kernel/src/IFS.cc b/dev/kernel/src/IFS.cc deleted file mode 100644 index 4679b8a3..00000000 --- a/dev/kernel/src/IFS.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DriveMgr.h> -#include <KernelKit/FileMgr.h> - -/************************************************************* - * - * File: IFS.cc - * Purpose: Filesystem to mountpoint interface. - * Date: 05/26/2025 - * - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - *************************************************************/ - -/// Useful macros regarding the IFS. - -#define fsi_ifs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS) -#define fsi_ifs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS) - -namespace Kernel { -/// @brief Read from fs disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_ifs_read(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) { - if (!Mnt) return kErrorDisk; - - DrvTrait.fPacket.fPacketGood = false; - - switch (DrvIndex) { - case IMountpoint::kDriveIndexA: { - fsi_ifs_read(A, DrvTrait.fPacket, Mnt); - break; - } - case IMountpoint::kDriveIndexB: { - fsi_ifs_read(B, DrvTrait.fPacket, Mnt); - break; - } - case IMountpoint::kDriveIndexC: { - fsi_ifs_read(C, DrvTrait.fPacket, Mnt); - break; - } - case IMountpoint::kDriveIndexD: { - fsi_ifs_read(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood ? kErrorSuccess : kErrorDisk; -} - -/// @brief Write to fs disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_ifs_write(IMountpoint* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) { - if (!Mnt) return kErrorDisk; - - DrvTrait.fPacket.fPacketGood = false; - - switch (DrvIndex) { - case IMountpoint::kDriveIndexA: { - fsi_ifs_write(A, DrvTrait.fPacket, Mnt); - break; - } - case IMountpoint::kDriveIndexB: { - fsi_ifs_write(B, DrvTrait.fPacket, Mnt); - break; - } - case IMountpoint::kDriveIndexC: { - fsi_ifs_write(C, DrvTrait.fPacket, Mnt); - break; - } - case IMountpoint::kDriveIndexD: { - fsi_ifs_write(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood ? kErrorSuccess : kErrorDisk; -} -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc deleted file mode 100644 index 4ba9278d..00000000 --- a/dev/kernel/src/IPEFDylibObject.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ======================================================== - * - * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#include <KernelKit/DebugOutput.h> -#include <KernelKit/IPEFDylibObject.h> -#include <KernelKit/PEF.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/ThreadLocalStorage.h> -#include <NeKit/Defines.h> - -/* ======================================== - - Revision History: - - 01/02/24: Reworked dll ABI, expect a rtl_init_dylib_pef and - rtl_fini_dylib_pef (amlel) - - 15/02/24: Breaking changes, changed the name of the - routines. (amlel) - - 07/28/24: Replace rt_library_free with rtl_fini_dylib_pef - - 10/8/24: FIX: Fix log comment. - - ======================================== */ - -using namespace Kernel; - -/***********************************************************************************/ -/// @file IPEFDylibObject.cc -/// @brief PEF's Dylib runtime. -///! @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -/***********************************************************************************/ -/** @brief Library initializer. */ -/***********************************************************************************/ - -EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) { - IDylibRef dll_obj = tls_new_class<IPEFDylibObject>(); - - if (!dll_obj) { - process.Crash(); - return nullptr; - } - - dll_obj->Mount(new IPEFDylibObject::DylibTraits()); - - if (!dll_obj->Get()) { - tls_delete_class(dll_obj); - dll_obj = nullptr; - - process.Crash(); - - return nullptr; - } - - dll_obj->Get()->ImageObject = process.Image.LeakBlob().Leak().Leak(); - - if (!dll_obj->Get()->ImageObject) { - delete dll_obj->Get(); - - tls_delete_class(dll_obj); - dll_obj = nullptr; - - process.Crash(); - - return nullptr; - } - - dll_obj->Get()->ImageEntrypointOffset = - dll_obj->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart, 0), kPefCode); - - return dll_obj; -} - -/***********************************************************************************/ -/** @brief Frees the dll_obj. */ -/** @note Please check if the dll_obj got freed! */ -/** @param dll_obj The dll_obj to free. */ -/** @param successful Reports if successful or not. */ -/***********************************************************************************/ - -EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) { - MUST_PASS(successful); - - if (!successful) { - return; - } - - // sanity check (will also trigger a bug check if this fails) - if (dll_obj == nullptr) { - *successful = false; - process.Crash(); - } - - delete dll_obj->Get(); - delete dll_obj; - - dll_obj = nullptr; - - *successful = true; -} diff --git a/dev/kernel/src/IndexableProperty.cc b/dev/kernel/src/IndexableProperty.cc deleted file mode 100644 index 85207d4b..00000000 --- a/dev/kernel/src/IndexableProperty.cc +++ /dev/null @@ -1,45 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <CompilerKit/CompilerKit.h> -#include <FSKit/IndexableProperty.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/MutableArray.h> -#include <NeKit/Utils.h> - -/// @brief File indexer API for fast path access. -/// BUGS: 0 - -#define kMaxLenIndexer (256U) - -namespace Kernel { -namespace Indexer { - Index& IndexableProperty::Leak() noexcept { return fIndex; } - - Void IndexableProperty::AddFlag(UInt16 flag) { fFlags |= flag; } - - Void IndexableProperty::RemoveFlag(UInt16 flag) { fFlags &= ~(flag); } - - UInt16 IndexableProperty::HasFlag(UInt16 flag) { return fFlags & flag; } - - /// @brief Index a file into the indexer instance. - /// @param filename filesystem path to access. - /// @param filenameLen used bytes in path. - /// @param indexer the filesystem indexer. - /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)). - Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) { - if (!indexer.HasFlag(kIndexerClaimed)) { - indexer.RemoveFlag(kIndexerUnclaimed); - indexer.AddFlag(kIndexerClaimed); - rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(filename)), - (VoidPtr) indexer.Leak().Path, filenameLen, kIndexerCatalogNameLength); - - (Void)(kout << "FSKit: Indexed new file: " << filename << kendl); - } - } -} // namespace Indexer -} // namespace Kernel diff --git a/dev/kernel/src/Json.cc b/dev/kernel/src/Json.cc deleted file mode 100644 index 198aed99..00000000 --- a/dev/kernel/src/Json.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Json.h> - -namespace Kernel {}
\ No newline at end of file diff --git a/dev/kernel/src/KPC.cc b/dev/kernel/src/KPC.cc deleted file mode 100644 index 4318b9cd..00000000 --- a/dev/kernel/src/KPC.cc +++ /dev/null @@ -1,39 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/HeapMgr.h> -#include <KernelKit/KPC.h> -#include <NeKit/KernelPanic.h> - -namespace Kernel { -STATIC Bool kRaiseOnBugCheck = false; - -/// @brief Does a system wide bug check. -/// @param void no params are needed. -/// @return if error-free: false, otherwise true. -Boolean err_bug_check_raise(Void) noexcept { - Char* ptr = new Char[512]; - - if (ptr == nullptr) goto bug_check_fail; - - if (!mm_is_valid_ptr(ptr)) goto bug_check_fail; - - delete[] ptr; - - return Yes; - -bug_check_fail: - if (ptr) delete[] ptr; - - ptr = nullptr; - - if (kRaiseOnBugCheck) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR); - } - - return No; -} -} // namespace Kernel diff --git a/dev/kernel/src/KernelTaskScheduler.cc b/dev/kernel/src/KernelTaskScheduler.cc deleted file mode 100644 index c3628765..00000000 --- a/dev/kernel/src/KernelTaskScheduler.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - FILE: KernelTaskScheduler.cc - PURPOSE: Kernel Task scheduler. - -======================================== */ - -#include <KernelKit/KernelTaskScheduler.h> - -/***********************************************************************************/ -/// @file KernelTaskScheduler.cc -/// @brief Kernel Task scheduler. -/// @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -namespace Kernel { -EXTERN_C Void hal_switch_kernel_task(HAL::StackFramePtr frame, KID kid); - -Bool KernelTaskHelper::Add(HAL::StackFramePtr frame_ptr, KID new_kid) { - NE_UNUSED(frame_ptr); - NE_UNUSED(new_kid); - - return NO; -} - -Bool KernelTaskHelper::Remove(const KID kid) { - NE_UNUSED(kid); - - return NO; -} - -Bool KernelTaskHelper::CanBeScheduled(const KERNEL_TASK& task) { - return task.Kid > 0 && task.Image.HasCode(); -} -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/src/LockDelegate.cc b/dev/kernel/src/LockDelegate.cc deleted file mode 100644 index 2fe2b464..00000000 --- a/dev/kernel/src/LockDelegate.cc +++ /dev/null @@ -1,11 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/LockDelegate.h> - -namespace Kernel { -/// @note Leave it empty for now. -} // namespace Kernel diff --git a/dev/kernel/src/MutableArray.cc b/dev/kernel/src/MutableArray.cc deleted file mode 100644 index 3c86e8b8..00000000 --- a/dev/kernel/src/MutableArray.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/MutableArray.h> diff --git a/dev/kernel/src/Network/IPAddress.cc b/dev/kernel/src/Network/IPAddress.cc deleted file mode 100644 index 98279979..00000000 --- a/dev/kernel/src/Network/IPAddress.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Utils.h> -#include <NetworkKit/IP.h> - -namespace Kernel { -UInt8* RawIPAddress::Address() { - return fAddr; -} - -RawIPAddress::RawIPAddress(UInt8 bytes[4]) { - rt_copy_memory(bytes, fAddr, 4); -} - -BOOL RawIPAddress::operator==(const RawIPAddress& ipv4) { - for (Size index = 0; index < 4; ++index) { - if (ipv4.fAddr[index] != fAddr[index]) return false; - } - - return true; -} - -BOOL RawIPAddress::operator!=(const RawIPAddress& ipv4) { - for (Size index = 0; index < 4; ++index) { - if (ipv4.fAddr[index] == fAddr[index]) return false; - } - - return true; -} - -UInt8& RawIPAddress::operator[](const Size& index) { - kout << "[RawIPAddress::operator[]] Fetching Index...\r"; - - static UInt8 IP_PLACEHOLDER = '0'; - if (index >= 4) return IP_PLACEHOLDER; - - return fAddr[index]; -} - -RawIPAddress6::RawIPAddress6(UInt8 bytes[16]) { - rt_copy_memory(bytes, fAddr, 16); -} - -UInt8& RawIPAddress6::operator[](const Size& index) { - kout << "[RawIPAddress6::operator[]] Fetching Index...\r"; - - static UInt8 IP_PLACEHOLDER = '0'; - if (index >= 16) return IP_PLACEHOLDER; - - return fAddr[index]; -} - -bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) { - for (SizeT index = 0; index < 16; ++index) { - if (ipv6.fAddr[index] != fAddr[index]) return false; - } - - return true; -} - -bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) { - for (SizeT index = 0; index < 16; ++index) { - if (ipv6.fAddr[index] == fAddr[index]) return false; - } - - return true; -} - -/// @todo -ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6) { - NE_UNUSED(ipv6); - auto str = KStringBuilder::Construct(""); - return str; -} - -/// @todo -ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4) { - NE_UNUSED(ipv4); - auto str = KStringBuilder::Construct(""); - return str; -} - -/// @note Doesn't catch IPs such as 256.999.0.1, UNSAFE! -bool IPFactory::IpCheckVersion4(const Char* ip) { - if (!ip) return NO; - - Int32 cnter = 0; - Int32 dot_cnter = 0; - - constexpr const auto kIP4DotCharacter = '.'; - - for (SizeT base = 0; base < rt_string_len(ip); ++base) { - if (ip[base] == kIP4DotCharacter) { - cnter = 0; - ++dot_cnter; - } else { - if (ip[base] > '5' || ip[base] < '0') return NO; - if (!rt_is_alnum(ip[base])) return NO; - if (cnter == 3) return NO; - - ++cnter; - } - } - - if (dot_cnter != 3) return NO; - - return YES; -} -} // namespace Kernel diff --git a/dev/kernel/src/Network/IPCAddress.cc b/dev/kernel/src/Network/IPCAddress.cc deleted file mode 100644 index 2da5ac0a..00000000 --- a/dev/kernel/src/Network/IPCAddress.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - ======================================== */ - -#include <KernelKit/KPC.h> -#include <KernelKit/ProcessScheduler.h> -#include <NetworkKit/IPC.h> - -namespace Kernel { -bool IPC_ADDR::operator==(const IPC_ADDR& addr) noexcept { - return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; -} - -bool IPC_ADDR::operator==(IPC_ADDR& addr) noexcept { - return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; -} - -bool IPC_ADDR::operator!=(const IPC_ADDR& addr) noexcept { - return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam; -} - -bool IPC_ADDR::operator!=(IPC_ADDR& addr) noexcept { - return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam; -} -} // namespace Kernel diff --git a/dev/kernel/src/Network/IPCMessage.cc b/dev/kernel/src/Network/IPCMessage.cc deleted file mode 100644 index b376b7c8..00000000 --- a/dev/kernel/src/Network/IPCMessage.cc +++ /dev/null @@ -1,129 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/KPC.h> -#include <KernelKit/ProcessScheduler.h> -#include <NetworkKit/IPC.h> - -namespace Kernel { -/***********************************************************************************/ -/// @internal internal use for IPC system only. -/// @brief The internal sanitize function. -/***********************************************************************************/ -Bool ipc_int_sanitize_packet(IPC_MSG* pckt) { - auto endian = RTL_ENDIAN(pckt, ((Char*) pckt)[0]); - - switch (endian) { - case Endian::kEndianBig: { - if (pckt->IpcEndianess == kIPCLittleEndian) goto ipc_check_failed; - - break; - } - case Endian::kEndianLittle: { - if (pckt->IpcEndianess == kIPCBigEndian) goto ipc_check_failed; - - break; - } - case Endian::kEndianMixed: { - if (pckt->IpcEndianess == kIPCMixedEndian) goto ipc_check_failed; - - break; - } - default: - goto ipc_check_failed; - } - - if (pckt->IpcFrom == pckt->IpcTo || pckt->IpcPacketSize > kIPCMsgSize) { - goto ipc_check_failed; - } - - return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic; - -ipc_check_failed: - err_local_get() = kErrorIPC; - return false; -} - -/***********************************************************************************/ -/// @brief Sanitize packet function -/// @retval true packet is correct. -/// @retval false packet is incorrect and process has crashed. -/***********************************************************************************/ -Bool ipc_sanitize_packet(IPC_MSG* pckt) { - if (!pckt || !ipc_int_sanitize_packet(pckt)) { - return false; - } - - return true; -} - -/***********************************************************************************/ -/// @brief Construct packet function -/// @retval true packet is correct. -/// @retval false packet is incorrect and process has crashed. -/***********************************************************************************/ -Bool ipc_construct_packet(_Output IPC_MSG** pckt_in) { - // don't act if it's not even valid. - if (!pckt_in) return false; - - if (!*pckt_in) *pckt_in = new IPC_MSG(); - - MUST_PASS(*pckt_in); - - if (*pckt_in) { - const auto endianess = RTL_ENDIAN((*pckt_in), ((Char*) (*pckt_in))[0]); - - (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic; - - (*pckt_in)->IpcEndianess = static_cast<UInt8>(endianess); - (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG); - - (*pckt_in)->IpcTo.UserProcessID = 0; - (*pckt_in)->IpcTo.UserProcessTeam = 0; - - (*pckt_in)->IpcFrom.UserProcessID = 0; - (*pckt_in)->IpcFrom.UserProcessTeam = 0; - - (*pckt_in)->IpcLock = kIPCLockFree; - - return Yes; - } - - return No; -} - -/***********************************************************************************/ -/// @brief Pass message from **src** to **target** -/// @param src Source message. -/// @param target Target message. -/***********************************************************************************/ -Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) noexcept { - if (src && target && (target != src)) { - if (src->IpcMsgSz > target->IpcMsgSz) return No; - if (target->IpcMsgSz > src->IpcMsgSz) return No; - - auto timeout = 0U; - - const auto kLimitTimeout = 1000000U; - - while ((target->IpcLock % kIPCLockUsed) != 0) { - if (timeout > kLimitTimeout) { - return No; - } - } - - ++target->IpcLock; - - rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcMsgSz, kIPCMsgSize); - - --target->IpcLock; - - return Yes; - } - - return No; -} -} // namespace Kernel diff --git a/dev/kernel/src/Network/MACAddressGetter.cc b/dev/kernel/src/Network/MACAddressGetter.cc deleted file mode 100644 index 09d82a78..00000000 --- a/dev/kernel/src/Network/MACAddressGetter.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NetworkKit/MAC.h> - -namespace Kernel { -Array<UInt8, kMACAddrLen>& MacAddressGetter::AsBytes() { - return this->fMacAddress; -} -} // namespace Kernel diff --git a/dev/kernel/src/Network/NetworkDevice.cc b/dev/kernel/src/Network/NetworkDevice.cc deleted file mode 100644 index 450c0191..00000000 --- a/dev/kernel/src/Network/NetworkDevice.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Utils.h> -#include <NetworkKit/NetworkDevice.h> - -namespace Kernel { -/// \brief Getter for fNetworkName. -/// \return Network device name. -const Char* NetworkDevice::Name() const { - return "/devices/net/net{}"; -} - -/// \brief Setter for fNetworkName. -Boolean NetworkDevice::Name(const Char* name) { - if (name == nullptr) return NO; - - if (*name == 0) return NO; - - if (rt_string_len(name) > rt_string_len(this->Name())) return NO; - - rt_copy_memory((VoidPtr) name, (VoidPtr) this->Name(), rt_string_len(this->Name())); - - return YES; -} -} // namespace Kernel diff --git a/dev/kernel/src/New+Delete.cc b/dev/kernel/src/New+Delete.cc deleted file mode 100644 index ba37e7ec..00000000 --- a/dev/kernel/src/New+Delete.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/HeapMgr.h> -#include <NeKit/New.h> - -void* operator new[](size_t sz) { - if (sz == 0) ++sz; - - return Kernel::mm_alloc_ptr(sz, true, false); -} - -void* operator new(size_t sz) { - if (sz == 0) ++sz; - - return Kernel::mm_alloc_ptr(sz, true, false); -} - -void operator delete[](void* ptr) noexcept { - if (ptr == nullptr) return; - - Kernel::mm_free_ptr(ptr); -} - -void operator delete(void* ptr) noexcept { - if (ptr == nullptr) return; - - Kernel::mm_free_ptr(ptr); -} - -void operator delete(void* ptr, size_t sz) { - if (ptr == nullptr) return; - - NE_UNUSED(sz); - - Kernel::mm_free_ptr(ptr); -} - -void operator delete[](void* ptr, size_t sz) { - if (ptr == nullptr) return; - - NE_UNUSED(sz); - - Kernel::mm_free_ptr(ptr); -} diff --git a/dev/kernel/src/OwnPtr.cc b/dev/kernel/src/OwnPtr.cc deleted file mode 100644 index e223d448..00000000 --- a/dev/kernel/src/OwnPtr.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/OwnPtr.h> diff --git a/dev/kernel/src/PE32CodeMgr.cc b/dev/kernel/src/PE32CodeMgr.cc deleted file mode 100644 index a8440c23..00000000 --- a/dev/kernel/src/PE32CodeMgr.cc +++ /dev/null @@ -1,258 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <CFKit/Utils.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/PE32CodeMgr.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/OwnPtr.h> - -namespace Kernel { -namespace Detail { - /***********************************************************************************/ - /// @brief Get the PE32+ platform signature according to the compiled architecture. - /***********************************************************************************/ - - UInt32 ldr_get_platform_pe(void) noexcept { -#if defined(__NE_AMD64__) - return kPEPlatformAMD64; -#elif defined(__NE_ARM64__) - return kPEPlatformARM64; -#else - return kPEPlatformInvalid; -#endif // __32x0__ || __64x0__ || __x86_64__ - } -} // namespace Detail - -/***********************************************************************************/ -/// @brief PE32+ loader constructor w/ blob. -/// @param blob file blob. -/***********************************************************************************/ - -PE32Loader::PE32Loader(const VoidPtr blob) : fCachedBlob(blob) { - MUST_PASS(fCachedBlob); - fBad = false; -} - -/***********************************************************************************/ -/// @brief PE32+ loader constructor. -/// @param path the filesystem path. -/***********************************************************************************/ - -PE32Loader::PE32Loader(const Char* path) : fCachedBlob(nullptr), fBad(false) { - fFile.New(const_cast<Char*>(path), kRestrictRB); - fPath = KStringBuilder::Construct(path).Leak(); - - auto kPefHeader = "PE32_BLOB"; - fCachedBlob = fFile->Read(kPefHeader, 0); - - if (!fCachedBlob) fBad = YES; -} - -/***********************************************************************************/ -/// @brief PE32+ destructor. -/***********************************************************************************/ - -PE32Loader::~PE32Loader() { - if (fCachedBlob) mm_free_ptr(fCachedBlob); - - fFile.Delete(); -} - -/***********************************************************************************/ -/// @brief Finds the section according to its name. -/// @param name name of section. -/***********************************************************************************/ - -ErrorOr<VoidPtr> PE32Loader::FindSectionByName(const Char* name) { - if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData}; - - LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header((const Char*) fCachedBlob); - LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header((const Char*) fCachedBlob); - - if (!header_ptr || !opt_header_ptr) return ErrorOr<VoidPtr>{kErrorInvalidData}; - -#ifdef __NE_AMD64__ - if (header_ptr->Machine != kPeMachineAMD64 || header_ptr->Signature != kPeSignature) { - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } - -#elif defined(__NE_ARM64__) - if (header_ptr->Machine != kPeMachineARM64 || header_ptr->Signature != kPeSignature) { - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } -#endif // __NE_AMD64__ || __NE_ARM64__ - - if (header_ptr->NumberOfSections < 1) { - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } - - LDR_SECTION_HEADER_PTR secs = - (LDR_SECTION_HEADER_PTR) (((Char*) opt_header_ptr) + header_ptr->SizeOfOptionalHeader); - - for (SizeT sectIndex = 0; sectIndex < header_ptr->NumberOfSections; ++sectIndex) { - LDR_SECTION_HEADER_PTR sect = &secs[sectIndex]; - - if (KStringBuilder::Equals(name, sect->Name)) { - return ErrorOr<VoidPtr>(sect); - } - } - - return ErrorOr<VoidPtr>{kErrorInvalidData}; -} - -/***********************************************************************************/ -/// @brief Finds the symbol according to it's name. -/// @param name name of symbol. -/// @param kind kind of symbol we want. -/***********************************************************************************/ - -ErrorOr<VoidPtr> PE32Loader::FindSymbol(const Char* name, Int32 kind) { - if (!name || *name == 0) return ErrorOr<VoidPtr>{kErrorInvalidData}; - - auto section_name = "\0"; - - switch (kind) { - case kPETypeData: - section_name = ".data"; - break; - case kPETypeBSS: - section_name = ".bss"; - break; - case kPETypeText: - section_name = ".text"; - break; - default: - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } - - auto sec = this->FindSectionByName(section_name); - LDR_SECTION_HEADER_PTR* sec_ptr = (LDR_SECTION_HEADER_PTR*) sec.Leak().Leak(); - - if (!sec_ptr || !*sec_ptr) return ErrorOr<VoidPtr>{kErrorInvalidData}; - - LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header((const Char*) fCachedBlob); - - if (opt_header_ptr) { - LDR_DATA_DIRECTORY_PTR data_dirs = - (LDR_DATA_DIRECTORY_PTR) ((UInt8*) opt_header_ptr + sizeof(LDR_OPTIONAL_HEADER)); - - LDR_DATA_DIRECTORY_PTR export_dir_entry = &data_dirs[0]; - - if (export_dir_entry->VirtualAddress == 0 || export_dir_entry->Size == 0) - return ErrorOr<VoidPtr>{kErrorInvalidData}; - - LDR_EXPORT_DIRECTORY* export_dir = - (LDR_EXPORT_DIRECTORY*) ((UIntPtr) fCachedBlob + export_dir_entry->VirtualAddress); - - UInt32* name_table = (UInt32*) ((UIntPtr) fCachedBlob + export_dir->AddressOfNames); - UInt16* ordinal_table = (UInt16*) ((UIntPtr) fCachedBlob + export_dir->AddressOfNameOrdinal); - UInt32* function_table = (UInt32*) ((UIntPtr) fCachedBlob + export_dir->AddressOfFunctions); - - for (UInt32 i = 0; i < export_dir->NumberOfNames; ++i) { - const char* exported_name = (const char*) ((UIntPtr) fCachedBlob + name_table[i]); - - if (KStringBuilder::Equals(exported_name, name)) { - UInt16 ordinal = ordinal_table[i]; - UInt32 rva = function_table[ordinal]; - - VoidPtr symbol_addr = (VoidPtr) ((UIntPtr) fCachedBlob + rva); - - return ErrorOr<VoidPtr>{symbol_addr}; - } - } - } - - return ErrorOr<VoidPtr>{kErrorInvalidData}; -} - -/// @brief Finds the executable entrypoint. -/// @return -ErrorOr<VoidPtr> PE32Loader::FindStart() { - if (auto sym = this->FindSymbol(kPeImageStart, 0); sym) return sym; - - return ErrorOr<VoidPtr>(kErrorExecutable); -} - -/// @brief Tells if the executable is loaded or not. -/// @return Whether it's not bad and is cached. -bool PE32Loader::IsLoaded() noexcept { - return !fBad && fCachedBlob; -} - -const Char* PE32Loader::Path() { - return fPath.Leak().CData(); -} - -const Char* PE32Loader::AsString() { -#ifdef __32x0__ - return "32x0 PE"; -#elif defined(__64x0__) - return "64x0 PE"; -#elif defined(__x86_64__) - return "x86_64 PE"; -#elif defined(__aarch64__) - return "AARCH64 PE"; -#elif defined(__powerpc64__) - return "POWER64 PE"; -#else - return "???? PE"; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ -} - -const Char* PE32Loader::MIME() { - return kPeApplicationMime; -} - -ErrorOr<VoidPtr> PE32Loader::GetBlob() { - return ErrorOr<VoidPtr>{this->fCachedBlob}; -} - -namespace Utils { - ProcessID rtl_create_user_process(PE32Loader& exec, const Int32& process_kind) noexcept { - auto errOrStart = exec.FindStart(); - - if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID; - - auto symname = exec.FindSymbol(kPeImageStart, 0); - - if (!symname) { - symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PE32+")}; - } - - auto id = - UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()), - errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - - mm_free_ptr(symname.Leak().Leak()); - - if (id != kSchedInvalidPID) { - auto stacksym = exec.FindSymbol(kPeStackSizeSymbol, 0); - - if (!stacksym) { - stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; - } - - if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) { - *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz; - } - - UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind; - UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize = - *(UIntPtr*) stacksym.Leak().Leak(); - - mm_free_ptr(stacksym.Leak().Leak()); - stacksym.Leak().Leak() = nullptr; - } - - return id; - } -} // namespace Utils -} // namespace Kernel
\ No newline at end of file diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc deleted file mode 100644 index c0a79c32..00000000 --- a/dev/kernel/src/PEFCodeMgr.cc +++ /dev/null @@ -1,335 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - Copyright (C) 2025, Amlal El Mahrouss & NeKernel contributors, licensed under the Apache 2.0 -license. - -======================================== */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DebugOutput.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/PEFCodeMgr.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/Defines.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/OwnPtr.h> -#include <NeKit/Utils.h> - -/// @author Amlal El Mahrouss (amlal@nekernel.org) -/// @brief PEF backend for the Code Manager. -/// @file PEFCodeMgr.cc - -/// @brief PEF stack size symbol. -#define kPefStackSizeSymbol "__PEFSizeOfReserveStack" -#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap" -#define kPefNameSymbol "__PEFProgramName" - -namespace Kernel { -namespace Detail { - /***********************************************************************************/ - /// @brief Get the PEF platform signature according to the compiled architecture. - /***********************************************************************************/ - static UInt32 ldr_get_platform(void) noexcept { -#if defined(__NE_32X0__) - return kPefArch32x0; -#elif defined(__NE_64X0__) - return kPefArch64x0; -#elif defined(__NE_AMD64__) - return kPefArchAMD64; -#elif defined(__NE_PPC64__) - return kPefArchPowerPC; -#elif defined(__NE_ARM64__) - return kPefArchARM64; -#else - return kPefArchInvalid; -#endif // __32x0__ || __64x0__ || __x86_64__ - } -} // namespace Detail - -/***********************************************************************************/ -/// @brief PEF loader constructor w/ blob. -/// @param blob file blob. -/***********************************************************************************/ -PEFLoader::PEFLoader(const VoidPtr blob) : fCachedBlob(blob) { - MUST_PASS(fCachedBlob); - - if (!fCachedBlob) { - this->fBad = YES; - return; - } - - PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); - - if (container->Abi == kPefAbi && - container->Count >= - 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */ - if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] && - container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] && - container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) { - return; - } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] && - container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] && - container->Magic[4] == kPefMagicFat[4]) { - /// This is a fat binary. Treat it as such. - this->fFatBinary = YES; - return; - } - } - - kout << "PEFLoader: warning: Binary format error!\r"; - - this->fFatBinary = NO; - this->fBad = YES; - - if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob); - this->fCachedBlob = nullptr; -} - -/***********************************************************************************/ -/// @brief PEF loader constructor. -/// @param path the filesystem path. -/***********************************************************************************/ -PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) { - fFile.New(const_cast<Char*>(path), kRestrictRB); - fPath = KStringBuilder::Construct(path).Leak(); - - constexpr auto kPefHeader = "PEF_CONTAINER"; - - /// @note zero here means that the FileMgr will read every container header inside the file. - fCachedBlob = fFile->Read(kPefHeader, 0UL); - - if (!fCachedBlob) { - this->fBad = YES; - return; - } - - PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); - - if (container->Abi == kPefAbi && - container->Count >= - 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */ - if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] && - container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] && - container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) { - return; - } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] && - container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] && - container->Magic[4] == kPefMagicFat[4]) { - /// This is a fat binary, treat it as such. - this->fFatBinary = YES; - return; - } - } - - kout << "PEFLoader: warning: Binary format error!\r"; - - this->fFatBinary = NO; - this->fBad = YES; - - if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob); - this->fCachedBlob = nullptr; -} - -/***********************************************************************************/ -/// @brief PEF destructor. -/***********************************************************************************/ -PEFLoader::~PEFLoader() { - if (fCachedBlob) mm_free_ptr(fCachedBlob); - - fFile.Delete(); -} - -/***********************************************************************************/ -/// @brief Finds the symbol according to it's name. -/// @param name name of symbol. -/// @param kind kind of symbol we want. -/***********************************************************************************/ -ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) { - if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData}; - - auto blob = fFile->Read(name, sizeof(PEFCommandHeader)); - - if (!blob) return ErrorOr<VoidPtr>{kErrorInvalidData}; - - PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); - - if (!container) return ErrorOr<VoidPtr>{kErrorInvalidData}; - - PEFCommandHeader* command_header = reinterpret_cast<PEFCommandHeader*>(blob); - - if (command_header->VMSize < 1 || command_header->VMAddress == 0) - return ErrorOr<VoidPtr>{kErrorInvalidData}; - - /// fat binary check. - if (command_header->Cpu != container->Cpu && !this->fFatBinary) - return ErrorOr<VoidPtr>{kErrorInvalidData}; - - const auto kMangleCharacter = '$'; - const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; - - ErrorOr<KString> error_or_symbol; - - switch (kind) { - case kPefCode: { - error_or_symbol = KStringBuilder::Construct(kContainerKinds[0]); // code symbol. - break; - } - case kPefData: { - error_or_symbol = KStringBuilder::Construct(kContainerKinds[1]); // data symbol. - break; - } - case kPefZero: { - error_or_symbol = KStringBuilder::Construct(kContainerKinds[2]); // block starting symbol. - break; - } - default: - return ErrorOr<VoidPtr>{kErrorInvalidData}; - // prevent that from the kernel's mode perspective, let that happen if it - // were a user process. - } - - Char* unconst_symbol = const_cast<Char*>(name); - - for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) { - if (rt_is_space(unconst_symbol[i])) { - unconst_symbol[i] = kMangleCharacter; - } - } - - error_or_symbol.Leak().Leak() += name; - - if (KStringBuilder::Equals(command_header->Name, error_or_symbol.Leak().Leak().CData())) { - if (command_header->Kind == kind) { - if (command_header->Cpu != Detail::ldr_get_platform()) { - if (!this->fFatBinary) { - mm_free_ptr(blob); - blob = nullptr; - - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } - } - - Char* container_blob_value = new Char[command_header->VMSize]; - - rt_copy_memory_safe((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value, - command_header->VMSize, command_header->VMSize); - - mm_free_ptr(blob); - - kout << "PEFLoader: info: Load stub: " << command_header->Name << "!\r"; - - Int32 ret = 0; - SizeT pages_count = (command_header->VMSize + kPageSize - 1) / kPageSize; - - for (SizeT i_vm{}; i_vm < pages_count; ++i_vm) { - ret = HAL::mm_map_page( - (VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)), - (VoidPtr) (HAL::mm_get_page_addr(container_blob_value) + (i_vm * kPageSize)), - HAL::kMMFlagsPresent | HAL::kMMFlagsUser); - - if (ret != kErrorSuccess) { - /// We set the VMAddress to nullptr, if the mapping fail here. - for (SizeT i_vm_unmap{}; i_vm_unmap < i_vm; ++i_vm_unmap) { - ret = HAL::mm_map_page((VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)), - nullptr, HAL::kMMFlagsPresent | HAL::kMMFlagsUser); - } - - delete[] container_blob_value; - container_blob_value = nullptr; - - return ErrorOr<VoidPtr>{kErrorInvalidData}; - } - } - - return ErrorOr<VoidPtr>{container_blob_value}; - } - } - - mm_free_ptr(blob); - return ErrorOr<VoidPtr>{kErrorInvalidData}; -} - -/// @brief Finds the executable entrypoint. -/// @return -ErrorOr<VoidPtr> PEFLoader::FindStart() { - if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return sym; - - return ErrorOr<VoidPtr>(kErrorExecutable); -} - -/// @brief Tells if the executable is loaded or not. -/// @return Whether it's not bad and is cached. -bool PEFLoader::IsLoaded() noexcept { - return !fBad && fCachedBlob; -} - -const Char* PEFLoader::Path() { - return fPath.Leak().CData(); -} - -const Char* PEFLoader::AsString() { -#ifdef __32x0__ - return "32x0 PEF"; -#elif defined(__64x0__) - return "64x0 PEF"; -#elif defined(__x86_64__) - return "x86_64 PEF"; -#elif defined(__aarch64__) - return "AARCH64 PEF"; -#elif defined(__powerpc64__) - return "POWER64 PEF"; -#else - return "???? PEF"; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ -} - -const Char* PEFLoader::MIME() { - return kPefApplicationMime; -} - -ErrorOr<VoidPtr> PEFLoader::GetBlob() { - return ErrorOr<VoidPtr>{this->fCachedBlob}; -} - -namespace Utils { - ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& process_kind) noexcept { - auto errOrStart = exec.FindStart(); - - if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID; - - auto symname = exec.FindSymbol(kPefNameSymbol, kPefData); - - if (!symname) { - symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PEF")}; - } - - ProcessID id = - UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()), - errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - - mm_free_ptr(symname.Leak().Leak()); - - if (id != kSchedInvalidPID) { - auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); - - if (!stacksym) { - stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; - } - - if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) { - *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz; - } - - UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind; - UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize = - *(UIntPtr*) stacksym.Leak().Leak(); - - mm_free_ptr(stacksym.Leak().Leak()); - } - - return id; - } -} // namespace Utils -} // namespace Kernel diff --git a/dev/kernel/src/PRDT.cc b/dev/kernel/src/PRDT.cc deleted file mode 100644 index 626a7e16..00000000 --- a/dev/kernel/src/PRDT.cc +++ /dev/null @@ -1,22 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DebugOutput.h> -#include <NeKit/KString.h> -#include <StorageKit/PRDT.h> - -namespace Kernel { -/***********************************************************************************/ -/// @brief constructs a new PRD. -/// @param prd PRD reference. -/// @note This doesnt construct a valid, please fill it by yourself. -/***********************************************************************************/ -void construct_prdt(Ref<PRDT>& prd) { - prd.Leak().fPhysAddress = 0x0; - prd.Leak().fSectorCount = 0x0; - prd.Leak().fEndBit = 0x0; -} -} // namespace Kernel diff --git a/dev/kernel/src/PageMgr.cc b/dev/kernel/src/PageMgr.cc deleted file mode 100644 index 81833ee2..00000000 --- a/dev/kernel/src/PageMgr.cc +++ /dev/null @@ -1,95 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DebugOutput.h> -#include <NeKit/PageMgr.h> - -#ifdef __NE_AMD64__ -#include <HALKit/AMD64/Paging.h> -#elif defined(__NE_ARM64__) -#include <HALKit/ARM64/Paging.h> -#endif // ifdef __NE_AMD64__ || defined(__NE_ARM64__) - -namespace Kernel { -PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) - : fRw(Rw), - fUser(User), - fExecDisable(ExecDisable), - fVirtAddr(VirtAddr), - fCache(false), - fShareable(false), - fWt(false), - fPresent(true), - fAccessed(false) {} - -PTEWrapper::~PTEWrapper() = default; - -/// @brief Flush virtual address. -/// @param VirtAddr -Void PageMgr::FlushTLB() { -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - hal_flush_tlb(); -#endif // !__NE_VIRTUAL_MEMORY_SUPPORT__ -} - -/// @brief Reclaim freed page. -/// @return -Bool PTEWrapper::Reclaim() { - if (!this->fPresent) { - this->fPresent = true; - return true; - } - - return false; -} - -/// @brief Request a PTE. -/// @param Rw Is it read write? or is it read only? -/// @param User user mode? -/// @param ExecDisable disable execution on page? -/// @return -PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz, SizeT Pad) { - // Store PTE wrapper right after PTE. - VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, NO, Pad); - - return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast<UIntPtr>(ptr)}; -} - -/// @brief Disable BitMap. -/// @param wrapper the wrapper. -/// @return If the page bitmap was cleared or not. -Bool PageMgr::Free(Ref<PTEWrapper>& wrapper) { - if (!Kernel::HAL::mm_free_bitmap((VoidPtr) wrapper.Leak().VirtualAddress())) return false; - - return true; -} - -/// @brief Virtual PTE address. -/// @return The virtual address of the page. -UIntPtr PTEWrapper::VirtualAddress() { - return (fVirtAddr); -} - -Bool PTEWrapper::Shareable() { - return fShareable; -} - -Bool PTEWrapper::Present() { - return fPresent; -} - -Bool PTEWrapper::Access() { - return fAccessed; -} - -Void PTEWrapper::NoExecute(const bool enable) { - fExecDisable = enable; -} - -Bool PTEWrapper::NoExecute() { - return fExecDisable; -} -} // namespace Kernel diff --git a/dev/kernel/src/Pmm.cc b/dev/kernel/src/Pmm.cc deleted file mode 100644 index 84086929..00000000 --- a/dev/kernel/src/Pmm.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/DebugOutput.h> -#include <NeKit/Pmm.h> - -#if defined(__NE_ARM64__) -#include <HALKit/ARM64/Processor.h> -#endif // defined(__NE_ARM64__) - -#if defined(__NE_AMD64__) -#include <HALKit/AMD64/Processor.h> -#endif // defined(__NE_AMD64__) - -namespace Kernel { -/***********************************************************************************/ -/// @brief Pmm constructor. -/***********************************************************************************/ -Pmm::Pmm() : fPageMgr() { - kout << "[PMM] Allocate PageMemoryMgr.\r"; -} - -Pmm::~Pmm() = default; - -/***********************************************************************************/ -/// @param If this returns Null pointer, enter emergency mode. -/// @param user is this a user page? -/// @param readWrite is it r/w? -/***********************************************************************************/ -Ref<PTEWrapper> Pmm::RequestPage(Boolean user, Boolean readWrite) { - PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize, 0); - - if (pt.fPresent) { - kout << "[PMM]: Allocation failed.\r"; - return {pt}; - } - - return Ref<PTEWrapper>(pt); -} - -Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef) { - if (!PageRef) return false; - - PageRef.Leak().fPresent = false; - - return true; -} - -Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable) { - if (!PageRef) return false; - - PageRef.Leak().fPresent = Enable; - - return true; -} - -Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable) { - if (!PageRef) return false; - - PageRef.Leak().fRw = Enable; - - return true; -} - -Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable) { - if (!PageRef) return false; - - PageRef.Leak().fRw = Enable; - - return true; -} - -Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable) { - if (!PageRef) return false; - - PageRef.Leak().fShareable = Enable; - - return true; -} -} // namespace Kernel diff --git a/dev/kernel/src/Property.cc b/dev/kernel/src/Property.cc deleted file mode 100644 index 8b7454fe..00000000 --- a/dev/kernel/src/Property.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <CFKit/Property.h> - -namespace Kernel::CF { -/***********************************************************************************/ -/// @brief Destructor. -/***********************************************************************************/ -Property::~Property() = default; - -/***********************************************************************************/ -/// @brief Constructor. -/***********************************************************************************/ -Property::Property() = default; - -/***********************************************************************************/ -/// @brief Check if property's name equals to name. -/// @param name string to check. -/***********************************************************************************/ -Bool Property::StringEquals(KBasicString<>& name) { - return this->fName && this->fName == name; -} - -/***********************************************************************************/ -/// @brief Gets the key (name) of property. -/***********************************************************************************/ -KBasicString<>& Property::GetKey() { - return this->fName; -} - -/***********************************************************************************/ -/// @brief Gets the value of the property. -/***********************************************************************************/ -PropertyId& Property::GetValue() { - return fValue; -} -} // namespace Kernel::CF diff --git a/dev/kernel/src/Ref.cc b/dev/kernel/src/Ref.cc deleted file mode 100644 index 90b1c22d..00000000 --- a/dev/kernel/src/Ref.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Ref.h> diff --git a/dev/kernel/src/Semaphore.cc b/dev/kernel/src/Semaphore.cc deleted file mode 100644 index 484c89ca..00000000 --- a/dev/kernel/src/Semaphore.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/Semaphore.h>
\ No newline at end of file diff --git a/dev/kernel/src/SoftwareTimer.cc b/dev/kernel/src/SoftwareTimer.cc deleted file mode 100644 index eafe8db6..00000000 --- a/dev/kernel/src/SoftwareTimer.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/Timer.h> - -/// ================================================================================ -/// @brief SoftwareTimer class, meant to be generic. -///! @author Amlal El Mahrouss (amlal@nekernel.org) -/// ================================================================================ - -using namespace Kernel; - -SoftwareTimer::SoftwareTimer(Int64 seconds) : fWaitFor(seconds) { - fDigitalTimer = new UIntPtr(); - MUST_PASS(fDigitalTimer); -} - -SoftwareTimer::~SoftwareTimer() { - delete fDigitalTimer; - fDigitalTimer = nullptr; - - fWaitFor = 0; -} - -BOOL SoftwareTimer::Wait() noexcept { - if (fWaitFor < 1) return NO; - - while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) { - ++(*fDigitalTimer); - } - - return YES; -} diff --git a/dev/kernel/src/Storage/AHCIDeviceInterface.cc b/dev/kernel/src/Storage/AHCIDeviceInterface.cc deleted file mode 100644 index 02b39fb5..00000000 --- a/dev/kernel/src/Storage/AHCIDeviceInterface.cc +++ /dev/null @@ -1,87 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <StorageKit/AHCI.h> - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive cleanup. -AHCIDeviceInterface::AHCIDeviceInterface(void (*out)(DeviceInterface* self, IMountpoint* outpacket), - void (*in)(DeviceInterface* self, IMountpoint* inpacket)) - : DeviceInterface(out, in) {} - -/// @brief Class desctructor -AHCIDeviceInterface::~AHCIDeviceInterface() = default; - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const Char* AHCIDeviceInterface::Name() const { - return "/devices/sda{}"; -} - -/// @brief Output operator. -/// @param mnt the disk mountpoint. -/// @return the class itself after operation. -AHCIDeviceInterface& AHCIDeviceInterface::operator<<(IMountpoint* mnt) { - if (!mnt) return *this; - - for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) { - auto interface = mnt->GetAddressOf(driveCount); - - if ((interface) && - rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) == 0) { - continue; - } else if ((interface) && - rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) != 0) { - return *this; - } - } - - return (AHCIDeviceInterface&) DeviceInterface<IMountpoint*>::operator<<(mnt); -} - -/// @brief Input operator. -/// @param mnt the disk mountpoint. -/// @return the class itself after operation. -AHCIDeviceInterface& AHCIDeviceInterface::operator>>(IMountpoint* mnt) { - if (!mnt) return *this; - - for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) { - auto interface = mnt->GetAddressOf(driveCount); - - // really check if it's ATA. - if ((interface) && - rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) == 0) { - continue; - } else if ((interface) && - rt_string_cmp((interface)->fProtocol(), "AHCI", rt_string_len("AHCI")) != 0) { - return *this; - } - } - - return (AHCIDeviceInterface&) DeviceInterface<IMountpoint*>::operator>>(mnt); -} - -const UInt16& AHCIDeviceInterface::GetPortsImplemented() { - return this->fPortsImplemented; -} - -Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi) { - MUST_PASS(pi > 0); - this->fPortsImplemented = pi; -} - -const UInt32& AHCIDeviceInterface::GetIndex() { - return this->fDriveIndex; -} - -Void AHCIDeviceInterface::SetIndex(const UInt32& drv) { - MUST_PASS(IMountpoint::kDriveIndexInvalid < drv); - this->fDriveIndex = drv; -}
\ No newline at end of file diff --git a/dev/kernel/src/Storage/ATADeviceInterface.cc b/dev/kernel/src/Storage/ATADeviceInterface.cc deleted file mode 100644 index 8e15fdea..00000000 --- a/dev/kernel/src/Storage/ATADeviceInterface.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <StorageKit/ATA.h> - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive cleanup. -ATADeviceInterface::ATADeviceInterface(void (*Out)(DeviceInterface*, IMountpoint* outpacket), - void (*In)(DeviceInterface*, IMountpoint* inpacket)) - : DeviceInterface(Out, In) {} - -/// @brief Class desctructor -ATADeviceInterface::~ATADeviceInterface() = default; - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const Char* ATADeviceInterface::Name() const { - return "/devices/hda{}"; -} - -/// @brief Output operator. -/// @param Data the disk mountpoint. -/// @return the class itself after operation. -ATADeviceInterface& ATADeviceInterface::operator<<(IMountpoint* Data) { - if (!Data) return *this; - - for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) { - auto interface = Data->GetAddressOf(driveCount); - - if ((interface) && - rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) == 0) { - continue; - } else if ((interface) && - rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) != 0) { - return *this; - } - } - - return (ATADeviceInterface&) DeviceInterface<IMountpoint*>::operator<<(Data); -} - -/// @brief Input operator. -/// @param Data the disk mountpoint. -/// @return the class itself after operation. -ATADeviceInterface& ATADeviceInterface::operator>>(IMountpoint* Data) { - if (!Data) return *this; - - for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount) { - auto interface = Data->GetAddressOf(driveCount); - - // really check if it's ATA. - if ((interface) && - rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) == 0) { - continue; - } else if ((interface) && - rt_string_cmp((interface)->fProtocol(), "ATA-", rt_string_len("ATA-")) != 0) { - return *this; - } - } - - return (ATADeviceInterface&) DeviceInterface<IMountpoint*>::operator>>(Data); -} - -const UInt32& ATADeviceInterface::GetIndex() { - return this->fDriveIndex; -} - -Void ATADeviceInterface::SetIndex(const UInt32& drv) { - MUST_PASS(IMountpoint::kDriveIndexInvalid < drv); - this->fDriveIndex = drv; -} - -const UInt16& ATADeviceInterface::GetIO() { - return this->fIO; -} - -Void ATADeviceInterface::SetIO(const UInt16& drv) { - MUST_PASS(0xFFFF != drv); - this->fIO = drv; -} - -const UInt16& ATADeviceInterface::GetMaster() { - return this->fIO; -} - -Void ATADeviceInterface::SetMaster(const UInt16& drv) { - MUST_PASS(0xFFFF != drv); - this->fMaster = drv; -}
\ No newline at end of file diff --git a/dev/kernel/src/Storage/NVMEDeviceInterface.cc b/dev/kernel/src/Storage/NVMEDeviceInterface.cc deleted file mode 100644 index f05d384e..00000000 --- a/dev/kernel/src/Storage/NVMEDeviceInterface.cc +++ /dev/null @@ -1,22 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <StorageKit/NVME.h> - -namespace Kernel { -NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(DeviceInterface*, IMountpoint* outpacket), - void (*in)(DeviceInterface*, IMountpoint* inpacket), - void (*cleanup)(void)) - : DeviceInterface(out, in), fCleanup(cleanup) {} - -NVMEDeviceInterface::~NVMEDeviceInterface() { - if (fCleanup) fCleanup(); -} - -const Char* NVMEDeviceInterface::Name() const { - return ("/devices/nvme{}"); -} -} // namespace Kernel diff --git a/dev/kernel/src/Storage/SCSIDeviceInterface.cc b/dev/kernel/src/Storage/SCSIDeviceInterface.cc deleted file mode 100644 index 2e331ae9..00000000 --- a/dev/kernel/src/Storage/SCSIDeviceInterface.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <StorageKit/SCSI.h> - -using namespace Kernel; diff --git a/dev/kernel/src/Stream.cc b/dev/kernel/src/Stream.cc deleted file mode 100644 index 8572e222..00000000 --- a/dev/kernel/src/Stream.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - File: Stream.cc - Purpose: Stream object - - Revision History: - -======================================== */ - -#include <NeKit/Stream.h> diff --git a/dev/kernel/src/Swap/DiskSwap.cc b/dev/kernel/src/Swap/DiskSwap.cc deleted file mode 100644 index f0fa5915..00000000 --- a/dev/kernel/src/Swap/DiskSwap.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss , licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/FileMgr.h> -#include <SwapKit/DiskSwap.h> - -namespace Kernel { -static constexpr UInt32 kSwapDiskHeaderMagic = 0x44535750; // 'DSWP' - -/***********************************************************************************/ -/// @brief Write memory chunk onto disk. -/// @param fork_name The swap name to recognize this memory region. -/// @param fork_name_len length of fork name. -/// @param data the data packet. -/// @return Whether the swap was written to disk, or not. -/***********************************************************************************/ -BOOL DiskSwapInterface::Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data) { - if (!fork_name || !fork_name_len) return NO; - - if (*fork_name == 0) return NO; - - if (!data || data->fMagic != kSwapDiskHeaderMagic) return NO; - - FileStream file(kSwapPageFilePath, kRestrictWRB); - - ErrorOr<Int64> ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz); - - if (ret.Error()) return NO; - - return YES; -} - -/***********************************************************************************/ -/// @brief Read memory chunk from disk. -/// @param fork_name The swap name to recognize this memory region. -/// @param fork_name_len length of fork name. -/// @param data the data packet length. -/// @return Whether the swap was fetched to disk, or not. -/***********************************************************************************/ -SWAP_DISK_HEADER* DiskSwapInterface::Read(const Char* fork_name, SizeT fork_name_len, - SizeT data_len) { - if (!fork_name || !fork_name_len) return nullptr; - - if (*fork_name == 0) return nullptr; - - if (data_len > kSwapBlockMaxSize) return nullptr; - - if (data_len == 0) return nullptr; - - FileStream file(kSwapPageFilePath, kRestrictRB); - - VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len); - - if (!blob || ((SWAP_DISK_HEADER*) blob)->fMagic != kSwapDiskHeaderMagic) { - if (blob) mm_free_ptr(blob); - return nullptr; - } - - return reinterpret_cast<SWAP_DISK_HEADER*>(blob); -} -} // namespace Kernel diff --git a/dev/kernel/src/ThreadLocalStorage.cc b/dev/kernel/src/ThreadLocalStorage.cc deleted file mode 100644 index fa445d84..00000000 --- a/dev/kernel/src/ThreadLocalStorage.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ======================================================== - * - * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#include <CFKit/Property.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/ThreadLocalStorage.h> -#include <NeKit/KString.h> - -/***********************************************************************************/ -/// @bugs: 0 -/// @file ThreadLocalStorage.cc -/// @brief NeKernel Thread Local Storage. -///! @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -using namespace Kernel; - -/** - * @brief Checks for cookie inside the TIB. - * @param tib_ptr the TIB to check. - * @return if the cookie is enabled, true; false otherwise - */ - -Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) { - if (!tib_ptr) return false; - - return tib_ptr->Cookie[kCookieMag0Idx] == kCookieMag0 && - tib_ptr->Cookie[kCookieMag1Idx] == kCookieMag1 && - tib_ptr->Cookie[kCookieMag2Idx] == kCookieMag2; -} - -/** - * @brief System call implementation of the TLS check. - * @param tib_ptr The TIB record. - * @return if the TIB record is valid or not. - */ -EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept { - if (!tib_ptr) { - kout << "TLS: Failed because of an invalid TIB...\r"; - return No; - } - - THREAD_INFORMATION_BLOCK* tib = reinterpret_cast<THREAD_INFORMATION_BLOCK*>(tib_ptr); - - return tls_check_tib(tib); -} diff --git a/dev/kernel/src/Timer.cc b/dev/kernel/src/Timer.cc deleted file mode 100644 index 648cc92b..00000000 --- a/dev/kernel/src/Timer.cc +++ /dev/null @@ -1,19 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/Timer.h> - -///! BUGS: 0 -///! @file Timer.cc -///! @brief Software Timer implementation -///! @author Amlal El Mahrouss (amlal@nekernel.org) - -using namespace Kernel; - -/// @brief Unimplemented as it is an interface. -BOOL TimerInterface::Wait() noexcept { - return NO; -} diff --git a/dev/kernel/src/UserMgr.cc b/dev/kernel/src/UserMgr.cc deleted file mode 100644 index 103e8ec9..00000000 --- a/dev/kernel/src/UserMgr.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* - * ======================================================== - * - * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - * File: UserMgr.cc - * Purpose: User Manager, used to provide authentication and security. - * - * ======================================================== - */ - -#include <KernelKit/FileMgr.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/KPC.h> -#include <KernelKit/ThreadLocalStorage.h> -#include <KernelKit/UserMgr.h> -#include <NeKit/KString.h> -#include <NeKit/KernelPanic.h> -#include <NeKit/Utils.h> - -#define kStdUserType (0xEE) -#define kSuperUserType (0xEF) - -/// @file UserMgr.cc -/// @brief Multi-user support. - -namespace Kernel { -namespace Detail { - //////////////////////////////////////////////////////////// - /// \brief Constructs a password by hashing the password. - /// \param password password to hash. - /// \return the hashed password - //////////////////////////////////////////////////////////// - STATIC UInt64 user_fnv_generator(const Char* password, User* user) { - if (!password || !user) return 0; - if (*password == 0) return 0; - - kout << "user_fnv_generator: Hashing user password...\r"; - - const UInt64 kFnvOffsetBasis = 0xcbf29ce484222325ULL; - const UInt64 fFnvPrime = 0x100000001b3ULL; - - UInt64 hash = kFnvOffsetBasis; - - while (*password) { - hash ^= (Char) (*password++); - hash *= fFnvPrime; - } - - kout << "user_fnv_generator: Hashed user password.\r"; - - return hash; - } -} // namespace Detail - -//////////////////////////////////////////////////////////// -/// @brief User ring constructor. -//////////////////////////////////////////////////////////// -User::User(const Int32& sel, const Char* user_name) : mUserRing((UserRingKind) sel) { - MUST_PASS(sel >= 0); - rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name), - kMaxUserNameLen); -} - -//////////////////////////////////////////////////////////// -/// @brief User ring constructor. -//////////////////////////////////////////////////////////// -User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) { - rt_copy_memory_safe((VoidPtr) user_name, this->mUserName, rt_string_len(user_name), - kMaxUserNameLen); -} - -//////////////////////////////////////////////////////////// -/// @brief User destructor class. -//////////////////////////////////////////////////////////// -User::~User() = default; - -Bool User::Save(const UserPublicKey password) noexcept { - if (!password || *password == 0) return No; - - this->mUserFNV = Detail::user_fnv_generator(password, this); - - kout << "User::Save: Saved password successfully...\r"; - - return Yes; -} - -Bool User::Login(const UserPublicKey password) noexcept { - if (!password || !*password) return No; - - auto ret = this->mUserFNV == Detail::user_fnv_generator(password, this); - - // now check if the password matches. - kout << (ret ? "User::Login: Password matches.\r" : "User::Login: Password doesn't match.\r"); - return ret; -} - -Bool User::operator==(const User& lhs) { - return lhs.mUserRing == this->mUserRing; -} - -Bool User::operator!=(const User& lhs) { - return lhs.mUserRing != this->mUserRing; -} - -//////////////////////////////////////////////////////////// -/// @brief Returns the user's name. -//////////////////////////////////////////////////////////// - -Char* User::Name() noexcept { - return this->mUserName; -} - -//////////////////////////////////////////////////////////// -/// @brief Returns the user's ring. -/// @return The king of ring the user is attached to. -//////////////////////////////////////////////////////////// - -const UserRingKind& User::Ring() noexcept { - return this->mUserRing; -} - -Bool User::IsStdUser() noexcept { - return this->Ring() == UserRingKind::kRingStdUser; -} - -Bool User::IsSuperUser() noexcept { - return this->Ring() == UserRingKind::kRingSuperUser; -} -} // namespace Kernel diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc deleted file mode 100644 index 264bddf3..00000000 --- a/dev/kernel/src/UserProcessScheduler.cc +++ /dev/null @@ -1,690 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - - FILE: UserProcessScheduler.cc - PURPOSE: Low-Privilege/Ring-3 process scheduler. - -======================================== */ - -/***********************************************************************************/ -/// @file UserProcessScheduler.cc -/// @brief Unprivileged/Ring-3 process scheduler. -/// @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/HardwareThreadScheduler.h> -#include <KernelKit/HeapMgr.h> -#include <KernelKit/IPEFDylibObject.h> -#include <KernelKit/KPC.h> -#include <KernelKit/ProcessScheduler.h> -#include <NeKit/KString.h> -#include <NeKit/Utils.h> -#include <SignalKit/Signals.h> - -///! BUGS: 0 - -namespace Kernel { -USER_PROCESS::USER_PROCESS() = default; -USER_PROCESS::~USER_PROCESS() = default; - -/// @brief Gets the last exit code. -/// @note Not thread-safe. -/// @return Int32 the last exit code. - -/***********************************************************************************/ -/// @brief Crashes the current process. -/***********************************************************************************/ - -Void USER_PROCESS::Crash() { - if (this->Status != ProcessStatusKind::kRunning) return; - - this->Status = ProcessStatusKind::kKilled; - - (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); -} - -/***********************************************************************************/ -/// @brief boolean operator, check status. -/***********************************************************************************/ - -USER_PROCESS::operator bool() { - return this->Status == ProcessStatusKind::kRunning; -} - -/***********************************************************************************/ -/// @brief Gets the local last exit code. -/// @note Not thread-safe. -/// @return Int32 the last exit code. -/***********************************************************************************/ - -KPCError& USER_PROCESS::GetExitCode() noexcept { - return this->LastExitCode; -} - -/***********************************************************************************/ -/// @brief Error code variable getter. -/***********************************************************************************/ - -KPCError& USER_PROCESS::GetLocalCode() noexcept { - return this->LocalCode; -} - -/***********************************************************************************/ -/// @brief Wakes process header. -/// @param should_wakeup if the program shall wakeup or not. -/***********************************************************************************/ - -Void USER_PROCESS::Wake(Bool should_wakeup) { - this->Status = should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; -} - -/***********************************************************************************/ -/** @brief Allocate pointer to heap tree. */ -/** @param tree The tree to calibrate */ -/***********************************************************************************/ - -template <typename T> -STATIC T* sched_try_go_upper_ptr_tree(T* tree) { - if (!tree) { - return nullptr; - } - - tree = tree->Parent; - - if (tree) { - auto tree_tmp = tree->Next; - - if (!tree_tmp) { - return tree; - } - - return tree_tmp; - } - - return tree; -} - -/***********************************************************************************/ -/** @brief Allocate pointer to heap/file tree. */ -/***********************************************************************************/ - -ErrorOr<VoidPtr> USER_PROCESS::New(SizeT sz, SizeT pad_amount) { - if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory); - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto vm_register = kKernelVM; - - hal_write_cr3(this->VMRegister); - - auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount); - - hal_write_cr3(vm_register); -#else - auto ptr = mm_alloc_ptr(sz, Yes, Yes, pad_amount); -#endif - - if (!this->HeapTree) { - this->HeapTree = new PROCESS_HEAP_TREE<VoidPtr>(); - - if (!this->HeapTree) { - this->Crash(); - return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory); - } - - this->HeapTree->EntryPad = pad_amount; - this->HeapTree->EntrySize = sz; - - this->HeapTree->Entry = ptr; - - this->HeapTree->Color = kBlackTreeKind; - - this->HeapTree->Prev = nullptr; - this->HeapTree->Next = nullptr; - this->HeapTree->Parent = nullptr; - this->HeapTree->Child = nullptr; - } else { - PROCESS_HEAP_TREE<VoidPtr>* entry = this->HeapTree; - PROCESS_HEAP_TREE<VoidPtr>* prev_entry = entry; - - BOOL is_parent = NO; - - while (entry) { - if (entry->EntrySize < 1) break; - - prev_entry = entry; - - if (entry->Child && entry->Child->EntrySize > 0 && entry->Child->EntrySize == sz) { - entry = entry->Child; - is_parent = YES; - } else if (entry->Next && entry->Next->EntrySize > 0 && entry->Next->EntrySize == sz) { - is_parent = NO; - entry = entry->Next; - } else { - entry = sched_try_go_upper_ptr_tree(entry); - if (entry && entry->Color == kBlackTreeKind) break; - } - } - - auto new_entry = new PROCESS_HEAP_TREE<VoidPtr>(); - - if (!new_entry) { - this->Crash(); - return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory); - } - - new_entry->Entry = ptr; - new_entry->EntrySize = sz; - new_entry->EntryPad = pad_amount; - new_entry->Parent = entry; - new_entry->Child = nullptr; - new_entry->Next = nullptr; - new_entry->Prev = nullptr; - - new_entry->Color = kBlackTreeKind; - prev_entry->Color = kRedTreeKind; - - if (is_parent) { - prev_entry->Child = new_entry; - new_entry->Parent = prev_entry; - } else { - prev_entry->Next = new_entry; - new_entry->Prev = prev_entry; - } - } - - this->UsedMemory += sz; - - return ErrorOr<VoidPtr>(ptr); -} - -/***********************************************************************************/ -/// @brief Gets the name of the current process. -/***********************************************************************************/ - -const Char* USER_PROCESS::GetName() noexcept { - return this->Name; -} - -/***********************************************************************************/ -/// @brief Gets the owner of the process. -/***********************************************************************************/ - -const User* USER_PROCESS::GetOwner() noexcept { - return this->Owner; -} - -/// @brief USER_PROCESS status getter. -const ProcessStatusKind& USER_PROCESS::GetStatus() noexcept { - return this->Status; -} - -/***********************************************************************************/ -/** -@brief Affinity is the time slot allowed for the process. -*/ -/***********************************************************************************/ - -const AffinityKind& USER_PROCESS::GetAffinity() noexcept { - return this->Affinity; -} - -/***********************************************************************************/ -/** @brief Free heap tree. */ -/***********************************************************************************/ - -template <typename T> -STATIC Void sched_free_ptr_tree(T* tree) { - // Deleting memory lists. Make sure to free all of them. - while (tree) { - if (tree->Entry) { - MUST_PASS(mm_free_ptr(tree->Entry)); - } - - auto next = tree->Next; - - if (next->Child) sched_free_ptr_tree(next->Child); - - tree->Child = nullptr; - - mm_free_ptr(tree); - - tree = nullptr; - tree = next; - } -} - -/***********************************************************************************/ -/** -@brief Exit process method. -@param exit_code The process's exit code. -*/ -/***********************************************************************************/ - -Void USER_PROCESS::Exit(const Int32& exit_code) { - this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; - this->LastExitCode = exit_code; - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto pd = kKernelVM; - hal_write_cr3(this->VMRegister); -#endif - - sched_free_ptr_tree(this->HeapTree); - this->HeapTree = nullptr; - - sched_free_ptr_tree(this->FileTree); - this->FileTree = nullptr; - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - hal_write_cr3(pd); -#endif - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - //! Free the memory's page directory. - if (this->VMRegister) HAL::mm_free_bitmap(this->VMRegister); -#endif - - //! Delete image if not done already. - if (this->Image.fCode && mm_is_valid_ptr(this->Image.fCode)) mm_free_ptr(this->Image.fCode); - - //! Delete blob too. - if (this->Image.fBlob && mm_is_valid_ptr(this->Image.fBlob)) mm_free_ptr(this->Image.fBlob); - - //! Delete stack frame. - if (this->StackFrame && mm_is_valid_ptr(this->StackFrame)) - mm_free_ptr((VoidPtr) this->StackFrame); - - //! Avoid use after free. - this->Image.fBlob = nullptr; - this->Image.fCode = nullptr; - this->StackFrame = nullptr; - - if (this->Kind == kExecutableDylibKind) { - Bool success = false; - - rtl_fini_dylib_pef(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success); - - if (!success) { - ke_panic(RUNTIME_CHECK_PROCESS); - } - - this->DylibDelegate = nullptr; - } - - this->ProcessId = 0UL; - this->Status = ProcessStatusKind::kFinished; - - --this->ParentTeam->mProcessCur; -} - -/***********************************************************************************/ -/// @brief Add dylib to the process object. -/***********************************************************************************/ - -Bool USER_PROCESS::InitDylib() { - // React according to the process's kind. - switch (this->Kind) { - case USER_PROCESS::kExecutableDylibKind: { - this->DylibDelegate = rtl_init_dylib_pef(*this); - - if (!this->DylibDelegate) { - this->Crash(); - return NO; - } - - return YES; - } - case USER_PROCESS::kExecutableKind: { - return NO; - } - default: { - break; - } - } - - (Void)(kout << "Unknown process kind: " << hex_number(this->Kind) << kendl); - this->Crash(); - - return NO; -} - -/***********************************************************************************/ -/// @brief Add process to team. -/// @param process the process *Ref* class. -/// @return the process index inside the team. -/***********************************************************************************/ - -ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image) { - if (!name || !code) { - return -kErrorProcessFault; - } - - if (*name == 0) { - return -kErrorProcessFault; - } - - ProcessID pid = this->mTeam.mProcessCur; - - if (pid > kSchedProcessLimitPerTeam) { - return -kErrorProcessFault; - } - - ++this->mTeam.mProcessCur; - - USER_PROCESS& process = this->mTeam.mProcessList[pid]; - - process.Image.fCode = code; - process.Image.fBlob = image; - - SizeT len = rt_string_len(name); - - if (len > kSchedNameLen) { - return -kErrorProcessFault; - } - - rt_copy_memory_safe(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, len, - kSchedNameLen); - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.VMRegister = kKernelVM; -#else - process.VMRegister = 0UL; -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - - process.StackFrame = new HAL::StackFrame(); - - if (!process.StackFrame) { - process.Crash(); - return -kErrorProcessFault; - } - - rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame)); - - process.StackFrame->IP = reinterpret_cast<UIntPtr>(code); - process.StackFrame->SP = reinterpret_cast<UIntPtr>(&process.StackReserve[0] + process.StackSize); - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - HAL::mm_map_page((VoidPtr) process.StackFrame->IP, - (VoidPtr) HAL::mm_get_page_addr((VoidPtr) process.StackFrame->IP), - HAL::kMMFlagsUser | HAL::kMMFlagsPresent); - HAL::mm_map_page((VoidPtr) process.StackFrame->SP, - (VoidPtr) HAL::mm_get_page_addr((VoidPtr) process.StackFrame->SP), - HAL::kMMFlagsUser | HAL::kMMFlagsPresent); -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - - process.StackSize = kSchedMaxStackSz; - - rt_set_memory(process.StackReserve, 0, process.StackSize); - - process.ParentTeam = &mTeam; - - process.ProcessId = pid; - process.Status = ProcessStatusKind::kRunning; - process.PTime = 0; - process.UTime = 0; - process.RTime = 0; - - if (!process.FileTree) { - process.FileTree = new PROCESS_FILE_TREE<VoidPtr>(); - - if (!process.FileTree) { - process.Crash(); - return ErrorOr<VoidPtr>(-kErrorHeapOutOfMemory); - } - - /// @todo File Tree allocation and dispose methods (amlal) - } - - (Void)(kout << "ProcessID: " << number(process.ProcessId) << kendl); - (Void)(kout << "ProcesName: " << process.Name << kendl); - - return pid; -} - -/***********************************************************************************/ -/// @brief Retrieves the singleton of the process scheduler. -/***********************************************************************************/ - -UserProcessScheduler& UserProcessScheduler::The() { - STATIC UserProcessScheduler kScheduler; - return kScheduler; -} - -/***********************************************************************************/ - -/// @brief Remove process from the team. -/// @param process_id process slot inside team. -/// @retval true process was removed. -/// @retval false process doesn't exist in team. - -/***********************************************************************************/ - -Void UserProcessScheduler::Remove(ProcessID process_id) { - if (process_id < 0 || process_id > kSchedProcessLimitPerTeam) return; - if (this->mTeam.mProcessList[process_id].Status == ProcessStatusKind::kInvalid) return; - - mTeam.mProcessList[process_id].Exit(kErrorSuccess); -} - -/// @brief Is it a user scheduler? - -Bool UserProcessScheduler::IsUser() { - return Yes; -} - -/// @brief Is it a kernel scheduler? - -Bool UserProcessScheduler::IsKernel() { - return No; -} - -/// @brief Is it a SMP scheduler? - -Bool UserProcessScheduler::HasMP() { - MUST_PASS(kHandoverHeader); - return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; -} - -/***********************************************************************************/ -/// @brief Run User scheduler object. -/// @return USER_PROCESS count executed within a team. -/***********************************************************************************/ - -SizeT UserProcessScheduler::Run() noexcept { - if (mTeam.mProcessCur < 1) { - return 0UL; - } - - SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - - for (; process_index < mTeam.AsArray().Capacity(); ++process_index) { - auto& process = mTeam.AsArray()[process_index]; - - //! Check if the process needs to be run. - if (UserProcessHelper::CanBeScheduled(process)) { - kout << process.Name << " will be run...\r"; - - //! Increase the usage time of the process. - if (process.UTime < process.PTime) { - ++process.UTime; - } - - this->TheCurrentProcess() = process; - - if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - process.PTime = static_cast<Int32>(process.Affinity); - - // We add a bigger cooldown according to the RTime and affinity here. - if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { - if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.RTime += (Int32) AffinityKind::kLowUsage; - else if (process.RTime < (Int32) AffinityKind::kHigh) - process.RTime += (Int32) AffinityKind::kStandard; - else if (process.RTime < (Int32) AffinityKind::kStandard) - process.RTime += (Int32) AffinityKind::kHigh; - - process.PTime -= process.RTime; - process.RTime = 0UL; - } - } - } else { - ++process.RTime; - --process.PTime; - } - } - - return process_index; -} - -/// @brief Gets the current scheduled team. -/// @return -UserProcessTeam& UserProcessScheduler::TheCurrentTeam() { - return mTeam; -} - -/***********************************************************************************/ -/// @brief Switches the current team. -/// @param team the new team to switch to. -/// @retval true team was switched. -/// @retval false team was not switched. -/***********************************************************************************/ - -BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) { - if (team.AsArray().Count() < 1) return No; - - this->mTeam = team; - - return Yes; -} - -/// @brief Gets current running process. -/// @return -Ref<USER_PROCESS>& UserProcessScheduler::TheCurrentProcess() { - return mTeam.AsRef(); -} - -/// @brief Current proccess id getter. -/// @return USER_PROCESS ID integer. -ErrorOr<ProcessID> UserProcessHelper::TheCurrentPID() { - if (!UserProcessScheduler::The().TheCurrentProcess()) - return ErrorOr<ProcessID>{-kErrorProcessFault}; - - kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return ErrorOr<ProcessID>{UserProcessScheduler::The().TheCurrentProcess().Leak().ProcessId}; -} - -/// @brief Check if process can be schedulded. -/// @param process the process reference. -/// @retval true can be schedulded. -/// @retval false cannot be schedulded. -Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { - if (process.Affinity == AffinityKind::kRealTime) return Yes; - - if (process.Status != ProcessStatusKind::kRunning) return No; - if (process.Affinity == AffinityKind::kInvalid) return No; - if (process.StackSize > kSchedMaxStackSz) return No; - if (!process.Name[0]) return No; - if (process.Signal.SignalID == sig_generate_unique<SIGTRAP>()) return No; - - return process.PTime < 1; -} - -/***********************************************************************************/ -/** - * @brief Start scheduling the current team. - */ -/***********************************************************************************/ - -SizeT UserProcessHelper::StartScheduling() { - return UserProcessScheduler::The().Run(); -} - -/***********************************************************************************/ -/** - * \brief Does a context switch in a CPU. - * \param the_stack the stackframe of the running app. - * \param new_pid the process's ProcessID. - */ -/***********************************************************************************/ - -Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, ProcessID new_pid) { - (Void)(kout << "IP: " << hex_number(frame_ptr->IP) << kendl); - - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { - if (!HardwareThreadScheduler::The()[index].Leak()) continue; - - if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid || - HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot) - continue; - - (Void)(kout << "AP_" << hex_number(index) << kendl); - - if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) { - (Void)(kout << "AP_" << hex_number(index)); - kout << " is busy\r"; - - continue; - } - - (Void)(kout << "AP_" << hex_number(index)); - kout << " is now trying to run a new task!\r"; - - //////////////////////////////////////////////////////////// - /// Prepare task switch. /// - //////////////////////////////////////////////////////////// - - HardwareThreadScheduler::The()[index].Leak()->Busy(YES); - - Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr); - - //////////////////////////////////////////////////////////// - /// Rollback on fail. /// - //////////////////////////////////////////////////////////// - - if (!ret) continue; - - UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid; - - HardwareThreadScheduler::The()[index].Leak()->fPTime = - UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; - - (Void)(kout << "AP_" << hex_number(index)); - kout << " is now running a new task!\r"; - - return YES; - } - - kout << "Couldn't find a suitable core for the current process!\r"; - - return NO; -} - -//////////////////////////////////////////////////////////// -/// @brief this checks if any process is on the team. -//////////////////////////////////////////////////////////// -UserProcessScheduler::operator bool() { - for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) { - auto& process = mTeam.AsArray()[process_index]; - if (UserProcessHelper::CanBeScheduled(process)) return true; - } - - return false; -} - -//////////////////////////////////////////////////////////// -/// @brief this checks if no process is on the team. -//////////////////////////////////////////////////////////// -Bool UserProcessScheduler::operator!() { - SInt64 cnt = 0UL; - - for (auto process_index = 0UL; process_index < mTeam.AsArray().Count(); ++process_index) { - auto& process = mTeam.AsArray()[process_index]; - if (UserProcessHelper::CanBeScheduled(process)) ++cnt; - } - - return cnt == 0L; -} -} // namespace Kernel diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc deleted file mode 100644 index e5b7a7eb..00000000 --- a/dev/kernel/src/UserProcessTeam.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/***********************************************************************************/ -/// @file UserProcessTeam.cc -/// @brief Process teams implementation. -/// @author Amlal El Mahrouss (amlal@nekernel.org) -/***********************************************************************************/ - -#include <KernelKit/UserProcessScheduler.h> - -namespace Kernel { -UserProcessTeam::UserProcessTeam() { - for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) { - this->mProcessList[i] = USER_PROCESS(); - this->mProcessList[i].PTime = 0; - this->mProcessList[i].RTime = 0; - this->mProcessList[i].UTime = 0; - this->mProcessList[i].Status = ProcessStatusKind::kKilled; - this->mProcessList[i].ParentTeam = this; - } - - this->mProcessCur = 0UL; -} - -/***********************************************************************************/ -/// @brief Process list array getter. -/// @return The list of process to schedule. -/***********************************************************************************/ - -Array<USER_PROCESS, kSchedProcessLimitPerTeam>& UserProcessTeam::AsArray() { - return this->mProcessList; -} - -/***********************************************************************************/ -/// @brief Get team ID. -/// @return The team's ID. -/***********************************************************************************/ - -ProcessID& UserProcessTeam::Id() noexcept { - return this->mTeamId; -} - -/***********************************************************************************/ -/// @brief Get current process getter as Ref. -/// @return The current process header. -/***********************************************************************************/ - -Ref<USER_PROCESS>& UserProcessTeam::AsRef() { - return this->mCurrentProcess; -} -} // namespace Kernel - -// last rev 05-03-24 diff --git a/dev/kernel/src/UtfUtils.cc b/dev/kernel/src/UtfUtils.cc deleted file mode 100644 index 47ac2729..00000000 --- a/dev/kernel/src/UtfUtils.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Utils.h> - -/// @author Amlal El Mahrouss (amlal@nekernel.org) - -namespace Kernel { -Size urt_string_len(const Utf8Char* str) { - if (!str) return 0; - - SizeT len{0}; - - while (str[len] != u8'\0') ++len; - - return len; -} - -Void urt_set_memory(const voidPtr src, UInt32 dst, Size len) { - if (!src) return; - - Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src); - Size index = 0; - - while (index < len) { - srcChr[index] = dst; - ++index; - } -} - -Int32 urt_string_cmp(const Utf8Char* src, const Utf8Char* cmp, Size size) { - if (!src) return 0; - - Int32 counter = 0; - - for (Size index = 0; index < size; ++index) { - if (src[index] != cmp[index]) ++counter; - } - - return counter; -} - -Int32 urt_copy_memory(const VoidPtr src, VoidPtr dst, Size len) { - if (!src) return 0; - if (!dst) return 0; - - Utf8Char* srcChr = reinterpret_cast<Utf8Char*>(src); - Utf8Char* dstChar = reinterpret_cast<Utf8Char*>(dst); - - Size index = 0; - - while (index < len) { - dstChar[index] = srcChr[index]; - ++index; - } - - return index; -} -} // namespace Kernel diff --git a/dev/kernel/src/Variant.cc b/dev/kernel/src/Variant.cc deleted file mode 100644 index fcf2f443..00000000 --- a/dev/kernel/src/Variant.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <NeKit/Variant.h> - -namespace Kernel { -const Char* Variant::ToString() { - switch (fKind) { - case VariantKind::kTOML: - return ("Class:{TOML}"); - case VariantKind::kJson: - return ("Class:{Json}"); - case VariantKind::kString: - return ("Class:{String}"); - case VariantKind::kBlob: - return ("Class:{Blob}"); - case VariantKind::kNull: - return ("Class:{Null}"); - case VariantKind::kSwap: - return ("Class:{Swap}"); - default: - return ("Class:{Unknown}"); - } -} - -/// @brief Return variant's kind. -Variant::VariantKind& Variant::Kind() { - return this->fKind; -} - -/// @brief Leak variant's instance. -VoidPtr Variant::Leak() { - return this->fPtr; -} -} // namespace Kernel diff --git a/dev/kernel/src/ZXD.cc b/dev/kernel/src/ZXD.cc deleted file mode 100644 index 1baa18f3..00000000 --- a/dev/kernel/src/ZXD.cc +++ /dev/null @@ -1,7 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <KernelKit/ZXD.h> |
