From 8ca2cdbdc65e167297e7c418db4f7abe13342948 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 20 Apr 2025 08:32:48 +0200 Subject: kernel, FSKit: cleanup fs and document HeFilesystemParser. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/FS/NeFS.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/FS/NeFS.cc b/dev/kernel/src/FS/NeFS.cc index 9cab99c5..115e4c82 100644 --- a/dev/kernel/src/FS/NeFS.cc +++ b/dev/kernel/src/FS/NeFS.cc @@ -4,7 +4,6 @@ ------------------------------------------- */ -#include "NewKit/Macros.h" #ifdef __FSKIT_INCLUDES_NEFS__ #include -- cgit v1.2.3 From 42e64fda5e096b70496f6f7593fb07c1c87a7d34 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 20 Apr 2025 09:18:26 +0200 Subject: fs, kernel(HeFS): Implement `hefs_get_index_node` for tree traversal. Signed-off-by: Amlal El Mahrouss --- compile_flags.txt | 4 +- dev/kernel/FSKit/HeFS.h | 7 +-- dev/kernel/NewKit/KString.h | 1 + dev/kernel/amd64-desktop.make | 2 +- dev/kernel/src/FS/Ext2.cc | 1 - dev/kernel/src/FS/HeFS.cc | 134 +++++++++++++++++++++++++++++++++++++++++- dev/kernel/src/KString.cc | 12 ++++ 7 files changed, 151 insertions(+), 10 deletions(-) (limited to 'dev/kernel/src') diff --git a/compile_flags.txt b/compile_flags.txt index d6115831..59862b28 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -22,4 +22,6 @@ -Wall -Wpedantic -Wextra --DBOOTZ_GPT_SUPPORT \ No newline at end of file +-DBOOTZ_GPT_SUPPORT +-D__FSKIT_INCLUDES_HeFS__ +-D__FSKIT_INCLUDES_EXT2__ \ No newline at end of file diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 41ae615a..b1a0d1d6 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -327,15 +327,10 @@ namespace Kernel::Detail } } - inline Lba hefs_get_block_size(Lba block_size) noexcept + inline SizeT hefs_get_block_size(SizeT block_size) noexcept { return block_size * kHeFSBlockCount; } - - inline Lba hefs_get_block_count(Lba block_size, Lba block_count) noexcept - { - return block_size / block_count; - } } // namespace Kernel::Detail namespace Kernel diff --git a/dev/kernel/NewKit/KString.h b/dev/kernel/NewKit/KString.h index 938096d5..e182fd30 100644 --- a/dev/kernel/NewKit/KString.h +++ b/dev/kernel/NewKit/KString.h @@ -89,6 +89,7 @@ namespace Kernel static const Char* FromBool(const Char* fmt, bool n); static const Char* Format(const Char* fmt, const Char* from); static bool Equals(const Char* lhs, const Char* rhs); + static bool Equals(const Utf16Char* lhs, const Utf16Char* rhs); static bool Equals(const WideChar* lhs, const WideChar* rhs); }; } // namespace Kernel diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index 9993796c..714b045d 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -5,7 +5,7 @@ CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -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__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot +CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_HeFS__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm diff --git a/dev/kernel/src/FS/Ext2.cc b/dev/kernel/src/FS/Ext2.cc index 5de8c842..8331f506 100644 --- a/dev/kernel/src/FS/Ext2.cc +++ b/dev/kernel/src/FS/Ext2.cc @@ -8,7 +8,6 @@ #include #include -#include #include #include #include diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 1c82548c..0344309e 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -19,4 +18,137 @@ #include #include +namespace Kernel +{ + namespace Detail + { + STATIC HeFS_INDEX_NODE* hefs_get_index_node(HeFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + { + if (root) + { + HeFS_INDEX_NODE* node = new HeFS_INDEX_NODE(); + HeFS_INDEX_NODE_DIRECTORY* dir = new HeFS_INDEX_NODE_DIRECTORY(); + + if (!node) + { + kout << "Error: Failed to allocate memory for index node.\r"; + return nullptr; + } + + auto start = root->fStartIND; + auto end = root->fEndIND; + + auto hop_watch = 0; + + while (start != end) + { + if (hop_watch++ > 100) + { + kout << "Error: Hop watch exceeded.\r"; + + break; + } + + if (start == 0) + { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HeFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) + { + delete node; + delete dir; + + err_global_get() = kErrorFileNotFound; + + + return nullptr; + } + + if (dir->fKind == kHeFSFileKindDirectory) + { + if (KStringBuilder::Equals(dir_name, dir->fName)) + { + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; ++inode_index) + { + if (dir->fIndexNodeStart[inode_index] != 0) + { + mnt->fPacket.fPacketLba = dir->fIndexNodeStart[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HeFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + + mnt->fInput(mnt->fPacket); + + if (mnt->fPacket.fPacketGood) + { + if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) + { + delete dir; + + return node; + } + } + else + { + break; + } + } + else if (dir->fIndexNodeEnd[inode_index] != 0) + { + mnt->fPacket.fPacketLba = dir->fIndexNodeEnd[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HeFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + + mnt->fInput(mnt->fPacket); + + if (mnt->fPacket.fPacketGood) + { + if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) + { + delete dir; + + return node; + } + } + else + { + break; + } + } + } + } + } + + start = dir->fNext; + + if (start == 0) + start = dir->fChild; + + if (start == 0) + start = dir->fParent; + } + + delete dir; + delete node; + + dir = nullptr; + node = nullptr; + } + + kout << "Error: Failed to find index node.\r"; + + err_global_get() = kErrorFileNotFound; + + return nullptr; + } + } // namespace Detail +} // namespace Kernel + #endif // ifdef __FSKIT_INCLUDES_HeFS__ diff --git a/dev/kernel/src/KString.cc b/dev/kernel/src/KString.cc index c1a8db65..2f81ad3d 100644 --- a/dev/kernel/src/KString.cc +++ b/dev/kernel/src/KString.cc @@ -143,6 +143,18 @@ namespace Kernel return true; } + /// @note This is unsafe!!! + bool KStringBuilder::Equals(const Utf16Char* lhs, const Utf16Char* rhs) + { + for (Size index = 0; index[rhs] != 0; ++index) + { + if (rhs[index] != lhs[index]) + return false; + } + + return true; + } + bool KStringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) { for (Size index = 0; rhs[index] != 0; ++index) -- cgit v1.2.3 From bc97b2b790eb06d8f9adb8ef8fa41874d7d19770 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 20 Apr 2025 16:47:35 +0200 Subject: kernel, dev: python script to make an ESP from files. - Started implementing the wrt_* APIs (Wide string functions) - Make user.sys link now, need to implement more syscalls. - Tiny HEFS refactors too. Signed-off-by: Amlal El Mahrouss --- compile_flags.txt | 4 ++-- debug_ahci_x64.sh | 3 +++ debug_ata_x64.sh | 3 +++ dev/kernel/FSKit/HeFS.h | 12 +++++------ dev/kernel/NewKit/Utils.h | 1 + dev/kernel/amd64-desktop.make | 2 +- dev/kernel/src/FS/HeFS.cc | 21 +++++++++++--------- dev/kernel/src/KString.cc | 2 +- dev/kernel/src/Utils.cc | 10 ++++++++++ dev/user/Opts.h | 12 +++++++++++ dev/user/src/SystemCalls+IO.asm | 2 +- dev/user/src/SystemCalls.cc | 34 +++++++++++++++++++++++++------ dev/user/user.json | 1 + tooling/copy_to_fat32.py | 44 +++++++++++++++++++++++++++++++++++++++++ 14 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 dev/user/Opts.h create mode 100755 tooling/copy_to_fat32.py (limited to 'dev/kernel/src') diff --git a/compile_flags.txt b/compile_flags.txt index 59862b28..001d0cfc 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -12,7 +12,6 @@ -std=c++20 -D__NE_AMD64__ -D__NEOSKRNL__ --D__FSKIT_INCLUDES_NEFS__ -D__NE_ED__ -xc++ -D__AHCI__ @@ -23,5 +22,6 @@ -Wpedantic -Wextra -DBOOTZ_GPT_SUPPORT --D__FSKIT_INCLUDES_HeFS__ +-D__FSKIT_INCLUDES_HEFS__ +-D__FSKIT_INCLUDES_NEFS__ -D__FSKIT_INCLUDES_EXT2__ \ No newline at end of file diff --git a/debug_ahci_x64.sh b/debug_ahci_x64.sh index 8c750a15..24b80246 100755 --- a/debug_ahci_x64.sh +++ b/debug_ahci_x64.sh @@ -9,4 +9,7 @@ cd dev/kernel make -f amd64-desktop.make all cd ../boot make -f amd64-desktop.make all +cd ../../ +./tooling/copy_to_fat32.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root +cd dev/boot make -f amd64-desktop.make run-efi-amd64-ahci \ No newline at end of file diff --git a/debug_ata_x64.sh b/debug_ata_x64.sh index b91f7d47..767e53f9 100755 --- a/debug_ata_x64.sh +++ b/debug_ata_x64.sh @@ -9,4 +9,7 @@ cd dev/kernel make -f amd64-desktop.make all cd ../boot make -f amd64-desktop.make all +cd ../../ +./tooling/copy_to_fat32.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root +cd dev/boot make -f amd64-desktop.make run-efi-amd64-ata-pio diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 58f51ae3..d0311a38 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -26,9 +26,9 @@ #define kHeFSMinimumDiskSize (gib_cast(4)) -struct HeFS_BOOT_NODE; -struct HeFS_INDEX_NODE; -struct HeFS_INDEX_NODE_DIRECTORY; +struct HEFS_BOOT_NODE; +struct HEFS_INDEX_NODE; +struct HEFS_INDEX_NODE_DIRECTORY; enum { @@ -84,7 +84,7 @@ inline constexpr UInt16 kHeFSInvalidVID = 0xFFFF; /// @brief HeFS 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 +struct PACKED HEFS_BOOT_NODE final { Kernel::Char fMagic[kHeFSMagicLen]; /// @brief Magic number of the filesystem. Kernel::Utf16Char fVolName[kHeFSPartNameLen]; /// @brief Volume name. @@ -115,7 +115,7 @@ inline constexpr ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; /// @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 +struct PACKED HEFS_INDEX_NODE final { Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief File name. Kernel::UInt32 fFlags; /// @brief File flags. @@ -147,7 +147,7 @@ enum /// @brief HeFS 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 +struct PACKED HEFS_INDEX_NODE_DIRECTORY final { Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief Directory name. diff --git a/dev/kernel/NewKit/Utils.h b/dev/kernel/NewKit/Utils.h index 5fc77366..7340631b 100644 --- a/dev/kernel/NewKit/Utils.h +++ b/dev/kernel/NewKit/Utils.h @@ -18,6 +18,7 @@ namespace Kernel 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 wrt_string_len(const Utf16Char* 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(Char chr); diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index 714b045d..ca31d130 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -5,7 +5,7 @@ CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_HeFS__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot +CCFLAGS = -fshort-wchar -c -D__NE_AMD64__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__FSKIT_INCLUDES_HEFS__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEOSKRNL__ -D__HAVE_NE_APIS__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 0344309e..142ddbea 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -4,7 +4,7 @@ ------------------------------------------- */ -#ifdef __FSKIT_INCLUDES_HeFS__ +#ifdef __FSKIT_INCLUDES_HEFS__ #include #include @@ -22,12 +22,12 @@ namespace Kernel { namespace Detail { - STATIC HeFS_INDEX_NODE* hefs_get_index_node(HeFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + STATIC HEFS_INDEX_NODE* hefs_get_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept { if (root) { - HeFS_INDEX_NODE* node = new HeFS_INDEX_NODE(); - HeFS_INDEX_NODE_DIRECTORY* dir = new HeFS_INDEX_NODE_DIRECTORY(); + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); if (!node) { @@ -45,7 +45,7 @@ namespace Kernel if (hop_watch++ > 100) { kout << "Error: Hop watch exceeded.\r"; - + break; } @@ -56,7 +56,7 @@ namespace Kernel } mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HeFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; mnt->fInput(mnt->fPacket); @@ -81,7 +81,7 @@ namespace Kernel if (dir->fIndexNodeStart[inode_index] != 0) { mnt->fPacket.fPacketLba = dir->fIndexNodeStart[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HeFS_INDEX_NODE); + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); mnt->fPacket.fPacketContent = node; mnt->fInput(mnt->fPacket); @@ -103,7 +103,7 @@ namespace Kernel else if (dir->fIndexNodeEnd[inode_index] != 0) { mnt->fPacket.fPacketLba = dir->fIndexNodeEnd[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HeFS_INDEX_NODE); + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); mnt->fPacket.fPacketContent = node; mnt->fInput(mnt->fPacket); @@ -151,4 +151,7 @@ namespace Kernel } // namespace Detail } // namespace Kernel -#endif // ifdef __FSKIT_INCLUDES_HeFS__ +/// @note HeFS 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. + +#endif // ifdef __FSKIT_INCLUDES_HEFS__ diff --git a/dev/kernel/src/KString.cc b/dev/kernel/src/KString.cc index 2f81ad3d..cb21e003 100644 --- a/dev/kernel/src/KString.cc +++ b/dev/kernel/src/KString.cc @@ -146,7 +146,7 @@ namespace Kernel /// @note This is unsafe!!! bool KStringBuilder::Equals(const Utf16Char* lhs, const Utf16Char* rhs) { - for (Size index = 0; index[rhs] != 0; ++index) + for (Size index = 0; index < wrt_string_len(rhs); ++index) { if (rhs[index] != lhs[index]) return false; diff --git a/dev/kernel/src/Utils.cc b/dev/kernel/src/Utils.cc index f5e61ddf..10c5d714 100644 --- a/dev/kernel/src/Utils.cc +++ b/dev/kernel/src/Utils.cc @@ -42,6 +42,16 @@ namespace Kernel return len; } + + Size wrt_string_len(const Utf16Char* str) + { + SizeT len{0}; + + while (str[len] != 0) + ++len; + + return len; + } Size rt_string_len(const Char* ptr) { diff --git a/dev/user/Opts.h b/dev/user/Opts.h new file mode 100644 index 00000000..09a77570 --- /dev/null +++ b/dev/user/Opts.h @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include + +IMPORT_C VoidPtr sci_syscall_arg_1(SizeT id); +IMPORT_C VoidPtr sci_syscall_arg_2(SizeT id, VoidPtr arg1); +IMPORT_C VoidPtr sci_syscall_arg_3(SizeT id, VoidPtr arg1, VoidPtr arg3); +IMPORT_C VoidPtr sci_syscall_arg_4(SizeT id, VoidPtr arg1, VoidPtr arg3, VoidPtr arg4); diff --git a/dev/user/src/SystemCalls+IO.asm b/dev/user/src/SystemCalls+IO.asm index 58ea79e7..77e22b59 100644 --- a/dev/user/src/SystemCalls+IO.asm +++ b/dev/user/src/SystemCalls+IO.asm @@ -1,7 +1,7 @@ ;; /* ;; * ======================================================== ;; * -;; * libsci +;; * user/src/SystemCalls+IO.asm ;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ;; * ;; * ======================================================== diff --git a/dev/user/src/SystemCalls.cc b/dev/user/src/SystemCalls.cc index 7ad0fe6f..20eaa0e0 100644 --- a/dev/user/src/SystemCalls.cc +++ b/dev/user/src/SystemCalls.cc @@ -5,14 +5,10 @@ ------------------------------------------- */ #include +#include /// @file SystemCalls.cc -/// @brief Source file for the memory functions of the libsci. - -IMPORT_C VoidPtr sci_syscall_arg_1(SizeT id); -IMPORT_C VoidPtr sci_syscall_arg_2(SizeT id, VoidPtr arg1); -IMPORT_C VoidPtr sci_syscall_arg_3(SizeT id, VoidPtr arg1, VoidPtr arg3); -IMPORT_C VoidPtr sci_syscall_arg_4(SizeT id, VoidPtr arg1, VoidPtr arg3, VoidPtr arg4); +/// @brief Source file for the memory functions of the user.sys. /// @brief Copy memory region. IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) @@ -32,6 +28,7 @@ IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input Si return dest; } +/// @brief Get string length. IMPORT_C SInt64 MmStrLen(const Char* in) { if (!in) @@ -89,3 +86,28 @@ IMPORT_C UInt64 IoTellFile(_Input Ref desc) auto ret = (UInt64*)sci_syscall_arg_2(4, reinterpret_cast(desc)); return *ret; } + +/// @brief Print to the file descriptor. +/// @param desc the file descriptor. +IMPORT_C SInt32 PrintOut(_Input IORef desc, const char* fmt, ...) +{ + va_list args; + + va_start(args, fmt); + + auto ret = (UInt64*)sci_syscall_arg_4(5, reinterpret_cast(desc), + reinterpret_cast(const_cast(fmt)), args); + + va_end(args); + + return *ret; +} + +IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) +{ + if (!expr) + { + PrintOut(nullptr, "Assertion failed: %s\r", origin); + PrintOut(nullptr, "Origin: %s\r", origin); + } +} \ No newline at end of file diff --git a/dev/user/user.json b/dev/user/user.json index 9581d4d4..05b90abf 100644 --- a/dev/user/user.json +++ b/dev/user/user.json @@ -7,6 +7,7 @@ "compiler_flags": [ "-ffreestanding", "-shared", + "-fPIC", "-fno-rtti", "-fno-exceptions", "-Wl,--subsystem=17" diff --git a/tooling/copy_to_fat32.py b/tooling/copy_to_fat32.py new file mode 100755 index 00000000..ea0cb1b9 --- /dev/null +++ b/tooling/copy_to_fat32.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import sys +import subprocess +import glob + +def copy_to_fat(image_path, source_dir): + if not os.path.isfile(image_path): + print(f"Error: FAT32 image {image_path} does not exist.") + sys.exit(1) + + if not os.path.isdir(source_dir): + print(f"Error: {source_dir} is not a valid directory.") + sys.exit(1) + + try: + files_to_copy = glob.glob(os.path.join(source_dir, "*")) + + # Now build the command + command = ["mcopy", "-spom", "-i", image_path] + files_to_copy + ["::"] + subprocess.run(command, check=True) + + print(f"Successfully copied contents of '{source_dir}' into '{image_path}'") + except FileNotFoundError: + print("Error: mcopy is not installed. Please install mtools.") + sys.exit(1) + except subprocess.CalledProcessError as e: + print(f"Error: mcopy failed with error code {e.returncode}.") + sys.exit(1) + except Exception as e: + print(f"mcopy failed: {e}") + sys.exit(1) + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: python3 copy_to_fat32.py ") + sys.exit(1) + + image_path = sys.argv[1] + source_dir = sys.argv[2] + + copy_to_fat(image_path, source_dir) \ No newline at end of file -- cgit v1.2.3 From f00211b6023ad406553a6bf9208092f834a44cdd Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 20 Apr 2025 17:46:18 +0200 Subject: dev, kernel: Create WideUtils.cc for wrt_ API. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/Utils.cc | 10 ---------- dev/kernel/src/WideUtils.cc | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 dev/kernel/src/WideUtils.cc (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/Utils.cc b/dev/kernel/src/Utils.cc index 10c5d714..399be317 100644 --- a/dev/kernel/src/Utils.cc +++ b/dev/kernel/src/Utils.cc @@ -43,16 +43,6 @@ namespace Kernel return len; } - Size wrt_string_len(const Utf16Char* str) - { - SizeT len{0}; - - while (str[len] != 0) - ++len; - - return len; - } - Size rt_string_len(const Char* ptr) { SizeT cnt{0}; diff --git a/dev/kernel/src/WideUtils.cc b/dev/kernel/src/WideUtils.cc new file mode 100644 index 00000000..a935c2d4 --- /dev/null +++ b/dev/kernel/src/WideUtils.cc @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + Size wrt_string_len(const Utf16Char* str) + { + SizeT len{0}; + + while (str[len] != 0) + ++len; + + return len; + } +} // namespace Kernel \ No newline at end of file -- cgit v1.2.3 From 00e314410e6049c2ddbcb4861c04af6b06eeeea3 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 21 Apr 2025 08:47:04 +0200 Subject: dev, kernel, tools, tooling, tex: add mk_app tool, see details. - Patch HeFS implementation file, working on a allocation function now. - Generated LaTeX specs from source code. - Add mk.{hefs, nefs} tools for future formatting (with diutil first) - Add python tool to generate user apps for NeKernel. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/FS/HeFS.cc | 82 +++++++++++++++------- docs/tex/hefs.tex | 121 ++++++++++++++++++++++++++++---- public/tools/diutil/src/CommandLine.cc | 6 +- public/tools/mk.hefs/.keep | 0 public/tools/mk.hefs/mk.hefs.json | 12 ++++ public/tools/mk.hefs/src/CommandLine.cc | 14 ++++ public/tools/mk.nefs/.keep | 0 public/tools/mk.nefs/mk.nefs.json | 12 ++++ public/tools/mk.nefs/src/CommandLine.cc | 14 ++++ tooling/copy_to_fat32.py | 44 ------------ tooling/mk_app.py | 67 ++++++++++++++++++ tooling/mk_img.py | 43 ++++++++++++ 12 files changed, 326 insertions(+), 89 deletions(-) create mode 100644 public/tools/mk.hefs/.keep create mode 100644 public/tools/mk.hefs/mk.hefs.json create mode 100644 public/tools/mk.hefs/src/CommandLine.cc create mode 100644 public/tools/mk.nefs/.keep create mode 100644 public/tools/mk.nefs/mk.nefs.json create mode 100644 public/tools/mk.nefs/src/CommandLine.cc delete mode 100755 tooling/copy_to_fat32.py create mode 100755 tooling/mk_app.py create mode 100755 tooling/mk_img.py (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 142ddbea..8d73b61e 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,30 @@ namespace Kernel { namespace Detail { - STATIC HEFS_INDEX_NODE* hefs_get_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + /// @brief Forward declarations of internal functions. + + /// @brief Get the index node of a file or directory. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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 HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; + + /// @brief Allocate a new index node. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read from. + /// @param parent_dir_name The name of the parent directory. + /// @return Status, see err_global_get(). + STATIC BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; + + /// @brief Get the index node of a file or directory. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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 HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept { if (root) { @@ -42,10 +66,9 @@ namespace Kernel while (start != end) { - if (hop_watch++ > 100) + if (hop_watch > 100) { - kout << "Error: Hop watch exceeded.\r"; - + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; break; } @@ -66,8 +89,10 @@ namespace Kernel delete node; delete dir; - err_global_get() = kErrorFileNotFound; + dir = nullptr; + node = nullptr; + err_global_get() = kErrorFileNotFound; return nullptr; } @@ -78,9 +103,10 @@ namespace Kernel { for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; ++inode_index) { - if (dir->fIndexNodeStart[inode_index] != 0) + if (dir->fIndexNodeStart[inode_index] != 0 || + dir->fIndexNodeEnd[inode_index] != 0) { - mnt->fPacket.fPacketLba = dir->fIndexNodeStart[inode_index]; + mnt->fPacket.fPacketLba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] : dir->fIndexNodeStart[inode_index]; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); mnt->fPacket.fPacketContent = node; @@ -91,35 +117,22 @@ namespace Kernel if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) { delete dir; + dir = nullptr; return node; } } else { - break; - } - } - else if (dir->fIndexNodeEnd[inode_index] != 0) - { - mnt->fPacket.fPacketLba = dir->fIndexNodeEnd[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; + err_global_get() = kErrorDiskIsCorrupted; - mnt->fInput(mnt->fPacket); + delete dir; + delete node; - if (mnt->fPacket.fPacketGood) - { - if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) - { - delete dir; + dir = nullptr; + node = nullptr; - return node; - } - } - else - { - break; + return nullptr; } } } @@ -148,6 +161,21 @@ namespace Kernel return nullptr; } + + /// @brief Allocate a new index node. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read from. + /// @param parent_dir_name The name of the parent directory. + /// @return Status, see err_global_get(). + STATIC BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept + { + NE_UNUSED(root); + NE_UNUSED(mnt); + NE_UNUSED(parent_dir_name); + NE_UNUSED(node); + + return NO; + } } // namespace Detail } // namespace Kernel diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index e74cf5e3..3370af48 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -1,32 +1,123 @@ \documentclass{article} -\usepackage[a4paper,margin=1in]{geometry} +\usepackage[a4paper, margin=1in]{geometry} +\usepackage{amsmath, amssymb} \usepackage{listings} \usepackage{xcolor} -\usepackage{amsmath} -\usepackage{hyperref} -\usepackage{longtable} -\usepackage{titlesec} -\usepackage{fancyhdr} -\usepackage{caption} \usepackage{graphicx} +\usepackage{enumitem} +\usepackage{caption} +\usepackage{longtable} -\definecolor{codegray}{gray}{0.95} -\lstset{ - backgroundcolor=\color{codegray}, +\definecolor{lightgray}{gray}{0.95} + +\lstdefinestyle{cstyle}{ + language=C++, + backgroundcolor=\color{lightgray}, basicstyle=\ttfamily\small, + keywordstyle=\color{blue}, + commentstyle=\color{green!60!black}, + stringstyle=\color{orange}, + numbers=left, + numberstyle=\tiny, breaklines=true, frame=single, - tabsize=4, - language=C++, showstringspaces=false } -\title{HeFS: High-Throughput Extended File System Specification} +\title{HeFS (Hierarchical Embedded File System) Specification} \author{Amlal El Mahrouss} -\date{2025} +\date{2024–2025} \begin{document} \maketitle -\end{document} +\section{Overview} +HeFS is a custom filesystem developed as part of the NeKernel project. It offers a journaling-like inode tree structure using red-black tree-inspired navigation for directories. Designed for robust use in desktop and server workloads, it supports various encoding modes and drive types. + +\section{Boot Node Structure} +\begin{longtable}{|l|l|p{8cm}|} +\hline +\textbf{Field} & \textbf{Type} & \textbf{Description} \\ +\hline +\verb|fMagic| & \verb|char[8]| & Filesystem magic (" HeFS") \\ +\verb|fVolName| & \verb|Utf16Char[128]| & Volume name \\ +\verb|fVersion| & \verb|UInt32| & Filesystem version (e.g., 0x0100) \\ +\verb|fSectorCount| & \verb|UInt64| & Total sector count \\ +\verb|fSectorSize| & \verb|UInt64| & Size of each sector \\ +\verb|fDriveKind| & \verb|UInt8| & Type of drive (e.g., HDD, SSD, USB) \\ +\verb|fEncoding| & \verb|UInt8| & Encoding mode (UTF-8, UTF-16, etc.) \\ +\verb|fStartIND| & \verb|UInt64| & Starting LBA of inode tree \\ +\verb|fEndIND| & \verb|UInt64| & Ending LBA of inode tree \\ +\verb|fChecksum| & \verb|UInt32| & CRC32 of boot node \\ +\verb|fDiskSize| & \verb|UInt64| & Logical size of the disk \\ +\hline +\end{longtable} + +\section{File Types and Flags} +\subsection*{File Kinds} +\begin{itemize}[label=--] + \item \verb|0x00| — Regular File + \item \verb|0x01| — Directory + \item \verb|0x02| — Block Device + \item \verb|0x03| — Character Device + \item \verb|0x04| — FIFO + \item \verb|0x05| — Socket + \item \verb|0x06| — Symbolic Link +\end{itemize} + +\subsection*{Drive Types} +\begin{itemize}[label=--] + \item \verb|0xC0| — Hard Drive + \item \verb|0xC1| — SSD + \item \verb|0xCC| — Mass Storage Device (USB) +\end{itemize} + +\section{Index Node Structure} +The inode tree allows for fast access and recovery via dual start/end block mappings and timestamped metadata. + +\begin{lstlisting}[style=cstyle, caption={HEFS\_INDEX\_NODE structure}] +struct HEFS_INDEX_NODE { + Utf16Char fName[256]; + UInt32 fFlags; + UInt16 fKind; + UInt32 fSize; + UInt32 fChecksum, fRecoverChecksum, fBlockChecksum, fLinkChecksum; + ATime fCreated, fAccessed, fModified, fDeleted; + UInt32 fUID, fGID; + UInt32 fMode; + UInt64 fBlockLinkStart[16], fBlockLinkEnd[16]; + UInt64 fBlockStart[16], fBlockEnd[16]; + UInt64 fBlockRecoveryStart[16], fBlockRecoveryEnd[16]; +}; +\end{lstlisting} + +\section{Directory Node Structure} +Each directory is a red-black tree node with child and sibling pointers. + +\begin{lstlisting}[style=cstyle, caption={HEFS\_INDEX\_NODE\_DIRECTORY structure}] +struct HEFS_INDEX_NODE_DIRECTORY { + Utf16Char fName[256]; + UInt32 fFlags; + UInt16 fKind; + UInt32 fSize; + UInt32 fChecksum, fIndexNodeChecksum; + ATime fCreated, fAccessed, fModified, fDeleted; + UInt32 fUID, fGID; + UInt32 fMode; + UInt64 fIndexNodeStart[16], fIndexNodeEnd[16]; + UInt8 fColor; + Lba fNext, fPrev, fChild, fParent; +}; +\end{lstlisting} + +\section{Future Work} +Planned extensions include: +\begin{itemize} + \item Journaling recovery logic + \item Advanced permission flags + \item Logical volume management support + \item Cross-filesystem linking (EPM integration) +\end{itemize} + +\end{document} \ No newline at end of file diff --git a/public/tools/diutil/src/CommandLine.cc b/public/tools/diutil/src/CommandLine.cc index 604520a9..3e7353e6 100644 --- a/public/tools/diutil/src/CommandLine.cc +++ b/public/tools/diutil/src/CommandLine.cc @@ -9,12 +9,12 @@ #include -static const Char kDiskName[kDIDiskNameLen] = "Disk"; -static SInt32 kDiskSectorSz = 512; +static const Char kDiskName[kDIDiskNameLen] = "DISK"; +static SInt32 kDiskSectorSz = kDISectorSz; static SizeT kDiskSz = gib_cast(4); static const Char kOutDisk[kDIOutNameLen] = "disk.eimg"; -/// @brief Filesystem tool entrypoint. +/// @brief Disk Utility entrypoint. int main(int argc, char** argv) { for (SInt32 arg = 0; arg < argc; ++arg) diff --git a/public/tools/mk.hefs/.keep b/public/tools/mk.hefs/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/mk.hefs/mk.hefs.json b/public/tools/mk.hefs/mk.hefs.json new file mode 100644 index 00000000..03f925cf --- /dev/null +++ b/public/tools/mk.hefs/mk.hefs.json @@ -0,0 +1,12 @@ +{ + "compiler_path": "g++", + "compiler_std": "c++20", + "headers_path": ["./", "../../../dev"], + "sources_path": ["src/CommandLine.cc"], + "output_name": "./dist/mk.hefs", + "cpp_macros": [ + "kCCVersion=0x0100", + "kCCVersionHighest=0x0100", + "kCCVersionLowest=0x0100" + ] +} diff --git a/public/tools/mk.hefs/src/CommandLine.cc b/public/tools/mk.hefs/src/CommandLine.cc new file mode 100644 index 00000000..23681be8 --- /dev/null +++ b/public/tools/mk.hefs/src/CommandLine.cc @@ -0,0 +1,14 @@ +/* + * Created on Thu Oct 17 08:00:42 CEST 2024 + * + * Copyright (c) 2025 Amlal El Mahrouss + */ + +#include + +/// @brief Placeholder program. + +SInt32 main(SInt32 argc, Char* argv[]) +{ + return EXIT_FAILURE; +} diff --git a/public/tools/mk.nefs/.keep b/public/tools/mk.nefs/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/mk.nefs/mk.nefs.json b/public/tools/mk.nefs/mk.nefs.json new file mode 100644 index 00000000..e92e0b9c --- /dev/null +++ b/public/tools/mk.nefs/mk.nefs.json @@ -0,0 +1,12 @@ +{ + "compiler_path": "g++", + "compiler_std": "c++20", + "headers_path": ["./", "../../../dev"], + "sources_path": ["src/CommandLine.cc"], + "output_name": "./dist/mk.nefs", + "cpp_macros": [ + "kCCVersion=0x0100", + "kCCVersionHighest=0x0100", + "kCCVersionLowest=0x0100" + ] +} diff --git a/public/tools/mk.nefs/src/CommandLine.cc b/public/tools/mk.nefs/src/CommandLine.cc new file mode 100644 index 00000000..23681be8 --- /dev/null +++ b/public/tools/mk.nefs/src/CommandLine.cc @@ -0,0 +1,14 @@ +/* + * Created on Thu Oct 17 08:00:42 CEST 2024 + * + * Copyright (c) 2025 Amlal El Mahrouss + */ + +#include + +/// @brief Placeholder program. + +SInt32 main(SInt32 argc, Char* argv[]) +{ + return EXIT_FAILURE; +} diff --git a/tooling/copy_to_fat32.py b/tooling/copy_to_fat32.py deleted file mode 100755 index ea0cb1b9..00000000 --- a/tooling/copy_to_fat32.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import os -import sys -import subprocess -import glob - -def copy_to_fat(image_path, source_dir): - if not os.path.isfile(image_path): - print(f"Error: FAT32 image {image_path} does not exist.") - sys.exit(1) - - if not os.path.isdir(source_dir): - print(f"Error: {source_dir} is not a valid directory.") - sys.exit(1) - - try: - files_to_copy = glob.glob(os.path.join(source_dir, "*")) - - # Now build the command - command = ["mcopy", "-spom", "-i", image_path] + files_to_copy + ["::"] - subprocess.run(command, check=True) - - print(f"Successfully copied contents of '{source_dir}' into '{image_path}'") - except FileNotFoundError: - print("Error: mcopy is not installed. Please install mtools.") - sys.exit(1) - except subprocess.CalledProcessError as e: - print(f"Error: mcopy failed with error code {e.returncode}.") - sys.exit(1) - except Exception as e: - print(f"mcopy failed: {e}") - sys.exit(1) - -if __name__ == "__main__": - if len(sys.argv) != 3: - print("Usage: python3 copy_to_fat32.py ") - sys.exit(1) - - image_path = sys.argv[1] - source_dir = sys.argv[2] - - copy_to_fat(image_path, source_dir) \ No newline at end of file diff --git a/tooling/mk_app.py b/tooling/mk_app.py new file mode 100755 index 00000000..34a7702e --- /dev/null +++ b/tooling/mk_app.py @@ -0,0 +1,67 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import json +import sys + +def create_directory_structure(base_path, project_name): + # Define the directory structure + structure = { + project_name: { + "src": { + ".keep": None + }, + "vendor": { + ".keep": None + }, + ".keep": None, + f"{project_name}.json": {} + } + } + + def create_structure(path, structure): + for name, content in structure.items(): + current_path = os.path.join(path, name) + # Create directories or files based on the content type + if isinstance(content, dict) and current_path.endswith(".json") == False: + os.makedirs(current_path, exist_ok=True) + create_structure(current_path, content) + elif content is None: + # Create an empty file + with open(current_path, 'w') as f: + pass + + # Create the base directory + os.makedirs(base_path, exist_ok=True) + create_structure(base_path, structure) + + # Create the JSON file + diutil_json_path = os.path.join(base_path, project_name, f"{project_name}.json") + manifest = { + "compiler_path": "g++", + "compiler_std": "c++20", + "headers_path": ["./", "../../../dev/kernel", "../../../public/frameworks/", "../../../dev/", "./"], + "sources_path": [ + + ], + "output_name": f"./dist/{project_name}", + "cpp_macros": [ + "kSampleVersion=0x0100", + "kSampleVersionHighest=0x0100", + "kSampleVersionLowest=0x0100", + "__NE_SDK__" + ] + } + + with open(diutil_json_path, 'w') as json_file: + json.dump(manifest, json_file, indent=4) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: mk_app.py ") + sys.exit(1) + + base_path = os.getcwd() # Use the current working directory as the base path + create_directory_structure(base_path, sys.argv[1]) + print("Ne application created successfully.") \ No newline at end of file diff --git a/tooling/mk_img.py b/tooling/mk_img.py new file mode 100755 index 00000000..253e5a6c --- /dev/null +++ b/tooling/mk_img.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import sys +import subprocess +import glob + +def copy_to_fat(image_path, source_dir): + if not os.path.isfile(image_path): + print(f"Error: FAT32 image {image_path} does not exist.") + sys.exit(1) + + if not os.path.isdir(source_dir): + print(f"Error: {source_dir} is not a valid directory.") + sys.exit(1) + + try: + files_to_copy = glob.glob(os.path.join(source_dir, "*")) + # Now build the command + command = ["mcopy", "-spom", "-i", image_path] + files_to_copy + ["::"] + subprocess.run(command, check=True) + + print(f"Successfully copied contents of '{source_dir}' into '{image_path}'") + except FileNotFoundError: + print("Error: mcopy is not installed. Please install mtools.") + sys.exit(1) + except subprocess.CalledProcessError as e: + print(f"Error: mcopy failed with error code {e.returncode}.") + sys.exit(1) + except Exception as e: + print(f"mcopy failed: {e}") + sys.exit(1) + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: mk_img.py ") + sys.exit(1) + + image_path = sys.argv[1] + source_dir = sys.argv[2] + + copy_to_fat(image_path, source_dir) \ No newline at end of file -- cgit v1.2.3 From f6b073cb7094e252516516c6b50ccbc34e4efe16 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 21 Apr 2025 13:26:12 +0200 Subject: dev, sched: scheduler security patches. - Regarding process spawning and process exit safer with boundary checks and pointer checks. - Made the method HasMP smarter, with assert as kHandoverHeader is expected to be valid. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/UserProcessScheduler.cc | 47 +++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 5e8cc89e..7e71fc22 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -13,6 +13,7 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ +#include "FirmwareKit/Handover.h" #include #include #include @@ -58,8 +59,8 @@ namespace Kernel if (this->Status != ProcessStatusKind::kRunning) return; - (void)(kout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << kendl); - this->Exit(kErrorProcessFault); + (void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); + this->Exit(-kErrorProcessFault); } /***********************************************************************************/ @@ -285,11 +286,21 @@ namespace Kernel ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image) { + if (!name || !code) + { + return -kErrorProcessFault; + } + + if (*name == 0) + { + return -kErrorProcessFault; + } + ProcessID pid = this->mTeam.mProcessCount; if (pid > kSchedProcessLimitPerTeam) { - return kErrorProcessFault; + return -kErrorProcessFault; } ++this->mTeam.mProcessCount; @@ -299,7 +310,14 @@ namespace Kernel process.Image.fCode = code; process.Image.fBlob = image; - rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, rt_string_len(name)); + SizeT len = rt_string_len(name); + + if (len > kSchedNameLen) + { + return -kErrorProcessFault; + } + + rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ process.VMRegister = new PDE(); @@ -307,7 +325,7 @@ namespace Kernel if (!process.VMRegister) { process.Crash(); - return kErrorProcessFault; + return -kErrorProcessFault; } UInt32 flags = HAL::kMMFlagsPresent; @@ -322,7 +340,7 @@ namespace Kernel if (!process.StackFrame) { process.Crash(); - return kErrorProcessFault; + return -kErrorProcessFault; } rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame)); @@ -357,7 +375,7 @@ namespace Kernel if (!process.StackReserve) { process.Crash(); - return kErrorProcessFault; + return -kErrorProcessFault; } rt_set_memory(process.StackReserve, 0, process.StackSize); @@ -402,6 +420,16 @@ namespace Kernel 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(0); } @@ -423,7 +451,8 @@ namespace Kernel Bool UserProcessScheduler::HasMP() { - return Yes; + MUST_PASS(kHandoverHeader); + return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; } /***********************************************************************************/ @@ -497,7 +526,7 @@ namespace Kernel ErrorOr UserProcessHelper::TheCurrentPID() { if (!kProcessScheduler.CurrentProcess()) - return ErrorOr{kErrorProcessFault}; + return ErrorOr{-kErrorProcessFault}; kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; return ErrorOr{kProcessScheduler.CurrentProcess().Leak().ProcessId}; -- cgit v1.2.3 From f4f543deae3a67c5580d1455081ab86b564cccea Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 21 Apr 2025 13:28:36 +0200 Subject: dev, scheduler: removed unused header included by extension. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/UserProcessScheduler.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 7e71fc22..b45294b3 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -13,7 +13,6 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ -#include "FirmwareKit/Handover.h" #include #include #include -- cgit v1.2.3 From 4f8fb9c70f814de796d61d7d85d4bf133afddafa Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 21 Apr 2025 17:47:16 +0200 Subject: dev, kernel: Made HeFS use a RB-Tree traversal algorithm. - ran format command. - a variation of a red-black tree traversal, with customized fallback mechanism. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FSKit/HeFS.h | 6 +++--- dev/kernel/FirmwareKit/GPT.h | 4 ++-- dev/kernel/FirmwareKit/VEPM.h | 2 -- dev/kernel/GfxKit/FB.h | 24 ++++++++++----------- dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 2 +- dev/kernel/src/FS/HeFS.cc | 23 ++++++++++++++------ dev/kernel/src/FS/NeFS.cc | 2 +- dev/kernel/src/UserProcessScheduler.cc | 2 +- dev/kernel/src/Utils.cc | 2 +- dev/modules/CoreGfx/CoreGfx.h | 28 ++++++++++++------------- 10 files changed, 52 insertions(+), 43 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index d0311a38..4a50f438 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -163,8 +163,8 @@ struct PACKED HEFS_INDEX_NODE_DIRECTORY final Kernel::UInt64 fIndexNodeStart[kHeFSBlockCount]; /// @brief Start of the index node. Kernel::UInt64 fIndexNodeEnd[kHeFSBlockCount]; /// @brief End of the index node. - Kernel::UInt8 fColor; /// @brief Color of the node. (Red or Black). - Kernel::Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers. + Kernel::UInt8 fColor; /// @brief Color of the node. (Red or Black). + Kernel::Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers. }; namespace Kernel::Detail @@ -346,7 +346,7 @@ namespace Kernel class HeFileSystemParser final { public: - HeFileSystemParser() = default; + HeFileSystemParser() = default; ~HeFileSystemParser() = default; public: diff --git a/dev/kernel/FirmwareKit/GPT.h b/dev/kernel/FirmwareKit/GPT.h index dc2b5ce3..aab6b650 100644 --- a/dev/kernel/FirmwareKit/GPT.h +++ b/dev/kernel/FirmwareKit/GPT.h @@ -12,8 +12,8 @@ #define kSectorAlignGPT_PartTbl (420U) #define kSectorAlignGPT_PartEntry (72U) #define kMagicLenGPT (8U) -#define kMagicGPT ("EFI PART") // "EFI PART" -#define kGPTPartitionTableLBA (512U + sizeof(GPT_PARTITION_TABLE)) +#define kMagicGPT ("EFI PART") // "EFI PART" +#define kGPTPartitionTableLBA (512U + sizeof(GPT_PARTITION_TABLE)) namespace Kernel { diff --git a/dev/kernel/FirmwareKit/VEPM.h b/dev/kernel/FirmwareKit/VEPM.h index 742d5868..9d8fa4d4 100644 --- a/dev/kernel/FirmwareKit/VEPM.h +++ b/dev/kernel/FirmwareKit/VEPM.h @@ -11,6 +11,4 @@ /// @brief The Virtual Explicit Partition Map scheme extension. - - #endif // FIRMWAREKIT_VEPM_H \ No newline at end of file diff --git a/dev/kernel/GfxKit/FB.h b/dev/kernel/GfxKit/FB.h index ce5751dc..b01743ff 100644 --- a/dev/kernel/GfxKit/FB.h +++ b/dev/kernel/GfxKit/FB.h @@ -14,22 +14,22 @@ namespace Kernel class FBDeviceInterface; struct FBDevicePacket; - /// @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. + /// @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 { - UInt32 fX; - UInt32 fY; - UInt32 fWidth; - UInt32 fHeight; - UInt32 fColor; - UInt32 fFlags; + UInt32 fX; + UInt32 fY; + UInt32 fWidth; + UInt32 fHeight; + UInt32 fColor; + UInt32 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 IDeviceObject class. + /// @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 IDeviceObject class. class FBDeviceInterface NE_DEVICE { public: diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 3955dd78..576c151b 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -286,7 +286,7 @@ STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi) kSATADev.EnableMmio(); kSATADev.BecomeBusMaster(); - HbaMem* mem_ahci = (HbaMem*)kSATADev.Bar(kSATABar5); + 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); diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 8d73b61e..2269896f 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -141,11 +141,22 @@ namespace Kernel start = dir->fNext; - if (start == 0) - start = dir->fChild; - - if (start == 0) - start = dir->fParent; + if (dir->fColor == kHeFSBlack) + { + if (dir->fParent != 0) + start = dir->fParent; + } + else + { + if (dir->fChild != 0) + start = dir->fChild; + else if (dir->fNext != 0) + start = dir->fNext; + else if (dir->fPrev != 0) + start = dir->fPrev; + else + start = dir->fParent; + } } delete dir; @@ -173,7 +184,7 @@ namespace Kernel NE_UNUSED(mnt); NE_UNUSED(parent_dir_name); NE_UNUSED(node); - + return NO; } } // namespace Detail diff --git a/dev/kernel/src/FS/NeFS.cc b/dev/kernel/src/FS/NeFS.cc index 115e4c82..e8e3804c 100644 --- a/dev/kernel/src/FS/NeFS.cc +++ b/dev/kernel/src/FS/NeFS.cc @@ -460,7 +460,7 @@ _Output Bool NeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, _In NE_UNUSED(end_lba); NE_UNUSED(flags); NE_UNUSED(part_name); - + (void)(kout << "FormatGPT: Not implemented yet.\r"); return NO; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index b45294b3..e96d2b27 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -428,7 +428,7 @@ namespace Kernel { return; } - + mTeam.mProcessList[process_id].Exit(0); } diff --git a/dev/kernel/src/Utils.cc b/dev/kernel/src/Utils.cc index 399be317..f5e61ddf 100644 --- a/dev/kernel/src/Utils.cc +++ b/dev/kernel/src/Utils.cc @@ -42,7 +42,7 @@ namespace Kernel return len; } - + Size rt_string_len(const Char* ptr) { SizeT cnt{0}; diff --git a/dev/modules/CoreGfx/CoreGfx.h b/dev/modules/CoreGfx/CoreGfx.h index 6df2329b..2e555c08 100644 --- a/dev/modules/CoreGfx/CoreGfx.h +++ b/dev/modules/CoreGfx/CoreGfx.h @@ -19,9 +19,9 @@ #ifdef __NE_AMD64__ /// @brief Performs Alpha drawing on the framebuffer. #define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ { \ *(((Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ @@ -34,9 +34,9 @@ /// @brief Performs drawing on the framebuffer. #define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ { \ *(((Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ @@ -48,9 +48,9 @@ } #define FBDrawBitMapInRegionToRgn(_Rgn, reg_ptr, height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ { \ *(((Kernel::UInt32*)(_Rgn + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ @@ -63,9 +63,9 @@ /// @brief Cleans a resource. #define FBClearRegion(height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ { \ *(((volatile Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ @@ -76,9 +76,9 @@ /// @brief Draws inside a zone. #define FBDrawInRegion(clr, height, width, base_x, base_y) \ - for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ + for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ { \ - for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ + for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ { \ *(((volatile Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ @@ -89,9 +89,9 @@ /// @brief Draws inside a zone. #define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y) \ - for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ + for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ { \ - for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ + for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ { \ *(((volatile Kernel::UInt32*)(_Rgn + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ @@ -102,9 +102,9 @@ } #define FBDrawInRegionA(clr, height, width, base_x, base_y) \ - for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ + for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ { \ - for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ + for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ { \ *(((volatile Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ -- cgit v1.2.3 From 42ae768f08f2ec8a41d2ea2183f30a571f0c432f Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 22 Apr 2025 08:48:07 +0200 Subject: dev, kernel: VEPM WiP implementation, and syschk fixes in WiP. - Currently working on VEPM and adapting it to SysChk. - Refactor DriveMgr for VEPM. - Fix warnings in HeFS.cc, ALIGN(8) on HeFS.h - Update PIO modules to use VEPM. Signed-off-by: Amlal El Mahrouss --- compile_flags.txt | 5 +- dev/boot/BootKit/BootKit.h | 127 ++++++++++++++++++++-------- dev/boot/amd64-ci.make | 4 +- dev/boot/amd64-desktop.make | 4 +- dev/boot/arm64-desktop.make | 4 +- dev/boot/modules/SysChk/SysChk.cc | 6 +- dev/boot/modules/SysChk/amd64-ahci-gpt.json | 3 +- dev/boot/modules/SysChk/amd64-pio-gpt.json | 3 +- dev/boot/src/BootThread.cc | 22 ++++- dev/boot/src/HEL/AMD64/BootAPI.S | 45 ++++++++++ dev/boot/src/HEL/AMD64/BootEFI.cc | 2 +- dev/boot/src/HEL/AMD64/BootPlatform.cc | 56 ------------ dev/boot/src/HEL/ARM64/BootEFI.cc | 2 +- dev/kernel/FSKit/HeFS.h | 4 +- dev/kernel/FirmwareKit/EPM.h | 11 ++- dev/kernel/FirmwareKit/GPT.h | 16 +--- dev/kernel/FirmwareKit/VEPM.h | 29 +++++++ dev/kernel/KernelKit/DriveMgr.h | 2 +- dev/kernel/amd64-ci.make | 2 +- dev/kernel/amd64-desktop.make | 2 +- dev/kernel/arm64-desktop.make | 2 +- dev/kernel/kernel_rsrc.rsrc | 2 +- dev/kernel/src/FS/HeFS.cc | 8 +- modules_pio_x64.sh | 2 +- 24 files changed, 229 insertions(+), 134 deletions(-) (limited to 'dev/kernel/src') diff --git a/compile_flags.txt b/compile_flags.txt index 001d0cfc..604ab767 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -21,7 +21,8 @@ -Wall -Wpedantic -Wextra --DBOOTZ_GPT_SUPPORT -D__FSKIT_INCLUDES_HEFS__ -D__FSKIT_INCLUDES_NEFS__ --D__FSKIT_INCLUDES_EXT2__ \ No newline at end of file +-D__FSKIT_INCLUDES_EXT2__ +-D__NE_VEPM__ +-DBOOTZ_VEPM_SUPPORT \ No newline at end of file diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index c781876c..2555812f 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -12,7 +12,6 @@ #pragma once #include -#include #include #include @@ -28,6 +27,9 @@ #include #include +#include +#include +#include #include /***********************************************************************************/ @@ -225,6 +227,7 @@ namespace Boot /// @brief check if partition is good. Bool IsPartitionValid() noexcept { +#if defined(BOOTZ_EPM_SUPPORT) fDiskDev.Leak().mBase = (kNeFSRootCatalogStartAddress); fDiskDev.Leak().mSize = BootDev::kSectorSize; @@ -258,6 +261,9 @@ namespace Boot writer.Write(L"BootZ: Partition: ").Write(blockPart->PartitionName).Write(L" is healthy.\r"); return true; +#else + return false; +#endif } private: @@ -307,7 +313,7 @@ namespace Boot BootDev fDiskDev; }; - /// @brief Format disk. + /// @brief Format disk with a specific partition scheme. /// @param part_name partition Name /// @param blob blos. /// @param blob_sz n blobs (n * sizeof(blob_struct)). @@ -321,11 +327,10 @@ namespace Boot if (!blob || !blob_sz) return false; /// sanity check - /// @note A catalog roughly equal to a sector. - + /// @note A catalog roughly equal to a sector in NeFS terms. constexpr auto kMinimumDiskSize = kNeFSMinimumDiskSize; // at minimum. - /// @note also look at EPM headers, for free part blocks. + /// @note also look at EPM headers, for free part blocks. (only applies if EPM or vEPM is used) if (fDiskDev.GetDiskSize() < kMinimumDiskSize) { @@ -349,13 +354,6 @@ namespace Boot part.DiskSize = fDiskDev.GetDiskSize(); part.Flags = kNeFSPartitionTypeBoot | kNeFSPartitionTypeStandard; -#if defined(BOOTZ_EPM_SUPPORT) - fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; - fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - - fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); -#endif // defined(BOOTZ_EPM_SUPPORT) - BootTextWriter writer; writer << "BootZ: Partition name: " << part.PartitionName << "\r"; @@ -369,7 +367,7 @@ namespace Boot EPM_PART_BLOCK epm_boot{0}; const auto kFsName = "NeFS"; - const auto kBlockName = "OS"; + const auto kBlockName = "OS (EPM)"; epm_boot.FsVersion = kNeFSVersionInteger; epm_boot.LbaStart = kNeFSRootCatalogStartAddress; @@ -378,11 +376,7 @@ namespace Boot epm_boot.Kind = kEPMNeKernel; epm_boot.NumBlocks = part.CatalogCount; - epm_boot.Guid.Data1 = 0x00000000; - epm_boot.Guid.Data2 = 0x0000; - epm_boot.Guid.Data3 = 0x0000; - - SetMem(epm_boot.Guid.Data4, 0, 8); + epm_boot.Guid = kEPMNilGuid; CopyMem(epm_boot.Fs, reinterpret_cast(const_cast(kFsName)), StrLen(kFsName)); CopyMem(epm_boot.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); @@ -393,36 +387,44 @@ namespace Boot fDiskDev.Write((Char*)&epm_boot, sizeof(EPM_PART_BLOCK)); - writer.Write(L"BootZ: Drive is EPM formatted.\r"); -#elif defined(BOOTZ_GPT_SUPPORT) - const auto kBlockName = "NeFS_OS"; + fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; + fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + + fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); + writer.Write(L"BootZ: Drive is EPM formatted.\r"); +#elif defined(BOOTZ_GPT_SUPPORT) || defined(BOOTZ_VEPM_SUPPORT) GPT_PARTITION_TABLE gpt_part{0}; CopyMem(gpt_part.Signature, reinterpret_cast(const_cast(kMagicGPT)), StrLen(kMagicGPT)); - gpt_part.Revision = 0x00010000; + gpt_part.Revision = 0x00010000; gpt_part.HeaderSize = sizeof(GPT_PARTITION_TABLE); gpt_part.CRC32 = 0x00000000; - gpt_part.Reserved1 = 0x00000000; - gpt_part.LBAHeader = 0x00000000; - gpt_part.LBAAltHeader = 0x00000000; + gpt_part.Reserved1 = 0x00000000; + gpt_part.LBAHeader = 0x00000000; + gpt_part.LBAAltHeader = 0x00000000; gpt_part.FirstGPTEntry = 0x00000000; - gpt_part.LastGPTEntry = 0x00000000; - gpt_part.Guid.Data1 = 0x00000000; - gpt_part.Guid.Data2 = 0x0000; - gpt_part.Guid.Data3 = 0x0000; + gpt_part.LastGPTEntry = 0x00000000; - gpt_part.Revision = 0x00010000; +#if defined(BOOTZ_GPT_SUPPORT) + gpt_part.Guid.Data1 = 0x00000000; + gpt_part.Guid.Data2 = 0x0000; + gpt_part.Guid.Data3 = 0x0000; SetMem(gpt_part.Guid.Data4, 0, 8); +#else + gpt_part.Guid = kVEPMGuidEFI; +#endif - gpt_part.StartingLBA = 0x00000000; + gpt_part.Revision = 0x00010000; + + gpt_part.StartingLBA = 0x00000000; gpt_part.NumPartitionEntries = 0x00000000; - gpt_part.SizeOfEntries = 0x00000000; - gpt_part.CRC32PartEntry = 0x00000000; + gpt_part.SizeOfEntries = 0x00000000; + gpt_part.CRC32PartEntry = 0x00000000; SetMem(gpt_part.Reserved2, 0, kSectorAlignGPT_PartTbl); @@ -431,6 +433,63 @@ namespace Boot fDiskDev.Write((Char*)&gpt_part, sizeof(GPT_PARTITION_TABLE)); +#if defined(BOOTZ_VEPM_SUPPORT) + const auto kBlockName = "OS (VEPM)"; + + GPT_PARTITION_ENTRY gpt_part_entry{0}; + + gpt_part_entry.StartLBA = kNeFSRootCatalogStartAddress; + gpt_part_entry.EndLBA = fDiskDev.GetDiskSize(); + gpt_part_entry.Attributes = 0x00000000; + + gpt_part_entry.PartitionTypeGUID.Data1 = 0x00000000; + gpt_part_entry.PartitionTypeGUID.Data2 = 0x0000; + gpt_part_entry.PartitionTypeGUID.Data3 = 0x0000; + + CopyMem(gpt_part_entry.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); + + SetMem(gpt_part_entry.PartitionTypeGUID.Data4, 0, 8); + + fDiskDev.Leak().mBase = kGPTPartitionTableLBA + sizeof(GPT_PARTITION_TABLE); + fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_ENTRY); + fDiskDev.Write((Char*)&gpt_part_entry, sizeof(GPT_PARTITION_ENTRY)); + + EPM_PART_BLOCK epm_boot{0}; + + const auto kFsName = "NeFS"; + + epm_boot.FsVersion = kNeFSVersionInteger; + epm_boot.LbaStart = kNeFSRootCatalogStartAddress; + epm_boot.LbaEnd = fDiskDev.GetDiskSize(); + epm_boot.SectorSz = part.SectorSize; + epm_boot.Kind = kEPMNeKernel; + epm_boot.NumBlocks = part.CatalogCount; + + epm_boot.Guid = kEPMNilGuid; + + CopyMem(epm_boot.Fs, reinterpret_cast(const_cast(kFsName)), StrLen(kFsName)); + CopyMem(epm_boot.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); + CopyMem(epm_boot.Magic, reinterpret_cast(const_cast(kEPMMagic)), StrLen(kEPMMagic)); + + fDiskDev.Leak().mBase = kGPTPartitionTableLBA + sizeof(GPT_PARTITION_TABLE); + fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_ENTRY); + + fDiskDev.Write((Char*)&gpt_part_entry, sizeof(GPT_PARTITION_ENTRY)); + + fDiskDev.Leak().mBase = gpt_part_entry.StartLBA; + fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); + + fDiskDev.Write((Char*)&epm_boot, sizeof(EPM_PART_BLOCK)); + + fDiskDev.Leak().mBase = gpt_part_entry.StartLBA + kNeFSRootCatalogStartAddress; + fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + + fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); + + writer.Write(L"BootZ: Drive is vEPM formatted.\r"); +#else + const auto kBlockName = "OS (GPT)"; + GPT_PARTITION_ENTRY gpt_part_entry{0}; gpt_part_entry.StartLBA = kNeFSRootCatalogStartAddress; @@ -455,7 +514,7 @@ namespace Boot fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); writer.Write(L"BootZ: Drive is GPT formatted.\r"); - +#endif /// defined(BOOTZ_VEPM_SUPPORT) #endif return YES; diff --git a/dev/boot/amd64-ci.make b/dev/boot/amd64-ci.make index 62ab9af1..b396b0d5 100644 --- a/dev/boot/amd64-ci.make +++ b/dev/boot/amd64-ci.make @@ -70,7 +70,7 @@ FLAG_GNU=-fshort-wchar -Wall -Wpedantic -Wextra -Werror -D__EFI_x86_64__ -mno-re -std=c++20 -DBOOTZ_GPT_SUPPORT -DBOOTZ_EPM_SUPPORT -D__HAVE_NE_APIS__ -DZBA_USE_FB -D__NE_AMD64__ -D__NE__ -DNE_AUTO_FORMAT BOOTLOADER=bootz.efi -KERNEL=vmkrnl.efi +KERNEL=krnl.efi SYSCHK=chk.efi BOOTNET=net.efi SCIKIT=user.sys @@ -130,7 +130,7 @@ efi: $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd BINS=*.bin -EXECUTABLES=bootz.efi vmkrnl.efi OVMF.fd +EXECUTABLES=bootz.efi krnl.efi OVMF.fd TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 45446333..432a00c8 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -72,7 +72,7 @@ FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -Wall -Wpedantic -Wextra -mno-red-zone - -std=c++20 -DBOOTZ_GPT_SUPPORT -DBOOTZ_EPM_SUPPORT -D__HAVE_NE_APIS__ -DZBA_USE_FB -D__NE_AMD64__ -D__NE__ -DNE_AUTO_FORMAT -Wl,--disable-reloc-section BOOTLOADER=bootz.efi -KERNEL=vmkrnl.efi +KERNEL=krnl.efi SYSCHK=chk.efi BOOTNET=net.efi SCIKIT=user.sys @@ -138,7 +138,7 @@ efi: $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd BINS=*.bin -EXECUTABLES=bootz.efi vmkrnl.efi OVMF.fd +EXECUTABLES=bootz.efi krnl.efi OVMF.fd TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) diff --git a/dev/boot/arm64-desktop.make b/dev/boot/arm64-desktop.make index 06ec84d0..114d2e7e 100644 --- a/dev/boot/arm64-desktop.make +++ b/dev/boot/arm64-desktop.make @@ -48,7 +48,7 @@ FLAG_GNU=-fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__NE_ARM64__ -fno- -std=c++20 -DBOOTZ_EPM_SUPPORT -DZBA_USE_FB -D__FSKIT_USE_NEFS__ -D__BOOTZ_STANDALONE__ -D__NEOSKRNL__ -D__BOOTZ__ -D__HAVE_NE_APIS__ -D__NE__ -I../ -I../kernel BOOT_LOADER=bootz.efi -KERNEL=vmkrnl.efi +KERNEL=krnl.efi SYSCHK=chk.efi STARTUP=startup.efi @@ -94,7 +94,7 @@ efi: $(HTTP_GET) https://retrage.github.io/edk2-nightly/bin/DEBUGAARCH64_QEMU_EFI.fd -O OVMF.fd BINS=*.bin -EXECUTABLES=bootz.efi vmkrnl.efi OVMF.fd +EXECUTABLES=bootz.efi krnl.efi OVMF.fd TARGETS=$(REM_FLAG) $(OBJ) $(BIN) $(IMG) $(IMG_2) $(EXECUTABLES) diff --git a/dev/boot/modules/SysChk/SysChk.cc b/dev/boot/modules/SysChk/SysChk.cc index 3979714d..1b1de6f4 100644 --- a/dev/boot/modules/SysChk/SysChk.cc +++ b/dev/boot/modules/SysChk/SysChk.cc @@ -23,7 +23,7 @@ // Makes the compiler shut up. #ifndef kMachineModel -#define kMachineModel "Ne" +#define kMachineModel "OS" #endif // !kMachineModel EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) @@ -31,6 +31,8 @@ EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) NE_UNUSED(handover); #if defined(__ATA_PIO__) + Boot::BootTextWriter writer; + Boot::BDiskFormatFactory partition_factory; if (partition_factory.IsPartitionValid()) @@ -44,6 +46,8 @@ EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) partition_factory.Format(kMachineModel, &desc, 1); + writer.Write(L"BootZ: Partition formatted.\r"); + if (partition_factory.IsPartitionValid()) return kEfiOk; diff --git a/dev/boot/modules/SysChk/amd64-ahci-gpt.json b/dev/boot/modules/SysChk/amd64-ahci-gpt.json index 52864969..6a204a25 100644 --- a/dev/boot/modules/SysChk/amd64-ahci-gpt.json +++ b/dev/boot/modules/SysChk/amd64-ahci-gpt.json @@ -17,7 +17,8 @@ "__BOOTZ_STANDALONE__", "__NE_AMD64__", "__AHCI__", - "BOOTZ_GPT_SUPPORT", + "__NE_VEPM__", + "BOOTZ_VEPM_SUPPORT", "kChkVersionHighest=0x0100", "kChkVersionLowest=0x0100", "kChkVersion=0x0100" diff --git a/dev/boot/modules/SysChk/amd64-pio-gpt.json b/dev/boot/modules/SysChk/amd64-pio-gpt.json index 2a4c4efe..4fe9d986 100644 --- a/dev/boot/modules/SysChk/amd64-pio-gpt.json +++ b/dev/boot/modules/SysChk/amd64-pio-gpt.json @@ -17,7 +17,8 @@ "__BOOTZ_STANDALONE__", "__NE_AMD64__", "__ATA_PIO__", - "BOOTZ_GPT_SUPPORT", + "__NE_VEPM__", + "BOOTZ_VEPM_SUPPORT", "kChkVersionHighest=0x0100", "kChkVersionLowest=0x0100", "kChkVersion=0x0100" diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index 0a1e74c9..cf303bec 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -129,16 +129,16 @@ namespace Boot #ifdef __NE_AMD64__ if (handover_struc->HandoverArch != HEL::kArchAMD64) { - fb_render_string("BootZ: Not an handover header, bad CPU...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + writer.Write("BootZ: Not an handover header, bad CPU...\r"); } #elif defined(__NE_ARM64__) if (handover_struc->HandoverArch != HEL::kArchARM64) { - fb_render_string("BootZ: Not an handover header, bad CPU...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + writer.Write("BootZ: Not an handover header, bad CPU...\r"); } #endif - fb_render_string("BootZ: Not an handover header...", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + writer.Write("BootZ: Not an handover header...\r"); ::Boot::Stop(); } } @@ -190,10 +190,24 @@ namespace Boot if (own_stack) { - return rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); + writer.Write("BootZ: Using own stack.\r"); + writer.Write("BootZ: Stack address: ").Write((UIntPtr)&fStack[mib_cast(16) - 1]).Write("\r"); + writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); + + rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); + + return kEfiOk; } else { + delete[] fStack; + fStack = nullptr; + // we don't need the stack anymore. + + BootTextWriter writer; + + writer.Write("BootZ: Using EFI stack.\r"); + return reinterpret_cast(fStartAddress)(fHandover); } diff --git a/dev/boot/src/HEL/AMD64/BootAPI.S b/dev/boot/src/HEL/AMD64/BootAPI.S index 963ef46a..9cc15918 100644 --- a/dev/boot/src/HEL/AMD64/BootAPI.S +++ b/dev/boot/src/HEL/AMD64/BootAPI.S @@ -58,3 +58,48 @@ boot_read_cr3: boot_write_cr3: mov cr3, rcx ret + +.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 \ No newline at end of file diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 8a920e1a..85b7f729 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -229,7 +229,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); // Assign to global 'kHandoverHeader'. - WideChar kernel_path[256U] = L"vmkrnl.efi"; + WideChar kernel_path[256U] = L"krnl.efi"; UInt32 kernel_path_sz = 256U; if (ST->RuntimeServices->GetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, nullptr, &kernel_path_sz, kernel_path) != kEfiOk) diff --git a/dev/boot/src/HEL/AMD64/BootPlatform.cc b/dev/boot/src/HEL/AMD64/BootPlatform.cc index a06b8aa0..1a1f9b89 100644 --- a/dev/boot/src/HEL/AMD64/BootPlatform.cc +++ b/dev/boot/src/HEL/AMD64/BootPlatform.cc @@ -38,62 +38,6 @@ EXTERN_C void rt_std() asm volatile("std"); } -EXTERN_C void rt_out8(UInt16 port, UInt8 value) -{ - asm volatile("outb %%al, %1" - : - : "a"(value), "Nd"(port) - : "memory"); -} - -EXTERN_C void rt_out16(UInt16 port, UInt16 value) -{ - asm volatile("outw %%ax, %1" - : - : "a"(value), "Nd"(port) - : "memory"); -} - -EXTERN_C void rt_out32(UInt16 port, UInt32 value) -{ - asm volatile("outl %%eax, %1" - : - : "a"(value), "Nd"(port) - : "memory"); -} - -EXTERN_C UInt8 rt_in8(UInt16 port) -{ - UInt8 value; - asm volatile("inb %1, %%al" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; -} - -EXTERN_C UInt16 rt_in16(UInt16 port) -{ - UInt16 value; - asm volatile("inw %%dx, %%ax" - : "=a"(value) - : "d"(port)); - - return value; -} - -EXTERN_C UInt32 rt_in32(UInt16 port) -{ - UInt32 value; - asm volatile("inl %1, %%eax" - : "=a"(value) - : "Nd"(port) - : "memory"); - - return value; -} - #else #include diff --git a/dev/boot/src/HEL/ARM64/BootEFI.cc b/dev/boot/src/HEL/ARM64/BootEFI.cc index e071def1..9132cec1 100644 --- a/dev/boot/src/HEL/ARM64/BootEFI.cc +++ b/dev/boot/src/HEL/ARM64/BootEFI.cc @@ -226,7 +226,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); - Boot::BootFileReader reader_kernel(L"vmkrnl.efi", image_handle); + Boot::BootFileReader reader_kernel(L"krnl.efi", image_handle); reader_kernel.ReadAll(0); diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 4a50f438..65594b99 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -115,7 +115,7 @@ inline constexpr ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; /// @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 +struct PACKED ALIGN(8) HEFS_INDEX_NODE final { Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief File name. Kernel::UInt32 fFlags; /// @brief File flags. @@ -147,7 +147,7 @@ enum /// @brief HeFS 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 +struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final { Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief Directory name. diff --git a/dev/kernel/FirmwareKit/EPM.h b/dev/kernel/FirmwareKit/EPM.h index 548bb9a7..6db82506 100644 --- a/dev/kernel/FirmwareKit/EPM.h +++ b/dev/kernel/FirmwareKit/EPM.h @@ -80,8 +80,8 @@ typedef struct EPM_GUID */ struct PACKED EPM_PART_BLOCK { - Kernel::Char Magic[kEPMMagicLength]; - Kernel::Char Name[kEPMNameLength]; + Kernel::Char Magic[kEPMMagicLength] = {0}; + Kernel::Char Name[kEPMNameLength] = {0}; EPM_GUID Guid; Kernel::Int32 Version; Kernel::Int64 NumBlocks; @@ -108,4 +108,11 @@ enum 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 index aab6b650..4be1fed2 100644 --- a/dev/kernel/FirmwareKit/GPT.h +++ b/dev/kernel/FirmwareKit/GPT.h @@ -17,19 +17,9 @@ namespace Kernel { - struct GPT_GUID; struct GPT_PARTITION_TABLE; struct GPT_PARTITION_ENTRY; - /// @brief GPT GUID structure. - typedef struct GPT_GUID - { - Kernel::UInt32 Data1; - Kernel::UInt16 Data2; - Kernel::UInt16 Data3; - Kernel::UInt8 Data4[8]; - } GPT_GUID; - struct PACKED GPT_PARTITION_TABLE final { Char Signature[kMagicLenGPT]; @@ -41,7 +31,7 @@ namespace Kernel UInt64 LBAAltHeader; UInt64 FirstGPTEntry; UInt64 LastGPTEntry; - GPT_GUID Guid; + EfiGUID Guid; UInt64 StartingLBA; UInt32 NumPartitionEntries; UInt32 SizeOfEntries; @@ -51,8 +41,8 @@ namespace Kernel struct PACKED GPT_PARTITION_ENTRY { - GPT_GUID PartitionTypeGUID; - GPT_GUID UniquePartitionGUID; + EfiGUID PartitionTypeGUID; + EfiGUID UniquePartitionGUID; UInt64 StartLBA; UInt64 EndLBA; UInt64 Attributes; diff --git a/dev/kernel/FirmwareKit/VEPM.h b/dev/kernel/FirmwareKit/VEPM.h index 9d8fa4d4..2b95e12d 100644 --- a/dev/kernel/FirmwareKit/VEPM.h +++ b/dev/kernel/FirmwareKit/VEPM.h @@ -8,7 +8,36 @@ #define FIRMWAREKIT_VEPM_H #include +#include /// @brief The Virtual Explicit Partition Map scheme extension. +#ifdef __NE_VEPM__ +#ifdef kEPMMagic +#undef kEPMMagic +#endif // kEPMMagic + +#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 EfiGUID kVEPMGuidEFI = { + 0x9a1b3f2e, + 0x4c3f, + 0x4d52, + { 0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac } +}; + +#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/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h index 36aa635e..9dc8162b 100644 --- a/dev/kernel/KernelKit/DriveMgr.h +++ b/dev/kernel/KernelKit/DriveMgr.h @@ -39,7 +39,7 @@ namespace Kernel /// Storage flags, combine with types. kReadOnlyDrive = 0x10, // Read only drive kEPMDrive = 0x11, // Explicit Partition Map. - kEPTDrive = 0x12, // ESP w/ EPM partition. + kVEPMDrive = 0x12, // ESP w/ EPM partition. kMBRDrive = 0x13, // PC classic partition scheme kGPTDrive = 0x14, // PC new partition scheme kUnformattedDrive = 0x15, diff --git a/dev/kernel/amd64-ci.make b/dev/kernel/amd64-ci.make index 7748fc7c..4fb87ee1 100644 --- a/dev/kernel/amd64-ci.make +++ b/dev/kernel/amd64-ci.make @@ -35,7 +35,7 @@ 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 = vmkrnl.efi +KERNEL_IMG = krnl.efi .PHONY: error error: diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index ca31d130..7a901229 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -37,7 +37,7 @@ 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 = vmkrnl.efi +KERNEL_IMG = krnl.efi .PHONY: error error: diff --git a/dev/kernel/arm64-desktop.make b/dev/kernel/arm64-desktop.make index ec2a04ce..8a1a8c19 100644 --- a/dev/kernel/arm64-desktop.make +++ b/dev/kernel/arm64-desktop.make @@ -23,7 +23,7 @@ LDFLAGS = -subsystem:efi_application -entry:hal_init_platform /nodefaultlib LDOBJ = obj/*.obj # This file is the Kernel, responsible of task management and memory. -KERNEL = vmkrnl.efi +KERNEL = krnl.efi .PHONY: error error: diff --git a/dev/kernel/kernel_rsrc.rsrc b/dev/kernel/kernel_rsrc.rsrc index ab149b31..69922999 100644 --- a/dev/kernel/kernel_rsrc.rsrc +++ b/dev/kernel/kernel_rsrc.rsrc @@ -13,7 +13,7 @@ BEGIN VALUE "FileVersion", KERNEL_VERSION VALUE "InternalName", "neoskrnl" VALUE "LegalCopyright", "(c) 2024-2025 Amlal El Mahrouss, all rights reserved" - VALUE "OriginalFilename", "vmkrnl.efi" + VALUE "OriginalFilename", "krnl.efi" VALUE "ProductName", "NeKernel" VALUE "ProductVersion", KERNEL_VERSION END diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 2269896f..e053c8c4 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -31,14 +31,14 @@ namespace Kernel /// @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 HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; + STATIC ATTRIBUTE(unused) HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; /// @brief Allocate a new index node. /// @param root The root node of the filesystem. /// @param mnt The drive to read from. /// @param parent_dir_name The name of the parent directory. /// @return Status, see err_global_get(). - STATIC BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; + STATIC ATTRIBUTE(unused) BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. @@ -46,7 +46,7 @@ namespace Kernel /// @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 HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + STATIC ATTRIBUTE(unused) HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept { if (root) { @@ -178,7 +178,7 @@ namespace Kernel /// @param mnt The drive to read from. /// @param parent_dir_name The name of the parent directory. /// @return Status, see err_global_get(). - STATIC BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept + STATIC ATTRIBUTE(unused) BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept { NE_UNUSED(root); NE_UNUSED(mnt); diff --git a/modules_pio_x64.sh b/modules_pio_x64.sh index b091704e..49f0e667 100755 --- a/modules_pio_x64.sh +++ b/modules_pio_x64.sh @@ -5,7 +5,7 @@ # 04/05/25: Improve and fix script. cd dev/boot/modules/SysChk -btb amd64-pio-epm.json +btb amd64-pio-gpt.json cd ../ cd BootNet btb amd64.json \ No newline at end of file -- cgit v1.2.3 From 902f36756c45035f6adb046af65c56482b3c75ea Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 22 Apr 2025 14:51:09 +0200 Subject: kernel, {fs,sched}: User RT scheduler fixes and HeFS advancements regarding the B-Tree. - RT Scheduler fixed. - B-Tree improved. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/FS/HeFS.cc | 361 ++++++++++++++++++++++++++++++--- dev/kernel/src/UserProcessScheduler.cc | 7 +- 2 files changed, 340 insertions(+), 28 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index e053c8c4..4a46236a 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -25,6 +25,13 @@ namespace Kernel { /// @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) Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start); + /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. /// @param mnt The drive to read from. @@ -35,11 +42,145 @@ namespace Kernel /// @brief Allocate a new index node. /// @param root The root node of the filesystem. - /// @param mnt The drive to read from. + /// @param mnt The drive to read/write from. /// @param parent_dir_name The name of the parent directory. /// @return Status, see err_global_get(). STATIC ATTRIBUTE(unused) BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; + /// @brief Balance RB-Tree of the filesystem. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read/write from. + /// @return Status, see err_global_get(). + STATIC ATTRIBUTE(unused) BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt); + + /// @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, Lba& start) + { + start = dir->fNext; + + if (dir->fColor == kHeFSBlack) + { + if (dir->fParent != 0) + start = dir->fParent; + } + else + { + if (dir->fChild != 0) + start = dir->fChild; + else if (dir->fNext != 0) + start = dir->fNext; + else if (dir->fPrev != 0) + start = dir->fPrev; + else + start = dir->fParent; + } + } + + /***********************************************************************************/ + /// @brief Rotate the RB-Tree to the left. + /// @internal + /***********************************************************************************/ + STATIC ATTRIBUTE(unused) Void hefsi_rotate_left(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) + { + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!parent) + { + kout << "Error: Failed to allocate memory for index node.\r"; + return; + } + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fInput(mnt->fPacket); + + HEFS_INDEX_NODE_DIRECTORY* grand_parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!grand_parent) + { + delete grand_parent; + kout << "Error: Failed to allocate memory for index node.\r"; + return; + } + + mnt->fPacket.fPacketLba = parent->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = grand_parent; + + mnt->fInput(mnt->fPacket); + + dir->fParent = parent->fParent; + parent->fParent = start; + parent->fNext = dir->fChild; + dir->fChild = dir->fParent; + + mnt->fPacket.fPacketLba = parent->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = grand_parent; + + mnt->fOutput(mnt->fPacket); + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fOutput(mnt->fPacket); + + delete parent; + parent = nullptr; + + delete grand_parent; + grand_parent = nullptr; + + dir->fColor = kHeFSBlack; + } + + /***********************************************************************************/ + /// @brief Rotate the RB-Tree to the right. + /// @internal + /***********************************************************************************/ + STATIC ATTRIBUTE(unused) Void hefsi_rotate_right(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) + { + if (dir->fChild || dir->fNext || dir->fPrev) + { + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fInput(mnt->fPacket); + + parent->fParent = dir->fParent; + dir->fParent = parent->fParent; + dir->fNext = parent->fChild; + parent->fChild = start; + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fOutput(mnt->fPacket); + + delete parent; + parent = nullptr; + + dir->fColor = kHeFSBlack; + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fOutput(mnt->fPacket); + } + } + /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. /// @param mnt The drive to read from. @@ -48,7 +189,7 @@ namespace Kernel /// @param kind The kind of the file (regular, directory, block, character, FIFO, socket, symbolic link, unknown). STATIC ATTRIBUTE(unused) HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept { - if (root) + if (root && mnt) { HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); @@ -64,8 +205,14 @@ namespace Kernel auto hop_watch = 0; - while (start != end) + while (YES) { + if (start > end) + { + kout << "Error: Invalid start/end values.\r"; + break; + } + if (hop_watch > 100) { kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; @@ -139,24 +286,7 @@ namespace Kernel } } - start = dir->fNext; - - if (dir->fColor == kHeFSBlack) - { - if (dir->fParent != 0) - start = dir->fParent; - } - else - { - if (dir->fChild != 0) - start = dir->fChild; - else if (dir->fNext != 0) - start = dir->fNext; - else if (dir->fPrev != 0) - start = dir->fPrev; - else - start = dir->fParent; - } + hefsi_traverse_tree(dir, start); } delete dir; @@ -180,10 +310,191 @@ namespace Kernel /// @return Status, see err_global_get(). STATIC ATTRIBUTE(unused) BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept { - NE_UNUSED(root); - NE_UNUSED(mnt); - NE_UNUSED(parent_dir_name); - NE_UNUSED(node); + if (root && mnt) + { + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + auto start = root->fStartIND; + + auto hop_watch = 0; + + while (YES) + { + if (hop_watch > 100) + { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) + { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (KStringBuilder::Equals(dir->fName, parent_dir_name)) + { + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; ++inode_index) + { + if (dir->fIndexNodeStart[inode_index] != 0 || + dir->fIndexNodeEnd[inode_index] != 0) + { + mnt->fPacket.fPacketLba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] : dir->fIndexNodeStart[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + + mnt->fOutput(mnt->fPacket); + + if (mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + return YES; + } + } + } + } + + hefsi_traverse_tree(dir, start); + } + + delete dir; + dir = nullptr; + + return YES; + } + + return NO; + } + + /// @brief Balance RB-Tree of the filesystem. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read/write from. + /// @return Status, see err_global_get(). + STATIC ATTRIBUTE(unused) BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt) + { + if (root && mnt) + { + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + HEFS_INDEX_NODE_DIRECTORY* dir_parent = new HEFS_INDEX_NODE_DIRECTORY(); + + auto start = root->fStartIND; + + while (YES) + { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (start == root->fStartIND) + { + dir->fColor = kHeFSBlack; + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fOutput(mnt->fPacket); + } + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; + + mnt->fInput(mnt->fPacket); + + if (dir_parent->fColor != kHeFSRed) + { + delete dir_parent; + delete dir; + + dir = nullptr; + dir_parent = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + + if (!mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + + HEFS_INDEX_NODE_DIRECTORY dir_uncle{}; + + mnt->fPacket.fPacketLba = dir_parent->fNext; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = &dir_uncle; + + mnt->fInput(mnt->fPacket); + + if (dir_uncle.fColor == kHeFSRed) + { + dir_parent->fColor = kHeFSBlack; + dir_uncle.fColor = kHeFSBlack; + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; + + mnt->fOutput(mnt->fPacket); + + mnt->fPacket.fPacketLba = dir_uncle.fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = &dir_uncle; + + mnt->fOutput(mnt->fPacket); + + hefsi_traverse_tree(dir, start); + continue; + } + else + { + if (dir_parent->fNext == start) + { + hefsi_rotate_left(dir, start, mnt); + hefsi_traverse_tree(dir, start); + + continue; + } + + dir_parent->fColor = kHeFSBlack; + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; + + mnt->fOutput(mnt->fPacket); + + hefsi_rotate_right(dir, start, mnt); + hefsi_traverse_tree(dir, start); + + continue; + } + + hefsi_traverse_tree(dir, start); + } + + delete dir; + dir = nullptr; + + return YES; + } return NO; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index e96d2b27..77831082 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -230,8 +230,11 @@ namespace Kernel memory_heap_list = next; } +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ //! Free the memory's page directory. - HAL::mm_free_bitmap(this->VMRegister); + if (this->VMRegister) + HAL::mm_free_bitmap(this->VMRegister); +#endif //! Delete image if not done already. if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode)) @@ -273,8 +276,6 @@ namespace Kernel this->Status = ProcessStatusKind::kFinished; --this->ProcessParentTeam->mProcessCount; - - delete this; } /***********************************************************************************/ -- cgit v1.2.3 From 8434a141533891ebd7cb5369c0541cb9a9c07971 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 22 Apr 2025 14:58:21 +0200 Subject: fs, HeFS: additional patches regarding tree traversal. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/FS/HeFS.cc | 53 ++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 4a46236a..ccd808ad 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -104,8 +104,9 @@ namespace Kernel if (!grand_parent) { - delete grand_parent; + delete parent; kout << "Error: Failed to allocate memory for index node.\r"; + return; } @@ -147,38 +148,42 @@ namespace Kernel /***********************************************************************************/ STATIC ATTRIBUTE(unused) Void hefsi_rotate_right(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) { - if (dir->fChild || dir->fNext || dir->fPrev) + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!parent) { - HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + kout << "Error: Failed to allocate memory for index node.\r"; - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = parent; + return; + } + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; - mnt->fInput(mnt->fPacket); + mnt->fInput(mnt->fPacket); - parent->fParent = dir->fParent; - dir->fParent = parent->fParent; - dir->fNext = parent->fChild; - parent->fChild = start; + parent->fParent = dir->fParent; + dir->fParent = parent->fParent; + dir->fNext = parent->fChild; + parent->fChild = start; - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = parent; + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; - mnt->fOutput(mnt->fPacket); + mnt->fOutput(mnt->fPacket); - delete parent; - parent = nullptr; + delete parent; + parent = nullptr; - dir->fColor = kHeFSBlack; + dir->fColor = kHeFSBlack; - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; - mnt->fOutput(mnt->fPacket); - } + mnt->fOutput(mnt->fPacket); } /// @brief Get the index node of a file or directory. @@ -402,7 +407,7 @@ namespace Kernel mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; - + mnt->fOutput(mnt->fPacket); } -- cgit v1.2.3 From 5ba2b615e172d93d1ffb06f611b19a4388ed074e Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 22 Apr 2025 18:30:00 +0200 Subject: dev, kernel: Milestone towards 0.0.2, see details. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Details: - Added support for 512 process teams (kTeams array). - New SwitchTeam() API in UserProcessScheduler. - Kernel main loop rotates active team every 200ms. - Renamed syscall tables for clarity (kSyscalls → kSysCalls, etc.). - Replaced kKernelMaxSystemCalls with kMaxDispatchCallCount. - Updated call sites to match new naming. - Bumped format version to 0x0101. - Added reserved fields to HEFS_BOOT_NODE for future use. - Changed inode indexing logic to operate on (start, size) pairs. Signed-off-by: Amlal El Mahrouss --- dev/kernel/ArchKit/ArchKit.h | 10 ++++---- dev/kernel/FSKit/HeFS.h | 10 +++++++- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 16 ++++++------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 17 +++++++++++++- dev/kernel/KernelKit/UserProcessScheduler.h | 9 +++++++- dev/kernel/src/FS/HeFS.cc | 4 ++-- dev/kernel/src/UserProcessScheduler.cc | 27 +++++++++++++++++----- 7 files changed, 69 insertions(+), 24 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h index c55f3872..bb483d28 100644 --- a/dev/kernel/ArchKit/ArchKit.h +++ b/dev/kernel/ArchKit/ArchKit.h @@ -26,7 +26,7 @@ #error !!! unknown architecture !!! #endif -#define kKernelMaxSystemCalls (512U) +#define kMaxDispatchCallCount (512U) namespace Kernel { @@ -88,11 +88,11 @@ struct HalSyscallEntry final }; inline Kernel::Array - kSyscalls; + kMaxDispatchCallCount> + kSysCalls; inline Kernel::Array - kKerncalls; + kMaxDispatchCallCount> + kKernCalls; EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 65594b99..60f1342a 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -17,7 +17,7 @@ /// @file HeFS.h /// @brief HeFS filesystem support. -#define kHeFSVersion (0x0100) +#define kHeFSVersion (0x0101) #define kHeFSMagic " HeFS" #define kHeFSMagicLen (8) @@ -102,6 +102,10 @@ struct PACKED HEFS_BOOT_NODE final Kernel::UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid). Kernel::UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). Kernel::UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). + Kernel::UInt64 fReserved; /// @brief Reserved for future use. + Kernel::UInt64 fReserved2; /// @brief Reserved for future use. + Kernel::UInt64 fReserved3; /// @brief Reserved for future use. + Kernel::UInt64 fReserved4; /// @brief Reserved for future use. }; /// @brief Access time type. @@ -160,6 +164,10 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. Kernel::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. Kernel::UInt64 fIndexNodeStart[kHeFSBlockCount]; /// @brief Start of the index node. Kernel::UInt64 fIndexNodeEnd[kHeFSBlockCount]; /// @brief End of the index node. diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 7209fd06..46775a7f 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -190,15 +190,15 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) /// @return nothing. EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, Kernel::UIntPtr rdx_syscall_struct) { - if (rcx_syscall_index < kSyscalls.Count()) + if (rcx_syscall_index < kSysCalls.Count()) { Kernel::kout << "syscall: Enter Syscall.\r"; - if (kSyscalls[rcx_syscall_index].fHooked) + if (kSysCalls[rcx_syscall_index].fHooked) { - if (kSyscalls[rcx_syscall_index].fProc) + if (kSysCalls[rcx_syscall_index].fProc) { - (kSyscalls[rcx_syscall_index].fProc)((Kernel::VoidPtr)rdx_syscall_struct); + (kSysCalls[rcx_syscall_index].fProc)((Kernel::VoidPtr)rdx_syscall_struct); } else { @@ -219,15 +219,15 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, K /// @return nothing. EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, Kernel::UIntPtr rdx_kerncall_struct) { - if (rcx_kerncall_index < kKerncalls.Count()) + if (rcx_kerncall_index < kKernCalls.Count()) { Kernel::kout << "kerncall: Enter Kernel Call List.\r"; - if (kKerncalls[rcx_kerncall_index].fHooked) + if (kKernCalls[rcx_kerncall_index].fHooked) { - if (kKerncalls[rcx_kerncall_index].fProc) + if (kKernCalls[rcx_kerncall_index].fProc) { - (kKerncalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr)rdx_kerncall_struct); + (kKernCalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr)rdx_kerncall_struct); } else { diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index ce8c1245..60d05e11 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -98,8 +98,23 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept idt_loader.Load(idt_reg); + auto constexpr kSchedTeamSwitchMS = 200U; /// @brief Team switch time in milliseconds. + + Kernel::HardwareTimer timer(rtl_ms(kSchedTeamSwitchMS)); + + SizeT i = 0U; + while (YES) { - ; + timer.Wait(); + + UserProcessScheduler::The().SwitchTeam(kTeams[i]); + + ++i; + + if (i > kSchedTeamCount) + { + i = 0U; + } } } diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 881f3957..d8c1dff8 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -19,6 +19,7 @@ #define kSchedMinMicroTime (AffinityKind::kStandard) #define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (32U) +#define kSchedTeamCount (512) #define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ #define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ @@ -328,13 +329,15 @@ namespace Kernel explicit UserProcessScheduler() = default; ~UserProcessScheduler() override = default; - NE_COPY_DEFAULT(UserProcessScheduler) + NE_COPY_DELETE(UserProcessScheduler) + NE_MOVE_DELETE(UserProcessScheduler) operator bool(); bool operator!(); public: ProcessTeam& CurrentTeam(); + BOOL SwitchTeam(ProcessTeam& team); public: ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); @@ -371,6 +374,10 @@ namespace Kernel }; const UInt32& sched_get_exit_code(void) noexcept; + + inline Kernel::Array + kTeams; } // namespace Kernel #include diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index ccd808ad..b48512c8 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -253,7 +253,7 @@ namespace Kernel { if (KStringBuilder::Equals(dir_name, dir->fName)) { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; ++inode_index) + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { if (dir->fIndexNodeStart[inode_index] != 0 || dir->fIndexNodeEnd[inode_index] != 0) @@ -345,7 +345,7 @@ namespace Kernel if (KStringBuilder::Equals(dir->fName, parent_dir_name)) { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; ++inode_index) + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { if (dir->fIndexNodeStart[inode_index] != 0 || dir->fIndexNodeEnd[inode_index] != 0) diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 77831082..d8d34010 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -35,7 +35,7 @@ namespace Kernel /// @brief External reference of the thread scheduler. /***********************************************************************************/ - STATIC UserProcessScheduler kProcessScheduler; + STATIC UserProcessScheduler kScheduler; Process::Process() = default; Process::~Process() = default; @@ -406,7 +406,7 @@ namespace Kernel UserProcessScheduler& UserProcessScheduler::The() { - return kProcessScheduler; + return kScheduler; } /***********************************************************************************/ @@ -512,7 +512,22 @@ namespace Kernel return mTeam; } - /// @internal + /***********************************************************************************/ + /// @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(ProcessTeam& team) + { + if (team.AsArray().Count() < 1) + return No; + + kScheduler.mTeam = team; + + return Yes; + } /// @brief Gets current running process. /// @return @@ -525,11 +540,11 @@ namespace Kernel /// @return Process ID integer. ErrorOr UserProcessHelper::TheCurrentPID() { - if (!kProcessScheduler.CurrentProcess()) + if (!kScheduler.CurrentProcess()) return ErrorOr{-kErrorProcessFault}; kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return ErrorOr{kProcessScheduler.CurrentProcess().Leak().ProcessId}; + return ErrorOr{kScheduler.CurrentProcess().Leak().ProcessId}; } /// @brief Check if process can be schedulded. @@ -568,7 +583,7 @@ namespace Kernel SizeT UserProcessHelper::StartScheduling() { - return kProcessScheduler.Run(); + return kScheduler.Run(); } /***********************************************************************************/ -- cgit v1.2.3 From d67240d20d1d4bbe33134e640fd632cfd5fc6795 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 22 Apr 2025 22:11:14 +0200 Subject: dev, kernel: WiP changes done to kernel and SysChk module. - Getting SysChk to work again. - Refactor scheduler. Signed-off-by: Amlal El Mahrouss --- compile_flags.txt | 3 +- debug_ahci_x64.sh | 1 + debug_ata_x64.sh | 1 + dev/boot/modules/SysChk/SysChk.cc | 2 + dev/boot/src/HEL/AMD64/BootEFI.cc | 2 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 4 +- .../AMD64/HalSchedulerCorePrimitivesAMD64.cc | 2 +- .../ARM64/HalSchedulerCorePrimitivesARM64.cc | 2 +- dev/kernel/KernelKit/BinaryMutex.h | 8 +- dev/kernel/KernelKit/IPEFDylibObject.h | 4 +- dev/kernel/KernelKit/ProcessSchedulerCore.h | 137 ++++++++++++++++ dev/kernel/KernelKit/UserProcessScheduler.h | 180 ++++----------------- dev/kernel/KernelKit/UserProcessScheduler.inl | 9 +- dev/kernel/NetworkKit/IPC.h | 2 +- dev/kernel/src/BinaryMutex.cc | 6 +- dev/kernel/src/IPEFDylibObject.cc | 4 +- dev/kernel/src/Network/IPCAddr.cc | 8 +- dev/kernel/src/Network/IPCMsg.cc | 4 +- dev/kernel/src/ProcessTeam.cc | 14 +- dev/kernel/src/UserProcessScheduler.cc | 48 +++--- release_ahci_x64.sh | 1 + release_ata_x64.sh | 1 + setup_x64.sh | 1 - 23 files changed, 233 insertions(+), 211 deletions(-) create mode 100644 dev/kernel/KernelKit/ProcessSchedulerCore.h (limited to 'dev/kernel/src') diff --git a/compile_flags.txt b/compile_flags.txt index 604ab767..c72b1987 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -25,4 +25,5 @@ -D__FSKIT_INCLUDES_NEFS__ -D__FSKIT_INCLUDES_EXT2__ -D__NE_VEPM__ --DBOOTZ_VEPM_SUPPORT \ No newline at end of file +-DBOOTZ_VEPM_SUPPORT +-D__x86_64__ \ No newline at end of file diff --git a/debug_ahci_x64.sh b/debug_ahci_x64.sh index e3ff833d..66121bb7 100755 --- a/debug_ahci_x64.sh +++ b/debug_ahci_x64.sh @@ -9,6 +9,7 @@ cd dev/kernel make -f amd64-desktop.make all cd ../boot make -f amd64-desktop.make all +make -f amd64-desktop.make disk cd ../../ ./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot diff --git a/debug_ata_x64.sh b/debug_ata_x64.sh index cc46b238..6f40887b 100755 --- a/debug_ata_x64.sh +++ b/debug_ata_x64.sh @@ -9,6 +9,7 @@ cd dev/kernel make -f amd64-desktop.make all cd ../boot make -f amd64-desktop.make all +make -f amd64-desktop.make disk cd ../../ ./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot diff --git a/dev/boot/modules/SysChk/SysChk.cc b/dev/boot/modules/SysChk/SysChk.cc index 1b1de6f4..9bdeb38d 100644 --- a/dev/boot/modules/SysChk/SysChk.cc +++ b/dev/boot/modules/SysChk/SysChk.cc @@ -31,6 +31,8 @@ EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) NE_UNUSED(handover); #if defined(__ATA_PIO__) + fw_init_efi((EfiSystemTable*)handover->f_FirmwareCustomTables[1]); + Boot::BootTextWriter writer; Boot::BDiskFormatFactory partition_factory; diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 85b7f729..ae6d4deb 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -164,7 +164,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, Int32 trials = 5 * 10000000; - writer.Write("BootZ: Allocating sufficent memory, trying with 4GB...\r"); + writer.Write("BootZ: Allocating sufficent memory, trying 4GB...\r"); while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) { diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 5c50b3e3..c2be925a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -21,13 +21,13 @@ EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; EXTERN_C Kernel::VoidPtr mp_user_switch_proc; EXTERN_C Kernel::Char mp_user_switch_proc_stack_begin[]; -STATIC Kernel::Array kTeams; +STATIC Kernel::Array kTeams; STATIC Kernel::Void hal_pre_init_scheduler() { for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) { - Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::Process(); + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::UserProcess(); Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i].Status = Kernel::ProcessStatusKind::kKilled; } } diff --git a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc index edad0e97..c2739f27 100644 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc @@ -14,7 +14,7 @@ namespace Kernel /// @param /***********************************************************************************/ - EXTERN_C Void __zka_pure_call(Process* process) + EXTERN_C Void __zka_pure_call(UserProcess* process) { if (process) process->Crash(); diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc index 594ee76e..2f5c92e5 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc @@ -14,7 +14,7 @@ namespace Kernel /// @param void /***********************************************************************************/ - EXTERN_C Void __zka_pure_call(Process* process) + EXTERN_C Void __zka_pure_call(UserProcess* process) { if (process) process->Crash(); diff --git a/dev/kernel/KernelKit/BinaryMutex.h b/dev/kernel/KernelKit/BinaryMutex.h index 675396fd..ec1e355d 100644 --- a/dev/kernel/KernelKit/BinaryMutex.h +++ b/dev/kernel/KernelKit/BinaryMutex.h @@ -12,9 +12,9 @@ namespace Kernel { - class Process; + class UserProcess; - typedef Process& UserProcessRef; + typedef UserProcess& UserProcessRef; /// @brief Access control class, which locks a task until one is done. class BinaryMutex final @@ -31,8 +31,8 @@ namespace Kernel BOOL WaitForProcess(const Int16& sec) noexcept; public: - bool Lock(Process& process); - bool LockOrWait(Process& process, TimerInterface* timer); + bool Lock(UserProcess& process); + bool LockOrWait(UserProcess& process, TimerInterface* timer); public: NE_COPY_DEFAULT(BinaryMutex) diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h index f1edc1d5..4769f0f9 100644 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ b/dev/kernel/KernelKit/IPEFDylibObject.h @@ -99,8 +99,8 @@ namespace Kernel typedef IPEFDylibObject* IDylibRef; - EXTERN_C IDylibRef rtl_init_dylib(Process& header); - EXTERN_C Void rtl_fini_dylib(Process& header, IDylibRef lib, Bool* successful); + EXTERN_C IDylibRef rtl_init_dylib(UserProcess& header); + EXTERN_C Void rtl_fini_dylib(UserProcess& header, IDylibRef lib, Bool* successful); } // namespace Kernel #endif /* ifndef __KERNELKIT_SHARED_OBJECT_H__ */ diff --git a/dev/kernel/KernelKit/ProcessSchedulerCore.h b/dev/kernel/KernelKit/ProcessSchedulerCore.h new file mode 100644 index 00000000..002e685e --- /dev/null +++ b/dev/kernel/KernelKit/ProcessSchedulerCore.h @@ -0,0 +1,137 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + class UserProcess; + class KernelProcess; + class UserProcessTeam; + + /***********************************************************************************/ + /// @brief Subsystem enum type. + /***********************************************************************************/ + + enum class ProcessSubsystem : Int32 + { + kProcessSubsystemSecurity = 100, + kProcessSubsystemApplication, + kProcessSubsystemService, + kProcessSubsystemDriver, + kProcessSubsystemInvalid = 256U, + kProcessSubsystemCount = 4, + }; + + typedef UInt64 PTime; + + /***********************************************************************************/ + //! @brief Local Process identifier. + /***********************************************************************************/ + typedef Int64 ProcessID; + + /***********************************************************************************/ + //! @brief Local Process status enum. + /***********************************************************************************/ + enum class ProcessStatusKind : Int32 + { + kInvalid, + kStarting, + kRunning, + kKilled, + kFrozen, + kFinished, + kCount, + }; + + /***********************************************************************************/ + //! @brief Affinity is the amount of nano-seconds this process is going to run. + /***********************************************************************************/ + enum class AffinityKind : Int32 + { + kRealTime = 500, + kVeryHigh = 250, + kHigh = 200, + kStandard = 1000, + kLowUsage = 1500, + kVeryLowUsage = 2000, + }; + + /***********************************************************************************/ + //! Operators for AffinityKind + /***********************************************************************************/ + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int >= rhs_int; + } + + using ProcessTime = UInt64; + using PID = Int64; + + /***********************************************************************************/ + /// @note For User manager, tells where we run the code. + /***********************************************************************************/ + enum class ProcessLevelRing : Int32 + { + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 5, + }; + + /***********************************************************************************/ + /// @brief Helper type to describe a code image. + /***********************************************************************************/ + using ImagePtr = VoidPtr; + + struct ProcessImage final + { + explicit ProcessImage() = default; + + ImagePtr fCode; + ImagePtr fBlob; + + Bool HasCode() + { + return this->fCode != nullptr; + } + + Bool HasImage() + { + return this->fBlob != nullptr; + } + }; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 25ff20e5..4ba4b779 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -8,18 +8,19 @@ #define INC_PROCESS_SCHEDULER_H /// @file UserProcessScheduler.h -/// @brief User Process scheduler code and definitions. +/// @brief User UserProcess scheduler code and definitions. /// @author Amlal El Mahrouss (amlal@nekernel.org) #include #include #include #include +#include #define kSchedMinMicroTime (AffinityKind::kStandard) #define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (32U) -#define kSchedTeamCount (512) +#define kSchedTeamCount (512U) #define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ #define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ @@ -35,147 +36,24 @@ namespace Kernel //! @brief Forward declarations. class IDylibObject; - class Process; - class ProcessTeam; class UserProcessScheduler; class UserProcessHelper; - typedef UInt64 PTime; - - /***********************************************************************************/ - //! @brief Local Process identifier. - /***********************************************************************************/ - typedef Int64 ProcessID; - - /***********************************************************************************/ - //! @brief Local Process status enum. - /***********************************************************************************/ - enum class ProcessStatusKind : Int32 - { - kInvalid, - kStarting, - kRunning, - kKilled, - kFrozen, - kFinished, - kCount, - }; - - /***********************************************************************************/ - //! @brief Affinity is the amount of nano-seconds this process is going to run. - /***********************************************************************************/ - enum class AffinityKind : Int32 - { - kRealTime = 500, - kVeryHigh = 250, - kHigh = 200, - kStandard = 1000, - kLowUsage = 1500, - kVeryLowUsage = 2000, - }; - - /***********************************************************************************/ - //! Operators for AffinityKind - /***********************************************************************************/ - - inline bool operator<(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int < rhs_int; - } - - inline bool operator>(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int > rhs_int; - } - - inline bool operator<=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int <= rhs_int; - } - - inline bool operator>=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int >= rhs_int; - } - - /***********************************************************************************/ - /// @brief Subsystem enum type. - /***********************************************************************************/ - - enum class ProcessSubsystem : Int32 - { - kProcessSubsystemSecurity = 100, - kProcessSubsystemApplication, - kProcessSubsystemService, - kProcessSubsystemDriver, - kProcessSubsystemInvalid = 256U, - kProcessSubsystemCount = 4, - }; - - using ProcessTime = UInt64; - using PID = Int64; - - /***********************************************************************************/ - /// @note For User manager, tells where we run the code. - /***********************************************************************************/ - enum class ProcessLevelRing : Int32 - { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 5, - }; - - /***********************************************************************************/ - /// @brief Helper type to describe a code image. - /***********************************************************************************/ - using ImagePtr = VoidPtr; - - struct ProcessImage final - { - explicit ProcessImage() = default; - - ImagePtr fCode; - ImagePtr fBlob; - - Bool HasCode() - { - return this->fCode != nullptr; - } - - Bool HasImage() - { - return this->fBlob != nullptr; - } - }; - /***********************************************************************************/ - /// @name Process - /// @brief Process class, holds information about the running process/thread. + /// @name UserProcess + /// @brief UserProcess class, holds information about the running process/thread. /***********************************************************************************/ - class Process final + class UserProcess final { public: - explicit Process(); - ~Process(); + explicit UserProcess(); + ~UserProcess(); public: - NE_COPY_DEFAULT(Process) + NE_COPY_DEFAULT(UserProcess) public: - Char Name[kSchedNameLen] = {"Process"}; + Char Name[kSchedNameLen] = {"UserProcess"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; User* Owner{nullptr}; HAL::StackFramePtr StackFrame{nullptr}; @@ -208,7 +86,7 @@ namespace Kernel ProcessSignal ProcessSignal; ProcessMemoryHeapList* ProcessMemoryHeap{nullptr}; - ProcessTeam* ProcessParentTeam; + UserProcessTeam* ProcessParentTeam; VoidPtr VMRegister{0UL}; @@ -220,7 +98,7 @@ namespace Kernel kExecutableKindCount, }; - ProcessTime PTime{0}; //! @brief Process allocated tine. + ProcessTime PTime{0}; //! @brief UserProcess allocated tine. PID ProcessId{kSchedInvalidPID}; Int32 Kind{kExecutableKind}; @@ -294,31 +172,31 @@ namespace Kernel /// \brief Processs Team (contains multiple processes inside it.) /// Equivalent to a process batch - class ProcessTeam final + class UserProcessTeam final { public: - explicit ProcessTeam(); - ~ProcessTeam() = default; + explicit UserProcessTeam(); + ~UserProcessTeam() = default; - NE_COPY_DEFAULT(ProcessTeam) + NE_COPY_DEFAULT(UserProcessTeam) - Array& AsArray(); - Ref& AsRef(); + Array& AsArray(); + Ref& AsRef(); ProcessID& Id() noexcept; public: - Array mProcessList; - Ref mCurrentProcess; + Array mProcessList; + Ref mCurrentProcess; ProcessID mTeamId{0}; ProcessID mProcessCount{0}; }; - typedef Array UserThreadArray; + typedef Array UserThreadArray; - using UserProcessRef = Process&; + using UserProcessRef = UserProcess&; /***********************************************************************************/ - /// @brief Process scheduler class. + /// @brief UserProcess scheduler class. /// The main class which you call to schedule user processes. /***********************************************************************************/ class UserProcessScheduler final : public ISchedulable @@ -336,8 +214,8 @@ namespace Kernel bool operator!(); public: - ProcessTeam& CurrentTeam(); - BOOL SwitchTeam(ProcessTeam& team); + UserProcessTeam& CurrentTeam(); + BOOL SwitchTeam(UserProcessTeam& team); public: ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); @@ -348,19 +226,19 @@ namespace Kernel Bool HasMP() override; public: - Ref& CurrentProcess(); + Ref& CurrentProcess(); SizeT Run() noexcept; public: STATIC UserProcessScheduler& The(); private: - ProcessTeam mTeam{}; + UserProcessTeam mTeam{}; }; /***********************************************************************************/ /** - * \brief Process helper class, which contains needed utilities for the scheduler. + * \brief UserProcess helper class, which contains needed utilities for the scheduler. */ /***********************************************************************************/ @@ -368,7 +246,7 @@ namespace Kernel { public: STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, PID new_pid); - STATIC Bool CanBeScheduled(const Process& process); + STATIC Bool CanBeScheduled(const UserProcess& process); STATIC ErrorOr TheCurrentPID(); STATIC SizeT StartScheduling(); }; diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index ea57cf65..4179545c 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -3,12 +3,13 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.inl - PURPOSE: Low level/Ring-3 Process scheduler. + PURPOSE: Low level/Ring-3 UserProcess scheduler. ------------------------------------------- */ -/// @brief Process scheduler inline definitions. +/// @brief UserProcess scheduler inline definitions. /// @author Amlal El Mahrouss (amlal@nekernel.org) +/// @date Tue Apr 22 22:01:07 CEST 2025 namespace Kernel { @@ -17,14 +18,14 @@ namespace Kernel /***********************************************************************************/ template - Boolean Process::Delete(ErrorOr ptr) + Boolean UserProcess::Delete(ErrorOr ptr) { if (!ptr) return No; if (!this->ProcessMemoryHeap) { - kout << "Process's heap is empty.\r"; + kout << "UserProcess's heap is empty.\r"; return No; } diff --git a/dev/kernel/NetworkKit/IPC.h b/dev/kernel/NetworkKit/IPC.h index 6304740c..6de306b2 100644 --- a/dev/kernel/NetworkKit/IPC.h +++ b/dev/kernel/NetworkKit/IPC.h @@ -34,7 +34,7 @@ namespace Kernel struct PACKED IPC_ADDR final { UInt64 UserProcessID; - UInt64 ProcessTeam; + UInt64 UserProcessTeam; //////////////////////////////////// // some operators. diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index 1ed08fa9..ea6d5408 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -16,7 +16,7 @@ namespace Kernel { if (fLockingProcess) { - fLockingProcess = Process(); + fLockingProcess = UserProcess(); fLockingProcess.Status = ProcessStatusKind::kFrozen; return Yes; } @@ -27,7 +27,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Locks process in the semaphore. /***********************************************************************************/ - Bool BinaryMutex::Lock(Process& process) + Bool BinaryMutex::Lock(UserProcess& process) { if (!process || fLockingProcess) return No; @@ -48,7 +48,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Try lock or wait. /***********************************************************************************/ - Bool BinaryMutex::LockOrWait(Process& process, TimerInterface* timer) + Bool BinaryMutex::LockOrWait(UserProcess& process, TimerInterface* timer) { if (timer == nullptr) return No; diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index 3dd956c9..a42d267a 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -41,7 +41,7 @@ using namespace Kernel; /** @brief Library initializer. */ /***********************************************************************************/ -EXTERN_C IDylibRef rtl_init_dylib(Process& process) +EXTERN_C IDylibRef rtl_init_dylib(UserProcess& process) { IDylibRef dll_obj = tls_new_class(); @@ -91,7 +91,7 @@ EXTERN_C IDylibRef rtl_init_dylib(Process& process) /** @param successful Reports if successful or not. */ /***********************************************************************************/ -EXTERN_C Void rtl_fini_dylib(Process& process, IDylibRef dll_obj, BOOL* successful) +EXTERN_C Void rtl_fini_dylib(UserProcess& process, IDylibRef dll_obj, BOOL* successful) { MUST_PASS(successful); diff --git a/dev/kernel/src/Network/IPCAddr.cc b/dev/kernel/src/Network/IPCAddr.cc index a56aec14..80a14264 100644 --- a/dev/kernel/src/Network/IPCAddr.cc +++ b/dev/kernel/src/Network/IPCAddr.cc @@ -12,21 +12,21 @@ namespace Kernel { bool IPC_ADDR::operator==(const IPC_ADDR& addr) noexcept { - return addr.UserProcessID == this->UserProcessID && addr.ProcessTeam == this->ProcessTeam; + return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; } bool IPC_ADDR::operator==(IPC_ADDR& addr) noexcept { - return addr.UserProcessID == this->UserProcessID && addr.ProcessTeam == this->ProcessTeam; + return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; } bool IPC_ADDR::operator!=(const IPC_ADDR& addr) noexcept { - return addr.UserProcessID != this->UserProcessID || addr.ProcessTeam != this->ProcessTeam; + return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam; } bool IPC_ADDR::operator!=(IPC_ADDR& addr) noexcept { - return addr.UserProcessID != this->UserProcessID || addr.ProcessTeam != this->ProcessTeam; + return addr.UserProcessID != this->UserProcessID || addr.UserProcessTeam != this->UserProcessTeam; } } // namespace Kernel diff --git a/dev/kernel/src/Network/IPCMsg.cc b/dev/kernel/src/Network/IPCMsg.cc index ceb0ae98..457776b3 100644 --- a/dev/kernel/src/Network/IPCMsg.cc +++ b/dev/kernel/src/Network/IPCMsg.cc @@ -91,10 +91,10 @@ namespace Kernel (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG); (*pckt_in)->IpcTo.UserProcessID = 0; - (*pckt_in)->IpcTo.ProcessTeam = 0; + (*pckt_in)->IpcTo.UserProcessTeam = 0; (*pckt_in)->IpcFrom.UserProcessID = 0; - (*pckt_in)->IpcFrom.ProcessTeam = 0; + (*pckt_in)->IpcFrom.UserProcessTeam = 0; return Yes; } diff --git a/dev/kernel/src/ProcessTeam.cc b/dev/kernel/src/ProcessTeam.cc index 87d21d67..5ac3efeb 100644 --- a/dev/kernel/src/ProcessTeam.cc +++ b/dev/kernel/src/ProcessTeam.cc @@ -5,19 +5,19 @@ ------------------------------------------- */ /***********************************************************************************/ -/// @file ProcessTeam.cc +/// @file UserProcessTeam.cc /// @brief Process teams implementation. /***********************************************************************************/ -#include +#include namespace Kernel { - ProcessTeam::ProcessTeam() + UserProcessTeam::UserProcessTeam() { for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) { - this->mProcessList[i] = Process(); + this->mProcessList[i] = UserProcess(); this->mProcessList[i].PTime = 0; this->mProcessList[i].Status = ProcessStatusKind::kKilled; } @@ -30,7 +30,7 @@ namespace Kernel /// @return The list of process to schedule. /***********************************************************************************/ - Array& ProcessTeam::AsArray() + Array& UserProcessTeam::AsArray() { return this->mProcessList; } @@ -40,7 +40,7 @@ namespace Kernel /// @return The team's ID. /***********************************************************************************/ - ProcessID& ProcessTeam::Id() noexcept + ProcessID& UserProcessTeam::Id() noexcept { return this->mTeamId; } @@ -50,7 +50,7 @@ namespace Kernel /// @return The current process header. /***********************************************************************************/ - Ref& ProcessTeam::AsRef() + Ref& UserProcessTeam::AsRef() { return this->mCurrentProcess; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index d8d34010..5295c15a 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -3,7 +3,7 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.cc - PURPOSE: Low level/Ring-3 Process scheduler. + PURPOSE: Low level/Ring-3 UserProcess scheduler. ------------------------------------------- */ @@ -37,8 +37,8 @@ namespace Kernel STATIC UserProcessScheduler kScheduler; - Process::Process() = default; - Process::~Process() = default; + UserProcess::UserProcess() = default; + UserProcess::~UserProcess() = default; /// @brief Gets the last exit code. /// @note Not thread-safe. @@ -53,7 +53,7 @@ namespace Kernel /// @brief Crashes the current process. /***********************************************************************************/ - Void Process::Crash() + Void UserProcess::Crash() { if (this->Status != ProcessStatusKind::kRunning) return; @@ -66,7 +66,7 @@ namespace Kernel /// @brief boolean operator, check status. /***********************************************************************************/ - Process::operator bool() + UserProcess::operator bool() { return this->Status == ProcessStatusKind::kRunning; } @@ -77,7 +77,7 @@ namespace Kernel /// @return Int32 the last exit code. /***********************************************************************************/ - const UInt32& Process::GetExitCode() noexcept + const UInt32& UserProcess::GetExitCode() noexcept { return this->fLastExitCode; } @@ -86,7 +86,7 @@ namespace Kernel /// @brief Error code variable getter. /***********************************************************************************/ - Int32& Process::GetLocalCode() noexcept + Int32& UserProcess::GetLocalCode() noexcept { return this->fLocalCode; } @@ -96,7 +96,7 @@ namespace Kernel /// @param should_wakeup if the program shall wakeup or not. /***********************************************************************************/ - Void Process::Wake(Bool should_wakeup) + Void UserProcess::Wake(Bool should_wakeup) { this->Status = should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; @@ -106,7 +106,7 @@ namespace Kernel /** @brief Allocate pointer to track list. */ /***********************************************************************************/ - ErrorOr Process::New(SizeT sz, SizeT pad_amount) + ErrorOr UserProcess::New(SizeT sz, SizeT pad_amount) { #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ auto vm_register = hal_read_cr3(); @@ -159,7 +159,7 @@ namespace Kernel /// @brief Gets the name of the current process. /***********************************************************************************/ - const Char* Process::GetName() noexcept + const Char* UserProcess::GetName() noexcept { return this->Name; } @@ -168,13 +168,13 @@ namespace Kernel /// @brief Gets the owner of the process. /***********************************************************************************/ - const User* Process::GetOwner() noexcept + const User* UserProcess::GetOwner() noexcept { return this->Owner; } - /// @brief Process status getter. - const ProcessStatusKind& Process::GetStatus() noexcept + /// @brief UserProcess status getter. + const ProcessStatusKind& UserProcess::GetStatus() noexcept { return this->Status; } @@ -185,7 +185,7 @@ namespace Kernel */ /***********************************************************************************/ - const AffinityKind& Process::GetAffinity() noexcept + const AffinityKind& UserProcess::GetAffinity() noexcept { return this->Affinity; } @@ -197,7 +197,7 @@ namespace Kernel */ /***********************************************************************************/ - Void Process::Exit(const Int32& exit_code) + Void UserProcess::Exit(const Int32& exit_code) { this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; this->fLastExitCode = exit_code; @@ -305,7 +305,7 @@ namespace Kernel ++this->mTeam.mProcessCount; - Process& process = this->mTeam.mProcessList[pid]; + UserProcess& process = this->mTeam.mProcessList[pid]; process.Image.fCode = code; process.Image.fBlob = image; @@ -356,12 +356,12 @@ namespace Kernel // React according to process kind. switch (process.Kind) { - case Process::kExecutableDylibKind: { + case UserProcess::kExecutableDylibKind: { process.DylibDelegate = rtl_init_dylib(process); MUST_PASS(process.DylibDelegate); break; } - case Process::kExecutableKind: { + case UserProcess::kExecutableKind: { break; } default: { @@ -457,7 +457,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Run User scheduler object. - /// @return Process count executed within a team. + /// @return UserProcess count executed within a team. /***********************************************************************************/ SizeT UserProcessScheduler::Run() noexcept @@ -507,7 +507,7 @@ namespace Kernel /// @brief Gets the current scheduled team. /// @return - ProcessTeam& UserProcessScheduler::CurrentTeam() + UserProcessTeam& UserProcessScheduler::CurrentTeam() { return mTeam; } @@ -519,7 +519,7 @@ namespace Kernel /// @retval false team was not switched. /***********************************************************************************/ - BOOL UserProcessScheduler::SwitchTeam(ProcessTeam& team) + BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) { if (team.AsArray().Count() < 1) return No; @@ -531,13 +531,13 @@ namespace Kernel /// @brief Gets current running process. /// @return - Ref& UserProcessScheduler::CurrentProcess() + Ref& UserProcessScheduler::CurrentProcess() { return mTeam.AsRef(); } /// @brief Current proccess id getter. - /// @return Process ID integer. + /// @return UserProcess ID integer. ErrorOr UserProcessHelper::TheCurrentPID() { if (!kScheduler.CurrentProcess()) @@ -551,7 +551,7 @@ namespace Kernel /// @param process the process reference. /// @retval true can be schedulded. /// @retval false cannot be schedulded. - Bool UserProcessHelper::CanBeScheduled(const Process& process) + Bool UserProcessHelper::CanBeScheduled(const UserProcess& process) { if (process.Status == ProcessStatusKind::kKilled || process.Status == ProcessStatusKind::kFinished || diff --git a/release_ahci_x64.sh b/release_ahci_x64.sh index d6289d58..d585e74e 100755 --- a/release_ahci_x64.sh +++ b/release_ahci_x64.sh @@ -6,6 +6,7 @@ cd dev/kernel make -f amd64-desktop.make all cd ../boot make -f amd64-desktop.make all +make -f amd64-desktop.make disk cd ../../ ./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot diff --git a/release_ata_x64.sh b/release_ata_x64.sh index 3fa5d655..c0a0e01e 100755 --- a/release_ata_x64.sh +++ b/release_ata_x64.sh @@ -6,6 +6,7 @@ cd dev/kernel make -f amd64-desktop.make all cd ../boot make -f amd64-desktop.make all +make -f amd64-desktop.make disk cd ../../ ./tooling/mk_img.py ./dev/boot/src/nekernel-esp.img ./dev/boot/src/root cd dev/boot diff --git a/setup_x64.sh b/setup_x64.sh index 35111b88..da2027a1 100755 --- a/setup_x64.sh +++ b/setup_x64.sh @@ -8,7 +8,6 @@ cd dev/user btb user.json cd ../boot make -f amd64-desktop.make efi -make -f amd64-desktop.make disk make -f amd64-desktop.make epm-img cd ../../dev/kernel/HALKit/AMD64 ./make_ap_blob.sh -- cgit v1.2.3 From 8c500f29bd0ef17f5b59e5be49f4cae88d827d85 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 23 Apr 2025 09:11:33 +0200 Subject: dev, kernel: scheduler and disk swap refactors. Details: - Reworked SCSI groundwork to prepare for a Generic SCSI driver. - Refatored scheduler's code with the new coding style for structs. - Add Leak and LeakBlob inside PROCESS_IMAGE struct. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FirmwareKit/EPM.h | 11 ++-- dev/kernel/FirmwareKit/GPT.h | 36 ++++++------ dev/kernel/FirmwareKit/VEPM.h | 18 +++--- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 36 ++++++------ dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 +- .../AMD64/HalSchedulerCorePrimitivesAMD64.cc | 2 +- dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc | 13 +++++ .../ARM64/HalSchedulerCorePrimitivesARM64.cc | 2 +- dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc | 13 +++++ dev/kernel/KernelKit/BinaryMutex.h | 10 ++-- dev/kernel/KernelKit/FileMgr.h | 8 +-- dev/kernel/KernelKit/IPEFDylibObject.h | 4 +- dev/kernel/KernelKit/ProcessSchedulerCore.h | 29 +++++++-- dev/kernel/KernelKit/UserProcessScheduler.h | 68 +++++++++++----------- dev/kernel/KernelKit/UserProcessScheduler.inl | 10 ++-- dev/kernel/StorageKit/SCSI.h | 4 +- dev/kernel/SwapKit/DiskSwap.h | 16 +++-- dev/kernel/src/BinaryMutex.cc | 6 +- dev/kernel/src/IPEFDylibObject.cc | 4 +- dev/kernel/src/Network/IPCMsg.cc | 8 +-- dev/kernel/src/ProcessTeam.cc | 6 +- dev/kernel/src/Storage/SCSIDeviceInterface.cc | 4 +- dev/kernel/src/Swap/DiskSwap.cc | 10 ++-- dev/kernel/src/User.cc | 6 +- dev/kernel/src/UserProcessScheduler.cc | 50 ++++++++-------- dev/modules/SCSI/SCSI.h | 12 +++- 26 files changed, 219 insertions(+), 169 deletions(-) create mode 100644 dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc create mode 100644 dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc (limited to 'dev/kernel/src') diff --git a/dev/kernel/FirmwareKit/EPM.h b/dev/kernel/FirmwareKit/EPM.h index 6db82506..fe228127 100644 --- a/dev/kernel/FirmwareKit/EPM.h +++ b/dev/kernel/FirmwareKit/EPM.h @@ -81,7 +81,7 @@ typedef struct EPM_GUID struct PACKED EPM_PART_BLOCK { Kernel::Char Magic[kEPMMagicLength] = {0}; - Kernel::Char Name[kEPMNameLength] = {0}; + Kernel::Char Name[kEPMNameLength] = {0}; EPM_GUID Guid; Kernel::Int32 Version; Kernel::Int64 NumBlocks; @@ -109,10 +109,9 @@ enum }; inline EPM_GUID kEPMNilGuid = { - 0x0U, - 0x0U, - 0x0U, - { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } -}; + 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 index 4be1fed2..55356121 100644 --- a/dev/kernel/FirmwareKit/GPT.h +++ b/dev/kernel/FirmwareKit/GPT.h @@ -22,30 +22,30 @@ namespace Kernel 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; + Char Signature[kMagicLenGPT]; + UInt32 Revision; + UInt32 HeaderSize; + UInt32 CRC32; + UInt32 Reserved1; + UInt64 LBAHeader; + UInt64 LBAAltHeader; + UInt64 FirstGPTEntry; + UInt64 LastGPTEntry; EfiGUID Guid; - UInt64 StartingLBA; - UInt32 NumPartitionEntries; - UInt32 SizeOfEntries; - UInt32 CRC32PartEntry; - UInt8 Reserved2[kSectorAlignGPT_PartTbl]; + UInt64 StartingLBA; + UInt32 NumPartitionEntries; + UInt32 SizeOfEntries; + UInt32 CRC32PartEntry; + UInt8 Reserved2[kSectorAlignGPT_PartTbl]; }; struct PACKED GPT_PARTITION_ENTRY { EfiGUID PartitionTypeGUID; EfiGUID UniquePartitionGUID; - UInt64 StartLBA; - UInt64 EndLBA; - UInt64 Attributes; - UInt8 Name[kSectorAlignGPT_PartEntry]; + UInt64 StartLBA; + UInt64 EndLBA; + UInt64 Attributes; + UInt8 Name[kSectorAlignGPT_PartEntry]; }; } // namespace Kernel diff --git a/dev/kernel/FirmwareKit/VEPM.h b/dev/kernel/FirmwareKit/VEPM.h index 2b95e12d..5830a879 100644 --- a/dev/kernel/FirmwareKit/VEPM.h +++ b/dev/kernel/FirmwareKit/VEPM.h @@ -22,20 +22,18 @@ /// @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 } -}; + 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 EfiGUID kVEPMGuidEFI = { - 0x9a1b3f2e, - 0x4c3f, - 0x4d52, - { 0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac } -}; + 0x9a1b3f2e, + 0x4c3f, + 0x4d52, + {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}}; #define kVEPMGuidStr "9a1b3f2e-4c3f-4d52-a783-9c217b5e4dac" #endif // __NE_VEPM__ diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 46775a7f..7114f9f7 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -24,9 +24,9 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) Kernel::kout << "Kernel: General Protection Fault.\r"; - process.Leak().ProcessSignal.SignalArg = rsp; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.PreviousStatus = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; @@ -49,9 +49,9 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) Kernel::kout << "Kernel: Page Fault.\r"; Kernel::kout << "Kernel: SIGKILL\r"; - process.Leak().ProcessSignal.SignalArg = rsp; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.PreviousStatus = process.Leak().Status; process.Leak().Status = Kernel::ProcessStatusKind::kKilled; @@ -99,9 +99,9 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) Kernel::kout << "Kernel: Math error (division by zero?).\r"; - process.Leak().ProcessSignal.SignalArg = rsp; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.PreviousStatus = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; @@ -123,9 +123,9 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) Kernel::kout << "Kernel: Generic Process Fault.\r"; - process.Leak().ProcessSignal.SignalArg = rsp; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.PreviousStatus = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; @@ -151,10 +151,10 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) (void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); Kernel::kout << "Kernel: SIGTRAP\r"; - process.Leak().ProcessSignal.SignalArg = rip; - process.Leak().ProcessSignal.SignalID = SIGTRAP; + process.Leak().Signal.SignalArg = rip; + process.Leak().Signal.SignalID = SIGTRAP; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.PreviousStatus = process.Leak().Status; Kernel::kout << "Kernel: SIGTRAP status.\r"; @@ -174,9 +174,9 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) Kernel::kout << "Kernel: Undefined Opcode.\r"; - process.Leak().ProcessSignal.SignalArg = rsp; - process.Leak().ProcessSignal.SignalID = SIGKILL; - process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.PreviousStatus = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index c2be925a..20994d9b 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -27,7 +27,7 @@ STATIC Kernel::Void hal_pre_init_scheduler() { for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) { - Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::UserProcess(); + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i].Status = Kernel::ProcessStatusKind::kKilled; } } diff --git a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc index c2739f27..56ed4b34 100644 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc @@ -14,7 +14,7 @@ namespace Kernel /// @param /***********************************************************************************/ - EXTERN_C Void __zka_pure_call(UserProcess* process) + EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { if (process) process->Crash(); diff --git a/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc new file mode 100644 index 00000000..cb387e73 --- /dev/null +++ b/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc @@ -0,0 +1,13 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include + +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/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc index 2f5c92e5..84aae986 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc @@ -14,7 +14,7 @@ namespace Kernel /// @param void /***********************************************************************************/ - EXTERN_C Void __zka_pure_call(UserProcess* process) + EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { if (process) process->Crash(); diff --git a/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc b/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc new file mode 100644 index 00000000..cb387e73 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc @@ -0,0 +1,13 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include + +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/KernelKit/BinaryMutex.h b/dev/kernel/KernelKit/BinaryMutex.h index ec1e355d..660d2e71 100644 --- a/dev/kernel/KernelKit/BinaryMutex.h +++ b/dev/kernel/KernelKit/BinaryMutex.h @@ -12,9 +12,7 @@ namespace Kernel { - class UserProcess; - - typedef UserProcess& UserProcessRef; + class USER_PROCESS; /// @brief Access control class, which locks a task until one is done. class BinaryMutex final @@ -31,13 +29,13 @@ namespace Kernel BOOL WaitForProcess(const Int16& sec) noexcept; public: - bool Lock(UserProcess& process); - bool LockOrWait(UserProcess& process, TimerInterface* timer); + bool Lock(USER_PROCESS& process); + bool LockOrWait(USER_PROCESS& process, TimerInterface* timer); public: NE_COPY_DEFAULT(BinaryMutex) private: - UserProcessRef fLockingProcess; + USER_PROCESS fLockingProcess; }; } // namespace Kernel diff --git a/dev/kernel/KernelKit/FileMgr.h b/dev/kernel/KernelKit/FileMgr.h index e5f67080..f4acdae9 100644 --- a/dev/kernel/KernelKit/FileMgr.h +++ b/dev/kernel/KernelKit/FileMgr.h @@ -40,8 +40,8 @@ #define kRestrictR "r" #define kRestrictRB "rb" #define kRestrictW "w" -#define kRestrictWB "rw" -#define kRestrictRWB "rwb" +#define kRestrictWR "rw" +#define kRestrictWRB "rwb" #define kRestrictMax (5U) @@ -354,7 +354,7 @@ namespace Kernel .fMappedTo = kFileMgrRestrictReadBinary, }, { - .fRestrict = kRestrictRWB, + .fRestrict = kRestrictWRB, .fMappedTo = kFileMgrRestrictReadWriteBinary, }, { @@ -362,7 +362,7 @@ namespace Kernel .fMappedTo = kFileMgrRestrictWrite, }, { - .fRestrict = kRestrictWB, + .fRestrict = kRestrictWR, .fMappedTo = kFileMgrRestrictReadWrite, }}; diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h index 4769f0f9..82f08932 100644 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ b/dev/kernel/KernelKit/IPEFDylibObject.h @@ -99,8 +99,8 @@ namespace Kernel typedef IPEFDylibObject* IDylibRef; - EXTERN_C IDylibRef rtl_init_dylib(UserProcess& header); - EXTERN_C Void rtl_fini_dylib(UserProcess& header, IDylibRef lib, Bool* successful); + EXTERN_C IDylibRef rtl_init_dylib(USER_PROCESS& header); + EXTERN_C Void rtl_fini_dylib(USER_PROCESS& header, IDylibRef lib, Bool* successful); } // namespace Kernel #endif /* ifndef __KERNELKIT_SHARED_OBJECT_H__ */ diff --git a/dev/kernel/KernelKit/ProcessSchedulerCore.h b/dev/kernel/KernelKit/ProcessSchedulerCore.h index 002e685e..ee90ed8b 100644 --- a/dev/kernel/KernelKit/ProcessSchedulerCore.h +++ b/dev/kernel/KernelKit/ProcessSchedulerCore.h @@ -7,11 +7,12 @@ #pragma once #include +#include namespace Kernel { - class UserProcess; - class KernelProcess; + class USER_PROCESS; + class KERNEL_PROCESS; class UserProcessTeam; /***********************************************************************************/ @@ -117,9 +118,9 @@ namespace Kernel /***********************************************************************************/ using ImagePtr = VoidPtr; - struct ProcessImage final + struct PROCESS_IMAGE final { - explicit ProcessImage() = default; + explicit PROCESS_IMAGE() = default; ImagePtr fCode; ImagePtr fBlob; @@ -133,5 +134,25 @@ namespace Kernel { return this->fBlob != nullptr; } + + ErrorOr Leak() + { + if (this->fCode) + { + return ErrorOr{this->fCode}; + } + + return ErrorOr{nullptr}; + } + + ErrorOr LeakBlob() + { + if (this->fBlob) + { + return ErrorOr{this->fBlob}; + } + + return ErrorOr{nullptr}; + } }; } // namespace Kernel diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 4ba4b779..6e1ca146 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -8,7 +8,7 @@ #define INC_PROCESS_SCHEDULER_H /// @file UserProcessScheduler.h -/// @brief User UserProcess scheduler code and definitions. +/// @brief User USER_PROCESS scheduler code and definitions. /// @author Amlal El Mahrouss (amlal@nekernel.org) #include @@ -20,7 +20,7 @@ #define kSchedMinMicroTime (AffinityKind::kStandard) #define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (32U) -#define kSchedTeamCount (512U) +#define kSchedTeamCount (512U) #define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ #define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ @@ -40,53 +40,53 @@ namespace Kernel class UserProcessHelper; /***********************************************************************************/ - /// @name UserProcess - /// @brief UserProcess class, holds information about the running process/thread. + /// @name USER_PROCESS + /// @brief USER_PROCESS class, holds information about the running process/thread. /***********************************************************************************/ - class UserProcess final + class USER_PROCESS final { public: - explicit UserProcess(); - ~UserProcess(); + explicit USER_PROCESS(); + ~USER_PROCESS(); public: - NE_COPY_DEFAULT(UserProcess) + NE_COPY_DEFAULT(USER_PROCESS) public: - Char Name[kSchedNameLen] = {"UserProcess"}; + Char Name[kSchedNameLen] = {"USER_PROCESS"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; User* Owner{nullptr}; HAL::StackFramePtr StackFrame{nullptr}; AffinityKind Affinity{AffinityKind::kStandard}; ProcessStatusKind Status{ProcessStatusKind::kFinished}; UInt8* StackReserve{nullptr}; - ProcessImage Image{}; + PROCESS_IMAGE Image{}; SizeT StackSize{kSchedMaxStackSz}; IDylibObject* DylibDelegate{nullptr}; SizeT MemoryCursor{0UL}; SizeT MemoryLimit{kSchedMaxMemoryLimit}; SizeT UsedMemory{0UL}; - struct ProcessMemoryHeapList final + struct USER_HEAP_LIST final { VoidPtr MemoryEntry{nullptr}; SizeT MemoryEntrySize{0UL}; SizeT MemoryEntryPad{0UL}; - struct ProcessMemoryHeapList* MemoryPrev{nullptr}; - struct ProcessMemoryHeapList* MemoryNext{nullptr}; + struct USER_HEAP_LIST* MemoryPrev{nullptr}; + struct USER_HEAP_LIST* MemoryNext{nullptr}; }; - struct ProcessSignal final + struct USER_PROCESS_SIGNAL final { UIntPtr SignalArg; ProcessStatusKind PreviousStatus; UIntPtr SignalID; }; - ProcessSignal ProcessSignal; - ProcessMemoryHeapList* ProcessMemoryHeap{nullptr}; - UserProcessTeam* ProcessParentTeam; + USER_PROCESS_SIGNAL Signal; + USER_HEAP_LIST* ProcessMemoryHeap{nullptr}; + UserProcessTeam* ProcessParentTeam; VoidPtr VMRegister{0UL}; @@ -98,7 +98,7 @@ namespace Kernel kExecutableKindCount, }; - ProcessTime PTime{0}; //! @brief UserProcess allocated tine. + ProcessTime PTime{0}; //! @brief USER_PROCESS allocated tine. PID ProcessId{kSchedInvalidPID}; Int32 Kind{kExecutableKind}; @@ -170,6 +170,8 @@ namespace Kernel friend UserProcessHelper; }; + typedef Array USER_PROCESS_ARRAY; + /// \brief Processs Team (contains multiple processes inside it.) /// Equivalent to a process batch class UserProcessTeam final @@ -180,23 +182,19 @@ namespace Kernel NE_COPY_DEFAULT(UserProcessTeam) - Array& AsArray(); - Ref& AsRef(); - ProcessID& Id() noexcept; + Array& AsArray(); + Ref& AsRef(); + ProcessID& Id() noexcept; public: - Array mProcessList; - Ref mCurrentProcess; - ProcessID mTeamId{0}; - ProcessID mProcessCount{0}; + USER_PROCESS_ARRAY mProcessList; + Ref mCurrentProcess; + ProcessID mTeamId{0}; + ProcessID mProcessCount{0}; }; - typedef Array UserThreadArray; - - using UserProcessRef = UserProcess&; - /***********************************************************************************/ - /// @brief UserProcess scheduler class. + /// @brief USER_PROCESS scheduler class. /// The main class which you call to schedule user processes. /***********************************************************************************/ class UserProcessScheduler final : public ISchedulable @@ -215,7 +213,7 @@ namespace Kernel public: UserProcessTeam& CurrentTeam(); - BOOL SwitchTeam(UserProcessTeam& team); + BOOL SwitchTeam(UserProcessTeam& team); public: ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image); @@ -226,8 +224,8 @@ namespace Kernel Bool HasMP() override; public: - Ref& CurrentProcess(); - SizeT Run() noexcept; + Ref& CurrentProcess(); + SizeT Run() noexcept; public: STATIC UserProcessScheduler& The(); @@ -238,7 +236,7 @@ namespace Kernel /***********************************************************************************/ /** - * \brief UserProcess helper class, which contains needed utilities for the scheduler. + * \brief USER_PROCESS helper class, which contains needed utilities for the scheduler. */ /***********************************************************************************/ @@ -246,7 +244,7 @@ namespace Kernel { public: STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, PID new_pid); - STATIC Bool CanBeScheduled(const UserProcess& process); + STATIC Bool CanBeScheduled(const USER_PROCESS& process); STATIC ErrorOr TheCurrentPID(); STATIC SizeT StartScheduling(); }; diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index 4179545c..a18af9c1 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -3,11 +3,11 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.inl - PURPOSE: Low level/Ring-3 UserProcess scheduler. + PURPOSE: Low level/Ring-3 USER_PROCESS scheduler. ------------------------------------------- */ -/// @brief UserProcess scheduler inline definitions. +/// @brief USER_PROCESS scheduler inline definitions. /// @author Amlal El Mahrouss (amlal@nekernel.org) /// @date Tue Apr 22 22:01:07 CEST 2025 @@ -18,18 +18,18 @@ namespace Kernel /***********************************************************************************/ template - Boolean UserProcess::Delete(ErrorOr ptr) + Boolean USER_PROCESS::Delete(ErrorOr ptr) { if (!ptr) return No; if (!this->ProcessMemoryHeap) { - kout << "UserProcess's heap is empty.\r"; + kout << "USER_PROCESS's heap is empty.\r"; return No; } - ProcessMemoryHeapList* entry = this->ProcessMemoryHeap; + USER_HEAP_LIST* entry = this->ProcessMemoryHeap; while (entry != nullptr) { diff --git a/dev/kernel/StorageKit/SCSI.h b/dev/kernel/StorageKit/SCSI.h index 655638f5..2a4c2393 100644 --- a/dev/kernel/StorageKit/SCSI.h +++ b/dev/kernel/StorageKit/SCSI.h @@ -8,4 +8,6 @@ #include -extern const scsi_packet_type<12> kCDRomPacketTemplate; +namespace Kernel +{ +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/SwapKit/DiskSwap.h b/dev/kernel/SwapKit/DiskSwap.h index 0e32eff5..78b1a896 100644 --- a/dev/kernel/SwapKit/DiskSwap.h +++ b/dev/kernel/SwapKit/DiskSwap.h @@ -9,9 +9,10 @@ #include #include +#include #define kSwapBlockMaxSize (mib_cast(16)) -#define kSwapPageFile "/boot/pagefile.sys" +#define kSwapPageFilePath "/boot/pagefile.sys" /// @file SwapDisk.h /// @brief Virtual memory swap disk. @@ -19,15 +20,18 @@ namespace Kernel { struct SWAP_DISK_HEADER; + class DiskSwapInterface; /// @brief Virtual memory interface to swap memory chunks onto disk. - class SwapDiskInterface final + /// @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 SwapDiskInterface() = default; - ~SwapDiskInterface() = default; + explicit DiskSwapInterface() = default; + ~DiskSwapInterface() = default; - NE_COPY_DEFAULT(SwapDiskInterface) + NE_COPY_DELETE(DiskSwapInterface) + NE_MOVE_DELETE(DiskSwapInterface) public: /***********************************************************************************/ @@ -46,7 +50,7 @@ namespace Kernel /// @param data the data packet length. /// @return Whether the swap was fetched to disk, or not. /***********************************************************************************/ - SWAP_DISK_HEADER* Read(const Char* fork_name, SizeT fork_name_len, SizeT data_len); + _Output SWAP_DISK_HEADER* Read(const Char* fork_name, SizeT fork_name_len, SizeT data_len); }; /// @brief Swap disk header, containing information about the held virtual memory. diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index ea6d5408..f86be37b 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -16,7 +16,7 @@ namespace Kernel { if (fLockingProcess) { - fLockingProcess = UserProcess(); + fLockingProcess = USER_PROCESS(); fLockingProcess.Status = ProcessStatusKind::kFrozen; return Yes; } @@ -27,7 +27,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Locks process in the semaphore. /***********************************************************************************/ - Bool BinaryMutex::Lock(UserProcess& process) + Bool BinaryMutex::Lock(USER_PROCESS& process) { if (!process || fLockingProcess) return No; @@ -48,7 +48,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Try lock or wait. /***********************************************************************************/ - Bool BinaryMutex::LockOrWait(UserProcess& process, TimerInterface* timer) + Bool BinaryMutex::LockOrWait(USER_PROCESS& process, TimerInterface* timer) { if (timer == nullptr) return No; diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index a42d267a..df6ec253 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -41,7 +41,7 @@ using namespace Kernel; /** @brief Library initializer. */ /***********************************************************************************/ -EXTERN_C IDylibRef rtl_init_dylib(UserProcess& process) +EXTERN_C IDylibRef rtl_init_dylib(USER_PROCESS& process) { IDylibRef dll_obj = tls_new_class(); @@ -91,7 +91,7 @@ EXTERN_C IDylibRef rtl_init_dylib(UserProcess& process) /** @param successful Reports if successful or not. */ /***********************************************************************************/ -EXTERN_C Void rtl_fini_dylib(UserProcess& process, IDylibRef dll_obj, BOOL* successful) +EXTERN_C Void rtl_fini_dylib(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) { MUST_PASS(successful); diff --git a/dev/kernel/src/Network/IPCMsg.cc b/dev/kernel/src/Network/IPCMsg.cc index 457776b3..06073214 100644 --- a/dev/kernel/src/Network/IPCMsg.cc +++ b/dev/kernel/src/Network/IPCMsg.cc @@ -90,11 +90,11 @@ namespace Kernel (*pckt_in)->IpcEndianess = static_cast(endianess); (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG); - (*pckt_in)->IpcTo.UserProcessID = 0; - (*pckt_in)->IpcTo.UserProcessTeam = 0; + (*pckt_in)->IpcTo.UserProcessID = 0; + (*pckt_in)->IpcTo.UserProcessTeam = 0; - (*pckt_in)->IpcFrom.UserProcessID = 0; - (*pckt_in)->IpcFrom.UserProcessTeam = 0; + (*pckt_in)->IpcFrom.UserProcessID = 0; + (*pckt_in)->IpcFrom.UserProcessTeam = 0; return Yes; } diff --git a/dev/kernel/src/ProcessTeam.cc b/dev/kernel/src/ProcessTeam.cc index 5ac3efeb..2fcc115e 100644 --- a/dev/kernel/src/ProcessTeam.cc +++ b/dev/kernel/src/ProcessTeam.cc @@ -17,7 +17,7 @@ namespace Kernel { for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) { - this->mProcessList[i] = UserProcess(); + this->mProcessList[i] = USER_PROCESS(); this->mProcessList[i].PTime = 0; this->mProcessList[i].Status = ProcessStatusKind::kKilled; } @@ -30,7 +30,7 @@ namespace Kernel /// @return The list of process to schedule. /***********************************************************************************/ - Array& UserProcessTeam::AsArray() + Array& UserProcessTeam::AsArray() { return this->mProcessList; } @@ -50,7 +50,7 @@ namespace Kernel /// @return The current process header. /***********************************************************************************/ - Ref& UserProcessTeam::AsRef() + Ref& UserProcessTeam::AsRef() { return this->mCurrentProcess; } diff --git a/dev/kernel/src/Storage/SCSIDeviceInterface.cc b/dev/kernel/src/Storage/SCSIDeviceInterface.cc index 1b924227..85432822 100644 --- a/dev/kernel/src/Storage/SCSIDeviceInterface.cc +++ b/dev/kernel/src/Storage/SCSIDeviceInterface.cc @@ -6,6 +6,4 @@ #include -///! @brief ATAPI SCSI packet. -const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; +using namespace Kernel; diff --git a/dev/kernel/src/Swap/DiskSwap.cc b/dev/kernel/src/Swap/DiskSwap.cc index 1650a5af..a2703394 100644 --- a/dev/kernel/src/Swap/DiskSwap.cc +++ b/dev/kernel/src/Swap/DiskSwap.cc @@ -16,7 +16,7 @@ namespace Kernel /// @param data the data packet. /// @return Whether the swap was written to disk, or not. /***********************************************************************************/ - BOOL SwapDiskInterface::Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data) + BOOL DiskSwapInterface::Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data) { if (!fork_name || !fork_name_len) return NO; @@ -27,9 +27,9 @@ namespace Kernel if (!data) return NO; - FileStream file(kSwapPageFile, "wb"); + FileStream file(kSwapPageFilePath, kRestrictWRB); - auto ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz); + ErrorOr ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz); if (ret.Error()) return NO; @@ -44,7 +44,7 @@ namespace Kernel /// @param data the data packet length. /// @return Whether the swap was fetched to disk, or not. /***********************************************************************************/ - SWAP_DISK_HEADER* SwapDiskInterface::Read(const Char* fork_name, SizeT fork_name_len, SizeT data_len) + SWAP_DISK_HEADER* DiskSwapInterface::Read(const Char* fork_name, SizeT fork_name_len, SizeT data_len) { if (!fork_name || !fork_name_len) return nullptr; @@ -58,7 +58,7 @@ namespace Kernel if (data_len == 0) return nullptr; - FileStream file(kSwapPageFile, "rb"); + FileStream file(kSwapPageFilePath, kRestrictRB); VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len); diff --git a/dev/kernel/src/User.cc b/dev/kernel/src/User.cc index d29ed112..421850f7 100644 --- a/dev/kernel/src/User.cc +++ b/dev/kernel/src/User.cc @@ -2,10 +2,10 @@ * ======================================================== * * NeKernel - * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. * - * File: User.cc - * Purpose: User class, used to provide authentication and security. + * File: User.cc + * Purpose: User class, used to provide authentication and security. * * ======================================================== */ diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 5295c15a..68629bb2 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -3,7 +3,7 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.cc - PURPOSE: Low level/Ring-3 UserProcess scheduler. + PURPOSE: Low level/Ring-3 USER_PROCESS scheduler. ------------------------------------------- */ @@ -37,8 +37,8 @@ namespace Kernel STATIC UserProcessScheduler kScheduler; - UserProcess::UserProcess() = default; - UserProcess::~UserProcess() = default; + USER_PROCESS::USER_PROCESS() = default; + USER_PROCESS::~USER_PROCESS() = default; /// @brief Gets the last exit code. /// @note Not thread-safe. @@ -53,7 +53,7 @@ namespace Kernel /// @brief Crashes the current process. /***********************************************************************************/ - Void UserProcess::Crash() + Void USER_PROCESS::Crash() { if (this->Status != ProcessStatusKind::kRunning) return; @@ -66,7 +66,7 @@ namespace Kernel /// @brief boolean operator, check status. /***********************************************************************************/ - UserProcess::operator bool() + USER_PROCESS::operator bool() { return this->Status == ProcessStatusKind::kRunning; } @@ -77,7 +77,7 @@ namespace Kernel /// @return Int32 the last exit code. /***********************************************************************************/ - const UInt32& UserProcess::GetExitCode() noexcept + const UInt32& USER_PROCESS::GetExitCode() noexcept { return this->fLastExitCode; } @@ -86,7 +86,7 @@ namespace Kernel /// @brief Error code variable getter. /***********************************************************************************/ - Int32& UserProcess::GetLocalCode() noexcept + Int32& USER_PROCESS::GetLocalCode() noexcept { return this->fLocalCode; } @@ -96,7 +96,7 @@ namespace Kernel /// @param should_wakeup if the program shall wakeup or not. /***********************************************************************************/ - Void UserProcess::Wake(Bool should_wakeup) + Void USER_PROCESS::Wake(Bool should_wakeup) { this->Status = should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; @@ -106,7 +106,7 @@ namespace Kernel /** @brief Allocate pointer to track list. */ /***********************************************************************************/ - ErrorOr UserProcess::New(SizeT sz, SizeT pad_amount) + ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ auto vm_register = hal_read_cr3(); @@ -121,7 +121,7 @@ namespace Kernel if (!this->ProcessMemoryHeap) { - this->ProcessMemoryHeap = new ProcessMemoryHeapList(); + this->ProcessMemoryHeap = new USER_HEAP_LIST(); this->ProcessMemoryHeap->MemoryEntryPad = pad_amount; this->ProcessMemoryHeap->MemoryEntrySize = sz; @@ -133,7 +133,7 @@ namespace Kernel } else { - ProcessMemoryHeapList* entry = this->ProcessMemoryHeap; + USER_HEAP_LIST* entry = this->ProcessMemoryHeap; while (entry) { @@ -143,7 +143,7 @@ namespace Kernel entry = entry->MemoryNext; } - entry->MemoryNext = new ProcessMemoryHeapList(); + entry->MemoryNext = new USER_HEAP_LIST(); entry->MemoryNext->MemoryEntry = ptr; entry->MemoryNext->MemoryPrev = entry; @@ -159,7 +159,7 @@ namespace Kernel /// @brief Gets the name of the current process. /***********************************************************************************/ - const Char* UserProcess::GetName() noexcept + const Char* USER_PROCESS::GetName() noexcept { return this->Name; } @@ -168,13 +168,13 @@ namespace Kernel /// @brief Gets the owner of the process. /***********************************************************************************/ - const User* UserProcess::GetOwner() noexcept + const User* USER_PROCESS::GetOwner() noexcept { return this->Owner; } - /// @brief UserProcess status getter. - const ProcessStatusKind& UserProcess::GetStatus() noexcept + /// @brief USER_PROCESS status getter. + const ProcessStatusKind& USER_PROCESS::GetStatus() noexcept { return this->Status; } @@ -185,7 +185,7 @@ namespace Kernel */ /***********************************************************************************/ - const AffinityKind& UserProcess::GetAffinity() noexcept + const AffinityKind& USER_PROCESS::GetAffinity() noexcept { return this->Affinity; } @@ -197,7 +197,7 @@ namespace Kernel */ /***********************************************************************************/ - Void UserProcess::Exit(const Int32& exit_code) + Void USER_PROCESS::Exit(const Int32& exit_code) { this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; this->fLastExitCode = exit_code; @@ -305,7 +305,7 @@ namespace Kernel ++this->mTeam.mProcessCount; - UserProcess& process = this->mTeam.mProcessList[pid]; + USER_PROCESS& process = this->mTeam.mProcessList[pid]; process.Image.fCode = code; process.Image.fBlob = image; @@ -356,12 +356,12 @@ namespace Kernel // React according to process kind. switch (process.Kind) { - case UserProcess::kExecutableDylibKind: { + case USER_PROCESS::kExecutableDylibKind: { process.DylibDelegate = rtl_init_dylib(process); MUST_PASS(process.DylibDelegate); break; } - case UserProcess::kExecutableKind: { + case USER_PROCESS::kExecutableKind: { break; } default: { @@ -457,7 +457,7 @@ namespace Kernel /***********************************************************************************/ /// @brief Run User scheduler object. - /// @return UserProcess count executed within a team. + /// @return USER_PROCESS count executed within a team. /***********************************************************************************/ SizeT UserProcessScheduler::Run() noexcept @@ -531,13 +531,13 @@ namespace Kernel /// @brief Gets current running process. /// @return - Ref& UserProcessScheduler::CurrentProcess() + Ref& UserProcessScheduler::CurrentProcess() { return mTeam.AsRef(); } /// @brief Current proccess id getter. - /// @return UserProcess ID integer. + /// @return USER_PROCESS ID integer. ErrorOr UserProcessHelper::TheCurrentPID() { if (!kScheduler.CurrentProcess()) @@ -551,7 +551,7 @@ namespace Kernel /// @param process the process reference. /// @retval true can be schedulded. /// @retval false cannot be schedulded. - Bool UserProcessHelper::CanBeScheduled(const UserProcess& process) + Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status == ProcessStatusKind::kKilled || process.Status == ProcessStatusKind::kFinished || diff --git a/dev/modules/SCSI/SCSI.h b/dev/modules/SCSI/SCSI.h index 923df409..f843aa02 100644 --- a/dev/modules/SCSI/SCSI.h +++ b/dev/modules/SCSI/SCSI.h @@ -9,7 +9,13 @@ #include /// @file SCSI.h -/// @brief Serial SCSI driver. +/// @brief Small Computer System Interface device. -template -using scsi_packet_type = Kernel::UInt16[PacketBitLen]; +namespace Kernel +{ + template + using scsi_packet_type = Kernel::UInt16[PacketBitLen]; + using scsi_packet_type_12 = scsi_packet_type<12>; + + extern const scsi_packet_type<12> kCDRomPacketTemplate; +} // namespace Kernel \ No newline at end of file -- cgit v1.2.3 From b55d3ac738b40677c579221b4f0dbf294dc3b017 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 23 Apr 2025 22:27:47 +0200 Subject: dev, kernel: necessary refactors regarding future changes. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FSKit/Ext2.h | 2 + dev/kernel/FSKit/HeFS.h | 63 +++++----- dev/kernel/FSKit/IndexableProperty.h | 5 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 +- dev/kernel/KernelKit/CoreProcessScheduler.h | 161 +++++++++++++++++++++++++ dev/kernel/KernelKit/HardwareThreadScheduler.h | 8 +- dev/kernel/KernelKit/IPEFDylibObject.h | 4 +- dev/kernel/KernelKit/PE.h | 13 +- dev/kernel/KernelKit/PECodeMgr.h | 55 +++++++++ dev/kernel/KernelKit/PEFCodeMgr.h | 4 +- dev/kernel/KernelKit/ProcessSchedulerCore.h | 161 ------------------------- dev/kernel/KernelKit/UserProcessScheduler.h | 2 +- dev/kernel/KernelKit/UserProcessScheduler.inl | 6 +- dev/kernel/src/IPEFDylibObject.cc | 10 +- dev/kernel/src/UserProcessScheduler.cc | 6 +- dev/user/Macros.h | 2 + public/tools/mk.hefs/src/CommandLine.cc | 3 + public/tools/mk.nefs/src/CommandLine.cc | 3 + tooling/mk_img.py | 10 +- 19 files changed, 295 insertions(+), 225 deletions(-) create mode 100644 dev/kernel/KernelKit/CoreProcessScheduler.h delete mode 100644 dev/kernel/KernelKit/ProcessSchedulerCore.h (limited to 'dev/kernel/src') diff --git a/dev/kernel/FSKit/Ext2.h b/dev/kernel/FSKit/Ext2.h index 856654d6..c27eb5f9 100644 --- a/dev/kernel/FSKit/Ext2.h +++ b/dev/kernel/FSKit/Ext2.h @@ -26,6 +26,7 @@ #define kExt2FSRev0 (0) #define kExt2FSRev1 (1) +/// @brief EXT2's file types. enum { kExt2FileTypeUnknown = 0, @@ -38,6 +39,7 @@ enum kExt2FileTypeSymbolicLink = 7 }; +/// @brief The super block structure, located at LBA 1024. struct PACKED EXT2_SUPER_BLOCK final { Kernel::UInt32 fInodeCount; diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 60f1342a..2d4562c4 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -81,6 +81,13 @@ inline constexpr UInt16 kHeFSBlockCount = 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; +} // namespace Kernel + /// @brief HeFS 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. @@ -108,12 +115,8 @@ struct PACKED HEFS_BOOT_NODE final Kernel::UInt64 fReserved4; /// @brief Reserved for future use. }; -/// @brief Access time type. -/// @details Used to keep track of the INode, INodeDir allocation status. -typedef Kernel::UInt64 ATime; - -inline constexpr ATime kHeFSTimeInvalid = 0x0000000000000000; -inline constexpr ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; +inline constexpr Kernel::ATime kHeFSTimeInvalid = 0x0000000000000000; +inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; /// @brief HeFS index node. /// @details This structure is used to store the file information of a file. @@ -127,7 +130,7 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE final Kernel::UInt32 fSize; /// @brief File size. Kernel::UInt32 fChecksum, fRecoverChecksum, fBlockChecksum, fLinkChecksum; /// @brief Checksum of the file, recovery checksum, block checksum, link checksum. - ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). @@ -160,7 +163,7 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final Kernel::UInt32 fSize; /// @brief Size of the directory. Kernel::UInt32 fChecksum, fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum. - ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). @@ -177,47 +180,47 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final namespace Kernel::Detail { - /// @brief HeFS get year from ATime. - /// @param raw_atime the raw ATime value. + /// @brief HeFS get year from Kernel::ATime. + /// @param raw_atime the raw Kernel::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 + /// @note The year is stored in the upper 32 bits of the Kernel::ATime value. + inline UInt32 hefs_year_get(Kernel::ATime raw_atime) noexcept { return (raw_atime) >> 32; } - /// @brief HeFS get month from ATime. - /// @param raw_atime the raw ATime value. + /// @brief HeFS get month from Kernel::ATime. + /// @param raw_atime the raw Kernel::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 + /// @note The month is stored in the upper 24 bits of the Kernel::ATime value. + inline UInt32 hefs_month_get(Kernel::ATime raw_atime) noexcept { return (raw_atime) >> 24; } - /// @brief HeFS get day from ATime. - /// @param raw_atime the raw ATime value. + /// @brief HeFS get day from Kernel::ATime. + /// @param raw_atime the raw Kernel::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 + /// @note The day is stored in the upper 16 bits of the Kernel::ATime value. + inline UInt32 hefs_day_get(Kernel::ATime raw_atime) noexcept { return (raw_atime) >> 16; } - /// @brief HeFS get hour from ATime. - /// @param raw_atime the raw ATime value. + /// @brief HeFS get hour from Kernel::ATime. + /// @param raw_atime the raw Kernel::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 + /// @note The hour is stored in the upper 8 bits of the Kernel::ATime value. + inline UInt32 hefs_hour_get(Kernel::ATime raw_atime) noexcept { return (raw_atime) >> 8; } - /// @brief HeFS get minute from ATime. - /// @param raw_atime the raw ATime value. + /// @brief HeFS get minute from Kernel::ATime. + /// @param raw_atime the raw Kernel::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 + /// @note The minute is stored in the lower 8 bits of the Kernel::ATime value. + inline UInt32 hefs_minute_get(Kernel::ATime raw_atime) noexcept { return (raw_atime)&0xFF; } @@ -262,7 +265,6 @@ namespace Kernel::Detail case kHeFSFlashDrive: return "Flash Drive"; case kHeFSUnknown: - return "Unknown"; default: return "Unknown"; } @@ -314,7 +316,6 @@ namespace Kernel::Detail case kHeFSFileKindSymbolicLink: return "Symbolic Link"; case kHeFSFileKindUnknown: - return "Unknown"; default: return "Unknown"; } @@ -376,6 +377,6 @@ namespace Kernel _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name); public: - UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief Drive index. + UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this filesystem is mounted on. }; } // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/FSKit/IndexableProperty.h b/dev/kernel/FSKit/IndexableProperty.h index 4dbeb9f4..96853fbc 100644 --- a/dev/kernel/FSKit/IndexableProperty.h +++ b/dev/kernel/FSKit/IndexableProperty.h @@ -10,8 +10,9 @@ #include #include -#define kIndexerCatalogNameLength 256U -#define kIndexerClaimed 0xCF +#define kIndexerCatalogNameLength (256U) +#define kIndexerClaimed (0xCF) +#define kIndexerUnclaimed (0xCA) namespace Kernel { diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 833788fe..3686a48f 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -25,7 +25,7 @@ STATIC Kernel::Void hal_pre_init_scheduler() noexcept { for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) { - Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); } } diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h new file mode 100644 index 00000000..bd493140 --- /dev/null +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -0,0 +1,161 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace Kernel +{ + class USER_PROCESS; + class KERNEL_PROCESS; + class UserProcessTeam; + + /***********************************************************************************/ + /// @brief Subsystem enum type. + /***********************************************************************************/ + + enum class ProcessSubsystem : Int32 + { + kProcessSubsystemSecurity = 100, + kProcessSubsystemApplication, + kProcessSubsystemService, + kProcessSubsystemDriver, + kProcessSubsystemInvalid = 256U, + kProcessSubsystemCount = 4, + }; + + typedef UInt64 PTime; + + /***********************************************************************************/ + //! @brief Local Process identifier. + /***********************************************************************************/ + typedef Int64 ProcessID; + + /***********************************************************************************/ + //! @brief Local Process status enum. + /***********************************************************************************/ + enum class ProcessStatusKind : Int32 + { + kInvalid, + kStarting, + kRunning, + kKilled, + kFrozen, + kFinished, + kCount, + }; + + /***********************************************************************************/ + //! @brief Affinity is the amount of nano-seconds this process is going to run. + /***********************************************************************************/ + enum class AffinityKind : Int32 + { + kRealTime = 500, + kVeryHigh = 250, + kHigh = 200, + kStandard = 1000, + kLowUsage = 1500, + kVeryLowUsage = 2000, + }; + + /***********************************************************************************/ + //! Operators for AffinityKind + /***********************************************************************************/ + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int >= rhs_int; + } + + using ProcessTime = UInt64; + using PID = Int64; + + /***********************************************************************************/ + /// @note For User manager, tells where we run the code. + /***********************************************************************************/ + enum class ProcessLevelRing : Int32 + { + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 5, + }; + + /***********************************************************************************/ + /// @brief Helper type to describe a code image. + /***********************************************************************************/ + using ImagePtr = VoidPtr; + + /***********************************************************************************/ + /// @brief Helper class to contain a process's image and blob. + /***********************************************************************************/ + struct PROCESS_IMAGE final + { + explicit PROCESS_IMAGE() = default; + + ImagePtr fCode; + ImagePtr fBlob; + + Bool HasCode() + { + return this->fCode != nullptr; + } + + Bool HasImage() + { + return this->fBlob != nullptr; + } + + ErrorOr Leak() + { + if (this->fCode) + { + return ErrorOr{this->fCode}; + } + + return ErrorOr{kErrorInvalidData}; + } + + ErrorOr LeakBlob() + { + if (this->fBlob) + { + return ErrorOr{this->fBlob}; + } + + return ErrorOr{kErrorInvalidData}; + } + }; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index 9af22715..4d2ebc73 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -57,12 +57,12 @@ namespace Kernel operator bool(); public: - void Wake(const bool wakeup = false) noexcept; - void Busy(const bool busy = false) noexcept; + void Wake(const BOOL wakeup = false) noexcept; + void Busy(const BOOL busy = false) noexcept; public: - bool Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid); - bool IsWakeup() noexcept; + BOOL Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid); + BOOL IsWakeup() noexcept; public: HAL::StackFramePtr StackFrame() noexcept; diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h index 82f08932..a708fb6c 100644 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ b/dev/kernel/KernelKit/IPEFDylibObject.h @@ -99,8 +99,8 @@ namespace Kernel typedef IPEFDylibObject* IDylibRef; - EXTERN_C IDylibRef rtl_init_dylib(USER_PROCESS& header); - EXTERN_C Void rtl_fini_dylib(USER_PROCESS& header, IDylibRef lib, Bool* successful); + 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_SHARED_OBJECT_H__ */ diff --git a/dev/kernel/KernelKit/PE.h b/dev/kernel/KernelKit/PE.h index fbf8fc20..e2184918 100644 --- a/dev/kernel/KernelKit/PE.h +++ b/dev/kernel/KernelKit/PE.h @@ -16,16 +16,13 @@ #include -#define kPeSignature 0x00004550 +#define kPeSignature (0x00004550) -#define kPeDLLBase 0x4000000 -#define kPeEXEBase 0x1000000 +#define kPeMagic32 (0x010b) +#define kPeMagic64 (0x020b) -#define kPeMagic32 0x010b -#define kPeMagic64 0x020b - -#define kPeMachineAMD64 0x8664 -#define kPeMachineARM64 0xaa64 +#define kPeMachineAMD64 (0x8664) +#define kPeMachineARM64 (0xaa64) typedef struct LDR_EXEC_HEADER final { diff --git a/dev/kernel/KernelKit/PECodeMgr.h b/dev/kernel/KernelKit/PECodeMgr.h index e666c501..23ef4ecf 100644 --- a/dev/kernel/KernelKit/PECodeMgr.h +++ b/dev/kernel/KernelKit/PECodeMgr.h @@ -22,3 +22,58 @@ #include #include #include +#include +#include + +#ifndef INC_PROCESS_SCHEDULER_H +#include +#endif + +#define kPefApplicationMime "application/vnd-portable-executable" + +namespace Kernel +{ + /// + /// \name PE32Loader + /// \brief PE32+ loader class. + /// + class PE32Loader : public LoaderInterface + { + 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 FindStart() override; + VoidPtr FindSymbol(const Char* name, Int32 kind) override; + ErrorOr GetBlob() override; + + public: + bool IsLoaded() noexcept; + + private: +#ifdef __FSKIT_INCLUDES_NEFS__ + OwnPtr> fFile; +#elif defined(__FSKIT_INCLUDES_HEFS__) + OwnPtr> fFile; +#else + OwnPtr> fFile; +#endif // __FSKIT_INCLUDES_NEFS__ + + Ref fPath; + VoidPtr fCachedBlob; + bool fBad; + }; +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/KernelKit/PEFCodeMgr.h b/dev/kernel/KernelKit/PEFCodeMgr.h index 9adab8f6..389774fd 100644 --- a/dev/kernel/KernelKit/PEFCodeMgr.h +++ b/dev/kernel/KernelKit/PEFCodeMgr.h @@ -16,7 +16,7 @@ #include #endif -#define kPefApplicationMime "application/vnd-amlal-executable" +#define kPefApplicationMime "application/vnd-nekernel-executable" namespace Kernel { @@ -53,6 +53,8 @@ namespace Kernel private: #ifdef __FSKIT_INCLUDES_NEFS__ OwnPtr> fFile; +#elif defined(__FSKIT_INCLUDES_HEFS__) + OwnPtr> fFile; #else OwnPtr> fFile; #endif // __FSKIT_INCLUDES_NEFS__ diff --git a/dev/kernel/KernelKit/ProcessSchedulerCore.h b/dev/kernel/KernelKit/ProcessSchedulerCore.h deleted file mode 100644 index bd493140..00000000 --- a/dev/kernel/KernelKit/ProcessSchedulerCore.h +++ /dev/null @@ -1,161 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include -#include - -namespace Kernel -{ - class USER_PROCESS; - class KERNEL_PROCESS; - class UserProcessTeam; - - /***********************************************************************************/ - /// @brief Subsystem enum type. - /***********************************************************************************/ - - enum class ProcessSubsystem : Int32 - { - kProcessSubsystemSecurity = 100, - kProcessSubsystemApplication, - kProcessSubsystemService, - kProcessSubsystemDriver, - kProcessSubsystemInvalid = 256U, - kProcessSubsystemCount = 4, - }; - - typedef UInt64 PTime; - - /***********************************************************************************/ - //! @brief Local Process identifier. - /***********************************************************************************/ - typedef Int64 ProcessID; - - /***********************************************************************************/ - //! @brief Local Process status enum. - /***********************************************************************************/ - enum class ProcessStatusKind : Int32 - { - kInvalid, - kStarting, - kRunning, - kKilled, - kFrozen, - kFinished, - kCount, - }; - - /***********************************************************************************/ - //! @brief Affinity is the amount of nano-seconds this process is going to run. - /***********************************************************************************/ - enum class AffinityKind : Int32 - { - kRealTime = 500, - kVeryHigh = 250, - kHigh = 200, - kStandard = 1000, - kLowUsage = 1500, - kVeryLowUsage = 2000, - }; - - /***********************************************************************************/ - //! Operators for AffinityKind - /***********************************************************************************/ - - inline bool operator<(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int < rhs_int; - } - - inline bool operator>(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int > rhs_int; - } - - inline bool operator<=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int <= rhs_int; - } - - inline bool operator>=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int >= rhs_int; - } - - using ProcessTime = UInt64; - using PID = Int64; - - /***********************************************************************************/ - /// @note For User manager, tells where we run the code. - /***********************************************************************************/ - enum class ProcessLevelRing : Int32 - { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 5, - }; - - /***********************************************************************************/ - /// @brief Helper type to describe a code image. - /***********************************************************************************/ - using ImagePtr = VoidPtr; - - /***********************************************************************************/ - /// @brief Helper class to contain a process's image and blob. - /***********************************************************************************/ - struct PROCESS_IMAGE final - { - explicit PROCESS_IMAGE() = default; - - ImagePtr fCode; - ImagePtr fBlob; - - Bool HasCode() - { - return this->fCode != nullptr; - } - - Bool HasImage() - { - return this->fBlob != nullptr; - } - - ErrorOr Leak() - { - if (this->fCode) - { - return ErrorOr{this->fCode}; - } - - return ErrorOr{kErrorInvalidData}; - } - - ErrorOr LeakBlob() - { - if (this->fBlob) - { - return ErrorOr{this->fBlob}; - } - - return ErrorOr{kErrorInvalidData}; - } - }; -} // namespace Kernel diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 6e1ca146..19818213 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #define kSchedMinMicroTime (AffinityKind::kStandard) #define kSchedInvalidPID (-1) diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index a18af9c1..e31b5462 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -3,11 +3,11 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.inl - PURPOSE: Low level/Ring-3 USER_PROCESS scheduler. + PURPOSE: Low level/Ring-3 process scheduler. ------------------------------------------- */ -/// @brief USER_PROCESS scheduler inline definitions. +/// @brief USER_PROCESS inline definitions. /// @author Amlal El Mahrouss (amlal@nekernel.org) /// @date Tue Apr 22 22:01:07 CEST 2025 @@ -57,7 +57,7 @@ namespace Kernel entry = entry->MemoryNext; } - kout << "Invalid Pointer: Trying to free a pointer which doesn't exist.\r"; + kout << "USER_PROCESS: Trying to free a pointer which doesn't exist.\r"; this->Crash(); diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index df6ec253..9b0b1ab8 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -18,13 +18,13 @@ Revision History: - 01/02/24: Reworked dll ABI, expect a rtl_init_dylib and - rtl_fini_dylib (amlel) + 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 + 07/28/24: Replace rt_library_free with rtl_fini_dylib_pef 10/8/24: FIX: Fix log comment. @@ -41,7 +41,7 @@ using namespace Kernel; /** @brief Library initializer. */ /***********************************************************************************/ -EXTERN_C IDylibRef rtl_init_dylib(USER_PROCESS& process) +EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) { IDylibRef dll_obj = tls_new_class(); @@ -91,7 +91,7 @@ EXTERN_C IDylibRef rtl_init_dylib(USER_PROCESS& process) /** @param successful Reports if successful or not. */ /***********************************************************************************/ -EXTERN_C Void rtl_fini_dylib(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) +EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) { MUST_PASS(successful); diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 68629bb2..8df98f87 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -3,7 +3,7 @@ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. FILE: UserProcessScheduler.cc - PURPOSE: Low level/Ring-3 USER_PROCESS scheduler. + PURPOSE: Low level/Ring-3 process scheduler. ------------------------------------------- */ @@ -262,7 +262,7 @@ namespace Kernel { Bool success = false; - rtl_fini_dylib(*this, reinterpret_cast(this->DylibDelegate), &success); + rtl_fini_dylib_pef(*this, reinterpret_cast(this->DylibDelegate), &success); if (!success) { @@ -357,7 +357,7 @@ namespace Kernel switch (process.Kind) { case USER_PROCESS::kExecutableDylibKind: { - process.DylibDelegate = rtl_init_dylib(process); + process.DylibDelegate = rtl_init_dylib_pef(process); MUST_PASS(process.DylibDelegate); break; } diff --git a/dev/user/Macros.h b/dev/user/Macros.h index 556833ea..a0dfcb00 100644 --- a/dev/user/Macros.h +++ b/dev/user/Macros.h @@ -123,3 +123,5 @@ IMPORT_C void _rtl_assert(Bool expr, const Char* origin); #ifndef tib_cast #define tib_cast(X) ((UInt64)gib_cast(X) * 1024) #endif + +#define SCI_UNUSED(X) ((void)X) diff --git a/public/tools/mk.hefs/src/CommandLine.cc b/public/tools/mk.hefs/src/CommandLine.cc index 23681be8..8ce77208 100644 --- a/public/tools/mk.hefs/src/CommandLine.cc +++ b/public/tools/mk.hefs/src/CommandLine.cc @@ -10,5 +10,8 @@ SInt32 main(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); + return EXIT_FAILURE; } diff --git a/public/tools/mk.nefs/src/CommandLine.cc b/public/tools/mk.nefs/src/CommandLine.cc index 23681be8..8ce77208 100644 --- a/public/tools/mk.nefs/src/CommandLine.cc +++ b/public/tools/mk.nefs/src/CommandLine.cc @@ -10,5 +10,8 @@ SInt32 main(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); + return EXIT_FAILURE; } diff --git a/tooling/mk_img.py b/tooling/mk_img.py index b4fdfa1e..4a663bc0 100755 --- a/tooling/mk_img.py +++ b/tooling/mk_img.py @@ -17,11 +17,15 @@ def copy_to_fat(image_path, source_dir): try: files_to_copy = glob.glob(os.path.join(source_dir, "*")) - # Now build the command + + if not files_to_copy: + print(f"Warning: No files found in {source_dir}. Nothing to copy.") + return + command = ["mcopy", "-spm", "-i", image_path] + files_to_copy + ["::"] subprocess.run(command, check=True) - print(f"Successfully copied contents of '{source_dir}' into '{image_path}'") + print(f"Info: Successfully copied contents of '{source_dir}' into '{image_path}'") except FileNotFoundError: print("Error: mcopy is not installed. Please install mtools.") sys.exit(1) @@ -29,7 +33,7 @@ def copy_to_fat(image_path, source_dir): print(f"Error: mcopy failed with error code {e.returncode}.") sys.exit(1) except Exception as e: - print(f"mcopy failed: {e}") + print(f"Error: mcopy: {e}") sys.exit(1) if __name__ == "__main__": -- cgit v1.2.3 From bed8bd7347434e6bca73a5d52c229a122980dd1f Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 24 Apr 2025 08:11:27 +0200 Subject: dev, kernel: HeFS patches and starting to implement filesystem. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FSKit/HeFS.h | 2 + dev/kernel/KernelKit/PECodeMgr.h | 2 +- dev/kernel/src/FS/HeFS.cc | 107 ++++++++++++++++++++++++++++++--------- 3 files changed, 85 insertions(+), 26 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 2d4562c4..8af6c568 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -26,6 +26,8 @@ #define kHeFSMinimumDiskSize (gib_cast(4)) +#define kHeFSDefaultVoluneName "HeFS Volume" + struct HEFS_BOOT_NODE; struct HEFS_INDEX_NODE; struct HEFS_INDEX_NODE_DIRECTORY; diff --git a/dev/kernel/KernelKit/PECodeMgr.h b/dev/kernel/KernelKit/PECodeMgr.h index 23ef4ecf..fdbd1032 100644 --- a/dev/kernel/KernelKit/PECodeMgr.h +++ b/dev/kernel/KernelKit/PECodeMgr.h @@ -29,7 +29,7 @@ #include #endif -#define kPefApplicationMime "application/vnd-portable-executable" +#define kPeApplicationMime "application/vnd-portable-executable" namespace Kernel { diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index b48512c8..87decf6a 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -30,7 +30,7 @@ namespace Kernel /// @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, Lba& start); + STATIC ATTRIBUTE(unused) _Output Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start); /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. @@ -38,36 +38,36 @@ namespace Kernel /// @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) HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; + STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; /// @brief Allocate a new index node. /// @param root The root node of the filesystem. /// @param mnt The drive to read/write from. /// @param parent_dir_name The name of the parent directory. /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; + STATIC ATTRIBUTE(unused) _Output BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; /// @brief Balance RB-Tree of the filesystem. /// @param root The root node of the filesystem. /// @param mnt The drive to read/write from. /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt); + STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt); /// @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, Lba& start) + STATIC ATTRIBUTE(unused) _Output Void hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start) { start = dir->fNext; - if (dir->fColor == kHeFSBlack) + if (dir->fColor == kHeFSBlack && start == 0) { if (dir->fParent != 0) start = dir->fParent; } - else + else if (dir->fColor == kHeFSRed && start == 0) { if (dir->fChild != 0) start = dir->fChild; @@ -84,7 +84,7 @@ namespace Kernel /// @brief Rotate the RB-Tree to the left. /// @internal /***********************************************************************************/ - STATIC ATTRIBUTE(unused) Void hefsi_rotate_left(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) + STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_left(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) { HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); @@ -146,7 +146,7 @@ namespace Kernel /// @brief Rotate the RB-Tree to the right. /// @internal /***********************************************************************************/ - STATIC ATTRIBUTE(unused) Void hefsi_rotate_right(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) + STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_right(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) { HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); @@ -192,7 +192,7 @@ namespace Kernel /// @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) HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept { if (root && mnt) { @@ -313,7 +313,7 @@ namespace Kernel /// @param mnt The drive to read from. /// @param parent_dir_name The name of the parent directory. /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept + STATIC ATTRIBUTE(unused) _Output BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept { if (root && mnt) { @@ -383,7 +383,7 @@ namespace Kernel /// @param root The root node of the filesystem. /// @param mnt The drive to read/write from. /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt) + STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt) { if (root && mnt) { @@ -400,6 +400,16 @@ namespace Kernel mnt->fInput(mnt->fPacket); + if (!mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + if (start == root->fStartIND) { dir->fColor = kHeFSBlack; @@ -417,19 +427,6 @@ namespace Kernel mnt->fInput(mnt->fPacket); - if (dir_parent->fColor != kHeFSRed) - { - delete dir_parent; - delete dir; - - dir = nullptr; - dir_parent = nullptr; - - err_global_get() = kErrorDiskIsCorrupted; - - return NO; - } - if (!mnt->fPacket.fPacketGood) { delete dir; @@ -448,6 +445,16 @@ namespace Kernel mnt->fInput(mnt->fPacket); + if (!mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + if (dir_uncle.fColor == kHeFSRed) { dir_parent->fColor = kHeFSBlack; @@ -465,7 +472,18 @@ namespace Kernel mnt->fOutput(mnt->fPacket); + if (!mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + hefsi_traverse_tree(dir, start); + continue; } else @@ -486,6 +504,16 @@ namespace Kernel mnt->fOutput(mnt->fPacket); + if (!mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + hefsi_rotate_right(dir, start, mnt); hefsi_traverse_tree(dir, start); @@ -509,4 +537,33 @@ namespace Kernel /// @note HeFS 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+HeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + _Output Bool HeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name) + { + NE_UNUSED(drive); + NE_UNUSED(end_lba); + NE_UNUSED(flags); + NE_UNUSED(part_name); + + return NO; + } + + /// @brief Make a EPM+HeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + _Output Bool HeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name) + { + NE_UNUSED(drive); + NE_UNUSED(end_lba); + NE_UNUSED(flags); + NE_UNUSED(part_name); + + return NO; + } +} // namespace Kernel + #endif // ifdef __FSKIT_INCLUDES_HEFS__ -- cgit v1.2.3 From f8a49e346e45daaf1463b658b386040f8843fa61 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 24 Apr 2025 09:14:06 +0200 Subject: dev, kernel, boot: HeFS, Scheduler, BootZ: see below. Refactored HeFS node handling and API for extensibility, added directory metadata, improved wildcard querying, and updated documentation accordingly. Signed-off-by: Amlal El Mahrouss --- dev/boot/amd64-desktop.make | 2 +- dev/boot/src/HEL/AMD64/BootEFI.cc | 6 +- dev/kernel/FSKit/HeFS.h | 11 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 + dev/kernel/src/FS/HeFS.cc | 180 ++++++++++++++++++++++++++++--- docs/tex/hefs.tex | 30 +++++- 6 files changed, 202 insertions(+), 29 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 00b37b94..652ba31e 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -97,7 +97,7 @@ all: compile-amd64 .PHONY: disk disk: dd if=/dev/zero of=$(BOOT) bs=7M count=100 - mformat -i $(BOOT) -F -v "NEKERNEL-ESP" + mformat -i $(BOOT) -F -v "ESP" ifneq ($(DEBUG_SUPPORT), ) diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 0fc21860..6411383d 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -190,7 +190,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, if (reader_syschk.Blob()) { syschk_thread = new Boot::BootThread(reader_syschk.Blob()); - syschk_thread->SetName("BootZ\\System Check"); + syschk_thread->SetName("BootZ/SysChk"); syschk_thread->Start(handover_hdr, NO); } @@ -258,7 +258,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, auto kernel_thread = Boot::BootThread(reader_kernel.Blob()); - kernel_thread.SetName("BootZ\\NeKernel"); + kernel_thread.SetName("BootZ/NeKernel"); handover_hdr->f_KernelImage = reader_kernel.Blob(); handover_hdr->f_KernelSz = reader_kernel.Size(); @@ -273,7 +273,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, return kEfiFail; auto netboot_thread = Boot::BootThread(reader_netboot.Blob()); - netboot_thread.SetName("BootZ\\BootNet"); + netboot_thread.SetName("BootZ/BootNet"); return netboot_thread.Start(handover_hdr, NO); } diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 8af6c568..0ad47739 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -26,7 +26,9 @@ #define kHeFSMinimumDiskSize (gib_cast(4)) -#define kHeFSDefaultVoluneName "HeFS Volume" +#define kHeFSDefaultVoluneName u"HeFS Volume" + +#define kHeFSSearchAllStr u"*" struct HEFS_BOOT_NODE; struct HEFS_INDEX_NODE; @@ -162,7 +164,7 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final Kernel::UInt32 fFlags; /// @brief File flags. Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, Symbolic Link, Unknown). - Kernel::UInt32 fSize; /// @brief Size of the directory. + Kernel::UInt32 fEntryCount; /// @brief Entry Count of this directory inode. Kernel::UInt32 fChecksum, fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum. Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. @@ -343,11 +345,6 @@ namespace Kernel::Detail return "Unknown"; } } - - inline SizeT hefs_get_block_size(SizeT block_size) noexcept - { - return block_size * kHeFSBlockCount; - } } // namespace Kernel::Detail namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 3686a48f..d59e9e86 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -98,6 +98,8 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept idt_loader.Load(idt_reg); + /// after the scheduler runs, we must look over teams, every 200ms in order to schedule every process according to their affinity fairly. + auto constexpr kSchedTeamSwitchMS = 200U; /// @brief Team switch time in milliseconds. Kernel::HardwareTimer timer(rtl_ms(kSchedTeamSwitchMS)); diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 87decf6a..cfa8baae 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -4,6 +4,7 @@ ------------------------------------------- */ +#include "NewKit/Defines.h" #ifdef __FSKIT_INCLUDES_HEFS__ #include @@ -38,7 +39,15 @@ namespace Kernel /// @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* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; + STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind, SizeT* cnt) noexcept; + + /// @brief Get the index node size. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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 SizeT hefs_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; /// @brief Allocate a new index node. /// @param root The root node of the filesystem. @@ -186,16 +195,125 @@ namespace Kernel mnt->fOutput(mnt->fPacket); } + /// @brief Get the index node size. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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 SizeT hefs_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + { + if (root && mnt) + { + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + SizeT sz = 0UL; + + auto start = root->fStartIND; + auto end = root->fEndIND; + + auto hop_watch = 0; + + while (YES) + { + if (start > end) + { + kout << "Error: Invalid start/end values.\r"; + break; + } + + if (hop_watch > 100) + { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) + { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) + { + delete node; + delete dir; + + dir = nullptr; + node = nullptr; + + err_global_get() = kErrorFileNotFound; + + return 0; + } + + if (dir->fKind == kHeFSFileKindDirectory) + { + if (KStringBuilder::Equals(dir_name, dir->fName) || + KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) + { + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) + { + if (dir->fIndexNodeStart[inode_index]) + { + mnt->fPacket.fPacketLba = dir->fIndexNodeStart[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + mnt->fInput(mnt->fPacket); + } + else if (dir->fIndexNodeEnd[inode_index]) + { + mnt->fPacket.fPacketLba = dir->fIndexNodeEnd[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + mnt->fInput(mnt->fPacket); + } + + if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) + { + if (node->fKind == kHeFSFileKindDirectory) + { + sz += hefs_fetch_index_node_size(root, mnt, dir_name, file_name, kind); + } + else + { + sz = node->fSize; + } + + return sz; + } + } + } + } + } + + err_global_get() = kErrorSuccess; + return sz; + } + + err_global_get() = kErrorFileNotFound; + return 0; + } + /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. /// @param mnt The drive 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* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept + STATIC ATTRIBUTE(unused) _Output HEFS_INDEX_NODE* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind, SizeT* cnt) noexcept { if (root && mnt) { + HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt]; + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); @@ -208,6 +326,8 @@ namespace Kernel auto start = root->fStartIND; auto end = root->fEndIND; + auto start_cnt = 0UL; + auto hop_watch = 0; while (YES) @@ -251,7 +371,8 @@ namespace Kernel if (dir->fKind == kHeFSFileKindDirectory) { - if (KStringBuilder::Equals(dir_name, dir->fName)) + if (KStringBuilder::Equals(dir_name, dir->fName) || + KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) { for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { @@ -271,7 +392,14 @@ namespace Kernel delete dir; dir = nullptr; - return node; + node_arr[start_cnt] = *node; + ++start_cnt; + + if (start_cnt > *cnt) + { + delete node; + return node_arr; + } } } else @@ -280,9 +408,11 @@ namespace Kernel delete dir; delete node; + delete[] node_arr; - dir = nullptr; - node = nullptr; + dir = nullptr; + node = nullptr; + node_arr = nullptr; return nullptr; } @@ -296,9 +426,11 @@ namespace Kernel delete dir; delete node; + delete[] node_arr; - dir = nullptr; - node = nullptr; + dir = nullptr; + node = nullptr; + node_arr = nullptr; } kout << "Error: Failed to find index node.\r"; @@ -350,18 +482,32 @@ namespace Kernel if (dir->fIndexNodeStart[inode_index] != 0 || dir->fIndexNodeEnd[inode_index] != 0) { - mnt->fPacket.fPacketLba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] : dir->fIndexNodeStart[inode_index]; + HEFS_INDEX_NODE prev_node; + + auto lba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] : dir->fIndexNodeStart[inode_index]; + + mnt->fPacket.fPacketLba = lba; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; + mnt->fPacket.fPacketContent = &prev_node; - mnt->fOutput(mnt->fPacket); + mnt->fInput(mnt->fPacket); - if (mnt->fPacket.fPacketGood) + if (prev_node.fDeleted > 0 && + !prev_node.fAccessed) { - delete dir; - dir = nullptr; + mnt->fPacket.fPacketLba = lba; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + + mnt->fOutput(mnt->fPacket); - return YES; + if (mnt->fPacket.fPacketGood) + { + delete dir; + dir = nullptr; + + return YES; + } } } } @@ -548,7 +694,7 @@ namespace Kernel NE_UNUSED(end_lba); NE_UNUSED(flags); NE_UNUSED(part_name); - + return NO; } @@ -561,7 +707,7 @@ namespace Kernel NE_UNUSED(end_lba); NE_UNUSED(flags); NE_UNUSED(part_name); - + return NO; } } // namespace Kernel diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index 3370af48..d20dfa5e 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -111,13 +111,41 @@ struct HEFS_INDEX_NODE_DIRECTORY { }; \end{lstlisting} +\section{Filesystem Design} + +HeFS is designed to be robust and efficient, with a focus on: +\begin{itemize} + \item Fast access to files and directories + \item Efficient use of disk space + \item Support for large files and directories + \item Compatibility with various drive types + \item Easy recovery from errors + \item Support for advanced features like journaling and permissions +\end{itemize} + +The filesystem uses a red-black tree structure for directories, allowing for efficient insertion, deletion, and searching of files. +Each file and directory is represented by an index node directory, which contains metadata such as timestamps, permissions, and checksums. + +The index node directory itself contains index nodes, which are the actual data structures that store file and directory information. +The filesystem also includes a boot node, which contains information about the filesystem itself, such as the magic number, version, and size. + +The filesystem is designed to be extensible, allowing for future enhancements and features to be added without breaking compatibility with existing data. + +\section{Minimum Requirements} + +HeFS requires at least 4GB of free space on the drive to function properly. +It is recommended to have more than 8GB of free space for optimal performance. +The filesystem is designed to work with various drive types, including hard drives, SSDs, and USB mass storage devices. + +But that really depends on what you do with the filesystem. + \section{Future Work} Planned extensions include: \begin{itemize} \item Journaling recovery logic \item Advanced permission flags \item Logical volume management support - \item Cross-filesystem linking (EPM integration) + \item Cross-filesystem linking (EPM, and GPT integration) \end{itemize} \end{document} \ No newline at end of file -- cgit v1.2.3 From e6185ca92212ab0686892a1a12efd392f895c1f7 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 24 Apr 2025 09:49:26 +0200 Subject: dev, kernel: some improvements on BitMapMgr and fixes on BinaryMutex. Signed-off-by: Amlal El Mahrouss --- dev/kernel/src/BinaryMutex.cc | 11 ++++++----- dev/kernel/src/BitMapMgr.cc | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index f86be37b..c149b362 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -10,7 +10,7 @@ namespace Kernel { /***********************************************************************************/ - /// @brief Unlocks the semaphore. + /// @brief Unlocks the binary mutex. /***********************************************************************************/ Bool BinaryMutex::Unlock() noexcept { @@ -18,6 +18,7 @@ namespace Kernel { fLockingProcess = USER_PROCESS(); fLockingProcess.Status = ProcessStatusKind::kFrozen; + return Yes; } @@ -25,14 +26,14 @@ namespace Kernel } /***********************************************************************************/ - /// @brief Locks process in the semaphore. + /// @brief Locks process in the binary mutex. /***********************************************************************************/ Bool BinaryMutex::Lock(USER_PROCESS& process) { - if (!process || fLockingProcess) + if (!process || this->IsLocked()) return No; - fLockingProcess = process; + this->fLockingProcess = process; return Yes; } @@ -42,7 +43,7 @@ namespace Kernel /***********************************************************************************/ Bool BinaryMutex::IsLocked() const { - return fLockingProcess.Status == ProcessStatusKind::kRunning; + return this->fLockingProcess.Status == ProcessStatusKind::kRunning; } /***********************************************************************************/ diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc index 96cbb803..1a1e2c0d 100644 --- a/dev/kernel/src/BitMapMgr.cc +++ b/dev/kernel/src/BitMapMgr.cc @@ -16,7 +16,6 @@ #include #define kBitMapMagic (0x10210U) -#define kBitMapPadSize (mib_cast(16)) #define kBitMapMagIdx (0U) #define kBitMapSizeIdx (1U) -- cgit v1.2.3 From 7faa5e2fcf41c4fbb2241b605e8f2a11738fc4d9 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 24 Apr 2025 15:52:36 +0200 Subject: dev, kernel: scheduler, timer: hw timer and scheduler improvements. Signed-off-by: Amlal El Mahrouss --- dev/boot/BootKit/Qr.h | 4 +- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 23 +---------- dev/kernel/HALKit/AMD64/HalDebugOutput.cc | 5 +++ dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc | 4 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 25 ++++++------ dev/kernel/HALKit/AMD64/HalTimerAMD64.cc | 47 ++++++++++++++-------- dev/kernel/KernelKit/Timer.h | 10 ++--- dev/kernel/KernelKit/UserProcessScheduler.h | 2 +- dev/kernel/src/BinaryMutex.cc | 2 +- dev/kernel/src/UserProcessScheduler.cc | 11 ++++- 10 files changed, 72 insertions(+), 61 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/boot/BootKit/Qr.h b/dev/boot/BootKit/Qr.h index 231fcee7..1bf9fa3d 100644 --- a/dev/boot/BootKit/Qr.h +++ b/dev/boot/BootKit/Qr.h @@ -957,8 +957,8 @@ namespace qr NE_COPY_DEFAULT(QrDelegate) /// @brief Draw method delegate. - template - bool draw(Qr& subject, int x, int y) noexcept + template + bool draw(Qr& subject, Int32 x, Int32 y) noexcept { return subject.draw(x, y); } diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 3b98e9e8..1f865057 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -219,17 +219,9 @@ namespace Kernel::HAL kApicBaseAddress = kMADTBlock->Address; - constexpr auto kMemoryAPStart = 0x7C000; - Char* ptr_ap_code = reinterpret_cast(kMemoryAPStart); - - mm_map_page(ptr_ap_code, ptr_ap_code, kMMFlagsWr | kMMFlagsPCD); - - SizeT hal_ap_blob_len = hal_ap_blob_end - hal_ap_blob_start; - - rt_copy_memory((Char*)hal_ap_blob_start, ptr_ap_code, hal_ap_blob_len); - while (Yes) { + /// @note Anything bigger than x2APIC type doesn't exist. if (kMADTBlock->List[index].Type > 9 || kSMPCount > kSchedProcessLimitPerTeam) break; @@ -243,17 +235,6 @@ namespace Kernel::HAL kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID; (void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); - // I'll just make the AP start from scratch here. - - hal_send_start_ipi(kApicBaseAddress, kAPICLocales[kSMPCount]); - - HardwareTimer timer(Kernel::rtl_ms(10)); - timer.Wait(); - - /// TODO: HAL helper to create an address. - - hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)ptr_ap_code) >> 12)); - ++kSMPCount; break; } @@ -264,7 +245,7 @@ namespace Kernel::HAL ++index; } - (void)(kout << "SMP: number of APs: " << number(kSMPCount) << kendl); + (void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl); // Kernel is now SMP aware. // That means that the scheduler is now available (on MP Kernels) diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc index b69614fd..84c8c348 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc @@ -121,6 +121,11 @@ namespace Kernel x += kFontSizeX; + if (x > kHandoverHeader->f_GOP.f_Width) + { + x = kFontSizeX; + } + if (y > kHandoverHeader->f_GOP.f_Height) { y = kFontSizeY; diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc index c0c7dfcf..f205e766 100644 --- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc +++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc @@ -107,10 +107,10 @@ namespace Kernel::HAL idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * (kKernelIdtSize); - hal_load_idt(idt); - Detail::hal_enable_pit(kPITTickForScheduler); + hal_load_idt(idt); + rt_sti(); } diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index d59e9e86..0c680f97 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -19,8 +19,6 @@ EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; -STATIC Kernel::Array kTeams; - STATIC Kernel::Void hal_pre_init_scheduler() noexcept { for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) @@ -98,11 +96,13 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept idt_loader.Load(idt_reg); - /// after the scheduler runs, we must look over teams, every 200ms in order to schedule every process according to their affinity fairly. + /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every process according to their affinity fairly. + + auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. - auto constexpr kSchedTeamSwitchMS = 200U; /// @brief Team switch time in milliseconds. + Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); - Kernel::HardwareTimer timer(rtl_ms(kSchedTeamSwitchMS)); + STATIC Kernel::Array kTeams; SizeT team_index = 0U; @@ -110,15 +110,16 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept /// @details Not even round-robin, just a simple loop in this boot core we're at. while (YES) { - timer.Wait(); - - UserProcessScheduler::The().SwitchTeam(kTeams[team_index]); - - ++team_index; - - if (team_index > kSchedTeamCount) + if (team_index > (kSchedTeamCount - 1)) { team_index = 0U; } + + while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])) + ; + + timer.Wait(); + + ++team_index; } } diff --git a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc index 72de8eb0..ade41d2f 100644 --- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc @@ -17,10 +17,10 @@ // timer slot 0 -#define cHPETCounterRegValue (0x00) -#define cHPETConfigRegValue (0x20) -#define cHPETCompRegValue (0x24) -#define cHPETInterruptRegValue (0x2C) +#define kHPETCounterRegValue (0x00) +#define kHPETConfigRegValue (0x20) +#define kHPETCompRegValue (0x24) +#define kHPETInterruptRegValue (0x2C) ///! BUGS: 0 ///! @file HalTimer.cc @@ -53,7 +53,19 @@ HardwareTimer::HardwareTimer(UInt64 ms) auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak(); MUST_PASS(hpet); - fDigitalTimer = (UIntPtr*)hpet->address.Address; + 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); // enable timer + *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) = *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) | (1 << 3); // one shot conf + } } HardwareTimer::~HardwareTimer() @@ -62,25 +74,28 @@ HardwareTimer::~HardwareTimer() fWaitFor = 0; } +/***********************************************************************************/ +/// @brief Wait for the timer to stop spinning. +/***********************************************************************************/ + BOOL HardwareTimer::Wait() noexcept { if (fWaitFor < 1) return NO; - // if not enabled yet. - if (!(*(fDigitalTimer + cHPETConfigRegValue) & (1 << 0))) - { - *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 0); // enable it - *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 3); // one shot conf - } + UInt64 hpet_cap = *((volatile UInt64*)(fDigitalTimer + kHPETCounterRegValue)); + UInt64 femtoseconds_per_tick = (hpet_cap >> 32); + + if (femtoseconds_per_tick == 0) + return NO; - UInt64 ticks = fWaitFor / ((*(fDigitalTimer) >> 32) & __UINT32_MAX__); - UInt64 prev = *(fDigitalTimer + cHPETCounterRegValue); + volatile UInt64* timer = (volatile UInt64*)(fDigitalTimer + kHPETCounterRegValue); - prev += ticks; + UInt64 now = *timer; + UInt64 prev = now + (fWaitFor / femtoseconds_per_tick); - while (*(fDigitalTimer + cHPETCounterRegValue) < (ticks)) - ; + while (*timer < (prev)) + asm volatile("pause"); return YES; } diff --git a/dev/kernel/KernelKit/Timer.h b/dev/kernel/KernelKit/Timer.h index b6d23e6b..1d12876b 100644 --- a/dev/kernel/KernelKit/Timer.h +++ b/dev/kernel/KernelKit/Timer.h @@ -60,24 +60,24 @@ namespace Kernel BOOL Wait() noexcept override; private: - UIntPtr* fDigitalTimer{nullptr}; + volatile UInt8* fDigitalTimer{nullptr}; Int64 fWaitFor{0}; }; - inline Int64 rtl_ms(Int64 time) + inline Int64 rtl_microseconds(Int64 time) { if (time < 0) return 0; // TODO: nanoseconds maybe? - return kTimeUnit * kTimeUnit * time; + return kTimeUnit * time; } - inline Int64 rtl_seconds(Int64 time) + inline Int64 rtl_milliseconds(Int64 time) { if (time < 0) return 0; - return kTimeUnit * rtl_ms(time); + return kTimeUnit * kTimeUnit * time; } } // namespace Kernel diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 53ee3476..ec16a0e2 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -20,7 +20,7 @@ #define kSchedMinMicroTime (AffinityKind::kStandard) #define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (32U) -#define kSchedTeamCount (512U) +#define kSchedTeamCount (256U) #define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ #define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index c149b362..f9faadd2 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -67,7 +67,7 @@ namespace Kernel /***********************************************************************************/ BOOL BinaryMutex::WaitForProcess(const Int16& sec) noexcept { - HardwareTimer hw_timer(rtl_seconds(sec)); + HardwareTimer hw_timer(rtl_milliseconds(sec)); hw_timer.Wait(); return !this->IsLocked(); diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 8df98f87..7aded611 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -31,8 +31,10 @@ namespace Kernel STATIC UInt32 kLastExitCode = 0U; + STATIC BOOL kCurrentlySwitching = No; + /***********************************************************************************/ - /// @brief External reference of the thread scheduler. + /// @brief Scheduler itself. /***********************************************************************************/ STATIC UserProcessScheduler kScheduler; @@ -470,6 +472,8 @@ namespace Kernel return 0UL; } + kCurrentlySwitching = Yes; + for (; process_index < mTeam.AsArray().Capacity(); ++process_index) { auto& process = mTeam.AsArray()[process_index]; @@ -502,6 +506,8 @@ namespace Kernel } } + kCurrentlySwitching = No; + return process_index; } @@ -524,6 +530,9 @@ namespace Kernel if (team.AsArray().Count() < 1) return No; + if (kCurrentlySwitching) + return No; + kScheduler.mTeam = team; return Yes; -- cgit v1.2.3 From 69703f6fdd788276e84cbe2714c91fcfdb9e76cb Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 24 Apr 2025 17:34:39 +0200 Subject: dev, kernel: scheduler and heap related work. - Replacing USER_HEAP_LIST with HEAP_HEAP_TREE. - Reworked Signal struct. - Add Team spinner inside ARM64 HAL too. Signed-off-by: Amlal --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 12 +++++----- dev/kernel/HALKit/ARM64/HalKernelMain.cc | 23 +++++++++++++++++++ dev/kernel/KernelKit/UserProcessScheduler.h | 25 ++++++++++++++++----- dev/kernel/KernelKit/UserProcessScheduler.inl | 4 ++-- dev/kernel/src/UserProcessScheduler.cc | 26 ++++++++++++---------- 5 files changed, 64 insertions(+), 26 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 7114f9f7..7dce21d1 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -26,7 +26,7 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; @@ -51,7 +51,7 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; process.Leak().Status = Kernel::ProcessStatusKind::kKilled; @@ -101,7 +101,7 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; @@ -125,7 +125,7 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; @@ -154,7 +154,7 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) process.Leak().Signal.SignalArg = rip; process.Leak().Signal.SignalID = SIGTRAP; - process.Leak().Signal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; Kernel::kout << "Kernel: SIGTRAP status.\r"; @@ -176,7 +176,7 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.PreviousStatus = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; Kernel::kout << "Kernel: SIGKILL status.\r"; diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index d9f3eb85..3498d477 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -48,7 +48,30 @@ EXTERN_C void hal_init_platform( Kernel::mp_initialize_gic(); + /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every process according to their affinity fairly. + + auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. + + Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); + + STATIC Kernel::Array kTeams; + + SizeT team_index = 0U; + + /// @brief This just loops over the teams and switches between them. + /// @details Not even round-robin, just a simple loop in this boot core we're at. while (YES) { + if (team_index > (kSchedTeamCount - 1)) + { + team_index = 0U; + } + + while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])) + ; + + timer.Wait(); + + ++team_index; } } diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index ec16a0e2..3811a2e2 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -67,26 +67,39 @@ namespace Kernel SizeT MemoryLimit{kSchedMaxMemoryLimit}; SizeT UsedMemory{0UL}; - struct USER_HEAP_LIST final + struct USER_HEAP_TREE final { VoidPtr MemoryEntry{nullptr}; SizeT MemoryEntrySize{0UL}; SizeT MemoryEntryPad{0UL}; - struct USER_HEAP_LIST* MemoryPrev{nullptr}; - struct USER_HEAP_LIST* MemoryNext{nullptr}; + enum + { + kInvalidMemory = 0, + kRedMemory = 100, + kBlackMemory = 101, + kCountMemory = 2, + }; + + Int32 MemoryColor{kBlackMemory}; + + struct USER_HEAP_TREE* MemoryParent{nullptr}; + struct USER_HEAP_TREE* MemoryChild{nullptr}; + + struct USER_HEAP_TREE* MemoryPrev{nullptr}; + struct USER_HEAP_TREE* MemoryNext{nullptr}; }; struct USER_PROCESS_SIGNAL final { UIntPtr SignalArg; - ProcessStatusKind PreviousStatus; + ProcessStatusKind Status; UIntPtr SignalID; }; USER_PROCESS_SIGNAL Signal; - USER_HEAP_LIST* ProcessMemoryHeap{nullptr}; - UserProcessTeam* ProcessParentTeam; + USER_HEAP_TREE* HeapTree{nullptr}; + UserProcessTeam* ParentTeam; VoidPtr VMRegister{0UL}; diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index e31b5462..63cdc795 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -23,13 +23,13 @@ namespace Kernel if (!ptr) return No; - if (!this->ProcessMemoryHeap) + if (!this->HeapTree) { kout << "USER_PROCESS's heap is empty.\r"; return No; } - USER_HEAP_LIST* entry = this->ProcessMemoryHeap; + USER_HEAP_TREE* entry = this->HeapTree; while (entry != nullptr) { diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 7aded611..cdf7d91f 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -121,21 +121,21 @@ namespace Kernel auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); #endif - if (!this->ProcessMemoryHeap) + if (!this->HeapTree) { - this->ProcessMemoryHeap = new USER_HEAP_LIST(); + this->HeapTree = new USER_HEAP_TREE(); - this->ProcessMemoryHeap->MemoryEntryPad = pad_amount; - this->ProcessMemoryHeap->MemoryEntrySize = sz; + this->HeapTree->MemoryEntryPad = pad_amount; + this->HeapTree->MemoryEntrySize = sz; - this->ProcessMemoryHeap->MemoryEntry = ptr; + this->HeapTree->MemoryEntry = ptr; - this->ProcessMemoryHeap->MemoryPrev = nullptr; - this->ProcessMemoryHeap->MemoryNext = nullptr; + this->HeapTree->MemoryPrev = nullptr; + this->HeapTree->MemoryNext = nullptr; } else { - USER_HEAP_LIST* entry = this->ProcessMemoryHeap; + USER_HEAP_TREE* entry = this->HeapTree; while (entry) { @@ -145,8 +145,10 @@ namespace Kernel entry = entry->MemoryNext; } - entry->MemoryNext = new USER_HEAP_LIST(); + entry->MemoryNext = new USER_HEAP_TREE(); entry->MemoryNext->MemoryEntry = ptr; + entry->MemoryEntrySize = sz; + entry->MemoryEntryPad = pad_amount; entry->MemoryNext->MemoryPrev = entry; entry->MemoryNext->MemoryNext = nullptr; @@ -206,7 +208,7 @@ namespace Kernel kLastExitCode = exit_code; - auto memory_heap_list = this->ProcessMemoryHeap; + auto memory_heap_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ auto pd = hal_read_cr3(); @@ -277,7 +279,7 @@ namespace Kernel this->ProcessId = 0UL; this->Status = ProcessStatusKind::kFinished; - --this->ProcessParentTeam->mProcessCount; + --this->ParentTeam->mProcessCount; } /***********************************************************************************/ @@ -390,7 +392,7 @@ namespace Kernel HAL::mm_map_page((VoidPtr)process.StackReserve, process.StackReserve, flags); #endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.ProcessParentTeam = &mTeam; + process.ParentTeam = &mTeam; process.ProcessId = pid; process.Status = ProcessStatusKind::kStarting; -- cgit v1.2.3 From 3d2143e248dc276b48c5c71e895f97fe8600d1d8 Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 24 Apr 2025 20:03:09 +0200 Subject: dev, kernel: early user_heap_tree rework of the scheduler's heap system. Signed-off-by: Amlal --- dev/kernel/src/FS/HeFS.cc | 1 - dev/kernel/src/MemoryMgr.cc | 10 ++-- dev/kernel/src/UserProcessScheduler.cc | 85 ++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 20 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index cfa8baae..7864bc6f 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -4,7 +4,6 @@ ------------------------------------------- */ -#include "NewKit/Defines.h" #ifdef __FSKIT_INCLUDES_HEFS__ #include diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc index 8020ca1c..eff54435 100644 --- a/dev/kernel/src/MemoryMgr.cc +++ b/dev/kernel/src/MemoryMgr.cc @@ -108,7 +108,7 @@ namespace Kernel if (!ptr_heap || new_sz < 1) return nullptr; - kout << "This function is not implemented by the kernel itself.\r"; + kout << "This function is not implemented by the kernel yet.\r"; ke_panic(RUNTIME_CHECK_INVALID); @@ -129,8 +129,8 @@ namespace Kernel sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK); - PageMgr heap_mgr; - auto wrapper = heap_mgr.Request(wr, user, No, sz_fix, pad_amount); + PageMgr page_mgr; + auto wrapper = page_mgr.Request(wr, user, No, sz_fix, pad_amount); Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast( @@ -244,8 +244,8 @@ namespace Kernel PTEWrapper page_wrapper(No, No, No, reinterpret_cast(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); Ref pte_address{page_wrapper}; - PageMgr heap_mgr; - heap_mgr.Free(pte_address); + PageMgr page_mgr; + page_mgr.Free(pte_address); return kErrorSuccess; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index cdf7d91f..660dd544 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -105,11 +105,33 @@ namespace Kernel } /***********************************************************************************/ - /** @brief Allocate pointer to track list. */ + /** @brief Allocate pointer to heap tree. */ + /***********************************************************************************/ + + USER_PROCESS::USER_HEAP_TREE* sched_try_go_upper_heap_tree(USER_PROCESS::USER_HEAP_TREE* tree) + { + if (tree) + { + tree = tree->MemoryNext; + + if (!tree) + { + return nullptr; + } + } + + return tree; + } + + /***********************************************************************************/ + /** @brief Allocate pointer to heap tree. */ /***********************************************************************************/ ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { + if (this->UsedMemory > kSchedMaxMemoryLimit) + return ErrorOr(-kErrorHeapOutOfMemory); + #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ auto vm_register = hal_read_cr3(); hal_write_cr3(this->VMRegister); @@ -125,33 +147,68 @@ namespace Kernel { this->HeapTree = new USER_HEAP_TREE(); - this->HeapTree->MemoryEntryPad = pad_amount; + this->HeapTree->MemoryColor = USER_HEAP_TREE::kBlackMemory; + + this->HeapTree->MemoryEntryPad = pad_amount; this->HeapTree->MemoryEntrySize = sz; this->HeapTree->MemoryEntry = ptr; - this->HeapTree->MemoryPrev = nullptr; - this->HeapTree->MemoryNext = nullptr; + this->HeapTree->MemoryPrev = nullptr; + this->HeapTree->MemoryNext = nullptr; + this->HeapTree->MemoryParent = nullptr; + this->HeapTree->MemoryChild = nullptr; } else { - USER_HEAP_TREE* entry = this->HeapTree; + USER_HEAP_TREE* entry = this->HeapTree; + USER_HEAP_TREE* prev_entry = entry; + + BOOL is_parent = NO; while (entry) { - if (entry->MemoryEntry == nullptr) - break; // chose to break here, when we get an already allocated memory entry for our needs. + if (entry->MemoryEntrySize < 1) + break; - entry = entry->MemoryNext; + prev_entry = entry; + + if (entry->MemoryNext) + { + entry = entry->MemoryNext; + } + else if (entry->MemoryChild) + { + entry = entry->MemoryChild; + is_parent = YES; + } + else + { + entry = entry->MemoryParent; + entry = sched_try_go_upper_heap_tree(entry); + } } - entry->MemoryNext = new USER_HEAP_TREE(); - entry->MemoryNext->MemoryEntry = ptr; - entry->MemoryEntrySize = sz; - entry->MemoryEntryPad = pad_amount; + if (!entry) + entry = new USER_HEAP_TREE(); - entry->MemoryNext->MemoryPrev = entry; - entry->MemoryNext->MemoryNext = nullptr; + entry->MemoryEntry = ptr; + entry->MemoryEntrySize = sz; + entry->MemoryEntryPad = pad_amount; + + if (is_parent) + { + entry->MemoryParent = prev_entry; + prev_entry->MemoryChild = entry; + + prev_entry->MemoryColor = USER_HEAP_TREE::kBlackMemory; + entry->MemoryColor = USER_HEAP_TREE::kRedMemory; + } + else + { + prev_entry->MemoryNext = entry; + entry->MemoryPrev = prev_entry; + } } this->UsedMemory += sz; -- cgit v1.2.3 From c68bfbfcac5c6b4e4fa0ca5596eeac7d452b76cd Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 24 Apr 2025 20:15:54 +0200 Subject: dev, kernel: scheduler: fully implement traversal and cleanup. Signed-off-by: Amlal --- dev/kernel/KernelKit/UserProcessScheduler.h | 1 + dev/kernel/src/UserProcessScheduler.cc | 67 +++++++++++++++++------------ 2 files changed, 41 insertions(+), 27 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index 3811a2e2..aeefe1d2 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -67,6 +67,7 @@ namespace Kernel SizeT MemoryLimit{kSchedMaxMemoryLimit}; SizeT UsedMemory{0UL}; + /// @brief Allocation tracker structure. struct USER_HEAP_TREE final { VoidPtr MemoryEntry{nullptr}; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 660dd544..aaf0d699 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -108,7 +108,7 @@ namespace Kernel /** @brief Allocate pointer to heap tree. */ /***********************************************************************************/ - USER_PROCESS::USER_HEAP_TREE* sched_try_go_upper_heap_tree(USER_PROCESS::USER_HEAP_TREE* tree) + STATIC USER_PROCESS::USER_HEAP_TREE* sched_try_go_upper_heap_tree(USER_PROCESS::USER_HEAP_TREE* tree) { if (tree) { @@ -175,7 +175,8 @@ namespace Kernel if (entry->MemoryNext) { - entry = entry->MemoryNext; + is_parent = NO; + entry = entry->MemoryNext; } else if (entry->MemoryChild) { @@ -190,24 +191,24 @@ namespace Kernel } if (!entry) - entry = new USER_HEAP_TREE(); + entry = new USER_HEAP_TREE(); - entry->MemoryEntry = ptr; - entry->MemoryEntrySize = sz; - entry->MemoryEntryPad = pad_amount; + entry->MemoryEntry = ptr; + entry->MemoryEntrySize = sz; + entry->MemoryEntryPad = pad_amount; if (is_parent) { - entry->MemoryParent = prev_entry; - prev_entry->MemoryChild = entry; + entry->MemoryParent = prev_entry; + prev_entry->MemoryChild = entry; prev_entry->MemoryColor = USER_HEAP_TREE::kBlackMemory; - entry->MemoryColor = USER_HEAP_TREE::kRedMemory; + entry->MemoryColor = USER_HEAP_TREE::kRedMemory; } else { prev_entry->MemoryNext = entry; - entry->MemoryPrev = prev_entry; + entry->MemoryPrev = prev_entry; } } @@ -252,26 +253,11 @@ namespace Kernel } /***********************************************************************************/ - /** - @brief Exit process method. - @param exit_code The process's exit code. - */ + /** @brief Free heap tree. */ /***********************************************************************************/ - Void USER_PROCESS::Exit(const Int32& exit_code) + STATIC Void sched_free_heap_tree(USER_PROCESS::USER_HEAP_TREE* memory_heap_list) { - this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen; - this->fLastExitCode = exit_code; - - kLastExitCode = exit_code; - - auto memory_heap_list = this->HeapTree; - -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto pd = hal_read_cr3(); - hal_write_cr3(this->VMRegister); -#endif - // Deleting memory lists. Make sure to free all of them. while (memory_heap_list) { @@ -288,8 +274,35 @@ namespace Kernel mm_delete_heap(memory_heap_list); + if (memory_heap_list->MemoryChild) + sched_free_heap_tree(memory_heap_list->MemoryChild); + memory_heap_list = 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->fLastExitCode = exit_code; + + kLastExitCode = exit_code; + + auto memory_heap_list = this->HeapTree; + +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + auto pd = hal_read_cr3(); + hal_write_cr3(this->VMRegister); +#endif + + sched_free_heap_tree(memory_heap_list); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ //! Free the memory's page directory. -- cgit v1.2.3 From 2a34afdf04a5ec24d091469fa50a09882c898881 Mon Sep 17 00:00:00 2001 From: Amlal Date: Thu, 24 Apr 2025 20:20:09 +0200 Subject: dev, kernel: scheduler: fix compiler error. Signed-off-by: Amlal --- dev/kernel/src/UserProcessScheduler.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index aaf0d699..fb33e447 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -266,10 +266,6 @@ namespace Kernel MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry)); } -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - hal_write_cr3(pd); -#endif - auto next = memory_heap_list->MemoryNext; mm_delete_heap(memory_heap_list); @@ -304,6 +300,10 @@ namespace Kernel sched_free_heap_tree(memory_heap_list); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + hal_write_cr3(pd); +#endif + #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ //! Free the memory's page directory. if (this->VMRegister) -- cgit v1.2.3 From 97f5407670a796ba41e107175f8242abba0c81cc Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 25 Apr 2025 08:37:12 +0200 Subject: dev, boot, kernel: improvements, and fixing the VEPM formatter. Signed-off-by: Amlal --- dev/boot/BootKit/BootKit.h | 207 ++++++--------------- dev/boot/BootKit/HW/ATA.h | 2 - dev/boot/modules/SysChk/SysChk.cc | 17 +- dev/boot/modules/SysChk/amd64-pio-epm.json | 10 +- dev/boot/src/BootThread.cc | 16 +- dev/kernel/FSKit/NeFS.h | 2 +- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 52 +++--- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 2 +- dev/kernel/HALKit/AMD64/HalKernelPanic.cc | 10 +- dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc | 16 +- dev/kernel/HALKit/AMD64/PCI/DMA.cc | 4 +- dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 2 +- dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 2 +- dev/kernel/HALKit/ARM64/HalKernelPanic.cc | 4 +- dev/kernel/HALKit/POWER/AP.h | 4 +- dev/kernel/HALKit/POWER/HalAP.cc | 40 ---- dev/kernel/HALKit/POWER/HalApplicationProcessor.cc | 41 ++++ dev/kernel/HALKit/POWER/HalHardwareThread.cc | 8 + dev/kernel/HALKit/POWER/HalThread.cc | 8 - dev/kernel/HALKit/RISCV/AP.h | 4 +- dev/kernel/HALKit/RISCV/HalAP.cc | 40 ---- dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc | 45 +++++ dev/kernel/src/ACPIFactoryInterface.cc | 16 +- dev/kernel/src/BitMapMgr.cc | 18 +- dev/kernel/src/CxxAbi-AMD64.cc | 6 +- dev/kernel/src/CxxAbi-ARM64.cc | 4 +- dev/kernel/src/FS/NeFS.cc | 52 +++--- dev/kernel/src/IndexableProperty.cc | 2 +- dev/kernel/src/MemoryMgr.cc | 6 +- dev/kernel/src/UserProcessScheduler.cc | 8 +- modules_pio_x64.sh | 2 +- 31 files changed, 277 insertions(+), 373 deletions(-) delete mode 100644 dev/kernel/HALKit/POWER/HalAP.cc create mode 100644 dev/kernel/HALKit/POWER/HalApplicationProcessor.cc create mode 100644 dev/kernel/HALKit/POWER/HalHardwareThread.cc delete mode 100644 dev/kernel/HALKit/POWER/HalThread.cc delete mode 100644 dev/kernel/HALKit/RISCV/HalAP.cc create mode 100644 dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc (limited to 'dev/kernel/src') diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 6299e27b..7b2a4f0a 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -32,6 +32,9 @@ #include #include +#define kBKBootFileMime "boot-x/file" +#define kBKBootDirMime "boot-x/dir" + /***********************************************************************************/ /// Framebuffer helpers. /***********************************************************************************/ @@ -184,15 +187,6 @@ namespace Boot #endif // __EFI_x86_64__ - static inline const UInt32 kRgbRed = 0x000000FF; - static inline const UInt32 kRgbGreen = 0x0000FF00; - static inline const UInt32 kRgbBlue = 0x00FF0000; - static inline const UInt32 kRgbBlack = 0x00000000; - static inline const UInt32 kRgbWhite = 0x00FFFFFF; - -#define kBKBootFileMime "boot-x/file" -#define kBKBootDirMime "boot-x/dir" - /// @brief BootKit Drive Formatter. template class BDiskFormatFactory final @@ -207,11 +201,6 @@ namespace Boot public: explicit BDiskFormatFactory() = default; - explicit BDiskFormatFactory(BootDev dev) - : fDiskDev(dev) - { - } - ~BDiskFormatFactory() = default; NE_COPY_DELETE(BDiskFormatFactory) @@ -222,18 +211,35 @@ namespace Boot /// @param blob_sz blobs array count. /// @retval True disk has been formatted. /// @retval False failed to format. - Boolean Format(const Char* part_name, BFileDescriptor* blob, SizeT blob_sz); + Boolean Format(const Char* part_name); /// @brief check if partition is good. Bool IsPartitionValid() noexcept { #if defined(BOOTZ_EPM_SUPPORT) + fDiskDev.Leak().mBase = (kEPMBootBlockLba); + fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); + + EPM_PART_BLOCK buf_epm = {}; + + fDiskDev.Read((Char*)&buf_epm, sizeof(EPM_PART_BLOCK)); + + if (StrCmp(buf_epm.Magic, kEPMMagic)) + { + return false; + } + + if (buf_epm.Version != kEPMRevisionBcd) + { + return false; + } + fDiskDev.Leak().mBase = (kNeFSRootCatalogStartAddress); - fDiskDev.Leak().mSize = BootDev::kSectorSize; + fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - Char buf[BootDev::kSectorSize] = {0}; + Char buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - fDiskDev.Read(buf, BootDev::kSectorSize); + fDiskDev.Read(buf, sizeof(NEFS_ROOT_PARTITION_BLOCK)); NEFS_ROOT_PARTITION_BLOCK* blockPart = reinterpret_cast(buf); @@ -258,55 +264,29 @@ namespace Boot return false; } - writer.Write(L"BootZ: Partition: ").Write(blockPart->PartitionName).Write(L" is healthy.\r"); + writer.Write(L"BootZ: NeFS Partition: ").Write(blockPart->PartitionName).Write(L" is healthy.\r"); return true; #else - return false; -#endif - } + GPT_PARTITION_TABLE gpt_part{}; - private: - /// @brief Write all of the requested catalogs into the filesystem. - /// @param blob the blobs. - /// @param blob_sz the number of blobs to write (n * sizeof(blob_struct)). - /// @param part the NeFS partition block. - Boolean WriteCatalogList(BFileDescriptor* blob, SizeT blob_sz, NEFS_ROOT_PARTITION_BLOCK& part) - { - if (blob_sz < sizeof(NEFS_CATALOG_STRUCT)) - return NO; + fDiskDev.Leak().mBase = (kGPTPartitionTableLBA); + fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE); - if (!blob) - return NO; + fDiskDev.Read((Char*)&gpt_part, sizeof(GPT_PARTITION_TABLE)); - Lba startLba = part.StartCatalog; BootTextWriter writer; - NEFS_CATALOG_STRUCT catalogKind{0}; - - constexpr auto cNeFSCatalogPadding = 4; - - catalogKind.PrevSibling = startLba; - catalogKind.NextSibling = (startLba + sizeof(NEFS_CATALOG_STRUCT) * cNeFSCatalogPadding); - - /// Fill catalog kind. - catalogKind.Kind = blob->fKind; - catalogKind.Flags |= kNeFSFlagCreated; - catalogKind.CatalogFlags = kNeFSStatusUnlocked; - - --part.FreeCatalog; - --part.FreeSectors; - - CopyMem(catalogKind.Name, blob->fFileName, StrLen(blob->fFileName)); - - fDiskDev.Leak().mBase = startLba; - fDiskDev.Leak().mSize = sizeof(NEFS_CATALOG_STRUCT); - - fDiskDev.Write((Char*)&catalogKind, sizeof(NEFS_CATALOG_STRUCT)); + if (StrCmp(gpt_part.Signature, kMagicGPT) == 0) + { + writer.Write("BootZ: GPT Partition found.\r"); + return true; + } - writer.Write(L"BootZ: wrote root directory: ").Write(blob->fFileName).Write(L"\r"); + writer.Write("BootZ: No Partition found.\r"); - return true; + return false; +#endif } private: @@ -320,13 +300,9 @@ namespace Boot /// @retval True disk has been formatted. /// @retval False failed to format. template - inline Boolean BDiskFormatFactory::Format(const Char* part_name, - BDiskFormatFactory::BFileDescriptor* blob, - SizeT blob_sz) + inline Boolean BDiskFormatFactory::Format(const Char* part_name) { - if (!blob || !blob_sz) - return false; /// sanity check - +#if defined(BOOTZ_EPM_SUPPORT) /// @note A catalog roughly equal to a sector in NeFS terms. constexpr auto kMinimumDiskSize = kNeFSMinimumDiskSize; // at minimum. @@ -344,7 +320,7 @@ namespace Boot CopyMem(part.PartitionName, part_name, StrLen(part_name)); part.Version = kNeFSVersionInteger; - part.CatalogCount = blob_sz / sizeof(NEFS_CATALOG_STRUCT); + part.CatalogCount = blob_sz; part.Kind = BootDev::kSectorSize; part.SectorSize = kATASectorSize; part.FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NEFS_CATALOG_STRUCT); @@ -363,7 +339,6 @@ namespace Boot writer << "BootZ: Free sectors: " << part.FreeSectors << "\r"; writer << "BootZ: Sector size: " << part.SectorSize << "\r"; -#if defined(BOOTZ_EPM_SUPPORT) EPM_PART_BLOCK epm_boot{}; const auto kFsName = "NeFS"; @@ -393,38 +368,36 @@ namespace Boot fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); writer.Write(L"BootZ: Drive is EPM formatted.\r"); -#elif defined(BOOTZ_GPT_SUPPORT) || defined(BOOTZ_VEPM_SUPPORT) +#elif defined(BOOTZ_VEPM_SUPPORT) + NE_UNUSED(part_name); + GPT_PARTITION_TABLE gpt_part{}; CopyMem(gpt_part.Signature, reinterpret_cast(const_cast(kMagicGPT)), StrLen(kMagicGPT)); - gpt_part.Revision = 0x00010000; + gpt_part.Revision = 0x00010000; gpt_part.HeaderSize = sizeof(GPT_PARTITION_TABLE); gpt_part.CRC32 = 0x00000000; - gpt_part.Reserved1 = 0x00000000; - gpt_part.LBAHeader = 0x00000000; - gpt_part.LBAAltHeader = 0x00000000; + gpt_part.Reserved1 = 0x00000000; + gpt_part.LBAHeader = 0x00000000; + gpt_part.LBAAltHeader = 0x00000000; gpt_part.FirstGPTEntry = 0x00000000; - gpt_part.LastGPTEntry = 0x00000000; + gpt_part.LastGPTEntry = 0x00000000; -#if defined(BOOTZ_GPT_SUPPORT) gpt_part.Guid.Data1 = 0x00000000; gpt_part.Guid.Data2 = 0x0000; gpt_part.Guid.Data3 = 0x0000; SetMem(gpt_part.Guid.Data4, 0, 8); -#else - gpt_part.Guid = kVEPMGuidEFI; -#endif gpt_part.Revision = 0x00010000; - gpt_part.StartingLBA = 0x00000000; + gpt_part.StartingLBA = 0x00000000; gpt_part.NumPartitionEntries = 0x00000000; - gpt_part.SizeOfEntries = 0x00000000; - gpt_part.CRC32PartEntry = 0x00000000; + gpt_part.SizeOfEntries = 0x00000000; + gpt_part.CRC32PartEntry = 0x00000000; SetMem(gpt_part.Reserved2, 0, kSectorAlignGPT_PartTbl); @@ -433,84 +406,8 @@ namespace Boot fDiskDev.Write((Char*)&gpt_part, sizeof(GPT_PARTITION_TABLE)); -#if defined(BOOTZ_VEPM_SUPPORT) - const auto kBlockName = "OS (VEPM)"; - - GPT_PARTITION_ENTRY gpt_part_entry{}; - - gpt_part_entry.StartLBA = kNeFSRootCatalogStartAddress; - gpt_part_entry.EndLBA = fDiskDev.GetDiskSize(); - gpt_part_entry.Attributes = 0x00000000; - - gpt_part_entry.PartitionTypeGUID.Data1 = 0x00000000; - gpt_part_entry.PartitionTypeGUID.Data2 = 0x0000; - gpt_part_entry.PartitionTypeGUID.Data3 = 0x0000; - - CopyMem(gpt_part_entry.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); - - SetMem(gpt_part_entry.PartitionTypeGUID.Data4, 0, 8); - - EPM_PART_BLOCK epm_boot{}; - - const auto kFsName = "NeFS"; - - epm_boot.FsVersion = kNeFSVersionInteger; - epm_boot.LbaStart = kNeFSRootCatalogStartAddress; - epm_boot.LbaEnd = fDiskDev.GetDiskSize(); - epm_boot.SectorSz = part.SectorSize; - epm_boot.Kind = kEPMNeKernel; - epm_boot.NumBlocks = part.CatalogCount; - - epm_boot.Guid = kEPMNilGuid; - - CopyMem(epm_boot.Fs, reinterpret_cast(const_cast(kFsName)), StrLen(kFsName)); - CopyMem(epm_boot.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); - CopyMem(epm_boot.Magic, reinterpret_cast(const_cast(kEPMMagic)), StrLen(kEPMMagic)); - - fDiskDev.Leak().mBase = kGPTPartitionTableLBA + sizeof(GPT_PARTITION_TABLE); - fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_ENTRY); - - fDiskDev.Write((Char*)&gpt_part_entry, sizeof(GPT_PARTITION_ENTRY)); - - fDiskDev.Leak().mBase = gpt_part_entry.StartLBA; - fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); - - fDiskDev.Write((Char*)&epm_boot, sizeof(EPM_PART_BLOCK)); - - fDiskDev.Leak().mBase = gpt_part_entry.StartLBA + kNeFSRootCatalogStartAddress; - fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - - fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); - - writer.Write(L"BootZ: Drive is vEPM formatted.\r"); -#else - const auto kBlockName = "OS (GPT)"; - - GPT_PARTITION_ENTRY gpt_part_entry{0}; - - gpt_part_entry.StartLBA = kNeFSRootCatalogStartAddress; - gpt_part_entry.EndLBA = fDiskDev.GetDiskSize(); - gpt_part_entry.Attributes = 0x00000000; - - gpt_part_entry.PartitionTypeGUID.Data1 = 0x00000000; - gpt_part_entry.PartitionTypeGUID.Data2 = 0x0000; - gpt_part_entry.PartitionTypeGUID.Data3 = 0x0000; - - CopyMem(gpt_part_entry.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); - - SetMem(gpt_part_entry.PartitionTypeGUID.Data4, 0, 8); - - fDiskDev.Leak().mBase = kGPTPartitionTableLBA + sizeof(GPT_PARTITION_TABLE); - fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_ENTRY); - fDiskDev.Write((Char*)&gpt_part_entry, sizeof(GPT_PARTITION_ENTRY)); - - fDiskDev.Leak().mBase = gpt_part_entry.StartLBA; - fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - - fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); - + BootTextWriter writer; writer.Write(L"BootZ: Drive is GPT formatted.\r"); -#endif /// defined(BOOTZ_VEPM_SUPPORT) #endif return YES; diff --git a/dev/boot/BootKit/HW/ATA.h b/dev/boot/BootKit/HW/ATA.h index cc5e1166..56393125 100644 --- a/dev/boot/BootKit/HW/ATA.h +++ b/dev/boot/BootKit/HW/ATA.h @@ -23,8 +23,6 @@ public: explicit BootDeviceATA() noexcept; ~BootDeviceATA() = default; - NE_COPY_DELETE(BootDeviceATA) - enum { kSectorSize = kATASectorSize diff --git a/dev/boot/modules/SysChk/SysChk.cc b/dev/boot/modules/SysChk/SysChk.cc index 16684666..032c031d 100644 --- a/dev/boot/modules/SysChk/SysChk.cc +++ b/dev/boot/modules/SysChk/SysChk.cc @@ -28,29 +28,18 @@ EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) { - NE_UNUSED(handover); - #if defined(__ATA_PIO__) fw_init_efi((EfiSystemTable*)handover->f_FirmwareCustomTables[1]); Boot::BDiskFormatFactory partition_factory; - if (partition_factory.IsPartitionValid()) - return kEfiFail; - - Boot::BDiskFormatFactory::BFileDescriptor desc{}; - - desc.fFileName[0] = '/'; - desc.fFileName[1] = 0; - desc.fKind = kNeFSCatalogKindDir; - - partition_factory.Format(kMachineModel, &desc, 1); - if (partition_factory.IsPartitionValid()) return kEfiOk; - return kEfiFail; + return partition_factory.Format(kMachineModel) == YES; #else + NE_UNUSED(handover); + return kEfiOk; #endif } diff --git a/dev/boot/modules/SysChk/amd64-pio-epm.json b/dev/boot/modules/SysChk/amd64-pio-epm.json index ccbb7d04..14a804d0 100644 --- a/dev/boot/modules/SysChk/amd64-pio-epm.json +++ b/dev/boot/modules/SysChk/amd64-pio-epm.json @@ -1,7 +1,13 @@ { "compiler_path": "x86_64-w64-mingw32-g++", "compiler_std": "c++20", - "headers_path": ["../", "../../", "../../../kernel", "../../../", "./"], + "headers_path": [ + "../", + "../../", + "../../../kernel", + "../../../", + "./" + ], "sources_path": [ "*.cc", "*.S", @@ -31,4 +37,4 @@ "kChkVersionLowest=0x0100", "kChkVersion=0x0100" ] -} +} \ No newline at end of file diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index efbacc32..b6236df8 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -190,22 +190,22 @@ namespace Boot if (own_stack) { - writer.Write("BootZ: Using own stack.\r"); + writer.Write("BootZ: Using it's own stack.\r"); writer.Write("BootZ: Stack address: ").Write((UIntPtr)&fStack[mib_cast(16) - 1]).Write("\r"); writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); + + // we don't need the stack anymore. + + delete[] fStack; + fStack = nullptr; + return ret; } else { - delete[] fStack; - fStack = nullptr; - // we don't need the stack anymore. - - BootTextWriter writer; - - writer.Write("BootZ: Using EFI stack.\r"); + writer.Write("BootZ: Using Bootloader's stack.\r"); return reinterpret_cast(fStartAddress)(fHandover); } diff --git a/dev/kernel/FSKit/NeFS.h b/dev/kernel/FSKit/NeFS.h index b6f92bc9..6b1849ff 100644 --- a/dev/kernel/FSKit/NeFS.h +++ b/dev/kernel/FSKit/NeFS.h @@ -432,7 +432,7 @@ namespace Kernel if (!parser->CreateFork(new_fork)) return NO; - (void)(kout << "XML commit: " << xml_data << " to fork: " << journal_name << kendl); + (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); diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 1f865057..fc50380a 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -36,15 +36,17 @@ namespace Kernel::HAL { - struct PROCESS_APIC_MADT; - struct PROCESS_CONTROL_BLOCK; + struct HAL_APIC_MADT; + struct HAL_HARDWARE_THREAD; - struct PROCESS_CONTROL_BLOCK final + struct HAL_HARDWARE_THREAD final { - HAL::StackFramePtr mFrame; + HAL::StackFramePtr mFramePtr; + ProcessID mProcessID{0}; + UInt8 mCoreID{0}; }; - STATIC PROCESS_APIC_MADT* kMADTBlock = nullptr; + STATIC HAL_APIC_MADT* kMADTBlock = nullptr; STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; @@ -55,7 +57,7 @@ namespace Kernel::HAL STATIC VoidPtr kRawMADT = nullptr; /// @brief Multiple APIC Descriptor Table. - struct PROCESS_APIC_MADT final SDT_OBJECT + struct HAL_APIC_MADT final SDT_OBJECT { UInt32 Address; // Madt address UInt8 Flags; // Madt flags @@ -65,8 +67,8 @@ namespace Kernel::HAL UInt8 Type; UInt8 Len; - union { - struct + union APIC { + struct IOAPIC { UInt8 IoID; UInt8 Zero; @@ -74,7 +76,7 @@ namespace Kernel::HAL UInt32 GISBase; } IOAPIC; - struct + struct LAPIC_NMI { UInt8 Source; UInt8 IRQSource; @@ -82,27 +84,27 @@ namespace Kernel::HAL UInt16 Flags; } LApicNMI; - struct + struct LAPIC { UInt8 ProcessorID; UInt16 Flags; UInt8 LINT; } LAPIC; - struct + struct LAPIC_OVERRIDE { UInt16 Reserved; UInt64 Address; } LApicOverride; - struct + struct LAPIC_X2 { UInt16 Reserved; UInt32 x2APICID; UInt32 Flags; UInt32 AcpiID; - } LApic; - }; + } LocalApicX2; + } Apic; } List[1]; // Records List }; @@ -145,12 +147,13 @@ namespace Kernel::HAL } } - STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; + STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) { const auto process_index = pid % kSchedProcessLimitPerTeam; - return kProcessBlocks[process_index].mFrame; + + return kHWThread[process_index].mFramePtr; } EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) @@ -159,11 +162,12 @@ namespace Kernel::HAL const auto process_index = pid % kSchedProcessLimitPerTeam; - kProcessBlocks[process_index].mFrame = stack_frame; + kHWThread[process_index].mFramePtr = stack_frame; + kHWThread[process_index].mProcessID = pid; - auto first_id = kAPICLocales[0]; + kHWThread[process_index].mCoreID = kAPICLocales[0]; - hal_send_sipi(kApicBaseAddress, first_id, (UInt8)(((UIntPtr)stack_frame->BP) >> 12)); + hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID, (UInt8)(((UIntPtr)stack_frame->BP) >> 12)); return YES; } @@ -205,7 +209,7 @@ namespace Kernel::HAL auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak(); - kMADTBlock = reinterpret_cast(kRawMADT); + kMADTBlock = reinterpret_cast(kRawMADT); kSMPAware = NO; if (kMADTBlock) @@ -229,11 +233,11 @@ namespace Kernel::HAL switch (kMADTBlock->List[index].Type) { case 0x00: { - if (kMADTBlock->List[kSMPCount].LAPIC.ProcessorID < 1) + if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) break; - kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID; - (void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); + kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID; + (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); ++kSMPCount; break; @@ -245,7 +249,7 @@ namespace Kernel::HAL ++index; } - (void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl); + (Void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl); // Kernel is now SMP aware. // That means that the scheduler is now available (on MP Kernels) diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 7dce21d1..4c873554 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -148,7 +148,7 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) kIsScheduling = NO; - (void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); + (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); Kernel::kout << "Kernel: SIGTRAP\r"; process.Leak().Signal.SignalArg = rip; diff --git a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc index 2641f058..9c8a235a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc @@ -33,9 +33,9 @@ namespace Kernel /***********************************************************************************/ Void ke_panic(const Kernel::Int32& id, const Char* message) { - (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); + (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(); } @@ -52,8 +52,8 @@ namespace Kernel { if (!expr) { - (void)(kout << "Kernel_Panic_File: " << file << kendl); - (void)(kout << "Kernel_Panic_Line: " << line << kendl); + (Void)(kout << "Kernel_Panic_File: " << file << kendl); + (Void)(kout << "Kernel_Panic_Line: " << line << kendl); ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed } diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc index c6c24be1..08caed82 100644 --- a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc @@ -41,14 +41,14 @@ namespace Kernel::HAL /***********************************************************************************/ STATIC Void mmi_page_status(Detail::PTE* pte) { - (void)(kout << (pte->Present ? "Present" : "Not Present") << kendl); - (void)(kout << (pte->Wr ? "W/R" : "Not W/R") << kendl); - (void)(kout << (pte->Nx ? "NX" : "Not NX") << kendl); - (void)(kout << (pte->User ? "User" : "Not User") << kendl); - (void)(kout << (pte->Pcd ? "Not Cached" : "Cached") << kendl); - (void)(kout << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); - (void)(kout << hex_number(pte->PhysicalAddress) << kendl); - (void)(kout << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") << kendl); + (Void)(kout << (pte->Present ? "Present" : "Not Present") << kendl); + (Void)(kout << (pte->Wr ? "W/R" : "Not W/R") << kendl); + (Void)(kout << (pte->Nx ? "NX" : "Not NX") << kendl); + (Void)(kout << (pte->User ? "User" : "Not User") << kendl); + (Void)(kout << (pte->Pcd ? "Not Cached" : "Cached") << kendl); + (Void)(kout << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); + (Void)(kout << hex_number(pte->PhysicalAddress) << kendl); + (Void)(kout << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") << kendl); } /***********************************************************************************/ diff --git a/dev/kernel/HALKit/AMD64/PCI/DMA.cc b/dev/kernel/HALKit/AMD64/PCI/DMA.cc index 4a63625e..b16039d4 100644 --- a/dev/kernel/HALKit/AMD64/PCI/DMA.cc +++ b/dev/kernel/HALKit/AMD64/PCI/DMA.cc @@ -38,7 +38,7 @@ namespace Kernel if (!this->fAddress) return false; - (void)(kout << "[DMAWrapper::Write] Writing at address: " << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); + (Void)(kout << "[DMAWrapper::Write] Writing at address: " << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); ke_dma_write(reinterpret_cast(this->fAddress), offset, bit); @@ -52,7 +52,7 @@ namespace Kernel if (!this->fAddress) return ~0; - (void)(kout << "[DMAWrapper::Write] Writing at address: " << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); + (Void)(kout << "[DMAWrapper::Write] Writing at address: " << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); return (UIntPtr)ke_dma_read(reinterpret_cast(this->fAddress), offset); } diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc index 257dd5c8..cd25ab7f 100644 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc @@ -108,7 +108,7 @@ ATAInit_Retry: kATADiskModel[40] = '\0'; - (void)(kout << "Drive Model: " << kATADiskModel << kendl); + (Void)(kout << "Drive Model: " << kATADiskModel << kendl); return true; } diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 1553b2ed..7d985a44 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -93,7 +93,7 @@ namespace Kernel const UInt16 kInterruptScheduler = 0x20; - (void)(kout << "Handling interrupt for AP: " << interrupt << kendl); + (Void)(kout << "Handling interrupt for AP: " << interrupt << kendl); switch (interrupt) { diff --git a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc index 1c88ccc6..ad966991 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc @@ -71,8 +71,8 @@ namespace Kernel { if (!expr) { - (void)(kout << "FAILED: FILE: " << file << kendl); - (void)(kout << "FAILED: LINE: " << line << kendl); + (Void)(kout << "FAILED: FILE: " << file << kendl); + (Void)(kout << "FAILED: LINE: " << line << kendl); ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed } diff --git a/dev/kernel/HALKit/POWER/AP.h b/dev/kernel/HALKit/POWER/AP.h index c990b950..4558804b 100644 --- a/dev/kernel/HALKit/POWER/AP.h +++ b/dev/kernel/HALKit/POWER/AP.h @@ -26,7 +26,9 @@ namespace Kernel typedef struct HAL_HARDWARE_THREAD { Kernel::UIntPtr fStartAddress; - Kernel::UInt8 fPrivleged : 1; + Kernel::UIntPtr fStackPtr; + Kernel::UIntPtr fFramePtr; + Kernel::UInt8 fPrivileged : 1; Kernel::UInt32 fPageMemoryFlags; hal_ap_kind fIdentNumber; } HAL_HARDWARE_THREAD; diff --git a/dev/kernel/HALKit/POWER/HalAP.cc b/dev/kernel/HALKit/POWER/HalAP.cc deleted file mode 100644 index 781b34a6..00000000 --- a/dev/kernel/HALKit/POWER/HalAP.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -namespace Kernel::Detail -{ - STATIC void mp_hang_fn(void) - { - while (YES) - ; - } -} // namespace Kernel::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(stack->R15), reinterpret_cast(stack->BP)); -} - -/// @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(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); -} diff --git a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc new file mode 100644 index 00000000..ca2153e3 --- /dev/null +++ b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc @@ -0,0 +1,41 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +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; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); + } + + /// @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(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); + } +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/HALKit/POWER/HalHardwareThread.cc b/dev/kernel/HALKit/POWER/HalHardwareThread.cc new file mode 100644 index 00000000..40bb7d8a --- /dev/null +++ b/dev/kernel/HALKit/POWER/HalHardwareThread.cc @@ -0,0 +1,8 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include +#include diff --git a/dev/kernel/HALKit/POWER/HalThread.cc b/dev/kernel/HALKit/POWER/HalThread.cc deleted file mode 100644 index 40bb7d8a..00000000 --- a/dev/kernel/HALKit/POWER/HalThread.cc +++ /dev/null @@ -1,8 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#include -#include diff --git a/dev/kernel/HALKit/RISCV/AP.h b/dev/kernel/HALKit/RISCV/AP.h index 0a8546e9..e55e3462 100644 --- a/dev/kernel/HALKit/RISCV/AP.h +++ b/dev/kernel/HALKit/RISCV/AP.h @@ -22,7 +22,9 @@ namespace Kernel typedef struct HAL_HARDWARE_THREAD { Kernel::UIntPtr fStartAddress; - Kernel::UInt8 fPrivleged : 1; + Kernel::UIntPtr fStackPtr; + Kernel::UIntPtr fFramePtr; + Kernel::UInt8 fPrivileged : 1; Kernel::UInt32 fPageMemoryFlags; hal_ap_kind fIdentNumber; } HAL_HARDWARE_THREAD; diff --git a/dev/kernel/HALKit/RISCV/HalAP.cc b/dev/kernel/HALKit/RISCV/HalAP.cc deleted file mode 100644 index 72a3cf13..00000000 --- a/dev/kernel/HALKit/RISCV/HalAP.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -namespace Kernel::Detail -{ - STATIC void mp_hang_fn(void) - { - while (YES) - ; - } -} // namespace Kernel::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(stack->R15), reinterpret_cast(stack->BP)); -} - -/// @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(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); -} diff --git a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc new file mode 100644 index 00000000..1967a649 --- /dev/null +++ b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc @@ -0,0 +1,45 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +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(stack->R15), reinterpret_cast(stack->BP)); + } + + /// @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(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); + } + +} // namespace Kernel diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index b85d6ab3..9a3c30d0 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -43,10 +43,10 @@ namespace Kernel 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); + (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); const short cAcpiSignatureLength = 4; @@ -54,8 +54,8 @@ namespace Kernel { SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); - (void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); - (void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); + (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); + (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) { @@ -64,8 +64,8 @@ namespace Kernel if (signature_index == (cAcpiSignatureLength - 1)) { - (void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl); - (void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl); + (Void)(kout << "ACPI: SDT Signature: " << sdt->Signature << kendl); + (Void)(kout << "ACPI: SDT OEM ID: " << sdt->OemId << kendl); return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); } } diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc index 1a1e2c0d..83efe4eb 100644 --- a/dev/kernel/src/BitMapMgr.cc +++ b/dev/kernel/src/BitMapMgr.cc @@ -161,18 +161,18 @@ namespace Kernel { if (!this->IsBitMap(ptr_bit_set)) { - (void)(kout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << kendl); + (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); + (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 diff --git a/dev/kernel/src/CxxAbi-AMD64.cc b/dev/kernel/src/CxxAbi-AMD64.cc index 6bf5d009..950e0c02 100644 --- a/dev/kernel/src/CxxAbi-AMD64.cc +++ b/dev/kernel/src/CxxAbi-AMD64.cc @@ -19,13 +19,13 @@ Kernel::UIntPtr __dso_handle; EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) { - (void)(Kernel::kout << "object: " << Kernel::number(reinterpret_cast(self))); - (void)(Kernel::kout << ", has unimplemented virtual functions.\r"); + (Kernel::Void)(Kernel::kout << "object: " << Kernel::number(reinterpret_cast(self))); + (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); } EXTERN_C void ___chkstk_ms(void) { - (void)(Kernel::kout << "Stack smashing detected!\r"); + (Kernel::Void)(Kernel::kout << "Stack smashing detected!\r"); dbg_break_point(); } diff --git a/dev/kernel/src/CxxAbi-ARM64.cc b/dev/kernel/src/CxxAbi-ARM64.cc index 34dab83a..b3db3815 100644 --- a/dev/kernel/src/CxxAbi-ARM64.cc +++ b/dev/kernel/src/CxxAbi-ARM64.cc @@ -83,8 +83,8 @@ namespace cxxabiv1 EXTERN_C Kernel::Void _purecall(void* self) { - kout << "object: " << Kernel::number(reinterpret_cast(self)); - kout << ", has unimplemented virtual functions.\r"; + (Kernel::Void)(Kernel::kout << "object: " << Kernel::number(reinterpret_cast(self))); + (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); } EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) diff --git a/dev/kernel/src/FS/NeFS.cc b/dev/kernel/src/FS/NeFS.cc index e8e3804c..8ebd551f 100644 --- a/dev/kernel/src/FS/NeFS.cc +++ b/dev/kernel/src/FS/NeFS.cc @@ -73,7 +73,7 @@ _Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) Lba lba = catalog->DataFork; - (void)(kout << "Fork LBA: " << hex_number(lba) << kendl); + (Void)(kout << "Fork LBA: " << hex_number(lba) << kendl); if (lba < kNeFSCatalogStartAddress) return NO; @@ -94,7 +94,7 @@ _Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) drv.fInput(drv.fPacket); - (void)(kout << "Next fork: " << hex_number(cur_fork.NextSibling) << kendl); + (Void)(kout << "Next fork: " << hex_number(cur_fork.NextSibling) << kendl); if (cur_fork.Flags & kNeFSFlagCreated) { @@ -144,10 +144,10 @@ _Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) fs_ifs_write(&kMountpoint, drv, MountpointInterface::kDriveIndexA); /// log what we have now. - (void)(kout << "Fork offset is at: " << hex_number(the_fork.DataOffset) + (Void)(kout << "Fork offset is at: " << hex_number(the_fork.DataOffset) << kendl); - (void)(kout << "Wrote fork metadata at: " << hex_number(lba) << kendl); + (Void)(kout << "Wrote fork metadata at: " << hex_number(lba) << kendl); return YES; } @@ -461,7 +461,7 @@ _Output Bool NeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, _In NE_UNUSED(flags); NE_UNUSED(part_name); - (void)(kout << "FormatGPT: Not implemented yet.\r"); + (Void)(kout << "FormatGPT: Not implemented yet.\r"); return NO; } @@ -600,14 +600,14 @@ bool NeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, _Input cons drive->fOutput(drive->fPacket); - (void)(kout << "drive kind: " << drive->fProtocol() << kendl); + (Void)(kout << "drive kind: " << drive->fProtocol() << kendl); - (void)(kout << "partition name: " << part_block->PartitionName << kendl); - (void)(kout << "start: " << 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); + (Void)(kout << "partition name: " << part_block->PartitionName << kendl); + (Void)(kout << "start: " << 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); // write the root catalog. this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); @@ -666,7 +666,7 @@ bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_r NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT(); NEFS_FORK_STRUCT prev_fork{}; - (void)(kout << hex_number(startFork) << kendl); + (Void)(kout << hex_number(startFork) << kendl); // sanity check of the fork position as the condition to run the loop. while (startFork >= kNeFSCatalogStartAddress) @@ -677,13 +677,13 @@ bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_r drive.fInput(drive.fPacket); - (void)(kout << hex_number(fork_data_input->DataSize) << kendl); - (void)(kout << hex_number(size_of_data) << kendl); - (void)(kout << hex_number(fork_data_input->Flags) << kendl); - (void)(kout << fork_name << kendl); - (void)(kout << fork_data_input->ForkName << kendl); - (void)(kout << fork_data_input->CatalogName << kendl); - (void)(kout << catalog_name << kendl); + (Void)(kout << hex_number(fork_data_input->DataSize) << kendl); + (Void)(kout << hex_number(size_of_data) << kendl); + (Void)(kout << hex_number(fork_data_input->Flags) << kendl); + (Void)(kout << fork_name << kendl); + (Void)(kout << fork_data_input->ForkName << kendl); + (Void)(kout << fork_data_input->CatalogName << kendl); + (Void)(kout << catalog_name << kendl); if ((fork_data_input->Flags & kNeFSFlagCreated) && KStringBuilder::Equals(fork_data_input->ForkName, fork_name) && @@ -698,11 +698,11 @@ bool NeFileSystemParser::WriteCatalog(_Input const Char* catalog_name, Bool is_r drive.fPacket.fPacketSize = size_of_data; drive.fPacket.fPacketLba = fork_data_input->DataOffset; - (void)(kout << "data offset: " << hex_number(fork_data_input->DataOffset) << kendl); + (Void)(kout << "data offset: " << hex_number(fork_data_input->DataOffset) << kendl); drive.fOutput(drive.fPacket); - (void)(kout << "wrote data at offset: " << hex_number(fork_data_input->DataOffset) << kendl); + (Void)(kout << "wrote data at offset: " << hex_number(fork_data_input->DataOffset) << kendl); delete fork_data_input; delete[] buf; @@ -841,8 +841,8 @@ kNeFSSearchThroughCatalogList: goto NeFSContinueSearch; } - (void)(kout << "Found available catalog at: " << hex_number(start_catalog_lba) << kendl); - (void)(kout << "Found available catalog at: " << temporary_catalog.Name << kendl); + (Void)(kout << "Found available catalog at: " << hex_number(start_catalog_lba) << kendl); + (Void)(kout << "Found available catalog at: " << temporary_catalog.Name << kendl); NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT(); rt_copy_memory(&temporary_catalog, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT)); @@ -998,8 +998,8 @@ VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* cata fs_fork_data = fs_buf; - (void)(kout << "ForkName: " << fs_fork_data->ForkName << kendl); - (void)(kout << "CatalogName: " << fs_fork_data->CatalogName << kendl); + (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)) diff --git a/dev/kernel/src/IndexableProperty.cc b/dev/kernel/src/IndexableProperty.cc index d586398d..05440ee9 100644 --- a/dev/kernel/src/IndexableProperty.cc +++ b/dev/kernel/src/IndexableProperty.cc @@ -50,7 +50,7 @@ namespace Kernel indexer.AddFlag(kIndexerClaimed); rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen); - (void)(kout << "FSKit: Indexed new file: " << filename << kendl); + (Void)(kout << "FSKit: Indexed new file: " << filename << kendl); } } } // namespace Indexer diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc index eff54435..2f70d85f 100644 --- a/dev/kernel/src/MemoryMgr.cc +++ b/dev/kernel/src/MemoryMgr.cc @@ -150,7 +150,7 @@ namespace Kernel auto result = reinterpret_cast(heap_info_ptr->fOffset); - (void)(kout << "Registered heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); + (Void)(kout << "Registered heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); return result; } @@ -172,7 +172,7 @@ namespace Kernel heap_info_ptr->fPage = true; - (void)(kout << "Registered page address: " << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); + (Void)(kout << "Registered page address: " << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); return kErrorSuccess; } @@ -239,7 +239,7 @@ namespace Kernel heap_info_ptr->fMagic = 0; heap_info_ptr->fPad = 0; - (void)(kout << "Address has been successfully freed: " << hex_number((UIntPtr)heap_info_ptr) << kendl); + (Void)(kout << "Address has been successfully freed: " << hex_number((UIntPtr)heap_info_ptr) << kendl); PTEWrapper page_wrapper(No, No, No, reinterpret_cast(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); Ref pte_address{page_wrapper}; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index fb33e447..d6be0f5f 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -60,7 +60,7 @@ namespace Kernel if (this->Status != ProcessStatusKind::kRunning) return; - (void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); + (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); this->Exit(-kErrorProcessFault); } @@ -439,7 +439,7 @@ namespace Kernel break; } default: { - (void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl); + (Void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl); break; } } @@ -468,8 +468,8 @@ namespace Kernel process.Status = ProcessStatusKind::kStarting; process.PTime = (UIntPtr)AffinityKind::kStandard; - (void)(kout << "PID: " << number(process.ProcessId) << kendl); - (void)(kout << "Name: " << process.Name << kendl); + (Void)(kout << "PID: " << number(process.ProcessId) << kendl); + (Void)(kout << "Name: " << process.Name << kendl); return pid; } diff --git a/modules_pio_x64.sh b/modules_pio_x64.sh index b091704e..49f0e667 100755 --- a/modules_pio_x64.sh +++ b/modules_pio_x64.sh @@ -5,7 +5,7 @@ # 04/05/25: Improve and fix script. cd dev/boot/modules/SysChk -btb amd64-pio-epm.json +btb amd64-pio-gpt.json cd ../ cd BootNet btb amd64.json \ No newline at end of file -- cgit v1.2.3 From fb790b07aeba8e22e4190cf3e1834d11ecde6c96 Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 25 Apr 2025 13:08:33 +0200 Subject: dev: better .clang-format, ran format command. Signed-off-by: Amlal --- .clang-format | 43 +- dev/boot/BootKit/BitManip.h | 14 +- dev/boot/BootKit/BootKit.h | 621 ++-- dev/boot/BootKit/BootThread.h | 66 +- dev/boot/BootKit/Device.h | 30 +- dev/boot/BootKit/EPM.h | 2 +- dev/boot/BootKit/HW/ATA.h | 61 +- dev/boot/BootKit/HW/SATA.h | 44 +- dev/boot/BootKit/Platform.h | 8 +- dev/boot/BootKit/Protocol.h | 2 +- dev/boot/BootKit/Qr.h | 1750 +++++------ dev/boot/BootKit/Shared/base.h | 32 +- dev/boot/BootKit/Shared/bit.h | 461 ++- dev/boot/BootKit/Support.h | 214 +- dev/boot/modules/BootNet/BootNet.cc | 147 +- dev/boot/modules/SysChk/SysChk.cc | 23 +- dev/boot/src/BootFileReader.cc | 293 +- dev/boot/src/BootString.cc | 97 +- dev/boot/src/BootSupport.cc | 67 +- dev/boot/src/BootTextWriter.cc | 214 +- dev/boot/src/BootThread.cc | 378 ++- dev/boot/src/HEL/AMD64/BootATA.cc | 288 +- dev/boot/src/HEL/AMD64/BootEFI.cc | 339 +- dev/boot/src/HEL/AMD64/BootPlatform.cc | 36 +- dev/boot/src/HEL/AMD64/BootSATA.cc | 4 +- dev/boot/src/HEL/ARM64/BootEFI.cc | 295 +- dev/boot/src/HEL/ARM64/BootPlatform.cc | 28 +- dev/boot/src/New+Delete.cc | 61 +- dev/ddk/DDKKit/ddk.h | 52 +- dev/ddk/DDKKit/dev.h | 21 +- dev/ddk/DDKKit/io.h | 4 +- dev/ddk/DDKKit/str.h | 6 +- dev/ddk/src/ddk_alloc.c | 32 +- dev/ddk/src/ddk_dev.c | 22 +- dev/ddk/src/ddk_io.c | 41 +- dev/ddk/src/ddk_kernel_call.c | 36 +- dev/ddk/src/ddk_rt_cxx.cc | 24 +- dev/ddk/src/ddk_str.c | 40 +- dev/ddk/src/ddk_ver.c | 12 +- dev/hint/CompilerHint.h | 4 +- dev/kernel/ArchKit/ArchKit.h | 108 +- dev/kernel/CFKit/GUIDWizard.h | 15 +- dev/kernel/CFKit/GUIDWrapper.h | 79 +- dev/kernel/CFKit/Property.h | 75 +- dev/kernel/CFKit/Utils.h | 90 +- dev/kernel/CompilerKit/CompilerKit.h | 2 +- dev/kernel/CompilerKit/Detail.h | 28 +- dev/kernel/CompilerKit/Version.h | 4 +- dev/kernel/FSKit/Defines.h | 4 +- dev/kernel/FSKit/Ext2.h | 206 +- dev/kernel/FSKit/HeFS.h | 620 ++-- dev/kernel/FSKit/IndexableProperty.h | 98 +- dev/kernel/FSKit/NeFS.h | 604 ++-- dev/kernel/FirmwareKit/CoreBoot/BootNet.h | 32 +- dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h | 36 +- dev/kernel/FirmwareKit/CoreBoot/NS.h | 6 +- dev/kernel/FirmwareKit/EFI.h | 2 +- dev/kernel/FirmwareKit/EFI/API.h | 112 +- dev/kernel/FirmwareKit/EFI/EFI.h | 1405 ++++----- dev/kernel/FirmwareKit/EFI/NS.h | 14 +- dev/kernel/FirmwareKit/EPM.h | 71 +- dev/kernel/FirmwareKit/GPT.h | 79 +- dev/kernel/FirmwareKit/Handover.h | 155 +- dev/kernel/FirmwareKit/VEPM.h | 20 +- dev/kernel/GfxKit/FB.h | 79 +- dev/kernel/HALKit/AMD64/CPUID.h | 147 +- dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc | 195 +- dev/kernel/HALKit/AMD64/HalAPICController.cc | 62 +- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 436 ++- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 265 +- dev/kernel/HALKit/AMD64/HalDebugOutput.cc | 267 +- dev/kernel/HALKit/AMD64/HalDebugPort.cc | 41 +- dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc | 155 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 204 +- dev/kernel/HALKit/AMD64/HalKernelPanic.cc | 87 +- dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc | 276 +- dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc | 155 +- .../AMD64/HalSchedulerCorePrimitivesAMD64.cc | 86 +- dev/kernel/HALKit/AMD64/HalTimerAMD64.cc | 114 +- dev/kernel/HALKit/AMD64/Hypervisor.h | 31 +- dev/kernel/HALKit/AMD64/PCI/DMA.cc | 105 +- dev/kernel/HALKit/AMD64/PCI/Database.cc | 6 +- dev/kernel/HALKit/AMD64/PCI/Device.cc | 285 +- dev/kernel/HALKit/AMD64/PCI/Express.cc | 6 +- dev/kernel/HALKit/AMD64/PCI/IO.cc | 2 +- dev/kernel/HALKit/AMD64/PCI/Iterator.cc | 49 +- dev/kernel/HALKit/AMD64/PCI/PCI.cc | 2 +- dev/kernel/HALKit/AMD64/Paging.h | 83 +- dev/kernel/HALKit/AMD64/Processor.h | 518 ++- dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 534 ++-- dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc | 200 +- dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 314 +- dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc | 6 +- dev/kernel/HALKit/ARM64/APM/APM+IO.cc | 40 +- dev/kernel/HALKit/ARM64/ApplicationProcessor.h | 9 +- dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc | 36 +- dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 191 +- dev/kernel/HALKit/ARM64/HalDebugOutput.cc | 118 +- dev/kernel/HALKit/ARM64/HalKernelMain.cc | 84 +- dev/kernel/HALKit/ARM64/HalKernelPanic.cc | 98 +- dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc | 143 +- dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc | 29 +- .../ARM64/HalSchedulerCorePrimitivesARM64.cc | 49 +- dev/kernel/HALKit/ARM64/HalTimerARM64.cc | 10 +- dev/kernel/HALKit/ARM64/Paging.h | 151 +- dev/kernel/HALKit/ARM64/Processor.h | 141 +- dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc | 6 +- dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc | 2 +- dev/kernel/HALKit/POWER/AP.h | 56 +- dev/kernel/HALKit/POWER/HalApplicationProcessor.cc | 60 +- dev/kernel/HALKit/POWER/HalDebugOutput.cc | 21 +- dev/kernel/HALKit/POWER/HalHardwareThread.cc | 2 +- dev/kernel/HALKit/POWER/HalVirtualMemory.cc | 51 +- dev/kernel/HALKit/POWER/Processor.h | 76 +- dev/kernel/HALKit/RISCV/AP.h | 48 +- dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc | 64 +- dev/kernel/KernelKit/BinaryMutex.h | 50 +- dev/kernel/KernelKit/CodeMgr.h | 61 +- dev/kernel/KernelKit/CoreProcessScheduler.h | 282 +- dev/kernel/KernelKit/DebugOutput.h | 268 +- dev/kernel/KernelKit/Defines.h | 4 +- dev/kernel/KernelKit/DeviceMgr.h | 207 +- dev/kernel/KernelKit/DriveMgr.h | 317 +- dev/kernel/KernelKit/FileMgr.h | 652 ++-- dev/kernel/KernelKit/HardwareThreadScheduler.h | 251 +- dev/kernel/KernelKit/IDylibObject.h | 60 +- dev/kernel/KernelKit/IPEFDylibObject.h | 156 +- dev/kernel/KernelKit/KPC.h | 101 +- dev/kernel/KernelKit/KernelProcessScheduler.h | 2 +- dev/kernel/KernelKit/LoaderInterface.h | 40 +- dev/kernel/KernelKit/LockDelegate.h | 109 +- dev/kernel/KernelKit/MSDOS.h | 51 +- dev/kernel/KernelKit/MemoryMgr.h | 140 +- dev/kernel/KernelKit/PCI/DMA.h | 125 +- dev/kernel/KernelKit/PCI/DMA.inl | 25 +- dev/kernel/KernelKit/PCI/Database.h | 77 +- dev/kernel/KernelKit/PCI/Device.h | 135 +- dev/kernel/KernelKit/PCI/Express.h | 4 +- dev/kernel/KernelKit/PCI/IO.h | 76 +- dev/kernel/KernelKit/PCI/IOArray+AMD64.inl | 77 +- dev/kernel/KernelKit/PCI/Iterator.h | 40 +- dev/kernel/KernelKit/PCI/PCI.h | 89 +- dev/kernel/KernelKit/PE.h | 191 +- dev/kernel/KernelKit/PECodeMgr.h | 98 +- dev/kernel/KernelKit/PEF.h | 153 +- dev/kernel/KernelKit/PEFCodeMgr.h | 103 +- dev/kernel/KernelKit/ProcessScheduler.h | 6 +- dev/kernel/KernelKit/Semaphore.h | 13 +- dev/kernel/KernelKit/ThreadLocalStorage.h | 9 +- dev/kernel/KernelKit/ThreadLocalStorage.inl | 74 +- dev/kernel/KernelKit/Timer.h | 138 +- dev/kernel/KernelKit/User.h | 95 +- dev/kernel/KernelKit/UserProcessScheduler.h | 472 ++- dev/kernel/KernelKit/UserProcessScheduler.inl | 72 +- dev/kernel/KernelKit/XCOFF.h | 46 +- dev/kernel/NetworkKit/IP.h | 137 +- dev/kernel/NetworkKit/IPC.h | 130 +- dev/kernel/NetworkKit/LTE.h | 8 +- dev/kernel/NetworkKit/MAC.h | 34 +- dev/kernel/NetworkKit/NetworkDevice.h | 101 +- dev/kernel/NetworkKit/NetworkDevice.inl | 37 +- dev/kernel/NewKit/Array.h | 73 +- dev/kernel/NewKit/ArrayList.h | 89 +- dev/kernel/NewKit/Atom.h | 64 +- dev/kernel/NewKit/Crc32.h | 9 +- dev/kernel/NewKit/CxxAbi.h | 18 +- dev/kernel/NewKit/Defines.h | 319 +- dev/kernel/NewKit/ErrorOr.h | 110 +- dev/kernel/NewKit/Function.h | 83 +- dev/kernel/NewKit/Json.h | 258 +- dev/kernel/NewKit/KString.h | 148 +- dev/kernel/NewKit/KernelPanic.h | 72 +- dev/kernel/NewKit/Macros.h | 70 +- dev/kernel/NewKit/MutableArray.h | 394 ++- dev/kernel/NewKit/New.h | 2 +- dev/kernel/NewKit/NewKit.h | 2 +- dev/kernel/NewKit/OwnPtr.h | 139 +- dev/kernel/NewKit/PageMgr.h | 131 +- dev/kernel/NewKit/Pair.h | 9 +- dev/kernel/NewKit/Pmm.h | 61 +- dev/kernel/NewKit/Ref.h | 164 +- dev/kernel/NewKit/Stream.h | 81 +- dev/kernel/NewKit/Utils.h | 41 +- dev/kernel/NewKit/Variant.h | 119 +- dev/kernel/SignalKit/Signals.h | 7 +- dev/kernel/StorageKit/AHCI.h | 58 +- dev/kernel/StorageKit/ATA.h | 70 +- dev/kernel/StorageKit/NVME.h | 36 +- dev/kernel/StorageKit/PRDT.h | 43 +- dev/kernel/StorageKit/SCSI.h | 6 +- dev/kernel/StorageKit/StorageKit.h | 23 +- dev/kernel/SwapKit/DiskSwap.h | 102 +- dev/kernel/src/ACPIFactoryInterface.cc | 172 +- dev/kernel/src/Array.cc | 2 +- dev/kernel/src/ArrayList.cc | 2 +- dev/kernel/src/Atom.cc | 2 +- dev/kernel/src/BinaryMutex.cc | 127 +- dev/kernel/src/BitMapMgr.cc | 351 +-- dev/kernel/src/CodeMgr.cc | 33 +- dev/kernel/src/Crc32.cc | 106 +- dev/kernel/src/CxxAbi-AMD64.cc | 111 +- dev/kernel/src/CxxAbi-ARM64.cc | 127 +- dev/kernel/src/Defines.cc | 2 +- dev/kernel/src/DeviceMgr.cc | 2 +- dev/kernel/src/DriveMgr+IO.cc | 127 +- dev/kernel/src/DriveMgr.cc | 318 +- dev/kernel/src/ErrorOr.cc | 2 +- dev/kernel/src/FS/Ext2+FileMgr.cc | 6 +- dev/kernel/src/FS/Ext2.cc | 16 +- dev/kernel/src/FS/HeFS+FileMgr.cc | 6 +- dev/kernel/src/FS/HeFS.cc | 1251 ++++---- dev/kernel/src/FS/NeFS+FileMgr.cc | 421 ++- dev/kernel/src/FS/NeFS.cc | 1280 ++++---- dev/kernel/src/FileMgr.cc | 76 +- dev/kernel/src/GUIDWizard.cc | 107 +- dev/kernel/src/GUIDWrapper.cc | 6 +- dev/kernel/src/Gfx/FBDeviceInterface.cc | 46 +- dev/kernel/src/HardwareThreadScheduler.cc | 401 ++- dev/kernel/src/IDylibObject.cc | 2 +- dev/kernel/src/IPEFDylibObject.cc | 93 +- dev/kernel/src/IndexableProperty.cc | 76 +- dev/kernel/src/Json.cc | 2 +- dev/kernel/src/KPC.cc | 50 +- dev/kernel/src/KString.cc | 388 +-- dev/kernel/src/KernelProcessScheduler.cc | 10 +- dev/kernel/src/LockDelegate.cc | 9 +- dev/kernel/src/MemoryMgr.cc | 462 ++- dev/kernel/src/MutableArray.cc | 2 +- dev/kernel/src/Network/IPAddr.cc | 213 +- dev/kernel/src/Network/IPCAddr.cc | 35 +- dev/kernel/src/Network/IPCMsg.cc | 215 +- dev/kernel/src/Network/MACAddressGetter.cc | 14 +- dev/kernel/src/Network/NetworkDevice.cc | 49 +- dev/kernel/src/New+Delete.cc | 54 +- dev/kernel/src/OwnPtr.cc | 2 +- dev/kernel/src/PEFCodeMgr.cc | 448 ++- dev/kernel/src/PRDT.cc | 28 +- dev/kernel/src/PageMgr.cc | 179 +- dev/kernel/src/Pmm.cc | 115 +- dev/kernel/src/ProcessTeam.cc | 84 +- dev/kernel/src/Property.cc | 72 +- dev/kernel/src/Ref.cc | 2 +- dev/kernel/src/SoftwareTimer.cc | 34 +- dev/kernel/src/Storage/AHCIDeviceInterface.cc | 119 +- dev/kernel/src/Storage/ATADeviceInterface.cc | 130 +- dev/kernel/src/Storage/NVMEDeviceInterface.cc | 33 +- dev/kernel/src/Storage/SCSIDeviceInterface.cc | 2 +- dev/kernel/src/Stream.cc | 8 +- dev/kernel/src/Swap/DiskSwap.cc | 84 +- dev/kernel/src/ThreadLocalStorage.cc | 48 +- dev/kernel/src/Timer.cc | 7 +- dev/kernel/src/User.cc | 265 +- dev/kernel/src/UserProcessScheduler.cc | 1246 ++++---- dev/kernel/src/Utils.cc | 343 +- dev/kernel/src/Variant.cc | 63 +- dev/kernel/src/WideUtils.cc | 19 +- dev/modules/ACPI/ACPI.h | 131 +- dev/modules/ACPI/ACPIFactoryInterface.h | 90 +- dev/modules/AHCI/AHCI.h | 529 ++-- dev/modules/APM/APM.h | 54 +- dev/modules/ATA/ATA.h | 156 +- dev/modules/CoreGfx/CoreAccess.h | 40 +- dev/modules/CoreGfx/CoreGfx.h | 171 +- dev/modules/CoreGfx/MathGfx.h | 28 +- dev/modules/CoreGfx/TextGfx.h | 315 +- dev/modules/HPET/Defines.h | 57 +- dev/modules/LTE/LTE.h | 26 +- dev/modules/MBCI/MBCI.h | 202 +- dev/modules/NVME/NVME.h | 183 +- dev/modules/Power/PowerFactory.h | 43 +- dev/modules/SCSI/SCSI.h | 15 +- dev/modules/XHCI/XHCI.h | 86 +- dev/user/Macros.h | 57 +- dev/user/Opts.h | 2 +- dev/user/ProcessCodes.h | 72 +- dev/user/SystemCalls.h | 23 +- dev/user/src/SystemCalls.cc | 127 +- .../frameworks/CoreFoundation.fwrk/headers/Array.h | 105 +- .../frameworks/CoreFoundation.fwrk/headers/Atom.h | 64 +- .../CoreFoundation.fwrk/headers/Foundation.h | 100 +- .../CoreFoundation.fwrk/headers/Object.h | 22 +- .../CoreFoundation.fwrk/headers/Property.h | 80 +- .../frameworks/CoreFoundation.fwrk/headers/Ref.h | 169 +- .../CoreFoundation.fwrk/headers/String.h | 16 +- .../CoreFoundation.fwrk/src/Foundation.cc | 29 +- .../frameworks/DiskImage.fwrk/headers/DiskImage.h | 76 +- .../frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc | 51 +- .../DiskImage.fwrk/src/DiskImage+NeFS.cc | 61 +- .../KernelTest.fwrk/headers/KernelTest.h | 29 +- public/tools/cc/src/CommandLine.cc | 8 +- public/tools/diutil/src/CommandLine.cc | 101 +- public/tools/diutil/vendor/Dialogs.h | 3287 +++++++++----------- public/tools/ld.dyn/src/CommandLine.cc | 66 +- public/tools/ld.fwrk/src/CommandLine.cc | 13 +- public/tools/mk.fwrk/Common.h | 8 +- public/tools/mk.fwrk/Framework.h | 10 +- public/tools/mk.fwrk/Steps.h | 29 +- public/tools/mk.fwrk/src/CommandLine.cc | 142 +- public/tools/mk.hefs/src/CommandLine.cc | 9 +- public/tools/mk.nefs/src/CommandLine.cc | 9 +- public/tools/open/src/CommandLine.cc | 52 +- 301 files changed, 19028 insertions(+), 22109 deletions(-) (limited to 'dev/kernel/src') diff --git a/.clang-format b/.clang-format index fb3cacb1..3943f553 100644 --- a/.clang-format +++ b/.clang-format @@ -1,16 +1,29 @@ ---- -BasedOnStyle: Microsoft -AccessModifierOffset: '-4' -AlignAfterOpenBracket: Align -AlignConsecutiveMacros: 'true' -AlignConsecutiveAssignments: 'true' -AlignConsecutiveDeclarations: 'true' -BinPackParameters: 'false' -ColumnLimit: '0' -Language: Cpp -NamespaceIndentation: All +BasedOnStyle: Google +IndentWidth: 2 +TabWidth: 2 +UseTab: Never +ColumnLimit: 100 +DerivePointerAlignment: false PointerAlignment: Left -ReflowComments: 'true' -SortIncludes: 'false' -UseTab: Always -... +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +SortIncludes: true +IncludeBlocks: Preserve +SpaceAfterCStyleCast: true +SpaceBeforeParens: ControlStatements +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +BreakBeforeBraces: Attach +ConstructorInitializerAllOnOneLineOrOnePerLine: true +Cpp11BracedListStyle: true +NamespaceIndentation: Inner +ReflowComments: true +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignTrailingComments: true +FixNamespaceComments: true +IncludeIsMainRegex: '(Test)?$' +SortUsingDeclarations: true diff --git a/dev/boot/BootKit/BitManip.h b/dev/boot/BootKit/BitManip.h index e4af0bf6..b1c72bfb 100644 --- a/dev/boot/BootKit/BitManip.h +++ b/dev/boot/BootKit/BitManip.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,11 +10,11 @@ /// File: BitManip.h /// Purpose: Bit manipulation helpers, based on coreboot-dev. -#define bk_set_bit(X, O) X = (1 << O) | X -#define bk_clear_bit(X, O) X = ~(1 << O) & X -#define bk_toogle(X, O) X = (1 << O) ^ X -#define bk_lsb(X) X = X & -X -#define bk_msb(X) X = -(mp_lsb(X)) & X +#define bk_set_bit(X, O) X = (1 << O) | X +#define bk_clear_bit(X, O) X = ~(1 << O) & X +#define bk_toogle(X, O) X = (1 << O) ^ X +#define bk_lsb(X) X = X & -X +#define bk_msb(X) X = -(mp_lsb(X)) & X #define bk_look_for_bit(X, O) (1 << O) | X -#endif // ifndef __BITMANIP_H__ +#endif // ifndef __BITMANIP_H__ diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 7b2a4f0a..76821b20 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -17,8 +17,8 @@ /// include NeFS header and Support header as well. -#include #include +#include /***********************************************************************************/ /// Include other APIs. @@ -27,389 +27,370 @@ #include #include -#include +#include #include #include -#include +#include #define kBKBootFileMime "boot-x/file" -#define kBKBootDirMime "boot-x/dir" +#define kBKBootDirMime "boot-x/dir" /***********************************************************************************/ /// Framebuffer helpers. /***********************************************************************************/ -namespace Boot -{ - EXTERN void ThrowError(const WideChar* errorCode, - const WideChar* reason) noexcept; - - class BootTextWriter; - class BootFileReader; - class BootThread; - class BVersionString; - - typedef Char* PEFImagePtr; - typedef Char* PEImagePtr; - - typedef WideChar CharacterTypeUTF16; - typedef Char CharacterTypeUTF8; - - using namespace Kernel; - - /** - * @brief BootKit Text Writer class - * Writes to UEFI StdOut. - */ - class BootTextWriter final - { - BootTextWriter& _Write(const UInt64& num); - - public: - BootTextWriter& Write(const UInt64& num); - BootTextWriter& Write(const Char* str); - BootTextWriter& Write(const CharacterTypeUTF16* str); - BootTextWriter& WriteCharacter(CharacterTypeUTF16 c); - BootTextWriter& Write(const UChar* str); - - template - BootTextWriter& operator<<(T elem) - { - this->Write(elem); - return *this; - } - - public: - explicit BootTextWriter() = default; - ~BootTextWriter() = default; - - public: - BootTextWriter& operator=(const BootTextWriter&) = default; - BootTextWriter(const BootTextWriter&) = default; - }; - - Kernel::SizeT BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len); - - Kernel::SizeT BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, const Kernel::SizeT len); - - /// String length functions. - - /// @brief get string length. - Kernel::SizeT BStrLen(const CharacterTypeUTF16* ptr); - - /// @brief set memory with custom value. - Kernel::SizeT BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, const Kernel::SizeT len); - - /** - * @brief BootKit File Reader class - * Reads the Firmware Boot partition and filesystem. - */ - class BootFileReader final - { - public: - explicit BootFileReader(const CharacterTypeUTF16* path, - EfiHandlePtr ImageHandle); - ~BootFileReader(); - - public: - Void ReadAll(SizeT until, SizeT chunk = kib_cast(4), UIntPtr out_address = 0UL); - - enum - { - kOperationOkay, - kNotSupported, - kEmptyDirectory, - kNoSuchEntry, - kIsDirectory, - kTooSmall, - kCount, - }; - - /// @brief error code getter. - /// @return the error code. - Int32& Error(); - - /// @brief blob getter. - /// @return the blob. - VoidPtr Blob(); - - /// @breif Size getter. - /// @return the size of the file. - UInt64& Size(); - - public: - BootFileReader& operator=(const BootFileReader&) = default; - BootFileReader(const BootFileReader&) = default; - - private: - Int32 mErrorCode{kOperationOkay}; - VoidPtr mBlob{nullptr}; - CharacterTypeUTF16 mPath[kPathLen]; - BootTextWriter mWriter; - EfiFileProtocol* mFile{nullptr}; - UInt64 mSizeFile{0}; - EfiFileProtocol* mRootFs; - }; - - typedef UInt8* BlobType; - - class BVersionString final - { - public: - static const CharacterTypeUTF8* The() - { - return BOOTLOADER_VERSION; - } - }; - - /***********************************************************************************/ - /// Provide some useful processor features. - /***********************************************************************************/ +namespace Boot { +EXTERN void ThrowError(const WideChar* errorCode, const WideChar* reason) noexcept; + +class BootTextWriter; +class BootFileReader; +class BootThread; +class BVersionString; + +typedef Char* PEFImagePtr; +typedef Char* PEImagePtr; + +typedef WideChar CharacterTypeUTF16; +typedef Char CharacterTypeUTF8; + +using namespace Kernel; + +/** + * @brief BootKit Text Writer class + * Writes to UEFI StdOut. + */ +class BootTextWriter final { + BootTextWriter& _Write(const UInt64& num); + + public: + BootTextWriter& Write(const UInt64& num); + BootTextWriter& Write(const Char* str); + BootTextWriter& Write(const CharacterTypeUTF16* str); + BootTextWriter& WriteCharacter(CharacterTypeUTF16 c); + BootTextWriter& Write(const UChar* str); + + template + BootTextWriter& operator<<(T elem) { + this->Write(elem); + return *this; + } + + public: + explicit BootTextWriter() = default; + ~BootTextWriter() = default; + + public: + BootTextWriter& operator=(const BootTextWriter&) = default; + BootTextWriter(const BootTextWriter&) = default; +}; + +Kernel::SizeT BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len); + +Kernel::SizeT BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, + const Kernel::SizeT len); + +/// String length functions. + +/// @brief get string length. +Kernel::SizeT BStrLen(const CharacterTypeUTF16* ptr); + +/// @brief set memory with custom value. +Kernel::SizeT BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, + const Kernel::SizeT len); + +/** + * @brief BootKit File Reader class + * Reads the Firmware Boot partition and filesystem. + */ +class BootFileReader final { + public: + explicit BootFileReader(const CharacterTypeUTF16* path, EfiHandlePtr ImageHandle); + ~BootFileReader(); + + public: + Void ReadAll(SizeT until, SizeT chunk = kib_cast(4), UIntPtr out_address = 0UL); + + enum { + kOperationOkay, + kNotSupported, + kEmptyDirectory, + kNoSuchEntry, + kIsDirectory, + kTooSmall, + kCount, + }; + + /// @brief error code getter. + /// @return the error code. + Int32& Error(); + + /// @brief blob getter. + /// @return the blob. + VoidPtr Blob(); + + /// @breif Size getter. + /// @return the size of the file. + UInt64& Size(); + + public: + BootFileReader& operator=(const BootFileReader&) = default; + BootFileReader(const BootFileReader&) = default; + + private: + Int32 mErrorCode{kOperationOkay}; + VoidPtr mBlob{nullptr}; + CharacterTypeUTF16 mPath[kPathLen]; + BootTextWriter mWriter; + EfiFileProtocol* mFile{nullptr}; + UInt64 mSizeFile{0}; + EfiFileProtocol* mRootFs; +}; + +typedef UInt8* BlobType; + +class BVersionString final { + public: + static const CharacterTypeUTF8* The() { return BOOTLOADER_VERSION; } +}; + +/***********************************************************************************/ +/// Provide some useful processor features. +/***********************************************************************************/ #ifdef __EFI_x86_64__ - /*** - * Common processor instructions. - */ - - EXTERN_C void rt_out8(UInt16 port, UInt8 value); - EXTERN_C void rt_out16(UInt16 port, UInt16 value); - EXTERN_C void rt_out32(UInt16 port, UInt32 value); - EXTERN_C UInt8 rt_in8(UInt16 port); - EXTERN_C UInt16 In16(UInt16 port); - EXTERN_C UInt32 rt_in32(UInt16 port); - - EXTERN_C void rt_hlt(); - EXTERN_C void rt_cli(); - EXTERN_C void rt_sti(); - EXTERN_C void rt_cld(); - EXTERN_C void rt_std(); - -#endif // __EFI_x86_64__ - - /// @brief BootKit Drive Formatter. - template - class BDiskFormatFactory final - { - public: - /// @brief File entry for **BDiskFormatFactory**. - struct BFileDescriptor final - { - Char fFileName[kNeFSCatalogNameLen]; - Int32 fKind; - }; - - public: - explicit BDiskFormatFactory() = default; - ~BDiskFormatFactory() = default; - - NE_COPY_DELETE(BDiskFormatFactory) - - /// @brief Format disk using partition name and blob. - /// @param Partition part_name the target partition name. - /// @param blob blobs array. - /// @param blob_sz blobs array count. - /// @retval True disk has been formatted. - /// @retval False failed to format. - Boolean Format(const Char* part_name); - - /// @brief check if partition is good. - Bool IsPartitionValid() noexcept - { +/*** + * Common processor instructions. + */ + +EXTERN_C void rt_out8(UInt16 port, UInt8 value); +EXTERN_C void rt_out16(UInt16 port, UInt16 value); +EXTERN_C void rt_out32(UInt16 port, UInt32 value); +EXTERN_C UInt8 rt_in8(UInt16 port); +EXTERN_C UInt16 In16(UInt16 port); +EXTERN_C UInt32 rt_in32(UInt16 port); + +EXTERN_C void rt_hlt(); +EXTERN_C void rt_cli(); +EXTERN_C void rt_sti(); +EXTERN_C void rt_cld(); +EXTERN_C void rt_std(); + +#endif // __EFI_x86_64__ + +/// @brief BootKit Drive Formatter. +template +class BDiskFormatFactory final { + public: + /// @brief File entry for **BDiskFormatFactory**. + struct BFileDescriptor final { + Char fFileName[kNeFSCatalogNameLen]; + Int32 fKind; + }; + + public: + explicit BDiskFormatFactory() = default; + ~BDiskFormatFactory() = default; + + NE_COPY_DELETE(BDiskFormatFactory) + + /// @brief Format disk using partition name and blob. + /// @param Partition part_name the target partition name. + /// @param blob blobs array. + /// @param blob_sz blobs array count. + /// @retval True disk has been formatted. + /// @retval False failed to format. + Boolean Format(const Char* part_name); + + /// @brief check if partition is good. + Bool IsPartitionValid() noexcept { #if defined(BOOTZ_EPM_SUPPORT) - fDiskDev.Leak().mBase = (kEPMBootBlockLba); - fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); + fDiskDev.Leak().mBase = (kEPMBootBlockLba); + fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); - EPM_PART_BLOCK buf_epm = {}; + EPM_PART_BLOCK buf_epm = {}; - fDiskDev.Read((Char*)&buf_epm, sizeof(EPM_PART_BLOCK)); + fDiskDev.Read((Char*) &buf_epm, sizeof(EPM_PART_BLOCK)); - if (StrCmp(buf_epm.Magic, kEPMMagic)) - { - return false; - } + if (StrCmp(buf_epm.Magic, kEPMMagic)) { + return false; + } - if (buf_epm.Version != kEPMRevisionBcd) - { - return false; - } + if (buf_epm.Version != kEPMRevisionBcd) { + return false; + } - fDiskDev.Leak().mBase = (kNeFSRootCatalogStartAddress); - fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + fDiskDev.Leak().mBase = (kNeFSRootCatalogStartAddress); + fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - Char buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; + Char buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - fDiskDev.Read(buf, sizeof(NEFS_ROOT_PARTITION_BLOCK)); + fDiskDev.Read(buf, sizeof(NEFS_ROOT_PARTITION_BLOCK)); - NEFS_ROOT_PARTITION_BLOCK* blockPart = reinterpret_cast(buf); + NEFS_ROOT_PARTITION_BLOCK* blockPart = reinterpret_cast(buf); - BootTextWriter writer; + BootTextWriter writer; - for (SizeT indexMag = 0UL; indexMag < kNeFSIdentLen; ++indexMag) - { - if (blockPart->Ident[indexMag] != kNeFSIdent[indexMag]) - return false; - } + for (SizeT indexMag = 0UL; indexMag < kNeFSIdentLen; ++indexMag) { + if (blockPart->Ident[indexMag] != kNeFSIdent[indexMag]) return false; + } - if (blockPart->DiskSize != this->fDiskDev.GetDiskSize() || - blockPart->DiskSize < 1 || - blockPart->SectorSize != BootDev::kSectorSize || - blockPart->Version != kNeFSVersionInteger || - blockPart->StartCatalog == 0) - { - return false; - } - else if (blockPart->PartitionName[0] == 0) - { - return false; - } + if (blockPart->DiskSize != this->fDiskDev.GetDiskSize() || blockPart->DiskSize < 1 || + blockPart->SectorSize != BootDev::kSectorSize || + blockPart->Version != kNeFSVersionInteger || blockPart->StartCatalog == 0) { + return false; + } else if (blockPart->PartitionName[0] == 0) { + return false; + } - writer.Write(L"BootZ: NeFS Partition: ").Write(blockPart->PartitionName).Write(L" is healthy.\r"); + writer.Write(L"BootZ: NeFS Partition: ") + .Write(blockPart->PartitionName) + .Write(L" is healthy.\r"); - return true; + return true; #else - GPT_PARTITION_TABLE gpt_part{}; + GPT_PARTITION_TABLE gpt_part{}; - fDiskDev.Leak().mBase = (kGPTPartitionTableLBA); - fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE); + fDiskDev.Leak().mBase = (kGPTPartitionTableLBA); + fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE); - fDiskDev.Read((Char*)&gpt_part, sizeof(GPT_PARTITION_TABLE)); + fDiskDev.Read((Char*) &gpt_part, sizeof(GPT_PARTITION_TABLE)); - BootTextWriter writer; + BootTextWriter writer; - if (StrCmp(gpt_part.Signature, kMagicGPT) == 0) - { - writer.Write("BootZ: GPT Partition found.\r"); - return true; - } + if (StrCmp(gpt_part.Signature, kMagicGPT) == 0) { + writer.Write("BootZ: GPT Partition found.\r"); + return true; + } - writer.Write("BootZ: No Partition found.\r"); + writer.Write("BootZ: No Partition found.\r"); - return false; + return false; #endif - } - - private: - BootDev fDiskDev; - }; - - /// @brief Format disk with a specific partition scheme. - /// @param part_name partition Name - /// @param blob blos. - /// @param blob_sz n blobs (n * sizeof(blob_struct)). - /// @retval True disk has been formatted. - /// @retval False failed to format. - template - inline Boolean BDiskFormatFactory::Format(const Char* part_name) - { + } + + private: + BootDev fDiskDev; +}; + +/// @brief Format disk with a specific partition scheme. +/// @param part_name partition Name +/// @param blob blos. +/// @param blob_sz n blobs (n * sizeof(blob_struct)). +/// @retval True disk has been formatted. +/// @retval False failed to format. +template +inline Boolean BDiskFormatFactory::Format(const Char* part_name) { #if defined(BOOTZ_EPM_SUPPORT) - /// @note A catalog roughly equal to a sector in NeFS terms. - constexpr auto kMinimumDiskSize = kNeFSMinimumDiskSize; // at minimum. + /// @note A catalog roughly equal to a sector in NeFS terms. + constexpr auto kMinimumDiskSize = kNeFSMinimumDiskSize; // at minimum. - /// @note also look at EPM headers, for free part blocks. (only applies if EPM or vEPM is used) + /// @note also look at EPM headers, for free part blocks. (only applies if EPM or vEPM is used) - if (fDiskDev.GetDiskSize() < kMinimumDiskSize) - { - Boot::ThrowError(L"Drive-Too-Tiny", L"Can't format a NeFS partition here."); - return false; - } + if (fDiskDev.GetDiskSize() < kMinimumDiskSize) { + Boot::ThrowError(L"Drive-Too-Tiny", L"Can't format a NeFS partition here."); + return false; + } - NEFS_ROOT_PARTITION_BLOCK part{}; + NEFS_ROOT_PARTITION_BLOCK part{}; - CopyMem(part.Ident, kNeFSIdent, kNeFSIdentLen - 1); - CopyMem(part.PartitionName, part_name, StrLen(part_name)); + CopyMem(part.Ident, kNeFSIdent, kNeFSIdentLen - 1); + CopyMem(part.PartitionName, part_name, StrLen(part_name)); - part.Version = kNeFSVersionInteger; - part.CatalogCount = blob_sz; - part.Kind = BootDev::kSectorSize; - part.SectorSize = kATASectorSize; - part.FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NEFS_CATALOG_STRUCT); - part.SectorCount = fDiskDev.GetSectorsCount(); - part.FreeSectors = fDiskDev.GetSectorsCount(); - part.StartCatalog = kNeFSCatalogStartAddress; - part.DiskSize = fDiskDev.GetDiskSize(); - part.Flags = kNeFSPartitionTypeBoot | kNeFSPartitionTypeStandard; + part.Version = kNeFSVersionInteger; + part.CatalogCount = blob_sz; + part.Kind = BootDev::kSectorSize; + part.SectorSize = kATASectorSize; + part.FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NEFS_CATALOG_STRUCT); + part.SectorCount = fDiskDev.GetSectorsCount(); + part.FreeSectors = fDiskDev.GetSectorsCount(); + part.StartCatalog = kNeFSCatalogStartAddress; + part.DiskSize = fDiskDev.GetDiskSize(); + part.Flags = kNeFSPartitionTypeBoot | kNeFSPartitionTypeStandard; - BootTextWriter writer; + BootTextWriter writer; - writer << "BootZ: Partition name: " << part.PartitionName << "\r"; - writer << "BootZ: Start: " << part.StartCatalog << "\r"; - writer << "BootZ: Number of catalogs: " << part.CatalogCount << "\r"; - writer << "BootZ: Free catalog: " << part.FreeCatalog << "\r"; - writer << "BootZ: Free sectors: " << part.FreeSectors << "\r"; - writer << "BootZ: Sector size: " << part.SectorSize << "\r"; + writer << "BootZ: Partition name: " << part.PartitionName << "\r"; + writer << "BootZ: Start: " << part.StartCatalog << "\r"; + writer << "BootZ: Number of catalogs: " << part.CatalogCount << "\r"; + writer << "BootZ: Free catalog: " << part.FreeCatalog << "\r"; + writer << "BootZ: Free sectors: " << part.FreeSectors << "\r"; + writer << "BootZ: Sector size: " << part.SectorSize << "\r"; - EPM_PART_BLOCK epm_boot{}; + EPM_PART_BLOCK epm_boot{}; - const auto kFsName = "NeFS"; - const auto kBlockName = "OS (EPM)"; + const auto kFsName = "NeFS"; + const auto kBlockName = "OS (EPM)"; - epm_boot.FsVersion = kNeFSVersionInteger; - epm_boot.LbaStart = kNeFSRootCatalogStartAddress; - epm_boot.LbaEnd = fDiskDev.GetDiskSize(); - epm_boot.SectorSz = part.SectorSize; - epm_boot.Kind = kEPMNeKernel; - epm_boot.NumBlocks = part.CatalogCount; + epm_boot.FsVersion = kNeFSVersionInteger; + epm_boot.LbaStart = kNeFSRootCatalogStartAddress; + epm_boot.LbaEnd = fDiskDev.GetDiskSize(); + epm_boot.SectorSz = part.SectorSize; + epm_boot.Kind = kEPMNeKernel; + epm_boot.NumBlocks = part.CatalogCount; - epm_boot.Guid = kEPMNilGuid; + epm_boot.Guid = kEPMNilGuid; - CopyMem(epm_boot.Fs, reinterpret_cast(const_cast(kFsName)), StrLen(kFsName)); - CopyMem(epm_boot.Name, reinterpret_cast(const_cast(kBlockName)), StrLen(kBlockName)); - CopyMem(epm_boot.Magic, reinterpret_cast(const_cast(kEPMMagic)), StrLen(kEPMMagic)); + CopyMem(epm_boot.Fs, reinterpret_cast(const_cast(kFsName)), StrLen(kFsName)); + CopyMem(epm_boot.Name, reinterpret_cast(const_cast(kBlockName)), + StrLen(kBlockName)); + CopyMem(epm_boot.Magic, reinterpret_cast(const_cast(kEPMMagic)), + StrLen(kEPMMagic)); - fDiskDev.Leak().mBase = kEPMBootBlockLba; // always always resies at zero block. - fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); + fDiskDev.Leak().mBase = kEPMBootBlockLba; // always always resies at zero block. + fDiskDev.Leak().mSize = sizeof(EPM_PART_BLOCK); - fDiskDev.Write((Char*)&epm_boot, sizeof(EPM_PART_BLOCK)); + fDiskDev.Write((Char*) &epm_boot, sizeof(EPM_PART_BLOCK)); - fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; - fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; + fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - fDiskDev.Write((Char*)&part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); + fDiskDev.Write((Char*) &part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); - writer.Write(L"BootZ: Drive is EPM formatted.\r"); + writer.Write(L"BootZ: Drive is EPM formatted.\r"); #elif defined(BOOTZ_VEPM_SUPPORT) - NE_UNUSED(part_name); + NE_UNUSED(part_name); - GPT_PARTITION_TABLE gpt_part{}; + GPT_PARTITION_TABLE gpt_part{}; - CopyMem(gpt_part.Signature, reinterpret_cast(const_cast(kMagicGPT)), StrLen(kMagicGPT)); + CopyMem(gpt_part.Signature, reinterpret_cast(const_cast(kMagicGPT)), + StrLen(kMagicGPT)); - gpt_part.Revision = 0x00010000; - gpt_part.HeaderSize = sizeof(GPT_PARTITION_TABLE); + gpt_part.Revision = 0x00010000; + gpt_part.HeaderSize = sizeof(GPT_PARTITION_TABLE); - gpt_part.CRC32 = 0x00000000; + gpt_part.CRC32 = 0x00000000; - gpt_part.Reserved1 = 0x00000000; - gpt_part.LBAHeader = 0x00000000; - gpt_part.LBAAltHeader = 0x00000000; - gpt_part.FirstGPTEntry = 0x00000000; - gpt_part.LastGPTEntry = 0x00000000; + gpt_part.Reserved1 = 0x00000000; + gpt_part.LBAHeader = 0x00000000; + gpt_part.LBAAltHeader = 0x00000000; + gpt_part.FirstGPTEntry = 0x00000000; + gpt_part.LastGPTEntry = 0x00000000; - gpt_part.Guid.Data1 = 0x00000000; - gpt_part.Guid.Data2 = 0x0000; - gpt_part.Guid.Data3 = 0x0000; + gpt_part.Guid.Data1 = 0x00000000; + gpt_part.Guid.Data2 = 0x0000; + gpt_part.Guid.Data3 = 0x0000; - SetMem(gpt_part.Guid.Data4, 0, 8); + SetMem(gpt_part.Guid.Data4, 0, 8); - gpt_part.Revision = 0x00010000; + gpt_part.Revision = 0x00010000; - gpt_part.StartingLBA = 0x00000000; - gpt_part.NumPartitionEntries = 0x00000000; - gpt_part.SizeOfEntries = 0x00000000; - gpt_part.CRC32PartEntry = 0x00000000; + gpt_part.StartingLBA = 0x00000000; + gpt_part.NumPartitionEntries = 0x00000000; + gpt_part.SizeOfEntries = 0x00000000; + gpt_part.CRC32PartEntry = 0x00000000; - SetMem(gpt_part.Reserved2, 0, kSectorAlignGPT_PartTbl); + SetMem(gpt_part.Reserved2, 0, kSectorAlignGPT_PartTbl); - fDiskDev.Leak().mBase = kGPTPartitionTableLBA; // always always resies at zero block. - fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE); + fDiskDev.Leak().mBase = kGPTPartitionTableLBA; // always always resies at zero block. + fDiskDev.Leak().mSize = sizeof(GPT_PARTITION_TABLE); - fDiskDev.Write((Char*)&gpt_part, sizeof(GPT_PARTITION_TABLE)); + fDiskDev.Write((Char*) &gpt_part, sizeof(GPT_PARTITION_TABLE)); - BootTextWriter writer; - writer.Write(L"BootZ: Drive is GPT formatted.\r"); + BootTextWriter writer; + writer.Write(L"BootZ: Drive is GPT formatted.\r"); #endif - return YES; - } -} // namespace Boot + return YES; +} +} // namespace Boot diff --git a/dev/boot/BootKit/BootThread.h b/dev/boot/BootKit/BootThread.h index 21202f91..b1b801d5 100644 --- a/dev/boot/BootKit/BootThread.h +++ b/dev/boot/BootKit/BootThread.h @@ -1,43 +1,41 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include -#include #include +#include +#include + +namespace Boot { +using namespace Kernel; + +class BootThread; + +/// @brief Bootloader Thread class. +class BootThread final { + public: + explicit BootThread() = delete; + ~BootThread() = default; + + explicit BootThread(Kernel::VoidPtr blob); + + BootThread& operator=(const BootThread&) = default; + BootThread(const BootThread&) = default; + + Int32 Start(HEL::BootInfoHeader* handover, BOOL is_own_stack); + void SetName(const char* name); + const char* GetName(); + bool IsValid(); -namespace Boot -{ - using namespace Kernel; - - class BootThread; - - /// @brief Bootloader Thread class. - class BootThread final - { - public: - explicit BootThread() = delete; - ~BootThread() = default; - - explicit BootThread(Kernel::VoidPtr blob); - - BootThread& operator=(const BootThread&) = default; - BootThread(const BootThread&) = default; - - Int32 Start(HEL::BootInfoHeader* handover, BOOL is_own_stack); - void SetName(const char* name); - const char* GetName(); - bool IsValid(); - - private: - Char fBlobName[256U] = {"BootThread"}; - VoidPtr fStartAddress{nullptr}; - VoidPtr fBlob{nullptr}; - UInt8* fStack{nullptr}; - HEL::BootInfoHeader* fHandover{nullptr}; - }; -} // namespace Boot + private: + Char fBlobName[256U] = {"BootThread"}; + VoidPtr fStartAddress{nullptr}; + VoidPtr fBlob{nullptr}; + UInt8* fStack{nullptr}; + HEL::BootInfoHeader* fHandover{nullptr}; +}; +} // namespace Boot diff --git a/dev/boot/BootKit/Device.h b/dev/boot/BootKit/Device.h index 88574bd6..8f5bf854 100644 --- a/dev/boot/BootKit/Device.h +++ b/dev/boot/BootKit/Device.h @@ -1,35 +1,33 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include using namespace Kernel; /// @brief Device type. -class Device -{ -public: - explicit Device() = default; - virtual ~Device() = default; +class Device { + public: + explicit Device() = default; + virtual ~Device() = default; - NE_MOVE_DEFAULT(Device) + NE_MOVE_DEFAULT(Device) - struct Trait - { - SizeT mBase{1024}; - SizeT mSize{1024}; - }; + struct Trait { + SizeT mBase{1024}; + SizeT mSize{1024}; + }; - virtual Trait& Leak() = 0; + virtual Trait& Leak() = 0; - virtual Device& Read(Char* Buf, SizeT SecCount) = 0; - virtual Device& Write(Char* Buf, SizeT SecCount) = 0; + virtual Device& Read(Char* Buf, SizeT SecCount) = 0; + virtual Device& Write(Char* Buf, SizeT SecCount) = 0; }; typedef Device BootDevice; diff --git a/dev/boot/BootKit/EPM.h b/dev/boot/BootKit/EPM.h index 03305c86..907f36e3 100644 --- a/dev/boot/BootKit/EPM.h +++ b/dev/boot/BootKit/EPM.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/boot/BootKit/HW/ATA.h b/dev/boot/BootKit/HW/ATA.h index 56393125..adb5c899 100644 --- a/dev/boot/BootKit/HW/ATA.h +++ b/dev/boot/BootKit/HW/ATA.h @@ -1,56 +1,47 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include using namespace Kernel; -class BootDeviceATA final : public Device -{ -public: - enum - { - kPrimary = ATA_PRIMARY_IO, - kSecondary = ATA_SECONDARY_IO, - }; +class BootDeviceATA final : public Device { + public: + enum { + kPrimary = ATA_PRIMARY_IO, + kSecondary = ATA_SECONDARY_IO, + }; - explicit BootDeviceATA() noexcept; - ~BootDeviceATA() = default; + explicit BootDeviceATA() noexcept; + ~BootDeviceATA() = default; - enum - { - kSectorSize = kATASectorSize - }; + enum { kSectorSize = kATASectorSize }; - struct ATATrait final : public Device::Trait - { - UInt16 mBus{kPrimary}; - UInt8 mMaster{0}; - Boolean mErr{false}; + struct ATATrait final : public Device::Trait { + UInt16 mBus{kPrimary}; + UInt8 mMaster{0}; + Boolean mErr{false}; - operator bool() - { - return !mErr; - } - }; + operator bool() { return !mErr; } + }; -public: - operator bool(); + public: + operator bool(); - SizeT GetSectorsCount() noexcept; - SizeT GetDiskSize() noexcept; + SizeT GetSectorsCount() noexcept; + SizeT GetDiskSize() noexcept; - BootDeviceATA& Read(Char* Buf, SizeT SecCount) override; - BootDeviceATA& Write(Char* Buf, SizeT SecCount) override; + BootDeviceATA& Read(Char* Buf, SizeT SecCount) override; + BootDeviceATA& Write(Char* Buf, SizeT SecCount) override; - ATATrait& Leak() override; + ATATrait& Leak() override; -private: - ATATrait mTrait; + private: + ATATrait mTrait; }; diff --git a/dev/boot/BootKit/HW/SATA.h b/dev/boot/BootKit/HW/SATA.h index 4073d959..7e84c061 100644 --- a/dev/boot/BootKit/HW/SATA.h +++ b/dev/boot/BootKit/HW/SATA.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,38 +9,30 @@ #include #include -class BootDeviceSATA final -{ -public: - explicit BootDeviceSATA() noexcept; - ~BootDeviceSATA() = default; +class BootDeviceSATA final { + public: + explicit BootDeviceSATA() noexcept; + ~BootDeviceSATA() = default; - NE_COPY_DEFAULT(BootDeviceSATA) + NE_COPY_DEFAULT(BootDeviceSATA) - struct SATATrait final - { - Kernel::SizeT mBase{1024}; - Kernel::Boolean mErr{false}; - Kernel::Boolean mDetected{false}; + struct SATATrait final { + Kernel::SizeT mBase{1024}; + Kernel::Boolean mErr{false}; + Kernel::Boolean mDetected{false}; - operator bool() - { - return !this->mErr; - } - }; + operator bool() { return !this->mErr; } + }; - operator bool() - { - return this->Leak().mDetected; - } + operator bool() { return this->Leak().mDetected; } - BootDeviceSATA& Read(Kernel::WideChar* Buf, const Kernel::SizeT SecCount); - BootDeviceSATA& Write(Kernel::WideChar* Buf, const Kernel::SizeT SecCount); + BootDeviceSATA& Read(Kernel::WideChar* Buf, const Kernel::SizeT SecCount); + BootDeviceSATA& Write(Kernel::WideChar* Buf, const Kernel::SizeT SecCount); - SATATrait& Leak(); + SATATrait& Leak(); -private: - SATATrait mTrait; + private: + SATATrait mTrait; }; #define kAHCISectorSz 4096 diff --git a/dev/boot/BootKit/Platform.h b/dev/boot/BootKit/Platform.h index e3eac52c..fdef85cb 100644 --- a/dev/boot/BootKit/Platform.h +++ b/dev/boot/BootKit/Platform.h @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once /** - @file Platform.h - @brief Platform specific code. + @file Platform.h + @brief Platform specific code. */ #ifdef __x86_64__ @@ -21,7 +21,7 @@ #ifndef EXTERN_C #define EXTERN_C extern #endif -#endif // __cplusplus +#endif // __cplusplus EXTERN_C void rt_halt(); EXTERN_C void rt_cli(); diff --git a/dev/boot/BootKit/Protocol.h b/dev/boot/BootKit/Protocol.h index d5bd62b5..4341a347 100644 --- a/dev/boot/BootKit/Protocol.h +++ b/dev/boot/BootKit/Protocol.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/boot/BootKit/Qr.h b/dev/boot/BootKit/Qr.h index 1bf9fa3d..2dcfc5fe 100644 --- a/dev/boot/BootKit/Qr.h +++ b/dev/boot/BootKit/Qr.h @@ -5,969 +5,793 @@ #include #include -#include #include #include +#include + +/// @note the QR code is still code 128, it utilizes the same concept of having it's own character +/// set. + +namespace qr { +inline uint8_t min_poly = 0b11101, /* Minimal polynomial x^8 + x^4 + x^3 + x^2 + 1 */ + generator = 0b10; /* Generator of Galois field */ + +/// @brief galois finite field multiplication. +inline uint8_t gf_mul(uint8_t a, uint8_t b) { + uint8_t res = 0; + + for (; b; b >>= 1) { + if (b & 1) res ^= a; + if (a & 0x80) + a = (a << 1) ^ min_poly; + else + a <<= 1; + } + + return res; +} + +// Size of Ecc block with respect to level and version. 0 version is for +// padding. +constexpr int ECC_CODEWORDS_PER_BLOCK[4][41] = { + {0, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, + 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, + {0, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, + 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, + {0, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, + 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, + {0, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, + 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, +}; + +// Number of Ecc blocks with respect to level and version. 0 version is for +// padding. +constexpr int N_ECC_BLOCKS[4][41] = { + {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, + 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, + {0, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, + 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, + {0, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, + 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, + {0, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, + 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, +}; + +// Positions of central modules of alignment patterns according to version. 0 +// version is for padding. +constexpr int ALIGN_POS[41][7] = { + {}, + {0}, + {6, 18}, + {6, 22}, + {6, 26}, + {6, 30}, + {6, 34}, + {6, 22, 38}, + {6, 24, 42}, + {6, 26, 46}, + {6, 28, 50}, + {6, 30, 54}, + {6, 32, 58}, + {6, 34, 62}, + {6, 26, 46, 66}, + {6, 26, 48, 70}, + {6, 26, 50, 74}, + {6, 30, 54, 78}, + {6, 30, 56, 82}, + {6, 30, 58, 86}, + {6, 34, 62, 90}, + {6, 28, 50, 72, 94}, + {6, 26, 50, 74, 98}, + {6, 30, 54, 78, 102}, + {6, 28, 54, 80, 106}, + {6, 32, 58, 84, 110}, + {6, 30, 58, 86, 114}, + {6, 34, 62, 90, 118}, + {6, 26, 50, 74, 98, 122}, + {6, 30, 54, 78, 102, 126}, + {6, 26, 52, 78, 104, 130}, + {6, 30, 56, 82, 108, 134}, + {6, 34, 60, 86, 112, 138}, + {6, 30, 58, 86, 114, 142}, + {6, 34, 62, 90, 118, 146}, + {6, 30, 54, 78, 102, 126, 150}, + {6, 24, 50, 76, 102, 128, 154}, + {6, 28, 54, 80, 106, 132, 158}, + {6, 32, 58, 84, 110, 136, 162}, + {6, 26, 54, 82, 110, 138, 166}, + {6, 30, 58, 86, 114, 142, 170}, +}; + +// Return n-th bit of arr starting from MSB. +constexpr uint8_t get_bit_r(uint8_t* arr, int n) { + return (arr[n >> 3] >> (7 - (n & 7))) & 1; +} + +// Add up to 16 bits to arr. Data starts from MSB as well as each byte of an +// array. +constexpr void add_bits(uint16_t data, int n, uint8_t* arr, size_t& pos) { + while (n--) { + arr[pos >> 3] |= ((data >> n) & 1) << (7 - (pos & 7)); + ++pos; + } +} + +// Translate char to alphanumeric encoding value, +constexpr int alphanumeric(char c) { + if (c >= '0' && c <= '9') return c - '0'; + + if (c >= 'A' && c <= 'Z') return c - 'A' + 10; + + switch (c) { + case ' ': + return 36; + case '$': + return 37; + case '%': + return 38; + case '*': + return 39; + case '+': + return 40; + case '-': + return 41; + case '.': + return 42; + case '/': + return 43; + case ':': + return 44; + } + return -1; +} + +// Check if string can be encoded in alphanumeric mode. +constexpr bool is_alphanumeric(const char* str, size_t len) { + for (size_t i = 0; i < len; ++i) + if (alphanumeric(str[i]) == -1) return false; + return true; +} + +// Check if string can be encoded in numeric mode. +constexpr bool is_numeric(const char* str, size_t len) { + for (size_t i = 0; i < len; ++i) + if (str[i] < '0' || str[i] > '9') return false; + return true; +} + +// Check if string can be encoded in kanji mode. +constexpr bool is_kanji(const char* str, size_t len) { + for (size_t i = 0; i < len; i += 2) { + uint16_t val = uint16_t(str[i]) | (uint16_t(str[i + 1]) << 8); + if (val < 0x8140 || val > 0xebbf || (val > 0x9ffc && val < 0xe040)) return false; + } + return true; +} + +// Reed-Solomon Ecc generator polynomial for the given degree. +constexpr void gf_gen_poly(int degree, uint8_t* poly) { + SetMem(poly, 0, degree); + + uint8_t root = poly[degree - 1] = 1; + + for (int i = 0; i < degree; ++i) { + for (int j = 0; j < degree - 1; ++j) poly[j] = gf_mul(poly[j], root) ^ poly[j + 1]; + poly[degree - 1] = gf_mul(poly[degree - 1], root); + root = (root << 1) ^ ((root >> 7) * 0x11d); + } +} + +// Polynomial division if Galois Field. +constexpr void gf_poly_div(uint8_t* dividend, size_t len, uint8_t* divisor, int degree, + uint8_t* result) { + SetMem(result, 0, degree); + + for (size_t i = 0; i < len; ++i) { + uint8_t factor = dividend[i] ^ result[0]; + MoveMem(&result[0], &result[1], degree - 1); + result[degree - 1] = 0; + for (int j = 0; j < degree; ++j) result[j] ^= gf_mul(divisor[j], factor); + } +} + +enum Ecc { + L, + M, + Q, + H, +}; + +enum Mode { + M_NUMERIC, + M_ALPHANUMERIC, + M_BYTE, + M_KANJI, +}; + +// Select appropriate encoding mode for string. +constexpr Mode select_mode(const char* str, size_t len) { + if (is_numeric(str, len)) return M_NUMERIC; + if (is_alphanumeric(str, len)) return M_ALPHANUMERIC; + if (is_kanji(str, len)) return M_KANJI; + return M_BYTE; +} + +// Return size of Character Control Indicator in bits for given version and +// mode. +constexpr int cci(int ver, Mode mode) { + constexpr int cnt[4][3] = { + {10, 12, 14}, + {9, 11, 13}, + {8, 16, 16}, + {8, 10, 12}, + }; + if (ver < 10) return cnt[mode][0]; + if (ver < 27) return cnt[mode][1]; + return cnt[mode][2]; +} + +template +struct Qr { + private: + friend class QrDelegate; + bool draw(int x, int y) noexcept; + + public: + constexpr auto side_size() const { return SIDE; } + + bool module(int x, int y); + bool encode(const char* str, size_t len, Ecc ecc, int mask = -1); + + private: + bool encode_data(const char* data, size_t len, Ecc ecc, uint8_t* out); + void encode_ecc(uint8_t* data, Ecc ecc, uint8_t* out); + + void add_data(uint8_t* data, uint8_t* patterns); + void add_patterns(); + void add_version(); + void add_format(Ecc ecc, int mask); + void reserve_patterns(uint8_t* out); + + template + void draw_rect(int y, int x, int height, int width, uint8_t* out); + template + void draw_bound(int y, int x, int height, int width, uint8_t* out); + + template + int rule_1_3_score(); + int penalty_score(); + int select_mask(Ecc ecc, uint8_t* patterns); + void apply_mask(int mask, uint8_t* patterns); + + private: + static_assert(V >= 1 && V <= 40, "invalid version"); + static constexpr int SIDE = 17 + V * 4; + static constexpr int N_BITS = SIDE * SIDE; + static constexpr int N_ALIGN = V == 1 ? 0 : V / 7 + 2; + static constexpr int N_ALIGN_BITS = V > 1 ? (N_ALIGN* N_ALIGN - 3) * 25 : 0; + static constexpr int N_TIMING_BITS = (SIDE - 16) * 2 - (10 * (V > 1 ? N_ALIGN - 2 : 0)); + static constexpr int N_VER_BITS = V > 6 ? 36 : 0; + static constexpr int N_DAT_BITS = N_BITS - (192 + N_ALIGN_BITS + N_TIMING_BITS + 31 + N_VER_BITS); + static constexpr int N_BYTES = utl::bytes_in_bits(N_BITS); // Actual number of bytes_in_bits + // required to store whole Qr code + static constexpr int N_DAT_BYTES = + utl::bytes_in_bits(N_DAT_BITS); // Actual number of bytes_in_bits required to store + // [data + ecc] + static constexpr int N_DAT_CAPACITY = + N_DAT_BITS >> 3; // Capacity of [data + ecc] without remainder bits + private: + /// @brief internal function to retrieve bit from a bitset. + uint8_t get_arr_bit(uint8_t* arr, unsigned bit) const { return utl::get_arr_bit(arr, bit); } + + /// @brief internal function to set bit from a bitset. + void set_arr_bit(uint8_t* arr, unsigned bit) { utl::set_arr_bit(arr, bit); } + + /// @brief internal function to clear bit from a bitset. + void clr_arr_bit(uint8_t* arr, unsigned bit) { utl::clr_arr_bit(arr, bit); } + + uint8_t code[N_BYTES] = {}; + + bool status = false; +}; + +// Get color of a module from left-to-right and top-to-bottom. Black is true. +template +bool Qr::module(int x, int y) { + return get_arr_bit(code, y * SIDE + x); +} + +/// @brief draw a new QR code. +template +bool Qr::draw(int whereX, int whereY) noexcept { + if (!this->status) return false; // it may be invalid. + + fb_init(); + + for (int y = 0; y < (this->side_size()); ++y) { + for (int x = 0; x < (this->side_size()); ++x) { + FBDrawInRegion((this->module(x, y) ? RGB(00, 00, 00) : RGB(0xFF, 0xFF, 0xFF)), 1, 1, + x + whereX, y + whereY); + } + } + + fb_clear(); + + return false; +} + +// Create Qr code with given error correction level. If mask == -1, +// then best mask selected automatically. NOTE: Automatic mask is the +// most expensive operation. Takes about 95 % of all computation time. +template +bool Qr::encode(const char* str, size_t len, Ecc ecc, int mask) { + uint8_t data[N_DAT_BYTES] = {}; + uint8_t data_with_ecc[N_DAT_BYTES] = {}; + uint8_t patterns[N_BYTES] = {}; + + if (!encode_data(str, len, ecc, data)) { + return status = false; + } + + encode_ecc(data, ecc, data_with_ecc); + + reserve_patterns(patterns); + CopyMem(code, patterns, N_BYTES); + + add_data(data_with_ecc, patterns); + add_patterns(); + add_version(); + + mask = mask != -1 ? mask & 7 : select_mask(ecc, patterns); + + add_format(ecc, mask); + apply_mask(mask, patterns); + + return status = true; +} + +template +bool Qr::encode_data(const char* data, size_t len, Ecc ecc, uint8_t* out) { + Mode mode = select_mode(data, len); + + size_t n_bits = (N_DAT_CAPACITY - ECC_CODEWORDS_PER_BLOCK[ecc][V] * N_ECC_BLOCKS[ecc][V]) << 3; + size_t pos = 0; + + add_bits(1 << mode, 4, out, pos); + add_bits(len, cci(V, mode), out, pos); + + if (mode == M_NUMERIC) { + const size_t triplets = len / 3; + const size_t triplets_size = triplets * 3; + const size_t rem = len % 3; + const size_t rem_bits = rem == 2 ? 7 : rem == 1 ? 4 : 0; + const size_t total_size = 10 * triplets + rem_bits; + + if (pos + total_size > n_bits) return false; + + char buf[4] = {}; + + for (size_t i = 0; i < triplets_size; i += 3) { + buf[0] = data[i]; + buf[1] = data[i + 1]; + buf[2] = data[i + 2]; + + uint16_t num = StringToLong(buf, NULL, 10); + add_bits(num, 10, out, pos); + } + + if (rem) { + buf[0] = data[triplets_size]; + buf[1] = data[triplets_size + 1]; + buf[rem] = 0; + + uint16_t num = StringToLong(buf, NULL, 10); + add_bits(num, rem_bits, out, pos); + } + } else if (mode == M_ALPHANUMERIC) { + if (pos + 11 * (int(len & ~1ul) / 2) > n_bits) return false; + + for (int i = 0; i < int(len & ~1ul); i += 2) { + uint16_t num = alphanumeric(data[i]) * 45 + alphanumeric(data[i + 1]); + add_bits(num, 11, out, pos); + } + if (len & 1) { + if (pos + 6 > n_bits) return false; + + add_bits(alphanumeric(data[len - 1]), 6, out, pos); + } + } else if (mode == M_BYTE) { + if (pos + len * 8 > n_bits) return false; + + for (size_t i = 0; i < len; ++i) add_bits(data[i], 8, out, pos); + } else { + if (pos + 13 * (len / 2) > n_bits) return false; + + for (size_t i = 0; i < len; i += 2) { + uint16_t val = ((uint8_t) data[i]) | (((uint8_t) data[i + 1]) << 8); + uint16_t res = 0; + val -= val < 0x9FFC ? 0x8140 : 0xC140; + res += val & 0xff; + res += (val >> 8) * 0xc0; + add_bits(res, 13, out, pos); + } + } + + size_t padding = n_bits - pos; + size_t i = 0; + + add_bits(0, padding > 4 ? 4 : padding, out, pos); + + if (pos & 7) add_bits(0, (8 - pos) & 7, out, pos); + + while (pos < n_bits) add_bits(++i & 1 ? 0xec : 0x11, 8, out, pos); + + return true; +} + +template +void Qr::encode_ecc(uint8_t* data, Ecc ecc, uint8_t* out) { + int n_blocks = N_ECC_BLOCKS[ecc][V]; + int ecc_len = ECC_CODEWORDS_PER_BLOCK[ecc][V]; + + int n_data_bytes = N_DAT_CAPACITY - ecc_len * n_blocks; + + int n_short_blocks = n_blocks - N_DAT_CAPACITY % n_blocks; + int short_len = N_DAT_CAPACITY / n_blocks - ecc_len; + + uint8_t gen_poly[30]; + uint8_t ecc_buf[30]; + + gf_gen_poly(ecc_len, gen_poly); + + uint8_t* data_ptr = data; + + for (int i = 0; i < n_blocks; ++i) { + int data_len = short_len; + + if (i >= n_short_blocks) ++data_len; + + gf_poly_div(data_ptr, data_len, gen_poly, ecc_len, ecc_buf); -/// @note the QR code is still code 128, it utilizes the same concept of having it's own character set. - -namespace qr -{ - inline uint8_t min_poly = - 0b11101, /* Minimal polynomial x^8 + x^4 + x^3 + x^2 + 1 */ - generator = 0b10; /* Generator of Galois field */ - - /// @brief galois finite field multiplication. - inline uint8_t gf_mul(uint8_t a, uint8_t b) - { - uint8_t res = 0; - - for (; b; b >>= 1) - { - if (b & 1) - res ^= a; - if (a & 0x80) - a = (a << 1) ^ min_poly; - else - a <<= 1; - } - - return res; - } - - // Size of Ecc block with respect to level and version. 0 version is for - // padding. - constexpr int ECC_CODEWORDS_PER_BLOCK[4][41] = { - {0, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, - 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, - {0, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, - 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, - {0, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, - 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, - {0, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, - 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, - }; - - // Number of Ecc blocks with respect to level and version. 0 version is for - // padding. - constexpr int N_ECC_BLOCKS[4][41] = { - {0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, - 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, - 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, - {0, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, - 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, - 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, - {0, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, - 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, - 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, - {0, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, - 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, - 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, - }; - - // Positions of central modules of alignment patterns according to version. 0 - // version is for padding. - constexpr int ALIGN_POS[41][7] = { - {}, - {0}, - {6, 18}, - {6, 22}, - {6, 26}, - {6, 30}, - {6, 34}, - {6, 22, 38}, - {6, 24, 42}, - {6, 26, 46}, - {6, 28, 50}, - {6, 30, 54}, - {6, 32, 58}, - {6, 34, 62}, - {6, 26, 46, 66}, - {6, 26, 48, 70}, - {6, 26, 50, 74}, - {6, 30, 54, 78}, - {6, 30, 56, 82}, - {6, 30, 58, 86}, - {6, 34, 62, 90}, - {6, 28, 50, 72, 94}, - {6, 26, 50, 74, 98}, - {6, 30, 54, 78, 102}, - {6, 28, 54, 80, 106}, - {6, 32, 58, 84, 110}, - {6, 30, 58, 86, 114}, - {6, 34, 62, 90, 118}, - {6, 26, 50, 74, 98, 122}, - {6, 30, 54, 78, 102, 126}, - {6, 26, 52, 78, 104, 130}, - {6, 30, 56, 82, 108, 134}, - {6, 34, 60, 86, 112, 138}, - {6, 30, 58, 86, 114, 142}, - {6, 34, 62, 90, 118, 146}, - {6, 30, 54, 78, 102, 126, 150}, - {6, 24, 50, 76, 102, 128, 154}, - {6, 28, 54, 80, 106, 132, 158}, - {6, 32, 58, 84, 110, 136, 162}, - {6, 26, 54, 82, 110, 138, 166}, - {6, 30, 58, 86, 114, 142, 170}, - }; - - // Return n-th bit of arr starting from MSB. - constexpr uint8_t get_bit_r(uint8_t* arr, int n) - { - return (arr[n >> 3] >> (7 - (n & 7))) & 1; - } - - // Add up to 16 bits to arr. Data starts from MSB as well as each byte of an - // array. - constexpr void add_bits(uint16_t data, int n, uint8_t* arr, size_t& pos) - { - while (n--) - { - arr[pos >> 3] |= ((data >> n) & 1) << (7 - (pos & 7)); - ++pos; - } - } - - // Translate char to alphanumeric encoding value, - constexpr int alphanumeric(char c) - { - if (c >= '0' && c <= '9') - return c - '0'; - - if (c >= 'A' && c <= 'Z') - return c - 'A' + 10; - - switch (c) - { - case ' ': - return 36; - case '$': - return 37; - case '%': - return 38; - case '*': - return 39; - case '+': - return 40; - case '-': - return 41; - case '.': - return 42; - case '/': - return 43; - case ':': - return 44; - } - return -1; - } - - // Check if string can be encoded in alphanumeric mode. - constexpr bool is_alphanumeric(const char* str, size_t len) - { - for (size_t i = 0; i < len; ++i) - if (alphanumeric(str[i]) == -1) - return false; - return true; - } - - // Check if string can be encoded in numeric mode. - constexpr bool is_numeric(const char* str, size_t len) - { - for (size_t i = 0; i < len; ++i) - if (str[i] < '0' || str[i] > '9') - return false; - return true; - } - - // Check if string can be encoded in kanji mode. - constexpr bool is_kanji(const char* str, size_t len) - { - for (size_t i = 0; i < len; i += 2) - { - uint16_t val = uint16_t(str[i]) | (uint16_t(str[i + 1]) << 8); - if (val < 0x8140 || val > 0xebbf || (val > 0x9ffc && val < 0xe040)) - return false; - } - return true; - } - - // Reed-Solomon Ecc generator polynomial for the given degree. - constexpr void gf_gen_poly(int degree, uint8_t* poly) - { - SetMem(poly, 0, degree); - - uint8_t root = poly[degree - 1] = 1; - - for (int i = 0; i < degree; ++i) - { - for (int j = 0; j < degree - 1; ++j) - poly[j] = gf_mul(poly[j], root) ^ poly[j + 1]; - poly[degree - 1] = gf_mul(poly[degree - 1], root); - root = (root << 1) ^ ((root >> 7) * 0x11d); - } - } - - // Polynomial division if Galois Field. - constexpr void gf_poly_div(uint8_t* dividend, size_t len, uint8_t* divisor, int degree, uint8_t* result) - { - SetMem(result, 0, degree); - - for (size_t i = 0; i < len; ++i) - { - uint8_t factor = dividend[i] ^ result[0]; - MoveMem(&result[0], &result[1], degree - 1); - result[degree - 1] = 0; - for (int j = 0; j < degree; ++j) - result[j] ^= gf_mul(divisor[j], factor); - } - } - - enum Ecc - { - L, - M, - Q, - H, - }; - - enum Mode - { - M_NUMERIC, - M_ALPHANUMERIC, - M_BYTE, - M_KANJI, - }; - - // Select appropriate encoding mode for string. - constexpr Mode select_mode(const char* str, size_t len) - { - if (is_numeric(str, len)) - return M_NUMERIC; - if (is_alphanumeric(str, len)) - return M_ALPHANUMERIC; - if (is_kanji(str, len)) - return M_KANJI; - return M_BYTE; - } - - // Return size of Character Control Indicator in bits for given version and - // mode. - constexpr int cci(int ver, Mode mode) - { - constexpr int cnt[4][3] = { - {10, 12, 14}, - {9, 11, 13}, - {8, 16, 16}, - {8, 10, 12}, - }; - if (ver < 10) - return cnt[mode][0]; - if (ver < 27) - return cnt[mode][1]; - return cnt[mode][2]; - } - - template - struct Qr - { - private: - friend class QrDelegate; - bool draw(int x, int y) noexcept; - - public: - constexpr auto side_size() const - { - return SIDE; - } - - bool module(int x, int y); - bool encode(const char* str, size_t len, Ecc ecc, int mask = -1); - - private: - bool encode_data(const char* data, size_t len, Ecc ecc, uint8_t* out); - void encode_ecc(uint8_t* data, Ecc ecc, uint8_t* out); - - void add_data(uint8_t* data, uint8_t* patterns); - void add_patterns(); - void add_version(); - void add_format(Ecc ecc, int mask); - void reserve_patterns(uint8_t* out); - - template - void draw_rect(int y, int x, int height, int width, uint8_t* out); - template - void draw_bound(int y, int x, int height, int width, uint8_t* out); - - template - int rule_1_3_score(); - int penalty_score(); - int select_mask(Ecc ecc, uint8_t* patterns); - void apply_mask(int mask, uint8_t* patterns); - - private: - static_assert(V >= 1 && V <= 40, "invalid version"); - static constexpr int SIDE = 17 + V * 4; - static constexpr int N_BITS = SIDE * SIDE; - static constexpr int N_ALIGN = V == 1 ? 0 : V / 7 + 2; - static constexpr int N_ALIGN_BITS = V > 1 ? (N_ALIGN* N_ALIGN - 3) * 25 : 0; - static constexpr int N_TIMING_BITS = - (SIDE - 16) * 2 - (10 * (V > 1 ? N_ALIGN - 2 : 0)); - static constexpr int N_VER_BITS = V > 6 ? 36 : 0; - static constexpr int N_DAT_BITS = - N_BITS - (192 + N_ALIGN_BITS + N_TIMING_BITS + 31 + N_VER_BITS); - static constexpr int N_BYTES = utl::bytes_in_bits(N_BITS); // Actual number of bytes_in_bits - // required to store whole Qr code - static constexpr int N_DAT_BYTES = utl::bytes_in_bits(N_DAT_BITS); // Actual number of bytes_in_bits required to store - // [data + ecc] - static constexpr int N_DAT_CAPACITY = - N_DAT_BITS >> 3; // Capacity of [data + ecc] without remainder bits - private: - /// @brief internal function to retrieve bit from a bitset. - uint8_t get_arr_bit(uint8_t* arr, unsigned bit) const - { - return utl::get_arr_bit(arr, bit); - } - - /// @brief internal function to set bit from a bitset. - void set_arr_bit(uint8_t* arr, unsigned bit) - { - utl::set_arr_bit(arr, bit); - } - - /// @brief internal function to clear bit from a bitset. - void clr_arr_bit(uint8_t* arr, unsigned bit) - { - utl::clr_arr_bit(arr, bit); - } - - uint8_t code[N_BYTES] = {}; - - bool status = false; - }; - - // Get color of a module from left-to-right and top-to-bottom. Black is true. - template - bool Qr::module(int x, int y) - { - return get_arr_bit(code, y * SIDE + x); - } - - /// @brief draw a new QR code. - template - bool Qr::draw(int whereX, int whereY) noexcept - { - if (!this->status) - return false; // it may be invalid. - - fb_init(); - - for (int y = 0; y < (this->side_size()); ++y) - { - for (int x = 0; x < (this->side_size()); ++x) - { - FBDrawInRegion( - (this->module(x, y) ? RGB(00, 00, 00) : RGB(0xFF, 0xFF, 0xFF)), - 1, 1, - x + whereX, y + whereY); - } - } - - fb_clear(); - - return false; - } - - // Create Qr code with given error correction level. If mask == -1, - // then best mask selected automatically. NOTE: Automatic mask is the - // most expensive operation. Takes about 95 % of all computation time. - template - bool Qr::encode(const char* str, size_t len, Ecc ecc, int mask) - { - uint8_t data[N_DAT_BYTES] = {}; - uint8_t data_with_ecc[N_DAT_BYTES] = {}; - uint8_t patterns[N_BYTES] = {}; - - if (!encode_data(str, len, ecc, data)) - { - return status = false; - } - - encode_ecc(data, ecc, data_with_ecc); - - reserve_patterns(patterns); - CopyMem(code, patterns, N_BYTES); - - add_data(data_with_ecc, patterns); - add_patterns(); - add_version(); - - mask = mask != -1 ? mask & 7 : select_mask(ecc, patterns); - - add_format(ecc, mask); - apply_mask(mask, patterns); - - return status = true; - } - - template - bool Qr::encode_data(const char* data, size_t len, Ecc ecc, uint8_t* out) - { - Mode mode = select_mode(data, len); - - size_t n_bits = - (N_DAT_CAPACITY - ECC_CODEWORDS_PER_BLOCK[ecc][V] * N_ECC_BLOCKS[ecc][V]) - << 3; - size_t pos = 0; - - add_bits(1 << mode, 4, out, pos); - add_bits(len, cci(V, mode), out, pos); - - if (mode == M_NUMERIC) - { - const size_t triplets = len / 3; - const size_t triplets_size = triplets * 3; - const size_t rem = len % 3; - const size_t rem_bits = rem == 2 ? 7 : rem == 1 ? 4 - : 0; - const size_t total_size = 10 * triplets + rem_bits; - - if (pos + total_size > n_bits) - return false; - - char buf[4] = {}; - - for (size_t i = 0; i < triplets_size; i += 3) - { - buf[0] = data[i]; - buf[1] = data[i + 1]; - buf[2] = data[i + 2]; - - uint16_t num = StringToLong(buf, NULL, 10); - add_bits(num, 10, out, pos); - } - - if (rem) - { - buf[0] = data[triplets_size]; - buf[1] = data[triplets_size + 1]; - buf[rem] = 0; - - uint16_t num = StringToLong(buf, NULL, 10); - add_bits(num, rem_bits, out, pos); - } - } - else if (mode == M_ALPHANUMERIC) - { - if (pos + 11 * (int(len & ~1ul) / 2) > n_bits) - return false; - - for (int i = 0; i < int(len & ~1ul); i += 2) - { - uint16_t num = alphanumeric(data[i]) * 45 + alphanumeric(data[i + 1]); - add_bits(num, 11, out, pos); - } - if (len & 1) - { - if (pos + 6 > n_bits) - return false; - - add_bits(alphanumeric(data[len - 1]), 6, out, pos); - } - } - else if (mode == M_BYTE) - { - if (pos + len * 8 > n_bits) - return false; - - for (size_t i = 0; i < len; ++i) - add_bits(data[i], 8, out, pos); - } - else - { - if (pos + 13 * (len / 2) > n_bits) - return false; - - for (size_t i = 0; i < len; i += 2) - { - uint16_t val = ((uint8_t)data[i]) | (((uint8_t)data[i + 1]) << 8); - uint16_t res = 0; - val -= val < 0x9FFC ? 0x8140 : 0xC140; - res += val & 0xff; - res += (val >> 8) * 0xc0; - add_bits(res, 13, out, pos); - } - } - - size_t padding = n_bits - pos; - size_t i = 0; - - add_bits(0, padding > 4 ? 4 : padding, out, pos); - - if (pos & 7) - add_bits(0, (8 - pos) & 7, out, pos); - - while (pos < n_bits) - add_bits(++i & 1 ? 0xec : 0x11, 8, out, pos); - - return true; - } - - template - void Qr::encode_ecc(uint8_t* data, Ecc ecc, uint8_t* out) - { - int n_blocks = N_ECC_BLOCKS[ecc][V]; - int ecc_len = ECC_CODEWORDS_PER_BLOCK[ecc][V]; - - int n_data_bytes = N_DAT_CAPACITY - ecc_len * n_blocks; - - int n_short_blocks = n_blocks - N_DAT_CAPACITY % n_blocks; - int short_len = N_DAT_CAPACITY / n_blocks - ecc_len; - - uint8_t gen_poly[30]; - uint8_t ecc_buf[30]; - - gf_gen_poly(ecc_len, gen_poly); - - uint8_t* data_ptr = data; - - for (int i = 0; i < n_blocks; ++i) - { - int data_len = short_len; - - if (i >= n_short_blocks) - ++data_len; - - gf_poly_div(data_ptr, data_len, gen_poly, ecc_len, ecc_buf); - - for (int j = 0, k = i; j < data_len; ++j, k += n_blocks) - { - if (j == short_len) - k -= n_short_blocks; - out[k] = data_ptr[j]; - } - for (int j = 0, k = n_data_bytes + i; j < ecc_len; ++j, k += n_blocks) - out[k] = ecc_buf[j]; - - data_ptr += data_len; - } - } - - template - void Qr::add_data(uint8_t* data, uint8_t* patterns) - { - int data_pos = 0; - - for (int x = SIDE - 1; x >= 1; x -= 2) - { - if (x == 6) - x = 5; - - for (int i = 0; i < SIDE; ++i) - { - int y = !((x + 1) & 2) ? SIDE - 1 - i : i; - int coord = y * SIDE + x; - - if (!get_arr_bit(patterns, coord)) - { - if (get_bit_r(data, data_pos)) - set_arr_bit(code, coord); - - ++data_pos; - } - - if (!get_arr_bit(patterns, coord - 1)) - { - if (get_bit_r(data, data_pos)) - set_arr_bit(code, coord - 1); - - ++data_pos; - } - } - } - } - - template - void Qr::add_patterns() - { - // White bounds inside finders - draw_bound(1, 1, 5, 5, code); - draw_bound(1, SIDE - 6, 5, 5, code); - draw_bound(SIDE - 6, 1, 5, 5, code); - - // Finish alignment patterns - for (int i = 0; i < N_ALIGN; ++i) - { - for (int j = 0; j < N_ALIGN; ++j) - { - if ((!i && !j) || (!i && j == N_ALIGN - 1) || (!j && i == N_ALIGN - 1)) - continue; - draw_bound(ALIGN_POS[V][i] - 1, ALIGN_POS[V][j] - 1, 3, 3, code); - } - } - - // Draw white separators - draw_rect(7, 0, 1, 8, code); - draw_rect(0, 7, 8, 1, code); - draw_rect(SIDE - 8, 0, 1, 8, code); - draw_rect(SIDE - 8, 7, 8, 1, code); - draw_rect(7, SIDE - 8, 1, 8, code); - draw_rect(0, SIDE - 8, 8, 1, code); - - // Perforate timing patterns - for (int i = 7; i < SIDE - 7; i += 2) - { - clr_arr_bit(code, 6 * SIDE + i); - clr_arr_bit(code, i * SIDE + 6); - } - } - - template - void Qr::add_version() - { - if (V < 7) - return; - - uint32_t rem = V; - - for (uint8_t i = 0; i < 12; ++i) - rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); - - uint32_t data = V << 12 | rem; - - for (int x = 0; x < 6; ++x) - { - for (int j = 0; j < 3; ++j) - { - int y = SIDE - 11 + j; - - bool black = (data >> (x * 3 + j)) & 1; - - if (!black) - { - clr_arr_bit(code, y * SIDE + x); - clr_arr_bit(code, y + SIDE * x); - } - } - } - } - - template - void Qr::add_format(Ecc ecc, int mask) - { - int data = (ecc ^ 1) << 3 | mask; - int rem = data; - - for (int i = 0; i < 10; i++) - rem = (rem << 1) ^ ((rem >> 9) * 0b10100110111); - - int res = (data << 10 | rem) ^ 0b101010000010010; - - for (int i = 0; i < 6; ++i) - { - if ((res >> i) & 1) - { - set_arr_bit(code, SIDE * 8 + SIDE - 1 - i); - set_arr_bit(code, SIDE * i + 8); - } - else - { - clr_arr_bit(code, SIDE * 8 + SIDE - 1 - i); - clr_arr_bit(code, SIDE * i + 8); - } - } - - for (int i = 6; i < 8; ++i) - { - if ((res >> i) & 1) - { - set_arr_bit(code, SIDE * 8 + SIDE - 1 - i); - set_arr_bit(code, SIDE * (i + 1) + 8); - } - else - { - clr_arr_bit(code, SIDE * 8 + SIDE - 1 - i); - clr_arr_bit(code, SIDE * (i + 1) + 8); - } - } - - if ((res >> 8) & 1) - { - set_arr_bit(code, SIDE * 8 + 7); - set_arr_bit(code, SIDE * (SIDE - 7) + 8); - } - else - { - clr_arr_bit(code, SIDE * 8 + 7); - clr_arr_bit(code, SIDE * (SIDE - 7) + 8); - } - - for (int i = 9, j = 5; i < 15; ++i, --j) - { - if ((res >> i) & 1) - { - set_arr_bit(code, SIDE * 8 + j); - set_arr_bit(code, SIDE * (SIDE - 1 - j) + 8); - } - else - { - clr_arr_bit(code, SIDE * 8 + j); - clr_arr_bit(code, SIDE * (SIDE - 1 - j) + 8); - } - } - } - - template - template - void Qr::draw_rect(int y, int x, int height, int width, uint8_t* out) - { - if (B) - { - for (int dy = y * SIDE; dy < (y + height) * SIDE; dy += SIDE) - for (int dx = x; dx < x + width; ++dx) - set_arr_bit(out, dy + dx); - } - else - { - for (int dy = y * SIDE; dy < (y + height) * SIDE; dy += SIDE) - for (int dx = x; dx < x + width; ++dx) - clr_arr_bit(out, dy + dx); - } - } - - template - template - void Qr::draw_bound(int y, int x, int height, int width, uint8_t* out) - { - if (B) - { - for (int i = y * SIDE + x; i < y * SIDE + x + width; ++i) - set_arr_bit(out, i); - for (int i = (y + height - 1) * SIDE + x; - i < (y + height - 1) * SIDE + x + width; ++i) - set_arr_bit(out, i); - for (int i = (y + 1) * SIDE + x; i < (y + height - 1) * SIDE + x; i += SIDE) - set_arr_bit(out, i); - for (int i = (y + 1) * SIDE + x + width - 1; - i < (y + height - 1) * SIDE + x + width - 1; i += SIDE) - set_arr_bit(out, i); - } - else - { - for (int i = y * SIDE + x; i < y * SIDE + x + width; ++i) - clr_arr_bit(out, i); - for (int i = (y + height - 1) * SIDE + x; - i < (y + height - 1) * SIDE + x + width; ++i) - clr_arr_bit(out, i); - for (int i = (y + 1) * SIDE + x; i < (y + height - 1) * SIDE + x; i += SIDE) - clr_arr_bit(out, i); - for (int i = (y + 1) * SIDE + x + width - 1; - i < (y + height - 1) * SIDE + x + width - 1; i += SIDE) - clr_arr_bit(out, i); - } - } - - template - void Qr::reserve_patterns(uint8_t* out) - { - draw_rect(0, 6, SIDE, 1, out); - draw_rect(6, 0, 1, SIDE, out); - - draw_rect(0, 0, 9, 9, out); - draw_rect(SIDE - 8, 0, 8, 9, out); - draw_rect(0, SIDE - 8, 9, 8, out); - - for (int i = 0; i < N_ALIGN; ++i) - { - for (int j = 0; j < N_ALIGN; ++j) - { - if ((!i && !j) || (!i && j == N_ALIGN - 1) || (!j && i == N_ALIGN - 1)) - continue; - draw_rect(ALIGN_POS[V][i] - 2, ALIGN_POS[V][j] - 2, 5, 5, out); - } - } - - if (V >= 7) - { - draw_rect(SIDE - 11, 0, 3, 6, out); - draw_rect(0, SIDE - 11, 6, 3, out); - } - } - - template - template - int Qr::rule_1_3_score() - { - constexpr int y_max = H ? N_BITS : SIDE; - constexpr int x_max = H ? SIDE : N_BITS; - constexpr int y_step = H ? SIDE : 1; - constexpr int x_step = H ? 1 : SIDE; - - int res = 0; - - for (int y = 0; y < y_max; y += y_step) - { - bool color = get_arr_bit(code, y); - int finder = color; - int cnt = 1; - for (int x = 1; x < x_max; x += x_step) - { - if (get_arr_bit(code, y + x) == color) - { - ++cnt; - if (cnt == 5) - res += 3; - if (cnt > 5) - ++res; - } - else - { - color = !color; - cnt = 1; - } - // Finder-like - finder = ((finder << 1) & 0x7ff) | color; - if (x >= x_step * 10) - { - if (finder == 0x05d || finder == 0x5d0) - res += 40; - } - } - } - return res; - } - - template - int Qr::penalty_score() - { - int res = 0; - - res += rule_1_3_score(); - res += rule_1_3_score(); - - for (int y = 0; y < N_BITS - SIDE; y += SIDE) - { - for (int x = 0; x < SIDE - 1; ++x) - { - bool c = get_arr_bit(code, y + x); - - if (c == get_arr_bit(code, y + x + 1) && - c == get_arr_bit(code, y + x + SIDE) && - c == get_arr_bit(code, y + x + SIDE + 1)) - res += 3; - } - } - - int black = 0; - for (int y = 0; y < N_BITS; y += SIDE) - { - for (int x = 0; x < SIDE; ++x) - black += get_arr_bit(code, y + x); - } - res += abs((black * 100) / N_BITS - 50) / 5 * 10; - - return res; - } - - template - int Qr::select_mask(Ecc ecc, uint8_t* patterns) - { - unsigned min_score = -1; - unsigned score = 0; - uint8_t mask = 0; - - for (int i = 0; i < 8; ++i) - { - add_format(ecc, i); - apply_mask(i, patterns); - score = penalty_score(); - if (score < min_score) - { - mask = i; - min_score = score; - } - apply_mask(i, patterns); - } - return mask; - } - - template - void Qr::apply_mask(int mask, uint8_t* patterns) - { - for (int y = 0, dy = 0; y < SIDE; ++y, dy += SIDE) - { - for (int x = 0; x < SIDE; ++x) - { - int coord = dy + x; - - if (get_arr_bit(patterns, coord)) - continue; - - bool keep = true; - - switch (mask) - { - case 0: - keep = (x + y) & 1; - break; - case 1: - keep = y & 1; - break; - case 2: - keep = x % 3; - break; - case 3: - keep = (x + y) % 3; - break; - case 4: - keep = (y / 2 + x / 3) & 1; - break; - case 5: - keep = x * y % 2 + x * y % 3; - break; - case 6: - keep = (x * y % 2 + x * y % 3) & 1; - break; - case 7: - keep = ((x + y) % 2 + x * y % 3) & 1; - break; - } - - if (!keep) - { - if (get_arr_bit(code, coord)) - clr_arr_bit(code, coord); - else - set_arr_bit(code, coord); - } - } - } - } - - /// @brief QR code encoder class. - class QrDelegate final - { - public: - explicit QrDelegate() = default; - ~QrDelegate() = default; - - NE_COPY_DEFAULT(QrDelegate) - - /// @brief Draw method delegate. - template - bool draw(Qr& subject, Int32 x, Int32 y) noexcept - { - return subject.draw(x, y); - } - }; -} // namespace qr - -namespace Kernel::Qr -{ - using namespace qr; -} // namespace Kernel::Qr - -#endif // QR_H \ No newline at end of file + for (int j = 0, k = i; j < data_len; ++j, k += n_blocks) { + if (j == short_len) k -= n_short_blocks; + out[k] = data_ptr[j]; + } + for (int j = 0, k = n_data_bytes + i; j < ecc_len; ++j, k += n_blocks) out[k] = ecc_buf[j]; + + data_ptr += data_len; + } +} + +template +void Qr::add_data(uint8_t* data, uint8_t* patterns) { + int data_pos = 0; + + for (int x = SIDE - 1; x >= 1; x -= 2) { + if (x == 6) x = 5; + + for (int i = 0; i < SIDE; ++i) { + int y = !((x + 1) & 2) ? SIDE - 1 - i : i; + int coord = y * SIDE + x; + + if (!get_arr_bit(patterns, coord)) { + if (get_bit_r(data, data_pos)) set_arr_bit(code, coord); + + ++data_pos; + } + + if (!get_arr_bit(patterns, coord - 1)) { + if (get_bit_r(data, data_pos)) set_arr_bit(code, coord - 1); + + ++data_pos; + } + } + } +} + +template +void Qr::add_patterns() { + // White bounds inside finders + draw_bound(1, 1, 5, 5, code); + draw_bound(1, SIDE - 6, 5, 5, code); + draw_bound(SIDE - 6, 1, 5, 5, code); + + // Finish alignment patterns + for (int i = 0; i < N_ALIGN; ++i) { + for (int j = 0; j < N_ALIGN; ++j) { + if ((!i && !j) || (!i && j == N_ALIGN - 1) || (!j && i == N_ALIGN - 1)) continue; + draw_bound(ALIGN_POS[V][i] - 1, ALIGN_POS[V][j] - 1, 3, 3, code); + } + } + + // Draw white separators + draw_rect(7, 0, 1, 8, code); + draw_rect(0, 7, 8, 1, code); + draw_rect(SIDE - 8, 0, 1, 8, code); + draw_rect(SIDE - 8, 7, 8, 1, code); + draw_rect(7, SIDE - 8, 1, 8, code); + draw_rect(0, SIDE - 8, 8, 1, code); + + // Perforate timing patterns + for (int i = 7; i < SIDE - 7; i += 2) { + clr_arr_bit(code, 6 * SIDE + i); + clr_arr_bit(code, i * SIDE + 6); + } +} + +template +void Qr::add_version() { + if (V < 7) return; + + uint32_t rem = V; + + for (uint8_t i = 0; i < 12; ++i) rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); + + uint32_t data = V << 12 | rem; + + for (int x = 0; x < 6; ++x) { + for (int j = 0; j < 3; ++j) { + int y = SIDE - 11 + j; + + bool black = (data >> (x * 3 + j)) & 1; + + if (!black) { + clr_arr_bit(code, y * SIDE + x); + clr_arr_bit(code, y + SIDE * x); + } + } + } +} + +template +void Qr::add_format(Ecc ecc, int mask) { + int data = (ecc ^ 1) << 3 | mask; + int rem = data; + + for (int i = 0; i < 10; i++) rem = (rem << 1) ^ ((rem >> 9) * 0b10100110111); + + int res = (data << 10 | rem) ^ 0b101010000010010; + + for (int i = 0; i < 6; ++i) { + if ((res >> i) & 1) { + set_arr_bit(code, SIDE * 8 + SIDE - 1 - i); + set_arr_bit(code, SIDE * i + 8); + } else { + clr_arr_bit(code, SIDE * 8 + SIDE - 1 - i); + clr_arr_bit(code, SIDE * i + 8); + } + } + + for (int i = 6; i < 8; ++i) { + if ((res >> i) & 1) { + set_arr_bit(code, SIDE * 8 + SIDE - 1 - i); + set_arr_bit(code, SIDE * (i + 1) + 8); + } else { + clr_arr_bit(code, SIDE * 8 + SIDE - 1 - i); + clr_arr_bit(code, SIDE * (i + 1) + 8); + } + } + + if ((res >> 8) & 1) { + set_arr_bit(code, SIDE * 8 + 7); + set_arr_bit(code, SIDE * (SIDE - 7) + 8); + } else { + clr_arr_bit(code, SIDE * 8 + 7); + clr_arr_bit(code, SIDE * (SIDE - 7) + 8); + } + + for (int i = 9, j = 5; i < 15; ++i, --j) { + if ((res >> i) & 1) { + set_arr_bit(code, SIDE * 8 + j); + set_arr_bit(code, SIDE * (SIDE - 1 - j) + 8); + } else { + clr_arr_bit(code, SIDE * 8 + j); + clr_arr_bit(code, SIDE * (SIDE - 1 - j) + 8); + } + } +} + +template +template +void Qr::draw_rect(int y, int x, int height, int width, uint8_t* out) { + if (B) { + for (int dy = y * SIDE; dy < (y + height) * SIDE; dy += SIDE) + for (int dx = x; dx < x + width; ++dx) set_arr_bit(out, dy + dx); + } else { + for (int dy = y * SIDE; dy < (y + height) * SIDE; dy += SIDE) + for (int dx = x; dx < x + width; ++dx) clr_arr_bit(out, dy + dx); + } +} + +template +template +void Qr::draw_bound(int y, int x, int height, int width, uint8_t* out) { + if (B) { + for (int i = y * SIDE + x; i < y * SIDE + x + width; ++i) set_arr_bit(out, i); + for (int i = (y + height - 1) * SIDE + x; i < (y + height - 1) * SIDE + x + width; ++i) + set_arr_bit(out, i); + for (int i = (y + 1) * SIDE + x; i < (y + height - 1) * SIDE + x; i += SIDE) + set_arr_bit(out, i); + for (int i = (y + 1) * SIDE + x + width - 1; i < (y + height - 1) * SIDE + x + width - 1; + i += SIDE) + set_arr_bit(out, i); + } else { + for (int i = y * SIDE + x; i < y * SIDE + x + width; ++i) clr_arr_bit(out, i); + for (int i = (y + height - 1) * SIDE + x; i < (y + height - 1) * SIDE + x + width; ++i) + clr_arr_bit(out, i); + for (int i = (y + 1) * SIDE + x; i < (y + height - 1) * SIDE + x; i += SIDE) + clr_arr_bit(out, i); + for (int i = (y + 1) * SIDE + x + width - 1; i < (y + height - 1) * SIDE + x + width - 1; + i += SIDE) + clr_arr_bit(out, i); + } +} + +template +void Qr::reserve_patterns(uint8_t* out) { + draw_rect(0, 6, SIDE, 1, out); + draw_rect(6, 0, 1, SIDE, out); + + draw_rect(0, 0, 9, 9, out); + draw_rect(SIDE - 8, 0, 8, 9, out); + draw_rect(0, SIDE - 8, 9, 8, out); + + for (int i = 0; i < N_ALIGN; ++i) { + for (int j = 0; j < N_ALIGN; ++j) { + if ((!i && !j) || (!i && j == N_ALIGN - 1) || (!j && i == N_ALIGN - 1)) continue; + draw_rect(ALIGN_POS[V][i] - 2, ALIGN_POS[V][j] - 2, 5, 5, out); + } + } + + if (V >= 7) { + draw_rect(SIDE - 11, 0, 3, 6, out); + draw_rect(0, SIDE - 11, 6, 3, out); + } +} + +template +template +int Qr::rule_1_3_score() { + constexpr int y_max = H ? N_BITS : SIDE; + constexpr int x_max = H ? SIDE : N_BITS; + constexpr int y_step = H ? SIDE : 1; + constexpr int x_step = H ? 1 : SIDE; + + int res = 0; + + for (int y = 0; y < y_max; y += y_step) { + bool color = get_arr_bit(code, y); + int finder = color; + int cnt = 1; + for (int x = 1; x < x_max; x += x_step) { + if (get_arr_bit(code, y + x) == color) { + ++cnt; + if (cnt == 5) res += 3; + if (cnt > 5) ++res; + } else { + color = !color; + cnt = 1; + } + // Finder-like + finder = ((finder << 1) & 0x7ff) | color; + if (x >= x_step * 10) { + if (finder == 0x05d || finder == 0x5d0) res += 40; + } + } + } + return res; +} + +template +int Qr::penalty_score() { + int res = 0; + + res += rule_1_3_score(); + res += rule_1_3_score(); + + for (int y = 0; y < N_BITS - SIDE; y += SIDE) { + for (int x = 0; x < SIDE - 1; ++x) { + bool c = get_arr_bit(code, y + x); + + if (c == get_arr_bit(code, y + x + 1) && c == get_arr_bit(code, y + x + SIDE) && + c == get_arr_bit(code, y + x + SIDE + 1)) + res += 3; + } + } + + int black = 0; + for (int y = 0; y < N_BITS; y += SIDE) { + for (int x = 0; x < SIDE; ++x) black += get_arr_bit(code, y + x); + } + res += abs((black * 100) / N_BITS - 50) / 5 * 10; + + return res; +} + +template +int Qr::select_mask(Ecc ecc, uint8_t* patterns) { + unsigned min_score = -1; + unsigned score = 0; + uint8_t mask = 0; + + for (int i = 0; i < 8; ++i) { + add_format(ecc, i); + apply_mask(i, patterns); + score = penalty_score(); + if (score < min_score) { + mask = i; + min_score = score; + } + apply_mask(i, patterns); + } + return mask; +} + +template +void Qr::apply_mask(int mask, uint8_t* patterns) { + for (int y = 0, dy = 0; y < SIDE; ++y, dy += SIDE) { + for (int x = 0; x < SIDE; ++x) { + int coord = dy + x; + + if (get_arr_bit(patterns, coord)) continue; + + bool keep = true; + + switch (mask) { + case 0: + keep = (x + y) & 1; + break; + case 1: + keep = y & 1; + break; + case 2: + keep = x % 3; + break; + case 3: + keep = (x + y) % 3; + break; + case 4: + keep = (y / 2 + x / 3) & 1; + break; + case 5: + keep = x * y % 2 + x * y % 3; + break; + case 6: + keep = (x * y % 2 + x * y % 3) & 1; + break; + case 7: + keep = ((x + y) % 2 + x * y % 3) & 1; + break; + } + + if (!keep) { + if (get_arr_bit(code, coord)) + clr_arr_bit(code, coord); + else + set_arr_bit(code, coord); + } + } + } +} + +/// @brief QR code encoder class. +class QrDelegate final { + public: + explicit QrDelegate() = default; + ~QrDelegate() = default; + + NE_COPY_DEFAULT(QrDelegate) + + /// @brief Draw method delegate. + template + bool draw(Qr& subject, Int32 x, Int32 y) noexcept { + return subject.draw(x, y); + } +}; +} // namespace qr + +namespace Kernel::Qr { +using namespace qr; +} // namespace Kernel::Qr + +#endif // QR_H \ No newline at end of file diff --git a/dev/boot/BootKit/Shared/base.h b/dev/boot/BootKit/Shared/base.h index 88459ec3..c95db0cc 100644 --- a/dev/boot/BootKit/Shared/base.h +++ b/dev/boot/BootKit/Shared/base.h @@ -1,26 +1,24 @@ #ifndef UTL_BASE_H #define UTL_BASE_H -#include -#include #include +#include +#include -namespace utl -{ +namespace utl { - /** - * @brief Helper to get number of elements in array. - * - * @tparam T Auto-deduced element type - * @tparam N Auto-deduced number of elements - * @return Array size - */ - template - constexpr size_t countof(T (&)[N]) - { - return N; - } +/** + * @brief Helper to get number of elements in array. + * + * @tparam T Auto-deduced element type + * @tparam N Auto-deduced number of elements + * @return Array size + */ +template +constexpr size_t countof(T (&)[N]) { + return N; +} -} // namespace utl +} // namespace utl #endif \ No newline at end of file diff --git a/dev/boot/BootKit/Shared/bit.h b/dev/boot/BootKit/Shared/bit.h index fa0fab82..1ac29c89 100644 --- a/dev/boot/BootKit/Shared/bit.h +++ b/dev/boot/BootKit/Shared/bit.h @@ -3,245 +3,226 @@ #include -namespace utl -{ - - /** - * @brief Size of object in terms of bits. - * - * @tparam T Object type - * @return Number of bits - */ - template - constexpr auto bit_size() - { - return sizeof(T) * 8; - } - - /** - * @brief Integer with all bits set to 1. - * - * @tparam T Integer type - * @return All set integer - */ - template - constexpr T bit_full() - { - return T(-1); - } - - /** - * @brief Wrap around mask for power of two number of bits - * within given integer type. For example: - * [ bit_wrap = 8 - 1 = 0b111 ] - * [ bit_wrap = 16 - 1 = 0b1111 ] - * [ bit_wrap = 32 - 1 = 0b11111 ] - * - * @tparam T Integer type - * @return Wrap around mask for number of bits - */ - template - constexpr T bit_wrap() - { - return bit_size() - 1; - } - - /** - * @brief Number of bits to fit bit_wrap result, in other words - * bit width of (sizeof(T) * 8 - 1). For example: - * [ bit_shft = bit_width(0b111) = 3 ] - * [ bit_shft = bit_width(0b1111) = 4 ] - * [ bit_shft = bit_width(0b11111) = 5 ] - * - * @tparam T Integer type - * @return Number of bits to shift to divide by sizeof(T) * 8 - */ - template - constexpr auto bit_shft() - { - return std::bit_width(bit_wrap()); - } - - /** - * @brief Round up division by number of bits within given integer type, - * which sizeof(T) * 8 is power of two. - * - * @tparam T Inetegr type - * @param x Dividend - * @return Quotient - */ - template - constexpr auto bit_ceil(auto x) - { - return (x + bit_wrap()) >> bit_shft(); - } - - /** - * @brief Count leading zeros. - * - * @param x Unsigned integer argument - * @return Number of leading zeros - */ - constexpr unsigned cntlz(auto x) - { - if constexpr (std::is_same_v) - return std::countl_zero(unsigned(x)); - else - return std::countl_zero(x); - } - - /** - * @brief Count trailing zeros. - * - * @param x Unsigned integer argument - * @return Number of trailing zeros - */ - constexpr unsigned cnttz(auto x) - { - if constexpr (std::is_same_v) - return std::countr_zero(unsigned(x)); - else - return std::countr_zero(x); - } - - /** - * @brief Get number of words (integers) required to store N bits. - * - * @tparam T Word integer type - * @param n Number of bits to store - * @return Number of words - */ - template - constexpr size_t words_in_bits(size_t n) - { - return (n >> bit_shft()) + !!(n & bit_wrap()); - } - - /** - * @brief Get number of bytes required to store N bits. - * - * @param n Number of bits to store - * @return Number of bytes - */ - constexpr size_t bytes_in_bits(size_t n) - { - return words_in_bits(n); - } - - /** - * @brief Make integer with bit at given position. - * - * @tparam T Inetegr type - * @param n Bit position - * @return Integer with set bit - */ - template - constexpr T bit(int n) - { - return T(1) << n; - } - - /** - * @brief Get n-th bit of an integer. - * - * @tparam T Integer type - * @param x Integer - * @param n Bit position from LSB - * @return true if set - */ - template - constexpr bool get_bit(T x, int n) - { - return (x >> n) & 1; - } - - /** - * @brief Set n-th bit of an integer. - * - * @tparam T Integer type - * @param x Integer - * @param n Bit position from LSB - */ - template - constexpr void set_bit(T& x, int n) - { - x |= 1 << n; - } - - /** - * @brief Clear n-th bit of an integer. - * - * @tparam T Integer type - * @param x Integer - * @param n Bit position from LSB - */ - template - constexpr void clr_bit(T& x, int n) - { - x &= ~(1 << n); - } - - /** - * @brief Get n-th bit in array of words (starting from LSB). - * - * @tparam T Word type - * @param p Array of words - * @param n Index of bit to get - * @return true if set - */ - template - constexpr bool get_arr_bit(const T* p, unsigned n) - { - return get_bit(p[n >> bit_shft()], n & bit_wrap()); - } - - /** - * @brief Set n-th bit in array of words (starting from LSB). - * - * @tparam T Word type - * @param p Array of words - * @param n Index of bit to set - */ - template - constexpr void set_arr_bit(T* p, unsigned n) - { - set_bit(p[n >> bit_shft()], n & bit_wrap()); - } - - /** - * @brief Clear n-th bit in array of words (starting from LSB). - * - * @tparam T Word type - * @param p Array of words - * @param n Index of bit to clear - */ - template - constexpr void clr_arr_bit(T* p, unsigned n) - { - clr_bit(p[n >> bit_shft()], n & bit_wrap()); - } - - /** - * @brief Shift bits left in array of integer elements from least significant bit - * and considering 0-th byte as the right most. - * uint16_t example: 0b10000000'11100001 ==> 0b00000001'11000010. - * - * @tparam T Integer type - * @tparam L Length of array - * @param x Array of integers, nullptr not acceptable! - * @param len Number of elements - */ - template - constexpr void shift_left(T (&x)[L]) - { - for (int i = L - 1; i > 0; --i) - { - x[i] <<= 1; - x[i] |= x[i - 1] >> bit_wrap(); - } - x[0] <<= 1; - } - -} // namespace utl +namespace utl { + +/** + * @brief Size of object in terms of bits. + * + * @tparam T Object type + * @return Number of bits + */ +template +constexpr auto bit_size() { + return sizeof(T) * 8; +} + +/** + * @brief Integer with all bits set to 1. + * + * @tparam T Integer type + * @return All set integer + */ +template +constexpr T bit_full() { + return T(-1); +} + +/** + * @brief Wrap around mask for power of two number of bits + * within given integer type. For example: + * [ bit_wrap = 8 - 1 = 0b111 ] + * [ bit_wrap = 16 - 1 = 0b1111 ] + * [ bit_wrap = 32 - 1 = 0b11111 ] + * + * @tparam T Integer type + * @return Wrap around mask for number of bits + */ +template +constexpr T bit_wrap() { + return bit_size() - 1; +} + +/** + * @brief Number of bits to fit bit_wrap result, in other words + * bit width of (sizeof(T) * 8 - 1). For example: + * [ bit_shft = bit_width(0b111) = 3 ] + * [ bit_shft = bit_width(0b1111) = 4 ] + * [ bit_shft = bit_width(0b11111) = 5 ] + * + * @tparam T Integer type + * @return Number of bits to shift to divide by sizeof(T) * 8 + */ +template +constexpr auto bit_shft() { + return std::bit_width(bit_wrap()); +} + +/** + * @brief Round up division by number of bits within given integer type, + * which sizeof(T) * 8 is power of two. + * + * @tparam T Inetegr type + * @param x Dividend + * @return Quotient + */ +template +constexpr auto bit_ceil(auto x) { + return (x + bit_wrap()) >> bit_shft(); +} + +/** + * @brief Count leading zeros. + * + * @param x Unsigned integer argument + * @return Number of leading zeros + */ +constexpr unsigned cntlz(auto x) { + if constexpr (std::is_same_v) + return std::countl_zero(unsigned(x)); + else + return std::countl_zero(x); +} + +/** + * @brief Count trailing zeros. + * + * @param x Unsigned integer argument + * @return Number of trailing zeros + */ +constexpr unsigned cnttz(auto x) { + if constexpr (std::is_same_v) + return std::countr_zero(unsigned(x)); + else + return std::countr_zero(x); +} + +/** + * @brief Get number of words (integers) required to store N bits. + * + * @tparam T Word integer type + * @param n Number of bits to store + * @return Number of words + */ +template +constexpr size_t words_in_bits(size_t n) { + return (n >> bit_shft()) + !!(n & bit_wrap()); +} + +/** + * @brief Get number of bytes required to store N bits. + * + * @param n Number of bits to store + * @return Number of bytes + */ +constexpr size_t bytes_in_bits(size_t n) { + return words_in_bits(n); +} + +/** + * @brief Make integer with bit at given position. + * + * @tparam T Inetegr type + * @param n Bit position + * @return Integer with set bit + */ +template +constexpr T bit(int n) { + return T(1) << n; +} + +/** + * @brief Get n-th bit of an integer. + * + * @tparam T Integer type + * @param x Integer + * @param n Bit position from LSB + * @return true if set + */ +template +constexpr bool get_bit(T x, int n) { + return (x >> n) & 1; +} + +/** + * @brief Set n-th bit of an integer. + * + * @tparam T Integer type + * @param x Integer + * @param n Bit position from LSB + */ +template +constexpr void set_bit(T& x, int n) { + x |= 1 << n; +} + +/** + * @brief Clear n-th bit of an integer. + * + * @tparam T Integer type + * @param x Integer + * @param n Bit position from LSB + */ +template +constexpr void clr_bit(T& x, int n) { + x &= ~(1 << n); +} + +/** + * @brief Get n-th bit in array of words (starting from LSB). + * + * @tparam T Word type + * @param p Array of words + * @param n Index of bit to get + * @return true if set + */ +template +constexpr bool get_arr_bit(const T* p, unsigned n) { + return get_bit(p[n >> bit_shft()], n & bit_wrap()); +} + +/** + * @brief Set n-th bit in array of words (starting from LSB). + * + * @tparam T Word type + * @param p Array of words + * @param n Index of bit to set + */ +template +constexpr void set_arr_bit(T* p, unsigned n) { + set_bit(p[n >> bit_shft()], n & bit_wrap()); +} + +/** + * @brief Clear n-th bit in array of words (starting from LSB). + * + * @tparam T Word type + * @param p Array of words + * @param n Index of bit to clear + */ +template +constexpr void clr_arr_bit(T* p, unsigned n) { + clr_bit(p[n >> bit_shft()], n & bit_wrap()); +} + +/** + * @brief Shift bits left in array of integer elements from least significant bit + * and considering 0-th byte as the right most. + * uint16_t example: 0b10000000'11100001 ==> 0b00000001'11000010. + * + * @tparam T Integer type + * @tparam L Length of array + * @param x Array of integers, nullptr not acceptable! + * @param len Number of elements + */ +template +constexpr void shift_left(T (&x)[L]) { + for (int i = L - 1; i > 0; --i) { + x[i] <<= 1; + x[i] |= x[i - 1] >> bit_wrap(); + } + x[0] <<= 1; +} + +} // namespace utl #endif \ No newline at end of file diff --git a/dev/boot/BootKit/Support.h b/dev/boot/BootKit/Support.h index 72aac293..6e1407c2 100644 --- a/dev/boot/BootKit/Support.h +++ b/dev/boot/BootKit/Support.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,7 +13,7 @@ #include #endif -#define kLongMax ((long)(~0UL >> 1)) +#define kLongMax ((long) (~0UL >> 1)) #define kLongMin (~kLongMax) #ifdef __BOOTZ__ @@ -40,134 +40,104 @@ EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight); #include -#endif // __BOOTZ__ +#endif // __BOOTZ__ -#define SetMem(dst, c, sz) memset(dst, c, sz) +#define SetMem(dst, c, sz) memset(dst, c, sz) #define MoveMem(dst, src, sz) memcpy(dst, src, sz) #define CopyMem(dst, src, sz) memcpy(dst, src, sz) -#define StrLen(src) strlen(src) -#define StrCmp(dst, src) strcmp(dst, src) +#define StrLen(src) strlen(src) +#define StrCmp(dst, src) strcmp(dst, src) -inline int IsSpace(int c) -{ - return c == ' '; +inline int IsSpace(int c) { + return c == ' '; } -inline int StringNCompare(const char* destination, const char* source, long length) -{ - long err = 0; +inline int StringNCompare(const char* destination, const char* source, long length) { + long err = 0; - for (long i = 0UL; i < length; ++i) - { - if (source[i] != destination[i]) - ++err; - } + for (long i = 0UL; i < length; ++i) { + if (source[i] != destination[i]) ++err; + } - return err; + return err; } -inline long StringToLong(const char* nptr, char** endptr, int base) -{ - const char *p = nptr, *endp; - bool is_neg = 0, overflow = 0; - - /* Need unsigned so (-kLongMin) can fit in these: */ - unsigned long n = 0UL, cutoff; - int cutlim; - - if (base < 0 || base == 1 || base > 36) - { - return 0L; - } - - endp = nptr; - - while (IsSpace(*p)) - p++; - - if (*p == '+') - { - p++; - } - else if (*p == '-') - { - is_neg = 1, p++; - } - if (*p == '0') - { - p++; - /* For strtol(" 0xZ", &endptr, 16), endptr should point to 'x'; - * pointing to ' ' or '0' is non-compliant. - * (Many implementations do this wrong.) */ - endp = p; - if (base == 16 && (*p == 'X' || *p == 'x')) - { - p++; - } - else if (base == 2 && (*p == 'B' || *p == 'b')) - { - /* C23 standard supports "0B" and "0b" prefixes. */ - p++; - } - else if (base == 0) - { - if (*p == 'X' || *p == 'x') - { - base = 16, p++; - } - else if (*p == 'B' || *p == 'b') - { - base = 2, p++; - } - else - { - base = 8; - } - } - } - else if (base == 0) - { - base = 10; - } - - cutoff = (is_neg) ? -(kLongMin / base) : kLongMax / base; - cutlim = (is_neg) ? -(kLongMin % base) : kLongMax % base; - - while (1) - { - int c; - if (*p >= 'A') - c = ((*p - 'A') & (~('a' ^ 'A'))) + 10; - else if (*p <= '9') - c = *p - '0'; - else - break; - if (c < 0 || c >= base) - break; - endp = ++p; - if (overflow) - { - /* endptr should go forward and point to the non-digit character - * (of the given base); required by ANSI standard. */ - if (endptr) - continue; - break; - } - if (n > cutoff || (n == cutoff && c > cutlim)) - { - overflow = 1; - continue; - } - n = n * base + c; - } - - if (endptr) - *endptr = (char*)endp; - - if (overflow) - { - return ((is_neg) ? kLongMin : kLongMax); - } - - return (long)((is_neg) ? -n : n); +inline long StringToLong(const char* nptr, char** endptr, int base) { + const char *p = nptr, *endp; + bool is_neg = 0, overflow = 0; + + /* Need unsigned so (-kLongMin) can fit in these: */ + unsigned long n = 0UL, cutoff; + int cutlim; + + if (base < 0 || base == 1 || base > 36) { + return 0L; + } + + endp = nptr; + + while (IsSpace(*p)) p++; + + if (*p == '+') { + p++; + } else if (*p == '-') { + is_neg = 1, p++; + } + if (*p == '0') { + p++; + /* For strtol(" 0xZ", &endptr, 16), endptr should point to 'x'; + * pointing to ' ' or '0' is non-compliant. + * (Many implementations do this wrong.) */ + endp = p; + if (base == 16 && (*p == 'X' || *p == 'x')) { + p++; + } else if (base == 2 && (*p == 'B' || *p == 'b')) { + /* C23 standard supports "0B" and "0b" prefixes. */ + p++; + } else if (base == 0) { + if (*p == 'X' || *p == 'x') { + base = 16, p++; + } else if (*p == 'B' || *p == 'b') { + base = 2, p++; + } else { + base = 8; + } + } + } else if (base == 0) { + base = 10; + } + + cutoff = (is_neg) ? -(kLongMin / base) : kLongMax / base; + cutlim = (is_neg) ? -(kLongMin % base) : kLongMax % base; + + while (1) { + int c; + if (*p >= 'A') + c = ((*p - 'A') & (~('a' ^ 'A'))) + 10; + else if (*p <= '9') + c = *p - '0'; + else + break; + if (c < 0 || c >= base) break; + endp = ++p; + if (overflow) { + /* endptr should go forward and point to the non-digit character + * (of the given base); required by ANSI standard. */ + if (endptr) continue; + break; + } + if (n > cutoff || (n == cutoff && c > cutlim)) { + overflow = 1; + continue; + } + n = n * base + c; + } + + if (endptr) *endptr = (char*) endp; + + if (overflow) { + return ((is_neg) ? kLongMin : kLongMax); + } + + return (long) ((is_neg) ? -n : n); } diff --git a/dev/boot/modules/BootNet/BootNet.cc b/dev/boot/modules/BootNet/BootNet.cc index 3e025949..840aabd5 100644 --- a/dev/boot/modules/BootNet/BootNet.cc +++ b/dev/boot/modules/BootNet/BootNet.cc @@ -7,117 +7,110 @@ * ======================================================== */ -#include -#include #include #include +#include +#include -STATIC EfiGUID kEfiSimpleProtoGUID = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; -STATIC EFI_SIMPLE_NETWORK_PROTOCOL* kEfiProtocol = nullptr; +STATIC EfiGUID kEfiSimpleProtoGUID = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; +STATIC EFI_SIMPLE_NETWORK_PROTOCOL* kEfiProtocol = nullptr; -STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet, BOOTNET_INTERNET_HEADER** inet_out); +STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet, + BOOTNET_INTERNET_HEADER** inet_out); -EXTERN_C Int32 BootNetModuleMain(Kernel::HEL::BootInfoHeader* handover) -{ - fw_init_efi((EfiSystemTable*)handover->f_FirmwareCustomTables[1]); +EXTERN_C Int32 BootNetModuleMain(Kernel::HEL::BootInfoHeader* handover) { + fw_init_efi((EfiSystemTable*) handover->f_FirmwareCustomTables[1]); - Boot::BootTextWriter writer; + Boot::BootTextWriter writer; - writer.Write("BootNet: Init BootNet...\r"); + writer.Write("BootNet: Init BootNet...\r"); - if (BS->LocateProtocol(&kEfiSimpleProtoGUID, nullptr, (VoidPtr*)&kEfiProtocol) != kEfiOk) - { - writer.Write("BootNet: Not supported by firmware.\r"); - return kEfiFail; - } + if (BS->LocateProtocol(&kEfiSimpleProtoGUID, nullptr, (VoidPtr*) &kEfiProtocol) != kEfiOk) { + writer.Write("BootNet: Not supported by firmware.\r"); + return kEfiFail; + } - BOOTNET_INTERNET_HEADER inet{}; - BOOTNET_INTERNET_HEADER* inet_out = nullptr; + BOOTNET_INTERNET_HEADER inet{}; + BOOTNET_INTERNET_HEADER* inet_out = nullptr; - SetMem(&inet, 0, sizeof(BOOTNET_INTERNET_HEADER)); + SetMem(&inet, 0, sizeof(BOOTNET_INTERNET_HEADER)); - writer.Write("BootNet: Downloading kernel...\r"); + writer.Write("BootNet: Downloading kernel...\r"); - bootnet_read_ip_packet(inet, &inet_out); + bootnet_read_ip_packet(inet, &inet_out); - if (inet_out->Length < 1) - { - writer.Write("BootNet: No executable attached to the packet, aborting.\r"); - return kEfiFail; - } + if (inet_out->Length < 1) { + writer.Write("BootNet: No executable attached to the packet, aborting.\r"); + return kEfiFail; + } - if (!inet_out->ImpliesProgram) - { - Boot::BootThread thread(inet_out->Data); + if (!inet_out->ImpliesProgram) { + Boot::BootThread thread(inet_out->Data); - if (thread.IsValid()) - { - writer.Write("BootNet: Running kernel...\r"); - return thread.Start(handover, YES); - } + if (thread.IsValid()) { + writer.Write("BootNet: Running kernel...\r"); + return thread.Start(handover, YES); + } - return kEfiFail; - } - else - { - constexpr auto kROMSize = 0x200; + return kEfiFail; + } else { + constexpr auto kROMSize = 0x200; - if (inet_out->Length > kROMSize) - { - writer.Write("BootNet: Not within 512K.\r"); - return kEfiFail; - } + if (inet_out->Length > kROMSize) { + writer.Write("BootNet: Not within 512K.\r"); + return kEfiFail; + } - writer.Write("BootNet: Programming the flash...\r"); + writer.Write("BootNet: Programming the flash...\r"); - /// TODO: Program new firmware to EEPROM (if crc and size matches) + /// TODO: Program new firmware to EEPROM (if crc and size matches) - const ATTRIBUTE(unused) UIntPtr kEEPROMStartAddress = 0; - const ATTRIBUTE(unused) UInt16 kEEPROMSize = inet_out->Length; + const ATTRIBUTE(unused) UIntPtr kEEPROMStartAddress = 0; + const ATTRIBUTE(unused) UInt16 kEEPROMSize = inet_out->Length; - return kEfiFail; - } + return kEfiFail; + } - return kEfiFail; + return kEfiFail; } -STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet, BOOTNET_INTERNET_HEADER** inet_out) -{ - NE_UNUSED(inet); +STATIC Void bootnet_read_ip_packet(BOOTNET_INTERNET_HEADER inet, + BOOTNET_INTERNET_HEADER** inet_out) { + NE_UNUSED(inet); - kEfiProtocol->Start(kEfiProtocol); + kEfiProtocol->Start(kEfiProtocol); - UInt32 size_inet = sizeof(inet); + UInt32 size_inet = sizeof(inet); - /// Connect to the local BootNet server. + /// Connect to the local BootNet server. - /// And receive the handshake packet. - if (kEfiProtocol->Receive(kEfiProtocol, &size_inet, (UInt32*)&inet.Length, (VoidPtr)&inet, nullptr, nullptr, nullptr) == kEfiOk) - { - BOOTNET_INTERNET_HEADER* out = nullptr; + /// And receive the handshake packet. + if (kEfiProtocol->Receive(kEfiProtocol, &size_inet, (UInt32*) &inet.Length, (VoidPtr) &inet, + nullptr, nullptr, nullptr) == kEfiOk) { + BOOTNET_INTERNET_HEADER* out = nullptr; - BS->AllocatePool(EfiLoaderData, sizeof(BOOTNET_INTERNET_HEADER) + inet.Length, (VoidPtr*)&out); + BS->AllocatePool(EfiLoaderData, sizeof(BOOTNET_INTERNET_HEADER) + inet.Length, (VoidPtr*) &out); - if (out == nullptr) - { - kEfiProtocol->Stop(kEfiProtocol); - kEfiProtocol->Shutdown(kEfiProtocol); - return; - } + if (out == nullptr) { + kEfiProtocol->Stop(kEfiProtocol); + kEfiProtocol->Shutdown(kEfiProtocol); + return; + } - SetMem(out, 0, sizeof(BOOTNET_INTERNET_HEADER)); - SetMem(out->Data, 0, inet.Length); + SetMem(out, 0, sizeof(BOOTNET_INTERNET_HEADER)); + SetMem(out->Data, 0, inet.Length); - size_inet = sizeof(BOOTNET_INTERNET_HEADER); + size_inet = sizeof(BOOTNET_INTERNET_HEADER); - auto full_size = size_inet + inet.Length; + auto full_size = size_inet + inet.Length; - /// Ask for it again since we know the full_size variable now. - kEfiProtocol->Receive(kEfiProtocol, &size_inet, (UInt32*)&full_size, (VoidPtr)out, nullptr, nullptr, nullptr); + /// Ask for it again since we know the full_size variable now. + kEfiProtocol->Receive(kEfiProtocol, &size_inet, (UInt32*) &full_size, (VoidPtr) out, nullptr, + nullptr, nullptr); - *inet_out = out; - } + *inet_out = out; + } - kEfiProtocol->Stop(kEfiProtocol); - kEfiProtocol->Shutdown(kEfiProtocol); + kEfiProtocol->Stop(kEfiProtocol); + kEfiProtocol->Shutdown(kEfiProtocol); } \ No newline at end of file diff --git a/dev/boot/modules/SysChk/SysChk.cc b/dev/boot/modules/SysChk/SysChk.cc index 032c031d..a3697bb1 100644 --- a/dev/boot/modules/SysChk/SysChk.cc +++ b/dev/boot/modules/SysChk/SysChk.cc @@ -8,8 +8,7 @@ */ #include -#include -#include +#include #include #include #include @@ -18,28 +17,26 @@ #include #include #include -#include #include +#include // Makes the compiler shut up. #ifndef kMachineModel #define kMachineModel "OS" -#endif // !kMachineModel +#endif // !kMachineModel -EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) -{ +EXTERN_C Int32 SysChkModuleMain(Kernel::HEL::BootInfoHeader* handover) { #if defined(__ATA_PIO__) - fw_init_efi((EfiSystemTable*)handover->f_FirmwareCustomTables[1]); + fw_init_efi((EfiSystemTable*) handover->f_FirmwareCustomTables[1]); - Boot::BDiskFormatFactory partition_factory; + Boot::BDiskFormatFactory partition_factory; - if (partition_factory.IsPartitionValid()) - return kEfiOk; + if (partition_factory.IsPartitionValid()) return kEfiOk; - return partition_factory.Format(kMachineModel) == YES; + return partition_factory.Format(kMachineModel) == YES; #else - NE_UNUSED(handover); + NE_UNUSED(handover); - return kEfiOk; + return kEfiOk; #endif } diff --git a/dev/boot/src/BootFileReader.cc b/dev/boot/src/BootFileReader.cc index 1236b7f0..32060bd7 100644 --- a/dev/boot/src/BootFileReader.cc +++ b/dev/boot/src/BootFileReader.cc @@ -1,18 +1,18 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: FileReader.cc - Purpose: New Boot FileReader, - Read complete file and store it in a buffer. + File: FileReader.cc + Purpose: New Boot FileReader, + Read complete file and store it in a buffer. ------------------------------------------- */ +#include #include #include -#include -#include #include +#include #include /// @file BootFileReader @@ -29,178 +29,149 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// /*** - @brief File Reader constructor. + @brief File Reader constructor. */ -Boot::BootFileReader::BootFileReader(const CharacterTypeUTF16* path, - EfiHandlePtr ImageHandle) -{ - if (path != nullptr) - { - SizeT index = 0UL; - for (; path[index] != L'\0'; ++index) - { - mPath[index] = path[index]; - } - - mPath[index] = 0; - } - - /// Load protocols with their GUIDs. - - EfiGUID guidEfp = EfiGUID(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID); - - EfiSimpleFilesystemProtocol* efp = nullptr; - - EfiLoadImageProtocol* img = nullptr; - EfiGUID guidImg = EfiGUID(EFI_LOADED_IMAGE_PROTOCOL_GUID); - - if (BS->HandleProtocol(ImageHandle, &guidImg, (void**)&img) != kEfiOk) - { - mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); - this->mErrorCode = kNotSupported; - } - - if (BS->HandleProtocol(img->DeviceHandle, &guidEfp, (void**)&efp) != kEfiOk) - { - mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); - this->mErrorCode = kNotSupported; - return; - } - - /// Start doing disk I/O - - if (efp->OpenVolume(efp, &mRootFs) != kEfiOk) - { - mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Volume").Write(L"\r"); - this->mErrorCode = kNotSupported; - return; - } - - EfiFileProtocol* fileFs = nullptr; - - if (mRootFs->Open(mRootFs, &fileFs, mPath, kEFIFileRead, kEFIReadOnly) != - kEfiOk) - { - mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Path: ") - .Write(mPath) - .Write(L"\r"); - this->mErrorCode = kNotSupported; - - fb_render_string("BootZ: PLEASE RECOVER YOUR MINKRNL INSTALL.", 40, 10, RGB(0xFF, 0xFF, 0xFF)); - - mRootFs->Close(mRootFs); - - return; - } - - mSizeFile = 0; - mFile = fileFs; - mErrorCode = kOperationOkay; +Boot::BootFileReader::BootFileReader(const CharacterTypeUTF16* path, EfiHandlePtr ImageHandle) { + if (path != nullptr) { + SizeT index = 0UL; + for (; path[index] != L'\0'; ++index) { + mPath[index] = path[index]; + } + + mPath[index] = 0; + } + + /// Load protocols with their GUIDs. + + EfiGUID guidEfp = EfiGUID(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID); + + EfiSimpleFilesystemProtocol* efp = nullptr; + + EfiLoadImageProtocol* img = nullptr; + EfiGUID guidImg = EfiGUID(EFI_LOADED_IMAGE_PROTOCOL_GUID); + + if (BS->HandleProtocol(ImageHandle, &guidImg, (void**) &img) != kEfiOk) { + mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); + this->mErrorCode = kNotSupported; + } + + if (BS->HandleProtocol(img->DeviceHandle, &guidEfp, (void**) &efp) != kEfiOk) { + mWriter.Write(L"BootZ: Handle-Protocol: No-Such-Protocol").Write(L"\r"); + this->mErrorCode = kNotSupported; + return; + } + + /// Start doing disk I/O + + if (efp->OpenVolume(efp, &mRootFs) != kEfiOk) { + mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Volume").Write(L"\r"); + this->mErrorCode = kNotSupported; + return; + } + + EfiFileProtocol* fileFs = nullptr; + + if (mRootFs->Open(mRootFs, &fileFs, mPath, kEFIFileRead, kEFIReadOnly) != kEfiOk) { + mWriter.Write(L"BootZ: Fetch-Protocol: No-Such-Path: ").Write(mPath).Write(L"\r"); + this->mErrorCode = kNotSupported; + + fb_render_string("BootZ: PLEASE RECOVER YOUR MINKRNL INSTALL.", 40, 10, RGB(0xFF, 0xFF, 0xFF)); + + mRootFs->Close(mRootFs); + + return; + } + + mSizeFile = 0; + mFile = fileFs; + mErrorCode = kOperationOkay; } -Boot::BootFileReader::~BootFileReader() -{ - if (this->mFile) - { - this->mFile->Close(this->mFile); - this->mFile = nullptr; - } - - if (this->mRootFs) - { - this->mRootFs->Close(this->mRootFs); - this->mRootFs = nullptr; - } - - if (this->mBlob) - { - BS->FreePool(this->mBlob); - this->mBlob = nullptr; - } - - BSetMem(this->mPath, 0, kPathLen); +Boot::BootFileReader::~BootFileReader() { + if (this->mFile) { + this->mFile->Close(this->mFile); + this->mFile = nullptr; + } + + if (this->mRootFs) { + this->mRootFs->Close(this->mRootFs); + this->mRootFs = nullptr; + } + + if (this->mBlob) { + BS->FreePool(this->mBlob); + this->mBlob = nullptr; + } + + BSetMem(this->mPath, 0, kPathLen); } /** - @brief Reads all of the file into a buffer. - @param **readUntil** size of file - @param **chunkToRead** chunk to read each time. + @brief Reads all of the file into a buffer. + @param **readUntil** size of file + @param **chunkToRead** chunk to read each time. */ -Void Boot::BootFileReader::ReadAll(SizeT readUntil, SizeT chunkToRead, UIntPtr out_address) -{ - UInt32 szInfo = sizeof(EfiFileInfo); - - EfiFileInfo newPtrInfo{}; - - EfiGUID kFileInfoGUID = EFI_FILE_INFO_GUID; - - if (mFile->GetInfo(mFile, &kFileInfoGUID, &szInfo, &newPtrInfo) == kEfiOk) - { - readUntil = newPtrInfo.FileSize; - mWriter.Write(L"BootZ: File size: ").Write(readUntil).Write("\r"); - } - - if (readUntil == 0) - { - mErrorCode = kNotSupported; - return; - } - - if (mBlob == nullptr) - { - if (!out_address) - { - if (auto err = BS->AllocatePool(EfiLoaderCode, readUntil, (VoidPtr*)&mBlob) != - kEfiOk) - { - mWriter.Write(L"*** error: ").Write(err).Write(L" ***\r"); - Boot::ThrowError(L"OutOfMemory", L"Out of memory."); - } - } - else - { - mBlob = (VoidPtr)out_address; - } - } - - mWriter.Write(L"*** Bytes to read: ").Write(readUntil).Write(L" ***\r"); - - UInt64 bufSize = chunkToRead; - UInt64 szCnt = 0UL; - - while (szCnt < readUntil) - { - auto res = mFile->Read(mFile, &bufSize, (VoidPtr)(&((Char*)mBlob)[szCnt])); - - szCnt += bufSize; - - if (res == kBufferTooSmall) - { - bufSize = chunkToRead; - } - } - - mSizeFile = szCnt; - mErrorCode = kOperationOkay; +Void Boot::BootFileReader::ReadAll(SizeT readUntil, SizeT chunkToRead, UIntPtr out_address) { + UInt32 szInfo = sizeof(EfiFileInfo); + + EfiFileInfo newPtrInfo{}; + + EfiGUID kFileInfoGUID = EFI_FILE_INFO_GUID; + + if (mFile->GetInfo(mFile, &kFileInfoGUID, &szInfo, &newPtrInfo) == kEfiOk) { + readUntil = newPtrInfo.FileSize; + mWriter.Write(L"BootZ: File size: ").Write(readUntil).Write("\r"); + } + + if (readUntil == 0) { + mErrorCode = kNotSupported; + return; + } + + if (mBlob == nullptr) { + if (!out_address) { + if (auto err = BS->AllocatePool(EfiLoaderCode, readUntil, (VoidPtr*) &mBlob) != kEfiOk) { + mWriter.Write(L"*** error: ").Write(err).Write(L" ***\r"); + Boot::ThrowError(L"OutOfMemory", L"Out of memory."); + } + } else { + mBlob = (VoidPtr) out_address; + } + } + + mWriter.Write(L"*** Bytes to read: ").Write(readUntil).Write(L" ***\r"); + + UInt64 bufSize = chunkToRead; + UInt64 szCnt = 0UL; + + while (szCnt < readUntil) { + auto res = mFile->Read(mFile, &bufSize, (VoidPtr) (&((Char*) mBlob)[szCnt])); + + szCnt += bufSize; + + if (res == kBufferTooSmall) { + bufSize = chunkToRead; + } + } + + mSizeFile = szCnt; + mErrorCode = kOperationOkay; } /// @brief error code getter. /// @return the error code. -Int32& Boot::BootFileReader::Error() -{ - return mErrorCode; +Int32& Boot::BootFileReader::Error() { + return mErrorCode; } /// @brief blob getter. /// @return the blob. -VoidPtr Boot::BootFileReader::Blob() -{ - return mBlob; +VoidPtr Boot::BootFileReader::Blob() { + return mBlob; } /// @breif Size getter. /// @return the size of the file. -UInt64& Boot::BootFileReader::Size() -{ - return mSizeFile; +UInt64& Boot::BootFileReader::Size() { + return mSizeFile; } diff --git a/dev/boot/src/BootString.cc b/dev/boot/src/BootString.cc index 7efa5bca..8762a151 100644 --- a/dev/boot/src/BootString.cc +++ b/dev/boot/src/BootString.cc @@ -1,92 +1,81 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: BootString.cc - Purpose: BootZ string library + File: BootString.cc + Purpose: BootZ string library - Revision History: + Revision History: ------------------------------------------- */ +#include #include #include -#include /// BUGS: 0 ///////////////////////////////////////////////////////////////////////////////////////////////////////// -Kernel::SizeT Boot::BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, const Kernel::SizeT len) -{ - if (!dest || !src) - return 0; +Kernel::SizeT Boot::BCopyMem(CharacterTypeUTF16* dest, CharacterTypeUTF16* src, + const Kernel::SizeT len) { + if (!dest || !src) return 0; - SizeT index = 0UL; - for (; index < len; ++index) - { - dest[index] = src[index]; - } + SizeT index = 0UL; + for (; index < len; ++index) { + dest[index] = src[index]; + } - return index; + return index; } -Kernel::SizeT Boot::BStrLen(const CharacterTypeUTF16* ptr) -{ - if (!ptr) - return 0; +Kernel::SizeT Boot::BStrLen(const CharacterTypeUTF16* ptr) { + if (!ptr) return 0; - Kernel::SizeT cnt = 0; + Kernel::SizeT cnt = 0; - while (*ptr != (CharacterTypeUTF16)0) - { - ++ptr; - ++cnt; - } + while (*ptr != (CharacterTypeUTF16) 0) { + ++ptr; + ++cnt; + } - return cnt; + return cnt; } -Kernel::SizeT Boot::BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, const Kernel::SizeT len) -{ - if (!src) - return 0; +Kernel::SizeT Boot::BSetMem(CharacterTypeUTF16* src, const CharacterTypeUTF16 byte, + const Kernel::SizeT len) { + if (!src) return 0; - Kernel::SizeT cnt = 0UL; + Kernel::SizeT cnt = 0UL; - while (*src != 0) - { - if (cnt > len) - break; + while (*src != 0) { + if (cnt > len) break; - *src = byte; - ++src; + *src = byte; + ++src; - ++cnt; - } + ++cnt; + } - return cnt; + return cnt; } -Kernel::SizeT Boot::BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, const Kernel::SizeT len) -{ - if (!src) - return 0; +Kernel::SizeT Boot::BSetMem(CharacterTypeUTF8* src, const CharacterTypeUTF8 byte, + const Kernel::SizeT len) { + if (!src) return 0; - Kernel::SizeT cnt = 0UL; + Kernel::SizeT cnt = 0UL; - while (*src != 0) - { - if (cnt > len) - break; + while (*src != 0) { + if (cnt > len) break; - *src = byte; - ++src; + *src = byte; + ++src; - ++cnt; - } + ++cnt; + } - return cnt; + return cnt; } diff --git a/dev/boot/src/BootSupport.cc b/dev/boot/src/BootSupport.cc index ade8ed01..ce824e0f 100644 --- a/dev/boot/src/BootSupport.cc +++ b/dev/boot/src/BootSupport.cc @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include +#include #include #include #include -#include #include #include @@ -18,62 +18,51 @@ /// @param dst destination pointer. /// @param byte value to fill in. /// @param len length of of src. -EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) -{ - for (size_t i = 0UL; i < len; ++i) - { - ((int*)dst)[i] = byte; - } - - return dst; +EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) { + for (size_t i = 0UL; i < len; ++i) { + ((int*) dst)[i] = byte; + } + + return dst; } /// @brief memcpy definition in C++. /// @param dst destination pointer. /// @param src source pointer. /// @param len length of of src. -EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) -{ - for (size_t i = 0UL; i < len; ++i) - { - ((int*)dst)[i] = ((int*)src)[i]; - } - - return dst; +EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) { + for (size_t i = 0UL; i < len; ++i) { + ((int*) dst)[i] = ((int*) src)[i]; + } + + return dst; } /// @brief strlen definition in C++. -EXTERN_C size_t strlen(const char* whatToCheck) -{ - SizeT len = 0; +EXTERN_C size_t strlen(const char* whatToCheck) { + SizeT len = 0; - while (whatToCheck[len] != 0) - { - ++len; - } + while (whatToCheck[len] != 0) { + ++len; + } - return len; + return len; } /// @brief strcmp definition in C++. -EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) -{ - SizeT len = 0; +EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) { + SizeT len = 0; - while (whatToCheck[len] == whatToCheckRight[len]) - { - if (whatToCheck[len] == 0) - return 0; + while (whatToCheck[len] == whatToCheckRight[len]) { + if (whatToCheck[len] == 0) return 0; - ++len; - } + ++len; + } - return len; + return len; } /// @brief something specific to the Microsoft's ABI, When the stack grows too big. -EXTERN_C void ___chkstk_ms(void) -{ -} +EXTERN_C void ___chkstk_ms(void) {} #endif diff --git a/dev/boot/src/BootTextWriter.cc b/dev/boot/src/BootTextWriter.cc index 95e248a2..5e826c6d 100644 --- a/dev/boot/src/BootTextWriter.cc +++ b/dev/boot/src/BootTextWriter.cc @@ -1,20 +1,20 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: BootTextWriter.cc - Purpose: BootZ string library + File: BootTextWriter.cc + Purpose: BootZ string library - Revision History: + Revision History: ------------------------------------------- */ -#include +#include #include #include -#include +#include ///////////////////////////////////////////////////////////////////////////////////////////////////////// /// BUGS: 0 /// @@ -23,147 +23,123 @@ /** @brief puts wrapper over EFI ConOut. */ -Boot::BootTextWriter& Boot::BootTextWriter::Write(const CharacterTypeUTF16* str) -{ +Boot::BootTextWriter& Boot::BootTextWriter::Write(const CharacterTypeUTF16* str) { #ifdef __DEBUG__ - if (!str || *str == 0) - return *this; - - CharacterTypeUTF16 strTmp[2]; - strTmp[1] = 0; - - for (size_t i = 0; str[i] != 0; i++) - { - if (str[i] == '\r') - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - - strTmp[0] = '\n'; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - else - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - } -#endif // ifdef __DEBUG__ - - return *this; + if (!str || *str == 0) return *this; + + CharacterTypeUTF16 strTmp[2]; + strTmp[1] = 0; + + for (size_t i = 0; str[i] != 0; i++) { + if (str[i] == '\r') { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + + strTmp[0] = '\n'; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } else { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + } +#endif // ifdef __DEBUG__ + + return *this; } /// @brief UTF-8 equivalent of Write (UTF-16). /// @param str the input string. -Boot::BootTextWriter& Boot::BootTextWriter::Write(const Char* str) -{ +Boot::BootTextWriter& Boot::BootTextWriter::Write(const Char* str) { #ifdef __DEBUG__ - if (!str || *str == 0) - return *this; - - CharacterTypeUTF16 strTmp[2]; - strTmp[1] = 0; - - for (size_t i = 0; str[i] != 0; i++) - { - if (str[i] == '\r') - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - - strTmp[0] = '\n'; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - else - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - } -#endif // ifdef __DEBUG__ - - return *this; + if (!str || *str == 0) return *this; + + CharacterTypeUTF16 strTmp[2]; + strTmp[1] = 0; + + for (size_t i = 0; str[i] != 0; i++) { + if (str[i] == '\r') { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + + strTmp[0] = '\n'; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } else { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + } +#endif // ifdef __DEBUG__ + + return *this; } -Boot::BootTextWriter& Boot::BootTextWriter::Write(const UChar* str) -{ +Boot::BootTextWriter& Boot::BootTextWriter::Write(const UChar* str) { #ifdef __DEBUG__ - if (!str || *str == 0) - return *this; - - CharacterTypeUTF16 strTmp[2]; - strTmp[1] = 0; - - for (size_t i = 0; str[i] != 0; i++) - { - if (str[i] == '\r') - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - - strTmp[0] = '\n'; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - else - { - strTmp[0] = str[i]; - ST->ConOut->OutputString(ST->ConOut, strTmp); - } - } -#endif // ifdef __DEBUG__ - - return *this; + if (!str || *str == 0) return *this; + + CharacterTypeUTF16 strTmp[2]; + strTmp[1] = 0; + + for (size_t i = 0; str[i] != 0; i++) { + if (str[i] == '\r') { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + + strTmp[0] = '\n'; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } else { + strTmp[0] = str[i]; + ST->ConOut->OutputString(ST->ConOut, strTmp); + } + } +#endif // ifdef __DEBUG__ + + return *this; } /** @brief putc wrapper over EFI ConOut. */ -Boot::BootTextWriter& Boot::BootTextWriter::WriteCharacter(CharacterTypeUTF16 c) -{ +Boot::BootTextWriter& Boot::BootTextWriter::WriteCharacter(CharacterTypeUTF16 c) { #ifdef __DEBUG__ - EfiCharType str[2]; + EfiCharType str[2]; - str[0] = c; - str[1] = 0; - ST->ConOut->OutputString(ST->ConOut, str); -#endif // ifdef __DEBUG__ + str[0] = c; + str[1] = 0; + ST->ConOut->OutputString(ST->ConOut, str); +#endif // ifdef __DEBUG__ - return *this; + return *this; } -Boot::BootTextWriter& Boot::BootTextWriter::Write(const UInt64& x) -{ +Boot::BootTextWriter& Boot::BootTextWriter::Write(const UInt64& x) { #ifdef __DEBUG__ - this->_Write(x); - this->Write("h"); -#endif // ifdef __DEBUG__ + this->_Write(x); + this->Write("h"); +#endif // ifdef __DEBUG__ - return *this; + return *this; } -Boot::BootTextWriter& Boot::BootTextWriter::_Write(const UInt64& x) -{ +Boot::BootTextWriter& Boot::BootTextWriter::_Write(const UInt64& x) { #ifdef __DEBUG__ - UInt64 y = (x > 0 ? x : -x) / 16; - UInt64 h = (x > 0 ? x : -x) % 16; + UInt64 y = (x > 0 ? x : -x) / 16; + UInt64 h = (x > 0 ? x : -x) % 16; - if (y) - this->_Write(y); + if (y) this->_Write(y); - /* fail if the hex number is not base-16 */ - if (h > 16) - { - this->WriteCharacter('?'); - return *this; - } + /* fail if the hex number is not base-16 */ + if (h > 16) { + this->WriteCharacter('?'); + return *this; + } - if (y == ~0UL) - y = -y; + if (y == ~0UL) y = -y; - const char cNumbers[] = "0123456789ABCDEF"; + const char cNumbers[] = "0123456789ABCDEF"; - this->WriteCharacter(cNumbers[h]); -#endif // ifdef __DEBUG__ + this->WriteCharacter(cNumbers[h]); +#endif // ifdef __DEBUG__ - return *this; + return *this; } diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index b6236df8..ada864bb 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -1,18 +1,18 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include #include -#include -#include -#include #include +#include +#include +#include #include /// @brief External boot services symbol. @@ -20,211 +20,187 @@ EXTERN EfiBootServices* BS; /// @note BootThread doesn't parse the symbols so doesn't nullify them, .bss is though. -namespace Boot -{ - EXTERN_C Int32 rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack); +namespace Boot { +EXTERN_C Int32 rt_jump_to_address(VoidPtr code, HEL::BootInfoHeader* handover, UInt8* stack); - BootThread::BootThread(VoidPtr blob) - : fStartAddress(nullptr), fBlob(blob) - { - // detect the format. - const Char* blob_bytes = reinterpret_cast(fBlob); +BootThread::BootThread(VoidPtr blob) : fStartAddress(nullptr), fBlob(blob) { + // detect the format. + const Char* blob_bytes = reinterpret_cast(fBlob); - BootTextWriter writer; + BootTextWriter writer; - if (!blob_bytes) - { - // failed to provide a valid pointer. - return; - } + if (!blob_bytes) { + // failed to provide a valid pointer. + return; + } - if (blob_bytes[0] == kMagMz0 && - blob_bytes[1] == kMagMz1) - { - LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header(blob_bytes); - LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header(blob_bytes); + if (blob_bytes[0] == kMagMz0 && blob_bytes[1] == kMagMz1) { + LDR_EXEC_HEADER_PTR header_ptr = CF::ldr_find_exec_header(blob_bytes); + LDR_OPTIONAL_HEADER_PTR opt_header_ptr = CF::ldr_find_opt_exec_header(blob_bytes); - if (!header_ptr || !opt_header_ptr) - return; + if (!header_ptr || !opt_header_ptr) return; #ifdef __NE_AMD64__ - if (header_ptr->Machine != kPeMachineAMD64 || - header_ptr->Signature != kPeSignature) - { - writer.Write("BootZ: Not a PE32+ executable.\r"); - return; - } + if (header_ptr->Machine != kPeMachineAMD64 || header_ptr->Signature != kPeSignature) { + writer.Write("BootZ: Not a PE32+ executable.\r"); + return; + } #elif defined(__NE_ARM64__) - if (header_ptr->Machine != kPeMachineARM64 || - header_ptr->Signature != kPeSignature) - { - writer.Write("BootZ: Not a PE32+ executable.\r"); - return; - } -#endif // __NE_AMD64__ || __NE_ARM64__ - - writer.Write("BootZ: PE32+ executable detected (NeKernel Subsystem).\r"); - - auto numSecs = header_ptr->NumberOfSections; - - writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->MajorLinkerVersion).Write("\r"); - writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->MinorLinkerVersion).Write("\r"); - writer.Write("BootZ: Major Subsystem Ver: ").Write(opt_header_ptr->MajorSubsystemVersion).Write("\r"); - writer.Write("BootZ: Minor Subsystem Ver: ").Write(opt_header_ptr->MinorSubsystemVersion).Write("\r"); - writer.Write("BootZ: Magic: ").Write(header_ptr->Signature).Write("\r"); - - EfiPhysicalAddress loadStartAddress = opt_header_ptr->ImageBase; - loadStartAddress += opt_header_ptr->BaseOfData; - - writer.Write("BootZ: Image base: ").Write(loadStartAddress).Write("\r"); - - fStack = new UInt8[mib_cast(16)]; - - if (!fStack) - { - writer.Write("BootZ: Unable to allocate stack.\r"); - return; - } - - LDR_SECTION_HEADER_PTR sectPtr = (LDR_SECTION_HEADER_PTR)(((Char*)opt_header_ptr) + header_ptr->SizeOfOptionalHeader); - - constexpr auto sectionForCode = ".text"; - constexpr auto sectionForBootZ = ".ldr"; - - for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) - { - LDR_SECTION_HEADER_PTR sect = §Ptr[sectIndex]; - - auto sz = sect->VirtualSize; - - if (sect->SizeOfRawData > 0) - sz = sect->SizeOfRawData; - - SetMem((VoidPtr)(loadStartAddress + sect->VirtualAddress), 0, sz); - - if (sect->SizeOfRawData > 0) - { - CopyMem((VoidPtr)(loadStartAddress + sect->VirtualAddress), - (VoidPtr)((UIntPtr)fBlob + sect->PointerToRawData), - sect->SizeOfRawData); - } - - if (StrCmp(sectionForCode, sect->Name) == 0) - { - fStartAddress = (VoidPtr)((UIntPtr)loadStartAddress + opt_header_ptr->AddressOfEntryPoint); - writer.Write("BootZ: Executable entry address: ").Write((UIntPtr)fStartAddress).Write("\r"); - } - else if (StrCmp(sectionForBootZ, sect->Name) == 0) - { - struct HANDOVER_INFORMATION_STUB - { - UInt64 HandoverMagic; - UInt32 HandoverType; - UInt32 HandoverPad; - UInt32 HandoverArch; - }* handover_struc = (struct HANDOVER_INFORMATION_STUB*)((UIntPtr)fBlob + sect->PointerToRawData); - - if (handover_struc->HandoverMagic != kHandoverMagic) - { + if (header_ptr->Machine != kPeMachineARM64 || header_ptr->Signature != kPeSignature) { + writer.Write("BootZ: Not a PE32+ executable.\r"); + return; + } +#endif // __NE_AMD64__ || __NE_ARM64__ + + writer.Write("BootZ: PE32+ executable detected (NeKernel Subsystem).\r"); + + auto numSecs = header_ptr->NumberOfSections; + + writer.Write("BootZ: Major Linker Ver: ").Write(opt_header_ptr->MajorLinkerVersion).Write("\r"); + writer.Write("BootZ: Minor Linker Ver: ").Write(opt_header_ptr->MinorLinkerVersion).Write("\r"); + writer.Write("BootZ: Major Subsystem Ver: ") + .Write(opt_header_ptr->MajorSubsystemVersion) + .Write("\r"); + writer.Write("BootZ: Minor Subsystem Ver: ") + .Write(opt_header_ptr->MinorSubsystemVersion) + .Write("\r"); + writer.Write("BootZ: Magic: ").Write(header_ptr->Signature).Write("\r"); + + EfiPhysicalAddress loadStartAddress = opt_header_ptr->ImageBase; + loadStartAddress += opt_header_ptr->BaseOfData; + + writer.Write("BootZ: Image base: ").Write(loadStartAddress).Write("\r"); + + fStack = new UInt8[mib_cast(16)]; + + if (!fStack) { + writer.Write("BootZ: Unable to allocate stack.\r"); + return; + } + + LDR_SECTION_HEADER_PTR sectPtr = + (LDR_SECTION_HEADER_PTR) (((Char*) opt_header_ptr) + header_ptr->SizeOfOptionalHeader); + + constexpr auto sectionForCode = ".text"; + constexpr auto sectionForBootZ = ".ldr"; + + for (SizeT sectIndex = 0; sectIndex < numSecs; ++sectIndex) { + LDR_SECTION_HEADER_PTR sect = §Ptr[sectIndex]; + + auto sz = sect->VirtualSize; + + if (sect->SizeOfRawData > 0) sz = sect->SizeOfRawData; + + SetMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), 0, sz); + + if (sect->SizeOfRawData > 0) { + CopyMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), + (VoidPtr) ((UIntPtr) fBlob + sect->PointerToRawData), sect->SizeOfRawData); + } + + if (StrCmp(sectionForCode, sect->Name) == 0) { + fStartAddress = + (VoidPtr) ((UIntPtr) loadStartAddress + opt_header_ptr->AddressOfEntryPoint); + writer.Write("BootZ: Executable entry address: ") + .Write((UIntPtr) fStartAddress) + .Write("\r"); + } else if (StrCmp(sectionForBootZ, sect->Name) == 0) { + struct HANDOVER_INFORMATION_STUB { + UInt64 HandoverMagic; + UInt32 HandoverType; + UInt32 HandoverPad; + UInt32 HandoverArch; + }* handover_struc = + (struct HANDOVER_INFORMATION_STUB*) ((UIntPtr) fBlob + sect->PointerToRawData); + + if (handover_struc->HandoverMagic != kHandoverMagic) { #ifdef __NE_AMD64__ - if (handover_struc->HandoverArch != HEL::kArchAMD64) - { - writer.Write("BootZ: Not an handover header, bad CPU...\r"); - } + if (handover_struc->HandoverArch != HEL::kArchAMD64) { + writer.Write("BootZ: Not an handover header, bad CPU...\r"); + } #elif defined(__NE_ARM64__) - if (handover_struc->HandoverArch != HEL::kArchARM64) - { - writer.Write("BootZ: Not an handover header, bad CPU...\r"); - } + if (handover_struc->HandoverArch != HEL::kArchARM64) { + writer.Write("BootZ: Not an handover header, bad CPU...\r"); + } #endif - writer.Write("BootZ: Not an handover header...\r"); - ::Boot::Stop(); - } - } - - writer.Write("BootZ: Raw offset: ").Write(sect->PointerToRawData).Write(" of ").Write(sect->Name).Write("\r"); - - CopyMem((VoidPtr)(loadStartAddress + sect->VirtualAddress), (VoidPtr)((UIntPtr)fBlob + sect->PointerToRawData), sect->SizeOfRawData); - } - } - else if (blob_bytes[0] == kPefMagic[0] && - blob_bytes[1] == kPefMagic[1] && - blob_bytes[2] == kPefMagic[2] && - blob_bytes[3] == kPefMagic[3]) - { - // ========================================= // - // PEF executable has been detected. - // ========================================= // - - fStartAddress = nullptr; - - writer.Write("BootZ: PEF executable detected, won't load it.\r"); - writer.Write("BootZ: note: PEF executables aren't supported for now.\r"); - } - else - { - writer.Write("BootZ: Invalid Executable.\r"); - } - } - - /// @note handover header has to be valid! - Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) - { - fHandover = handover; - - if (!fStartAddress) - { - return kEfiFail; - } - - if (!fHandover) - { - return kEfiFail; - } - - BootTextWriter writer; - - writer.Write("BootZ: Starting: ").Write(fBlobName).Write("\r"); - writer.Write("BootZ: Handover address: ").Write((UIntPtr)fHandover).Write("\r"); - - if (own_stack) - { - writer.Write("BootZ: Using it's own stack.\r"); - writer.Write("BootZ: Stack address: ").Write((UIntPtr)&fStack[mib_cast(16) - 1]).Write("\r"); - writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); - - auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); - - // we don't need the stack anymore. - - delete[] fStack; - fStack = nullptr; - - return ret; - } - else - { - writer.Write("BootZ: Using Bootloader's stack.\r"); - - return reinterpret_cast(fStartAddress)(fHandover); - } - - return kEfiFail; - } - - const Char* BootThread::GetName() - { - return fBlobName; - } - - Void BootThread::SetName(const Char* name) - { - CopyMem(fBlobName, name, StrLen(name)); - } - - bool BootThread::IsValid() - { - return fStartAddress != nullptr; - } -} // namespace Boot \ No newline at end of file + writer.Write("BootZ: Not an handover header...\r"); + ::Boot::Stop(); + } + } + + writer.Write("BootZ: Raw offset: ") + .Write(sect->PointerToRawData) + .Write(" of ") + .Write(sect->Name) + .Write("\r"); + + CopyMem((VoidPtr) (loadStartAddress + sect->VirtualAddress), + (VoidPtr) ((UIntPtr) fBlob + sect->PointerToRawData), sect->SizeOfRawData); + } + } else if (blob_bytes[0] == kPefMagic[0] && blob_bytes[1] == kPefMagic[1] && + blob_bytes[2] == kPefMagic[2] && blob_bytes[3] == kPefMagic[3]) { + // ========================================= // + // PEF executable has been detected. + // ========================================= // + + fStartAddress = nullptr; + + writer.Write("BootZ: PEF executable detected, won't load it.\r"); + writer.Write("BootZ: note: PEF executables aren't supported for now.\r"); + } else { + writer.Write("BootZ: Invalid Executable.\r"); + } +} + +/// @note handover header has to be valid! +Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) { + fHandover = handover; + + if (!fStartAddress) { + return kEfiFail; + } + + if (!fHandover) { + return kEfiFail; + } + + BootTextWriter writer; + + writer.Write("BootZ: Starting: ").Write(fBlobName).Write("\r"); + writer.Write("BootZ: Handover address: ").Write((UIntPtr) fHandover).Write("\r"); + + if (own_stack) { + writer.Write("BootZ: Using it's own stack.\r"); + writer.Write("BootZ: Stack address: ").Write((UIntPtr) &fStack[mib_cast(16) - 1]).Write("\r"); + writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); + + auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); + + // we don't need the stack anymore. + + delete[] fStack; + fStack = nullptr; + + return ret; + } else { + writer.Write("BootZ: Using Bootloader's stack.\r"); + + return reinterpret_cast(fStartAddress)(fHandover); + } + + return kEfiFail; +} + +const Char* BootThread::GetName() { + return fBlobName; +} + +Void BootThread::SetName(const Char* name) { + CopyMem(fBlobName, name, StrLen(name)); +} + +bool BootThread::IsValid() { + return fStartAddress != nullptr; +} +} // namespace Boot \ No newline at end of file diff --git a/dev/boot/src/HEL/AMD64/BootATA.cc b/dev/boot/src/HEL/AMD64/BootATA.cc index 8b1b5a0a..693513e0 100644 --- a/dev/boot/src/HEL/AMD64/BootATA.cc +++ b/dev/boot/src/HEL/AMD64/BootATA.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -15,9 +15,9 @@ * */ -#include #include #include +#include /// bugs: 0 @@ -25,159 +25,143 @@ using namespace Boot; #define kATADataLen (256) -static Boolean kATADetected = false; +static Boolean kATADetected = false; static UInt16 kATAData[kATADataLen] = {0}; Boolean boot_ata_detected(Void); -STATIC Boolean boot_ata_wait_io(UInt16 IO) -{ - for (int i = 0; i < 400; i++) - rt_in8(IO + ATA_REG_STATUS); +STATIC Boolean boot_ata_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); + auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - if ((status_rdy & ATA_SR_BSY)) - goto ATAWaitForIO_Retry; + if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; ATAWaitForIO_Retry2: - status_rdy = rt_in8(IO + ATA_REG_STATUS); + status_rdy = rt_in8(IO + ATA_REG_STATUS); - if (status_rdy & ATA_SR_ERR) - return false; + if (status_rdy & ATA_SR_ERR) return false; - if (!(status_rdy & ATA_SR_DRDY)) - goto ATAWaitForIO_Retry2; + if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - return true; + return true; } -Void boot_ata_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); +Void boot_ata_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 boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) -{ - NE_UNUSED(Drive); +Boolean boot_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { + NE_UNUSED(Drive); - if (boot_ata_detected()) - return true; + if (boot_ata_detected()) return true; - BootTextWriter writer; + BootTextWriter writer; - UInt16 IO = Bus; + UInt16 IO = Bus; - boot_ata_select(IO); + boot_ata_select(IO); - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); - // identify until it's good. + // identify until it's good. ATAInit_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); + auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - if (status_rdy & ATA_SR_ERR) - { - writer.Write( - L"BootZ: ATA: Not an IDE based drive.\r"); + if (status_rdy & ATA_SR_ERR) { + writer.Write(L"BootZ: ATA: Not an IDE based drive.\r"); - return false; - } + return false; + } - if ((status_rdy & ATA_SR_BSY)) - goto ATAInit_Retry; + if ((status_rdy & ATA_SR_BSY)) goto ATAInit_Retry; - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - /// fetch serial info - /// model, speed, number of sectors... + /// fetch serial info + /// model, speed, number of sectors... - boot_ata_wait_io(IO); + boot_ata_wait_io(IO); - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) - { - kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - } + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { + kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + } - OutBus = - (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; + OutBus = (Bus == ATA_PRIMARY_IO) ? BootDeviceATA::kPrimary : BootDeviceATA::kSecondary; - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - return true; + return true; } -Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; +Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, + SizeT Size) { + Lba /= SectorSz; - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - boot_ata_wait_io(IO); - boot_ata_select(IO); + boot_ata_wait_io(IO); + boot_ata_select(IO); - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + 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_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_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); + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - boot_ata_wait_io(IO); + boot_ata_wait_io(IO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - boot_ata_wait_io(IO); - Buf[IndexOff] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - boot_ata_wait_io(IO); - } + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + boot_ata_wait_io(IO); + Buf[IndexOff] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + boot_ata_wait_io(IO); + } } -Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; +Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, SizeT SectorSz, + SizeT Size) { + Lba /= SectorSz; - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - boot_ata_wait_io(IO); - boot_ata_select(IO); + boot_ata_wait_io(IO); + boot_ata_select(IO); - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + 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_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_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); + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - boot_ata_wait_io(IO); + boot_ata_wait_io(IO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - boot_ata_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); - boot_ata_wait_io(IO); - } + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + boot_ata_wait_io(IO); + rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + boot_ata_wait_io(IO); + } - boot_ata_wait_io(IO); + boot_ata_wait_io(IO); } /// @check is ATA detected? -Boolean boot_ata_detected(Void) -{ - return kATADetected; +Boolean boot_ata_detected(Void) { + return kATADetected; } /*** @@ -192,93 +176,79 @@ Boolean boot_ata_detected(Void) * @brief ATA Device constructor. * @param void none. */ -BootDeviceATA::BootDeviceATA() noexcept -{ - if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, - this->Leak().mMaster) || - boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, - this->Leak().mMaster)) - { - kATADetected = true; - } +BootDeviceATA::BootDeviceATA() noexcept { + if (boot_ata_init(ATA_PRIMARY_IO, true, this->Leak().mBus, this->Leak().mMaster) || + boot_ata_init(ATA_SECONDARY_IO, true, this->Leak().mBus, this->Leak().mMaster)) { + kATADetected = true; + } } /** * @brief Is ATA detected? */ -BootDeviceATA::operator bool() -{ - return boot_ata_detected(); +BootDeviceATA::operator bool() { + return boot_ata_detected(); } /** - @brief Read Buf from disk - @param Sz Sector size - @param Buf buffer + @brief Read Buf from disk + @param Sz Sector size + @param Buf buffer */ -BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) -{ - if (!boot_ata_detected()) - { - Leak().mErr = true; - return *this; - } +BootDeviceATA& BootDeviceATA::Read(CharacterTypeUTF8* Buf, SizeT SectorSz) { + if (!boot_ata_detected()) { + Leak().mErr = true; + return *this; + } - this->Leak().mErr = false; + this->Leak().mErr = false; - if (!Buf || SectorSz < 1) - return *this; + if (!Buf || SectorSz < 1) return *this; - boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, - Buf, SectorSz, this->Leak().mSize); + boot_ata_read(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, + this->Leak().mSize); - return *this; + return *this; } /** - @brief Write Buf into disk - @param Sz Sector size - @param Buf buffer + @brief Write Buf into disk + @param Sz Sector size + @param Buf buffer */ -BootDeviceATA& BootDeviceATA::Write(CharacterTypeUTF8* Buf, SizeT SectorSz) -{ - if (!boot_ata_detected()) - { - Leak().mErr = true; - return *this; - } - - Leak().mErr = false; - - if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) - { - Leak().mErr = true; - return *this; - } - - boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, - Buf, SectorSz, this->Leak().mSize); - - return *this; +BootDeviceATA& BootDeviceATA::Write(CharacterTypeUTF8* Buf, SizeT SectorSz) { + if (!boot_ata_detected()) { + Leak().mErr = true; + return *this; + } + + Leak().mErr = false; + + if (!Buf || SectorSz < 1 || this->Leak().mSize < 1) { + Leak().mErr = true; + return *this; + } + + boot_ata_write(this->Leak().mBase, this->Leak().mBus, this->Leak().mMaster, Buf, SectorSz, + this->Leak().mSize); + + return *this; } /** * @brief ATA trait getter. * @return BootDeviceATA::ATATrait& the drive config. */ -BootDeviceATA::ATATrait& BootDeviceATA::Leak() -{ - return mTrait; +BootDeviceATA::ATATrait& BootDeviceATA::Leak() { + return mTrait; } /*** - @brief Getter, gets the number of sectors inside the drive. + @brief Getter, gets the number of sectors inside the drive. */ -SizeT BootDeviceATA::GetSectorsCount() noexcept -{ - return (kATAData[61] << 16) | kATAData[60]; +SizeT BootDeviceATA::GetSectorsCount() noexcept { + return (kATAData[61] << 16) | kATAData[60]; } -SizeT BootDeviceATA::GetDiskSize() noexcept -{ - return this->GetSectorsCount() * BootDeviceATA::kSectorSize; +SizeT BootDeviceATA::GetDiskSize() noexcept { + return this->GetSectorsCount() * BootDeviceATA::kSectorSize; } diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 6411383d..739876da 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -1,12 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -#include -#include +#include #include #include #include @@ -15,265 +14,249 @@ #include #include #include -#include #include +#include // Makes the compiler shut up. #ifndef kMachineModel #define kMachineModel "OS" -#endif // !kMachineModel +#endif // !kMachineModel /** Graphics related. */ -STATIC EfiGraphicsOutputProtocol* kGop = nullptr; -STATIC UInt16 kGopStride = 0U; -STATIC EfiGUID kGopGuid; +STATIC EfiGraphicsOutputProtocol* kGop = nullptr; +STATIC UInt16 kGopStride = 0U; +STATIC EfiGUID kGopGuid; /** Related to jumping to the reset vector. */ EXTERN_C Void rt_reset_hardware(); /** - @brief Finds and stores the GOP object. + @brief Finds and stores the GOP object. */ -STATIC Bool boot_init_fb() noexcept -{ - kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); - kGop = nullptr; +STATIC Bool boot_init_fb() noexcept { + kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); + kGop = nullptr; - if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*)&kGop) != kEfiOk) - return No; + if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*) &kGop) != kEfiOk) return No; - kGopStride = 4; + kGopStride = 4; - return Yes; + return Yes; } EfiGUID kEfiGlobalNamespaceVarGUID = { - 0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}}; + 0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}}; /// @brief BootloaderMain EFI entrypoint. /// @param image_handle Handle of this image. /// @param sys_table The system table of it. /// @return nothing, never returns. -EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, - EfiSystemTable* sys_table) -{ - fw_init_efi(sys_table); ///! Init the EFI library. +EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTable* sys_table) { + fw_init_efi(sys_table); ///! Init the EFI library. + + ST->ConOut->ClearScreen(sys_table->ConOut); + ST->ConOut->SetAttribute(sys_table->ConOut, kEFIYellow); + + ST->BootServices->SetWatchdogTimer(0, 0, 0, nullptr); + ST->ConOut->EnableCursor(ST->ConOut, false); - ST->ConOut->ClearScreen(sys_table->ConOut); - ST->ConOut->SetAttribute(sys_table->ConOut, kEFIYellow); + HEL::BootInfoHeader* handover_hdr = new HEL::BootInfoHeader(); - ST->BootServices->SetWatchdogTimer(0, 0, 0, nullptr); - ST->ConOut->EnableCursor(ST->ConOut, false); + UInt32 map_key = 0; + UInt32 size_struct_ptr = sizeof(EfiMemoryDescriptor); + EfiMemoryDescriptor* struct_ptr = nullptr; + UInt32 sz_desc = sizeof(EfiMemoryDescriptor); + UInt32 rev_desc = 0; - HEL::BootInfoHeader* handover_hdr = - new HEL::BootInfoHeader(); + Boot::BootTextWriter writer; - UInt32 map_key = 0; - UInt32 size_struct_ptr = sizeof(EfiMemoryDescriptor); - EfiMemoryDescriptor* struct_ptr = nullptr; - UInt32 sz_desc = sizeof(EfiMemoryDescriptor); - UInt32 rev_desc = 0; - - Boot::BootTextWriter writer; + if (!boot_init_fb()) { + writer.Write("BootZ: Invalid Framebuffer, can't boot to NeKernel.\r"); + Boot::Stop(); + } - if (!boot_init_fb()) - { - writer.Write("BootZ: Invalid Framebuffer, can't boot to NeKernel.\r"); - Boot::Stop(); - } - - for (SizeT index_vt = 0; index_vt < sys_table->NumberOfTableEntries; - ++index_vt) - { - Char* vendor_table = reinterpret_cast( - sys_table->ConfigurationTable[index_vt].VendorTable); + for (SizeT index_vt = 0; index_vt < sys_table->NumberOfTableEntries; ++index_vt) { + Char* vendor_table = + reinterpret_cast(sys_table->ConfigurationTable[index_vt].VendorTable); - // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...) - if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && - vendor_table[2] == 'D' && vendor_table[3] == ' ' && - vendor_table[4] == 'P' && vendor_table[5] == 'T' && - vendor_table[6] == 'R' && vendor_table[7] == ' ') - { - handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr)vendor_table; - break; - } - } + // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...) + if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && vendor_table[2] == 'D' && + vendor_table[3] == ' ' && vendor_table[4] == 'P' && vendor_table[5] == 'T' && + vendor_table[6] == 'R' && vendor_table[7] == ' ') { + handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr) vendor_table; + break; + } + } - // ------------------------------------------ // - // draw background color. - // ------------------------------------------ // + // ------------------------------------------ // + // draw background color. + // ------------------------------------------ // - handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase; - handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; - handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; - handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; - handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; - handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; + handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase; + handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; + handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; + handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; + handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; + handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; - // ------------------------------------------- // - // Grab MP services, extended to runtime. // - // ------------------------------------------- // + // ------------------------------------------- // + // Grab MP services, extended to runtime. // + // ------------------------------------------- // - EfiGUID guid_mp = EfiGUID(EFI_MP_SERVICES_PROTOCOL_GUID); - EfiMpServicesProtocol* mp = nullptr; + EfiGUID guid_mp = EfiGUID(EFI_MP_SERVICES_PROTOCOL_GUID); + EfiMpServicesProtocol* mp = nullptr; - BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast(&mp)); + BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast(&mp)); - handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast(mp); + handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast(mp); - kHandoverHeader = handover_hdr; + kHandoverHeader = handover_hdr; - FB::fb_clear_video(); + FB::fb_clear_video(); - UInt32 cnt_enabled = 0; - UInt32 cnt_disabled = 0; + UInt32 cnt_enabled = 0; + UInt32 cnt_disabled = 0; - if (mp) - { - mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); - handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1; - } - else - { - handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = NO; - } + if (mp) { + mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); + handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1; + } else { + handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = NO; + } - // Fill handover header now. + // Fill handover header now. - handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */ - handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */ + handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */ + handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */ - Int32 trials = 5 * 10000000; + Int32 trials = 5 * 10000000; - writer.Write("BootZ: Welcome to BootZ.\r"); - writer.Write("BootZ: Allocating sufficent memory, trying 4GB...\r"); + writer.Write("BootZ: Welcome to BootZ.\r"); + writer.Write("BootZ: Allocating sufficent memory, trying 4GB...\r"); - while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) - { - --trials; + while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, + &handover_hdr->f_BitMapStart) != kEfiOk) { + --trials; - if (!trials) - { - writer.Write("BootZ: Unable to allocate sufficent memory, trying again with 2GB...\r"); + if (!trials) { + writer.Write("BootZ: Unable to allocate sufficent memory, trying again with 2GB...\r"); - trials = 3 * 10000000; + trials = 3 * 10000000; - handover_hdr->f_BitMapSize = kHandoverBitMapSz / 2; /* Size of bitmap in bytes. */ + handover_hdr->f_BitMapSize = kHandoverBitMapSz / 2; /* Size of bitmap in bytes. */ - while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) - { - --trials; + while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, + &handover_hdr->f_BitMapStart) != kEfiOk) { + --trials; - if (!trials) - { - writer.Write("BootZ: Unable to allocate sufficent memory, aborting...\r"); - Boot::Stop(); - } - } - } - } + if (!trials) { + writer.Write("BootZ: Unable to allocate sufficent memory, aborting...\r"); + Boot::Stop(); + } + } + } + } - handover_hdr->f_FirmwareCustomTables[0] = (VoidPtr)BS; - handover_hdr->f_FirmwareCustomTables[1] = (VoidPtr)ST; + handover_hdr->f_FirmwareCustomTables[0] = (VoidPtr) BS; + handover_hdr->f_FirmwareCustomTables[1] = (VoidPtr) ST; - // ------------------------------------------ // - // If we succeed in reading the blob, then execute it. - // ------------------------------------------ // + // ------------------------------------------ // + // If we succeed in reading the blob, then execute it. + // ------------------------------------------ // - Boot::BootFileReader reader_syschk(L"chk.efi", image_handle); - reader_syschk.ReadAll(0); + Boot::BootFileReader reader_syschk(L"chk.efi", image_handle); + reader_syschk.ReadAll(0); - Boot::BootThread* syschk_thread = nullptr; + Boot::BootThread* syschk_thread = nullptr; - if (reader_syschk.Blob()) - { - syschk_thread = new Boot::BootThread(reader_syschk.Blob()); - syschk_thread->SetName("BootZ/SysChk"); + if (reader_syschk.Blob()) { + syschk_thread = new Boot::BootThread(reader_syschk.Blob()); + syschk_thread->SetName("BootZ/SysChk"); - syschk_thread->Start(handover_hdr, NO); - } + syschk_thread->Start(handover_hdr, NO); + } - BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); + BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); - handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); + handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); - handover_hdr->f_Magic = kHandoverMagic; - handover_hdr->f_Version = kHandoverVersion; + handover_hdr->f_Magic = kHandoverMagic; + handover_hdr->f_Version = kHandoverVersion; - handover_hdr->f_HardwareTables.f_ImageKey = map_key; - handover_hdr->f_HardwareTables.f_ImageHandle = image_handle; + handover_hdr->f_HardwareTables.f_ImageKey = map_key; + handover_hdr->f_HardwareTables.f_ImageHandle = image_handle; - // Provide fimware vendor name. + // Provide fimware vendor name. - Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, sys_table->FirmwareVendor, - handover_hdr->f_FirmwareVendorLen); + Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, sys_table->FirmwareVendor, + handover_hdr->f_FirmwareVendorLen); - handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); - // Assign to global 'kHandoverHeader'. + handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); + // Assign to global 'kHandoverHeader'. - WideChar kernel_path[256U] = L"krnl.efi"; - UInt32 kernel_path_sz = 256U; + WideChar kernel_path[256U] = L"krnl.efi"; + UInt32 kernel_path_sz = 256U; - if (ST->RuntimeServices->GetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, nullptr, &kernel_path_sz, kernel_path) != kEfiOk) - { - /// access attributes (in order) - /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS - UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004; + if (ST->RuntimeServices->GetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, nullptr, + &kernel_path_sz, kernel_path) != kEfiOk) { + /// access attributes (in order) + /// EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS + UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004; - ST->RuntimeServices->SetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, &attr, &kernel_path_sz, kernel_path); - } + ST->RuntimeServices->SetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, &attr, + &kernel_path_sz, kernel_path); + } - UInt32 sz_ver = sizeof(UInt64); - UInt64 ver = KERNEL_VERSION_BCD; + UInt32 sz_ver = sizeof(UInt64); + UInt64 ver = KERNEL_VERSION_BCD; - ST->RuntimeServices->GetVariable(L"/props/kern_ver", kEfiGlobalNamespaceVarGUID, nullptr, &sz_ver, &ver); + ST->RuntimeServices->GetVariable(L"/props/kern_ver", kEfiGlobalNamespaceVarGUID, nullptr, &sz_ver, + &ver); - if (ver != KERNEL_VERSION_BCD) - { - ver = KERNEL_VERSION_BCD; + if (ver != KERNEL_VERSION_BCD) { + ver = KERNEL_VERSION_BCD; - ST->RuntimeServices->SetVariable(L"/props/kern_ver", kEfiGlobalNamespaceVarGUID, nullptr, &sz_ver, &ver); - writer.Write("BootZ: version has been updated: ").Write(ver).Write("\r"); - } + ST->RuntimeServices->SetVariable(L"/props/kern_ver", kEfiGlobalNamespaceVarGUID, nullptr, + &sz_ver, &ver); + writer.Write("BootZ: version has been updated: ").Write(ver).Write("\r"); + } - writer.Write("BootZ: version: ").Write(ver).Write("\r"); + writer.Write("BootZ: version: ").Write(ver).Write("\r"); - // boot to kernel, if not netboot this. + // boot to kernel, if not netboot this. - Boot::BootFileReader reader_kernel(kernel_path, image_handle); + Boot::BootFileReader reader_kernel(kernel_path, image_handle); - reader_kernel.ReadAll(0); + reader_kernel.ReadAll(0); - // ------------------------------------------ // - // If we succeed in reading the blob, then execute it. - // ------------------------------------------ // + // ------------------------------------------ // + // If we succeed in reading the blob, then execute it. + // ------------------------------------------ // - if (reader_kernel.Blob()) - { - // ------------------------------------------ // - // null these fields, to avoid being reused later. - // ------------------------------------------ // + if (reader_kernel.Blob()) { + // ------------------------------------------ // + // null these fields, to avoid being reused later. + // ------------------------------------------ // - auto kernel_thread = Boot::BootThread(reader_kernel.Blob()); + auto kernel_thread = Boot::BootThread(reader_kernel.Blob()); - kernel_thread.SetName("BootZ/NeKernel"); + kernel_thread.SetName("BootZ/NeKernel"); - handover_hdr->f_KernelImage = reader_kernel.Blob(); - handover_hdr->f_KernelSz = reader_kernel.Size(); + handover_hdr->f_KernelImage = reader_kernel.Blob(); + handover_hdr->f_KernelSz = reader_kernel.Size(); - kernel_thread.Start(handover_hdr, YES); - } + kernel_thread.Start(handover_hdr, YES); + } - Boot::BootFileReader reader_netboot(L"net.efi", image_handle); - reader_netboot.ReadAll(0); + Boot::BootFileReader reader_netboot(L"net.efi", image_handle); + reader_netboot.ReadAll(0); - if (!reader_netboot.Blob()) - return kEfiFail; + if (!reader_netboot.Blob()) return kEfiFail; - auto netboot_thread = Boot::BootThread(reader_netboot.Blob()); - netboot_thread.SetName("BootZ/BootNet"); + auto netboot_thread = Boot::BootThread(reader_netboot.Blob()); + netboot_thread.SetName("BootZ/BootNet"); - return netboot_thread.Start(handover_hdr, NO); + return netboot_thread.Start(handover_hdr, NO); } diff --git a/dev/boot/src/HEL/AMD64/BootPlatform.cc b/dev/boot/src/HEL/AMD64/BootPlatform.cc index 1a1f9b89..8b4d57c4 100644 --- a/dev/boot/src/HEL/AMD64/BootPlatform.cc +++ b/dev/boot/src/HEL/AMD64/BootPlatform.cc @@ -1,50 +1,44 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include #ifdef __BOOTZ_STANDALONE__ using namespace Boot; -EXTERN_C void rt_hlt() -{ - asm volatile("hlt"); +EXTERN_C void rt_hlt() { + asm volatile("hlt"); } -EXTERN_C void rt_cli() -{ - asm volatile("cli"); +EXTERN_C void rt_cli() { + asm volatile("cli"); } -EXTERN_C void rt_sti() -{ - asm volatile("sti"); +EXTERN_C void rt_sti() { + asm volatile("sti"); } -EXTERN_C void rt_cld() -{ - asm volatile("cld"); +EXTERN_C void rt_cld() { + asm volatile("cld"); } -EXTERN_C void rt_std() -{ - asm volatile("std"); +EXTERN_C void rt_std() { + asm volatile("std"); } #else #include -void rt_hlt() -{ - Kernel::HAL::rt_halt(); +void rt_hlt() { + Kernel::HAL::rt_halt(); } -#endif // __BOOTZ_STANDALONE__ +#endif // __BOOTZ_STANDALONE__ diff --git a/dev/boot/src/HEL/AMD64/BootSATA.cc b/dev/boot/src/HEL/AMD64/BootSATA.cc index e60aebde..ef5d2096 100644 --- a/dev/boot/src/HEL/AMD64/BootSATA.cc +++ b/dev/boot/src/HEL/AMD64/BootSATA.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -15,6 +15,6 @@ * */ +#include #include #include -#include diff --git a/dev/boot/src/HEL/ARM64/BootEFI.cc b/dev/boot/src/HEL/ARM64/BootEFI.cc index 9132cec1..1e5b62f3 100644 --- a/dev/boot/src/HEL/ARM64/BootEFI.cc +++ b/dev/boot/src/HEL/ARM64/BootEFI.cc @@ -1,12 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -#include -#include +#include #include #include #include @@ -15,8 +14,8 @@ #include #include #include -#include #include +#include #ifndef kExpectedWidth #define kExpectedWidth (800) @@ -28,43 +27,39 @@ /** Graphics related. */ -STATIC EfiGraphicsOutputProtocol* kGop = nullptr; -STATIC UInt16 kGopStride = 0U; -STATIC EfiGUID kGopGuid; +STATIC EfiGraphicsOutputProtocol* kGop = nullptr; +STATIC UInt16 kGopStride = 0U; +STATIC EfiGUID kGopGuid; EXTERN_C Void rt_reset_hardware(); EXTERN EfiBootServices* BS; /** - @brief Finds and stores the GOP object. + @brief Finds and stores the GOP object. */ -STATIC Bool boot_init_fb() noexcept -{ - kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); - kGop = nullptr; +STATIC Bool boot_init_fb() noexcept { + kGopGuid = EfiGUID(EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID); + kGop = nullptr; - if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*)&kGop) != kEfiOk) - return No; + if (BS->LocateProtocol(&kGopGuid, nullptr, (VoidPtr*) &kGop) != kEfiOk) return No; - kGopStride = 4; + kGopStride = 4; - for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) - { - EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr; - UInt32 sz = 0U; + for (SizeT i = 0; i < kGop->Mode->MaxMode; ++i) { + EfiGraphicsOutputProtocolModeInformation* infoPtr = nullptr; + UInt32 sz = 0U; - kGop->QueryMode(kGop, i, &sz, &infoPtr); + kGop->QueryMode(kGop, i, &sz, &infoPtr); - if (infoPtr->HorizontalResolution == kExpectedWidth && - infoPtr->VerticalResolution == kExpectedHeight) - { - kGop->SetMode(kGop, i); - return Yes; - } - } + if (infoPtr->HorizontalResolution == kExpectedWidth && + infoPtr->VerticalResolution == kExpectedHeight) { + kGop->SetMode(kGop, i); + return Yes; + } + } - return No; + return No; } EXTERN EfiBootServices* BS; @@ -73,179 +68,167 @@ EXTERN EfiBootServices* BS; /// @param image_handle Handle of this image. /// @param sys_table The system table of it. /// @return nothing, never returns. -EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, - EfiSystemTable* sys_table) -{ - fw_init_efi(sys_table); ///! Init the EFI library. +EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTable* sys_table) { + fw_init_efi(sys_table); ///! Init the EFI library. - HEL::BootInfoHeader* handover_hdr = - new HEL::BootInfoHeader(); + HEL::BootInfoHeader* handover_hdr = new HEL::BootInfoHeader(); - UInt32 map_key = 0; + UInt32 map_key = 0; #ifdef ZBA_USE_FB - if (!boot_init_fb()) - return 1; ///! Init the GOP. - - for (SizeT index_vt = 0; index_vt < sys_table->NumberOfTableEntries; - ++index_vt) - { - Char* vendor_table = reinterpret_cast( - sys_table->ConfigurationTable[index_vt].VendorTable); - - // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...) - if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && - vendor_table[2] == 'D' && vendor_table[3] == ' ' && - vendor_table[4] == 'P' && vendor_table[5] == 'T' && - vendor_table[6] == 'R' && vendor_table[7] == ' ') - { - handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr)vendor_table; - break; - } - } + if (!boot_init_fb()) return 1; ///! Init the GOP. + + for (SizeT index_vt = 0; index_vt < sys_table->NumberOfTableEntries; ++index_vt) { + Char* vendor_table = + reinterpret_cast(sys_table->ConfigurationTable[index_vt].VendorTable); + + // ACPI's 'RSD PTR', which contains the ACPI SDT (MADT, FACP...) + if (vendor_table[0] == 'R' && vendor_table[1] == 'S' && vendor_table[2] == 'D' && + vendor_table[3] == ' ' && vendor_table[4] == 'P' && vendor_table[5] == 'T' && + vendor_table[6] == 'R' && vendor_table[7] == ' ') { + handover_hdr->f_HardwareTables.f_VendorPtr = (VoidPtr) vendor_table; + break; + } + } - // ------------------------------------------ // - // draw background color. - // ------------------------------------------ // + // ------------------------------------------ // + // draw background color. + // ------------------------------------------ // - handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase; - handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; - handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; - handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; - handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; - handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; -#endif // ZBA_USE_FB + handover_hdr->f_GOP.f_The = kGop->Mode->FrameBufferBase; + handover_hdr->f_GOP.f_Width = kGop->Mode->Info->VerticalResolution; + handover_hdr->f_GOP.f_Height = kGop->Mode->Info->HorizontalResolution; + handover_hdr->f_GOP.f_PixelPerLine = kGop->Mode->Info->PixelsPerScanLine; + handover_hdr->f_GOP.f_PixelFormat = kGop->Mode->Info->PixelFormat; + handover_hdr->f_GOP.f_Size = kGop->Mode->FrameBufferSize; +#endif // ZBA_USE_FB - // ------------------------------------------- // - // Grab MP services, extended to runtime. // - // ------------------------------------------- // + // ------------------------------------------- // + // Grab MP services, extended to runtime. // + // ------------------------------------------- // - EfiGUID guid_mp = EfiGUID(EFI_MP_SERVICES_PROTOCOL_GUID); - EfiMpServicesProtocol* mp = nullptr; + EfiGUID guid_mp = EfiGUID(EFI_MP_SERVICES_PROTOCOL_GUID); + EfiMpServicesProtocol* mp = nullptr; - BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast(&mp)); - handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast(mp); + BS->LocateProtocol(&guid_mp, nullptr, reinterpret_cast(&mp)); + handover_hdr->f_HardwareTables.f_MpPtr = reinterpret_cast(mp); - // Assign to global 'kHandoverHeader'. - kHandoverHeader = handover_hdr; + // Assign to global 'kHandoverHeader'. + kHandoverHeader = handover_hdr; - fb_init(); + fb_init(); - FB::fb_clear_video(); + FB::fb_clear_video(); - FBDrawBitMapInRegion(zka_disk, NE_DISK_WIDTH, NE_DISK_HEIGHT, (kHandoverHeader->f_GOP.f_Width - NE_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - NE_DISK_HEIGHT) / 2); + FBDrawBitMapInRegion(zka_disk, NE_DISK_WIDTH, NE_DISK_HEIGHT, + (kHandoverHeader->f_GOP.f_Width - NE_DISK_WIDTH) / 2, + (kHandoverHeader->f_GOP.f_Height - NE_DISK_HEIGHT) / 2); - fb_clear(); + fb_clear(); - UInt32 cnt_enabled = 0; - UInt32 cnt_disabled = 0; + UInt32 cnt_enabled = 0; + UInt32 cnt_disabled = 0; - if (mp) - { - mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); - handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1; - } - else - { - handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = NO; - } + if (mp) { + mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); + handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = cnt_enabled > 1; + } else { + handover_hdr->f_HardwareTables.f_MultiProcessingEnabled = NO; + } - //-------------------------------------------------------------// - // Allocate heap. - //-------------------------------------------------------------// + //-------------------------------------------------------------// + // Allocate heap. + //-------------------------------------------------------------// - Boot::BootTextWriter writer; + Boot::BootTextWriter writer; - handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */ - handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */ - Int32 trials = 5 * 10000000; + handover_hdr->f_BitMapStart = nullptr; /* Start of bitmap. */ + handover_hdr->f_BitMapSize = kHandoverBitMapSz; /* Size of bitmap in bytes. */ + Int32 trials = 5 * 10000000; - while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) - { - --trials; + while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, + &handover_hdr->f_BitMapStart) != kEfiOk) { + --trials; - if (!trials) - { - writer.Write("BootZ: Unable to allocate sufficent memory, trying again with 2GB...\r"); + if (!trials) { + writer.Write("BootZ: Unable to allocate sufficent memory, trying again with 2GB...\r"); - trials = 3 * 10000000; + trials = 3 * 10000000; - handover_hdr->f_BitMapSize = kHandoverBitMapSz / 2; /* Size of bitmap in bytes. */ + handover_hdr->f_BitMapSize = kHandoverBitMapSz / 2; /* Size of bitmap in bytes. */ - while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, &handover_hdr->f_BitMapStart) != kEfiOk) - { - --trials; + while (BS->AllocatePool(EfiLoaderData, handover_hdr->f_BitMapSize, + &handover_hdr->f_BitMapStart) != kEfiOk) { + --trials; - if (!trials) - { - writer.Write("BootZ: Unable to allocate sufficent memory, aborting...\r"); - Boot::Stop(); - } - } - } - } + if (!trials) { + writer.Write("BootZ: Unable to allocate sufficent memory, aborting...\r"); + Boot::Stop(); + } + } + } + } - Boot::BootFileReader reader_syschk(L"chk.efi", image_handle); - reader_syschk.ReadAll(0); + Boot::BootFileReader reader_syschk(L"chk.efi", image_handle); + reader_syschk.ReadAll(0); - Boot::BootThread* syschk_thread = nullptr; + Boot::BootThread* syschk_thread = nullptr; - if (reader_syschk.Blob()) - { - syschk_thread = new Boot::BootThread(reader_syschk.Blob()); - syschk_thread->SetName("BootZ: System Check"); + if (reader_syschk.Blob()) { + syschk_thread = new Boot::BootThread(reader_syschk.Blob()); + syschk_thread->SetName("BootZ: System Check"); - if (syschk_thread->Start(handover_hdr, NO) != kEfiOk) - { - fb_init(); + if (syschk_thread->Start(handover_hdr, NO) != kEfiOk) { + fb_init(); - FB::fb_clear_video(); + FB::fb_clear_video(); - FBDrawBitMapInRegion(zka_no_disk, NE_NO_DISK_WIDTH, NE_NO_DISK_HEIGHT, (kHandoverHeader->f_GOP.f_Width - NE_NO_DISK_WIDTH) / 2, (kHandoverHeader->f_GOP.f_Height - NE_NO_DISK_HEIGHT) / 2); + FBDrawBitMapInRegion(zka_no_disk, NE_NO_DISK_WIDTH, NE_NO_DISK_HEIGHT, + (kHandoverHeader->f_GOP.f_Width - NE_NO_DISK_WIDTH) / 2, + (kHandoverHeader->f_GOP.f_Height - NE_NO_DISK_HEIGHT) / 2); - fb_clear(); - } - } + fb_clear(); + } + } - // ------------------------------------------ // - // null these fields, to avoid being reused later. - // ------------------------------------------ // + // ------------------------------------------ // + // null these fields, to avoid being reused later. + // ------------------------------------------ // - handover_hdr->f_FirmwareCustomTables[0] = nullptr; - handover_hdr->f_FirmwareCustomTables[1] = nullptr; + handover_hdr->f_FirmwareCustomTables[0] = nullptr; + handover_hdr->f_FirmwareCustomTables[1] = nullptr; - handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); + handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); - handover_hdr->f_Magic = kHandoverMagic; - handover_hdr->f_Version = kHandoverVersion; + handover_hdr->f_Magic = kHandoverMagic; + handover_hdr->f_Version = kHandoverVersion; - // Provide fimware vendor name. + // Provide fimware vendor name. - Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, sys_table->FirmwareVendor, - handover_hdr->f_FirmwareVendorLen); + Boot::BCopyMem(handover_hdr->f_FirmwareVendorName, sys_table->FirmwareVendor, + handover_hdr->f_FirmwareVendorLen); - handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); + handover_hdr->f_FirmwareVendorLen = Boot::BStrLen(sys_table->FirmwareVendor); - Boot::BootFileReader reader_kernel(L"krnl.efi", image_handle); + Boot::BootFileReader reader_kernel(L"krnl.efi", image_handle); - reader_kernel.ReadAll(0); + reader_kernel.ReadAll(0); - // ------------------------------------------ // - // If we succeed in reading the blob, then execute it. - // ------------------------------------------ // + // ------------------------------------------ // + // If we succeed in reading the blob, then execute it. + // ------------------------------------------ // - if (reader_kernel.Blob()) - { - auto kernel_thread = Boot::BootThread(reader_kernel.Blob()); - kernel_thread.SetName("BootZ: Kernel."); + if (reader_kernel.Blob()) { + auto kernel_thread = Boot::BootThread(reader_kernel.Blob()); + kernel_thread.SetName("BootZ: Kernel."); - handover_hdr->f_KernelImage = reader_kernel.Blob(); - handover_hdr->f_KernelSz = reader_kernel.Size(); + handover_hdr->f_KernelImage = reader_kernel.Blob(); + handover_hdr->f_KernelSz = reader_kernel.Size(); - Boot::ExitBootServices(map_key, image_handle); + Boot::ExitBootServices(map_key, image_handle); - kernel_thread.Start(handover_hdr, YES); - } + kernel_thread.Start(handover_hdr, YES); + } - CANT_REACH(); + CANT_REACH(); } diff --git a/dev/boot/src/HEL/ARM64/BootPlatform.cc b/dev/boot/src/HEL/ARM64/BootPlatform.cc index bf359c6c..0f6a738f 100644 --- a/dev/boot/src/HEL/ARM64/BootPlatform.cc +++ b/dev/boot/src/HEL/ARM64/BootPlatform.cc @@ -1,37 +1,27 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include #ifdef __BOOTZ_STANDALONE__ using namespace Boot; -EXTERN_C void rt_hlt() -{ - while (Yes) - ; +EXTERN_C void rt_hlt() { + while (Yes); } -EXTERN_C void rt_cli() -{ -} +EXTERN_C void rt_cli() {} -EXTERN_C void rt_sti() -{ -} +EXTERN_C void rt_sti() {} -EXTERN_C void rt_cld() -{ -} +EXTERN_C void rt_cld() {} -EXTERN_C void rt_std() -{ -} +EXTERN_C void rt_std() {} -#endif // __BOOTZ_STANDALONE__ +#endif // __BOOTZ_STANDALONE__ diff --git a/dev/boot/src/New+Delete.cc b/dev/boot/src/New+Delete.cc index 387ceaa0..f7ad2898 100644 --- a/dev/boot/src/New+Delete.cc +++ b/dev/boot/src/New+Delete.cc @@ -1,12 +1,12 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include #include #ifdef __BOOTZ_STANDALONE__ @@ -14,71 +14,60 @@ /// @brief Allocates a new object. /// @param sz the size. /// @return -void* operator new(size_t sz) -{ - void* buf = nullptr; +void* operator new(size_t sz) { + void* buf = nullptr; - while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) != kEfiOk) - ; + while (BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf) != kEfiOk); - return buf; + return buf; } /// @brief Allocates a new object. /// @param sz the size. /// @return -void* operator new[](size_t sz) -{ - void* buf = nullptr; - BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf); +void* operator new[](size_t sz) { + void* buf = nullptr; + BS->AllocatePool(EfiMemoryType::EfiLoaderData, sz, &buf); - return buf; + return buf; } /// @brief Deletes the object. /// @param buf the object. -void operator delete(void* buf) -{ - if (!buf) - return; +void operator delete(void* buf) { + if (!buf) return; - BS->FreePool(buf); + BS->FreePool(buf); } /// @brief Deletes the object. /// @param buf the object. -void operator delete[](void* buf) -{ - if (!buf) - return; +void operator delete[](void* buf) { + if (!buf) return; - BS->FreePool(buf); + BS->FreePool(buf); } /// @brief Deletes the object (array specific). /// @param buf the object. /// @param size it's size. -void operator delete(void* buf, size_t size) -{ - if (!buf) - return; +void operator delete(void* buf, size_t size) { + if (!buf) return; - NE_UNUSED(size); + NE_UNUSED(size); - BS->FreePool(buf); + BS->FreePool(buf); } /// @brief Deletes the object (array specific). /// @param buf the object. /// @param size it's size. -void operator delete[](void* buf, size_t size) -{ - if (!buf) - return; +void operator delete[](void* buf, size_t size) { + if (!buf) return; - NE_UNUSED(size); + NE_UNUSED(size); - BS->FreePool(buf); + BS->FreePool(buf); } -#endif // __BOOTZ_STANDALONE__ +#endif // __BOOTZ_STANDALONE__ diff --git a/dev/ddk/DDKKit/ddk.h b/dev/ddk/DDKKit/ddk.h index 04d067ae..b7bcd52c 100644 --- a/dev/ddk/DDKKit/ddk.h +++ b/dev/ddk/DDKKit/ddk.h @@ -1,36 +1,36 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - FILE: ddk.h - PURPOSE: DDK Driver model base header. + FILE: ddk.h + PURPOSE: DDK Driver model base header. ------------------------------------------- */ #pragma once -#include #include +#include #if defined(__cplusplus) -#define BOOL bool -#define YES true -#define NO false +#define BOOL bool +#define YES true +#define NO false #define DDK_EXTERN extern "C" __declspec(dllexport) -#define nil nullptr +#define nil nullptr #undef NULL -#define NULL 0 +#define NULL 0 #define DDK_FINAL final #else -#define BOOL char -#define YES 1 -#define NO 0 +#define BOOL char +#define YES 1 +#define NO 0 #define DDK_EXTERN extern __declspec(dllexport) -#define nil ((void*)0) +#define nil ((void*) 0) #undef NULL -#define NULL ((void*)0) +#define NULL ((void*) 0) #define DDK_FINAL -#endif // defined(__cplusplus) +#endif // defined(__cplusplus) #ifndef __DDK__ #undef DDK_EXTERN @@ -45,26 +45,24 @@ #ifndef __NEOSKRNL__ #error !!! Do not include header in EL0/Ring 3 mode !!! -#endif // __MINOSKRNL__ +#endif // __MINOSKRNL__ struct DDK_STATUS_STRUCT; struct DDK_OBJECT_MANIFEST; /// \brief Object handle manifest. -struct DDK_OBJECT_MANIFEST DDK_FINAL -{ - char* p_name; - int32_t p_kind; - void* p_object; +struct DDK_OBJECT_MANIFEST DDK_FINAL { + char* p_name; + int32_t p_kind; + void* p_object; }; /// \brief DDK status ping structure. -struct DDK_STATUS_STRUCT DDK_FINAL -{ - int32_t s_action_id; - int32_t s_issuer_id; - int32_t s_group_id; - void* s_object; +struct DDK_STATUS_STRUCT DDK_FINAL { + int32_t s_action_id; + int32_t s_issuer_id; + int32_t s_group_id; + void* s_object; }; /// @brief Call Kernel procedure. diff --git a/dev/ddk/DDKKit/dev.h b/dev/ddk/DDKKit/dev.h index 80cb77c9..6c8a828e 100644 --- a/dev/ddk/DDKKit/dev.h +++ b/dev/ddk/DDKKit/dev.h @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - File: dev.h - Purpose: DDK device support. + File: dev.h + Purpose: DDK device support. ------------------------------------------- */ @@ -16,14 +16,13 @@ struct _DDK_DEVICE; #define DDK_DEVICE_NAME_LEN (255) /// @brief Kernel Device driver. -typedef struct _DDK_DEVICE DDK_FINAL -{ - char d_name[DDK_DEVICE_NAME_LEN]; // the device name. Could be /./DEVICE_NAME/ - void* (*d_read)(void* arg, int len); // read from device. - void (*d_write)(void* arg, int len); - void (*d_wait)(void); // write to device. - struct _DDK_DEVICE* (*d_open)(const char* path); // open device. - void (*d_close)(struct _DDK_DEVICE* dev); // close device. +typedef struct _DDK_DEVICE DDK_FINAL { + char d_name[DDK_DEVICE_NAME_LEN]; // the device name. Could be /./DEVICE_NAME/ + void* (*d_read)(void* arg, int len); // read from device. + void (*d_write)(void* arg, int len); + void (*d_wait)(void); // write to device. + struct _DDK_DEVICE* (*d_open)(const char* path); // open device. + void (*d_close)(struct _DDK_DEVICE* dev); // close device. } DDK_DEVICE, *DDK_DEVICE_PTR; /// @brief Open a new device from path. diff --git a/dev/ddk/DDKKit/io.h b/dev/ddk/DDKKit/io.h index 076af518..28396608 100644 --- a/dev/ddk/DDKKit/io.h +++ b/dev/ddk/DDKKit/io.h @@ -1,8 +1,8 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK Text I/O. + Purpose: DDK Text I/O. ------------------------------------------- */ diff --git a/dev/ddk/DDKKit/str.h b/dev/ddk/DDKKit/str.h index cb4a7d36..fbf6506d 100644 --- a/dev/ddk/DDKKit/str.h +++ b/dev/ddk/DDKKit/str.h @@ -1,8 +1,8 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK Strings. + Purpose: DDK Strings. ------------------------------------------- */ @@ -14,4 +14,4 @@ /// @file str.h DDK_EXTERN size_t kstrlen(const char* in); -DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len); +DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len); diff --git a/dev/ddk/src/ddk_alloc.c b/dev/ddk/src/ddk_alloc.c index 17d83d13..6daafb7e 100644 --- a/dev/ddk/src/ddk_alloc.c +++ b/dev/ddk/src/ddk_alloc.c @@ -1,36 +1,32 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK allocator. + Purpose: DDK allocator. ------------------------------------------- */ #include /** - \brief Allocates a new heap on the Kernel's side. - \param sz the size of the heap block. - \return the newly allocated pointer. + \brief Allocates a new heap on the Kernel's side. + \param sz the size of the heap block. + \return the newly allocated pointer. */ -DDK_EXTERN void* kalloc(size_t sz) -{ - if (!sz) - ++sz; +DDK_EXTERN void* kalloc(size_t sz) { + if (!sz) ++sz; - void* ptr = ke_call("mm_new_heap", 1, &sz, sizeof(size_t)); + void* ptr = ke_call("mm_new_heap", 1, &sz, sizeof(size_t)); - return ptr; + return ptr; } /** - \brief Frees a pointer from the heap. - \param ptr the pointer to free. + \brief Frees a pointer from the heap. + \param ptr the pointer to free. */ -DDK_EXTERN void kfree(void* ptr) -{ - if (!ptr) - return; +DDK_EXTERN void kfree(void* ptr) { + if (!ptr) return; - ke_call("mm_delete_heap", 1, ptr, 0); + ke_call("mm_delete_heap", 1, ptr, 0); } diff --git a/dev/ddk/src/ddk_dev.c b/dev/ddk/src/ddk_dev.c index 86b8466f..281e48c7 100644 --- a/dev/ddk/src/ddk_dev.c +++ b/dev/ddk/src/ddk_dev.c @@ -1,8 +1,8 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK Text I/O. + Purpose: DDK Text I/O. ------------------------------------------- */ @@ -10,21 +10,17 @@ #include /// @brief Open a new binary device from path. -DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) -{ - if (!devicePath) - return nil; +DDK_EXTERN DDK_DEVICE_PTR open(const char* devicePath) { + if (!devicePath) return nil; - return ke_call("sk_open_dev", 1, (void*)devicePath, kstrlen(devicePath)); + return ke_call("sk_open_dev", 1, (void*) devicePath, kstrlen(devicePath)); } /// @brief Close any device. /// @param device valid device. -DDK_EXTERN BOOL close(DDK_DEVICE_PTR device) -{ - if (!device) - return NO; +DDK_EXTERN BOOL close(DDK_DEVICE_PTR device) { + if (!device) return NO; - ke_call("sk_close_dev", 1, device, sizeof(DDK_DEVICE)); - return YES; + ke_call("sk_close_dev", 1, device, sizeof(DDK_DEVICE)); + return YES; } diff --git a/dev/ddk/src/ddk_io.c b/dev/ddk/src/ddk_io.c index c0e672bd..ba6d4e55 100644 --- a/dev/ddk/src/ddk_io.c +++ b/dev/ddk/src/ddk_io.c @@ -1,37 +1,32 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK Text I/O. + Purpose: DDK Text I/O. ------------------------------------------- */ #include -DDK_EXTERN void kputc(const char ch) -{ - char assembled[2] = {0}; - assembled[0] = ch; - assembled[1] = 0; +DDK_EXTERN void kputc(const char ch) { + char assembled[2] = {0}; + assembled[0] = ch; + assembled[1] = 0; - ke_call("ke_put_string", 1, assembled, 1); + ke_call("ke_put_string", 1, assembled, 1); } /// @brief print string to UART. /// @param message UART to transmit. -DDK_EXTERN void kprint(const char* message) -{ - if (!message) - return; - if (*message == 0) - return; - - size_t index = 0; - size_t len = kstrlen(message); - - while (index < len) - { - kputc(message[index]); - ++index; - } +DDK_EXTERN void kprint(const char* message) { + if (!message) return; + if (*message == 0) return; + + size_t index = 0; + size_t len = kstrlen(message); + + while (index < len) { + kputc(message[index]); + ++index; + } } diff --git a/dev/ddk/src/ddk_kernel_call.c b/dev/ddk/src/ddk_kernel_call.c index e929eae4..b5c494f7 100644 --- a/dev/ddk/src/ddk_kernel_call.c +++ b/dev/ddk/src/ddk_kernel_call.c @@ -1,8 +1,8 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK Kernel call. + Purpose: DDK Kernel call. ------------------------------------------- */ @@ -10,7 +10,8 @@ #include /// @brief this is an internal call, do not use it. -DDK_EXTERN ATTRIBUTE(naked) void* ke_call_dispatch(const char* name, int32_t cnt, void* data, size_t sz); +DDK_EXTERN ATTRIBUTE(naked) void* ke_call_dispatch(const char* name, int32_t cnt, void* data, + size_t sz); /// @brief Interupt Kernel and call it's RPC. /// @param KernelRpcName RPC name @@ -19,34 +20,30 @@ DDK_EXTERN ATTRIBUTE(naked) void* ke_call_dispatch(const char* name, int32_t cnt /// @param sz The size of the whole data pointer. /// @retval void* Kernel call was successful. /// @retval nil Kernel call failed, call KernelLastError(void) -DDK_EXTERN void* ke_call(const char* name, int32_t cnt, void* data, size_t sz) -{ - if (!name || *name == 0 || cnt == 0) - return nil; +DDK_EXTERN void* ke_call(const char* name, int32_t cnt, void* data, size_t sz) { + if (!name || *name == 0 || cnt == 0) return nil; - return ke_call_dispatch(name, cnt, data, sz); + return ke_call_dispatch(name, cnt, data, sz); } /// @brief Add system call. /// @param slot system call slot /// @param slotFn, syscall slot. -DDK_EXTERN void ke_add_syscall(const int slot, void (*slotFn)(void* a0)) -{ - ke_call("ke_add_syscall", slot, slotFn, 1); +DDK_EXTERN void ke_add_syscall(const int slot, void (*slotFn)(void* a0)) { + ke_call("ke_add_syscall", slot, slotFn, 1); } /// @brief Get a Kernel object. /// @param slot property id (always 0) /// @param name the object's name. /// @return Object manifest. -DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name) -{ - struct DDK_OBJECT_MANIFEST* manifest = (struct DDK_OBJECT_MANIFEST*)ke_call("cf_get_kobj", slot, (void*)name, 1); +DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* name) { + struct DDK_OBJECT_MANIFEST* manifest = + (struct DDK_OBJECT_MANIFEST*) ke_call("cf_get_kobj", slot, (void*) name, 1); - if (!manifest) - return nil; + if (!manifest) return nil; - return manifest; + return manifest; } /// @brief Set a Kernel object. @@ -54,7 +51,6 @@ DDK_EXTERN struct DDK_OBJECT_MANIFEST* ke_get_obj(const int slot, const char* na /// @param name the object's name. /// @param ddk_pr pointer to a object's DDK_OBJECT_MANIFEST. /// @return property's object. -DDK_EXTERN void* ke_set_obj(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr) -{ - return ke_call("cf_set_kobj", slot, (void*)ddk_pr, 1); +DDK_EXTERN void* ke_set_obj(const int slot, const struct DDK_OBJECT_MANIFEST* ddk_pr) { + return ke_call("cf_set_kobj", slot, (void*) ddk_pr, 1); } diff --git a/dev/ddk/src/ddk_rt_cxx.cc b/dev/ddk/src/ddk_rt_cxx.cc index da62b88d..7daf0fcc 100644 --- a/dev/ddk/src/ddk_rt_cxx.cc +++ b/dev/ddk/src/ddk_rt_cxx.cc @@ -1,29 +1,25 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK C++ runtime. + Purpose: DDK C++ runtime. ------------------------------------------- */ #include -void* operator new(size_t sz) -{ - return kalloc(sz); +void* operator new(size_t sz) { + return kalloc(sz); } -void operator delete(void* ptr) -{ - kfree(ptr); +void operator delete(void* ptr) { + kfree(ptr); } -void* operator new[](size_t sz) -{ - return kalloc(sz); +void* operator new[](size_t sz) { + return kalloc(sz); } -void operator delete[](void* ptr) -{ - kfree(ptr); +void operator delete[](void* ptr) { + kfree(ptr); } diff --git a/dev/ddk/src/ddk_str.c b/dev/ddk/src/ddk_str.c index 5b5c615a..d50a5d03 100644 --- a/dev/ddk/src/ddk_str.c +++ b/dev/ddk/src/ddk_str.c @@ -1,40 +1,34 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK Strings. + Purpose: DDK Strings. ------------------------------------------- */ #include -DDK_EXTERN size_t kstrlen(const char* in) -{ - if (in == nil) - return 0; +DDK_EXTERN size_t kstrlen(const char* in) { + if (in == nil) return 0; - if (*in == 0) - return 0; + if (*in == 0) return 0; - size_t index = 0; + size_t index = 0; - while (in[index] != 0) - { - ++index; - } + while (in[index] != 0) { + ++index; + } - return index; + return index; } -DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len) -{ - size_t index = 0; +DDK_EXTERN int kstrncpy(char* dst, const char* src, size_t len) { + size_t index = 0; - while (index != len) - { - dst[index] = src[index]; - ++index; - } + while (index != len) { + dst[index] = src[index]; + ++index; + } - return index; + return index; } diff --git a/dev/ddk/src/ddk_ver.c b/dev/ddk/src/ddk_ver.c index eae27744..b2370b23 100644 --- a/dev/ddk/src/ddk_ver.c +++ b/dev/ddk/src/ddk_ver.c @@ -1,8 +1,8 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. - Purpose: DDK version symbols. + Purpose: DDK version symbols. ------------------------------------------- */ @@ -10,16 +10,16 @@ #ifndef kDDKVersionHighest #define kDDKVersionHighest 1 -#endif // !kDDKVersionHighest +#endif // !kDDKVersionHighest #ifndef kDDKVersionLowest #define kDDKVersionLowest 1 -#endif // !kDDKVersionLowest +#endif // !kDDKVersionLowest #ifndef kDDKVersion #define kDDKVersion 1 -#endif // !kDDKVersion +#endif // !kDDKVersion int32_t kApiVersionHighest = kDDKVersionHighest; int32_t kApiVersionLowest = kDDKVersionLowest; -int32_t kApiVersion = kDDKVersion; +int32_t kApiVersion = kDDKVersion; diff --git a/dev/hint/CompilerHint.h b/dev/hint/CompilerHint.h index 34531cb7..fed805e3 100644 --- a/dev/hint/CompilerHint.h +++ b/dev/hint/CompilerHint.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -22,4 +22,4 @@ #define _InOut #define _StrictInOut -#endif // ifndef _NE_COMPILERHINT_H_ +#endif // ifndef _NE_COMPILERHINT_H_ diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h index bb483d28..41a36e69 100644 --- a/dev/kernel/ArchKit/ArchKit.h +++ b/dev/kernel/ArchKit/ArchKit.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,8 +13,8 @@ #include #ifdef __NE_AMD64__ -#include #include +#include #include #elif defined(__NE_POWER64__) #include @@ -28,71 +28,57 @@ #define kMaxDispatchCallCount (512U) -namespace Kernel -{ - inline SSizeT rt_hash_seed(const Char* seed, int mul) - { - SSizeT 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 - 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 - 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 +namespace Kernel { +inline SSizeT rt_hash_seed(const Char* seed, int mul) { + SSizeT 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 +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 +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); -struct HalSyscallEntry final -{ - Kernel::Int64 fHash; - Kernel::Bool fHooked; - rt_syscall_proc fProc; +struct HalSyscallEntry final { + Kernel::Int64 fHash; + Kernel::Bool fHooked; + rt_syscall_proc fProc; - operator bool() - { - return fHooked; - } + operator bool() { return fHooked; } }; -inline Kernel::Array - kSysCalls; +inline Kernel::Array kSysCalls; -inline Kernel::Array - kKernCalls; +inline Kernel::Array kKernCalls; EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); diff --git a/dev/kernel/CFKit/GUIDWizard.h b/dev/kernel/CFKit/GUIDWizard.h index b1d3e310..ae62b8fc 100644 --- a/dev/kernel/CFKit/GUIDWizard.h +++ b/dev/kernel/CFKit/GUIDWizard.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,14 +11,13 @@ #include #include #include +#include #include #include -#include -namespace CF::XRN::Version1 -{ - using namespace Kernel; +namespace CF::XRN::Version1 { +using namespace Kernel; - Ref cf_make_sequence(const ArrayList& seq); - ErrorOr> cf_try_guid_to_string(Ref& guid); -} // namespace CF::XRN::Version1 +Ref cf_make_sequence(const ArrayList& seq); +ErrorOr> cf_try_guid_to_string(Ref& guid); +} // namespace CF::XRN::Version1 diff --git a/dev/kernel/CFKit/GUIDWrapper.h b/dev/kernel/CFKit/GUIDWrapper.h index c8143cea..cc01bfad 100644 --- a/dev/kernel/CFKit/GUIDWrapper.h +++ b/dev/kernel/CFKit/GUIDWrapper.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -15,46 +15,37 @@ #define kXRNNil "@{........-....-M...-N...-............}" /// @brief eXtended Resource Namespace -namespace CF::XRN -{ - using namespace Kernel; - - union GUIDSequence { - 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: - GUID& operator=(const GUID&) = default; - GUID(const GUID&) = default; - - public: - GUIDSequence& operator->() noexcept - { - return fUUID; - } - GUIDSequence& Leak() noexcept - { - return fUUID; - } - - private: - GUIDSequence fUUID; - }; -} // namespace CF::XRN +namespace CF::XRN { +using namespace Kernel; + +union GUIDSequence { + 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: + GUID& operator=(const GUID&) = default; + GUID(const GUID&) = default; + + public: + GUIDSequence& operator->() noexcept { return fUUID; } + GUIDSequence& Leak() noexcept { return fUUID; } + + private: + GUIDSequence fUUID; +}; +} // namespace CF::XRN diff --git a/dev/kernel/CFKit/Property.h b/dev/kernel/CFKit/Property.h index 510b2c53..4dde15f9 100644 --- a/dev/kernel/CFKit/Property.h +++ b/dev/kernel/CFKit/Property.h @@ -1,56 +1,53 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef CFKIT_PROPS_H #define CFKIT_PROPS_H +#include #include #include #include #include -#include #define kMaxPropLen (256U) -namespace CF -{ - using namespace Kernel; - - /// @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(KString& name); - PropertyId& GetValue(); - KString& GetKey(); - - private: - KString fName{kMaxPropLen}; - PropertyId fValue{0UL}; - Ref fGUID{}; - }; - - template - using PropertyArray = Array; -} // namespace CF - -namespace Kernel -{ - using namespace CF; +namespace CF { +using namespace Kernel; + +/// @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(KString& name); + PropertyId& GetValue(); + KString& GetKey(); + + private: + KString fName{kMaxPropLen}; + PropertyId fValue{0UL}; + Ref fGUID{}; +}; + +template +using PropertyArray = Array; +} // namespace CF + +namespace Kernel { +using namespace CF; } -#endif // !CFKIT_PROPS_H +#endif // !CFKIT_PROPS_H diff --git a/dev/kernel/CFKit/Utils.h b/dev/kernel/CFKit/Utils.h index b2a8b708..a5df8097 100644 --- a/dev/kernel/CFKit/Utils.h +++ b/dev/kernel/CFKit/Utils.h @@ -1,56 +1,46 @@ #ifndef CFKIT_UTILS_H #define CFKIT_UTILS_H -#include #include +#include /// @brief CFKit -namespace CF -{ - using namespace Kernel; - - /// @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; - - return (LDR_EXEC_HEADER_PTR)(VoidPtr)(&ptrDos->eLfanew + 1); - } - - /// @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 CF - -#endif // ifndef CFKIT_UTILS_H +namespace CF { +using namespace Kernel; + +/// @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; + + return (LDR_EXEC_HEADER_PTR) (VoidPtr) (&ptrDos->eLfanew + 1); +} + +/// @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 CF + +#endif // ifndef CFKIT_UTILS_H diff --git a/dev/kernel/CompilerKit/CompilerKit.h b/dev/kernel/CompilerKit/CompilerKit.h index 7f3bbe28..83910ee0 100644 --- a/dev/kernel/CompilerKit/CompilerKit.h +++ b/dev/kernel/CompilerKit/CompilerKit.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/CompilerKit/Detail.h b/dev/kernel/CompilerKit/Detail.h index 8fb07256..863ca145 100644 --- a/dev/kernel/CompilerKit/Detail.h +++ b/dev/kernel/CompilerKit/Detail.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,20 +8,20 @@ #ifdef __NEOSKRNL__ #include -#endif // ifdef __NEOSKRNL__ +#endif // ifdef __NEOSKRNL__ -#define NE_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; +#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_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_DELETE(KLASS) \ + KLASS& operator=(KLASS&&) = delete; \ + KLASS(KLASS&&) = delete; -#define NE_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; +#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 index 0f4f863d..21d9b4f2 100644 --- a/dev/kernel/CompilerKit/Version.h +++ b/dev/kernel/CompilerKit/Version.h @@ -4,7 +4,7 @@ /// .. #define BOOTLOADER_VERSION "1104.2025.110" -#define KERNEL_VERSION "1104.2025.110" +#define KERNEL_VERSION "1104.2025.110" #define BOOTLOADER_VERSION_BCD 0x20250415 -#define KERNEL_VERSION_BCD 0x20250415 +#define KERNEL_VERSION_BCD 0x20250415 diff --git a/dev/kernel/FSKit/Defines.h b/dev/kernel/FSKit/Defines.h index 9ab87e0f..c4c4e497 100644 --- a/dev/kernel/FSKit/Defines.h +++ b/dev/kernel/FSKit/Defines.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,5 +8,5 @@ #include -#define FSKIT_VERSION "1.0.0" +#define FSKIT_VERSION "1.0.0" #define FSKIT_VERSION_BCD 0x0100 diff --git a/dev/kernel/FSKit/Ext2.h b/dev/kernel/FSKit/Ext2.h index c27eb5f9..17645139 100644 --- a/dev/kernel/FSKit/Ext2.h +++ b/dev/kernel/FSKit/Ext2.h @@ -1,135 +1,133 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -#include #include #include #include +#include /// @file Ext2.h /// @brief EXT2 filesystem structures and constants. -#define kExt2FSMagic (0xEF53) -#define kExt2FSMaxFileNameLen (255U) +#define kExt2FSMagic (0xEF53) +#define kExt2FSMaxFileNameLen (255U) #define kExt2FSSuperblockOffset (1024) -#define kExt2FSRootInodeNumber (2) +#define kExt2FSRootInodeNumber (2) -#define kExt2FSInodeSize (128U) +#define kExt2FSInodeSize (128U) #define kExt2FSBlockSizeBase (1024U) #define kExt2FSRev0 (0) #define kExt2FSRev1 (1) /// @brief EXT2's file types. -enum -{ - kExt2FileTypeUnknown = 0, - kExt2FileTypeRegular = 1, - kExt2FileTypeDirectory = 2, - kExt2FileTypeCharDevice = 3, - kExt2FileTypeBlockDevice = 4, - kExt2FileTypeFIFO = 5, - kExt2FileTypeSocket = 6, - kExt2FileTypeSymbolicLink = 7 +enum { + kExt2FileTypeUnknown = 0, + kExt2FileTypeRegular = 1, + kExt2FileTypeDirectory = 2, + kExt2FileTypeCharDevice = 3, + kExt2FileTypeBlockDevice = 4, + kExt2FileTypeFIFO = 5, + kExt2FileTypeSocket = 6, + kExt2FileTypeSymbolicLink = 7 }; /// @brief The super block structure, located at LBA 1024. -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; // should be 0xEF53 - 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; - - // Optional journal fields and padding - 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_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; // should be 0xEF53 + 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; + + // Optional journal fields and padding + 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]; // 0-11: direct, 12: indirect, 13: double indirect, 14: triple indirect - - Kernel::UInt32 fGeneration; - Kernel::UInt32 fFileACL; - Kernel::UInt32 fDirACL; // Only for revision 1+ - Kernel::UInt32 fFragmentAddr; - - Kernel::UInt8 fOSD2[12]; +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]; // 0-11: direct, 12: indirect, 13: double indirect, 14: triple indirect + + Kernel::UInt32 fGeneration; + Kernel::UInt32 fFileACL; + Kernel::UInt32 fDirACL; // Only for revision 1+ + Kernel::UInt32 fFragmentAddr; + + Kernel::UInt8 fOSD2[12]; }; -struct PACKED EXT2_DIR_ENTRY final -{ - Kernel::UInt32 fInode; - Kernel::UInt16 fRecordLength; - Kernel::UInt8 fNameLength; - Kernel::UInt8 fFileType; - Kernel::Char fName[kExt2FSMaxFileNameLen]; // null-terminated, not fixed-length in actual on-disk layout +struct PACKED EXT2_DIR_ENTRY final { + Kernel::UInt32 fInode; + Kernel::UInt16 fRecordLength; + Kernel::UInt8 fNameLength; + Kernel::UInt8 fFileType; + Kernel::Char + fName[kExt2FSMaxFileNameLen]; // null-terminated, not fixed-length in actual on-disk layout }; \ No newline at end of file diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 0ad47739..e4da9a47 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -1,24 +1,24 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -#include #include -#include -#include #include #include +#include +#include +#include /// @file HeFS.h /// @brief HeFS filesystem support. -#define kHeFSVersion (0x0101) -#define kHeFSMagic " HeFS" +#define kHeFSVersion (0x0101) +#define kHeFSMagic " HeFS" #define kHeFSMagicLen (8) #define kHeFSFileNameLen (256U) @@ -34,348 +34,334 @@ struct HEFS_BOOT_NODE; struct HEFS_INDEX_NODE; struct HEFS_INDEX_NODE_DIRECTORY; -enum -{ - 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 = 7, +enum { + 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 = 7, }; -enum -{ - kHeFSStatusUnlocked = 0x18, - kHeFSStatusLocked, - kHeFSStatusError, - kHeFSStatusInvalid, - kHeFSStatusCount, +enum { + kHeFSStatusUnlocked = 0x18, + kHeFSStatusLocked, + kHeFSStatusError, + kHeFSStatusInvalid, + kHeFSStatusCount, }; -enum -{ - kHeFSEncodingUTF8 = 0x00, - kHeFSEncodingUTF16, - kHeFSEncodingUTF32, - kHeFSEncodingUTF16BE, - kHeFSEncodingUTF16LE, - kHeFSEncodingUTF32BE, - kHeFSEncodingUTF32LE, - kHeFSEncodingUTF8BE, - kHeFSEncodingUTF8LE, - kHeFSEncodingCount, +enum { + kHeFSEncodingUTF8 = 0x00, + kHeFSEncodingUTF16, + kHeFSEncodingUTF32, + kHeFSEncodingUTF16BE, + kHeFSEncodingUTF16LE, + kHeFSEncodingUTF32BE, + kHeFSEncodingUTF32LE, + kHeFSEncodingUTF8BE, + kHeFSEncodingUTF8LE, + kHeFSEncodingCount, }; -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 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; +inline constexpr UInt16 kHeFSFileKindUnknown = 0x07; +inline constexpr UInt16 kHeFSFileKindCount = 0x08; /// @brief HeFS 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. +/// @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 kHeFSBlockCount = 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; -} // namespace Kernel +namespace Kernel { +/// @brief Access time type. +/// @details Used to keep track of the INode, INodeDir allocation status. +typedef UInt64 ATime; +} // namespace Kernel /// @brief HeFS 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 -{ - Kernel::Char fMagic[kHeFSMagicLen]; /// @brief Magic number of the filesystem. - Kernel::Utf16Char fVolName[kHeFSPartNameLen]; /// @brief Volume name. - Kernel::UInt32 fVersion; /// @brief Version of the filesystem. - Kernel::UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem. - Kernel::UInt64 fSectorCount; /// @brief Number of sectors in the filesystem. - Kernel::UInt64 fSectorSize; /// @brief Size of the sector. - Kernel::UInt32 fChecksum; /// @brief Checksum of the boot node. - Kernel::UInt8 fDriveKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical Drive, etc). - Kernel::UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc). - Kernel::UInt64 fStartIND; /// @brief Start of the INode tree. - Kernel::UInt64 fEndIND; /// @brief End of the INode tree. - Kernel::UInt64 fINDCount; /// @brief Number of leafs in the INode tree. - Kernel::UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the real size of the disk.) - Kernel::UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid). - Kernel::UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). - Kernel::UInt16 fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). - Kernel::UInt64 fReserved; /// @brief Reserved for future use. - Kernel::UInt64 fReserved2; /// @brief Reserved for future use. - Kernel::UInt64 fReserved3; /// @brief Reserved for future use. - Kernel::UInt64 fReserved4; /// @brief Reserved for future use. +struct PACKED HEFS_BOOT_NODE final { + Kernel::Char fMagic[kHeFSMagicLen]; /// @brief Magic number of the filesystem. + Kernel::Utf16Char fVolName[kHeFSPartNameLen]; /// @brief Volume name. + Kernel::UInt32 fVersion; /// @brief Version of the filesystem. + Kernel::UInt64 fBadSectors; /// @brief Number of bad sectors in the filesystem. + Kernel::UInt64 fSectorCount; /// @brief Number of sectors in the filesystem. + Kernel::UInt64 fSectorSize; /// @brief Size of the sector. + Kernel::UInt32 fChecksum; /// @brief Checksum of the boot node. + Kernel::UInt8 fDriveKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical + /// Drive, etc). + Kernel::UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc). + Kernel::UInt64 fStartIND; /// @brief Start of the INode tree. + Kernel::UInt64 fEndIND; /// @brief End of the INode tree. + Kernel::UInt64 fINDCount; /// @brief Number of leafs in the INode tree. + Kernel::UInt64 fDiskSize; /// @brief Size of the disk. (Could be a virtual size, that is not the + /// real size of the disk.) + Kernel::UInt16 fDiskStatus; /// @brief Status of the disk. (locked, unlocked, error, invalid). + Kernel::UInt16 fDiskFlags; /// @brief Flags of the disk. (read-only, read-write, etc). + Kernel::UInt16 + fVID; /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used). + Kernel::UInt64 fReserved; /// @brief Reserved for future use. + Kernel::UInt64 fReserved2; /// @brief Reserved for future use. + Kernel::UInt64 fReserved3; /// @brief Reserved for future use. + Kernel::UInt64 fReserved4; /// @brief Reserved for future use. }; inline constexpr Kernel::ATime kHeFSTimeInvalid = 0x0000000000000000; -inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; +inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; /// @brief HeFS 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 ALIGN(8) HEFS_INDEX_NODE final -{ - Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief File name. - Kernel::UInt32 fFlags; /// @brief File flags. - Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, Symbolic Link, Unknown). - Kernel::UInt32 fSize; /// @brief File size. - Kernel::UInt32 fChecksum, fRecoverChecksum, fBlockChecksum, fLinkChecksum; /// @brief Checksum of the file, recovery checksum, block checksum, link checksum. - - Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. - Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. - Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). - - Kernel::UInt64 fBlockLinkStart[kHeFSBlockCount]; /// @brief Start of the block link. - Kernel::UInt64 fBlockLinkEnd[kHeFSBlockCount]; /// @brief End of the block link. - - Kernel::UInt64 fBlockStart[kHeFSBlockCount]; /// @brief Start of the block. - Kernel::UInt64 fBlockEnd[kHeFSBlockCount]; /// @brief End of the block. - - Kernel::UInt64 fBlockRecoveryStart[kHeFSBlockCount]; /// @brief Start of the block recovery. - Kernel::UInt64 fBlockRecoveryEnd[kHeFSBlockCount]; /// @brief End of the block recovery. +struct PACKED ALIGN(8) HEFS_INDEX_NODE final { + Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief File name. + Kernel::UInt32 fFlags; /// @brief File flags. + Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, + /// Symbolic Link, Unknown). + Kernel::UInt32 fSize; /// @brief File size. + Kernel::UInt32 fChecksum, fRecoverChecksum, fBlockChecksum, + fLinkChecksum; /// @brief Checksum of the file, recovery checksum, block checksum, link + /// checksum. + + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. + Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. + Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). + + Kernel::UInt64 fBlockLinkStart[kHeFSBlockCount]; /// @brief Start of the block link. + Kernel::UInt64 fBlockLinkEnd[kHeFSBlockCount]; /// @brief End of the block link. + + Kernel::UInt64 fBlockStart[kHeFSBlockCount]; /// @brief Start of the block. + Kernel::UInt64 fBlockEnd[kHeFSBlockCount]; /// @brief End of the block. + + Kernel::UInt64 fBlockRecoveryStart[kHeFSBlockCount]; /// @brief Start of the block recovery. + Kernel::UInt64 fBlockRecoveryEnd[kHeFSBlockCount]; /// @brief End of the block recovery. }; -enum -{ - kHeFSRed = 100, - kHeFSBlack, - kHeFSColorCount, +enum { + kHeFSRed = 100, + kHeFSBlack, + kHeFSColorCount, }; /// @brief HeFS 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 ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final -{ - Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief Directory name. - - Kernel::UInt32 fFlags; /// @brief File flags. - Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, Symbolic Link, Unknown). - Kernel::UInt32 fEntryCount; /// @brief Entry Count of this directory inode. - Kernel::UInt32 fChecksum, fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum. - - Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. - Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. - Kernel::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. - Kernel::UInt64 fIndexNodeStart[kHeFSBlockCount]; /// @brief Start of the index node. - Kernel::UInt64 fIndexNodeEnd[kHeFSBlockCount]; /// @brief End of the index node. - - Kernel::UInt8 fColor; /// @brief Color of the node. (Red or Black). - Kernel::Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers. +struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final { + Kernel::Utf16Char fName[kHeFSFileNameLen]; /// @brief Directory name. + + Kernel::UInt32 fFlags; /// @brief File flags. + Kernel::UInt16 fKind; /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket, + /// Symbolic Link, Unknown). + Kernel::UInt32 fEntryCount; /// @brief Entry Count of this directory inode. + Kernel::UInt32 fChecksum, + fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum. + + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. + Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. + Kernel::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. + Kernel::UInt64 fIndexNodeStart[kHeFSBlockCount]; /// @brief Start of the index node. + Kernel::UInt64 fIndexNodeEnd[kHeFSBlockCount]; /// @brief End of the index node. + + Kernel::UInt8 fColor; /// @brief Color of the node. (Red or Black). + Kernel::Lba fNext, fPrev, fChild, fParent; /// @brief Red-black tree pointers. }; -namespace Kernel::Detail -{ - /// @brief HeFS get year from Kernel::ATime. - /// @param raw_atime the raw Kernel::ATime value. - /// @return the year value. - /// @note The year is stored in the upper 32 bits of the Kernel::ATime value. - inline UInt32 hefs_year_get(Kernel::ATime raw_atime) noexcept - { - return (raw_atime) >> 32; - } - - /// @brief HeFS get month from Kernel::ATime. - /// @param raw_atime the raw Kernel::ATime value. - /// @return the month value. - /// @note The month is stored in the upper 24 bits of the Kernel::ATime value. - inline UInt32 hefs_month_get(Kernel::ATime raw_atime) noexcept - { - return (raw_atime) >> 24; - } - - /// @brief HeFS get day from Kernel::ATime. - /// @param raw_atime the raw Kernel::ATime value. - /// @return the day value. - /// @note The day is stored in the upper 16 bits of the Kernel::ATime value. - inline UInt32 hefs_day_get(Kernel::ATime raw_atime) noexcept - { - return (raw_atime) >> 16; - } - - /// @brief HeFS get hour from Kernel::ATime. - /// @param raw_atime the raw Kernel::ATime value. - /// @return the hour value. - /// @note The hour is stored in the upper 8 bits of the Kernel::ATime value. - inline UInt32 hefs_hour_get(Kernel::ATime raw_atime) noexcept - { - return (raw_atime) >> 8; - } - - /// @brief HeFS get minute from Kernel::ATime. - /// @param raw_atime the raw Kernel::ATime value. - /// @return the minute value. - /// @note The minute is stored in the lower 8 bits of the Kernel::ATime value. - inline UInt32 hefs_minute_get(Kernel::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 kHeFSEncodingUTF8: - return "UTF-8"; - case kHeFSEncodingUTF16: - return "UTF-16"; - case kHeFSEncodingUTF32: - return "UTF-32"; - case kHeFSEncodingUTF16BE: - return "UTF-16BE"; - case kHeFSEncodingUTF16LE: - return "UTF-16LE"; - case kHeFSEncodingUTF32BE: - return "UTF-32BE"; - case kHeFSEncodingUTF32LE: - return "UTF-32LE"; - case kHeFSEncodingUTF8BE: - return "UTF-8BE"; - case kHeFSEncodingUTF8LE: - 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 0x00: - return "No Flags"; - case 0x01: - return "Read Only"; - case 0x02: - return "Hidden"; - case 0x04: - return "System"; - case 0x08: - return "Archive"; - case 0x10: - return "Device"; - default: - return "Unknown"; - } - } -} // namespace Kernel::Detail - -namespace Kernel -{ - /// @brief HeFS filesystem parser class. - /// @details This class is used to parse the HeFS 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+HeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name); - - /// @brief Make a GPT+HeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name); - - public: - UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this filesystem is mounted on. - }; -} // namespace Kernel \ No newline at end of file +namespace Kernel::Detail { +/// @brief HeFS get year from Kernel::ATime. +/// @param raw_atime the raw Kernel::ATime value. +/// @return the year value. +/// @note The year is stored in the upper 32 bits of the Kernel::ATime value. +inline UInt32 hefs_year_get(Kernel::ATime raw_atime) noexcept { + return (raw_atime) >> 32; +} + +/// @brief HeFS get month from Kernel::ATime. +/// @param raw_atime the raw Kernel::ATime value. +/// @return the month value. +/// @note The month is stored in the upper 24 bits of the Kernel::ATime value. +inline UInt32 hefs_month_get(Kernel::ATime raw_atime) noexcept { + return (raw_atime) >> 24; +} + +/// @brief HeFS get day from Kernel::ATime. +/// @param raw_atime the raw Kernel::ATime value. +/// @return the day value. +/// @note The day is stored in the upper 16 bits of the Kernel::ATime value. +inline UInt32 hefs_day_get(Kernel::ATime raw_atime) noexcept { + return (raw_atime) >> 16; +} + +/// @brief HeFS get hour from Kernel::ATime. +/// @param raw_atime the raw Kernel::ATime value. +/// @return the hour value. +/// @note The hour is stored in the upper 8 bits of the Kernel::ATime value. +inline UInt32 hefs_hour_get(Kernel::ATime raw_atime) noexcept { + return (raw_atime) >> 8; +} + +/// @brief HeFS get minute from Kernel::ATime. +/// @param raw_atime the raw Kernel::ATime value. +/// @return the minute value. +/// @note The minute is stored in the lower 8 bits of the Kernel::ATime value. +inline UInt32 hefs_minute_get(Kernel::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 kHeFSEncodingUTF8: + return "UTF-8"; + case kHeFSEncodingUTF16: + return "UTF-16"; + case kHeFSEncodingUTF32: + return "UTF-32"; + case kHeFSEncodingUTF16BE: + return "UTF-16BE"; + case kHeFSEncodingUTF16LE: + return "UTF-16LE"; + case kHeFSEncodingUTF32BE: + return "UTF-32BE"; + case kHeFSEncodingUTF32LE: + return "UTF-32LE"; + case kHeFSEncodingUTF8BE: + return "UTF-8BE"; + case kHeFSEncodingUTF8LE: + 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 0x00: + return "No Flags"; + case 0x01: + return "Read Only"; + case 0x02: + return "Hidden"; + case 0x04: + return "System"; + case 0x08: + return "Archive"; + case 0x10: + return "Device"; + default: + return "Unknown"; + } +} +} // namespace Kernel::Detail + +namespace Kernel { +/// @brief HeFS filesystem parser class. +/// @details This class is used to parse the HeFS 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+HeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + _Output Bool FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, + _Input const Int32 flags, const Char* part_name); + + /// @brief Make a GPT+HeFS drive out of the disk. + /// @param drive The drive to write on. + /// @return If it was sucessful, see err_local_get(). + _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, + _Input const Int32 flags, const Char* part_name); + + public: + UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this + /// filesystem is mounted on. +}; +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/FSKit/IndexableProperty.h b/dev/kernel/FSKit/IndexableProperty.h index 96853fbc..3f2c42ac 100644 --- a/dev/kernel/FSKit/IndexableProperty.h +++ b/dev/kernel/FSKit/IndexableProperty.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,54 +11,48 @@ #include #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() - { - Kernel::KString strProp(kMaxPropLen); - strProp += "/prop/indexable"; - - this->GetKey() = strProp; - } - - ~IndexableProperty() override = default; - - NE_COPY_DEFAULT(IndexableProperty) - - public: - Index& Leak() noexcept; - - public: - void AddFlag(Int16 flag); - void RemoveFlag(Int16 flag); - Int16 HasFlag(Int16 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 +#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() { + Kernel::KString strProp(kMaxPropLen); + strProp += "/prop/indexable"; + + this->GetKey() = strProp; + } + + ~IndexableProperty() override = default; + + NE_COPY_DEFAULT(IndexableProperty) + + public: + Index& Leak() noexcept; + + public: + void AddFlag(Int16 flag); + void RemoveFlag(Int16 flag); + Int16 HasFlag(Int16 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 index 6b1849ff..425ab051 100644 --- a/dev/kernel/FSKit/NeFS.h +++ b/dev/kernel/FSKit/NeFS.h @@ -1,15 +1,15 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - FILE: NeFS.h - PURPOSE: NeFS (New extended File System) support. + FILE: NeFS.h + PURPOSE: NeFS (New extended File System) support. - Revision History: + 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 + ?/?/?: 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. ------------------------------------------- */ @@ -17,17 +17,17 @@ default. #pragma once #include -#include #include #include #include +#include /** - @brief New extended File System specification. - @author Amlal El Mahrouss (Amlal El Mahrouss, amlalelmahrouss at icloud dot com) + @brief New extended File System specification. + @author Amlal El Mahrouss (Amlal El Mahrouss, amlalelmahrouss at icloud dot com) */ -#define kNeFSInvalidFork (-1) +#define kNeFSInvalidFork (-1) #define kNeFSInvalidCatalog (-1) #define kNeFSCatalogNameLen (256) @@ -36,415 +36,381 @@ default. #define kNeFSSectorSz (512) #define kNeFSIdentLen (8) -#define kNeFSIdent " NeFS" -#define kNeFSPadLen (392) +#define kNeFSIdent " NeFS" +#define kNeFSPadLen (392) #define kNeFSMetaFilePrefix '$' #define kNeFSVersionInteger (0x0129) -#define kNeFSVerionString "1.2.9" +#define kNeFSVerionString "1.2.9" /// @brief Standard fork types. -#define kNeFSDataFork "main_data" +#define kNeFSDataFork "main_data" #define kNeFSResourceFork "main_rsrc" #define kNeFSForkSize (sizeof(NEFS_FORK_STRUCT)) #define kNeFSPartitionTypeStandard (7) -#define kNeFSPartitionTypePage (8) -#define kNeFSPartitionTypeBoot (9) +#define kNeFSPartitionTypePage (8) +#define kNeFSPartitionTypeBoot (9) -#define kNeFSCatalogKindFile (1) -#define kNeFSCatalogKindDir (2) +#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 kNeFSCatalogKindResource (5) #define kNeFSCatalogKindExecutable (6) #define kNeFSCatalogKindPage (8) #define kNeFSCatalogKindDevice (9) -#define kNeFSCatalogKindLock (10) +#define kNeFSCatalogKindLock (10) -#define kNeFSCatalogKindRLE (11) +#define kNeFSCatalogKindRLE (11) #define kNeFSCatalogKindMetaFile (12) -#define kNeFSCatalogKindTTF (13) +#define kNeFSCatalogKindTTF (13) #define kNeFSCatalogKindRIFF (14) #define kNeFSCatalogKindMPEG (15) #define kNeFSCatalogKindMOFF (16) -#define kNeFSSeparator '/' +#define kNeFSSeparator '/' #define kNeFSSeparatorAlt '/' -#define kNeFSUpDir ".." -#define kNeFSRoot "/" +#define kNeFSUpDir ".." +#define kNeFSRoot "/" #define kNeFSRootAlt "/" -#define kNeFSLF '\r' +#define kNeFSLF '\r' #define kNeFSEOF (-1) #define kNeFSBitWidth (sizeof(Kernel::Char)) -#define kNeFSLbaType (Kernel::Lba) +#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 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 kResourceTypeMenu (12) +#define kResourceTypeSound (13) +#define kResourceTypeFont (14) +#define kNeFSPartLen (32) -#define kNeFSFlagDeleted (70) +#define kNeFSFlagDeleted (70) #define kNeFSFlagUnallocated (0) -#define kNeFSFlagCreated (71) +#define kNeFSFlagCreated (71) #define kNeFSMimeNameLen (200) #define kNeFSForkNameLen (200) -#define kNeFSFrameworkExt ".fwrk/" -#define kNeFSStepsExt ".step/" +#define kNeFSFrameworkExt ".fwrk/" +#define kNeFSStepsExt ".step/" #define kNeFSApplicationExt ".app/" -#define kNeFSJournalExt ".jrnl" +#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 { + 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, +enum { + kNeFSStatusUnlocked = 0x18, + kNeFSStatusLocked, + kNeFSStatusError, + kNeFSStatusInvalid, + kNeFSStatusCount, }; /// @brief Catalog record type. -struct PACKED NEFS_CATALOG_STRUCT final -{ - BOOL ForkOrCatalog : 1 {0}; +struct PACKED NEFS_CATALOG_STRUCT final { + BOOL ForkOrCatalog : 1 {0}; - Kernel::Char Name[kNeFSCatalogNameLen] = {0}; - Kernel::Char Mime[kNeFSMimeNameLen] = {0}; + Kernel::Char Name[kNeFSCatalogNameLen] = {0}; + Kernel::Char Mime[kNeFSMimeNameLen] = {0}; - /// Catalog flags. - Kernel::UInt16 Flags; + /// Catalog flags. + Kernel::UInt16 Flags; - /// Catalog allocation status. - Kernel::UInt16 Status; + /// Catalog allocation status. + Kernel::UInt16 Status; - /// Custom catalog flags. - Kernel::UInt16 CatalogFlags; + /// Custom catalog flags. + Kernel::UInt16 CatalogFlags; - /// Catalog kind. - Kernel::Int32 Kind; + /// Catalog kind. + Kernel::Int32 Kind; - /// Size of the data fork. - Kernel::Lba DataForkSize; + /// Size of the data fork. + Kernel::Lba DataForkSize; - /// Size of all resource forks. - Kernel::Lba ResourceForkSize; + /// Size of all resource forks. + Kernel::Lba ResourceForkSize; - /// Forks LBA. - Kernel::Lba DataFork; - Kernel::Lba ResourceFork; + /// Forks LBA. + Kernel::Lba DataFork; + Kernel::Lba ResourceFork; - /// Buddy allocation tracker. - Kernel::Lba NextSibling; - Kernel::Lba PrevSibling; + /// Buddy allocation tracker. + Kernel::Lba NextSibling; + Kernel::Lba PrevSibling; - /// Best-buddy tracker. - Kernel::Lba NextBestSibling; - Kernel::Lba NextPrevSibling; + /// Best-buddy tracker. + Kernel::Lba NextBestSibling; + Kernel::Lba NextPrevSibling; - Kernel::UInt32 Checksum; + 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}; +/// @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::Char ForkName[kNeFSForkNameLen] = {0}; + Kernel::Char CatalogName[kNeFSCatalogNameLen] = {0}; - Kernel::Int32 Flags; - Kernel::Int32 Kind; + Kernel::Int32 Flags; + Kernel::Int32 Kind; - Kernel::Int64 ResourceId; - Kernel::Int32 ResourceKind; - Kernel::Int32 ResourceFlags; + 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 DataOffset; // 8 Where to look for this data? + Kernel::SizeT DataSize; /// Data size according using sector count. - Kernel::Lba NextSibling; - Kernel::Lba PreviousSibling; + Kernel::Lba NextSibling; + Kernel::Lba PreviousSibling; - Kernel::Char Pad[2] = {0}; + Kernel::Char Pad[2] = {0}; }; /// @brief Partition block type -struct PACKED NEFS_ROOT_PARTITION_BLOCK final -{ - Kernel::Char Ident[kNeFSIdentLen] = {0}; - Kernel::Char PartitionName[kNeFSPartLen] = {0}; +struct PACKED NEFS_ROOT_PARTITION_BLOCK final { + Kernel::Char Ident[kNeFSIdentLen] = {0}; + Kernel::Char PartitionName[kNeFSPartLen] = {0}; + + Kernel::Int32 Flags; + Kernel::Int32 Kind; - Kernel::Int32 Flags; - Kernel::Int32 Kind; + Kernel::Lba StartCatalog; + Kernel::SizeT CatalogCount; - Kernel::Lba StartCatalog; - Kernel::SizeT CatalogCount; + Kernel::SizeT DiskSize; - Kernel::SizeT DiskSize; + Kernel::SizeT FreeCatalog; + Kernel::SizeT FreeSectors; - Kernel::SizeT FreeCatalog; - Kernel::SizeT FreeSectors; + Kernel::SizeT SectorCount; + Kernel::SizeT SectorSize; - Kernel::SizeT SectorCount; - Kernel::SizeT SectorSize; + Kernel::UInt64 Version; - Kernel::UInt64 Version; + Kernel::Lba EpmBlock; - Kernel::Lba EpmBlock; + Kernel::Char Pad[kNeFSPadLen]; +}; - Kernel::Char Pad[kNeFSPadLen]; +namespace Kernel { +class NeFileSystemParser; +class NeFileSystemJournal; +class NeFileSystemHelper; + +enum { + kNeFSSubDriveA, + kNeFSSubDriveB, + kNeFSSubDriveC, + kNeFSSubDriveD, + kNeFSSubDriveInvalid, + kNeFSSubDriveCount, }; -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 FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name); - - _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _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)); - } +/// \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); - ~NeFileSystemJournal() = default; + _Output NEFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalog_name, Lba& ou_lba, + Bool search_hidden = YES, Bool local_search = NO); - NE_COPY_DEFAULT(NeFileSystemJournal) + _Output NEFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name); - Bool CreateJournal(NeFileSystemParser* parser) - { - if (!parser) - return NO; - - delete parser->CreateCatalog("/etc/xml/", 0, kNeFSCatalogKindDir); - mNode = parser->CreateCatalog(mStamp); + _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name, _Input const Int32& flags, + _Input const Int32& kind); - if (!mNode) - return NO; + _Output NEFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name); - return YES; - } + _Output Bool WriteCatalog(_Input const Char* catalog, _Input Bool rsrc, _Input VoidPtr data, + _Input SizeT sz, _Input const Char* name); - Bool GetJournal(NeFileSystemParser* parser) - { - if (!parser) - return NO; + _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 FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, + _Input const Int32 flags, const Char* part_name); + + _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, + _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(); +}; - auto node = parser->GetCatalog(mStamp); +/// @brief Journal class for NeFS. +class NeFileSystemJournal final { + private: + NEFS_CATALOG_STRUCT* mNode{nullptr}; - if (node) - { - mNode = node; - return YES; - } + public: + explicit NeFileSystemJournal(const char* stamp = nullptr) { + if (!stamp) { + kout << "Invalid: Journal stamp, using default name.\r"; + return; + } - return NO; - } + (Void)(kout << "Info: Journal stamp: " << stamp << kendl); + rt_copy_memory((VoidPtr) stamp, this->mStamp, rt_string_len(stamp)); + } - Bool ReleaseJournal() - { - if (mNode) - { - delete mNode; - mNode = nullptr; - return YES; - } + ~NeFileSystemJournal() = default; - return NO; - } + 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}; +}; - 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 +namespace NeFS { + Boolean fs_init_nefs(Void) noexcept; +} // namespace NeFS +} // namespace Kernel diff --git a/dev/kernel/FirmwareKit/CoreBoot/BootNet.h b/dev/kernel/FirmwareKit/CoreBoot/BootNet.h index b692c774..6639d9e3 100644 --- a/dev/kernel/FirmwareKit/CoreBoot/BootNet.h +++ b/dev/kernel/FirmwareKit/CoreBoot/BootNet.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,25 +8,25 @@ #include -#define kBootNetINetMagic "NETB" +#define kBootNetINetMagic "NETB" #define kBootNetINetMagicLength (4) #define kBootNetNameLen (256U) /// @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) +/// 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 'N' - Kernel::Char NB2; /// magic char 2 'E' - Kernel::Char NB3; /// magic char 3 'T' - Kernel::Char NB4; /// magic char 4 'B' - - 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** +typedef struct BOOTNET_INTERNET_HEADER { + Kernel::Char NB1; /// magic char 1 'N' + Kernel::Char NB2; /// magic char 2 'E' + Kernel::Char NB3; /// magic char 3 'T' + Kernel::Char NB4; /// magic char 4 'B' + + 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** } BOOTNET_INTERNET_HEADER; diff --git a/dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h b/dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h index e1f3fbc6..2b274f21 100644 --- a/dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h +++ b/dev/kernel/FirmwareKit/CoreBoot/CoreBoot.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,29 +8,27 @@ #include -namespace Firmware::Detail::CoreBoot -{ - using namespace Kernel; +namespace Firmware::Detail::CoreBoot { +using namespace Kernel; - struct COREBOOT_LINEAR_EXEC; +struct COREBOOT_LINEAR_EXEC; - /// @brief Linear Executable Header - /// @author Amlal El Mahrouss - struct ATTRIBUTE(aligned(4)) COREBOOT_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) +/// @brief Linear Executable Header +/// @author Amlal El Mahrouss +struct ATTRIBUTE(aligned(4)) COREBOOT_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. + 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. + UIntPtr fMBCIStructure; // MBCI structure for MBCI (ARM) + UIntPtr fMBCIStructureVersion; // MBCI structure version. #endif - }; -} // namespace Firmware::Detail::CoreBoot +}; +} // namespace Firmware::Detail::CoreBoot diff --git a/dev/kernel/FirmwareKit/CoreBoot/NS.h b/dev/kernel/FirmwareKit/CoreBoot/NS.h index 711a233d..06197fcd 100644 --- a/dev/kernel/FirmwareKit/CoreBoot/NS.h +++ b/dev/kernel/FirmwareKit/CoreBoot/NS.h @@ -1,10 +1,10 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include -#include \ No newline at end of file +#include +#include \ No newline at end of file diff --git a/dev/kernel/FirmwareKit/EFI.h b/dev/kernel/FirmwareKit/EFI.h index ca4360b1..96c4ad98 100644 --- a/dev/kernel/FirmwareKit/EFI.h +++ b/dev/kernel/FirmwareKit/EFI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/FirmwareKit/EFI/API.h b/dev/kernel/FirmwareKit/EFI/API.h index 87ab697b..0b937477 100644 --- a/dev/kernel/FirmwareKit/EFI/API.h +++ b/dev/kernel/FirmwareKit/EFI/API.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,7 +12,7 @@ #include #include -#define kNeWebsiteMacro "https://aker.com/help" +#define kNeWebsiteMacro "https://aker.com/help" #define kNeKernelSubsystem (StrLen(kNeWebsiteMacro)) #ifdef __BOOTZ__ @@ -23,79 +23,69 @@ class BootTextWriter; #include #include -#endif // ifdef __BOOTZ__ +#endif // ifdef __BOOTZ__ -inline EfiSystemTable* ST = nullptr; +inline EfiSystemTable* ST = nullptr; inline EfiBootServices* BS = nullptr; EXTERN_C void rt_cli(); EXTERN_C void rt_hlt(); -namespace Boot -{ - /// @brief Halt and clear interrupts. - /// @return - inline Void Stop() noexcept - { - while (YES) - { - rt_cli(); - rt_hlt(); - } - } - - /** +namespace Boot { +/// @brief Halt and clear interrupts. +/// @return +inline Void Stop() noexcept { + while (YES) { + rt_cli(); + rt_hlt(); + } +} + +/** @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; +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 -#endif // ifdef __BOOTZ__ +#endif // ifdef __BOOTZ__ #endif /* ifndef __EFI_API__ */ diff --git a/dev/kernel/FirmwareKit/EFI/EFI.h b/dev/kernel/FirmwareKit/EFI/EFI.h index 2772582b..196deb29 100644 --- a/dev/kernel/FirmwareKit/EFI/EFI.h +++ b/dev/kernel/FirmwareKit/EFI/EFI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -19,11 +19,11 @@ using namespace Kernel; #ifndef EPI_API #define EFI_API __attribute__((ms_abi)) -#endif // ifndef EPI_API +#endif // ifndef EPI_API #ifndef EPIAPI #define EFIAPI __attribute__((ms_abi)) -#endif // ifndef EPIAPI +#endif // ifndef EPIAPI #define IN #define OUT @@ -56,14 +56,13 @@ typedef Char16 EfiChar16Type; /// @brief Core Handle Kind /// Self is like NT's Win32 HANDLE type. -typedef struct EfiHandle -{ -} * EfiHandlePtr; +typedef struct EfiHandle { +}* EfiHandlePtr; /* UEFI uses wide characters by default. */ typedef WideChar EfiCharType; -typedef UInt64 EfiPhysicalAddress; +typedef UInt64 EfiPhysicalAddress; typedef UIntPtr EfiVirtualAddress; /// What's BootBolicy? @@ -72,18 +71,15 @@ typedef UIntPtr EfiVirtualAddress; /// FALSE, then FilePath must match an exact file to be loaded. typedef UInt64(EFI_API* EfiTextString)(struct EfiSimpleTextOutputProtocol* Self, - const WideChar* OutputString); + const WideChar* OutputString); typedef UInt64(EFI_API* EfiTextAttrib)(struct EfiSimpleTextOutputProtocol* Self, - const WideChar Attribute); + 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* EfiLoadFile)(EfiLoadFileProtocol* Self, EfiFileDevicePathProtocol* FilePath, + Boolean BootPolicy, UInt32* BufferSize, VoidPtr Buffer); typedef UInt64(EFI_API* EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length); @@ -91,146 +87,139 @@ typedef UInt64(EFI_API* EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length); typedef UInt64(EFI_API* EfiHandleProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Device); -typedef UInt64(EFI_API* EfiLocateDevicePath)(EfiGUID* Protocol, - EfiDevicePathProtocol** DevicePath, - EfiHandlePtr Device); +typedef UInt64(EFI_API* EfiLocateDevicePath)(EfiGUID* 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); +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, +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 +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; +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); @@ -242,362 +231,324 @@ typedef UInt64(EFI_API* EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize, UInt32 /** @brief Present in every header, used to identify a UEFI structure. */ -typedef struct EfiTableHeader -{ - UInt64 Signature; - UInt32 Revision; - UInt32 HeaderSize; - UInt32 Crc32; - UInt32 Reserved; +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_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_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 \ - } \ - } +#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 +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_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_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(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_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 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; +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; +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; +typedef struct EfiBitmask { + UInt32 RedMask; + UInt32 GreenMask; + UInt32 BlueMask; + UInt32 ReservedMask; } EfiBitmask; -typedef struct -{ - UInt8 Blue; - UInt8 Green; - UInt8 Red; - UInt8 Reserved; +typedef struct { + UInt8 Blue; + UInt8 Green; + UInt8 Red; + UInt8 Reserved; } EfiGraphicsOutputBltPixel; -typedef enum EfiGraphicsOutputProtocolBltOperation -{ - EfiBltVideoFill, - EfiBltVideoToBltBuffer, - EfiBltBufferToVideo, - EfiBltVideoToVideo, - EfiGraphicsOutputBltOperationMax +typedef enum EfiGraphicsOutputProtocolBltOperation { + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphicsOutputBltOperationMax } EfiGraphicsOutputProtocolBltOperation; -typedef struct EfiGraphicsOutputProtocolModeInformation -{ - UInt32 Version; - UInt32 HorizontalResolution; - UInt32 VerticalResolution; - UInt32 PixelFormat; - EfiBitmask PixelInformation; - UInt32 PixelsPerScanLine; +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); + EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber, UInt32* SizeOfInfo, + EfiGraphicsOutputProtocolModeInformation** Info); -typedef UInt64(EFI_API* EfiGraphicsOutputProtocolSetMode)( - EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber); +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; + 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; +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; +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; +typedef struct EfiLoadFileProtocol { + EfiLoadFile LoadFile; } EfiLoadFileProtocol; -typedef struct EfiDevicePathProtocol -{ - UInt8 Kind; - UInt8 SubType; - UInt8 Length[2]; +typedef struct EfiDevicePathProtocol { + UInt8 Kind; + UInt8 SubType; + UInt8 Length[2]; } EfiDevicePathProtocol; -typedef struct EfiFileDevicePathProtocol -{ - EfiDevicePathProtocol Proto; +typedef struct EfiFileDevicePathProtocol { + EfiDevicePathProtocol Proto; - /// - /// File Path of this struct - /// - WideChar Path[kPathLen]; + /// + /// File Path of this struct + /// + WideChar Path[kPathLen]; } EfiFileDevicePathProtocol; -typedef UInt64(EFI_API* EfiExitBootServices)(VoidPtr ImageHandle, - UInt32 MapKey); +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* 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); +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 EfiGUID EFI_FINAL -{ - UInt32 Data1; - UInt16 Data2; - UInt16 Data3; - UInt8 Data4[8]; +typedef struct EfiGUID EFI_FINAL { + UInt32 Data1; + UInt16 Data2; + UInt16 Data3; + UInt8 Data4[8]; } EfiGUID; /*** * Protocol stuff... */ -#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ - { \ - 0x387477c1, 0x69c7, 0x11d2, \ - { \ - 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ - } \ - } +#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_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 +#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 -typedef UInt64(EFI_API* EfiLocateProtocol)(EfiGUID* Protocol, - VoidPtr Registration, - VoidPtr* Interface); +typedef UInt64(EFI_API* EfiLocateProtocol)(EfiGUID* Protocol, VoidPtr Registration, + VoidPtr* Interface); -typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Interface, EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle, UInt32 Attributes); +typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Interface, + EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle, + UInt32 Attributes); typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Boolean Visible); @@ -606,432 +557,388 @@ typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Bool @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; +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 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; +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; +typedef struct { + UInt16 ScanCode; + EfiChar16Type UnicodeChar; } EfiInputKey; -typedef EfiStatusType(EFI_API* EfiInputReadKey)( - IN EfiSimpleTextInputProtocol* This, - OUT EfiInputKey* Key); +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* EfiInputReset)(IN EfiSimpleTextInputProtocol* This, + IN Boolean ExtendedChk); -typedef EfiStatusType(EFI_API* EfiWaitForEvent)( - IN UInt32 NumberOfEvents, - IN VoidPtr Event, - OUT UInt32* Index); +typedef EfiStatusType(EFI_API* EfiWaitForEvent)(IN UInt32 NumberOfEvents, IN VoidPtr Event, + OUT UInt32* Index); -typedef struct EfiSimpleTextInputProtocol -{ - EfiInputReset Reset; - EfiInputReadKey ReadKeyStroke; - EfiWaitForEvent WaitForKey; +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 EfiFileProtocol**); -struct EfiSimpleFilesystemProtocol -{ - UInt64 Revision; - EfiOpenVolume OpenVolume; +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, EfiGUID VendorGUID, UInt32* Attributes, UInt32* DataSize, VoidPtr Data); - VoidPtr GetNextVariable; - UInt64(EFI_API* SetVariable)(const WideChar* Name, EfiGUID VendorGUID, UInt32* Attributes, UInt32* DataSize, VoidPtr Data); - VoidPtr GetNextHighMonotonicCount; - VoidPtr ResetSystem; - VoidPtr UpdateCapsule; - VoidPtr QueryCapsuleCapabilites; - VoidPtr QueryVariableInfo; +typedef struct EfiRuntimeServices { + EfiTableHeader SystemTable; + VoidPtr GetTime, SetTime, GetWakeupTime, SetWakeupTime, SetVirtualAddressMap, ConvertPointer; + UInt64(EFI_API* GetVariable)(const WideChar* Name, EfiGUID VendorGUID, UInt32* Attributes, + UInt32* DataSize, VoidPtr Data); + VoidPtr GetNextVariable; + UInt64(EFI_API* SetVariable)(const WideChar* Name, EfiGUID 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 - { - EfiGUID VendorGUID; - VoidPtr VendorTable; - } * ConfigurationTable; +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 { + EfiGUID VendorGUID; + VoidPtr VendorTable; + }* ConfigurationTable; } EfiSystemTable; -#define kEfiOk 0 -#define kEfiFail -1 +#define kEfiOk 0 +#define kEfiFail -1 #define kBufferTooSmall 5 #define EFI_EXTERN_C extern "C" -typedef struct EfiIPV4 -{ - UInt8 Addr[4]; +typedef struct EfiIPV4 { + UInt8 Addr[4]; } EfiIPV4; /// /// 16-byte buffer. An IPv6 internet protocol address. /// -typedef struct EfiIPV6 -{ - UInt8 Addr[16]; +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, +#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_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 kEFIFileRead 0x0000000000000001 +#define kEFIFileWrite 0x0000000000000002 #define kEFIFileCreate 0x0000000000000000 -#define kEFIReadOnly 0x01 -#define kEFIHidden 0x02 -#define kEFISystem 0x04 -#define kEFIReserved 0x08 +#define kEFIReadOnly 0x01 +#define kEFIHidden 0x02 +#define kEFISystem 0x04 +#define kEFIReserved 0x08 #define kEFIDirectory 0x10 -#define kEFIArchive 0x20 +#define kEFIArchive 0x20 -#define EFI_FILE_PROTOCOL_REVISION 0x00010000 -#define EFI_FILE_PROTOCOL_REVISION2 0x00020000 +#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 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; +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; +typedef struct EfiFileProtocol { + UInt64 Revision; - EfiStatusType(EFI_API* Open)(struct EfiFileProtocol* Self, - struct EfiFileProtocol** Out, - EfiCharType* CharType, - UInt64 OpenMode, - UInt64 Attrib); + 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* Close)(struct EfiFileProtocol* Self); - EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self); + EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self); - EfiStatusType(EFI_API* Read)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); + 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* Write)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut); - EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position); + EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position); - EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position); + EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position); - EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); + EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); - EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); + EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*); - EfiStatusType(EFI_API* Flush)(EfiFileProtocol*); + 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* 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* ReadEx)(EfiFileProtocol* Self, struct EfiIOToken* Token); - EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self, - struct EfiIOToken* Token); + EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self, struct EfiIOToken* Token); - EfiStatusType(EFI_API* FlushEx)(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; +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]; +#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; +typedef struct _EfiCPUPhyiscalLocation { + UInt32 Package; + UInt32 Core; + UInt32 Thread; } EfiCPUPhyiscalLocation; typedef union _EfiExtendedProcessorInformation { - EfiCPUPhyiscalLocation Location2; + EfiCPUPhyiscalLocation Location2; } EfiExtendedProcessorInformation; -typedef struct _EfiProcessorInformation -{ - UInt64 ProcessorId; - UInt32 StatusFlag; - EfiCPUPhyiscalLocation Location; - EfiExtendedProcessorInformation ExtendedInformation; +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); + 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); + IN struct _EfiMpServicesProtocol* Self, IN UInt32* ProcessorNumber, + OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors); -typedef void EFI_API (*EFI_AP_PROCEDURE)( - IN VoidPtr ProcedureArgument); +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); + 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; + 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 +#endif // ifndef FIRMWARE_KIT_EFI_H diff --git a/dev/kernel/FirmwareKit/EFI/NS.h b/dev/kernel/FirmwareKit/EFI/NS.h index b2902c44..f5a28e10 100644 --- a/dev/kernel/FirmwareKit/EFI/NS.h +++ b/dev/kernel/FirmwareKit/EFI/NS.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,13 +8,11 @@ #include -namespace Firmware::Detail::EFI -{ - using namespace Kernel; +namespace Firmware::Detail::EFI { +using namespace Kernel; - EXTERN_C - { +EXTERN_C { #include - } +} -} // namespace Firmware::Detail::EFI +} // namespace Firmware::Detail::EFI diff --git a/dev/kernel/FirmwareKit/EPM.h b/dev/kernel/FirmwareKit/EPM.h index fe228127..27d635f3 100644 --- a/dev/kernel/FirmwareKit/EPM.h +++ b/dev/kernel/FirmwareKit/EPM.h @@ -1,11 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ /** - @brief The Explicit Partition Map scheme. + @brief The Explicit Partition Map scheme. */ #ifndef FIRMWAREKIT_EPM_H @@ -13,9 +13,9 @@ #include -#define kEPMNameLength (32) +#define kEPMNameLength (32) #define kEPMFilesystemLength (16) -#define kEPMMagicLength (5) +#define kEPMMagicLength (5) /* @brief AMD64 magic for EPM */ #define kEPMMagic86 "EPMAM" @@ -66,52 +66,45 @@ 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]; +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] = {0}; - Kernel::Char Name[kEPMNameLength] = {0}; - 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, HeFS... */ - Kernel::Char Reserved[kEPMReserveLen]; // to fill a full sector. +struct PACKED EPM_PART_BLOCK { + Kernel::Char Magic[kEPMMagicLength] = {0}; + Kernel::Char Name[kEPMNameLength] = {0}; + 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, HeFS... */ + 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 Berkeley Soft. Distribution - kEPMNeKernel = 0x1f, /// @brief NeKernel. - kEPMInvalidOS = 0xff, +enum { + kEPMInvalid = 0x00, + kEPMGeneric = 0xcf, /// @brief Generic OS + kEPMLinux = 0x8f, /// @brief Linux on EPM + kEPMBSD = 0x9f, /// @brief Berkeley Soft. Distribution + kEPMNeKernel = 0x1f, /// @brief NeKernel. + kEPMInvalidOS = 0xff, }; -inline EPM_GUID kEPMNilGuid = { - 0x0U, - 0x0U, - 0x0U, - {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; +inline EPM_GUID kEPMNilGuid = {0x0U, 0x0U, 0x0U, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; -#endif // ifndef FIRMWAREKIT_EPM_H +#endif // ifndef FIRMWAREKIT_EPM_H diff --git a/dev/kernel/FirmwareKit/GPT.h b/dev/kernel/FirmwareKit/GPT.h index 55356121..7e5a910b 100644 --- a/dev/kernel/FirmwareKit/GPT.h +++ b/dev/kernel/FirmwareKit/GPT.h @@ -1,51 +1,48 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include -#define kSectorAlignGPT_PartTbl (420U) +#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; - EfiGUID Guid; - UInt64 StartingLBA; - UInt32 NumPartitionEntries; - UInt32 SizeOfEntries; - UInt32 CRC32PartEntry; - UInt8 Reserved2[kSectorAlignGPT_PartTbl]; - }; - - struct PACKED GPT_PARTITION_ENTRY - { - EfiGUID PartitionTypeGUID; - EfiGUID UniquePartitionGUID; - UInt64 StartLBA; - UInt64 EndLBA; - UInt64 Attributes; - UInt8 Name[kSectorAlignGPT_PartEntry]; - }; -} // namespace Kernel +#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; + EfiGUID Guid; + UInt64 StartingLBA; + UInt32 NumPartitionEntries; + UInt32 SizeOfEntries; + UInt32 CRC32PartEntry; + UInt8 Reserved2[kSectorAlignGPT_PartTbl]; +}; + +struct PACKED GPT_PARTITION_ENTRY { + EfiGUID PartitionTypeGUID; + EfiGUID 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 index 3a5e9e19..fbf4bb28 100644 --- a/dev/kernel/FirmwareKit/Handover.h +++ b/dev/kernel/FirmwareKit/Handover.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -20,92 +20,85 @@ #include #include -#define kHandoverMagic 0xBADCC +#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_StartupImage; - SizeT f_StartupSz; - - 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 +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_StartupImage; + SizeT f_StartupSz; + + 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/VEPM.h b/dev/kernel/FirmwareKit/VEPM.h index 5830a879..ca6c83bf 100644 --- a/dev/kernel/FirmwareKit/VEPM.h +++ b/dev/kernel/FirmwareKit/VEPM.h @@ -1,41 +1,35 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef FIRMWAREKIT_VEPM_H #define FIRMWAREKIT_VEPM_H -#include #include +#include /// @brief The Virtual Explicit Partition Map scheme extension. #ifdef __NE_VEPM__ #ifdef kEPMMagic #undef kEPMMagic -#endif // kEPMMagic +#endif // kEPMMagic #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}}; + 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 EfiGUID kVEPMGuidEFI = { - 0x9a1b3f2e, - 0x4c3f, - 0x4d52, - {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}}; + 0x9a1b3f2e, 0x4c3f, 0x4d52, {0xa7, 0x83, 0x9c, 0x21, 0x7b, 0x5e, 0x4d, 0xac}}; #define kVEPMGuidStr "9a1b3f2e-4c3f-4d52-a783-9c217b5e4dac" -#endif // __NE_VEPM__ +#endif // __NE_VEPM__ -#endif // FIRMWAREKIT_VEPM_H \ No newline at end of file +#endif // FIRMWAREKIT_VEPM_H \ No newline at end of file diff --git a/dev/kernel/GfxKit/FB.h b/dev/kernel/GfxKit/FB.h index b01743ff..33895ce6 100644 --- a/dev/kernel/GfxKit/FB.h +++ b/dev/kernel/GfxKit/FB.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,43 +9,40 @@ #include #include -namespace Kernel -{ - class FBDeviceInterface; - struct FBDevicePacket; - - /// @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 - { - UInt32 fX; - UInt32 fY; - UInt32 fWidth; - UInt32 fHeight; - UInt32 fColor; - UInt32 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 IDeviceObject class. - class FBDeviceInterface NE_DEVICE - { - public: - explicit FBDeviceInterface(void (*out)(IDeviceObject* self, FBDevicePacket* out), - void (*in)(IDeviceObject* 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* Data) override; - FBDeviceInterface& operator>>(FBDevicePacket* Data) override; - }; -} // namespace Kernel +namespace Kernel { +class FBDeviceInterface; +struct FBDevicePacket; + +/// @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 { + UInt32 fX; + UInt32 fY; + UInt32 fWidth; + UInt32 fHeight; + UInt32 fColor; + UInt32 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 IDeviceObject class. +class FBDeviceInterface NE_DEVICE { + public: + explicit FBDeviceInterface(void (*out)(IDeviceObject* self, FBDevicePacket* out), + void (*in)(IDeviceObject* 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* Data) override; + FBDeviceInterface& operator>>(FBDevicePacket* Data) override; +}; +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/CPUID.h b/dev/kernel/HALKit/AMD64/CPUID.h index 9b9c3a1c..8250dfad 100644 --- a/dev/kernel/HALKit/AMD64/CPUID.h +++ b/dev/kernel/HALKit/AMD64/CPUID.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: CPUID.h - Purpose: CPUID flags. + File: CPUID.h + Purpose: CPUID flags. - Revision History: + Revision History: - 30/01/24: Added file (amlel) + 30/01/24: Added file (amlel) ------------------------------------------- */ @@ -15,78 +15,75 @@ #include -EXTERN_C -{ +EXTERN_C { #include } -namespace Kernel -{ +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 - }; +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 +typedef Int64 CPUID; +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc index 2430da07..f4dd1347 100644 --- a/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc +++ b/dev/kernel/HALKit/AMD64/HalACPIFactoryInterface.cc @@ -1,120 +1,113 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include -#include -#include #include +#include #include +#include +#include -namespace Kernel -{ - namespace Detail - { - struct FADT final : public SDT - { - UInt32 FirmwareCtrl; - UInt32 Dsdt; +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; + // 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; + 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; + // reserved in ACPI 1.0; used since ACPI 2.0+ + UInt16 BootArchitecturkMMFlags; - UInt8 Reserved2; - UInt32 Flags; + UInt8 Reserved2; + UInt32 Flags; - // 12 byte structure; see below for details - ACPI_ADDRESS ResetReg; + // 12 byte structure; see below for details + ACPI_ADDRESS ResetReg; - UInt8 ResetValue; - UInt8 Reserved3[3]; + UInt8 ResetValue; + UInt8 Reserved3[3]; - // 64bit pointers - Available on ACPI 2.0+ - UInt64 X_FirmwareControl; - UInt64 X_Dsdt; + // 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 + 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) - { - } +ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {} - Bool ACPIFactoryInterface::Shutdown() - { - return NO; - } +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 +/// @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/HalAPICController.cc b/dev/kernel/HALKit/AMD64/HalAPICController.cc index 5a020014..758e2f52 100644 --- a/dev/kernel/HALKit/AMD64/HalAPICController.cc +++ b/dev/kernel/HALKit/AMD64/HalAPICController.cc @@ -1,44 +1,38 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include +#include #define cIOAPICRegVal (4) #define cIOAPICRegReg (0) -namespace Kernel::HAL -{ - APICController::APICController(VoidPtr base) - : fApic(base) - { - } - - /// @brief Read from APIC controller. - /// @param reg register. - UInt32 APICController::Read(UInt32 reg) noexcept - { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic; - io_apic[cIOAPICRegReg] = (reg & 0xFF); - - return io_apic[cIOAPICRegVal]; - } - - /// @brief Write to APIC controller. - /// @param reg register. - /// @param value value. - Void APICController::Write(UInt32 reg, UInt32 value) noexcept - { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic; - - io_apic[cIOAPICRegReg] = (reg & 0xFF); - io_apic[cIOAPICRegVal] = value; - } -} // namespace Kernel::HAL +namespace Kernel::HAL { +APICController::APICController(VoidPtr base) : fApic(base) {} + +/// @brief Read from APIC controller. +/// @param reg register. +UInt32 APICController::Read(UInt32 reg) noexcept { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; + io_apic[cIOAPICRegReg] = (reg & 0xFF); + + return io_apic[cIOAPICRegVal]; +} + +/// @brief Write to APIC controller. +/// @param reg register. +/// @param value value. +Void APICController::Write(UInt32 reg, UInt32 value) noexcept { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; + + io_apic[cIOAPICRegReg] = (reg & 0xFF); + io_apic[cIOAPICRegVal] = value; +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index fc50380a..dd9a36ed 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -1,29 +1,28 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include -#include -#include #include +#include #include +#include #include #include -#include #include -#include +#include +#include #define kAPIC_Signature "APIC" -#define kAPIC_ICR_Low 0x300 -#define kAPIC_ICR_High 0x310 +#define kAPIC_ICR_Low 0x300 +#define kAPIC_ICR_High 0x310 #define kAPIC_SIPI_Vector 0x00500 #define kAPIC_EIPI_Vector 0x00400 -#define kAPIC_BASE_MSR 0x1B -#define kAPIC_BASE_MSR_BSP 0x100 +#define kAPIC_BASE_MSR 0x1B +#define kAPIC_BASE_MSR_BSP 0x100 #define kAPIC_BASE_MSR_ENABLE 0x800 /// @note: _hal_switch_context is internal @@ -34,231 +33,208 @@ /////////////////////////////////////////////////////////////////////////////////////// -namespace Kernel::HAL -{ - struct HAL_APIC_MADT; - struct HAL_HARDWARE_THREAD; - - struct HAL_HARDWARE_THREAD final - { - HAL::StackFramePtr mFramePtr; - ProcessID mProcessID{0}; - UInt8 mCoreID{0}; - }; - - STATIC HAL_APIC_MADT* kMADTBlock = nullptr; - STATIC Bool kSMPAware = false; - STATIC Int64 kSMPCount = 0; - - STATIC UIntPtr kApicBaseAddress = 0UL; - - STATIC Int32 kSMPInterrupt = 0; - STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; - STATIC VoidPtr kRawMADT = nullptr; - - /// @brief Multiple APIC Descriptor Table. - struct HAL_APIC_MADT final SDT_OBJECT - { - UInt32 Address; // Madt address - UInt8 Flags; // Madt flags - - struct - { - UInt8 Type; - UInt8 Len; - - union APIC { - struct IOAPIC - { - UInt8 IoID; - UInt8 Zero; - UInt32 IoAddress; - UInt32 GISBase; - } IOAPIC; - - struct LAPIC_NMI - { - UInt8 Source; - UInt8 IRQSource; - UInt32 GSI; - UInt16 Flags; - } LApicNMI; - - struct LAPIC - { - UInt8 ProcessorID; - UInt16 Flags; - UInt8 LINT; - } LAPIC; - - struct LAPIC_OVERRIDE - { - UInt16 Reserved; - UInt64 Address; - } LApicOverride; - - struct LAPIC_X2 - { - UInt16 Reserved; - UInt32 x2APICID; - UInt32 Flags; - UInt32 AcpiID; - } LocalApicX2; - } Apic; - } List[1]; // Records List - }; - - /////////////////////////////////////////////////////////////////////////////////////// - - /***********************************************************************************/ - /// @brief Send IPI command to APIC. - /// @param apic_id programmable interrupt controller id. - /// @param vector vector interrupt. - /// @param target target APIC adress. - /// @return - /***********************************************************************************/ - - Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) - { - Kernel::ke_dma_write(target, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); - - while (Kernel::ke_dma_read(target, kAPIC_ICR_Low) & 0x1000) - { - ; - } - } - - /***********************************************************************************/ - /// @brief Send end IPI for CPU. - /// @param apic_id - /// @param vector - /// @param target - /// @return - /***********************************************************************************/ - Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) - { - Kernel::ke_dma_write(target, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write(target, kAPIC_ICR_Low, 0x00000600 | 0x00004000 | 0x00000000 | vector); - - while (Kernel::ke_dma_read(target, kAPIC_ICR_Low) & 0x1000) - { - NE_UNUSED(0); - } - } - - STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; - - EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) - { - const auto process_index = pid % kSchedProcessLimitPerTeam; - - return kHWThread[process_index].mFramePtr; - } - - EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) - { - MUST_PASS(stack_frame); - - const auto process_index = pid % kSchedProcessLimitPerTeam; - - kHWThread[process_index].mFramePtr = stack_frame; - kHWThread[process_index].mProcessID = pid; - - kHWThread[process_index].mCoreID = kAPICLocales[0]; - - hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID, (UInt8)(((UIntPtr)stack_frame->BP) >> 12)); - - 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 Assembly symbol to bootstrap AP. - /***********************************************************************************/ - EXTERN_C Char* hal_ap_blob_start; - - /***********************************************************************************/ - /// @brief Assembly symbol to bootstrap AP. - /***********************************************************************************/ - EXTERN_C Char* hal_ap_blob_end; - - /***********************************************************************************/ - /// @brief Fetch and enable SMP scheduler. - /// @param vendor_ptr SMP containing structure. - /***********************************************************************************/ - Void mp_init_cores(VoidPtr vendor_ptr) noexcept - { - if (!vendor_ptr) - return; - - if (!kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) - { - kSMPAware = NO; - return; - } - - auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); - kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak(); - - kMADTBlock = reinterpret_cast(kRawMADT); - kSMPAware = NO; - - if (kMADTBlock) - { - SizeT index = 1; - - kSMPInterrupt = 0; - kSMPCount = 0; - - kout << "SMP: Starting APs...\r"; - - kApicBaseAddress = kMADTBlock->Address; - - while (Yes) - { - /// @note Anything bigger than x2APIC type doesn't exist. - if (kMADTBlock->List[index].Type > 9 || - kSMPCount > kSchedProcessLimitPerTeam) - break; - - switch (kMADTBlock->List[index].Type) - { - case 0x00: { - if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) - break; - - kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID; - (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); +namespace Kernel::HAL { +struct HAL_APIC_MADT; +struct HAL_HARDWARE_THREAD; + +struct HAL_HARDWARE_THREAD final { + HAL::StackFramePtr mFramePtr; + ProcessID mProcessID{0}; + UInt8 mCoreID{0}; +}; + +STATIC HAL_APIC_MADT* kMADTBlock = nullptr; +STATIC Bool kSMPAware = false; +STATIC Int64 kSMPCount = 0; + +STATIC UIntPtr kApicBaseAddress = 0UL; + +STATIC Int32 kSMPInterrupt = 0; +STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; +STATIC VoidPtr kRawMADT = nullptr; + +/// @brief Multiple APIC Descriptor Table. +struct HAL_APIC_MADT final SDT_OBJECT { + UInt32 Address; // Madt address + UInt8 Flags; // Madt flags + + struct { + UInt8 Type; + UInt8 Len; + + union APIC { + struct IOAPIC { + UInt8 IoID; + UInt8 Zero; + UInt32 IoAddress; + UInt32 GISBase; + } IOAPIC; + + struct LAPIC_NMI { + UInt8 Source; + UInt8 IRQSource; + UInt32 GSI; + UInt16 Flags; + } LApicNMI; + + struct LAPIC { + UInt8 ProcessorID; + UInt16 Flags; + UInt8 LINT; + } LAPIC; + + struct LAPIC_OVERRIDE { + UInt16 Reserved; + UInt64 Address; + } LApicOverride; + + struct LAPIC_X2 { + UInt16 Reserved; + UInt32 x2APICID; + UInt32 Flags; + UInt32 AcpiID; + } LocalApicX2; + } Apic; + } List[1]; // Records List +}; + +/////////////////////////////////////////////////////////////////////////////////////// + +/***********************************************************************************/ +/// @brief Send IPI command to APIC. +/// @param apic_id programmable interrupt controller id. +/// @param vector vector interrupt. +/// @param target target APIC adress. +/// @return +/***********************************************************************************/ + +Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { + Kernel::ke_dma_write(target, kAPIC_ICR_High, apic_id << 24); + Kernel::ke_dma_write(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); + + while (Kernel::ke_dma_read(target, kAPIC_ICR_Low) & 0x1000) { + ; + } +} + +/***********************************************************************************/ +/// @brief Send end IPI for CPU. +/// @param apic_id +/// @param vector +/// @param target +/// @return +/***********************************************************************************/ +Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) { + Kernel::ke_dma_write(target, kAPIC_ICR_High, apic_id << 24); + Kernel::ke_dma_write(target, kAPIC_ICR_Low, + 0x00000600 | 0x00004000 | 0x00000000 | vector); + + while (Kernel::ke_dma_read(target, kAPIC_ICR_Low) & 0x1000) { + NE_UNUSED(0); + } +} + +STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}}; + +EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) { + const auto process_index = pid % kSchedProcessLimitPerTeam; + + return kHWThread[process_index].mFramePtr; +} + +EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { + MUST_PASS(stack_frame); + + const auto process_index = pid % kSchedProcessLimitPerTeam; + + kHWThread[process_index].mFramePtr = stack_frame; + kHWThread[process_index].mProcessID = pid; + + kHWThread[process_index].mCoreID = kAPICLocales[0]; + + hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID, + (UInt8) (((UIntPtr) stack_frame->BP) >> 12)); + + 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 Assembly symbol to bootstrap AP. +/***********************************************************************************/ +EXTERN_C Char* hal_ap_blob_start; + +/***********************************************************************************/ +/// @brief Assembly symbol to bootstrap AP. +/***********************************************************************************/ +EXTERN_C Char* hal_ap_blob_end; + +/***********************************************************************************/ +/// @brief Fetch and enable SMP scheduler. +/// @param vendor_ptr SMP containing structure. +/***********************************************************************************/ +Void mp_init_cores(VoidPtr vendor_ptr) noexcept { + if (!vendor_ptr) return; + + if (!kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) { + kSMPAware = NO; + return; + } + + auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); + kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak(); + + kMADTBlock = reinterpret_cast(kRawMADT); + kSMPAware = NO; + + if (kMADTBlock) { + SizeT index = 1; + + kSMPInterrupt = 0; + kSMPCount = 0; + + kout << "SMP: Starting APs...\r"; + + kApicBaseAddress = kMADTBlock->Address; + + while (Yes) { + /// @note Anything bigger than x2APIC type doesn't exist. + if (kMADTBlock->List[index].Type > 9 || kSMPCount > kSchedProcessLimitPerTeam) break; + + switch (kMADTBlock->List[index].Type) { + case 0x00: { + if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) break; + + kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID; + (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); - ++kSMPCount; - break; - } - default: - break; - } + ++kSMPCount; + break; + } + default: + break; + } - ++index; - } + ++index; + } - (Void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl); + (Void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl); - // Kernel is now SMP aware. - // That means that the scheduler is now available (on MP Kernels) + // Kernel is now SMP aware. + // That means that the scheduler is now available (on MP Kernels) - kSMPAware = true; + kSMPAware = true; - /// TODO: Notify Boot AP that it must start. - } - } -} // namespace Kernel::HAL + /// TODO: Notify Boot AP that it must start. + } +} +} // namespace Kernel::HAL /////////////////////////////////////////////////////////////////////////////////////// diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 4c873554..641fb8e4 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,232 +13,201 @@ STATIC BOOL kIsScheduling = NO; /// @brief Handle GPF fault. /// @param rsp -EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) -{ - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); +EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - return; + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - kIsScheduling = NO; + kIsScheduling = NO; - Kernel::kout << "Kernel: General Protection Fault.\r"; + Kernel::kout << "Kernel: General Protection Fault.\r"; - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.Status = process.Leak().Status; - Kernel::kout << "Kernel: SIGKILL status.\r"; + Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); + process.Leak().Crash(); } /// @brief Handle page fault. /// @param rsp -EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) -{ - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); +EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - return; + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - kIsScheduling = NO; + kIsScheduling = NO; - Kernel::kout << "Kernel: Page Fault.\r"; - Kernel::kout << "Kernel: SIGKILL\r"; + Kernel::kout << "Kernel: Page Fault.\r"; + Kernel::kout << "Kernel: SIGKILL\r"; - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.Status = process.Leak().Status; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); + process.Leak().Crash(); } -namespace Kernel::Detail -{ - constexpr static Int32 kTimeoutCount = 100000UL; +namespace Kernel::Detail { +constexpr static Int32 kTimeoutCount = 100000UL; } /// @brief Handle scheduler interrupt. -EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) -{ - NE_UNUSED(rsp); +EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { + NE_UNUSED(rsp); - static Kernel::Int64 try_count_before_brute = Kernel::Detail::kTimeoutCount; + static Kernel::Int64 try_count_before_brute = Kernel::Detail::kTimeoutCount; - while (kIsScheduling) - { - --try_count_before_brute; + while (kIsScheduling) { + --try_count_before_brute; - if (try_count_before_brute < 1) - break; - } + if (try_count_before_brute < 1) break; + } - try_count_before_brute = Kernel::Detail::kTimeoutCount; - kIsScheduling = YES; + try_count_before_brute = Kernel::Detail::kTimeoutCount; + kIsScheduling = YES; - Kernel::UserProcessHelper::StartScheduling(); + Kernel::UserProcessHelper::StartScheduling(); - kIsScheduling = NO; + kIsScheduling = NO; } /// @brief Handle math fault. /// @param rsp -EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) -{ - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); +EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - return; + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - kIsScheduling = NO; + kIsScheduling = NO; - Kernel::kout << "Kernel: Math error (division by zero?).\r"; + Kernel::kout << "Kernel: Math error (division by zero?).\r"; - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.Status = process.Leak().Status; - Kernel::kout << "Kernel: SIGKILL status.\r"; + Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); + process.Leak().Crash(); } /// @brief Handle any generic fault. /// @param rsp -EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) -{ - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); +EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - return; + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - kIsScheduling = NO; + kIsScheduling = NO; - Kernel::kout << "Kernel: Generic Process Fault.\r"; + Kernel::kout << "Kernel: Generic Process Fault.\r"; - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.Status = process.Leak().Status; - Kernel::kout << "Kernel: SIGKILL status.\r"; + Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); + process.Leak().Crash(); } -EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) -{ - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); +EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { + auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - { - Kernel::kout << "Kernel: SIGTRAP\r"; + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) { + Kernel::kout << "Kernel: SIGTRAP\r"; - while (YES) - ; - } + while (YES); + } - kIsScheduling = NO; + kIsScheduling = NO; - (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); - Kernel::kout << "Kernel: SIGTRAP\r"; + (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); + Kernel::kout << "Kernel: SIGTRAP\r"; - process.Leak().Signal.SignalArg = rip; - process.Leak().Signal.SignalID = SIGTRAP; + process.Leak().Signal.SignalArg = rip; + process.Leak().Signal.SignalID = SIGTRAP; - process.Leak().Signal.Status = process.Leak().Status; + process.Leak().Signal.Status = process.Leak().Status; - Kernel::kout << "Kernel: SIGTRAP status.\r"; + Kernel::kout << "Kernel: SIGTRAP status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + 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().CurrentProcess(); +EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { + auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - return; + if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) return; - kIsScheduling = NO; + kIsScheduling = NO; - Kernel::kout << "Kernel: Undefined Opcode.\r"; + Kernel::kout << "Kernel: Undefined Opcode.\r"; - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Leak().Signal.SignalArg = rsp; + process.Leak().Signal.SignalID = SIGKILL; + process.Leak().Signal.Status = process.Leak().Status; - Kernel::kout << "Kernel: SIGKILL status.\r"; + Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; + process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); + process.Leak().Crash(); } /// @brief Enter syscall from assembly. /// @param stack the stack pushed from assembly routine. /// @return nothing. -EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, Kernel::UIntPtr rdx_syscall_struct) -{ - if (rcx_syscall_index < kSysCalls.Count()) - { - Kernel::kout << "syscall: Enter Syscall.\r"; - - if (kSysCalls[rcx_syscall_index].fHooked) - { - if (kSysCalls[rcx_syscall_index].fProc) - { - (kSysCalls[rcx_syscall_index].fProc)((Kernel::VoidPtr)rdx_syscall_struct); - } - else - { - Kernel::kout << "syscall: syscall isn't valid at all! (is nullptr)\r"; - } - } - else - { - Kernel::kout << "syscall: syscall isn't hooked at all! (is set to false)\r"; - } - - Kernel::kout << "syscall: Exit Syscall.\r"; - } +EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, + Kernel::UIntPtr rdx_syscall_struct) { + if (rcx_syscall_index < kSysCalls.Count()) { + Kernel::kout << "syscall: Enter Syscall.\r"; + + if (kSysCalls[rcx_syscall_index].fHooked) { + if (kSysCalls[rcx_syscall_index].fProc) { + (kSysCalls[rcx_syscall_index].fProc)((Kernel::VoidPtr) rdx_syscall_struct); + } else { + Kernel::kout << "syscall: syscall isn't valid at all! (is nullptr)\r"; + } + } else { + Kernel::kout << "syscall: syscall isn't hooked at all! (is set to false)\r"; + } + + Kernel::kout << "syscall: Exit Syscall.\r"; + } } /// @brief Enter Kernel call from assembly (DDK only). /// @param stack the stack pushed from assembly routine. /// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, Kernel::UIntPtr rdx_kerncall_struct) -{ - if (rcx_kerncall_index < kKernCalls.Count()) - { - Kernel::kout << "kerncall: Enter Kernel Call List.\r"; - - if (kKernCalls[rcx_kerncall_index].fHooked) - { - if (kKernCalls[rcx_kerncall_index].fProc) - { - (kKernCalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr)rdx_kerncall_struct); - } - else - { - Kernel::kout << "kerncall: Kernel call isn't valid at all! (is nullptr)\r"; - } - } - else - { - Kernel::kout << "kerncall: Kernel call isn't hooked at all! (is set to false)\r"; - } - - Kernel::kout << "kerncall: Exit Kernel Call List.\r"; - } +EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, + Kernel::UIntPtr rdx_kerncall_struct) { + if (rcx_kerncall_index < kKernCalls.Count()) { + Kernel::kout << "kerncall: Enter Kernel Call List.\r"; + + if (kKernCalls[rcx_kerncall_index].fHooked) { + if (kKernCalls[rcx_kerncall_index].fProc) { + (kKernCalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr) rdx_kerncall_struct); + } else { + Kernel::kout << "kerncall: Kernel call isn't valid at all! (is nullptr)\r"; + } + } else { + Kernel::kout << "kerncall: Kernel call isn't hooked at all! (is set to false)\r"; + } + + Kernel::kout << "kerncall: Exit Kernel Call List.\r"; + } } diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc index 84c8c348..9d290708 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc @@ -1,193 +1,170 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -#include #include +#include #include #include -namespace Kernel -{ - enum CommStatus : UInt16 - { - kStateInvalid, - kStateReady = 0xCF, - kStateTransmit = 0xFC, - kStateCnt = 3 - }; - - namespace Detail - { - constexpr const UInt16 kPort = 0x3F8; - static UInt16 kState = kStateInvalid; - - /// @brief Init COM1. - /// @return - template - 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; - - EXTERN_C void ke_io_write(IDeviceObject* obj, const Char* bytes) - { - NE_UNUSED(obj); +namespace Kernel { +enum CommStatus : UInt16 { + kStateInvalid, + kStateReady = 0xCF, + kStateTransmit = 0xFC, + kStateCnt = 3 +}; + +namespace Detail { + constexpr const UInt16 kPort = 0x3F8; + static UInt16 kState = kStateInvalid; + + /// @brief Init COM1. + /// @return + template + 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; + +EXTERN_C void ke_io_write(IDeviceObject* obj, const Char* bytes) { + NE_UNUSED(obj); #ifdef __DEBUG__ - Detail::hal_serial_init(); + Detail::hal_serial_init(); - if (!bytes || Detail::kState != kStateReady) - return; + if (!bytes || Detail::kState != kStateReady) return; - if (*bytes == 0) - return; + if (*bytes == 0) return; - Detail::kState = kStateTransmit; + Detail::kState = kStateTransmit; - SizeT index = 0; - SizeT len = 0; + SizeT index = 0; + SizeT len = 0; - index = 0; - len = rt_string_len(bytes, 256U); + index = 0; + len = rt_string_len(bytes, 256U); - static SizeT x = kFontSizeX, y = kFontSizeY; + static SizeT x = kFontSizeX, y = kFontSizeY; - static BOOL not_important = YES; + static BOOL not_important = YES; - while (index < len) - { - if (bytes[index] == '\r') - HAL::rt_out8(Detail::kPort, '\r'); + while (index < len) { + if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); - HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); + HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); - char tmp_str[2]; - tmp_str[0] = bytes[index]; - tmp_str[1] = 0; + char tmp_str[2]; + tmp_str[0] = bytes[index]; + tmp_str[1] = 0; - if (bytes[index] == '*') - { - if (not_important) - not_important = NO; - else - not_important = YES; + if (bytes[index] == '*') { + if (not_important) + not_important = NO; + else + not_important = YES; - ++index; + ++index; - continue; - } + continue; + } - fb_render_string(tmp_str, y, x, not_important ? RGB(0xff, 0xff, 0xff) : RGB(0x00, 0x00, 0xff)); + fb_render_string(tmp_str, y, x, not_important ? RGB(0xff, 0xff, 0xff) : RGB(0x00, 0x00, 0xff)); - if (bytes[index] == '\r') - { - y += kFontSizeY; - x = kFontSizeX; - } + if (bytes[index] == '\r') { + y += kFontSizeY; + x = kFontSizeX; + } - x += kFontSizeX; + x += kFontSizeX; - if (x > kHandoverHeader->f_GOP.f_Width) - { - x = kFontSizeX; - } + if (x > kHandoverHeader->f_GOP.f_Width) { + x = kFontSizeX; + } - if (y > kHandoverHeader->f_GOP.f_Height) - { - y = kFontSizeY; + if (y > kHandoverHeader->f_GOP.f_Height) { + y = kFontSizeY; - FBDrawInRegion(fb_get_clear_clr(), FB::FBAccessibilty::Height(), FB::FBAccessibilty::Width(), - 0, 0); - } + FBDrawInRegion(fb_get_clear_clr(), FB::FBAccessibilty::Height(), FB::FBAccessibilty::Width(), + 0, 0); + } - ++index; - } + ++index; + } - Detail::kState = kStateReady; -#endif // __DEBUG__ - } + Detail::kState = kStateReady; +#endif // __DEBUG__ +} - EXTERN_C void ke_io_read(IDeviceObject*, const Char* bytes) - { +EXTERN_C void ke_io_read(IDeviceObject*, const Char* bytes) { #ifdef __DEBUG__ - Detail::hal_serial_init(); + Detail::hal_serial_init(); - if (!bytes || Detail::kState != kStateReady) - return; + if (!bytes || Detail::kState != kStateReady) return; - Detail::kState = kStateTransmit; + Detail::kState = kStateTransmit; - SizeT index = 0; + SizeT index = 0; - ///! TODO: Look on how to wait for the UART to complete. - while (true) - { - auto in = HAL::rt_in8(Detail::kPort); + ///! 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 enter pressed then break. + if (in == 0xD) { + break; + } - if (in < '0' || in < 'A' || in < 'a') - { - if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || - in != ':') - { - continue; - } - } + if (in < '0' || in < 'A' || in < 'a') { + if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') { + continue; + } + } - ((char*)bytes)[index] = in; + ((char*) bytes)[index] = in; - ++index; - } + ++index; + } - ((char*)bytes)[index] = 0; + ((char*) bytes)[index] = 0; - Detail::kState = kStateReady; -#endif // __DEBUG__ - } + Detail::kState = kStateReady; +#endif // __DEBUG__ +} - TerminalDevice TerminalDevice::The() noexcept - { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; - } +TerminalDevice TerminalDevice::The() noexcept { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; +} -} // namespace Kernel +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalDebugPort.cc b/dev/kernel/HALKit/AMD64/HalDebugPort.cc index 63bc99bd..6289ff1f 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugPort.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugPort.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,31 +12,26 @@ // after that we have start of additional data. -namespace Kernel -{ - void rt_debug_listen(DebuggerPortHeader* theHook) noexcept - { - if (theHook == nullptr) - return; +namespace Kernel { +void rt_debug_listen(DebuggerPortHeader* theHook) noexcept { + if (theHook == nullptr) return; - for (UInt32 i = 0U; i < kDebugMaxPorts; ++i) - { - HAL::rt_out16(theHook->fPort[i], kDebugMag0); - HAL::rt_wait_400ns(); + for (UInt32 i = 0U; i < kDebugMaxPorts; ++i) { + HAL::rt_out16(theHook->fPort[i], kDebugMag0); + HAL::rt_wait_400ns(); - HAL::rt_out16(theHook->fPort[i], kDebugMag1); - HAL::rt_wait_400ns(); + HAL::rt_out16(theHook->fPort[i], kDebugMag1); + HAL::rt_wait_400ns(); - HAL::rt_out16(theHook->fPort[i], kDebugMag2); - HAL::rt_wait_400ns(); + HAL::rt_out16(theHook->fPort[i], kDebugMag2); + HAL::rt_wait_400ns(); - HAL::rt_out16(theHook->fPort[i], kDebugMag3); - HAL::rt_wait_400ns(); + HAL::rt_out16(theHook->fPort[i], kDebugMag3); + HAL::rt_wait_400ns(); - if (HAL::rt_in16(theHook->fPort[i]) != kDebugUnboundPort) - ++theHook->fPortCnt; + if (HAL::rt_in16(theHook->fPort[i]) != kDebugUnboundPort) ++theHook->fPortCnt; - HAL::rt_wait_400ns(); - } - } -} // namespace Kernel + HAL::rt_wait_400ns(); + } +} +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc index f205e766..e6d57be2 100644 --- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc +++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc @@ -1,21 +1,19 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include +#include #include #define kPITDefaultTicks (1000U) -namespace Kernel::HAL -{ - namespace Detail - { - STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 - kInterruptVectorTable[kKernelIdtSize] = {}; +namespace Kernel::HAL { +namespace Detail { + STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 kInterruptVectorTable[kKernelIdtSize] = + {}; #if 0 STATIC void hal_set_irq_mask(UInt8 irql) [[maybe_unused]] @@ -36,101 +34,88 @@ namespace Kernel::HAL value = rt_in8(port) | (1 << irql); rt_out8(port, value); } -#endif // make gcc shut up +#endif // make gcc shut up - STATIC void hal_clear_irq_mask(UInt8 irql) [[maybe_unused]] - { - UInt16 port; - UInt8 value; + STATIC void hal_clear_irq_mask(UInt8 irql) [[maybe_unused]] { + UInt16 port; + UInt8 value; - if (irql < 8) - { - port = kPICData; - } - else - { - port = kPIC2Data; - irql -= 8; - } + if (irql < 8) { + port = kPICData; + } else { + port = kPIC2Data; + irql -= 8; + } - value = rt_in8(port) & ~(1 << irql); - rt_out8(port, value); - } + value = rt_in8(port) & ~(1 << irql); + rt_out8(port, value); + } - STATIC Void hal_enable_pit(UInt16 ticks) noexcept - { - if (ticks == 0) - ticks = kPITDefaultTicks; + STATIC Void hal_enable_pit(UInt16 ticks) noexcept { + if (ticks == 0) ticks = kPITDefaultTicks; - // Configure PIT to receieve scheduler interrupts. + // Configure PIT to receieve scheduler interrupts. - UInt16 kPITCommDivisor = kPITFrequency / ticks; // 100 Hz. + UInt16 kPITCommDivisor = kPITFrequency / ticks; // 100 Hz. - HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT - HAL::rt_out8(kPITChannel0Port, kPITCommDivisor & 0xFF); // Send low byte - HAL::rt_out8(kPITChannel0Port, (kPITCommDivisor >> 8) & 0xFF); // Send high byte + HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT + HAL::rt_out8(kPITChannel0Port, kPITCommDivisor & 0xFF); // Send low byte + HAL::rt_out8(kPITChannel0Port, (kPITCommDivisor >> 8) & 0xFF); // Send high byte - hal_clear_irq_mask(32); - } - } // namespace Detail + hal_clear_irq_mask(32); + } +} // namespace Detail - /// @brief Loads the provided Global Descriptor Table. - /// @param gdt - /// @return - Void GDTLoader::Load(Register64& gdt) - { - hal_load_gdt(gdt); - } +/// @brief Loads the provided Global Descriptor Table. +/// @param gdt +/// @return +Void GDTLoader::Load(Register64& gdt) { + hal_load_gdt(gdt); +} - Void IDTLoader::Load(Register64& idt) - { - rt_cli(); +Void IDTLoader::Load(Register64& idt) { + rt_cli(); - const Int16 kPITTickForScheduler = kPITDefaultTicks; + const Int16 kPITTickForScheduler = kPITDefaultTicks; - volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**)idt.Base; + volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::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 = 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; - } + 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 = 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); + idt.Base = (UIntPtr) &Detail::kInterruptVectorTable[0]; + idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * (kKernelIdtSize); - Detail::hal_enable_pit(kPITTickForScheduler); + Detail::hal_enable_pit(kPITTickForScheduler); - hal_load_idt(idt); + hal_load_idt(idt); - rt_sti(); - } + rt_sti(); +} - /// @brief Loads the Global Descriptor Table into the CPU. - /// @param gdt GDT register wrapped in a ref. - void GDTLoader::Load(Ref& gdt) - { - if (!gdt) - return; +/// @brief Loads the Global Descriptor Table into the CPU. +/// @param gdt GDT register wrapped in a ref. +void GDTLoader::Load(Ref& gdt) { + if (!gdt) return; - GDTLoader::Load(gdt.Leak()); - } + GDTLoader::Load(gdt.Leak()); +} - /// @brief Loads the IDT, for interupts. - /// @param idt IDT register wrapped in a ref. - void IDTLoader::Load(Ref& idt) - { - if (!idt) - return; +/// @brief Loads the IDT, for interupts. +/// @param idt IDT register wrapped in a ref. +void IDTLoader::Load(Ref& idt) { + if (!idt) return; - IDTLoader::Load(idt.Leak()); - } -} // namespace Kernel::HAL + IDTLoader::Load(idt.Leak()); +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 0c680f97..82020520 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -1,125 +1,143 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include -#include -#include -#include -#include -#include #include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; -STATIC Kernel::Void hal_pre_init_scheduler() noexcept -{ - for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) - { - Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); - } +STATIC Kernel::Void hal_pre_init_scheduler() noexcept { + for (Kernel::SizeT i = 0U; + i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) { + Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); + } } /// @brief Kernel init procedure. -EXTERN_C Int32 hal_init_platform( - Kernel::HEL::BootInfoHeader* handover_hdr) -{ - if (handover_hdr->f_Magic != kHandoverMagic && - handover_hdr->f_Version != kHandoverVersion) - { - return kEfiFail; - } - - kHandoverHeader = handover_hdr; - - FB::fb_clear_video(); - - fw_init_efi((EfiSystemTable*)handover_hdr->f_FirmwareCustomTables[1]); - - Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, handover_hdr->f_HardwareTables.f_ImageHandle); - - /************************************** */ - /* INITIALIZE BIT MAP. */ - /************************************** */ - - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = reinterpret_cast( - reinterpret_cast(kHandoverHeader->f_BitMapStart)); - - /************************************** */ - /* INITIALIZE GDT AND SEGMENTS. */ - /************************************** */ - - STATIC CONST auto kGDTEntriesCount = 6; - - /* GDT, mostly descriptors for user and kernel segments. */ - STATIC Kernel::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 - {.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 - }; - - // Load memory descriptors. - Kernel::HAL::Register64 gdt_reg; - - gdt_reg.Base = reinterpret_cast(kGDTArray); - gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1; - - //! GDT will load hal_read_init after it successfully loads the segments. - Kernel::HAL::GDTLoader gdt_loader; - gdt_loader.Load(gdt_reg); - - return kEfiFail; +EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { + if (handover_hdr->f_Magic != kHandoverMagic && handover_hdr->f_Version != kHandoverVersion) { + return kEfiFail; + } + + kHandoverHeader = handover_hdr; + + FB::fb_clear_video(); + + fw_init_efi((EfiSystemTable*) handover_hdr->f_FirmwareCustomTables[1]); + + Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, + handover_hdr->f_HardwareTables.f_ImageHandle); + + /************************************** */ + /* INITIALIZE BIT MAP. */ + /************************************** */ + + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + kKernelBitMpStart = reinterpret_cast( + reinterpret_cast(kHandoverHeader->f_BitMapStart)); + + /************************************** */ + /* INITIALIZE GDT AND SEGMENTS. */ + /************************************** */ + + STATIC CONST auto kGDTEntriesCount = 6; + + /* GDT, mostly descriptors for user and kernel segments. */ + STATIC Kernel::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 + {.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 + }; + + // Load memory descriptors. + Kernel::HAL::Register64 gdt_reg; + + gdt_reg.Base = reinterpret_cast(kGDTArray); + gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::NE_GDT_ENTRY) * kGDTEntriesCount) - 1; + + //! GDT will load hal_read_init after it successfully loads the segments. + Kernel::HAL::GDTLoader gdt_loader; + gdt_loader.Load(gdt_reg); + + return kEfiFail; } -EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept -{ - hal_pre_init_scheduler(); +EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { + hal_pre_init_scheduler(); - Kernel::NeFS::fs_init_nefs(); + Kernel::NeFS::fs_init_nefs(); - Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable; + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = (Kernel::UIntPtr) kInterruptVectorTable; - Kernel::HAL::IDTLoader idt_loader; + Kernel::HAL::IDTLoader idt_loader; - idt_loader.Load(idt_reg); + idt_loader.Load(idt_reg); - /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every process according to their affinity fairly. + /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every + /// process according to their affinity fairly. - auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. + auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. - Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); + Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); - STATIC Kernel::Array kTeams; + STATIC Kernel::Array kTeams; - SizeT team_index = 0U; + SizeT team_index = 0U; - /// @brief This just loops over the teams and switches between them. - /// @details Not even round-robin, just a simple loop in this boot core we're at. - while (YES) - { - if (team_index > (kSchedTeamCount - 1)) - { - team_index = 0U; - } + /// @brief This just loops over the teams and switches between them. + /// @details Not even round-robin, just a simple loop in this boot core we're at. + while (YES) { + if (team_index > (kSchedTeamCount - 1)) { + team_index = 0U; + } - while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])) - ; + while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])); - timer.Wait(); + timer.Wait(); - ++team_index; - } + ++team_index; + } } diff --git a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc index 9c8a235a..3a35f9b1 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelPanic.cc @@ -1,61 +1,54 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include -#include -#include -#include #include +#include #include +#include +#include +#include +#include #include #include -#include /* 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 << "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 << "Kernel_Panic_File: " << file << kendl); - (Void)(kout << "Kernel_Panic_Line: " << line << kendl); - - ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed - } - } -} // namespace Kernel +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 << "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 << "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/HalPagingMgrAMD64.cc b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc index 08caed82..8e80c4d8 100644 --- a/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalPagingMgrAMD64.cc @@ -1,156 +1,142 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: HalPagingMgr.cc - Purpose: Platform Paging Manager. + File: HalPagingMgr.cc + Purpose: Platform Paging Manager. ------------------------------------------- */ #include #include -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) - { - (Void)(kout << (pte->Present ? "Present" : "Not Present") << kendl); - (Void)(kout << (pte->Wr ? "W/R" : "Not W/R") << kendl); - (Void)(kout << (pte->Nx ? "NX" : "Not NX") << kendl); - (Void)(kout << (pte->User ? "User" : "Not User") << kendl); - (Void)(kout << (pte->Pcd ? "Not Cached" : "Cached") << kendl); - (Void)(kout << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); - (Void)(kout << hex_number(pte->PhysicalAddress) << kendl); - (Void)(kout << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") << kendl); - } - - /***********************************************************************************/ - /// @brief Gets a physical address from a virtual address. - /// @param virt a valid virtual address. - /// @return Physical address. - /***********************************************************************************/ - UIntPtr hal_get_phys_address(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(cr3); - UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9Bits]; - - if (!(pml4e & 1)) - return 0; - - // Level 3 - auto pdpt = reinterpret_cast(pml4e & ~kPageOffsetMask); - UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9Bits]; - - if (!(pdpte & 1)) - return 0; - - // Level 2 - auto pd = reinterpret_cast(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(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; - } - - /***********************************************************************************/ - /// @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) - { - 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(cr3); - UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9]; - - if (!(pml4e & 1)) - return kErrorInvalidData; - - UInt64* pdpt = reinterpret_cast(pml4e & ~kPageMask); - UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9]; - - if (!(pdpte & 1)) - return kErrorInvalidData; - - UInt64* pd = reinterpret_cast(pdpte & ~kPageMask); - UInt64 pde = pd[(kVMAddr >> 21) & kMask9]; - - if (!(pde & 1)) - return kErrorInvalidData; - - UInt64* pt = reinterpret_cast(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)); - - hal_invl_tlb(virtual_address); +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) { + (Void)(kout << (pte->Present ? "Present" : "Not Present") << kendl); + (Void)(kout << (pte->Wr ? "W/R" : "Not W/R") << kendl); + (Void)(kout << (pte->Nx ? "NX" : "Not NX") << kendl); + (Void)(kout << (pte->User ? "User" : "Not User") << kendl); + (Void)(kout << (pte->Pcd ? "Not Cached" : "Cached") << kendl); + (Void)(kout << (pte->Accessed ? "Accessed" : "Not Accessed") << kendl); + (Void)(kout << hex_number(pte->PhysicalAddress) << kendl); + (Void)(kout << (pte->ProtectionKey ? "Protected" : "Not Protected/PKU Disabled") << kendl); +} + +/***********************************************************************************/ +/// @brief Gets a physical address from a virtual address. +/// @param virt a valid virtual address. +/// @return Physical address. +/***********************************************************************************/ +UIntPtr hal_get_phys_address(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(cr3); + UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9Bits]; + + if (!(pml4e & 1)) return 0; + + // Level 3 + auto pdpt = reinterpret_cast(pml4e & ~kPageOffsetMask); + UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9Bits]; + + if (!(pdpte & 1)) return 0; + + // Level 2 + auto pd = reinterpret_cast(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(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; +} + +/***********************************************************************************/ +/// @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) { + 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(cr3); + UInt64 pml4e = pml4[(kVMAddr >> 39) & kMask9]; + + if (!(pml4e & 1)) return kErrorInvalidData; + + UInt64* pdpt = reinterpret_cast(pml4e & ~kPageMask); + UInt64 pdpte = pdpt[(kVMAddr >> 30) & kMask9]; + + if (!(pdpte & 1)) return kErrorInvalidData; + + UInt64* pd = reinterpret_cast(pdpte & ~kPageMask); + UInt64 pde = pd[(kVMAddr >> 21) & kMask9]; + + if (!(pde & 1)) return kErrorInvalidData; + + UInt64* pt = reinterpret_cast(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)); + + hal_invl_tlb(virtual_address); - mmi_page_status(pte); + mmi_page_status(pte); - return kErrorSuccess; - } -} // namespace Kernel::HAL + return kErrorSuccess; +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc b/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc index e6b94ece..66f27c24 100644 --- a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: HalCPU.cc - Purpose: Platform processor routines. + File: HalCPU.cc + Purpose: Platform processor routines. ------------------------------------------- */ @@ -15,94 +15,61 @@ * @brief Common CPU API. */ -namespace Kernel::HAL -{ - 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 +namespace Kernel::HAL { +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/HalSchedulerCorePrimitivesAMD64.cc b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc index 56ed4b34..8f7ffdaf 100644 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc @@ -1,55 +1,47 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Unimplemented function (crashes by default) - /// @param - /***********************************************************************************/ - - EXTERN_C Void __zka_pure_call(USER_PROCESS* process) - { - if (process) - process->Crash(); - } - - /***********************************************************************************/ - /// @brief Validate user stack. - /// @param stack_ptr the frame pointer. - /***********************************************************************************/ - - EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) - { - if (!stack_ptr) - return No; - - return stack_ptr->SP != 0 && stack_ptr->BP != 0; - } - - /// @brief Wakes up thread. - /// Wakes up thread from the hang state. - Void mp_wakeup_thread(HAL::StackFrame* stack) - { - NE_UNUSED(stack); - 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) - { - NE_UNUSED(stack); - - while (Yes) - { - /* Nothing to do, code is spinning */ - } - } -} // namespace Kernel +namespace Kernel { +/***********************************************************************************/ +/// @brief Unimplemented function (crashes by default) +/// @param +/***********************************************************************************/ + +EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { + if (process) process->Crash(); +} + +/***********************************************************************************/ +/// @brief Validate user stack. +/// @param stack_ptr the frame pointer. +/***********************************************************************************/ + +EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) { + if (!stack_ptr) return No; + + return stack_ptr->SP != 0 && stack_ptr->BP != 0; +} + +/// @brief Wakes up thread. +/// Wakes up thread from the hang state. +Void mp_wakeup_thread(HAL::StackFrame* stack) { + NE_UNUSED(stack); + 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) { + NE_UNUSED(stack); + + while (Yes) { + /* Nothing to do, code is spinning */ + } +} +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc index ade41d2f..79165289 100644 --- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc @@ -1,101 +1,95 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: HalTimer.cc - Purpose: HAL timer + File: HalTimer.cc + Purpose: HAL timer - Revision History: + Revision History: - 07/07/24: Added file (amlel) + 07/07/24: Added file (amlel) ------------------------------------------- */ -#include #include #include +#include // timer slot 0 -#define kHPETCounterRegValue (0x00) -#define kHPETConfigRegValue (0x20) -#define kHPETCompRegValue (0x24) +#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 +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); +HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) { + auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr); - auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak(); - MUST_PASS(hpet); + auto hpet = (Detail::HPET_BLOCK*) power.Find("HPET").Leak().Leak(); + MUST_PASS(hpet); - fDigitalTimer = (UInt8*)hpet->address.Address; + fDigitalTimer = (UInt8*) hpet->address.Address; - if (hpet->page_protection) - { - HAL::mm_map_page((VoidPtr)fDigitalTimer, (VoidPtr)fDigitalTimer, HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt); - } + 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); // enable timer - *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) = *((volatile UInt64*)((UInt8*)fDigitalTimer + kHPETConfigRegValue)) | (1 << 3); // one shot conf - } + // if not enabled yet. + if (!(*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) & (1 << 0))) { + *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) = + *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | + (1 << 0); // enable timer + *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) = + *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | + (1 << 3); // one shot conf + } } -HardwareTimer::~HardwareTimer() -{ - fDigitalTimer = nullptr; - fWaitFor = 0; +HardwareTimer::~HardwareTimer() { + fDigitalTimer = nullptr; + fWaitFor = 0; } /***********************************************************************************/ /// @brief Wait for the timer to stop spinning. /***********************************************************************************/ -BOOL HardwareTimer::Wait() noexcept -{ - if (fWaitFor < 1) - return NO; +BOOL HardwareTimer::Wait() noexcept { + if (fWaitFor < 1) return NO; - UInt64 hpet_cap = *((volatile UInt64*)(fDigitalTimer + kHPETCounterRegValue)); - UInt64 femtoseconds_per_tick = (hpet_cap >> 32); + UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue)); + UInt64 femtoseconds_per_tick = (hpet_cap >> 32); - if (femtoseconds_per_tick == 0) - return NO; + if (femtoseconds_per_tick == 0) return NO; - volatile UInt64* timer = (volatile UInt64*)(fDigitalTimer + kHPETCounterRegValue); + volatile UInt64* timer = (volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue); - UInt64 now = *timer; - UInt64 prev = now + (fWaitFor / femtoseconds_per_tick); + UInt64 now = *timer; + UInt64 prev = now + (fWaitFor / femtoseconds_per_tick); - while (*timer < (prev)) - asm volatile("pause"); + while (*timer < (prev)) asm volatile("pause"); - return YES; + return YES; } diff --git a/dev/kernel/HALKit/AMD64/Hypervisor.h b/dev/kernel/HALKit/AMD64/Hypervisor.h index 848f79bb..df88b02b 100644 --- a/dev/kernel/HALKit/AMD64/Hypervisor.h +++ b/dev/kernel/HALKit/AMD64/Hypervisor.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,18 +8,17 @@ #include -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 +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/PCI/DMA.cc b/dev/kernel/HALKit/AMD64/PCI/DMA.cc index b16039d4..38533448 100644 --- a/dev/kernel/HALKit/AMD64/PCI/DMA.cc +++ b/dev/kernel/HALKit/AMD64/PCI/DMA.cc @@ -1,85 +1,72 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include +#include -namespace Kernel -{ - DMAWrapper::operator bool() - { - return this->fAddress; - } +namespace Kernel { +DMAWrapper::operator bool() { + return this->fAddress; +} - bool DMAWrapper::operator!() - { - return !this->fAddress; - } +bool DMAWrapper::operator!() { + return !this->fAddress; +} - Boolean DMAWrapper::Check(UIntPtr offset) const - { - if (!this->fAddress) - return false; +Boolean DMAWrapper::Check(UIntPtr offset) const { + if (!this->fAddress) return false; - if (offset == 0) - return false; + if (offset == 0) return false; - kout << "[DMAWrapper::IsIn] Checking offset...\r"; - return reinterpret_cast(this->fAddress) >= offset; - } + kout << "[DMAWrapper::IsIn] Checking offset...\r"; + return reinterpret_cast(this->fAddress) >= offset; +} - bool DMAWrapper::Write(UIntPtr& bit, const UInt32& offset) - { - kout << "[DMAWrapper::Read] Checking this->fAddress...\r"; +bool DMAWrapper::Write(UIntPtr& bit, const UInt32& offset) { + kout << "[DMAWrapper::Read] Checking this->fAddress...\r"; - if (!this->fAddress) - return false; + if (!this->fAddress) return false; - (Void)(kout << "[DMAWrapper::Write] Writing at address: " << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); + (Void)(kout << "[DMAWrapper::Write] Writing at address: " + << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); - ke_dma_write(reinterpret_cast(this->fAddress), offset, bit); + ke_dma_write(reinterpret_cast(this->fAddress), offset, bit); - return true; - } + return true; +} - UIntPtr DMAWrapper::Read(const UInt32& offset) - { - kout << "[DMAWrapper::Read] Checking this->fAddress...\r"; +UIntPtr DMAWrapper::Read(const UInt32& offset) { + kout << "[DMAWrapper::Read] Checking this->fAddress...\r"; - if (!this->fAddress) - return ~0; + if (!this->fAddress) return ~0; - (Void)(kout << "[DMAWrapper::Write] Writing at address: " << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); + (Void)(kout << "[DMAWrapper::Write] Writing at address: " + << hex_number(reinterpret_cast(this->fAddress) + offset) << kendl); - return (UIntPtr)ke_dma_read(reinterpret_cast(this->fAddress), offset); - } + return (UIntPtr) ke_dma_read(reinterpret_cast(this->fAddress), offset); +} - UIntPtr DMAWrapper::operator[](UIntPtr& offset) - { - return this->Read(offset); - } +UIntPtr DMAWrapper::operator[](UIntPtr& offset) { + return this->Read(offset); +} - OwnPtr> DMAFactory::Construct(OwnPtr& dma) - { - if (!dma) - return {}; +OwnPtr> DMAFactory::Construct(OwnPtr& dma) { + if (!dma) return {}; - OwnPtr> dmaOwnPtr = - mm_make_own_ptr, char*>(reinterpret_cast(dma->fAddress)); + OwnPtr> dmaOwnPtr = + mm_make_own_ptr, char*>(reinterpret_cast(dma->fAddress)); - if (!dmaOwnPtr) - return {}; + if (!dmaOwnPtr) return {}; - kout << "Returning the new OwnPtr>!\r"; - return dmaOwnPtr; - } + kout << "Returning the new OwnPtr>!\r"; + return dmaOwnPtr; +} - DMAWrapper& DMAWrapper::operator=(voidPtr Ptr) - { - this->fAddress = Ptr; - return *this; - } -} // namespace Kernel +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 index 356792e4..9e6c349b 100644 --- a/dev/kernel/HALKit/AMD64/PCI/Database.cc +++ b/dev/kernel/HALKit/AMD64/PCI/Database.cc @@ -1,11 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ -} +namespace Kernel {} diff --git a/dev/kernel/HALKit/AMD64/PCI/Device.cc b/dev/kernel/HALKit/AMD64/PCI/Device.cc index ced473ed..f11f7777 100644 --- a/dev/kernel/HALKit/AMD64/PCI/Device.cc +++ b/dev/kernel/HALKit/AMD64/PCI/Device.cc @@ -1,173 +1,142 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -#define PCI_BAR_IO (0x01) -#define PCI_BAR_LOWMEM (0x02) -#define PCI_BAR_64 (0x04) +#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) +#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); +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_out32((Kernel::UShort) Kernel::PCI::PciConfigKind::ConfigAddress, target); - Kernel::HAL::rt_wait_400ns(); + Kernel::HAL::rt_wait_400ns(); - return Kernel::HAL::rt_in32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigData); + 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(); + +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(bar & ~0x03); + + if (bar & PCI_BAR_64) { + UInt32 high = NE_PCIReadRaw((bar_in + 4) & ~0x03, fBus, fDevice, fFunction); + return (static_cast(high) << 32) | (bar & ~0x0F); + } + + return static_cast(bar & ~0x0F); +} + +UShort Device::Vendor() { + UShort vendor = this->VendorId(); + return vendor; +} + +Device::operator bool() { + return this->VendorId() != (UShort) PciConfigKind::Invalid; } - -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(bar & ~0x03); - - if (bar & PCI_BAR_64) - { - UInt32 high = NE_PCIReadRaw((bar_in + 4) & ~0x03, fBus, fDevice, fFunction); - return (static_cast(high) << 32) | (bar & ~0x0F); - } - - return static_cast(bar & ~0x0F); - } - - UShort Device::Vendor() - { - UShort vendor = this->VendorId(); - return vendor; - } - - Device::operator bool() - { - return this->VendorId() != (UShort)PciConfigKind::Invalid; - } -} // namespace Kernel::PCI +} // namespace Kernel::PCI diff --git a/dev/kernel/HALKit/AMD64/PCI/Express.cc b/dev/kernel/HALKit/AMD64/PCI/Express.cc index 6d257531..6031e792 100644 --- a/dev/kernel/HALKit/AMD64/PCI/Express.cc +++ b/dev/kernel/HALKit/AMD64/PCI/Express.cc @@ -1,11 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ -} +namespace Kernel {} diff --git a/dev/kernel/HALKit/AMD64/PCI/IO.cc b/dev/kernel/HALKit/AMD64/PCI/IO.cc index 7d43707e..1d72316a 100644 --- a/dev/kernel/HALKit/AMD64/PCI/IO.cc +++ b/dev/kernel/HALKit/AMD64/PCI/IO.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/HALKit/AMD64/PCI/Iterator.cc b/dev/kernel/HALKit/AMD64/PCI/Iterator.cc index 09cfb2d2..2590aa94 100644 --- a/dev/kernel/HALKit/AMD64/PCI/Iterator.cc +++ b/dev/kernel/HALKit/AMD64/PCI/Iterator.cc @@ -1,39 +1,30 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel::PCI -{ - Iterator::Iterator(const Types::PciDeviceKind& type) - { - // probe devices. - for (int bus = 0; bus < NE_BUS_COUNT; ++bus) - { - for (int device = 0; device < NE_DEVICE_COUNT; ++device) - { - for (int function = 0; function < NE_FUNCTION_COUNT; ++function) - { - Device dev(bus, device, function, 0x00); +namespace Kernel::PCI { +Iterator::Iterator(const Types::PciDeviceKind& type) { + // probe devices. + for (int bus = 0; bus < NE_BUS_COUNT; ++bus) { + for (int device = 0; device < NE_DEVICE_COUNT; ++device) { + for (int function = 0; function < NE_FUNCTION_COUNT; ++function) { + Device dev(bus, device, function, 0x00); - if (dev.Class() == type) - { - fDevices[bus] = dev; - } - } - } - } - } + if (dev.Class() == type) { + fDevices[bus] = dev; + } + } + } + } +} - Iterator::~Iterator() - { - } +Iterator::~Iterator() {} - Ref Iterator::operator[](const Size& at) - { - return fDevices[at]; - } -} // namespace Kernel::PCI +Ref 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 index c3e93084..616b3eea 100644 --- a/dev/kernel/HALKit/AMD64/PCI/PCI.cc +++ b/dev/kernel/HALKit/AMD64/PCI/PCI.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h index ea20dece..074c1113 100644 --- a/dev/kernel/HALKit/AMD64/Paging.h +++ b/dev/kernel/HALKit/AMD64/Paging.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,7 +8,7 @@ /** --------------------------------------------------- - * THIS FILE CONTAINS CODE FOR X86_64 PAGING. + * THIS FILE CONTAINS CODE FOR X86_64 PAGING. ------------------------------------------------------- */ @@ -16,60 +16,55 @@ #ifndef kPageMax #define kPageMax (0x200) -#endif //! kPageMax +#endif //! kPageMax #ifndef kPageAlign #define kPageAlign (0x08) -#endif //! kPageAlign +#endif //! kPageAlign #ifndef kPageSize #define kPageSize (0x1000) -#endif // !kPageSize +#endif // !kPageSize #ifndef kAlign #define kAlign __BIGGEST_ALIGNMENT__ -#endif // !kAlign +#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 table. - -namespace Kernel::HAL -{ - 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(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 -{ - typedef VoidPtr PTE; - typedef VoidPtr PDE; -} // namespace Kernel +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 table. + +namespace Kernel::HAL { +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(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 { +typedef VoidPtr PTE; +typedef VoidPtr PDE; +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index 13819f3e..1319277f 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -1,32 +1,32 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: Prcoessor.h - Purpose: AMD64 processor abstraction. + File: Prcoessor.h + Purpose: AMD64 processor abstraction. - Revision History: + Revision History: - 30/01/24: Added file (amlel) + 30/01/24: Added file (amlel) ------------------------------------------- */ #pragma once +#include +#include #include #include #include -#include -#include -#define kPITControlPort (0x43) +#define kPITControlPort (0x43) #define kPITChannel0Port (0x40) -#define kPITFrequency (1193180) +#define kPITFrequency (1193180) -#define kPICCommand (0x20) -#define kPICData (0x21) +#define kPICCommand (0x20) +#define kPICData (0x21) #define kPIC2Command (0xA0) -#define kPIC2Data (0xA1) +#define kPIC2Data (0xA1) #include @@ -38,269 +38,241 @@ /// @brief interrupt for system call. #define kKernelInterruptId (0x32) -#define IsActiveLow(FLG) (FLG & 2) +#define IsActiveLow(FLG) (FLG & 2) #define IsLevelTriggered(FLG) (FLG & 8) #define kInterruptGate (0x8E) -#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 = 4, - }; - - 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 final - { - RawRegister R8{0}; - RawRegister R9{0}; - RawRegister R10{0}; - RawRegister FS{0}; - RawRegister R12{0}; - RawRegister R13{0}; - RawRegister R14{0}; - RawRegister R15{0}; - RawRegister GS{0}; - RawRegister SP{0}; - RawRegister BP{0}; - }; - - 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; - - 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; - - class GDTLoader final - { - public: - static Void Load(Register64& gdt); - static Void Load(Ref& gdt); - }; - - class IDTLoader final - { - public: - static Void Load(Register64& idt); - static Void Load(Ref& 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. - /***********************************************************************************/ - 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); - } - - UIntPtr hal_get_phys_address(VoidPtr virtual_address); - - /***********************************************************************************/ - /// @brief Get Model specific register inside core. - /// @param msr MSR - /// @param lo low byte - /// @param hi high byte - /***********************************************************************************/ - inline UInt32 hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept - { - if (!lo || !hi) - return 0; - - asm volatile("rdmsr" - : "=a"(*lo), "=d"(*hi) - : "c"(msr)); - - return *lo + *hi; - } - - /// @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 APICController final - { - public: - explicit APICController(VoidPtr base); - ~APICController() = default; - - NE_COPY_DEFAULT(APICController) - - public: - UInt32 Read(UInt32 reg) noexcept; - Void Write(UInt32 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); - - 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(); -} // namespace Kernel::HAL +#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 = 4, +}; + +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 final { + RawRegister R8{0}; + RawRegister R9{0}; + RawRegister R10{0}; + RawRegister FS{0}; + RawRegister R12{0}; + RawRegister R13{0}; + RawRegister R14{0}; + RawRegister R15{0}; + RawRegister GS{0}; + RawRegister SP{0}; + RawRegister BP{0}; +}; + +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; + +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; + +class GDTLoader final { + public: + static Void Load(Register64& gdt); + static Void Load(Ref& gdt); +}; + +class IDTLoader final { + public: + static Void Load(Register64& idt); + static Void Load(Ref& 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. +/***********************************************************************************/ +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); +} + +UIntPtr hal_get_phys_address(VoidPtr virtual_address); + +/***********************************************************************************/ +/// @brief Get Model specific register inside core. +/// @param msr MSR +/// @param lo low byte +/// @param hi high byte +/***********************************************************************************/ +inline UInt32 hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept { + if (!lo || !hi) return 0; + + asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); + + return *lo + *hi; +} + +/// @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 APICController final { + public: + explicit APICController(VoidPtr base); + ~APICController() = default; + + NE_COPY_DEFAULT(APICController) + + public: + UInt32 Read(UInt32 reg) noexcept; + Void Write(UInt32 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); + +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(); +} // namespace Kernel::HAL EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp); EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp); @@ -311,4 +283,4 @@ 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; +inline Kernel::UIntPtr kKernelBitMpSize = 0UL; diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index 576c151b..aa9ab2cb 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss Corporation, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss Corporation, all rights reserved. ------------------------------------------- */ @@ -15,23 +15,23 @@ * */ +#include #include #include -#include #include -#include -#include -#include -#include +#include #include +#include #include -#include +#include +#include +#include #define kHBAErrTaskFile (1 << 30) -#define kHBAPxCmdST (0x0001) -#define kHBAPxCmdFre (0x0010) -#define kHBAPxCmdFR (0x4000) -#define kHBAPxCmdCR (0x8000) +#define kHBAPxCmdST (0x0001) +#define kHBAPxCmdFre (0x0010) +#define kHBAPxCmdFR (0x4000) +#define kHBAPxCmdCR (0x8000) #define kSATALBAMode (1 << 6) @@ -39,87 +39,84 @@ #define kSATASRDrq (0x08) #define kHBABohcBiosOwned (1 << 0) -#define kHBABohcOSOwned (1 << 1) +#define kHBABohcOSOwned (1 << 1) #define kSATAPortCnt (0x20) -#define kSATASig (0x00000101) +#define kSATASig (0x00000101) #define kSATAPISig (0xEB140101) #define kSATAProgIfAHCI (0x01) -#define kSATASubClass (0x06) -#define kSATABar5 (0x24) +#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 Lba kSATASectorCount = 0UL; +STATIC UInt16 kSATAIndex = 0U; +STATIC Char kCurrentDiskModel[50] = {"GENERIC SATA"}; +STATIC UInt16 kSATAPortsImplemented = 0U; template -STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept; +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 Void drv_compute_disk_ahci() noexcept -{ - kSATASectorCount = 0UL; +STATIC Void drv_compute_disk_ahci() noexcept { + kSATASectorCount = 0UL; - /// Normally 512 bytes, but add an additional 512 bytes to make 1 KIB. - const UInt16 kSzIdent = 512; + /// Normally 512 bytes, but add an additional 512 bytes to make 1 KIB. + const UInt16 kSzIdent = 512; - /// Push it to the stack - UInt8* identify_data = new UInt8[kSzIdent]; + /// Push it to the stack + UInt8* identify_data = new UInt8[kSzIdent]; - /// Send AHCI command for identification. - drv_std_input_output_ahci(0, identify_data, kAHCISectorSize, kSzIdent); + /// Send AHCI command for identification. + drv_std_input_output_ahci(0, identify_data, kAHCISectorSize, kSzIdent); - /// Extract 48-bit LBA. - UInt64 lba48_sectors = 0; - lba48_sectors |= (UInt64)identify_data[100]; - lba48_sectors |= (UInt64)identify_data[101] << 16; - lba48_sectors |= (UInt64)identify_data[102] << 32; + /// Extract 48-bit LBA. + UInt64 lba48_sectors = 0; + lba48_sectors |= (UInt64) identify_data[100]; + lba48_sectors |= (UInt64) identify_data[101] << 16; + lba48_sectors |= (UInt64) identify_data[102] << 32; - /// Now verify if lba48 - if (lba48_sectors == 0) - kSATASectorCount = (identify_data[61] << 16) | identify_data[60]; - else - kSATASectorCount = lba48_sectors; + /// Now verify if lba48 + if (lba48_sectors == 0) + kSATASectorCount = (identify_data[61] << 16) | identify_data[60]; + else + kSATASectorCount = lba48_sectors; - for (Int32 i = 0; i < 20; i++) - { - kCurrentDiskModel[i * 2] = (identify_data[27 + i] >> 8) & 0xFF; - kCurrentDiskModel[i * 2 + 1] = identify_data[27 + i] & 0xFF; - } + for (Int32 i = 0; i < 20; i++) { + kCurrentDiskModel[i * 2] = (identify_data[27 + i] >> 8) & 0xFF; + kCurrentDiskModel[i * 2 + 1] = identify_data[27 + i] & 0xFF; + } - kCurrentDiskModel[40] = '\0'; + kCurrentDiskModel[40] = '\0'; - (Void)(kout << "SATA Sector Count: " << hex_number(kSATASectorCount) << kendl); - (Void)(kout << "SATA Disk Model: " << kCurrentDiskModel << kendl); + (Void)(kout << "SATA Sector Count: " << hex_number(kSATASectorCount) << kendl); + (Void)(kout << "SATA Disk Model: " << kCurrentDiskModel << kendl); - delete[] identify_data; - identify_data = nullptr; + delete[] identify_data; + identify_data = nullptr; } /// @brief Finds a command slot for a HBA port. /// @param port The port to search on. /// @return The slot, or ~0. -STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept -{ - UInt32 slots = port->Sact | port->Ci; +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; - } + 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 + return -1; // no free slot found } /// @brief Send an AHCI command, according to the template parameters. @@ -128,225 +125,204 @@ STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept /// @param sector_sz The disk's sector size (unused) /// @param size_buffer The size of the **buffer** parameter. template -STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept -{ - UIntPtr slot = 0UL; +STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, + SizeT size_buffer) noexcept { + UIntPtr slot = 0UL; - slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); + slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); - if (slot == ~0UL) - { - err_global_get() = kErrorDisk; - return; - } + if (slot == ~0UL) { + err_global_get() = kErrorDisk; + return; + } - if (size_buffer > mib_cast(4) || - sector_sz > kAHCISectorSize) - return; + if (size_buffer > mib_cast(4) || sector_sz > kAHCISectorSize) return; - if (!Write) - { - // Zero-memory the buffer field. - rt_set_memory(buffer, 0, size_buffer); - } + if (!Write) { + // Zero-memory the buffer field. + rt_set_memory(buffer, 0, size_buffer); + } - /// prepare command header. - volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)(((UInt64)kSATAHba->Ports[kSATAIndex].Clb))); + /// prepare command header. + volatile HbaCmdHeader* command_header = + ((volatile HbaCmdHeader*) (((UInt64) kSATAHba->Ports[kSATAIndex].Clb))); - /// Offset to specific command slot. - command_header += slot; + /// Offset to specific command slot. + command_header += slot; - /// check for command header. - MUST_PASS(command_header); + /// check for command header. + MUST_PASS(command_header); - command_header->Struc.Cfl = sizeof(FisRegH2D) / sizeof(UInt32); - command_header->Struc.Write = Write; - command_header->Prdtl = 8; + command_header->Struc.Cfl = sizeof(FisRegH2D) / sizeof(UInt32); + command_header->Struc.Write = Write; + command_header->Prdtl = 8; - auto ctba_phys = ((UInt64)command_header->Ctbau << 32) | command_header->Ctba; - auto command_table = reinterpret_cast(ctba_phys); + auto ctba_phys = ((UInt64) command_header->Ctbau << 32) | command_header->Ctba; + auto command_table = reinterpret_cast(ctba_phys); - MUST_PASS(command_table); + MUST_PASS(command_table); - UIntPtr buffer_phys = HAL::hal_get_phys_address(buffer); - SizeT bytes_remaining = size_buffer; + UIntPtr buffer_phys = HAL::hal_get_phys_address(buffer); + SizeT bytes_remaining = size_buffer; - command_table->Prdt[0].Dba = (UInt32)(buffer_phys & 0xFFFFFFFF); - command_table->Prdt[0].Dbau = (UInt32)(buffer_phys >> 32); - command_table->Prdt[0].Dbc = bytes_remaining - 1; - command_table->Prdt[0].Ie = NO; + command_table->Prdt[0].Dba = (UInt32) (buffer_phys & 0xFFFFFFFF); + command_table->Prdt[0].Dbau = (UInt32) (buffer_phys >> 32); + command_table->Prdt[0].Dbc = bytes_remaining - 1; + command_table->Prdt[0].Ie = NO; - volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)(&command_table->Cfis[0]); + 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->FisType = kFISTypeRegH2D; + h2d_fis->CmdOrCtrl = CommandOrCTRL; + h2d_fis->Command = + (Identify ? (kAHCICmdIdentify) : (Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx)); - h2d_fis->Lba0 = (lba)&0xFF; - h2d_fis->Lba1 = (lba >> 8) & 0xFF; - h2d_fis->Lba2 = (lba >> 16) & 0xFF; + h2d_fis->Lba0 = (lba) & 0xFF; + h2d_fis->Lba1 = (lba >> 8) & 0xFF; + h2d_fis->Lba2 = (lba >> 16) & 0xFF; - h2d_fis->Device = kSATALBAMode; + h2d_fis->Device = kSATALBAMode; - h2d_fis->Lba3 = (lba >> 24) & 0xFF; - h2d_fis->Lba4 = (lba >> 32) & 0xFF; - h2d_fis->Lba5 = (lba >> 40) & 0xFF; + h2d_fis->Lba3 = (lba >> 24) & 0xFF; + h2d_fis->Lba4 = (lba >> 32) & 0xFF; + h2d_fis->Lba5 = (lba >> 40) & 0xFF; - h2d_fis->CountLow = (size_buffer)&0xFF; - h2d_fis->CountHigh = (size_buffer >> 8) & 0xFF; + h2d_fis->CountLow = (size_buffer) & 0xFF; + h2d_fis->CountHigh = (size_buffer >> 8) & 0xFF; - kSATAHba->Ports[kSATAIndex].Ci = (1 << slot); + kSATAHba->Ports[kSATAIndex].Ci = (1 << slot); - for (Int32 i = 0; i < 1000000; ++i) - { - if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) - break; - } + for (Int32 i = 0; i < 1000000; ++i) { + if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break; + } - if (kSATAHba->Is & kHBAErrTaskFile) - { - err_global_get() = kErrorDiskIsCorrupted; - return; - } + if (kSATAHba->Is & kHBAErrTaskFile) { + err_global_get() = kErrorDiskIsCorrupted; + return; + } - err_global_get() = kErrorSuccess; + err_global_get() = kErrorSuccess; } /*** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. + @brief Gets the number of sectors inside the drive. + @return Sector size in bytes. */ -SizeT drv_get_sector_count_ahci() -{ - return kSATASectorCount; +SizeT drv_get_sector_count_ahci() { + return kSATASectorCount; } /// @brief Get the drive size. /// @return Disk size in bytes. -SizeT drv_get_size_ahci() -{ - return drv_get_sector_count() * kAHCISectorSize; +SizeT drv_get_size_ahci() { + return drv_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; +STATIC BOOL ahci_enable_and_probe() { + if (kSATAHba->Cap == 0x0) return NO; - kSATAHba->Ports[kSATAIndex].Cmd &= ~kHBAPxCmdFre; - kSATAHba->Ports[kSATAIndex].Cmd &= ~kHBAPxCmdST; + kSATAHba->Ports[kSATAIndex].Cmd &= ~kHBAPxCmdFre; + kSATAHba->Ports[kSATAIndex].Cmd &= ~kHBAPxCmdST; - while (YES) - { - if (kSATAHba->Ports[kSATAIndex].Cmd & kHBAPxCmdCR) - continue; + while (YES) { + if (kSATAHba->Ports[kSATAIndex].Cmd & kHBAPxCmdCR) continue; - if (kSATAHba->Ports[kSATAIndex].Cmd & kHBAPxCmdFR) - continue; + if (kSATAHba->Ports[kSATAIndex].Cmd & kHBAPxCmdFR) continue; - break; - } + break; + } - // Now we are ready. + // Now we are ready. - kSATAHba->Ports[kSATAIndex].Cmd |= kHBAPxCmdFre; - kSATAHba->Ports[kSATAIndex].Cmd |= kHBAPxCmdST; + kSATAHba->Ports[kSATAIndex].Cmd |= kHBAPxCmdFre; + kSATAHba->Ports[kSATAIndex].Cmd |= kHBAPxCmdST; - if (kSATAHba->Bohc & kHBABohcBiosOwned) - { - kSATAHba->Bohc |= kHBABohcOSOwned; + if (kSATAHba->Bohc & kHBABohcBiosOwned) { + kSATAHba->Bohc |= kHBABohcOSOwned; - while (kSATAHba->Bohc & kHBABohcBiosOwned) - { - ; - } - } + while (kSATAHba->Bohc & kHBABohcBiosOwned) { + ; + } + } - drv_compute_disk_ahci(); + drv_compute_disk_ahci(); - return YES; + 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) -{ - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); +STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi) { + PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) - { - kSATADev = iterator[device_index].Leak(); // Leak device. + 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(); + if (kSATADev.Subclass() == kSATASubClass && kSATADev.ProgIf() == kSATAProgIfAHCI) { + kSATADev.EnableMmio(); + kSATADev.BecomeBusMaster(); - HbaMem* mem_ahci = (HbaMem*)kSATADev.Bar(kSATABar5); + 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); + 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; + UInt32 ports_implemented = mem_ahci->Pi; + UInt16 ahci_index = 0; - pi = ports_implemented; + pi = ports_implemented; - const UInt16 kSATAMaxPortsImplemented = ports_implemented; - const UInt32 kSATASignature = kSATASig; - const UInt32 kSATAPISignature = kSATAPISig; - const UInt8 kSATAPresent = 0x03; - const UInt8 kSATAIPMActive = 0x01; + 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; + 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); + 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 (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 ((mem_ahci->Ports[ahci_index].Sig == kSATASignature) || + (atapi && kSATAPISignature == mem_ahci->Ports[ahci_index].Sig)) { + kSATAIndex = ahci_index; + kSATAHba = mem_ahci; - goto success_hba_fetch; - } + goto success_hba_fetch; + } - ports_implemented >>= 1; - ++ahci_index; - } - } - } + ports_implemented >>= 1; + ++ahci_index; + } + } + } - err_global_get() = kErrorDisk; + err_global_get() = kErrorDisk; - return NO; + return NO; success_hba_fetch: - if (ahci_enable_and_probe()) - { - err_global_get() = kErrorSuccess; + if (ahci_enable_and_probe()) { + err_global_get() = kErrorSuccess; - return YES; - } + return YES; + } - return NO; + return NO; } /// @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; +Bool drv_std_detected_ahci() { + return kSATADev.DeviceId() != (UShort) PCI::PciConfigKind::Invalid && + kSATADev.Bar(kSATABar5) != 0; } // ================================================================================================ @@ -362,133 +338,121 @@ Bool drv_std_detected_ahci() //////////////////////////////////////////////////// /// //////////////////////////////////////////////////// -Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) -{ - drv_std_input_output_ahci(lba, reinterpret_cast(buffer), sector_sz, size_buffer); +Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { + drv_std_input_output_ahci(lba, reinterpret_cast(buffer), sector_sz, + size_buffer); } //////////////////////////////////////////////////// /// //////////////////////////////////////////////////// -Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) -{ - drv_std_input_output_ahci(lba, reinterpret_cast(buffer), sector_sz, size_buffer); +Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { + drv_std_input_output_ahci(lba, reinterpret_cast(buffer), sector_sz, + size_buffer); } //////////////////////////////////////////////////// /// //////////////////////////////////////////////////// -Bool drv_std_init(UInt16& pi) -{ - BOOL atapi = NO; - return drv_std_init_ahci(pi, atapi); +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(); +Bool drv_std_detected(Void) { + return drv_std_detected_ahci(); } //////////////////////////////////////////////////// /** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. + @brief Gets the number of sectors inside the drive. + @return Sector size in bytes. */ //////////////////////////////////////////////////// -SizeT drv_get_sector_count() -{ - return drv_get_sector_count_ahci(); +SizeT drv_get_sector_count() { + return drv_get_sector_count_ahci(); } //////////////////////////////////////////////////// /// @brief Get the drive size. /// @return Disk size in bytes. //////////////////////////////////////////////////// -SizeT drv_get_size() -{ - return drv_get_size_ahci(); +SizeT drv_get_size() { + return drv_get_size_ahci(); } -#endif // ifdef __AHCI__ +#endif // ifdef __AHCI__ -namespace Kernel -{ - /// @brief Initialize an AHCI device (StorageKit) - UInt16 sk_init_ahci_device(BOOL atapi) - { - UInt16 pi = 0; +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; + if (drv_std_init_ahci(pi, atapi)) kSATAPortsImplemented = pi; - return 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(IDeviceObject* self, MountpointInterface* mnt) - { - AHCIDeviceInterface* dev = (AHCIDeviceInterface*)self; +/// @brief Implementation details namespace. +namespace Detail { + /// @brief Read AHCI device. + /// @param self device + /// @param mnt mounted disk. + STATIC Void sk_io_read_ahci(IDeviceObject* self, MountpointInterface* mnt) { + AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self; - err_global_get() = kErrorDisk; + err_global_get() = kErrorDisk; - if (!dev) - return; + if (!dev) return; - auto disk = mnt->GetAddressOf(dev->GetIndex()); + auto disk = mnt->GetAddressOf(dev->GetIndex()); - if (!disk) - return; + if (!disk) return; - err_global_get() = kErrorSuccess; + err_global_get() = kErrorSuccess; - drv_std_input_output_ahci(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize); - } + drv_std_input_output_ahci(disk->fPacket.fPacketLba, + (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(IDeviceObject* self, MountpointInterface* mnt) - { - AHCIDeviceInterface* dev = (AHCIDeviceInterface*)self; + /// @brief Write AHCI device. + /// @param self device + /// @param mnt mounted disk. + STATIC Void sk_io_write_ahci(IDeviceObject* self, + MountpointInterface* mnt) { + AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self; - err_global_get() = kErrorDisk; + err_global_get() = kErrorDisk; - if (!dev) - return; + if (!dev) return; - auto disk = mnt->GetAddressOf(dev->GetIndex()); + auto disk = mnt->GetAddressOf(dev->GetIndex()); - if (!disk) - return; + if (!disk) return; - err_global_get() = kErrorSuccess; + err_global_get() = kErrorSuccess; - drv_std_input_output_ahci(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize); - } - } // namespace Detail + drv_std_input_output_ahci(disk->fPacket.fPacketLba, + (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 sk_acquire_ahci_device(Int32 drv_index) - { - if (!drv_std_detected_ahci()) - return ErrorOr(kErrorDisk); +/// @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 sk_acquire_ahci_device(Int32 drv_index) { + if (!drv_std_detected_ahci()) return ErrorOr(kErrorDisk); - AHCIDeviceInterface device(Detail::sk_io_read_ahci, - Detail::sk_io_write_ahci); + AHCIDeviceInterface device(Detail::sk_io_read_ahci, Detail::sk_io_write_ahci); - device.SetPortsImplemented(kSATAPortsImplemented); - device.SetIndex(drv_index); + device.SetPortsImplemented(kSATAPortsImplemented); + device.SetIndex(drv_index); - return ErrorOr(device); - } -} // namespace Kernel + return ErrorOr(device); +} +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc index f04d25eb..a7361778 100644 --- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -15,9 +15,9 @@ * */ -#include #include #include +#include #if defined(__ATA_DMA__) @@ -28,185 +28,165 @@ using namespace Kernel::HAL; /// BUGS: 0 -STATIC Boolean kATADetected = false; -STATIC Int32 kATADeviceType = kATADeviceCount; +STATIC Boolean kATADetected = false; +STATIC Int32 kATADeviceType = kATADeviceCount; STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; STATIC Kernel::PCI::Device kATADevice; -STATIC Char kATADiskModel[50] = {"GENERIC DMA"}; +STATIC Char kATADiskModel[50] = {"GENERIC DMA"}; -Boolean drv_std_wait_io(UInt16 IO) -{ - for (int i = 0; i < 400; i++) - rt_in8(IO + ATA_REG_STATUS); +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); + auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - if ((status_rdy & ATA_SR_BSY)) - goto ATAWaitForIO_Retry; + if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; ATAWaitForIO_Retry2: - status_rdy = rt_in8(IO + ATA_REG_STATUS); + status_rdy = rt_in8(IO + ATA_REG_STATUS); - if (status_rdy & ATA_SR_ERR) - return false; + if (status_rdy & ATA_SR_ERR) return false; - if (!(status_rdy & ATA_SR_DRDY)) - goto ATAWaitForIO_Retry2; + if (!(status_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - return true; + 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); +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) -{ - 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. +Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { + PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - /// IDE interface - if (kATADevice.Subclass() == 0x01) - { + for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { + kATADevice = iterator[device_index].Leak(); // And then leak the reference. - break; - } - } + /// IDE interface + if (kATADevice.Subclass() == 0x01) { + break; + } + } - return NO; + 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 +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; +Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { + Lba /= SectorSz; - if (Size > kib_cast(64)) - return; + if (Size > kib_cast(64)) return; - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - rt_copy_memory((VoidPtr)Buf, (VoidPtr)kReadAddr, Size); + rt_copy_memory((VoidPtr) Buf, (VoidPtr) kReadAddr, Size); - drv_std_select(IO); + drv_std_select(IO); - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + 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_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); + 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. + 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. + 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_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) + ATA_REG_COMMAND, ATA_CMD_READ_DMA); - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine + rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; + while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01); - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine + rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine - rt_copy_memory((VoidPtr)kReadAddr, (VoidPtr)Buf, Size); + rt_copy_memory((VoidPtr) kReadAddr, (VoidPtr) Buf, Size); - delete prd; - prd = nullptr; + delete prd; + prd = nullptr; } -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; +Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { + Lba /= SectorSz; - if (Size > kib_cast(64)) - return; + if (Size > kib_cast(64)) return; - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - rt_copy_memory((VoidPtr)Buf, (VoidPtr)kWriteAddr, Size); + rt_copy_memory((VoidPtr) Buf, (VoidPtr) kWriteAddr, Size); - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + 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_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); + 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); + Kernel::Detail::PRDEntry* prd = (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4); - prd->mAddress = (UInt32)(UIntPtr)kWriteAddr; - prd->mByteCount = Size - 1; - prd->mFlags = 0x8000; + 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_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 + rt_out8(IO + 0x00, 0x09); // Start DMA engine - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; + while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01); - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine + rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine - delete prd; - prd = nullptr; + delete prd; + prd = nullptr; } /***********************************************************************************/ /// @brief Is ATA detected? /***********************************************************************************/ -Boolean drv_std_detected(Void) -{ - return kATADetected; +Boolean drv_std_detected(Void) { + return kATADetected; } /***********************************************************************************/ /*** - @brief Gets the number of sectors inside the drive. - @return Number of sectors, or zero. + @brief Gets the number of sectors inside the drive. + @return Number of sectors, or zero. */ /***********************************************************************************/ -Kernel::SizeT drv_get_sector_count() -{ - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; +Kernel::SizeT drv_get_sector_count() { + return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; } /***********************************************************************************/ /// @brief Get the size of the current drive. /***********************************************************************************/ -Kernel::SizeT drv_get_size() -{ - return (drv_get_sector_count()) * kATASectorSize; +Kernel::SizeT drv_get_size() { + return (drv_get_sector_count()) * kATASectorSize; } #endif /* ifdef __ATA_DMA__ */ diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc index cd25ab7f..6fb1d8a3 100644 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -15,10 +15,10 @@ * */ -#include #include #include #include +#include using namespace Kernel; using namespace Kernel::HAL; @@ -27,264 +27,234 @@ using namespace Kernel::HAL; #define kATADataLen 256 -STATIC Boolean kATADetected = false; +STATIC Boolean kATADetected = false; STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; -STATIC Char kATADiskModel[50] = {"GENERIC PIO"}; +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); +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); + auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - if ((stat_rdy & ATA_SR_BSY)) - goto ATAWaitForIO_Retry; + if ((stat_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; ATAWaitForIO_Retry2: - stat_rdy = rt_in8(IO + ATA_REG_STATUS); + stat_rdy = rt_in8(IO + ATA_REG_STATUS); - if (stat_rdy & ATA_SR_ERR) - return false; + if (stat_rdy & ATA_SR_ERR) return false; - if (!(stat_rdy & ATA_SR_DRDY)) - goto ATAWaitForIO_Retry2; + if (!(stat_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - return true; + 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); +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; +Boolean drv_pio_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { + UInt16 IO = Bus; - NE_UNUSED(Drive); + NE_UNUSED(Drive); - drv_pio_std_select(IO); + drv_pio_std_select(IO); - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); - // identify until it's good. + // identify until it's good. ATAInit_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); + auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - if (stat_rdy & ATA_SR_ERR) - { - return false; - } + if (stat_rdy & ATA_SR_ERR) { + return false; + } - if ((stat_rdy & ATA_SR_BSY)) - goto ATAInit_Retry; + 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; + OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - drv_pio_std_wait_io(IO); + drv_pio_std_wait_io(IO); - /// fetch serial info - /// model, speed, number of sectors... + /// fetch serial info + /// model, speed, number of sectors... - for (SizeT i = 0ul; i < kATADataLen; ++i) - { - kATAIdentifyData[i] = HAL::rt_in16(OutBus + ATA_REG_DATA); - } + for (SizeT i = 0ul; i < kATADataLen; ++i) { + kATAIdentifyData[i] = HAL::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; - } + 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'; + kATADiskModel[40] = '\0'; - (Void)(kout << "Drive Model: " << kATADiskModel << kendl); + (Void)(kout << "Drive Model: " << kATADiskModel << kendl); - return true; + return true; } -Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; +Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { + Lba /= SectorSz; - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); + 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_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); + 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_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); + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - drv_pio_std_wait_io(IO); - Buf[IndexOff] = HAL::rt_in16(IO + ATA_REG_DATA); - } + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + drv_pio_std_wait_io(IO); + Buf[IndexOff] = HAL::rt_in16(IO + ATA_REG_DATA); + } } -Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; +Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { + Lba /= SectorSz; - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); + 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_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); + 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_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); + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - drv_pio_std_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); - } + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + drv_pio_std_wait_io(IO); + rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + } } /// @brief is ATA detected? -Boolean drv_pio_std_detected(Void) -{ - return kATADetected; +Boolean drv_pio_std_detected(Void) { + return kATADetected; } /*** - @brief Getter, gets the number of sectors inside the drive. + @brief Getter, gets the number of sectors inside the drive. */ -SizeT drv_pio_get_sector_count() -{ - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; +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; +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_pio_device(BOOL is_master, UInt16& io, UInt8& master) - { - return drv_pio_std_init(ATA_SECONDARY_IO, is_master, io, master); - } +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_pio_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(IDeviceObject* self, MountpointInterface* mnt) - { - ATADeviceInterface* dev = (ATADeviceInterface*)self; +/// @brief Implementation details namespace. +namespace Detail { + /// @brief Read PIO device. + /// @param self device + /// @param mnt mounted disk. + STATIC Void sk_io_read_pio(IDeviceObject* self, MountpointInterface* mnt) { + ATADeviceInterface* dev = (ATADeviceInterface*) self; - err_global_get() = kErrorDisk; + err_global_get() = kErrorDisk; - if (!dev) - return; + if (!dev) return; - auto disk = mnt->GetAddressOf(dev->GetIndex()); + auto disk = mnt->GetAddressOf(dev->GetIndex()); - if (!disk) - return; + if (!disk) return; - err_global_get() = kErrorSuccess; + err_global_get() = kErrorSuccess; - drv_pio_std_read(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), (Char*)disk->fPacket.fPacketContent, kATASectorSize, disk->fPacket.fPacketSize); - } + 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(IDeviceObject* self, MountpointInterface* mnt) - { - ATADeviceInterface* dev = (ATADeviceInterface*)self; + /// @brief Write PIO device. + /// @param self device + /// @param mnt mounted disk. + STATIC Void sk_io_write_pio(IDeviceObject* self, MountpointInterface* mnt) { + ATADeviceInterface* dev = (ATADeviceInterface*) self; - err_global_get() = kErrorDisk; + err_global_get() = kErrorDisk; - if (!dev) - return; + if (!dev) return; - auto disk = mnt->GetAddressOf(dev->GetIndex()); + auto disk = mnt->GetAddressOf(dev->GetIndex()); - if (!disk) - return; + if (!disk) return; - err_global_get() = kErrorSuccess; + 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 + 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 sk_acquire_pio_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); +/// @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 sk_acquire_pio_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); + device.SetIndex(drv_index); - return ErrorOr(device); - } -} // namespace Kernel + return ErrorOr(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_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); +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_get_size() -{ - return drv_pio_get_size(); +SizeT drv_get_size() { + return drv_pio_get_size(); } -SizeT drv_get_sector_count() -{ - return drv_pio_get_sector_count(); +SizeT drv_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); +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 index cb387e73..1cc97cba 100644 --- a/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,5 +9,5 @@ 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}; +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 index fc53e4e0..3df8a407 100644 --- a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc +++ b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc @@ -1,11 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include +#include using namespace Kernel; @@ -13,25 +13,23 @@ using namespace Kernel; /// @param base_dma the IO base port. /// @param cmd the command. /// @return status code. -EXTERN_C Int32 apm_send_io_command(UInt16 cmd, APMPowerCmd value) -{ - switch (cmd) - { - case kAPMPowerCommandReboot: { - asm volatile( - "ldr x0, =0x84000004\n" - "svc #0\n"); +EXTERN_C Int32 apm_send_io_command(UInt16 cmd, APMPowerCmd value) { + 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; + } + case kAPMPowerCommandShutdown: { + asm volatile( + "ldr x0, =0x84000008\n" + "svc #0\n"); - return kErrorSuccess; - } - default: - return kErrorInvalidData; - } + return kErrorSuccess; + } + default: + return kErrorInvalidData; + } } diff --git a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h index 6068d503..f48c1483 100644 --- a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h +++ b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h @@ -1,19 +1,18 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include /************************************************** */ /* INITIALIZE THE GIC ON CPU. */ /************************************************** */ -namespace Kernel -{ - BOOL mp_initialize_gic(Kernel::Void); +namespace Kernel { +BOOL mp_initialize_gic(Kernel::Void); } \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc index 27ea0977..31f5a4f2 100644 --- a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc +++ b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc @@ -1,32 +1,26 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include -#include #include #include +#include +#include #include -namespace Kernel -{ - ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) - : fRsdp(rsp_ptr), fEntries(0) - { - } +namespace Kernel { +ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) : fRsdp(rsp_ptr), fEntries(0) {} - BOOL ACPIFactoryInterface::Shutdown() - { - apm_send_io_command(kAPMPowerCommandShutdown, 0); - return NO; - } +BOOL ACPIFactoryInterface::Shutdown() { + apm_send_io_command(kAPMPowerCommandShutdown, 0); + 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, 0); - } -} // namespace Kernel +/// @brief Reboot machine in either ACPI or by triple faulting. +/// @return nothing it's a reboot. +Void ACPIFactoryInterface::Reboot() { + apm_send_io_command(kAPMPowerCommandReboot, 0); +} +} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 7d985a44..14af1a16 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -1,145 +1,132 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include #include -#define GICD_BASE 0x08000000 // Distributor base address -#define GICC_BASE 0x08010000 // CPU interface base address +#define GICD_BASE 0x08000000 // Distributor base address +#define GICC_BASE 0x08010000 // CPU interface base address -#define GICD_CTLR 0x000 // Distributor Control Register -#define GICD_ISENABLER 0x100 // Interrupt Set-Enable Registers -#define GICD_ICENABLER 0x180 // Interrupt Clear-Enable Registers -#define GICD_ISPENDR 0x200 // Interrupt Set-Pending Registers -#define GICD_ICPENDR 0x280 // Interrupt Clear-Pending Registers -#define GICD_IPRIORITYR 0x400 // Interrupt Priority Registers -#define GICD_ITARGETSR 0x800 // Interrupt Processor Targets Registers -#define GICD_ICFGR 0xC00 // Interrupt Configuration Registers +#define GICD_CTLR 0x000 // Distributor Control Register +#define GICD_ISENABLER 0x100 // Interrupt Set-Enable Registers +#define GICD_ICENABLER 0x180 // Interrupt Clear-Enable Registers +#define GICD_ISPENDR 0x200 // Interrupt Set-Pending Registers +#define GICD_ICPENDR 0x280 // Interrupt Clear-Pending Registers +#define GICD_IPRIORITYR 0x400 // Interrupt Priority Registers +#define GICD_ITARGETSR 0x800 // Interrupt Processor Targets Registers +#define GICD_ICFGR 0xC00 // Interrupt Configuration Registers -#define GICC_CTLR 0x000 // CPU Interface Control Register -#define GICC_PMR 0x004 // Interrupt Priority Mask Register -#define GICC_IAR 0x00C // Interrupt Acknowledge Register -#define GICC_EOIR 0x010 // End of Interrupt Register +#define GICC_CTLR 0x000 // CPU Interface Control Register +#define GICC_PMR 0x004 // Interrupt Priority Mask Register +#define GICC_IAR 0x00C // Interrupt Acknowledge Register +#define GICC_EOIR 0x010 // End of Interrupt Register // ================================================================= // -namespace Kernel -{ - struct PROCESS_CONTROL_BLOCK final - { - HAL::StackFramePtr mFrame; - }; +namespace Kernel { +struct PROCESS_CONTROL_BLOCK final { + HAL::StackFramePtr mFrame; +}; - STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; +STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; - namespace Detail - { - STATIC BOOL kGICEnabled = NO; +namespace Detail { + STATIC BOOL kGICEnabled = NO; - STATIC void mp_hang_fn(void) - { - while (YES) - ; + STATIC void mp_hang_fn(void) { + while (YES); - dbg_break_point(); - } + dbg_break_point(); + } - Void mp_setup_gic_el0(Void) - { - // enable distributor. - ke_dma_write(GICD_BASE, GICD_CTLR, YES); + Void mp_setup_gic_el0(Void) { + // enable distributor. + ke_dma_write(GICD_BASE, GICD_CTLR, YES); - UInt32 gicc_ctlr = ke_dma_read(GICC_BASE, GICC_CTLR); + UInt32 gicc_ctlr = ke_dma_read(GICC_BASE, GICC_CTLR); - const auto kEnableSignalInt = YES; + const auto kEnableSignalInt = YES; - gicc_ctlr |= kEnableSignalInt; // Enable signaling of interrupts - gicc_ctlr |= (kEnableSignalInt << 1); // Allow Group 1 interrupts in EL0 + gicc_ctlr |= kEnableSignalInt; // Enable signaling of interrupts + gicc_ctlr |= (kEnableSignalInt << 1); // Allow Group 1 interrupts in EL0 - ke_dma_write(GICC_BASE, GICC_CTLR, gicc_ctlr); + ke_dma_write(GICC_BASE, GICC_CTLR, gicc_ctlr); - // Set priority mask (accept all priorities) - ke_dma_write(GICC_BASE, GICC_PMR, 0xFF); + // Set priority mask (accept all priorities) + ke_dma_write(GICC_BASE, GICC_PMR, 0xFF); - UInt32 icfgr = ke_dma_read(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4); + UInt32 icfgr = ke_dma_read(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4); - icfgr |= (0x2 << ((32 % 16) * 2)); // Edge-triggered - ke_dma_write(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr); + icfgr |= (0x2 << ((32 % 16) * 2)); // Edge-triggered + ke_dma_write(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr); - // Target interrupt 32 to CPU 1 - ke_dma_write(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8)); + // Target interrupt 32 to CPU 1 + ke_dma_write(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8)); - // Set interrupt 32 priority to lowest (0xFF) - ke_dma_write(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8)); + // Set interrupt 32 priority to lowest (0xFF) + ke_dma_write(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8)); - // Enable interrupt 32 for AP. - ke_dma_write(GICD_BASE, GICD_ISENABLER + 4, 0x01); - } + // Enable interrupt 32 for AP. + ke_dma_write(GICD_BASE, GICD_ISENABLER + 4, 0x01); + } - BOOL mp_handle_gic_interrupt_el0(Void) - { - // Read the interrupt ID - UInt32 interrupt_id = ke_dma_read(GICC_BASE, GICC_IAR); + BOOL mp_handle_gic_interrupt_el0(Void) { + // Read the interrupt ID + UInt32 interrupt_id = ke_dma_read(GICC_BASE, GICC_IAR); - // Check if it's a valid interrupt (not spurious) - if ((interrupt_id & 0x3FF) < 1020) - { - auto interrupt = interrupt_id & 0x3FF; + // Check if it's a valid interrupt (not spurious) + if ((interrupt_id & 0x3FF) < 1020) { + auto interrupt = interrupt_id & 0x3FF; - const UInt16 kInterruptScheduler = 0x20; + const UInt16 kInterruptScheduler = 0x20; - (Void)(kout << "Handling interrupt for AP: " << interrupt << kendl); + (Void)(kout << "Handling interrupt for AP: " << interrupt << kendl); - switch (interrupt) - { - case kInterruptScheduler: { - ke_dma_write(GICC_BASE, GICC_EOIR, interrupt_id); - UserProcessHelper::StartScheduling(); - break; - } - default: { - ke_dma_write(GICC_BASE, GICC_EOIR, interrupt_id); - break; - } - } + switch (interrupt) { + case kInterruptScheduler: { + ke_dma_write(GICC_BASE, GICC_EOIR, interrupt_id); + UserProcessHelper::StartScheduling(); + break; + } + default: { + ke_dma_write(GICC_BASE, GICC_EOIR, interrupt_id); + break; + } + } - return YES; - } + return YES; + } - // spurious interrupt - return NO; - } - } // namespace Detail + // spurious interrupt + return NO; + } +} // namespace Detail - EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) - { - return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame; - } +EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid) { + return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame; +} - EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) - { - MUST_PASS(stack_frame); +EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { + MUST_PASS(stack_frame); - const auto process_index = pid % kSchedProcessLimitPerTeam; + const auto process_index = pid % kSchedProcessLimitPerTeam; - kProcessBlocks[process_index].mFrame = stack_frame; + kProcessBlocks[process_index].mFrame = stack_frame; - return YES; - } + return YES; +} - BOOL mp_initialize_gic(Void) - { - if (!Detail::kGICEnabled) - { - Detail::kGICEnabled = YES; - Detail::mp_setup_gic_el0(); - } +BOOL mp_initialize_gic(Void) { + if (!Detail::kGICEnabled) { + Detail::kGICEnabled = YES; + Detail::mp_setup_gic_el0(); + } - return Detail::kGICEnabled; - } -} // namespace Kernel \ No newline at end of file + return Detail::kGICEnabled; +} +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc index 7f9c73be..7ec90c6e 100644 --- a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc @@ -1,83 +1,71 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -#include #include +#include -namespace Kernel -{ - EXTERN_C void ke_io_write(IDeviceObject* self, const Char* bytes) - { +namespace Kernel { +EXTERN_C void ke_io_write(IDeviceObject* self, const Char* bytes) { #ifdef __DEBUG__ - if (*bytes == 0) - return; + if (*bytes == 0) return; - SizeT index = 0; - SizeT len = 0; + SizeT index = 0; + SizeT len = 0; - index = 0; - len = rt_string_len(bytes, 256U); + index = 0; + len = rt_string_len(bytes, 256U); - volatile UInt8* uart_ptr = (UInt8*)0x09000000; + volatile UInt8* uart_ptr = (UInt8*) 0x09000000; - while (index < len) - { - if (bytes[index] == '\r') - *uart_ptr = '\r'; + while (index < len) { + if (bytes[index] == '\r') *uart_ptr = '\r'; - *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index]; - ++index; - } -#endif // __DEBUG__ - } + *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index]; + ++index; + } +#endif // __DEBUG__ +} - TerminalDevice::~TerminalDevice() = default; +TerminalDevice::~TerminalDevice() = default; - EXTERN_C void ke_io_read(IDeviceObject* self, const Char* bytes) - { +EXTERN_C void ke_io_read(IDeviceObject* 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 + 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/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index 3498d477..3e6701ea 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -1,77 +1,71 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -#include +#include #include +#include +#include #include #include #include #include +#include #include -#include #include -#include -#include -#include +#include #include -EXTERN_C void hal_init_platform( - Kernel::HEL::BootInfoHeader* handover_hdr) -{ - - /************************************************** */ - /* INITIALIZE AND VALIDATE HEADER. */ - /************************************************** */ +EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { + /************************************************** */ + /* INITIALIZE AND VALIDATE HEADER. */ + /************************************************** */ - kHandoverHeader = handover_hdr; + kHandoverHeader = handover_hdr; - if (kHandoverHeader->f_Magic != kHandoverMagic && - kHandoverHeader->f_Version != kHandoverVersion) - { - return; - } + if (kHandoverHeader->f_Magic != kHandoverMagic && + kHandoverHeader->f_Version != kHandoverVersion) { + return; + } - /************************************** */ - /* INITIALIZE BIT MAP. */ - /************************************** */ + /************************************** */ + /* INITIALIZE BIT MAP. */ + /************************************** */ - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - kKernelBitMpStart = reinterpret_cast( - reinterpret_cast(kHandoverHeader->f_BitMapStart)); + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + kKernelBitMpStart = reinterpret_cast( + reinterpret_cast(kHandoverHeader->f_BitMapStart)); - /// @note do initialize the interrupts after it. + /// @note do initialize the interrupts after it. - Kernel::mp_initialize_gic(); + Kernel::mp_initialize_gic(); - /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every process according to their affinity fairly. + /// after the scheduler runs, we must look over teams, every 5000s in order to schedule every + /// process according to their affinity fairly. - auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. + auto constexpr kSchedTeamSwitchMS = 5U; /// @brief Team switch time in milliseconds. - Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); + Kernel::HardwareTimer timer(rtl_milliseconds(kSchedTeamSwitchMS)); - STATIC Kernel::Array kTeams; + STATIC Kernel::Array kTeams; - SizeT team_index = 0U; + SizeT team_index = 0U; - /// @brief This just loops over the teams and switches between them. - /// @details Not even round-robin, just a simple loop in this boot core we're at. - while (YES) - { - if (team_index > (kSchedTeamCount - 1)) - { - team_index = 0U; - } + /// @brief This just loops over the teams and switches between them. + /// @details Not even round-robin, just a simple loop in this boot core we're at. + while (YES) { + if (team_index > (kSchedTeamCount - 1)) { + team_index = 0U; + } - while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])) - ; + while (!UserProcessScheduler::The().SwitchTeam(kTeams[team_index])); - timer.Wait(); + timer.Wait(); - ++team_index; - } + ++team_index; + } } diff --git a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc index ad966991..5680041c 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc @@ -1,80 +1,74 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include -#include -#include -#include #include +#include #include +#include +#include +#include +#include #include #include -#include /* 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; - }; +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) - { - fb_init(); +/***********************************************************************************/ +/// @brief Stops execution of the kernel. +/// @param id kernel stop ID. +/***********************************************************************************/ +Void ke_panic(const Kernel::Int32& id, const Char* message) { + fb_init(); - auto panic_text = RGB(0xff, 0xff, 0xff); + auto panic_text = RGB(0xff, 0xff, 0xff); - auto y = 10; - auto x = 10; + auto y = 10; + auto x = 10; - Char* message_apicid = new Char[128]; - rt_set_memory(message_apicid, 0, 128); + Char* message_apicid = new Char[128]; + rt_set_memory(message_apicid, 0, 128); - rt_copy_memory((VoidPtr) "panic id: ", message_apicid, rt_string_len("panic id: ")); - rt_to_string(message_apicid + rt_string_len("panic id: "), (UIntPtr)id, 10); + rt_copy_memory((VoidPtr) "panic id: ", message_apicid, rt_string_len("panic id: ")); + rt_to_string(message_apicid + rt_string_len("panic id: "), (UIntPtr) id, 10); - fb_render_string(message_apicid, y, x, panic_text); + fb_render_string(message_apicid, y, x, panic_text); - y += 10; + y += 10; - fb_render_string((message ? message : "message: panic raised, going nowhere after this!"), y, x, panic_text); + fb_render_string((message ? message : "message: panic raised, going nowhere after this!"), y, x, + panic_text); - y += 10; + y += 10; - fb_clear(); + fb_clear(); - RecoveryFactory::Recover(); - } + RecoveryFactory::Recover(); +} - Void RecoveryFactory::Recover() noexcept - { - while (YES) - { - HAL::rt_halt(); - } - } +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 << "FAILED: FILE: " << file << kendl); - (Void)(kout << "FAILED: LINE: " << line << kendl); +void ke_runtime_check(bool expr, const Char* file, const Char* line) { + if (!expr) { + (Void)(kout << "FAILED: FILE: " << file << kendl); + (Void)(kout << "FAILED: LINE: " << line << kendl); - ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed - } - } -} // namespace Kernel + ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed + } +} +} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc index 08dd6180..e8c6875d 100644 --- a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc @@ -1,86 +1,75 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: HalPagingMgr.cc - Purpose: Platform Paging Manager. + File: HalPagingMgr.cc + Purpose: Platform Paging Manager. ------------------------------------------- */ #include #include -namespace Kernel::HAL -{ - typedef UInt32 PageTableIndex; - - /// \brief Page store type. - struct NE_PAGE_STORE final - { - struct - { - PDE* fPde{nullptr}; - PTE* fPte{nullptr}; - VoidPtr fVAddr{nullptr}; - } fInternalStore; - - Bool fStoreOp{No}; // Store operation in progress. - - static NE_PAGE_STORE& The() - { - static NE_PAGE_STORE the; - return the; - } - }; - - /// \brief Retrieve the page status of a PTE. - STATIC Void mmi_page_status(PTE* pte) - { - } - - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); - - /// @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) - { - if (!virtual_address || - !flags) - return 0; - - NE_PAGE_STORE& page_store = NE_PAGE_STORE::The(); - - while (page_store.fStoreOp) - ; - - page_store.fStoreOp = Yes; - - if (page_store.fInternalStore.fVAddr == virtual_address) - { - page_store.fStoreOp = No; - return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte); - } - - return 1; - } - - /// @brief Maps flags for a specific pte. - /// @internal Internal function. - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) - { - NE_PAGE_STORE& page_store = NE_PAGE_STORE::The(); - - // Update internal store. - - page_store.fInternalStore.fPde = nullptr; - page_store.fInternalStore.fPte = pt_entry; - page_store.fInternalStore.fVAddr = virtual_address; - - page_store.fStoreOp = No; - - return 0; - } -} // namespace Kernel::HAL +namespace Kernel::HAL { +typedef UInt32 PageTableIndex; + +/// \brief Page store type. +struct NE_PAGE_STORE final { + struct { + PDE* fPde{nullptr}; + PTE* fPte{nullptr}; + VoidPtr fVAddr{nullptr}; + } fInternalStore; + + Bool fStoreOp{No}; // Store operation in progress. + + static NE_PAGE_STORE& The() { + static NE_PAGE_STORE the; + return the; + } +}; + +/// \brief Retrieve the page status of a PTE. +STATIC Void mmi_page_status(PTE* pte) {} + +STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); + +/// @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) { + if (!virtual_address || !flags) return 0; + + NE_PAGE_STORE& page_store = NE_PAGE_STORE::The(); + + while (page_store.fStoreOp); + + page_store.fStoreOp = Yes; + + if (page_store.fInternalStore.fVAddr == virtual_address) { + page_store.fStoreOp = No; + return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, + page_store.fInternalStore.fPte); + } + + return 1; +} + +/// @brief Maps flags for a specific pte. +/// @internal Internal function. +STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) { + NE_PAGE_STORE& page_store = NE_PAGE_STORE::The(); + + // Update internal store. + + page_store.fInternalStore.fPde = nullptr; + page_store.fInternalStore.fPte = pt_entry; + page_store.fInternalStore.fVAddr = virtual_address; + + page_store.fStoreOp = No; + + return 0; +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc index 538124a6..b3f1b62a 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc @@ -1,24 +1,21 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - /// @brief Wakes up thread. - /// Wakes up thread from the hang state. - Void mp_wakeup_thread(HAL::StackFrame* stack) - { - NE_UNUSED(stack); - } +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 +/// @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/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc index 84aae986..a8f0b1e1 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc @@ -1,35 +1,30 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Unimplemented function (crashes by default) - /// @param void - /***********************************************************************************/ - - EXTERN_C Void __zka_pure_call(USER_PROCESS* process) - { - if (process) - process->Crash(); - } - - /***********************************************************************************/ - /// @brief Validate user stack. - /// @param stack_ptr the frame pointer. - /***********************************************************************************/ - - EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) - { - if (!stack_ptr) - return No; - - return stack_ptr->SP != 0 && stack_ptr->BP != 0; - } -} // namespace Kernel +namespace Kernel { +/***********************************************************************************/ +/// @brief Unimplemented function (crashes by default) +/// @param void +/***********************************************************************************/ + +EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { + if (process) process->Crash(); +} + +/***********************************************************************************/ +/// @brief Validate user stack. +/// @param stack_ptr the frame pointer. +/***********************************************************************************/ + +EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) { + if (!stack_ptr) return No; + + return stack_ptr->SP != 0 && stack_ptr->BP != 0; +} +} // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/HalTimerARM64.cc b/dev/kernel/HALKit/ARM64/HalTimerARM64.cc index c9fb1617..32f64aec 100644 --- a/dev/kernel/HALKit/ARM64/HalTimerARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalTimerARM64.cc @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: HalTimer.cc - Purpose: HAL timer + File: HalTimer.cc + Purpose: HAL timer - Revision History: + Revision History: - 07/07/24: Added file (amlel) + 07/07/24: Added file (amlel) ------------------------------------------- */ diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h index 26c277db..e23c0538 100644 --- a/dev/kernel/HALKit/ARM64/Paging.h +++ b/dev/kernel/HALKit/ARM64/Paging.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,7 +8,7 @@ /** --------------------------------------------------- - * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. + * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. ------------------------------------------------------- */ @@ -16,105 +16,90 @@ #ifndef kPageMax #define kPageMax (0x200) -#endif //! kPageMax +#endif //! kPageMax #ifndef kPageAlign #define kPageAlign (0x1000) -#endif //! kPageAlign +#endif //! kPageAlign #ifndef kPageSize #define kPageSize (0x1000) -#endif // !kPageSize +#endif // !kPageSize //! short format address range #define c16KBPage 0b000 -#define c8KBPage 0b001 -#define c4KBPage 0b010 -#define c2KBPage 0b011 -#define c1KBPage 0b100 +#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 cPageMAll \ + { 0b000, 0b000 } #define cPageMToMax(M) \ - { \ - M, 0b000 \ - } + { M, 0b000 } #define cPageMaxToM(M) \ - { \ - 0b000, 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(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) -> 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 + { 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(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) -> 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(); diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 3a04bed1..38902627 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -1,93 +1,84 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once +#include #include #include #include -#include #define kCPUBackendName "ARMv8" -namespace Kernel::HAL -{ - struct PACKED Register64 final - { - UShort Limit; - UIntPtr Base; - }; - - /// @brief Memory Manager mapping flags. - enum - { - kMMFlagsPresent = 1 << 0, - kMMFlagsWr = 1 << 1, - kMMFlagsUser = 1 << 2, - kMMFlagsNX = 1 << 3, - kMMFlagsPCD = 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); - - EXTERN_C UIntPtr hal_get_phys_address(VoidPtr virtual_address); - - typedef UIntPtr Reg; - typedef Register64 Register; - - /// @note let's keep the same name as AMD64 HAL. - 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 BP{0}; - }; - - typedef StackFrame* StackFramePtr; - - inline Void rt_halt() noexcept - { - while (Yes) - { - } - } - - template - inline void hal_dma_write(UIntPtr address, DataKind value) - { - *reinterpret_cast(address) = value; - } - - template - inline DataKind hal_dma_read(UIntPtr address) - { - return *reinterpret_cast(address); - } - - inline Void hal_wfi(Void) - { - asm volatile("wfi"); - } -} // namespace Kernel::HAL +namespace Kernel::HAL { +struct PACKED Register64 final { + UShort Limit; + UIntPtr Base; +}; + +/// @brief Memory Manager mapping flags. +enum { + kMMFlagsPresent = 1 << 0, + kMMFlagsWr = 1 << 1, + kMMFlagsUser = 1 << 2, + kMMFlagsNX = 1 << 3, + kMMFlagsPCD = 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); + +EXTERN_C UIntPtr hal_get_phys_address(VoidPtr virtual_address); + +typedef UIntPtr Reg; +typedef Register64 Register; + +/// @note let's keep the same name as AMD64 HAL. +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 BP{0}; +}; + +typedef StackFrame* StackFramePtr; + +inline Void rt_halt() noexcept { + while (Yes) { + } +} + +template +inline void hal_dma_write(UIntPtr address, DataKind value) { + *reinterpret_cast(address) = value; +} + +template +inline DataKind hal_dma_read(UIntPtr address) { + return *reinterpret_cast(address); +} + +inline Void hal_wfi(Void) { + asm volatile("wfi"); +} +} // namespace Kernel::HAL inline Kernel::VoidPtr kKernelBitMpStart = nullptr; -inline Kernel::UIntPtr kKernelBitMpSize = 0UL; +inline Kernel::UIntPtr kKernelBitMpSize = 0UL; inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; diff --git a/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc b/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc index cb387e73..1cc97cba 100644 --- a/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc +++ b/dev/kernel/HALKit/ARM64/Storage/SCSI+Generic.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,5 +9,5 @@ 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}; +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 index 1529e158..e5ef7b91 100644 --- a/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc +++ b/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/HALKit/POWER/AP.h b/dev/kernel/HALKit/POWER/AP.h index 4558804b..f938d6a1 100644 --- a/dev/kernel/HALKit/POWER/AP.h +++ b/dev/kernel/HALKit/POWER/AP.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: AP.h - Purpose: POWER hardware threads. + File: AP.h + Purpose: POWER hardware threads. - Revision History: + Revision History: - 14/04/24: Added file (amlel) + 14/04/24: Added file (amlel) ------------------------------------------- */ @@ -15,27 +15,25 @@ #include -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 +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/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc index ca2153e3..eb44b72b 100644 --- a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc @@ -1,41 +1,35 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include -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; - - hal_set_pc_to_hart(reinterpret_cast(stack->R15), reinterpret_cast(stack->BP)); - } - - /// @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(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); - } -} // namespace Kernel \ No newline at end of file +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; + + hal_set_pc_to_hart(reinterpret_cast(stack->R15), + reinterpret_cast(stack->BP)); +} + +/// @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(stack->R15), + reinterpret_cast(Kernel::Detail::mp_hang_fn)); +} +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/HALKit/POWER/HalDebugOutput.cc b/dev/kernel/HALKit/POWER/HalDebugOutput.cc index 8142364c..bcc6922c 100644 --- a/dev/kernel/HALKit/POWER/HalDebugOutput.cc +++ b/dev/kernel/HALKit/POWER/HalDebugOutput.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,17 +11,14 @@ using namespace Kernel; /// @brief Writes to COM1. /// @param bytes -void ke_io_write(const Char* bytes) -{ - if (!bytes) - return; +void ke_io_write(const Char* bytes) { + if (!bytes) return; - SizeT index = 0; - SizeT len = rt_string_len(bytes, 256U); + SizeT index = 0; + SizeT len = rt_string_len(bytes, 256U); - while (index < len) - { - // TODO - ++index; - } + while (index < len) { + // TODO + ++index; + } } diff --git a/dev/kernel/HALKit/POWER/HalHardwareThread.cc b/dev/kernel/HALKit/POWER/HalHardwareThread.cc index 40bb7d8a..2c7c69ba 100644 --- a/dev/kernel/HALKit/POWER/HalHardwareThread.cc +++ b/dev/kernel/HALKit/POWER/HalHardwareThread.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/HALKit/POWER/HalVirtualMemory.cc b/dev/kernel/HALKit/POWER/HalVirtualMemory.cc index 5c20458e..07c40134 100644 --- a/dev/kernel/HALKit/POWER/HalVirtualMemory.cc +++ b/dev/kernel/HALKit/POWER/HalVirtualMemory.cc @@ -1,49 +1,46 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include /// @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); +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(); + 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; - } +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); + 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); + hal_write_tlb(mas0, mas1, mas2, mas3, mas7); - return true; + return true; } /// @brief Flush TLB -EXTERN_C void hal_flush_tlb() -{ - asm volatile("isync;tlbwe;msync;isync"); +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 index 507805c7..850b636d 100644 --- a/dev/kernel/HALKit/POWER/Processor.h +++ b/dev/kernel/HALKit/POWER/Processor.h @@ -1,8 +1,8 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - Purpose: POWER processor header. + Purpose: POWER processor header. ------------------------------------------- */ @@ -11,52 +11,50 @@ #include #include -#define rtl_nop_op() asm volatile("mr 0, 0") +#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 BP{0}; - }; - - typedef StackFrame* StackFramePtr; - - inline void rt_halt() - { - while (true) - { - NoOp(); // no oop. - } - } - - inline void rt_cli() - { - NoOp(); // no oop - } -} // namespace Kernel::HAL +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 BP{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); +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); +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/AP.h b/dev/kernel/HALKit/RISCV/AP.h index e55e3462..0e94fd97 100644 --- a/dev/kernel/HALKit/RISCV/AP.h +++ b/dev/kernel/HALKit/RISCV/AP.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: AP.h - Purpose: RISC-V hardware threads. + File: AP.h + Purpose: RISC-V hardware threads. - Revision History: + Revision History: - 30/01/24: Added file (amlel) + 30/01/24: Added file (amlel) ------------------------------------------- */ @@ -15,23 +15,21 @@ #include -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 +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/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc index 1967a649..548167a4 100644 --- a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc @@ -1,45 +1,39 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include -#include 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(stack->R15), reinterpret_cast(stack->BP)); - } - - /// @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(stack->R15), reinterpret_cast(Kernel::Detail::mp_hang_fn)); - } - -} // 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(stack->R15), + reinterpret_cast(stack->BP)); +} + +/// @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(stack->R15), + reinterpret_cast(Kernel::Detail::mp_hang_fn)); +} + +} // namespace Kernel diff --git a/dev/kernel/KernelKit/BinaryMutex.h b/dev/kernel/KernelKit/BinaryMutex.h index 660d2e71..5b7200f9 100644 --- a/dev/kernel/KernelKit/BinaryMutex.h +++ b/dev/kernel/KernelKit/BinaryMutex.h @@ -1,41 +1,39 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include -#include #include +#include +#include -namespace Kernel -{ - class USER_PROCESS; +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; +/// @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 IsLocked() const; + bool Unlock() noexcept; - public: - BOOL WaitForProcess(const Int16& sec) noexcept; + public: + BOOL WaitForProcess(const Int16& sec) noexcept; - public: - bool Lock(USER_PROCESS& process); - bool LockOrWait(USER_PROCESS& process, TimerInterface* timer); + public: + bool Lock(USER_PROCESS& process); + bool LockOrWait(USER_PROCESS& process, TimerInterface* timer); - public: - NE_COPY_DEFAULT(BinaryMutex) + public: + NE_COPY_DEFAULT(BinaryMutex) - private: - USER_PROCESS fLockingProcess; - }; -} // namespace Kernel + private: + USER_PROCESS fLockingProcess; +}; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/CodeMgr.h b/dev/kernel/KernelKit/CodeMgr.h index 47c05d2e..bb287b24 100644 --- a/dev/kernel/KernelKit/CodeMgr.h +++ b/dev/kernel/KernelKit/CodeMgr.h @@ -1,43 +1,44 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: CodeMgr.h - Purpose: Code Mgr. + File: CodeMgr.h + Purpose: Code Mgr. - Revision History: + Revision History: - 30/01/24: Added file (amlel) - 3/8/24: Add UPP struct. + 30/01/24: Added file (amlel) + 3/8/24: Add UPP struct. ------------------------------------------- */ #pragma once +#include #include #include -#include -namespace Kernel -{ - /// @brief Main process entrypoint. - typedef void (*rtl_main_kind)(SizeT argc, Char** argv, Char** envp, SizeT envp_len); - - /// @brief C++ Constructor entrypoint. - typedef void (*rtl_ctor_kind)(void); - - /// @brief C++ Destructor entrypoint. - typedef void (*rtl_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. - ProcessID rtl_create_kernel_process(rtl_main_kind main, const Char* process_name) 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 +namespace Kernel { +/// @brief Main process entrypoint. +typedef void (*rtl_main_kind)(SizeT argc, Char** argv, Char** envp, SizeT envp_len); + +/// @brief C++ Constructor entrypoint. +typedef void (*rtl_ctor_kind)(void); + +/// @brief C++ Destructor entrypoint. +typedef void (*rtl_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. +ProcessID rtl_create_kernel_process(rtl_main_kind main, const Char* process_name) 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 index bd493140..3b581ffe 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,153 +9,133 @@ #include #include -namespace Kernel -{ - class USER_PROCESS; - class KERNEL_PROCESS; - class UserProcessTeam; - - /***********************************************************************************/ - /// @brief Subsystem enum type. - /***********************************************************************************/ - - enum class ProcessSubsystem : Int32 - { - kProcessSubsystemSecurity = 100, - kProcessSubsystemApplication, - kProcessSubsystemService, - kProcessSubsystemDriver, - kProcessSubsystemInvalid = 256U, - kProcessSubsystemCount = 4, - }; - - typedef UInt64 PTime; - - /***********************************************************************************/ - //! @brief Local Process identifier. - /***********************************************************************************/ - typedef Int64 ProcessID; - - /***********************************************************************************/ - //! @brief Local Process status enum. - /***********************************************************************************/ - enum class ProcessStatusKind : Int32 - { - kInvalid, - kStarting, - kRunning, - kKilled, - kFrozen, - kFinished, - kCount, - }; - - /***********************************************************************************/ - //! @brief Affinity is the amount of nano-seconds this process is going to run. - /***********************************************************************************/ - enum class AffinityKind : Int32 - { - kRealTime = 500, - kVeryHigh = 250, - kHigh = 200, - kStandard = 1000, - kLowUsage = 1500, - kVeryLowUsage = 2000, - }; - - /***********************************************************************************/ - //! Operators for AffinityKind - /***********************************************************************************/ - - inline bool operator<(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int < rhs_int; - } - - inline bool operator>(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int > rhs_int; - } - - inline bool operator<=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int <= rhs_int; - } - - inline bool operator>=(AffinityKind lhs, AffinityKind rhs) - { - Int32 lhs_int = static_cast(lhs); - Int32 rhs_int = static_cast(rhs); - - return lhs_int >= rhs_int; - } - - using ProcessTime = UInt64; - using PID = Int64; - - /***********************************************************************************/ - /// @note For User manager, tells where we run the code. - /***********************************************************************************/ - enum class ProcessLevelRing : Int32 - { - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 5, - }; - - /***********************************************************************************/ - /// @brief Helper type to describe a code image. - /***********************************************************************************/ - using ImagePtr = VoidPtr; - - /***********************************************************************************/ - /// @brief Helper class to contain a process's image and blob. - /***********************************************************************************/ - struct PROCESS_IMAGE final - { - explicit PROCESS_IMAGE() = default; - - ImagePtr fCode; - ImagePtr fBlob; - - Bool HasCode() - { - return this->fCode != nullptr; - } - - Bool HasImage() - { - return this->fBlob != nullptr; - } - - ErrorOr Leak() - { - if (this->fCode) - { - return ErrorOr{this->fCode}; - } - - return ErrorOr{kErrorInvalidData}; - } - - ErrorOr LeakBlob() - { - if (this->fBlob) - { - return ErrorOr{this->fBlob}; - } - - return ErrorOr{kErrorInvalidData}; - } - }; -} // namespace Kernel +namespace Kernel { +class USER_PROCESS; +class KERNEL_PROCESS; +class UserProcessTeam; + +/***********************************************************************************/ +/// @brief Subsystem enum type. +/***********************************************************************************/ + +enum class ProcessSubsystem : Int32 { + kProcessSubsystemSecurity = 100, + kProcessSubsystemApplication, + kProcessSubsystemService, + kProcessSubsystemDriver, + kProcessSubsystemInvalid = 256U, + kProcessSubsystemCount = 4, +}; + +typedef UInt64 PTime; + +/***********************************************************************************/ +//! @brief Local Process identifier. +/***********************************************************************************/ +typedef Int64 ProcessID; + +/***********************************************************************************/ +//! @brief Local Process status enum. +/***********************************************************************************/ +enum class ProcessStatusKind : Int32 { + kInvalid, + kStarting, + kRunning, + kKilled, + kFrozen, + kFinished, + kCount, +}; + +/***********************************************************************************/ +//! @brief Affinity is the amount of nano-seconds this process is going to run. +/***********************************************************************************/ +enum class AffinityKind : Int32 { + kRealTime = 500, + kVeryHigh = 250, + kHigh = 200, + kStandard = 1000, + kLowUsage = 1500, + kVeryLowUsage = 2000, +}; + +/***********************************************************************************/ +//! Operators for AffinityKind +/***********************************************************************************/ + +inline bool operator<(AffinityKind lhs, AffinityKind rhs) { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int < rhs_int; +} + +inline bool operator>(AffinityKind lhs, AffinityKind rhs) { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int > rhs_int; +} + +inline bool operator<=(AffinityKind lhs, AffinityKind rhs) { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int <= rhs_int; +} + +inline bool operator>=(AffinityKind lhs, AffinityKind rhs) { + Int32 lhs_int = static_cast(lhs); + Int32 rhs_int = static_cast(rhs); + + return lhs_int >= rhs_int; +} + +using ProcessTime = UInt64; +using PID = Int64; + +/***********************************************************************************/ +/// @note For User manager, tells where we run the code. +/***********************************************************************************/ +enum class ProcessLevelRing : Int32 { + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 5, +}; + +/***********************************************************************************/ +/// @brief Helper type to describe a code image. +/***********************************************************************************/ +using ImagePtr = VoidPtr; + +/***********************************************************************************/ +/// @brief Helper class to contain a process's image and blob. +/***********************************************************************************/ +struct PROCESS_IMAGE final { + explicit PROCESS_IMAGE() = default; + + ImagePtr fCode; + ImagePtr fBlob; + + Bool HasCode() { return this->fCode != nullptr; } + + Bool HasImage() { return this->fBlob != nullptr; } + + ErrorOr Leak() { + if (this->fCode) { + return ErrorOr{this->fCode}; + } + + return ErrorOr{kErrorInvalidData}; + } + + ErrorOr LeakBlob() { + if (this->fBlob) { + return ErrorOr{this->fBlob}; + } + + return ErrorOr{kErrorInvalidData}; + } +}; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/DebugOutput.h b/dev/kernel/KernelKit/DebugOutput.h index 6d740138..7110a941 100644 --- a/dev/kernel/KernelKit/DebugOutput.h +++ b/dev/kernel/KernelKit/DebugOutput.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include #include #include @@ -19,183 +19,159 @@ #define kDebugMag3 'G' #define kDebugSourceFile 23 -#define kDebugLine 33 -#define kDebugTeam 43 -#define kDebugEOP 49 - -namespace Kernel -{ - class TerminalDevice; - class DTraceDevice; - - 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 - { - public: - TerminalDevice(void (*print)(IDeviceObject*, const Char*), void (*gets)(IDeviceObject*, const Char*)) - : IDeviceObject(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; - }; - - inline TerminalDevice end_line() - { - TerminalDevice self = TerminalDevice::The(); - - self.operator<<("\r"); - return self; - } - - inline TerminalDevice carriage_return() - { - TerminalDevice self = TerminalDevice::The(); - - self.operator<<("\r"); - return self; - } - - inline TerminalDevice tabulate() - { - TerminalDevice self = TerminalDevice::The(); +#define kDebugLine 33 +#define kDebugTeam 43 +#define kDebugEOP 49 + +namespace Kernel { +class TerminalDevice; +class DTraceDevice; + +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 { + public: + TerminalDevice(void (*print)(IDeviceObject*, const Char*), + void (*gets)(IDeviceObject*, const Char*)) + : IDeviceObject(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; +}; + +inline TerminalDevice end_line() { + TerminalDevice self = TerminalDevice::The(); + + self.operator<<("\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; - } + self.operator<<("\t"); + return self; +} - /// @brief emulate a terminal bell, like the VT100 does. - inline TerminalDevice bell() - { - TerminalDevice self = TerminalDevice::The(); +/// @brief emulate a terminal bell, like the VT100 does. +inline TerminalDevice bell() { + TerminalDevice self = TerminalDevice::The(); - self.operator<<("\a"); - return self; - } + 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; +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); + if (y) _write_number(y, term); - /* fail if the number is not base-10 */ - if (h > 10) - { - _write_number('?', term); - return term; - } + /* fail if the number is not base-10 */ + if (h > 10) { + _write_number('?', term); + return term; + } - if (y == ~0UL) - y = -y; + if (y == ~0UL) y = -y; - const Char kNumbers[11] = "0123456789"; + const Char kNumbers[11] = "0123456789"; - Char buf[2]; - buf[0] = kNumbers[h]; - buf[1] = 0; + Char buf[2]; + buf[0] = kNumbers[h]; + buf[1] = 0; - term.operator<<(buf); - return term; - } + 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; + 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); + 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; - } + /* fail if the hex number is not base-16 */ + if (h > 16) { + _write_number_hex('?', term); + return term; + } - if (y == ~0UL) - y = -y; + if (y == ~0UL) y = -y; - const Char kNumbers[17] = "0123456789ABCDEF"; + const Char kNumbers[17] = "0123456789ABCDEF"; - Char buf[2]; - buf[0] = kNumbers[h]; - buf[1] = 0; + Char buf[2]; + buf[0] = kNumbers[h]; + buf[1] = 0; - term.operator<<(buf); - return term; - } - } // namespace Detail + term.operator<<(buf); + return term; + } +} // namespace Detail - inline TerminalDevice hex_number(const Long& x) - { - TerminalDevice self = TerminalDevice::The(); +inline TerminalDevice hex_number(const Long& x) { + TerminalDevice self = TerminalDevice::The(); - Detail::_write_number_hex(x, self); - self.operator<<("h"); + Detail::_write_number_hex(x, self); + self.operator<<("h"); - return self; - } + return self; +} - inline TerminalDevice number(const Long& x) - { - TerminalDevice self = TerminalDevice::The(); +inline TerminalDevice number(const Long& x) { + TerminalDevice self = TerminalDevice::The(); - Detail::_write_number(x, self); + Detail::_write_number(x, self); - return self; - } + return self; +} - inline TerminalDevice get_console_in(Char* buf) - { - TerminalDevice self = TerminalDevice::The(); +inline TerminalDevice get_console_in(Char* buf) { + TerminalDevice self = TerminalDevice::The(); - self >> buf; + self >> buf; - return self; - } + return self; +} - inline constexpr SizeT kDebugTypeLen = 256U; +inline constexpr SizeT kDebugTypeLen = 256U; - typedef Char rt_debug_type[kDebugTypeLen]; +typedef Char rt_debug_type[kDebugTypeLen]; - class DebuggerPortHeader final - { - public: - Int16 fPort; - Int16 fPortBsy; - }; +class DebuggerPortHeader final { + public: + Int16 fPort; + Int16 fPortBsy; +}; - inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) - { - src = number(num); - return src; - } -} // namespace Kernel +inline TerminalDevice& operator<<(TerminalDevice& src, const Long& num) { + src = number(num); + return src; +} +} // namespace Kernel #ifdef kout #undef kout -#endif // ifdef kout +#endif // ifdef kout #define kout TerminalDevice::The() diff --git a/dev/kernel/KernelKit/Defines.h b/dev/kernel/KernelKit/Defines.h index 1356f340..2c170940 100644 --- a/dev/kernel/KernelKit/Defines.h +++ b/dev/kernel/KernelKit/Defines.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,7 +8,7 @@ #include -#define KERNELKIT_VERSION "0.0.1" +#define KERNELKIT_VERSION "0.0.1" #define KERNELKIT_VERSION_BCD 0x0001 class UserProcessScheduler; diff --git a/dev/kernel/KernelKit/DeviceMgr.h b/dev/kernel/KernelKit/DeviceMgr.h index 9cfc54dd..8da52699 100644 --- a/dev/kernel/KernelKit/DeviceMgr.h +++ b/dev/kernel/KernelKit/DeviceMgr.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,8 +8,8 @@ Revision History: - 31/01/24: Add kDeviceCnt (amlel) - 15/11/24: Add NE_DEVICE macro, to inherit from device object. + 31/01/24: Add kDeviceCnt (amlel) + 15/11/24: Add NE_DEVICE macro, to inherit from device object. ------------------------------------------- */ @@ -28,114 +28,93 @@ // Last Rev: Wed, Apr 3, 2024 9:09:41 AM -namespace Kernel -{ - template - class IDeviceObject; - - /***********************************************************************************/ - /// @brief Device contract interface, represents an HW device. - /***********************************************************************************/ - template - class IDeviceObject - { - public: - explicit IDeviceObject(void (*Out)(IDeviceObject*, T), void (*In)(IDeviceObject*, T)) - : fOut(Out), fIn(In) - { - } - - virtual ~IDeviceObject() = default; - - public: - IDeviceObject& operator=(const IDeviceObject&) = default; - IDeviceObject(const IDeviceObject&) = default; - - public: - virtual IDeviceObject& operator<<(T Data) - { - fOut(this, Data); - return *this; - } - - virtual IDeviceObject& operator>>(T Data) - { - fIn(this, Data); - return *this; - } - - virtual const char* Name() const - { - return "/dev/null"; - } - - operator bool() - { - return fOut && fIn; - } - - Bool operator!() - { - return !fOut || !fIn; - } - - protected: - Void (*fOut)(IDeviceObject*, T Data) = {nullptr}; - Void (*fIn)(IDeviceObject*, T Data) = {nullptr}; - }; - - /// - /// @brief Input Output abstract class. - /// Used mainly to communicate between OS to hardware. - /// - template - 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&) = default; - IOBuf(const IOBuf&) = default; - - ~IOBuf() = default; - - public: - template - R operator->() const - { - return fData; - } - - template - R& operator[](Size index) const - { - return fData[index]; - } - - private: - T fData; - }; - - ///! @brief Device enum types. - enum - { - kDeviceTypeIDE, - kDeviceTypeEthernet, - kDeviceTypeWiFi, - kDeviceTypeFW, - kDeviceTypeBT, - kDeviceTypeRS232, - kDeviceTypeSCSI, - kDeviceTypeAHCI, - kDeviceTypeMBCI, - kDeviceTypeATA, - kDeviceTypeUSB, - kDeviceTypeMediaCtrl, // MM controller - kDeviceTypeCount, - }; -} // namespace Kernel +namespace Kernel { +template +class IDeviceObject; + +/***********************************************************************************/ +/// @brief Device contract interface, represents an HW device. +/***********************************************************************************/ +template +class IDeviceObject { + public: + explicit IDeviceObject(void (*Out)(IDeviceObject*, T), void (*In)(IDeviceObject*, T)) + : fOut(Out), fIn(In) {} + + virtual ~IDeviceObject() = default; + + public: + IDeviceObject& operator=(const IDeviceObject&) = default; + IDeviceObject(const IDeviceObject&) = default; + + public: + virtual IDeviceObject& operator<<(T Data) { + fOut(this, Data); + return *this; + } + + virtual IDeviceObject& operator>>(T Data) { + fIn(this, Data); + return *this; + } + + virtual const char* Name() const { return "/dev/null"; } + + operator bool() { return fOut && fIn; } + + Bool operator!() { return !fOut || !fIn; } + + protected: + Void (*fOut)(IDeviceObject*, T Data) = {nullptr}; + Void (*fIn)(IDeviceObject*, T Data) = {nullptr}; +}; + +/// +/// @brief Input Output abstract class. +/// Used mainly to communicate between OS to hardware. +/// +template +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&) = default; + IOBuf(const IOBuf&) = default; + + ~IOBuf() = default; + + public: + template + R operator->() const { + return fData; + } + + template + R& operator[](Size index) const { + return fData[index]; + } + + private: + T fData; +}; + +///! @brief Device enum types. +enum { + kDeviceTypeIDE, + kDeviceTypeEthernet, + kDeviceTypeWiFi, + kDeviceTypeFW, + kDeviceTypeBT, + kDeviceTypeRS232, + kDeviceTypeSCSI, + kDeviceTypeAHCI, + kDeviceTypeMBCI, + kDeviceTypeATA, + kDeviceTypeUSB, + kDeviceTypeMediaCtrl, // MM controller + kDeviceTypeCount, +}; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h index 9dc8162b..e0bed8f5 100644 --- a/dev/kernel/KernelKit/DriveMgr.h +++ b/dev/kernel/KernelKit/DriveMgr.h @@ -1,191 +1,170 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef INC_DRIVE_MANAGER_H #define INC_DRIVE_MANAGER_H -#include #include #include #include #include +#include #include #include #include -#define kDriveMaxCount (4U) -#define kDriveSectorSz (512U) +#define kDriveMaxCount (4U) +#define kDriveSectorSz (512U) #define kDriveInvalidID (-1) -#define kDriveNameLen (32) +#define kDriveNameLen (32) #define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ)) -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]; // /System, /boot, //./Devices/USB... - Int32 fKind; // fMassStorage, fFloppy, fOpticalDrive. - Int32 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{512}; - - Void (*fInput)(DrivePacket packet); - Void (*fOutput)(DrivePacket packet); - Void (*fVerify)(DrivePacket packet); - Void (*fInit)(DrivePacket packet); - const Char* (*fProtocol)(Void); - }; - - ///! 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 MountpointInterface final - { - public: - explicit MountpointInterface() = default; - ~MountpointInterface() = default; - - NE_COPY_DEFAULT(MountpointInterface) - - 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. - /// @return the new drive as a trait. - DriveTrait io_construct_main_drive(Void) noexcept; - - namespace Detect - { - Void io_detect_drive(DriveTrait& trait); - } - - /// @brief Read from newfs disk. - /// @param Mnt mounted interface. - /// @param DrvTrait drive info - /// @param DrvIndex drive index. - /// @return - Int32 fs_ifs_read(MountpointInterface* 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(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex); -} // namespace Kernel +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]; // /System, /boot, //./Devices/USB... + Int32 fKind; // fMassStorage, fFloppy, fOpticalDrive. + Int32 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{512}; + + Void (*fInput)(DrivePacket packet); + Void (*fOutput)(DrivePacket packet); + Void (*fVerify)(DrivePacket packet); + Void (*fInit)(DrivePacket packet); + const Char* (*fProtocol)(Void); +}; + +///! 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 MountpointInterface final { + public: + explicit MountpointInterface() = default; + ~MountpointInterface() = default; + + NE_COPY_DEFAULT(MountpointInterface) + + 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. +/// @return the new drive as a trait. +DriveTrait io_construct_main_drive(Void) noexcept; + +namespace Detect { + Void io_detect_drive(DriveTrait& trait); +} + +/// @brief Read from newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_ifs_read(MountpointInterface* 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(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex); +} // namespace Kernel #endif /* ifndef INC_DRIVE_MANAGER_H */ diff --git a/dev/kernel/KernelKit/FileMgr.h b/dev/kernel/KernelKit/FileMgr.h index f4acdae9..465d0afb 100644 --- a/dev/kernel/KernelKit/FileMgr.h +++ b/dev/kernel/KernelKit/FileMgr.h @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss Labs, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss Labs, all rights reserved. - File: FileMgr.h - Purpose: Kernel file manager. + File: FileMgr.h + Purpose: Kernel file manager. ------------------------------------------- */ @@ -11,10 +11,10 @@ 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. + 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. ------------------------------------------- */ @@ -26,21 +26,21 @@ #include #include -#include -#include #include -#include -#include +#include #include +#include #include +#include +#include /// @brief Filesystem manager, abstraction over mounted filesystem. /// Works like the VFS or IFS. -#define kRestrictR "r" -#define kRestrictRB "rb" -#define kRestrictW "w" -#define kRestrictWR "rw" +#define kRestrictR "r" +#define kRestrictRB "rb" +#define kRestrictW "w" +#define kRestrictWR "rw" #define kRestrictWRB "rwb" #define kRestrictMax (5U) @@ -48,343 +48,303 @@ #define node_cast(PTR) reinterpret_cast(PTR) /** - @note Refer to first enum. + @note Refer to first enum. */ -#define kFileOpsCount (4U) +#define kFileOpsCount (4U) #define kFileMimeGeneric "ne-application-kind/all" /** @brief invalid position. (n-pos) */ #define kNPos (SizeT)(-1); -namespace Kernel -{ - enum - { - kFileWriteAll = 100, - kFileReadAll = 101, - kFileReadChunk = 102, - kFileWriteChunk = 103, - kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, - // file flags - kFileFlagRsrc = 104, - kFileFlagData = 105, - }; - - typedef VoidPtr NodePtr; - - /** - @brief Filesystem Mgr Interface class - @brief Used to provide common I/O for a specific filesystem. +namespace Kernel { +enum { + kFileWriteAll = 100, + kFileReadAll = 101, + kFileReadChunk = 102, + kFileWriteChunk = 103, + kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, + // file flags + kFileFlagRsrc = 104, + kFileFlagData = 105, +}; + +typedef VoidPtr NodePtr; + +/** +@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; - }; +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__ - - /** - * FileStream class. - * @tparam Encoding file encoding (char, wchar_t...) - * @tparam FSClass Filesystem contract who takes care of it. - */ - template - class FileStream final - { - public: - explicit FileStream(const Encoding* path, const Encoding* restrict_type); - ~FileStream(); - - public: - FileStream& operator=(const FileStream&); - FileStream(const FileStream&); - - public: - ErrorOr Write(SizeT offset, const VoidPtr data, SizeT len) noexcept - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictWrite && - this->fFileRestrict != kFileMgrRestrictWriteBinary) - return ErrorOr(kErrorInvalidData); - - if (data == nullptr) - return ErrorOr(kErrorInvalidData); - - auto man = FSClass::GetMounted(); - - if (man) - { - man->Write(offset, fFile, data, len); - return ErrorOr(0); - } - - return ErrorOr(kErrorInvalidData); - } - - ErrorOr 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(kErrorInvalidData); - - if (data == nullptr) - return ErrorOr(kErrorInvalidData); - - auto man = FSClass::GetMounted(); - - if (man) - { - man->Write(name, fFile, data, 0, len); - return ErrorOr(0); - } - - return ErrorOr(kErrorInvalidData); - } - - VoidPtr Read(const Char* name, SizeT sz) noexcept - { - if (this->fFileRestrict != kFileMgrRestrictReadWrite && - this->fFileRestrict != kFileMgrRestrictReadWriteBinary && - this->fFileRestrict != kFileMgrRestrictRead && - this->fFileRestrict != kFileMgrRestrictReadBinary) - return nullptr; - - NE_UNUSED(sz); - - auto man = FSClass::GetMounted(); - - if (man) - { - VoidPtr ret = man->Read(name, fFile, kFileReadAll, 0); - 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(fMime); - } - - enum - { - kFileMgrRestrictRead, - kFileMgrRestrictReadBinary, - kFileMgrRestrictWrite, - kFileMgrRestrictWriteBinary, - kFileMgrRestrictReadWrite, - kFileMgrRestrictReadWriteBinary, - }; - - private: - NodePtr fFile{nullptr}; - Int32 fFileRestrict{kFileMgrRestrictReadBinary}; - const Char* fMime{kFileMimeGeneric}; - }; - - using FileStreamUTF8 = FileStream; - using FileStreamUTF16 = FileStream; - - typedef UInt64 CursorType; - - inline static const auto kRestrictStrLen = 8U; - - /// @brief restrict information about the file descriptor. - struct FileRestrictKind final - { - Char fRestrict[kRestrictStrLen]; - Int32 fMappedTo; - }; - - /// @brief constructor - template - inline FileStream::FileStream(const Encoding* path, - const Encoding* restrict_type) - : fFile(Class::GetMounted()->Open(path, restrict_type)) - { - SizeT kRestrictCount = kRestrictMax; - const FileRestrictKind 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 << "new file: " << path << ".\r"; - } - - /// @brief destructor of the file stream. - template - inline FileStream::~FileStream() - { - mm_delete_heap(fFile); - } -} // namespace Kernel - -#endif // ifndef INC_FILEMGR_H +/** + * @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__ + +/** + * FileStream class. + * @tparam Encoding file encoding (char, wchar_t...) + * @tparam FSClass Filesystem contract who takes care of it. + */ +template +class FileStream final { + public: + explicit FileStream(const Encoding* path, const Encoding* restrict_type); + ~FileStream(); + + public: + FileStream& operator=(const FileStream&); + FileStream(const FileStream&); + + public: + ErrorOr Write(SizeT offset, const VoidPtr data, SizeT len) noexcept { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictWrite && + this->fFileRestrict != kFileMgrRestrictWriteBinary) + return ErrorOr(kErrorInvalidData); + + if (data == nullptr) return ErrorOr(kErrorInvalidData); + + auto man = FSClass::GetMounted(); + + if (man) { + man->Write(offset, fFile, data, len); + return ErrorOr(0); + } + + return ErrorOr(kErrorInvalidData); + } + + ErrorOr 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(kErrorInvalidData); + + if (data == nullptr) return ErrorOr(kErrorInvalidData); + + auto man = FSClass::GetMounted(); + + if (man) { + man->Write(name, fFile, data, 0, len); + return ErrorOr(0); + } + + return ErrorOr(kErrorInvalidData); + } + + VoidPtr Read(const Char* name, SizeT sz) noexcept { + if (this->fFileRestrict != kFileMgrRestrictReadWrite && + this->fFileRestrict != kFileMgrRestrictReadWriteBinary && + this->fFileRestrict != kFileMgrRestrictRead && + this->fFileRestrict != kFileMgrRestrictReadBinary) + return nullptr; + + NE_UNUSED(sz); + + auto man = FSClass::GetMounted(); + + if (man) { + VoidPtr ret = man->Read(name, fFile, kFileReadAll, 0); + 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(fMime); } + + enum { + kFileMgrRestrictRead, + kFileMgrRestrictReadBinary, + kFileMgrRestrictWrite, + kFileMgrRestrictWriteBinary, + kFileMgrRestrictReadWrite, + kFileMgrRestrictReadWriteBinary, + }; + + private: + NodePtr fFile{nullptr}; + Int32 fFileRestrict{kFileMgrRestrictReadBinary}; + const Char* fMime{kFileMimeGeneric}; +}; + +using FileStreamUTF8 = FileStream; +using FileStreamUTF16 = FileStream; + +typedef UInt64 CursorType; + +inline static const auto kRestrictStrLen = 8U; + +/// @brief restrict information about the file descriptor. +struct FileRestrictKind final { + Char fRestrict[kRestrictStrLen]; + Int32 fMappedTo; +}; + +/// @brief constructor +template +inline FileStream::FileStream(const Encoding* path, const Encoding* restrict_type) + : fFile(Class::GetMounted()->Open(path, restrict_type)) { + SizeT kRestrictCount = kRestrictMax; + const FileRestrictKind 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 << "new file: " << path << ".\r"; +} + +/// @brief destructor of the file stream. +template +inline FileStream::~FileStream() { + mm_delete_heap(fFile); +} +} // namespace Kernel + +#endif // ifndef INC_FILEMGR_H diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index 4d2ebc73..4f7746ef 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -16,134 +16,121 @@ #define kMaxAPInsideSched (8U) -namespace Kernel -{ - class HardwareThread; - class HardwareThreadScheduler; - - using ThreadID = UInt32; - - enum ThreadKind - { - kAPInvalid, - kAPSystemReserved, // 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(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid); - BOOL IsWakeup() noexcept; - - public: - HAL::StackFramePtr StackFrame() noexcept; - const ThreadKind& Kind() noexcept; - bool IsBusy() noexcept; - const ThreadID& ID() noexcept; - - private: - HAL::StackFramePtr fStack{nullptr}; - ThreadKind fKind{ThreadKind::kAPStandard}; - ThreadID fID{0}; - ThreadID fPID{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 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 fThreadList; - ThreadID fCurrentThread{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__ +namespace Kernel { +class HardwareThread; +class HardwareThreadScheduler; + +using ThreadID = UInt32; + +enum ThreadKind { + kAPInvalid, + kAPSystemReserved, // 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(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid); + BOOL IsWakeup() noexcept; + + public: + HAL::StackFramePtr StackFrame() noexcept; + const ThreadKind& Kind() noexcept; + bool IsBusy() noexcept; + const ThreadID& ID() noexcept; + + private: + HAL::StackFramePtr fStack{nullptr}; + ThreadKind fKind{ThreadKind::kAPStandard}; + ThreadID fID{0}; + ThreadID fPID{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 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 fThreadList; + ThreadID fCurrentThread{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/IDylibObject.h b/dev/kernel/KernelKit/IDylibObject.h index 52c55bf5..7a7cd913 100644 --- a/dev/kernel/KernelKit/IDylibObject.h +++ b/dev/kernel/KernelKit/IDylibObject.h @@ -9,40 +9,34 @@ #pragma once -#include #include +#include #define NE_DYLIB_OBJECT : public IDylibObject -namespace Kernel -{ - /// @brief Dylib class object. A handle to a shared library. - class IDylibObject - { - public: - explicit IDylibObject() = default; - virtual ~IDylibObject() = default; - - struct DLL_TRAITS final - { - VoidPtr ImageObject{nullptr}; - VoidPtr ImageEntrypointOffset{nullptr}; - - Bool IsValid() - { - return ImageObject && ImageEntrypointOffset; - } - }; - - NE_COPY_DEFAULT(IDylibObject) - - virtual DLL_TRAITS** GetAddressOf() = 0; - virtual DLL_TRAITS* Get() = 0; - - virtual Void Mount(DLL_TRAITS* to_mount) = 0; - virtual Void Unmount() = 0; - }; - - /// @brief Pure implementation, missing method/function handler. - EXTERN_C void __zka_pure_call(void); -} // namespace Kernel +namespace Kernel { +/// @brief Dylib class object. A handle to a shared library. +class IDylibObject { + public: + explicit IDylibObject() = default; + virtual ~IDylibObject() = default; + + struct DLL_TRAITS final { + VoidPtr ImageObject{nullptr}; + VoidPtr ImageEntrypointOffset{nullptr}; + + Bool IsValid() { return ImageObject && ImageEntrypointOffset; } + }; + + NE_COPY_DEFAULT(IDylibObject) + + virtual DLL_TRAITS** GetAddressOf() = 0; + virtual DLL_TRAITS* Get() = 0; + + virtual Void Mount(DLL_TRAITS* to_mount) = 0; + virtual Void Unmount() = 0; +}; + +/// @brief Pure implementation, missing method/function handler. +EXTERN_C void __zka_pure_call(void); +} // namespace Kernel diff --git a/dev/kernel/KernelKit/IPEFDylibObject.h b/dev/kernel/KernelKit/IPEFDylibObject.h index a708fb6c..4031bd85 100644 --- a/dev/kernel/KernelKit/IPEFDylibObject.h +++ b/dev/kernel/KernelKit/IPEFDylibObject.h @@ -10,97 +10,77 @@ #ifndef __KERNELKIT_SHARED_OBJECT_H__ #define __KERNELKIT_SHARED_OBJECT_H__ +#include #include -#include #include #include -#include +#include + +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: + DLL_TRAITS* fMounted{nullptr}; + + public: + DLL_TRAITS** GetAddressOf() { return &fMounted; } + + DLL_TRAITS* Get() { return fMounted; } + + public: + void Mount(DLL_TRAITS* to_mount) { + 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() { + if (fMounted) fMounted = nullptr; + }; + + template + SymbolType Load(const Char* symbol_name, SizeT len, Int32 kind) { + if (symbol_name == nullptr || *symbol_name == 0) return nullptr; + if (len > kPathLen || len < 1) return nullptr; + + auto ret = reinterpret_cast(fLoader->FindSymbol(symbol_name, kind)); + + if (!ret) { + if (kind == kPefCode) return (VoidPtr) &__zka_pure_call; + + return nullptr; + } + + return ret; + } + + private: + PEFLoader* fLoader{nullptr}; +}; + +typedef IPEFDylibObject* IDylibRef; -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: - DLL_TRAITS* fMounted{nullptr}; - - public: - DLL_TRAITS** GetAddressOf() - { - return &fMounted; - } - - DLL_TRAITS* Get() - { - return fMounted; - } - - public: - void Mount(DLL_TRAITS* to_mount) - { - 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() - { - if (fMounted) - fMounted = nullptr; - }; - - template - SymbolType Load(const Char* symbol_name, SizeT len, Int32 kind) - { - if (symbol_name == nullptr || *symbol_name == 0) - return nullptr; - if (len > kPathLen || len < 1) - return nullptr; - - auto ret = - reinterpret_cast(fLoader->FindSymbol(symbol_name, kind)); - - if (!ret) - { - if (kind == kPefCode) - return (VoidPtr)&__zka_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 +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_SHARED_OBJECT_H__ */ diff --git a/dev/kernel/KernelKit/KPC.h b/dev/kernel/KernelKit/KPC.h index 67bbea81..e195d5ad 100644 --- a/dev/kernel/KernelKit/KPC.h +++ b/dev/kernel/KernelKit/KPC.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,57 +11,60 @@ /// @file KPC.h /// @brief Kernel Procedure Code. -#define err_local_ok() (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() == Kernel::kErrorSuccess) -#define err_local_fail() (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() != Kernel::kErrorSuccess) -#define err_local_get() (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode()) +#define err_local_ok() \ + (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() == \ + Kernel::kErrorSuccess) +#define err_local_fail() \ + (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode() != \ + Kernel::kErrorSuccess) +#define err_local_get() (Kernel::UserProcessScheduler::The().CurrentProcess().Leak().GetLocalCode()) -#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess) +#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess) #define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess) -#define err_global_get() (Kernel::kErrorLocalNumber) +#define err_global_get() (Kernel::kErrorLocalNumber) -namespace Kernel -{ - typedef Int32 KPCError; +namespace Kernel { +typedef Int32 KPCError; - inline KPCError kErrorLocalNumber = 0UL; +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 kErrorUnimplemented = -1; +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 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 +/// @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/KernelProcessScheduler.h b/dev/kernel/KernelKit/KernelProcessScheduler.h index 47d61ff7..24d40a36 100644 --- a/dev/kernel/KernelKit/KernelProcessScheduler.h +++ b/dev/kernel/KernelKit/KernelProcessScheduler.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/KernelKit/LoaderInterface.h b/dev/kernel/KernelKit/LoaderInterface.h index 259b8521..42046a53 100644 --- a/dev/kernel/KernelKit/LoaderInterface.h +++ b/dev/kernel/KernelKit/LoaderInterface.h @@ -1,34 +1,32 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -#include #include #include +#include -namespace Kernel -{ - /// @brief This interface is used to make loader contracts (MSCOFF, PEF). - /// @author @Amlal-El-Mahrouss - class LoaderInterface - { - public: - explicit LoaderInterface() = default; - virtual ~LoaderInterface() = default; +namespace Kernel { +/// @brief This interface is used to make loader contracts (MSCOFF, PEF). +/// @author @Amlal-El-Mahrouss +class LoaderInterface { + public: + explicit LoaderInterface() = default; + virtual ~LoaderInterface() = default; - NE_COPY_DEFAULT(LoaderInterface) + NE_COPY_DEFAULT(LoaderInterface) - public: - virtual _Output ErrorOr GetBlob() = 0; - virtual _Output const Char* AsString() = 0; - virtual _Output const Char* MIME() = 0; - virtual _Output const Char* Path() = 0; - virtual _Output ErrorOr FindStart() = 0; - virtual _Output VoidPtr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; - }; -} // namespace Kernel + public: + virtual _Output ErrorOr GetBlob() = 0; + virtual _Output const Char* AsString() = 0; + virtual _Output const Char* MIME() = 0; + virtual _Output const Char* Path() = 0; + virtual _Output ErrorOr FindStart() = 0; + virtual _Output VoidPtr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0; +}; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/LockDelegate.h b/dev/kernel/KernelKit/LockDelegate.h index ac54d9c5..18ab0cf5 100644 --- a/dev/kernel/KernelKit/LockDelegate.h +++ b/dev/kernel/KernelKit/LockDelegate.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,63 +9,50 @@ #include #include -namespace Kernel -{ - enum - { - kLockInvalid, - kLockDone = 200, - kLockTimedOut, - 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 - 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 fLockStatus; - }; -} // namespace Kernel +namespace Kernel { +enum { + kLockInvalid, + kLockDone = 200, + kLockTimedOut, + 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 +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 fLockStatus; +}; +} // namespace Kernel diff --git a/dev/kernel/KernelKit/MSDOS.h b/dev/kernel/KernelKit/MSDOS.h index 23d582ca..a0751a6f 100644 --- a/dev/kernel/KernelKit/MSDOS.h +++ b/dev/kernel/KernelKit/MSDOS.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: MSDOS.h - Purpose: MS-DOS header for Kernel. + File: MSDOS.h + Purpose: MS-DOS header for Kernel. - Revision History: + Revision History: - 30/01/24: Added file (amlel) + 30/01/24: Added file (amlel) ------------------------------------------- */ @@ -26,27 +26,26 @@ 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; +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/MemoryMgr.h b/dev/kernel/KernelKit/MemoryMgr.h index ac11ac29..2274e24e 100644 --- a/dev/kernel/KernelKit/MemoryMgr.h +++ b/dev/kernel/KernelKit/MemoryMgr.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,77 +11,73 @@ /// @file: MemoryMgr.h /// @brief: Memory allocation support for the NeKernel. -#include #include +#include #include -namespace Kernel -{ - /// @brief Declare pointer as free. - /// @param heap_ptr the pointer. - /// @return a status code regarding the deallocation. - Int32 mm_delete_heap(VoidPtr heap_ptr); - - /// @brief Declare a new size for heap_ptr. - /// @param heap_ptr the pointer. - /// @return unsupported always returns nullptr. - VoidPtr mm_realloc_heap(VoidPtr heap_ptr, SizeT new_sz); - - /// @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_heap(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_new_heap(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_heap(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_make_flags(VoidPtr heap_ptr, UInt64 flags); - - /// @brief Gets the flags of a heap header. - /// @param heap_ptr the pointer to get. - UInt64 mm_get_flags(VoidPtr heap_ptr); - - /// @brief Allocate C++ class. - /// @param cls The class to allocate. - /// @param args The args to pass. - template - 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 - inline Void mm_delete_class(_Input _Output T** cls) - { - delete *cls; - *cls = nullptr; - } -} // namespace Kernel - -#endif // !INC_KERNEL_HEAP_H +namespace Kernel { +/// @brief Declare pointer as free. +/// @param heap_ptr the pointer. +/// @return a status code regarding the deallocation. +Int32 mm_delete_heap(VoidPtr heap_ptr); + +/// @brief Declare a new size for heap_ptr. +/// @param heap_ptr the pointer. +/// @return unsupported always returns nullptr. +VoidPtr mm_realloc_heap(VoidPtr heap_ptr, SizeT new_sz); + +/// @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_heap(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_new_heap(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_heap(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_make_flags(VoidPtr heap_ptr, UInt64 flags); + +/// @brief Gets the flags of a heap header. +/// @param heap_ptr the pointer to get. +UInt64 mm_get_flags(VoidPtr heap_ptr); + +/// @brief Allocate C++ class. +/// @param cls The class to allocate. +/// @param args The args to pass. +template +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 +inline Void mm_delete_class(_Input _Output T** cls) { + delete *cls; + *cls = nullptr; +} +} // namespace Kernel + +#endif // !INC_KERNEL_HEAP_H diff --git a/dev/kernel/KernelKit/PCI/DMA.h b/dev/kernel/KernelKit/PCI/DMA.h index b2d3cfa8..28256389 100644 --- a/dev/kernel/KernelKit/PCI/DMA.h +++ b/dev/kernel/KernelKit/PCI/DMA.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,70 +12,63 @@ #include #include -namespace Kernel -{ - enum class DmaKind - { - PCI, // 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. - Invalid, - }; - - 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 - T* operator->(); - - template - 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> Construct(OwnPtr& dma); - }; -} // namespace Kernel +namespace Kernel { +enum class DmaKind { + PCI, // 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. + Invalid, +}; + +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 + T* operator->(); + + template + 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> Construct(OwnPtr& dma); +}; +} // namespace Kernel #include diff --git a/dev/kernel/KernelKit/PCI/DMA.inl b/dev/kernel/KernelKit/PCI/DMA.inl index 89381149..4df24371 100644 --- a/dev/kernel/KernelKit/PCI/DMA.inl +++ b/dev/kernel/KernelKit/PCI/DMA.inl @@ -1,20 +1,17 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -namespace Kernel -{ - template - T* DMAWrapper::operator->() - { - return this->fAddress; - } +namespace Kernel { +template +T* DMAWrapper::operator->() { + return this->fAddress; +} - template - T* DMAWrapper::Get(UIntPtr offset) - { - return reinterpret_cast((UIntPtr)this->fAddress + offset); - } -} // namespace Kernel +template +T* DMAWrapper::Get(UIntPtr offset) { + return reinterpret_cast((UIntPtr) this->fAddress + offset); +} +} // namespace Kernel diff --git a/dev/kernel/KernelKit/PCI/Database.h b/dev/kernel/KernelKit/PCI/Database.h index e97640f7..6da653dd 100644 --- a/dev/kernel/KernelKit/PCI/Database.h +++ b/dev/kernel/KernelKit/PCI/Database.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once @@ -8,51 +8,44 @@ #include #include -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; +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==(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; } -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 index 0c434b0b..d9bb4e70 100644 --- a/dev/kernel/KernelKit/PCI/Device.h +++ b/dev/kernel/KernelKit/PCI/Device.h @@ -1,78 +1,73 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -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 - UInt Read(UInt bar) - { - static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported"); - return Read(bar, sizeof(T)); - } - - template - 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 +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 + UInt Read(UInt bar) { + static_assert(sizeof(T) <= sizeof(UInt32), "64-bit PCI addressing is unsupported"); + return Read(bar, sizeof(T)); + } + + template + 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 index b8b4df4d..4d94830c 100644 --- a/dev/kernel/KernelKit/PCI/Express.h +++ b/dev/kernel/KernelKit/PCI/Express.h @@ -1,12 +1,12 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include #define PCI_EXPRESS_BUS_COUNT (4096) diff --git a/dev/kernel/KernelKit/PCI/IO.h b/dev/kernel/KernelKit/PCI/IO.h index 78fcef76..bd5751ec 100644 --- a/dev/kernel/KernelKit/PCI/IO.h +++ b/dev/kernel/KernelKit/PCI/IO.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,65 +11,53 @@ #include #include -namespace Kernel -{ - template - class IOArray final - { - public: - IOArray() = delete; +namespace Kernel { +template +class IOArray final { + public: + IOArray() = delete; - IOArray(nullPtr) = delete; + IOArray(nullPtr) = delete; - explicit IOArray(Array& ports) - : fPorts(ports) - { - } + explicit IOArray(Array& ports) : fPorts(ports) {} - ~IOArray() - { - } + ~IOArray() {} - IOArray& operator=(const IOArray&) = default; + IOArray& operator=(const IOArray&) = default; - IOArray(const IOArray&) = default; + IOArray(const IOArray&) = default; - operator bool() - { - return !fPorts.Empty(); - } + operator bool() { return !fPorts.Empty(); } - public: - template - T In(SizeT index); + public: + template + T In(SizeT index); - template - void Out(SizeT index, T value); + template + void Out(SizeT index, T value); - private: - Array fPorts; - }; + private: + Array fPorts; +}; - inline constexpr UInt16 kMaxPorts = 16; +inline constexpr UInt16 kMaxPorts = 16; - using IOArray16 = IOArray; +using IOArray16 = IOArray; - template - inline Array make_ports(UShort base) - { - Array ports; +template +inline Array make_ports(UShort base) { + Array ports; - for (UShort i = 0; i < Sz; ++i) - { - ports[i] = base + i; - } + for (UShort i = 0; i < Sz; ++i) { + ports[i] = base + i; + } - return ports; - } -} // namespace Kernel + return ports; +} +} // namespace Kernel #ifdef __x86_64__ #include #else #error Please provide platform specific code for the I/O -#endif // ifdef __x86_64__ +#endif // ifdef __x86_64__ diff --git a/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl b/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl index 57539e7e..842062e3 100644 --- a/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl +++ b/dev/kernel/KernelKit/PCI/IOArray+AMD64.inl @@ -1,54 +1,49 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: IO-Impl-AMD64.h - Purpose: I/O for AMD64. + File: IO-Impl-AMD64.h + Purpose: I/O for AMD64. - Revision History: + Revision History: - 30/01/24: Add file. (amlel) - 02/02/24: Update I/O routines. (amlel) + 30/01/24: Add file. (amlel) + 02/02/24: Update I/O routines. (amlel) ------------------------------------------- */ -namespace Kernel -{ - template - template - T IOArray::In(SizeT index) - { - switch (sizeof(T)) - { +namespace Kernel { +template +template +T IOArray::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()); + 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; - } - } + default: + return 0xFFFF; + } +} - template - template - void IOArray::Out(SizeT index, T value) - { - switch (sizeof(T)) - { +template +template +void IOArray::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); + 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 + 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 index 8b91f85f..10924bc8 100644 --- a/dev/kernel/KernelKit/PCI/Iterator.h +++ b/dev/kernel/KernelKit/PCI/Iterator.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,31 +13,29 @@ #include #include -#define NE_BUS_COUNT (256) -#define NE_DEVICE_COUNT (33) +#define NE_BUS_COUNT (256) +#define NE_DEVICE_COUNT (33) #define NE_FUNCTION_COUNT (8) -namespace Kernel::PCI -{ - class Iterator final - { - public: - Iterator() = delete; +namespace Kernel::PCI { +class Iterator final { + public: + Iterator() = delete; - public: - explicit Iterator(const Types::PciDeviceKind& deviceType); + public: + explicit Iterator(const Types::PciDeviceKind& deviceType); - Iterator& operator=(const Iterator&) = default; - Iterator(const Iterator&) = default; + Iterator& operator=(const Iterator&) = default; + Iterator(const Iterator&) = default; - ~Iterator(); + ~Iterator(); - public: - Ref operator[](const Size& sz); + public: + Ref operator[](const Size& sz); - private: - Array fDevices; - }; -} // namespace Kernel::PCI + private: + Array fDevices; +}; +} // namespace Kernel::PCI -#endif // __PCI_ITERATOR_H__ +#endif // __PCI_ITERATOR_H__ diff --git a/dev/kernel/KernelKit/PCI/PCI.h b/dev/kernel/KernelKit/PCI/PCI.h index 02b08864..7b30d455 100644 --- a/dev/kernel/KernelKit/PCI/PCI.h +++ b/dev/kernel/KernelKit/PCI/PCI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,51 +9,46 @@ #include #define kPCIConfigAddressPort (0xCF8) -#define kPCIConfigDataPort (0xCFC) +#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 +#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 index e2184918..b961e901 100644 --- a/dev/kernel/KernelKit/PE.h +++ b/dev/kernel/KernelKit/PE.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: PE.h - Purpose: Portable Executable for Kernel. + File: PE.h + Purpose: Portable Executable for Kernel. - Revision History: + Revision History: - 30/01/24: Added file (amlel) + 30/01/24: Added file (amlel) ------------------------------------------- */ @@ -24,117 +24,108 @@ #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; +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::UInt32 BaseOfData; - Kernel::UInt32 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; +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::UInt32 BaseOfData; + Kernel::UInt32 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; +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, +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 +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; +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; +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; +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, +enum { + kUserSection = 0x00000020, + kPEResourceId = 0xFFaadd00, }; #endif /* ifndef __KERNELKIT_INC_PE_H__ */ diff --git a/dev/kernel/KernelKit/PECodeMgr.h b/dev/kernel/KernelKit/PECodeMgr.h index fdbd1032..860f3426 100644 --- a/dev/kernel/KernelKit/PECodeMgr.h +++ b/dev/kernel/KernelKit/PECodeMgr.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: PECodeMgr.h - Purpose: PE32+ Code Mgr and Dylib mgr. + File: PECodeMgr.h + Purpose: PE32+ Code Mgr and Dylib mgr. - Revision History: + Revision History: - 12/02/24: Added file (amlel) + 12/02/24: Added file (amlel) ------------------------------------------- */ @@ -19,11 +19,11 @@ //////////////////////////////////////////////////// +#include +#include #include #include #include -#include -#include #ifndef INC_PROCESS_SCHEDULER_H #include @@ -31,49 +31,47 @@ #define kPeApplicationMime "application/vnd-portable-executable" -namespace Kernel -{ - /// - /// \name PE32Loader - /// \brief PE32+ loader class. - /// - class PE32Loader : public LoaderInterface - { - 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 FindStart() override; - VoidPtr FindSymbol(const Char* name, Int32 kind) override; - ErrorOr GetBlob() override; - - public: - bool IsLoaded() noexcept; - - private: +namespace Kernel { +/// +/// \name PE32Loader +/// \brief PE32+ loader class. +/// +class PE32Loader : public LoaderInterface { + 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 FindStart() override; + VoidPtr FindSymbol(const Char* name, Int32 kind) override; + ErrorOr GetBlob() override; + + public: + bool IsLoaded() noexcept; + + private: #ifdef __FSKIT_INCLUDES_NEFS__ - OwnPtr> fFile; + OwnPtr> fFile; #elif defined(__FSKIT_INCLUDES_HEFS__) - OwnPtr> fFile; + OwnPtr> fFile; #else - OwnPtr> fFile; -#endif // __FSKIT_INCLUDES_NEFS__ - - Ref fPath; - VoidPtr fCachedBlob; - bool fBad; - }; -} // namespace Kernel \ No newline at end of file + OwnPtr> fFile; +#endif // __FSKIT_INCLUDES_NEFS__ + + Ref fPath; + VoidPtr fCachedBlob; + bool fBad; +}; +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/KernelKit/PEF.h b/dev/kernel/KernelKit/PEF.h index 0b2f5cb7..4c6ee5ae 100644 --- a/dev/kernel/KernelKit/PEF.h +++ b/dev/kernel/KernelKit/PEF.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: PEF.h - Purpose: Preferred Executable Format for Kernel. + File: PEF.h + Purpose: Preferred Executable Format for Kernel. - Revision History: + Revision History: - ?/?/23: Added file (amlel) + ?/?/23: Added file (amlel) ------------------------------------------- */ @@ -18,7 +18,7 @@ #include #include -#define kPefMagic "Joy!" +#define kPefMagic "Joy!" #define kPefMagicFat "yoJ!" #define kPefMagicLen (5) @@ -27,11 +27,11 @@ #define kPefNameLen (256U) /* not mandatory, only for non fork based filesystems. */ -#define kPefExt ".exec" -#define kPefDylibExt ".dylib" -#define kPefLibExt ".lib" +#define kPefExt ".exec" +#define kPefDylibExt ".dylib" +#define kPefLibExt ".lib" #define kPefObjectExt ".obj" -#define kPefDebugExt ".dbg" +#define kPefDebugExt ".dbg" #define kPefDriverExt ".sys" // Kernel System Binary Interface. @@ -42,77 +42,70 @@ #define kPefStart "__ImageStart" #define kPefMainSymbol "_NeMain" -#define kPefForkKind kPefMagic +#define kPefForkKind kPefMagic #define kPefForkKindFAT kPefMagicFat -namespace Kernel -{ - enum - { - kPefArchIntel86S, - kPefArchAMD64, - kPefArchRISCV, - kPefArch64x0, /* 64x0. ISA */ - kPefArch32x0, /* 32x0. ISA */ - kPefArchPowerPC, - kPefArchARM64, - kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, - kPefArchInvalid = 0xFF, - }; - - enum - { - kPefSubArchAMD, - kPefSubArchIntel, - kPefSubArchARM, - kPefSubArchGeneric, - kPefSubArchIBM, - }; - - enum - { - kPefKindExec = 1, /* .o */ - 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 */ - } 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 Size; /* content Size */ - } PACKED PEFCommandHeader; - - enum - { - kPefCode = 0xC, - kPefData = 0xD, - kPefZero = 0xE, - kPefLinkerID = 0x1, - }; -} // namespace Kernel +namespace Kernel { +enum { + kPefArchIntel86S, + kPefArchAMD64, + kPefArchRISCV, + kPefArch64x0, /* 64x0. ISA */ + kPefArch32x0, /* 32x0. ISA */ + kPefArchPowerPC, + kPefArchARM64, + kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, + kPefArchInvalid = 0xFF, +}; + +enum { + kPefSubArchAMD, + kPefSubArchIntel, + kPefSubArchARM, + kPefSubArchGeneric, + kPefSubArchIBM, +}; + +enum { + kPefKindExec = 1, /* .o */ + 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 */ +} 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 Size; /* content Size */ +} PACKED PEFCommandHeader; + +enum { + kPefCode = 0xC, + kPefData = 0xD, + kPefZero = 0xE, + kPefLinkerID = 0x1, +}; +} // namespace Kernel #endif /* ifndef KERNELKIT_PEF_H */ diff --git a/dev/kernel/KernelKit/PEFCodeMgr.h b/dev/kernel/KernelKit/PEFCodeMgr.h index 389774fd..b3ca43d0 100644 --- a/dev/kernel/KernelKit/PEFCodeMgr.h +++ b/dev/kernel/KernelKit/PEFCodeMgr.h @@ -1,16 +1,16 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef _INC_CODE_MANAGER_PEF_H_ #define _INC_CODE_MANAGER_PEF_H_ +#include #include #include #include -#include #ifndef INC_PROCESS_SCHEDULER_H #include @@ -18,57 +18,54 @@ #define kPefApplicationMime "application/vnd-nekernel-executable" -namespace Kernel -{ - /// - /// \name PEFLoader - /// \brief PEF loader class. - /// - class PEFLoader : public LoaderInterface - { - 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 FindStart() override; - VoidPtr FindSymbol(const Char* name, Int32 kind) override; - ErrorOr GetBlob() override; - - public: - bool IsLoaded() noexcept; - - private: +namespace Kernel { +/// +/// \name PEFLoader +/// \brief PEF loader class. +/// +class PEFLoader : public LoaderInterface { + 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 FindStart() override; + VoidPtr FindSymbol(const Char* name, Int32 kind) override; + ErrorOr GetBlob() override; + + public: + bool IsLoaded() noexcept; + + private: #ifdef __FSKIT_INCLUDES_NEFS__ - OwnPtr> fFile; + OwnPtr> fFile; #elif defined(__FSKIT_INCLUDES_HEFS__) - OwnPtr> fFile; + OwnPtr> fFile; #else - OwnPtr> fFile; -#endif // __FSKIT_INCLUDES_NEFS__ - - Ref 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_ + OwnPtr> fFile; +#endif // __FSKIT_INCLUDES_NEFS__ + + Ref 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 index 038f46db..6da176b3 100644 --- a/dev/kernel/KernelKit/ProcessScheduler.h +++ b/dev/kernel/KernelKit/ProcessScheduler.h @@ -1,10 +1,10 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include -#include \ No newline at end of file +#include +#include \ No newline at end of file diff --git a/dev/kernel/KernelKit/Semaphore.h b/dev/kernel/KernelKit/Semaphore.h index f11bbbd9..9a66b9fe 100644 --- a/dev/kernel/KernelKit/Semaphore.h +++ b/dev/kernel/KernelKit/Semaphore.h @@ -1,16 +1,15 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#include -#include #include +#include +#include -namespace Kernel -{ - typedef Int64 Semaphore; -} // namespace Kernel \ No newline at end of file +namespace Kernel { +typedef Int64 Semaphore; +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/KernelKit/ThreadLocalStorage.h b/dev/kernel/KernelKit/ThreadLocalStorage.h index 00203ab1..bf34f39a 100644 --- a/dev/kernel/KernelKit/ThreadLocalStorage.h +++ b/dev/kernel/KernelKit/ThreadLocalStorage.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -26,10 +26,9 @@ 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[kTLSCookieLen]{0}; //! Thread magic number. - Kernel::VoidPtr Record{nullptr}; //! Thread information record. +struct PACKED THREAD_INFORMATION_BLOCK final { + Kernel::Char Cookie[kTLSCookieLen]{0}; //! Thread magic number. + Kernel::VoidPtr Record{nullptr}; //! Thread information record. }; ///! @brief Cookie Sanity check. diff --git a/dev/kernel/KernelKit/ThreadLocalStorage.inl b/dev/kernel/KernelKit/ThreadLocalStorage.inl index 9161b5d0..553f8d42 100644 --- a/dev/kernel/KernelKit/ThreadLocalStorage.inl +++ b/dev/kernel/KernelKit/ThreadLocalStorage.inl @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,53 +12,47 @@ #endif template -inline T* tls_new_ptr(void) noexcept -{ - using namespace Kernel; +inline T* tls_new_ptr(void) noexcept { + using namespace Kernel; - auto ref_process = UserProcessScheduler::The().CurrentProcess(); - MUST_PASS(ref_process); + auto ref_process = UserProcessScheduler::The().CurrentProcess(); + MUST_PASS(ref_process); - auto pointer = ref_process.Leak().New(sizeof(T)); + auto pointer = ref_process.Leak().New(sizeof(T)); - if (pointer.Error()) - return nullptr; + if (pointer.Error()) return nullptr; - return reinterpret_cast(pointer.Leak().Leak()); + return reinterpret_cast(pointer.Leak().Leak()); } //! @brief Delete process pointer. //! @param obj The pointer to delete. template -inline Kernel::Bool tls_delete_ptr(T* obj) noexcept -{ - using namespace Kernel; +inline Kernel::Bool tls_delete_ptr(T* obj) noexcept { + using namespace Kernel; - if (!obj) - return No; + if (!obj) return No; - auto ref_process = UserProcessScheduler::The().CurrentProcess(); - MUST_PASS(ref_process); + auto ref_process = UserProcessScheduler::The().CurrentProcess(); + MUST_PASS(ref_process); - ErrorOr obj_wrapped{obj}; + ErrorOr obj_wrapped{obj}; - return ref_process.Leak().Delete(obj_wrapped); + return ref_process.Leak().Delete(obj_wrapped); } //! @brief Delete process pointer. //! @param obj The pointer to delete. template -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept -{ - return tls_delete_ptr(obj.Leak()); +inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept { + return tls_delete_ptr(obj.Leak()); } //! @brief Delete process pointer. //! @param obj The pointer to delete. template -inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept -{ - return tls_delete_ptr(obj->Leak()); +inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept { + return tls_delete_ptr(obj->Leak()); } /// @brief Allocate a C++ class, and then call the constructor of it. @@ -67,19 +61,17 @@ inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr obj) noexcept /// @param args arguments list. /// @return Class instance. template -T* tls_new_class(Args&&... args) -{ - using namespace Kernel; +T* tls_new_class(Args&&... args) { + using namespace Kernel; - T* obj = tls_new_ptr(); + T* obj = tls_new_ptr(); - if (obj) - { - *obj = T(forward(args)...); - return obj; - } + if (obj) { + *obj = T(forward(args)...); + return obj; + } - return nullptr; + return nullptr; } /// @brief Delete a C++ class (call constructor first.) @@ -87,13 +79,11 @@ T* tls_new_class(Args&&... args) /// @param obj /// @return template -inline Kernel::Bool tls_delete_class(T* obj) -{ - using namespace Kernel; +inline Kernel::Bool tls_delete_class(T* obj) { + using namespace Kernel; - if (!obj) - return No; + if (!obj) return No; - obj->~T(); - return tls_delete_ptr(obj); + obj->~T(); + return tls_delete_ptr(obj); } diff --git a/dev/kernel/KernelKit/Timer.h b/dev/kernel/KernelKit/Timer.h index 1d12876b..d6cfee39 100644 --- a/dev/kernel/KernelKit/Timer.h +++ b/dev/kernel/KernelKit/Timer.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,75 +9,67 @@ #include #include -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 Int64 rtl_microseconds(Int64 time) - { - if (time < 0) - return 0; - - // TODO: nanoseconds maybe? - return kTimeUnit * time; - } - - inline Int64 rtl_milliseconds(Int64 time) - { - if (time < 0) - return 0; - - return kTimeUnit * kTimeUnit * time; - } -} // namespace Kernel +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 Int64 rtl_microseconds(Int64 time) { + if (time < 0) return 0; + + // TODO: nanoseconds maybe? + return kTimeUnit * time; +} + +inline Int64 rtl_milliseconds(Int64 time) { + if (time < 0) return 0; + + return kTimeUnit * kTimeUnit * time; +} +} // namespace Kernel diff --git a/dev/kernel/KernelKit/User.h b/dev/kernel/KernelKit/User.h index a228c9f0..250b1dfc 100644 --- a/dev/kernel/KernelKit/User.h +++ b/dev/kernel/KernelKit/User.h @@ -17,79 +17,76 @@ #include #include -#include #include +#include ///! We got the Super, Standard (%s format) and Guest user, ///! all are used to make authorization operations on the OS. #define kSuperUser "OS AUTHORITY/SUPER/%s" #define kGuestUser "OS AUTHORITY/GUEST/%s" -#define kStdUser "OS AUTHORITY/STD/%s" +#define kStdUser "OS AUTHORITY/STD/%s" #define kUsersDir "/user/" -#define kMaxUserNameLen (256U) +#define kMaxUserNameLen (256U) #define kMaxUserTokenLen (256U) -namespace Kernel -{ - class User; +namespace Kernel { +class User; - enum class UserRingKind - { - kRingInvalid = 0, - kRingStdUser = 1, - kRingSuperUser = 2, - kRingGuestUser = 5, - kRingCount = 3, - }; +enum class UserRingKind { + kRingInvalid = 0, + kRingStdUser = 1, + kRingSuperUser = 2, + kRingGuestUser = 5, + kRingCount = 3, +}; - typedef Char* UserPublicKey; - typedef Char UserPublicKeyType; +typedef Char* UserPublicKey; +typedef Char UserPublicKeyType; - /// @brief User class. - class User final - { - public: - User() = delete; +/// @brief User class. +class User final { + public: + User() = delete; - User(const Int32& sel, const Char* username); - User(const UserRingKind& kind, const Char* username); + User(const Int32& sel, const Char* username); + User(const UserRingKind& kind, const Char* username); - ~User(); + ~User(); - public: - NE_COPY_DEFAULT(User) + public: + NE_COPY_DEFAULT(User) - public: - bool operator==(const User& lhs); - bool operator!=(const User& lhs); + public: + bool operator==(const User& lhs); + bool operator!=(const User& lhs); - public: - /// @brief Get software ring - const UserRingKind& Ring() noexcept; + public: + /// @brief Get software ring + const UserRingKind& Ring() noexcept; - /// @brief Get user name - Char* Name() noexcept; + /// @brief Get user name + Char* Name() noexcept; - /// @brief Is he a standard user? - Bool IsStdUser() noexcept; + /// @brief Is he a standard user? + Bool IsStdUser() noexcept; - /// @brief Is she a super user? - Bool IsSuperUser() 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 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 Matches(const UserPublicKey password) noexcept; + /// @brief Checks if a password matches the **password**. + /// @param password the password to check. + Bool Matches(const UserPublicKey password) noexcept; - private: - UserRingKind mUserRing{UserRingKind::kRingStdUser}; - Char mUserName[kMaxUserNameLen] = {0}; - Char mUserKey[kMaxUserTokenLen] = {0}; - }; -} // namespace Kernel + private: + UserRingKind mUserRing{UserRingKind::kRingStdUser}; + Char mUserName[kMaxUserNameLen] = {0}; + Char mUserKey[kMaxUserTokenLen] = {0}; +}; +} // namespace Kernel #endif /* ifndef INC_USER_H */ diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index aeefe1d2..d6cd7ad4 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,18 +12,18 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) #include +#include #include #include #include -#include -#define kSchedMinMicroTime (AffinityKind::kStandard) -#define kSchedInvalidPID (-1) +#define kSchedMinMicroTime (AffinityKind::kStandard) +#define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (32U) -#define kSchedTeamCount (256U) +#define kSchedTeamCount (256U) #define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ -#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ +#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ #define kSchedNameLen (128U) @@ -31,240 +31,232 @@ // 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::kProcessSubsystemInvalid}; - User* Owner{nullptr}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity{AffinityKind::kStandard}; - ProcessStatusKind Status{ProcessStatusKind::kKilled}; - UInt8* StackReserve{nullptr}; - PROCESS_IMAGE Image{}; - SizeT StackSize{kSchedMaxStackSz}; - IDylibObject* DylibDelegate{nullptr}; - SizeT MemoryCursor{0UL}; - SizeT MemoryLimit{kSchedMaxMemoryLimit}; - SizeT UsedMemory{0UL}; - - /// @brief Allocation tracker structure. - struct USER_HEAP_TREE final - { - VoidPtr MemoryEntry{nullptr}; - SizeT MemoryEntrySize{0UL}; - SizeT MemoryEntryPad{0UL}; - - enum - { - kInvalidMemory = 0, - kRedMemory = 100, - kBlackMemory = 101, - kCountMemory = 2, - }; - - Int32 MemoryColor{kBlackMemory}; - - struct USER_HEAP_TREE* MemoryParent{nullptr}; - struct USER_HEAP_TREE* MemoryChild{nullptr}; - - struct USER_HEAP_TREE* MemoryPrev{nullptr}; - struct USER_HEAP_TREE* MemoryNext{nullptr}; - }; - - struct USER_PROCESS_SIGNAL final - { - UIntPtr SignalArg; - ProcessStatusKind Status; - UIntPtr SignalID; - }; - - USER_PROCESS_SIGNAL Signal; - USER_HEAP_TREE* HeapTree{nullptr}; - UserProcessTeam* ParentTeam; - - VoidPtr VMRegister{0UL}; - - enum - { - kInvalidExecutableKind, - kExecutableKind, - kExecutableDylibKind, - kExecutableKindCount, - }; - - ProcessTime PTime{0}; //! @brief USER_PROCESS allocated tine. - - PID ProcessId{kSchedInvalidPID}; - Int32 Kind{kExecutableKind}; - - public: - /***********************************************************************************/ - //! @brief boolean operator, check status. - /***********************************************************************************/ - operator bool(); - - /***********************************************************************************/ - ///! @brief Crashes the app, exits with code ~0. - /***********************************************************************************/ - Void Crash(); - - /***********************************************************************************/ - ///! @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 New(SizeT sz, SizeT pad_amount = 0); - - /***********************************************************************************/ - ///! @brief TLS free. - ///! @param ptr the pointer to free. - ///! @param sz the size of it. - /***********************************************************************************/ - template - Boolean Delete(ErrorOr ptr); - - /***********************************************************************************/ - ///! @brief Wakes up thread. - /***********************************************************************************/ - Void Wake(Bool wakeup = false); - - public: - /***********************************************************************************/ - //! @brief Gets the local exit code. - /***********************************************************************************/ - const UInt32& 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. - /***********************************************************************************/ - Int32& GetLocalCode() noexcept; - - const User* GetOwner() noexcept; - const ProcessStatusKind& GetStatus() noexcept; - const AffinityKind& GetAffinity() noexcept; - - private: - UInt32 fLastExitCode{0}; - Int32 fLocalCode{0}; - - friend UserProcessScheduler; - friend UserProcessHelper; - }; - - typedef Array USER_PROCESS_ARRAY; - - /// \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& AsArray(); - Ref& AsRef(); - ProcessID& Id() noexcept; - - public: - USER_PROCESS_ARRAY mProcessList; - Ref mCurrentProcess; - ProcessID mTeamId{0}; - ProcessID mProcessCount{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) - - operator bool(); - bool operator!(); - - public: - UserProcessTeam& CurrentTeam(); - 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: - Ref& CurrentProcess(); - 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(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, PID new_pid); - STATIC Bool CanBeScheduled(const USER_PROCESS& process); - STATIC ErrorOr TheCurrentPID(); - STATIC SizeT StartScheduling(); - }; - - const UInt32& sched_get_exit_code(void) noexcept; -} // namespace Kernel +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::kProcessSubsystemInvalid}; + User* Owner{nullptr}; + HAL::StackFramePtr StackFrame{nullptr}; + AffinityKind Affinity{AffinityKind::kStandard}; + ProcessStatusKind Status{ProcessStatusKind::kKilled}; + UInt8* StackReserve{nullptr}; + PROCESS_IMAGE Image{}; + SizeT StackSize{kSchedMaxStackSz}; + IDylibObject* DylibDelegate{nullptr}; + SizeT MemoryCursor{0UL}; + SizeT MemoryLimit{kSchedMaxMemoryLimit}; + SizeT UsedMemory{0UL}; + + /// @brief Allocation tracker structure. + struct USER_HEAP_TREE final { + VoidPtr MemoryEntry{nullptr}; + SizeT MemoryEntrySize{0UL}; + SizeT MemoryEntryPad{0UL}; + + enum { + kInvalidMemory = 0, + kRedMemory = 100, + kBlackMemory = 101, + kCountMemory = 2, + }; + + Int32 MemoryColor{kBlackMemory}; + + struct USER_HEAP_TREE* MemoryParent{nullptr}; + struct USER_HEAP_TREE* MemoryChild{nullptr}; + + struct USER_HEAP_TREE* MemoryPrev{nullptr}; + struct USER_HEAP_TREE* MemoryNext{nullptr}; + }; + + struct USER_PROCESS_SIGNAL final { + UIntPtr SignalArg; + ProcessStatusKind Status; + UIntPtr SignalID; + }; + + USER_PROCESS_SIGNAL Signal; + USER_HEAP_TREE* HeapTree{nullptr}; + UserProcessTeam* ParentTeam; + + VoidPtr VMRegister{0UL}; + + enum { + kInvalidExecutableKind, + kExecutableKind, + kExecutableDylibKind, + kExecutableKindCount, + }; + + ProcessTime PTime{0}; //! @brief USER_PROCESS allocated tine. + + PID ProcessId{kSchedInvalidPID}; + Int32 Kind{kExecutableKind}; + + public: + /***********************************************************************************/ + //! @brief boolean operator, check status. + /***********************************************************************************/ + operator bool(); + + /***********************************************************************************/ + ///! @brief Crashes the app, exits with code ~0. + /***********************************************************************************/ + Void Crash(); + + /***********************************************************************************/ + ///! @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 New(SizeT sz, SizeT pad_amount = 0); + + /***********************************************************************************/ + ///! @brief TLS free. + ///! @param ptr the pointer to free. + ///! @param sz the size of it. + /***********************************************************************************/ + template + Boolean Delete(ErrorOr ptr); + + /***********************************************************************************/ + ///! @brief Wakes up thread. + /***********************************************************************************/ + Void Wake(Bool wakeup = false); + + public: + /***********************************************************************************/ + //! @brief Gets the local exit code. + /***********************************************************************************/ + const UInt32& 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. + /***********************************************************************************/ + Int32& GetLocalCode() noexcept; + + const User* GetOwner() noexcept; + const ProcessStatusKind& GetStatus() noexcept; + const AffinityKind& GetAffinity() noexcept; + + private: + UInt32 fLastExitCode{0}; + Int32 fLocalCode{0}; + + friend UserProcessScheduler; + friend UserProcessHelper; +}; + +typedef Array USER_PROCESS_ARRAY; + +/// \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& AsArray(); + Ref& AsRef(); + ProcessID& Id() noexcept; + + public: + USER_PROCESS_ARRAY mProcessList; + Ref mCurrentProcess; + ProcessID mTeamId{0}; + ProcessID mProcessCount{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) + + operator bool(); + bool operator!(); + + public: + UserProcessTeam& CurrentTeam(); + 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: + Ref& CurrentProcess(); + 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(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, + PID new_pid); + STATIC Bool CanBeScheduled(const USER_PROCESS& process); + STATIC ErrorOr TheCurrentPID(); + STATIC SizeT StartScheduling(); +}; + +const UInt32& sched_get_exit_code(void) noexcept; +} // namespace Kernel #include #include diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index 63cdc795..2333b898 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - FILE: UserProcessScheduler.inl - PURPOSE: Low level/Ring-3 process scheduler. + FILE: UserProcessScheduler.inl + PURPOSE: Low level/Ring-3 process scheduler. ------------------------------------------- */ @@ -11,56 +11,50 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) /// @date Tue Apr 22 22:01:07 CEST 2025 -namespace Kernel -{ - /***********************************************************************************/ - /** @brief Free pointer from usage. */ - /***********************************************************************************/ +namespace Kernel { +/***********************************************************************************/ +/** @brief Free pointer from usage. */ +/***********************************************************************************/ - template - Boolean USER_PROCESS::Delete(ErrorOr ptr) - { - if (!ptr) - return No; +template +Boolean USER_PROCESS::Delete(ErrorOr ptr) { + if (!ptr) return No; - if (!this->HeapTree) - { - kout << "USER_PROCESS's heap is empty.\r"; - return No; - } + if (!this->HeapTree) { + kout << "USER_PROCESS's heap is empty.\r"; + return No; + } - USER_HEAP_TREE* entry = this->HeapTree; + USER_HEAP_TREE* entry = this->HeapTree; - while (entry != nullptr) - { - if (entry->MemoryEntry == ptr.Leak().Leak()) - { - this->UsedMemory -= entry->MemoryEntrySize; + while (entry != nullptr) { + if (entry->MemoryEntry == ptr.Leak().Leak()) { + this->UsedMemory -= entry->MemoryEntrySize; #ifdef __NE_AMD64__ - auto pd = hal_read_cr3(); + auto pd = hal_read_cr3(); - hal_write_cr3(this->VMRegister); + hal_write_cr3(this->VMRegister); - auto ret = mm_delete_heap(entry->MemoryEntry); + auto ret = mm_delete_heap(entry->MemoryEntry); - hal_write_cr3(pd); + hal_write_cr3(pd); - return ret == kErrorSuccess; + return ret == kErrorSuccess; #else - Bool ret = mm_delete_heap(ptr.Leak().Leak()); + Bool ret = mm_delete_heap(ptr.Leak().Leak()); - return ret == kErrorSuccess; + return ret == kErrorSuccess; #endif - } + } - entry = entry->MemoryNext; - } + entry = entry->MemoryNext; + } - kout << "USER_PROCESS: Trying to free a pointer which doesn't exist.\r"; + kout << "USER_PROCESS: Trying to free a pointer which doesn't exist.\r"; - this->Crash(); + this->Crash(); - return No; - } -} // namespace Kernel + return No; +} +} // namespace Kernel diff --git a/dev/kernel/KernelKit/XCOFF.h b/dev/kernel/KernelKit/XCOFF.h index 69cb0c53..7b15782b 100644 --- a/dev/kernel/KernelKit/XCOFF.h +++ b/dev/kernel/KernelKit/XCOFF.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: XCOFF.h - Purpose: XCOFF for Kernel. + File: XCOFF.h + Purpose: XCOFF for Kernel. - Revision History: + Revision History: - 04/07/24: Added file (amlel) + 04/07/24: Added file (amlel) ------------------------------------------- */ @@ -16,38 +16,36 @@ #include -#define kXCOFF64Magic (0x01F7) +#define kXCOFF64Magic (0x01F7) #define kXCOFF64ForkNameLen (256U) -#define kXCOFFRelFlg (0x0001) +#define kXCOFFRelFlg (0x0001) #define kXCOFFExecutable (0x0002) -#define kXCOFFLnno (0x0004) -#define kXCOFFLSyms (0x0008) +#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 +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]; +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 +#endif // ifndef INC_XOCFF_H diff --git a/dev/kernel/NetworkKit/IP.h b/dev/kernel/NetworkKit/IP.h index 5df23dc3..bf3b24ff 100644 --- a/dev/kernel/NetworkKit/IP.h +++ b/dev/kernel/NetworkKit/IP.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,76 +8,69 @@ #include #include -#include #include +#include + +namespace Kernel { +class RawIPAddress6; +class RawIPAddress; +class IPFactory; + +class RawIPAddress final { + private: + explicit RawIPAddress(char bytes[4]); + ~RawIPAddress() = default; + + RawIPAddress& operator=(const RawIPAddress&) = delete; + RawIPAddress(const RawIPAddress&) = default; + + public: + Char* Address(); + + Char& operator[](const Size& index); + + BOOL operator==(const RawIPAddress& ipv6); + BOOL operator!=(const RawIPAddress& ipv6); + + private: + Char 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(char Bytes[8]); + ~RawIPAddress6() = default; + + RawIPAddress6& operator=(const RawIPAddress6&) = delete; + RawIPAddress6(const RawIPAddress6&) = default; + + public: + char* Address() { return fAddr; } + + char& operator[](const Size& index); + + bool operator==(const RawIPAddress6& ipv6); + bool operator!=(const RawIPAddress6& ipv6); + + private: + char fAddr[8]; + + friend IPFactory; +}; -namespace Kernel -{ - class RawIPAddress6; - class RawIPAddress; - class IPFactory; - - class RawIPAddress final - { - private: - explicit RawIPAddress(char bytes[4]); - ~RawIPAddress() = default; - - RawIPAddress& operator=(const RawIPAddress&) = delete; - RawIPAddress(const RawIPAddress&) = default; - - public: - Char* Address(); - - Char& operator[](const Size& index); - - BOOL operator==(const RawIPAddress& ipv6); - BOOL operator!=(const RawIPAddress& ipv6); - - private: - Char 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(char Bytes[8]); - ~RawIPAddress6() = default; - - RawIPAddress6& operator=(const RawIPAddress6&) = delete; - RawIPAddress6(const RawIPAddress6&) = default; - - public: - char* Address() - { - return fAddr; - } - - char& operator[](const Size& index); - - bool operator==(const RawIPAddress6& ipv6); - bool operator!=(const RawIPAddress6& ipv6); - - private: - char fAddr[8]; - - friend IPFactory; - }; - - /** - * @brief IP Creation helpers - */ - class IPFactory final - { - public: - static ErrorOr ToKString(Ref& ipv6); - static ErrorOr ToKString(Ref& ipv4); - static bool IpCheckVersion4(const Char* ip); - }; -} // namespace Kernel +/** + * @brief IP Creation helpers + */ +class IPFactory final { + public: + static ErrorOr ToKString(Ref& ipv6); + static ErrorOr ToKString(Ref& ipv4); + static bool IpCheckVersion4(const Char* ip); +}; +} // namespace Kernel diff --git a/dev/kernel/NetworkKit/IPC.h b/dev/kernel/NetworkKit/IPC.h index 6de306b2..43b58d35 100644 --- a/dev/kernel/NetworkKit/IPC.h +++ b/dev/kernel/NetworkKit/IPC.h @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.. - File: IPC.h. - Purpose: IPC protocol. + File: IPC.h. + Purpose: IPC protocol. ------------------------------------------- */ @@ -25,67 +25,63 @@ #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; - - /// @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]; - - /// @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 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 +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; + +/// @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]; + + /// @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 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 index c44841de..71254cbf 100644 --- a/dev/kernel/NetworkKit/LTE.h +++ b/dev/kernel/NetworkKit/LTE.h @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.. - File: LTE.h. - Purpose: LTE protocol classes. + File: LTE.h. + Purpose: LTE protocol classes. ------------------------------------------- */ @@ -13,4 +13,4 @@ #include #include -#endif // ifndef _INC_NETWORK_LTE_H_ +#endif // ifndef _INC_NETWORK_LTE_H_ diff --git a/dev/kernel/NetworkKit/MAC.h b/dev/kernel/NetworkKit/MAC.h index 0509fed4..8520037e 100644 --- a/dev/kernel/NetworkKit/MAC.h +++ b/dev/kernel/NetworkKit/MAC.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,25 +12,23 @@ #define kMACAddrLen (32) -namespace Kernel -{ - class MacAddressGetter; +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; +/// \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) + NE_COPY_DEFAULT(MacAddressGetter) - public: - Array& AsBytes(); + public: + Array& AsBytes(); - private: - Array fMacAddress; - }; + private: + Array fMacAddress; +}; -} // namespace Kernel +} // namespace Kernel diff --git a/dev/kernel/NetworkKit/NetworkDevice.h b/dev/kernel/NetworkKit/NetworkDevice.h index 48e4e883..7ed67bab 100644 --- a/dev/kernel/NetworkKit/NetworkDevice.h +++ b/dev/kernel/NetworkKit/NetworkDevice.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,72 +12,69 @@ /// @note Can either work with: Ethernet, GPRS, WiFi -namespace Kernel -{ - struct NetworkDeviceCommand; - class NetworkDevice; +namespace Kernel { +struct NetworkDeviceCommand; +class NetworkDevice; - /** - * \brief Network device interface, establishes a connection to the NIC. - */ - class NetworkDevice final : public IDeviceObject - { - public: - NetworkDevice(void (*out)(IDeviceObject*, NetworkDeviceCommand), - void (*in)(IDeviceObject*, NetworkDeviceCommand), - void (*onCleanup)(void) = nullptr); +/** + * \brief Network device interface, establishes a connection to the NIC. + */ +class NetworkDevice final : public IDeviceObject { + public: + NetworkDevice(void (*out)(IDeviceObject*, NetworkDeviceCommand), + void (*in)(IDeviceObject*, NetworkDeviceCommand), + void (*onCleanup)(void) = nullptr); - ~NetworkDevice() override; + ~NetworkDevice() override; - public: - NetworkDevice& operator=(const NetworkDevice&) = default; - NetworkDevice(const NetworkDevice&) = default; + public: + NetworkDevice& operator=(const NetworkDevice&) = default; + NetworkDevice(const NetworkDevice&) = default; - public: - const Char* Name() const override; - Boolean Name(const Char* newStr); + public: + const Char* Name() const override; + Boolean Name(const Char* newStr); - private: - static constexpr auto cNetworkNameLen = 512; + private: + static constexpr auto cNetworkNameLen = 512; - Void (*fCleanup)(void); - Char fNetworkName[cNetworkNameLen]; - }; + Void (*fCleanup)(void); + Char fNetworkName[cNetworkNameLen]; +}; - struct NetworkDeviceCommand final - { - UInt32 CommandName; - UInt32 CommandType; - UInt32 CommandFlags; - VoidPtr CommandBuffer; - SizeT CommandSizeBuffer; - }; +struct NetworkDeviceCommand final { + UInt32 CommandName; + UInt32 CommandType; + UInt32 CommandFlags; + VoidPtr CommandBuffer; + SizeT CommandSizeBuffer; +}; - /// @brief TCP device. - using TCPNetworkDevice = NetworkDevice; +/// @brief TCP device. +using TCPNetworkDevice = NetworkDevice; - /// @brief UDP device. - using UDPNetworkDevice = NetworkDevice; +/// @brief UDP device. +using UDPNetworkDevice = NetworkDevice; - /// @brief PPP device. - using PPPNetworkDevice = NetworkDevice; +/// @brief PPP device. +using PPPNetworkDevice = NetworkDevice; - /// @brief IPC device. - using IPCNetworkDevice = NetworkDevice; +/// @brief IPC device. +using IPCNetworkDevice = NetworkDevice; - /// @brief GRPS device. - using GPRSNetworkDevice = NetworkDevice; +/// @brief GRPS device. +using GPRSNetworkDevice = NetworkDevice; - /// @brief GSM device. - using GSMNetworkDevice = NetworkDevice; +/// @brief GSM device. +using GSMNetworkDevice = NetworkDevice; - /// @brief Bluetooth device. - using BTNetworkDevice = NetworkDevice; +/// @brief Bluetooth device. +using BTNetworkDevice = NetworkDevice; - /// @brief LTE device. - using LTENetworkDevice = NetworkDevice; -} // namespace Kernel +/// @brief LTE device. +using LTENetworkDevice = NetworkDevice; +} // namespace Kernel #include -#endif // !__INC_NETWORK_DEVICE_H__ +#endif // !__INC_NETWORK_DEVICE_H__ diff --git a/dev/kernel/NetworkKit/NetworkDevice.inl b/dev/kernel/NetworkKit/NetworkDevice.inl index c16756b1..797b8adc 100644 --- a/dev/kernel/NetworkKit/NetworkDevice.inl +++ b/dev/kernel/NetworkKit/NetworkDevice.inl @@ -1,32 +1,29 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ /*** - Dtor and ctors. + Dtor and ctors. */ -namespace Kernel -{ - NetworkDevice::NetworkDevice(void (*out)(IDeviceObject*, NetworkDeviceCommand), - void (*in)(IDeviceObject*, NetworkDeviceCommand), - void (*on_cleanup)(void)) - : IDeviceObject(out, in), fCleanup(on_cleanup) - { - kout << "NetworkDevice initialized.\r"; +namespace Kernel { +NetworkDevice::NetworkDevice(void (*out)(IDeviceObject*, + NetworkDeviceCommand), + void (*in)(IDeviceObject*, NetworkDeviceCommand), + void (*on_cleanup)(void)) + : IDeviceObject(out, in), fCleanup(on_cleanup) { + kout << "NetworkDevice initialized.\r"; - MUST_PASS(out && in && on_cleanup); - } + MUST_PASS(out && in && on_cleanup); +} - NetworkDevice::~NetworkDevice() - { - MUST_PASS(fCleanup); +NetworkDevice::~NetworkDevice() { + MUST_PASS(fCleanup); - kout << "NetworkDevice cleanup.\r"; + kout << "NetworkDevice cleanup.\r"; - if (fCleanup) - fCleanup(); - } -} // namespace Kernel + if (fCleanup) fCleanup(); +} +} // namespace Kernel diff --git a/dev/kernel/NewKit/Array.h b/dev/kernel/NewKit/Array.h index 1dcc6720..af73d002 100644 --- a/dev/kernel/NewKit/Array.h +++ b/dev/kernel/NewKit/Array.h @@ -1,65 +1,46 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -#include #include +#include -namespace Kernel -{ - template - class Array final - { - public: - explicit Array() = default; - ~Array() = default; +namespace Kernel { +template +class Array final { + public: + explicit Array() = default; + ~Array() = default; - Array& operator=(const Array&) = default; - Array(const Array&) = default; + Array& operator=(const Array&) = default; + Array(const Array&) = default; - T& operator[](SizeT at) - { - MUST_PASS(at < this->Count()); - return fArray[at]; - } + T& operator[](SizeT at) { + MUST_PASS(at < this->Count()); + return fArray[at]; + } - Boolean Empty() - { - return this->Count() > 0; - } + Boolean Empty() { return this->Count() > 0; } - SizeT Capacity() - { - return N; - } + SizeT Capacity() { return N; } - SizeT Count() - { - return N; - } + SizeT Count() { return N; } - const T* CData() - { - return fArray; - } + const T* CData() { return fArray; } - operator bool() - { - return !Empty(); - } + operator bool() { return !Empty(); } - private: - T fArray[N]; - }; + private: + T fArray[N]; +}; - template - auto make_list(ValueType val) - { - return Array{val}; - } -} // namespace Kernel +template +auto make_list(ValueType val) { + return Array{val}; +} +} // namespace Kernel diff --git a/dev/kernel/NewKit/ArrayList.h b/dev/kernel/NewKit/ArrayList.h index 1ea69fc5..d07e534c 100644 --- a/dev/kernel/NewKit/ArrayList.h +++ b/dev/kernel/NewKit/ArrayList.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,56 +8,37 @@ #include -namespace Kernel -{ - template - class ArrayList final - { - public: - explicit ArrayList(T* list, SizeT length) - : fList(reinterpret_cast(list)) - { - } - - ~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 - ArrayList make_list(ValueType val) - { - return ArrayList{val}; - } -} // namespace Kernel +namespace Kernel { +template +class ArrayList final { + public: + explicit ArrayList(T* list, SizeT length) : fList(reinterpret_cast(list)) {} + + ~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 +ArrayList make_list(ValueType val) { + return ArrayList{val}; +} +} // namespace Kernel diff --git a/dev/kernel/NewKit/Atom.h b/dev/kernel/NewKit/Atom.h index f9645fd8..4b23c933 100644 --- a/dev/kernel/NewKit/Atom.h +++ b/dev/kernel/NewKit/Atom.h @@ -1,47 +1,33 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -namespace Kernel -{ - template - 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& atomic, const T& idx) - { - return atomic[idx] == idx; - } - - friend Boolean operator!=(Atom& atomic, const T& idx) - { - return atomic[idx] == idx; - } - - private: - T fArrayOfAtoms; - }; -} // namespace Kernel +namespace Kernel { +template +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& atomic, const T& idx) { return atomic[idx] == idx; } + + friend Boolean operator!=(Atom& atomic, const T& idx) { return atomic[idx] == idx; } + + private: + T fArrayOfAtoms; +}; +} // namespace Kernel diff --git a/dev/kernel/NewKit/Crc32.h b/dev/kernel/NewKit/Crc32.h index b64a29a1..b6f33714 100644 --- a/dev/kernel/NewKit/Crc32.h +++ b/dev/kernel/NewKit/Crc32.h @@ -15,9 +15,8 @@ #define kCrcCnt (256) -namespace Kernel -{ - UInt32 ke_calculate_crc32(const Char* crc, Int32 len) noexcept; -} // namespace Kernel +namespace Kernel { +UInt32 ke_calculate_crc32(const Char* crc, Int32 len) noexcept; +} // namespace Kernel -#endif // !CRC32_H +#endif // !CRC32_H diff --git a/dev/kernel/NewKit/CxxAbi.h b/dev/kernel/NewKit/CxxAbi.h index 4bd3f662..8fb93bf8 100644 --- a/dev/kernel/NewKit/CxxAbi.h +++ b/dev/kernel/NewKit/CxxAbi.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once @@ -11,18 +11,16 @@ #define kAtExitMacDestructors (128) -struct atexit_func_entry_t -{ - void (*destructor_func)(); - void* obj_ptr; - void* dso_handle; +struct atexit_func_entry_t { + void (*destructor_func)(); + void* obj_ptr; + void* dso_handle; }; typedef unsigned uarch_t; -namespace cxxabiv1 -{ - typedef void* __guard; +namespace cxxabiv1 { +typedef void* __guard; } -#endif // __GNUC__ +#endif // __GNUC__ diff --git a/dev/kernel/NewKit/Defines.h b/dev/kernel/NewKit/Defines.h index 15b1d907..0d2f830f 100644 --- a/dev/kernel/NewKit/Defines.h +++ b/dev/kernel/NewKit/Defines.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -28,174 +28,149 @@ #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 = int; - using UShort = unsigned short; - using UInt16 = unsigned short; - using Short = short; - using Int16 = short; - using UInt = unsigned int; - using UInt32 = unsigned int; - 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 UChar = unsigned char; - using UInt8 = unsigned char; - - using SSize = Int64; - using SSizeT = Int64; - 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 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 - inline Args&& forward(Args& arg) - { - return static_cast(arg); - } - - /// @brief Move object. - /// @tparam Args the object type. - /// @param arg the object. - /// @return object's rvalue - template - inline Args&& move(Args&& arg) - { - return static_cast(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 - 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 - OutputClass* Construct(Char* type) noexcept - { - FactoryClass class_fac; - return class_fac.template From(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 - Y As(T type) noexcept - { - if (type.template IsSerializable()) - { - return reinterpret_cast(type); - } - - return type.template As(); - } - }; - - /// \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 +namespace Kernel { +using voidPtr = void*; +using VoidPtr = void*; +using nullPtr = decltype(nullptr); +using NullPtr = decltype(nullptr); + +using Int = int; +using Int32 = int; +using UShort = unsigned short; +using UInt16 = unsigned short; +using Short = short; +using Int16 = short; +using UInt = unsigned int; +using UInt32 = unsigned int; +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 UChar = unsigned char; +using UInt8 = unsigned char; + +using SSize = Int64; +using SSizeT = Int64; +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 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 +inline Args&& forward(Args& arg) { + return static_cast(arg); +} + +/// @brief Move object. +/// @tparam Args the object type. +/// @param arg the object. +/// @return object's rvalue +template +inline Args&& move(Args&& arg) { + return static_cast(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 + 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 + OutputClass* Construct(Char* type) noexcept { + FactoryClass class_fac; + return class_fac.template From(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 + Y As(T type) noexcept { + if (type.template IsSerializable()) { + return reinterpret_cast(type); + } + + return type.template As(); + } +}; + +/// \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/NewKit/ErrorOr.h b/dev/kernel/NewKit/ErrorOr.h index 0342a0db..f2de3432 100644 --- a/dev/kernel/NewKit/ErrorOr.h +++ b/dev/kernel/NewKit/ErrorOr.h @@ -12,71 +12,45 @@ #include #include -namespace Kernel -{ - using ErrorT = UInt; - - template - class ErrorOr final - { - public: - ErrorOr() = default; - ~ErrorOr() = default; - - public: - explicit ErrorOr(Int32 err) - : mId(err) - { - } - - explicit ErrorOr(nullPtr Null) - { - } - - 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& refErr) - { - mRef = refErr; - return *this; - } - - Ref& Leak() - { - return mRef; - } - - Int32 Error() - { - return mId; - } - - operator bool() - { - return mRef; - } - - BOOL HasError() - { - return this->mId > 0; - } - - private: - Ref mRef; - UInt32 mId{0}; - }; - - using ErrorOrAny = ErrorOr; - -} // namespace Kernel +namespace Kernel { +using ErrorT = UInt; + +template +class ErrorOr final { + public: + ErrorOr() = default; + ~ErrorOr() = default; + + public: + explicit ErrorOr(Int32 err) : mId(err) {} + + explicit ErrorOr(nullPtr Null) {} + + 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& refErr) { + mRef = refErr; + return *this; + } + + Ref& Leak() { return mRef; } + + Int32 Error() { return mId; } + + operator bool() { return mRef; } + + BOOL HasError() { return this->mId > 0; } + + private: + Ref mRef; + UInt32 mId{0}; +}; + +using ErrorOrAny = ErrorOr; + +} // namespace Kernel diff --git a/dev/kernel/NewKit/Function.h b/dev/kernel/NewKit/Function.h index 9fa218af..e0af5842 100644 --- a/dev/kernel/NewKit/Function.h +++ b/dev/kernel/NewKit/Function.h @@ -3,51 +3,38 @@ #include -namespace Kernel -{ - template - 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 - T operator()(Args... args) - { - return fFn(args...); - } - - template - T Call(Args... args) - { - return fFn(args...); - } - - operator bool() - { - return fFn; - } - - bool operator!() - { - return !fFn; - } - - private: - T(*fFn) - (Args... args); - }; -} // namespace Kernel - -#endif // !_INC_FUNCTION_H__ +namespace Kernel { +template +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 + T operator()(Args... args) { + return fFn(args...); + } + + template + T Call(Args... args) { + return fFn(args...); + } + + operator bool() { return fFn; } + + bool operator!() { return !fFn; } + + private: + T(*fFn) + (Args... args); +}; +} // namespace Kernel + +#endif // !_INC_FUNCTION_H__ diff --git a/dev/kernel/NewKit/Json.h b/dev/kernel/NewKit/Json.h index 8520dd71..6af71b72 100644 --- a/dev/kernel/NewKit/Json.h +++ b/dev/kernel/NewKit/Json.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,155 +11,119 @@ #include #include -#include #include +#include #include -#define kJSONMaxLen (8196) -#define kJSONLen (256) +#define kJSONMaxLen (8196) +#define kJSONLen (256) #define kJSONNullArr "[]" #define kJSONNullObj "{}" -namespace Kernel -{ - /// @brief JavaScript object class - class Json final - { - public: - explicit Json() - { - auto len = kJSONMaxLen; - KString key = KString(len); - key += kJSONNullObj; - - this->AsKey() = key; - this->AsValue() = key; - } - - explicit Json(SizeT lhsLen, SizeT rhsLen) - : fKey(lhsLen), fValue(rhsLen) - { - } - - ~Json() = default; - - NE_COPY_DEFAULT(Json) - - Bool& IsUndefined() - { - return fUndefined; - } - - private: - Bool fUndefined; // is this instance undefined? - KString fKey; - KString fValue; - - public: - /// @brief returns the key of the json - /// @return the key as string view. - KString& AsKey() - { - return fKey; - } - - /// @brief returns the value of the json. - /// @return the key as string view. - KString& AsValue() - { - return fValue; - } - - static Json kNull; - }; - - /// @brief Json stream reader helper. - struct JsonStreamReader final - { - STATIC Json 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 Json::kNull; - - start_val = '['; - end_val = ']'; - - probe_value = true; - } - - SizeT len = rt_string_len(full_array); - - SizeT key_len = 0; - SizeT value_len = 0; - - Json type(kJSONMaxLen, kJSONMaxLen); - - 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; - } - }; - - using JsonStream = Stream; -} // namespace Kernel +namespace Kernel { +/// @brief JavaScript object class +class Json final { + public: + explicit Json() { + auto len = kJSONMaxLen; + KString key = KString(len); + key += kJSONNullObj; + + this->AsKey() = key; + this->AsValue() = key; + } + + explicit Json(SizeT lhsLen, SizeT rhsLen) : fKey(lhsLen), fValue(rhsLen) {} + + ~Json() = default; + + NE_COPY_DEFAULT(Json) + + Bool& IsUndefined() { return fUndefined; } + + private: + Bool fUndefined; // is this instance undefined? + KString fKey; + KString fValue; + + public: + /// @brief returns the key of the json + /// @return the key as string view. + KString& AsKey() { return fKey; } + + /// @brief returns the value of the json. + /// @return the key as string view. + KString& AsValue() { return fValue; } + + static Json kNull; +}; + +/// @brief Json stream reader helper. +struct JsonStreamReader final { + STATIC Json 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 Json::kNull; + + start_val = '['; + end_val = ']'; + + probe_value = true; + } + + SizeT len = rt_string_len(full_array); + + SizeT key_len = 0; + SizeT value_len = 0; + + Json type(kJSONMaxLen, kJSONMaxLen); + + 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; + } +}; + +using JsonStream = Stream; +} // namespace Kernel diff --git a/dev/kernel/NewKit/KString.h b/dev/kernel/NewKit/KString.h index e182fd30..133fe945 100644 --- a/dev/kernel/NewKit/KString.h +++ b/dev/kernel/NewKit/KString.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,87 +9,73 @@ #include #include #include -#include #include +#include #define cMinimumStringSize 8196 -namespace Kernel -{ - /// @brief Kernel string class, not dynamic. - class KString final - { - public: - explicit KString() - { - fDataSz = cMinimumStringSize; - - fData = new Char[fDataSz]; - MUST_PASS(fData); - - rt_set_memory(fData, 0, fDataSz); - } - - explicit KString(SizeT Sz) - : fDataSz(Sz) - { - MUST_PASS(Sz > 1); - - fData = new Char[Sz]; - MUST_PASS(fData); - - rt_set_memory(fData, 0, Sz); - } - - ~KString() - { - if (fData) - { - delete[] fData; - fData = nullptr; - } - } - - NE_COPY_DEFAULT(KString) - - Char* Data(); - const Char* CData() const; - Size Length() const; - - bool operator==(const Char* rhs) const; - bool operator!=(const Char* rhs) const; - - bool operator==(const KString& rhs) const; - bool operator!=(const KString& rhs) const; - - KString& operator+=(const Char* rhs); - KString& operator+=(const KString& rhs); - - operator bool() - { - return fData; - } - - bool operator!() - { - return fData; - } - - private: - Char* fData{nullptr}; - Size fDataSz{0}; - Size fCur{0}; - - friend class KStringBuilder; - }; - - struct KStringBuilder final - { - static ErrorOr Construct(const Char* data); - static const Char* FromBool(const Char* fmt, bool n); - static const Char* Format(const Char* fmt, const Char* from); - static bool Equals(const Char* lhs, const Char* rhs); - static bool Equals(const Utf16Char* lhs, const Utf16Char* rhs); - static bool Equals(const WideChar* lhs, const WideChar* rhs); - }; -} // namespace Kernel +namespace Kernel { +/// @brief Kernel string class, not dynamic. +class KString final { + public: + explicit KString() { + fDataSz = cMinimumStringSize; + + fData = new Char[fDataSz]; + MUST_PASS(fData); + + rt_set_memory(fData, 0, fDataSz); + } + + explicit KString(SizeT Sz) : fDataSz(Sz) { + MUST_PASS(Sz > 1); + + fData = new Char[Sz]; + MUST_PASS(fData); + + rt_set_memory(fData, 0, Sz); + } + + ~KString() { + if (fData) { + delete[] fData; + fData = nullptr; + } + } + + NE_COPY_DEFAULT(KString) + + Char* Data(); + const Char* CData() const; + Size Length() const; + + bool operator==(const Char* rhs) const; + bool operator!=(const Char* rhs) const; + + bool operator==(const KString& rhs) const; + bool operator!=(const KString& rhs) const; + + KString& operator+=(const Char* rhs); + KString& operator+=(const KString& rhs); + + operator bool() { return fData; } + + bool operator!() { return fData; } + + private: + Char* fData{nullptr}; + Size fDataSz{0}; + Size fCur{0}; + + friend class KStringBuilder; +}; + +struct KStringBuilder final { + static ErrorOr Construct(const Char* data); + static const Char* FromBool(const Char* fmt, bool n); + static const Char* Format(const Char* fmt, const Char* from); + static bool Equals(const Char* lhs, const Char* rhs); + static bool Equals(const Utf16Char* lhs, const Utf16Char* rhs); + static bool Equals(const WideChar* lhs, const WideChar* rhs); +}; +} // namespace Kernel diff --git a/dev/kernel/NewKit/KernelPanic.h b/dev/kernel/NewKit/KernelPanic.h index d630e6b4..6d7f4d23 100644 --- a/dev/kernel/NewKit/KernelPanic.h +++ b/dev/kernel/NewKit/KernelPanic.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,9 +9,8 @@ #include -namespace Kernel -{ - void ke_runtime_check(bool expr, const Char* file, const Char* line); +namespace Kernel { +void ke_runtime_check(bool expr, const Char* file, const Char* line); } #define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG) @@ -20,14 +19,13 @@ namespace Kernel #undef TRY #endif -#define TRY(X) \ - { \ - auto fn = X; \ - if ((fn()) == NO) \ - { \ - MUST_PASS(NO); \ - } \ - } +#define TRY(X) \ + { \ + auto fn = X; \ + if ((fn()) == NO) { \ + MUST_PASS(NO); \ + } \ + } #ifdef __MUST_PASS #undef __MUST_PASS @@ -37,37 +35,35 @@ namespace Kernel #ifdef __DEBUG__ #define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__) -#define assert(EXPR) MUST_PASS(EXPR) +#define assert(EXPR) MUST_PASS(EXPR) #else #define MUST_PASS(EXPR) (Kernel::Void)(EXPR) -#define assert(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, +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 +namespace Kernel { +void ke_panic(const Int32& id, const Char* message = nullptr); +} // namespace Kernel diff --git a/dev/kernel/NewKit/Macros.h b/dev/kernel/NewKit/Macros.h index 83dbc7b5..b89f5d67 100644 --- a/dev/kernel/NewKit/Macros.h +++ b/dev/kernel/NewKit/Macros.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -16,52 +16,51 @@ #endif #ifndef kib_cast -#define kib_cast(X) (Kernel::UInt64)((X)*1024) +#define kib_cast(X) (Kernel::UInt64)((X) * 1024) #endif #ifndef MIB -#define MIB(X) (Kernel::UInt64)((Kernel::UInt64)KIB(X) / 1024) +#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) +#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) +#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) +#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) +#define TIB(X) (Kernel::UInt64)((Kernel::UInt64) GIB(X) / 1024) #endif #ifndef tib_cast -#define tib_cast(X) ((Kernel::UInt64)gib_cast(X) * 1024) +#define tib_cast(X) ((Kernel::UInt64) gib_cast(X) * 1024) #endif #ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) \ - (((sizeof(a) / sizeof(*(a))) / \ - (static_cast(!(sizeof(a) % sizeof(*(a))))))) +#define ARRAY_SIZE(a) \ + (((sizeof(a) / sizeof(*(a))) / (static_cast(!(sizeof(a) % sizeof(*(a))))))) #endif #define DEPRECATED ATTRIBUTE(deprecated) #ifndef ALIGN #define ALIGN(X) __attribute__((aligned(X))) -#endif // #ifndef ALIGN +#endif // #ifndef ALIGN #ifndef ATTRIBUTE #define ATTRIBUTE(...) __attribute__((__VA_ARGS__)) -#endif // #ifndef ATTRIBUTE +#endif // #ifndef ATTRIBUTE #ifndef __NE_VER__ #define __NE_VER__ (2024) -#endif // !__NE_VER__ +#endif // !__NE_VER__ #ifndef EXTERN #define EXTERN extern @@ -72,21 +71,17 @@ #endif #ifndef MAKE_ENUM -#define MAKE_ENUM(NAME) \ - enum NAME \ - { +#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 \ - { +#define MAKE_STRING_ENUM(NAME) namespace NAME { #endif #ifndef ENUM_STRING @@ -99,18 +94,18 @@ #ifndef RTL_ALLOCA #define RTL_ALLOCA(sz) __builtin_alloca(sz) -#endif // #ifndef RTL_ALLOCA +#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 kBadAddress 0x0000000000000000 +#define kMaxAddr 0xFFFFFFFFFFFFFFFF +#define kPathLen 0x100 -#define PACKED ATTRIBUTE(packed) +#define PACKED ATTRIBUTE(packed) #define NO_EXEC ATTRIBUTE(noexec) #define EXTERN extern @@ -119,36 +114,35 @@ #define CONST const #define STRINGIFY(X) #X -#define NE_UNUSED(X) ((Kernel::Void)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 +#endif // !RGB #ifdef __NE_AMD64__ #define dbg_break_point() asm volatile("int $3") #else -#define dbg_break_point() ((void)0) +#define dbg_break_point() ((void) 0) #endif -#define RTL_ENDIAN(address, value) \ - (((reinterpret_cast(address)[0]) == (value)) \ - ? (Kernel::Endian::kEndianBig) \ - : (Kernel::Endian::kEndianLittle)) +#define RTL_ENDIAN(address, value) \ + (((reinterpret_cast(address)[0]) == (value)) ? (Kernel::Endian::kEndianBig) \ + : (Kernel::Endian::kEndianLittle)) #define Yes true -#define No false +#define No false #define YES true -#define NO false +#define NO false -#define TRUE true +#define TRUE true #define FALSE false #define BOOL Kernel::Boolean #ifdef rtl_init_object #undef rtl_init_object -#endif // ifdef rtl_init_object +#endif // ifdef rtl_init_object #define rtl_init_object(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/dev/kernel/NewKit/MutableArray.h b/dev/kernel/NewKit/MutableArray.h index 40d61495..08c8cbf5 100644 --- a/dev/kernel/NewKit/MutableArray.h +++ b/dev/kernel/NewKit/MutableArray.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once @@ -9,231 +9,195 @@ #include #include -#define TRY_FIND_NODE(NAME, NODE) \ - auto* NAME = NODE; \ - while (NAME) \ - { \ - if (NAME->fIndex == Index) \ - return NAME->fVal; \ - NAME = NAME->fNext; \ - } - -#define TRY_FIND_NODE2(NAME, NODE) \ - auto* NAME = NODE; \ - while (NAME) \ - { \ - if (NAME->fIndex == Index) \ - return Ref{NAME->fVal}; \ - NAME = NAME->fNext; \ - } +#define TRY_FIND_NODE(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) { \ + if (NAME->fIndex == Index) return NAME->fVal; \ + NAME = NAME->fNext; \ + } + +#define TRY_FIND_NODE2(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) { \ + if (NAME->fIndex == Index) return Ref{NAME->fVal}; \ + NAME = NAME->fNext; \ + } #define TRY_REMOVE_NODE(NODE) \ - if (NODE && NODE->fIndex == Index) \ - { \ - NODE->fUsed = false; \ - NODE->fIndex = 0; \ + if (NODE && NODE->fIndex == Index) { \ + NODE->fUsed = false; \ + NODE->fIndex = 0; \ \ - return true; \ - } + return true; \ + } // FIXME: this is a shitty algorithm, which is consumer hungry. // Remove and occurences of that, and remove that class. -namespace Kernel -{ - template - class MutableArray; - - template - class NullableMutableArray; - - template - class MutableLinkedList - { - public: - T fVal; - SizeT fIndex{0}; - Boolean fUsed{false}; - - MutableLinkedList* fPrev{nullptr}; - MutableLinkedList* fNext{nullptr}; - }; - - template - class NullableMutableArray - { - public: - // explicit this. - explicit NullableMutableArray() - : fFirstNode(new MutableLinkedList()) - { - } - - /* - * We free all the nodes allocated by the array - * and store the next one inside "NextIt" - */ - - virtual ~NullableMutableArray() - { - auto* It = fFirstNode; - MutableLinkedList* 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 - { - TRY_FIND_NODE(first, fFirstNode); - TRY_FIND_NODE(last, fLastNode); - - return _PlaceHolderValue; - } - - SizeT Count() const - { - return fNodeCount; - } - - public: - Boolean Remove(SizeT Index) - { - TRY_REMOVE_NODE(fFirstNode); - 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* fLastNode{nullptr}; - MutableLinkedList* fFirstNode{nullptr}; - - /* Number of nodes inside of this dynamic array. */ - Kernel::SizeT fNodeCount{0}; - - private: - // don't remove that - friend MutableArray; - }; - - template - class MutableArray : public NullableMutableArray - { - 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(); - 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; - } +namespace Kernel { +template +class MutableArray; + +template +class NullableMutableArray; + +template +class MutableLinkedList { + public: + T fVal; + SizeT fIndex{0}; + Boolean fUsed{false}; + + MutableLinkedList* fPrev{nullptr}; + MutableLinkedList* fNext{nullptr}; +}; + +template +class NullableMutableArray { + public: + // explicit this. + explicit NullableMutableArray() : fFirstNode(new MutableLinkedList()) {} + + /* + * We free all the nodes allocated by the array + * and store the next one inside "NextIt" + */ + + virtual ~NullableMutableArray() { + auto* It = fFirstNode; + MutableLinkedList* 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 { + TRY_FIND_NODE(first, fFirstNode); + TRY_FIND_NODE(last, fLastNode); + + return _PlaceHolderValue; + } + + SizeT Count() const { return fNodeCount; } + + public: + Boolean Remove(SizeT Index) { + TRY_REMOVE_NODE(fFirstNode); + 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* fLastNode{nullptr}; + MutableLinkedList* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; + + private: + // don't remove that + friend MutableArray; +}; + +template +class MutableArray : public NullableMutableArray { + 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(); + 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 operator[](SizeT Index) const { + TRY_FIND_NODE2(first, fFirstNode); + TRY_FIND_NODE2(last, fLastNode); - public: - Ref operator[](SizeT Index) const - { - TRY_FIND_NODE2(first, fFirstNode); - TRY_FIND_NODE2(last, fLastNode); - - return {}; - } + return {}; + } - SizeT Count() const - { - return fNodeCount; - } + SizeT Count() const { return fNodeCount; } - bool Contains(T& value) noexcept - { - MutableLinkedList* first = fFirstNode; + bool Contains(T& value) noexcept { + MutableLinkedList* first = fFirstNode; - while (first) - { - if (first->fVal == value && first->fUsed) - return true; + while (first) { + if (first->fVal == value && first->fUsed) return true; - first = first->fNext; - } + first = first->fNext; + } - return false; - } + return false; + } - private: - /* Avoid useless lookups */ - MutableLinkedList* fLastNode{nullptr}; - MutableLinkedList* fFirstNode{nullptr}; + private: + /* Avoid useless lookups */ + MutableLinkedList* fLastNode{nullptr}; + MutableLinkedList* fFirstNode{nullptr}; - /* Number of nodes inside of this dynamic array. */ - Kernel::SizeT fNodeCount{0}; - }; -} // namespace Kernel + /* Number of nodes inside of this dynamic array. */ + Kernel::SizeT fNodeCount{0}; +}; +} // namespace Kernel diff --git a/dev/kernel/NewKit/New.h b/dev/kernel/NewKit/New.h index 7571206c..de242141 100644 --- a/dev/kernel/NewKit/New.h +++ b/dev/kernel/NewKit/New.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/NewKit/NewKit.h b/dev/kernel/NewKit/NewKit.h index 6c5f033b..66ca2bb3 100644 --- a/dev/kernel/NewKit/NewKit.h +++ b/dev/kernel/NewKit/NewKit.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/NewKit/OwnPtr.h b/dev/kernel/NewKit/OwnPtr.h index f15bc339..f00f51c4 100644 --- a/dev/kernel/NewKit/OwnPtr.h +++ b/dev/kernel/NewKit/OwnPtr.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,85 +11,58 @@ #include #include -namespace Kernel -{ - template - class OwnPtr; - - template - class NonNullRefPtr; - - template - class OwnPtr final - { - public: - OwnPtr() - { - } - ~OwnPtr() - { - this->Delete(); - } - - OwnPtr& operator=(const OwnPtr&) = default; - OwnPtr(const OwnPtr&) = default; - - public: - template - 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 AsRef() - { - return Ref(fCls); - } - - operator bool() - { - return fCls; - } - bool operator!() - { - return !fCls; - } - - private: - T* fCls; - }; - - template - inline OwnPtr mm_make_own_ptr(Args... args) - { - OwnPtr ret; - ret.template New(forward(args)...); - MUST_PASS(ret); - - return ret; - } -} // namespace Kernel +namespace Kernel { +template +class OwnPtr; + +template +class NonNullRefPtr; + +template +class OwnPtr final { + public: + OwnPtr() {} + ~OwnPtr() { this->Delete(); } + + OwnPtr& operator=(const OwnPtr&) = default; + OwnPtr(const OwnPtr&) = default; + + public: + template + 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 AsRef() { return Ref(fCls); } + + operator bool() { return fCls; } + bool operator!() { return !fCls; } + + private: + T* fCls; +}; + +template +inline OwnPtr mm_make_own_ptr(Args... args) { + OwnPtr ret; + ret.template New(forward(args)...); + MUST_PASS(ret); + + return ret; +} +} // namespace Kernel diff --git a/dev/kernel/NewKit/PageMgr.h b/dev/kernel/NewKit/PageMgr.h index bc8ee776..3aef2733 100644 --- a/dev/kernel/NewKit/PageMgr.h +++ b/dev/kernel/NewKit/PageMgr.h @@ -3,7 +3,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,70 +12,65 @@ #include #include -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& wrapper); - - private: - void FlushTLB(); - - private: - friend PTEWrapper; - friend class Pmm; - }; -} // namespace Kernel +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& wrapper); + + private: + void FlushTLB(); + + private: + friend PTEWrapper; + friend class Pmm; +}; +} // namespace Kernel diff --git a/dev/kernel/NewKit/Pair.h b/dev/kernel/NewKit/Pair.h index 8124cf56..28512831 100644 --- a/dev/kernel/NewKit/Pair.h +++ b/dev/kernel/NewKit/Pair.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,7 +8,6 @@ #include -namespace Kernel -{ - class Pair; -} // namespace Kernel +namespace Kernel { +class Pair; +} // namespace Kernel diff --git a/dev/kernel/NewKit/Pmm.h b/dev/kernel/NewKit/Pmm.h index 45770f86..41d988e1 100644 --- a/dev/kernel/NewKit/Pmm.h +++ b/dev/kernel/NewKit/Pmm.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,35 +10,30 @@ #include #include -namespace Kernel -{ - class Pmm; - class PTEWrapper; - - class Pmm final - { - public: - explicit Pmm(); - ~Pmm(); - - Pmm& operator=(const Pmm&) = delete; - Pmm(const Pmm&) = default; - - Ref RequestPage(Boolean user = false, Boolean readWrite = false); - Boolean FreePage(Ref refPage); - - Boolean ToggleRw(Ref refPage, Boolean enable = true); - Boolean TogglePresent(Ref refPage, Boolean enable = true); - Boolean ToggleUser(Ref refPage, Boolean enable = true); - Boolean ToggleShare(Ref refPage, Boolean enable = true); - - /// @brief Get the page manager of this. - Ref& Leak() - { - return fPageMgr; - } - - private: - Ref fPageMgr; - }; -} // namespace Kernel +namespace Kernel { +class Pmm; +class PTEWrapper; + +class Pmm final { + public: + explicit Pmm(); + ~Pmm(); + + Pmm& operator=(const Pmm&) = delete; + Pmm(const Pmm&) = default; + + Ref RequestPage(Boolean user = false, Boolean readWrite = false); + Boolean FreePage(Ref refPage); + + Boolean ToggleRw(Ref refPage, Boolean enable = true); + Boolean TogglePresent(Ref refPage, Boolean enable = true); + Boolean ToggleUser(Ref refPage, Boolean enable = true); + Boolean ToggleShare(Ref refPage, Boolean enable = true); + + /// @brief Get the page manager of this. + Ref& Leak() { return fPageMgr; } + + private: + Ref fPageMgr; +}; +} // namespace Kernel diff --git a/dev/kernel/NewKit/Ref.h b/dev/kernel/NewKit/Ref.h index 7ec0825a..6737ce09 100644 --- a/dev/kernel/NewKit/Ref.h +++ b/dev/kernel/NewKit/Ref.h @@ -1,109 +1,79 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef _NEWKIT_REF_H_ #define _NEWKIT_REF_H_ +#include #include #include -#include -namespace Kernel -{ - template - class Ref final - { - public: - Ref() = default; - - ~Ref() - { - if (mm_is_valid_heap(fClass)) - delete fClass; - } - - public: - Ref(T* cls) - : fClass(cls) - { - } - - Ref(T cls) - : fClass(nullptr) - { - fClass = new T(cls); - } - - Ref& operator=(T ref) - { - if (!fClass) - return *this; - - fClass = &ref; - return *this; - } - - public: - T operator->() const - { - MUST_PASS(*fClass); - return *fClass; - } - - T& Leak() noexcept - { - return *fClass; - } - - T& TryLeak() const noexcept - { - MUST_PASS(*fClass); - return *fClass; - } - - T operator*() - { - return *fClass; - } - - operator bool() noexcept - { - return fClass; - } - - private: - T* fClass{nullptr}; - }; - - template - class NonNullRef final - { - public: - NonNullRef() = delete; - NonNullRef(nullPtr) = delete; - - NonNullRef(T* ref) - : fRef(ref) - { - MUST_PASS(ref); - } - - Ref& operator->() - { - MUST_PASS(fRef); - return fRef; - } - - NonNullRef& operator=(const NonNullRef& ref) = delete; - NonNullRef(const NonNullRef& ref) = default; - - private: - Ref fRef{nullptr}; - }; -} // namespace Kernel - -#endif // ifndef _NEWKIT_REF_H_ +namespace Kernel { +template +class Ref final { + public: + Ref() = default; + + ~Ref() { + if (mm_is_valid_heap(fClass)) delete fClass; + } + + public: + Ref(T* cls) : fClass(cls) {} + + Ref(T cls) : fClass(nullptr) { fClass = new T(cls); } + + Ref& operator=(T ref) { + if (!fClass) return *this; + + fClass = &ref; + return *this; + } + + public: + T operator->() const { + MUST_PASS(*fClass); + return *fClass; + } + + T& Leak() noexcept { return *fClass; } + + T& TryLeak() const noexcept { + MUST_PASS(*fClass); + return *fClass; + } + + T operator*() { return *fClass; } + + operator bool() noexcept { return fClass; } + + private: + T* fClass{nullptr}; +}; + +template +class NonNullRef final { + public: + NonNullRef() = delete; + NonNullRef(nullPtr) = delete; + + NonNullRef(T* ref) : fRef(ref) { MUST_PASS(ref); } + + Ref& operator->() { + MUST_PASS(fRef); + return fRef; + } + + NonNullRef& operator=(const NonNullRef& ref) = delete; + NonNullRef(const NonNullRef& ref) = default; + + private: + Ref fRef{nullptr}; +}; +} // namespace Kernel + +#endif // ifndef _NEWKIT_REF_H_ diff --git a/dev/kernel/NewKit/Stream.h b/dev/kernel/NewKit/Stream.h index dfe1881c..8b72046c 100644 --- a/dev/kernel/NewKit/Stream.h +++ b/dev/kernel/NewKit/Stream.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,49 +10,36 @@ #include #include -namespace Kernel -{ - template - class Stream final - { - public: - explicit Stream(Ref ref) - : fStream(ref) - { - } - - ~Stream() = default; - - Stream& operator=(const Stream&) = default; - Stream(const Stream&) = default; - - template - friend Stream& operator>>(Stream& Ks, Ref& Buf) - { - Ks.fKind = Ks.fStream->In(Buf); - return *Ks; - } - - template - friend Stream& operator<<(Stream& Ks, Ref& Buf) - { - Ks.fKind = Buf; - Ks.fStream->Out(Buf.Leak()); - return *Ks; - } - - Ref& AsStreamTrait() - { - return fStream; - } - - Ref& AsType() - { - return fKind; - } - - private: - Ref fStream; - Ref fKind; - }; -} // namespace Kernel +namespace Kernel { +template +class Stream final { + public: + explicit Stream(Ref ref) : fStream(ref) {} + + ~Stream() = default; + + Stream& operator=(const Stream&) = default; + Stream(const Stream&) = default; + + template + friend Stream& operator>>(Stream& Ks, Ref& Buf) { + Ks.fKind = Ks.fStream->In(Buf); + return *Ks; + } + + template + friend Stream& operator<<(Stream& Ks, Ref& Buf) { + Ks.fKind = Buf; + Ks.fStream->Out(Buf.Leak()); + return *Ks; + } + + Ref& AsStreamTrait() { return fStream; } + + Ref& AsType() { return fKind; } + + private: + Ref fStream; + Ref fKind; +}; +} // namespace Kernel diff --git a/dev/kernel/NewKit/Utils.h b/dev/kernel/NewKit/Utils.h index 7340631b..ca1c7d1c 100644 --- a/dev/kernel/NewKit/Utils.h +++ b/dev/kernel/NewKit/Utils.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,23 +9,22 @@ #include -namespace Kernel -{ - 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 wrt_string_len(const Utf16Char* 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(Char chr); - Boolean rt_is_space(Char chr); - Int32 rt_is_alnum(Int32 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); -} // namespace Kernel +namespace Kernel { +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 wrt_string_len(const Utf16Char* 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(Char chr); +Boolean rt_is_space(Char chr); +Int32 rt_is_alnum(Int32 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); +} // namespace Kernel diff --git a/dev/kernel/NewKit/Variant.h b/dev/kernel/NewKit/Variant.h index a55b8a7b..83602602 100644 --- a/dev/kernel/NewKit/Variant.h +++ b/dev/kernel/NewKit/Variant.h @@ -1,80 +1,61 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -#include #include +#include #include -namespace Kernel -{ - class Variant final - { - public: - enum class VariantKind - { - kString, - kBlob, - kNull, - kJson, - kXML, - kSwap, - kInvalid, - }; - - public: - explicit Variant() = delete; - - public: - NE_COPY_DEFAULT(Variant) - - ~Variant() = default; - - public: - explicit Variant(KString* stringView) - : fPtr((VoidPtr)stringView), fKind(VariantKind::kString) - { - } - - explicit Variant(Json* json) - : fPtr((VoidPtr)json), fKind(VariantKind::kJson) - { - } - - 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(); - VoidPtr Leak(); - - template - T* As() - { - return reinterpret_cast(fPtr); - } - - VariantKind& Kind(); - - private: - voidPtr fPtr{nullptr}; - VariantKind fKind{VariantKind::kNull}; - }; -} // namespace Kernel +namespace Kernel { +class Variant final { + public: + enum class VariantKind { + kString, + kBlob, + kNull, + kJson, + kXML, + kSwap, + kInvalid, + }; + + public: + explicit Variant() = delete; + + public: + NE_COPY_DEFAULT(Variant) + + ~Variant() = default; + + public: + explicit Variant(KString* stringView) : fPtr((VoidPtr) stringView), fKind(VariantKind::kString) {} + + explicit Variant(Json* json) : fPtr((VoidPtr) json), fKind(VariantKind::kJson) {} + + 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(); + VoidPtr Leak(); + + template + T* As() { + return reinterpret_cast(fPtr); + } + + VariantKind& Kind(); + + private: + voidPtr fPtr{nullptr}; + VariantKind fKind{VariantKind::kNull}; +}; +} // namespace Kernel diff --git a/dev/kernel/SignalKit/Signals.h b/dev/kernel/SignalKit/Signals.h index 2859ab22..ba0b80cb 100644 --- a/dev/kernel/SignalKit/Signals.h +++ b/dev/kernel/SignalKit/Signals.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -19,7 +19,6 @@ #define SIGATCH 661 #define SIGDTCH 662 -namespace Kernel -{ - typedef UInt32 SignalKind; +namespace Kernel { +typedef UInt32 SignalKind; } \ No newline at end of file diff --git a/dev/kernel/StorageKit/AHCI.h b/dev/kernel/StorageKit/AHCI.h index 68a42c46..d40feb36 100644 --- a/dev/kernel/StorageKit/AHCI.h +++ b/dev/kernel/StorageKit/AHCI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,42 +10,40 @@ #include #include -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 IDeviceObject class. - class AHCIDeviceInterface NE_DEVICE - { - public: - explicit AHCIDeviceInterface(void (*out)(IDeviceObject* self, MountpointInterface* out), - void (*in)(IDeviceObject* self, MountpointInterface* in)); +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 IDeviceObject class. +class AHCIDeviceInterface NE_DEVICE { + public: + explicit AHCIDeviceInterface(void (*out)(IDeviceObject* self, MountpointInterface* out), + void (*in)(IDeviceObject* self, MountpointInterface* in)); - virtual ~AHCIDeviceInterface() override; + virtual ~AHCIDeviceInterface() override; - public: - AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default; - AHCIDeviceInterface(const AHCIDeviceInterface&) = default; + public: + AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default; + AHCIDeviceInterface(const AHCIDeviceInterface&) = default; - const Char* Name() const override; + const Char* Name() const override; - const UInt16& GetPortsImplemented(); + const UInt16& GetPortsImplemented(); - Void SetPortsImplemented(const UInt16& pi); + Void SetPortsImplemented(const UInt16& pi); - const UInt32& GetIndex(); + const UInt32& GetIndex(); - Void SetIndex(const UInt32& drv); + Void SetIndex(const UInt32& drv); - public: - AHCIDeviceInterface& operator<<(MountpointInterface* Data) override; - AHCIDeviceInterface& operator>>(MountpointInterface* Data) override; + public: + AHCIDeviceInterface& operator<<(MountpointInterface* Data) override; + AHCIDeviceInterface& operator>>(MountpointInterface* Data) override; - private: - UInt16 fPortsImplemented{0U}; - UInt32 fDriveIndex{0U}; - }; + private: + UInt16 fPortsImplemented{0U}; + UInt32 fDriveIndex{0U}; +}; - UInt16 sk_init_ahci_device(BOOL atapi); - ErrorOr sk_acquire_ahci_device(Int32 drv_index); -} // namespace Kernel +UInt16 sk_init_ahci_device(BOOL atapi); +ErrorOr sk_acquire_ahci_device(Int32 drv_index); +} // namespace Kernel diff --git a/dev/kernel/StorageKit/ATA.h b/dev/kernel/StorageKit/ATA.h index 04cf88d7..d2950228 100644 --- a/dev/kernel/StorageKit/ATA.h +++ b/dev/kernel/StorageKit/ATA.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,48 +11,46 @@ #include #include -namespace Kernel -{ - /// @brief ATA device interface class. - class ATADeviceInterface : public IDeviceObject - { - public: - explicit ATADeviceInterface(void (*Out)(IDeviceObject*, MountpointInterface* outpacket), - void (*In)(IDeviceObject*, MountpointInterface* inpacket)); +namespace Kernel { +/// @brief ATA device interface class. +class ATADeviceInterface : public IDeviceObject { + public: + explicit ATADeviceInterface(void (*Out)(IDeviceObject*, MountpointInterface* outpacket), + void (*In)(IDeviceObject*, MountpointInterface* inpacket)); - virtual ~ATADeviceInterface(); + virtual ~ATADeviceInterface(); - public: - ATADeviceInterface& operator<<(MountpointInterface* Data) override; - ATADeviceInterface& operator>>(MountpointInterface* Data) override; + public: + ATADeviceInterface& operator<<(MountpointInterface* Data) override; + ATADeviceInterface& operator>>(MountpointInterface* Data) override; - public: - ATADeviceInterface& operator=(const ATADeviceInterface&) = default; - ATADeviceInterface(const ATADeviceInterface&) = default; + public: + ATADeviceInterface& operator=(const ATADeviceInterface&) = default; + ATADeviceInterface(const ATADeviceInterface&) = default; - const Char* Name() const override; + const Char* Name() const override; - const UInt16& GetIO(); - Void SetIO(const UInt16& io); + const UInt16& GetIO(); + Void SetIO(const UInt16& io); - const UInt16& GetMaster(); - Void SetMaster(const UInt16& master); + const UInt16& GetMaster(); + Void SetMaster(const UInt16& master); - const UInt32& GetIndex(); - Void SetIndex(const UInt32& drv); + const UInt32& GetIndex(); + Void SetIndex(const UInt32& drv); - private: - UInt32 fDriveIndex{0U}; - UInt16 fIO, fMaster{0U}; - }; + 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_pio_device(BOOL is_master, UInt16& io, UInt8& master); +/// @brief Initialize an PIO device (StorageKit function) +/// @param is_master is the current PIO master? +/// @return [io:master] for PIO device. +BOOL sk_init_pio_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 sk_acquire_pio_device(Int32 drv_index); -} // namespace Kernel +/// @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 sk_acquire_pio_device(Int32 drv_index); +} // namespace Kernel diff --git a/dev/kernel/StorageKit/NVME.h b/dev/kernel/StorageKit/NVME.h index c86135d0..aae36a94 100644 --- a/dev/kernel/StorageKit/NVME.h +++ b/dev/kernel/StorageKit/NVME.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,26 +9,24 @@ #include #include -namespace Kernel -{ - class NVMEDeviceInterface final NE_DEVICE - { - public: - explicit NVMEDeviceInterface(Void (*out)(IDeviceObject*, MountpointInterface* out_packet), - Void (*in)(IDeviceObject*, MountpointInterface* in_packet), - Void (*cleanup)(Void)); +namespace Kernel { +class NVMEDeviceInterface final NE_DEVICE { + public: + explicit NVMEDeviceInterface(Void (*out)(IDeviceObject*, MountpointInterface* out_packet), + Void (*in)(IDeviceObject*, MountpointInterface* in_packet), + Void (*cleanup)(Void)); - ~NVMEDeviceInterface() override; + ~NVMEDeviceInterface() override; - public: - NE_COPY_DEFAULT(NVMEDeviceInterface) + public: + NE_COPY_DEFAULT(NVMEDeviceInterface) - const Char* Name() const override; + const Char* Name() const override; - public: - OwnPtr operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz); + public: + OwnPtr operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz); - private: - Void (*fCleanup)(Void) = {nullptr}; - }; -} // namespace Kernel + private: + Void (*fCleanup)(Void) = {nullptr}; +}; +} // namespace Kernel diff --git a/dev/kernel/StorageKit/PRDT.h b/dev/kernel/StorageKit/PRDT.h index dde9c208..f67cad05 100644 --- a/dev/kernel/StorageKit/PRDT.h +++ b/dev/kernel/StorageKit/PRDT.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,25 +12,22 @@ #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& prd); - - EXTERN_C Int32 kPRDTTransferStatus; -} // namespace Kernel +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& prd); + +EXTERN_C Int32 kPRDTTransferStatus; +} // namespace Kernel diff --git a/dev/kernel/StorageKit/SCSI.h b/dev/kernel/StorageKit/SCSI.h index 2a4c2393..25e11716 100644 --- a/dev/kernel/StorageKit/SCSI.h +++ b/dev/kernel/StorageKit/SCSI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,6 +8,4 @@ #include -namespace Kernel -{ -} // namespace Kernel \ No newline at end of file +namespace Kernel {} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/StorageKit/StorageKit.h b/dev/kernel/StorageKit/StorageKit.h index bbd34476..9dbb014d 100644 --- a/dev/kernel/StorageKit/StorageKit.h +++ b/dev/kernel/StorageKit/StorageKit.h @@ -1,22 +1,21 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once -#define kDriveSectorSizeHDD (512U) -#define kDriveSectorSizeSSD (512U) +#define kDriveSectorSizeHDD (512U) +#define kDriveSectorSizeSSD (512U) #define kDriveSectorSizeOptical (2048) -namespace Kernel -{ - template - class IDeviceObject; +namespace Kernel { +template +class IDeviceObject; - class NVMEDeviceInterface; - class AHCIDeviceInterface; - class ATADeviceInterface; - class SCSIDeviceInterface; -} // namespace Kernel +class NVMEDeviceInterface; +class AHCIDeviceInterface; +class ATADeviceInterface; +class SCSIDeviceInterface; +} // namespace Kernel diff --git a/dev/kernel/SwapKit/DiskSwap.h b/dev/kernel/SwapKit/DiskSwap.h index 78b1a896..b7e403aa 100644 --- a/dev/kernel/SwapKit/DiskSwap.h +++ b/dev/kernel/SwapKit/DiskSwap.h @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025 Amlal El Mahrouss Labs, all rights reserved. + Copyright (C) 2024-2025 Amlal El Mahrouss Labs, all rights reserved. ------------------------------------------- */ #pragma once -#include #include +#include #include #define kSwapBlockMaxSize (mib_cast(16)) @@ -17,58 +17,56 @@ /// @file SwapDisk.h /// @brief Virtual memory swap disk. -namespace Kernel -{ - struct SWAP_DISK_HEADER; - class DiskSwapInterface; +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; +/// @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) + NE_COPY_DELETE(DiskSwapInterface) + NE_MOVE_DELETE(DiskSwapInterface) - public: - /***********************************************************************************/ - /// @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 Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data); + public: + /***********************************************************************************/ + /// @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 Write(const Char* fork_name, SizeT fork_name_len, SWAP_DISK_HEADER* data); - /***********************************************************************************/ - /// @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. - /***********************************************************************************/ - _Output SWAP_DISK_HEADER* Read(const Char* fork_name, SizeT fork_name_len, SizeT data_len); - }; + /***********************************************************************************/ + /// @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. + /***********************************************************************************/ + _Output SWAP_DISK_HEADER* Read(const Char* fork_name, SizeT fork_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 SWAP_DISK_HEADER; -} // namespace Kernel +/// @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 SWAP_DISK_HEADER; +} // namespace Kernel diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index 9a3c30d0..a76caff2 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -1,101 +1,87 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include -#include #include #include +#include +#include + +namespace Kernel { +/// @brief Finds a descriptor table inside ACPI XSDT. +ErrorOr ACPIFactoryInterface::Find(const Char* signature) { + MUST_PASS(this->fRsdp); + + if (!signature) return ErrorOr{-1}; + + if (*signature == 0) return ErrorOr{-1}; + + RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); + + if (rsp_ptr->Revision <= 1) return ErrorOr{-1}; + + RSDT* xsdt = reinterpret_cast(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{-1}; + } + + 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); + + const short cAcpiSignatureLength = 4; + + for (Size index = 0; index < this->fEntries; ++index) { + SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); + + (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); + (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); + + for (short 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(reinterpret_cast(xsdt->AddressArr[index])); + } + } + } + + return ErrorOr{-1}; +} + +/*** +@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) return 1; + + char chr = 0; + + for (int index = 0; index < len; ++index) { + chr += checksum[index]; + } + + return chr == 0; +} -namespace Kernel -{ - /// @brief Finds a descriptor table inside ACPI XSDT. - ErrorOr ACPIFactoryInterface::Find(const Char* signature) - { - MUST_PASS(this->fRsdp); - - if (!signature) - return ErrorOr{-1}; - - if (*signature == 0) - return ErrorOr{-1}; - - RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - - if (rsp_ptr->Revision <= 1) - return ErrorOr{-1}; - - RSDT* xsdt = reinterpret_cast(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{-1}; - } - - 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); - - const short cAcpiSignatureLength = 4; - - for (Size index = 0; index < this->fEntries; ++index) - { - SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); - - (Void)(kout << "ACPI: Checksum: " << number(sdt->Checksum) << kendl); - (Void)(kout << "ACPI: Revision: " << number(sdt->Revision) << kendl); - - for (short 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(reinterpret_cast(xsdt->AddressArr[index])); - } - } - } - - return ErrorOr{-1}; - } - - /*** - @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) - return 1; - - char chr = 0; - - for (int index = 0; index < len; ++index) - { - chr += checksum[index]; - } - - return chr == 0; - } - - ErrorOr ACPIFactoryInterface::operator[](const Char* signature) - { - return this->Find(signature); - } -} // namespace Kernel +ErrorOr ACPIFactoryInterface::operator[](const Char* signature) { + return this->Find(signature); +} +} // namespace Kernel diff --git a/dev/kernel/src/Array.cc b/dev/kernel/src/Array.cc index 334231f0..7cb1b156 100644 --- a/dev/kernel/src/Array.cc +++ b/dev/kernel/src/Array.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/ArrayList.cc b/dev/kernel/src/ArrayList.cc index ee9dab93..269dc47e 100644 --- a/dev/kernel/src/ArrayList.cc +++ b/dev/kernel/src/ArrayList.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/Atom.cc b/dev/kernel/src/Atom.cc index bbeebd45..8968a2c2 100644 --- a/dev/kernel/src/Atom.cc +++ b/dev/kernel/src/Atom.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/BinaryMutex.cc b/dev/kernel/src/BinaryMutex.cc index f9faadd2..8bf1432e 100644 --- a/dev/kernel/src/BinaryMutex.cc +++ b/dev/kernel/src/BinaryMutex.cc @@ -1,75 +1,66 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include +#include -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Unlocks the binary mutex. - /***********************************************************************************/ - Bool BinaryMutex::Unlock() noexcept - { - if (fLockingProcess) - { - fLockingProcess = USER_PROCESS(); - fLockingProcess.Status = ProcessStatusKind::kFrozen; - - 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::LockOrWait(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 Int16& sec) noexcept - { - HardwareTimer hw_timer(rtl_milliseconds(sec)); - hw_timer.Wait(); - - return !this->IsLocked(); - } -} // namespace Kernel +namespace Kernel { +/***********************************************************************************/ +/// @brief Unlocks the binary mutex. +/***********************************************************************************/ +Bool BinaryMutex::Unlock() noexcept { + if (fLockingProcess) { + fLockingProcess = USER_PROCESS(); + fLockingProcess.Status = ProcessStatusKind::kFrozen; + + 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::LockOrWait(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 Int16& 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 index 83efe4eb..948c6ff3 100644 --- a/dev/kernel/src/BitMapMgr.cc +++ b/dev/kernel/src/BitMapMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -15,204 +15,179 @@ #include #include -#define kBitMapMagic (0x10210U) +#define kBitMapMagic (0x10210U) -#define kBitMapMagIdx (0U) +#define kBitMapMagIdx (0U) #define kBitMapSizeIdx (1U) #define kBitMapUsedIdx (2U) -namespace Kernel -{ - namespace HAL - { - namespace Detail - { - /***********************************************************************************/ - /// \brief Proxy Interface to manage a bitmap allocator. - /***********************************************************************************/ - class IBitMapProxy final - { - public: - explicit IBitMapProxy() = default; - ~IBitMapProxy() = default; +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) + NE_COPY_DELETE(IBitMapProxy) - auto IsBitMap(VoidPtr page_ptr) -> Bool - { - if (!page_ptr) - return No; + auto IsBitMap(VoidPtr page_ptr) -> Bool { + if (!page_ptr) return No; - UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); + UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); - if (!ptr_bit_set[kBitMapMagIdx] || - ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) - return No; + if (!ptr_bit_set[kBitMapMagIdx] || ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) return No; - return Yes; - } + return Yes; + } - auto FreeBitMap(VoidPtr page_ptr) -> Bool - { - if (this->IsBitMap(page_ptr) == No) - return No; + auto FreeBitMap(VoidPtr page_ptr) -> Bool { + if (this->IsBitMap(page_ptr) == No) return No; - UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); + UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); - ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[kBitMapUsedIdx] = No; + ptr_bit_set[kBitMapMagIdx] = kBitMapMagic; + ptr_bit_set[kBitMapUsedIdx] = No; - this->GetBitMapStatus(ptr_bit_set); - - return Yes; - } + this->GetBitMapStatus(ptr_bit_set); - UInt32 MakeMMFlags(Bool wr, Bool user) - { - UInt32 flags = kMMFlagsPresent; - - if (wr) - flags |= kMMFlagsWr; - - if (user) - flags |= kMMFlagsUser; - - flags |= HAL::kMMFlagsPCD; - - 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; - - VoidPtr base = reinterpret_cast((UIntPtr)base_ptr); - - MUST_PASS(base); - - static SizeT biggest = 0UL; - - while (YES) - { - UIntPtr* ptr_bit_set = reinterpret_cast(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, ptr_bit_set, flags); - - if (biggest < (size + pad)) - biggest = 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, ptr_bit_set, flags); - - if (biggest < (size + pad)) - biggest = (size + pad); - - return (VoidPtr)ptr_bit_set; - } - - UIntPtr raw_base = reinterpret_cast(base); - UIntPtr offset = (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) - ? (size + pad) - : ptr_bit_set[kBitMapSizeIdx]; - - base = reinterpret_cast(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 - - auto mm_is_bitmap(VoidPtr ptr) -> BOOL - { - Detail::IBitMapProxy bitmp; - return bitmp.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; - Detail::IBitMapProxy bitmp; - - NE_UNUSED(is_page); - - ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user, pad); - return (UIntPtr*)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; - - Detail::IBitMapProxy bitmp; - Bool ret = bitmp.FreeBitMap(ptr); - - return ret; - } - } // namespace HAL -} // namespace Kernel + return Yes; + } + + UInt32 MakeMMFlags(Bool wr, Bool user) { + UInt32 flags = kMMFlagsPresent; + + if (wr) flags |= kMMFlagsWr; + + if (user) flags |= kMMFlagsUser; + + flags |= HAL::kMMFlagsPCD; + + 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; + + VoidPtr base = reinterpret_cast((UIntPtr) base_ptr); + + MUST_PASS(base); + + static SizeT biggest = 0UL; + + while (YES) { + UIntPtr* ptr_bit_set = reinterpret_cast(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, ptr_bit_set, flags); + + if (biggest < (size + pad)) biggest = 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, ptr_bit_set, flags); + + if (biggest < (size + pad)) biggest = (size + pad); + + return (VoidPtr) ptr_bit_set; + } + + UIntPtr raw_base = reinterpret_cast(base); + UIntPtr offset = (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) + ? (size + pad) + : ptr_bit_set[kBitMapSizeIdx]; + + base = reinterpret_cast(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 + + auto mm_is_bitmap(VoidPtr ptr) -> BOOL { + Detail::IBitMapProxy bitmp; + return bitmp.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; + Detail::IBitMapProxy bitmp; + + NE_UNUSED(is_page); + + ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user, pad); + return (UIntPtr*) 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; + + Detail::IBitMapProxy bitmp; + Bool ret = bitmp.FreeBitMap(ptr); + + return ret; + } +} // namespace HAL +} // namespace Kernel diff --git a/dev/kernel/src/CodeMgr.cc b/dev/kernel/src/CodeMgr.cc index 3604df30..c4ac011c 100644 --- a/dev/kernel/src/CodeMgr.cc +++ b/dev/kernel/src/CodeMgr.cc @@ -1,28 +1,25 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -#include #include +#include -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 if the process was started or not. - /***********************************************************************************/ +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 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; +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(main), nullptr); - } -} // namespace Kernel + return UserProcessScheduler::The().Spawn(process_name, reinterpret_cast(main), nullptr); +} +} // namespace Kernel diff --git a/dev/kernel/src/Crc32.cc b/dev/kernel/src/Crc32.cc index cd22a762..332faa33 100644 --- a/dev/kernel/src/Crc32.cc +++ b/dev/kernel/src/Crc32.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,57 +9,53 @@ // @file CRC32.cpp // @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 Char* in, Int32 len) noexcept - { - if (!in || *in == 0) - return ~0; - - UInt32 crc = 0xffffffff; - - while ((len--) > 0) - crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF]; - - return ~crc; - } -} // namespace Kernel +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 Char* in, Int32 len) noexcept { + if (!in || *in == 0) return ~0; + + UInt32 crc = 0xffffffff; + + while ((len--) > 0) crc = (crc >> 8) ^ kChecksumPolys[(crc ^ *(in++)) & 0xFF]; + + return ~crc; +} +} // namespace Kernel diff --git a/dev/kernel/src/CxxAbi-AMD64.cc b/dev/kernel/src/CxxAbi-AMD64.cc index 950e0c02..452f23cd 100644 --- a/dev/kernel/src/CxxAbi-AMD64.cc +++ b/dev/kernel/src/CxxAbi-AMD64.cc @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifdef __NE_AMD64__ #include -#include #include +#include atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; @@ -17,74 +17,61 @@ 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(self))); - (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); +EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) { + (Kernel::Void)(Kernel::kout << "object: " + << Kernel::number(reinterpret_cast(self))); + (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); } -EXTERN_C void ___chkstk_ms(void) -{ - (Kernel::Void)(Kernel::kout << "Stack smashing detected!\r"); - dbg_break_point(); +EXTERN_C void ___chkstk_ms(void) { + (Kernel::Void)(Kernel::kout << "Stack smashing detected!\r"); + dbg_break_point(); } -EXTERN_C int atexit(void (*f)()) -{ - if (__atexit_func_count >= kAtExitMacDestructors) - return 1; +EXTERN_C int atexit(void (*f)()) { + if (__atexit_func_count >= kAtExitMacDestructors) return 1; + + __atexit_funcs[__atexit_func_count].destructor_func = f; + + __atexit_func_count++; - __atexit_funcs[__atexit_func_count].destructor_func = f; + 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; + }; + } +} - __atexit_func_count++; +namespace cxxabiv1 { +EXTERN_C int __cxa_guard_acquire(__guard* g) { + (void) g; + return 0; +} - return 0; +EXTERN_C int __cxa_guard_release(__guard* g) { + *(char*) g = 1; + 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; - }; - } +EXTERN_C void __cxa_guard_abort(__guard* g) { + (void) g; } +} // namespace cxxabiv1 -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 - -#endif // ifdef __NE_AMD64__ +#endif // ifdef __NE_AMD64__ diff --git a/dev/kernel/src/CxxAbi-ARM64.cc b/dev/kernel/src/CxxAbi-ARM64.cc index b3db3815..1605692b 100644 --- a/dev/kernel/src/CxxAbi-ARM64.cc +++ b/dev/kernel/src/CxxAbi-ARM64.cc @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifdef __NE_ARM64__ #include -#include #include +#include atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; @@ -17,91 +17,74 @@ uarch_t __atexit_func_count; /// @brief dynamic shared object Handle. Kernel::UIntPtr __dso_handle; -EXTERN_C void __chkstk(void) -{ -} +EXTERN_C void __chkstk(void) {} -EXTERN_C int atexit(void (*f)(void*), void* arg, void* dso) -{ - if (__atexit_func_count >= kAtExitMacDestructors) - return 1; +EXTERN_C int atexit(void (*f)(void*), 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_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++; + __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].obj_ptr); + }; + } + + return; + } + + while (i--) { + if (__atexit_funcs[i].destructor_func) { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); + __atexit_funcs[i].destructor_func = 0; + }; + } +} + +namespace cxxabiv1 { +EXTERN_C int __cxa_guard_acquire(__guard* g) { + (void) g; + return 0; +} - return 0; +EXTERN_C int __cxa_guard_release(__guard* g) { + *(char*) g = 1; + 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].obj_ptr); - }; - } - - return; - } - - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr); - __atexit_funcs[i].destructor_func = 0; - }; - } +EXTERN_C void __cxa_guard_abort(__guard* g) { + (void) g; } +} // namespace cxxabiv1 -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(self))); - (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); +EXTERN_C Kernel::Void _purecall(void* self) { + (Kernel::Void)(Kernel::kout << "object: " + << Kernel::number(reinterpret_cast(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_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_epoch(Kernel::Void) { + NE_UNUSED(0); } -EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) -{ - NE_UNUSED(0); +EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) { + NE_UNUSED(0); } EXTERN_C Kernel::Int _tls_index = 0UL; -#endif // ifdef __NE_ARM64__ +#endif // ifdef __NE_ARM64__ diff --git a/dev/kernel/src/Defines.cc b/dev/kernel/src/Defines.cc index ab832d80..7f6e571d 100644 --- a/dev/kernel/src/Defines.cc +++ b/dev/kernel/src/Defines.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/DeviceMgr.cc b/dev/kernel/src/DeviceMgr.cc index 8594d051..c137552e 100644 --- a/dev/kernel/src/DeviceMgr.cc +++ b/dev/kernel/src/DeviceMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/DriveMgr+IO.cc b/dev/kernel/src/DriveMgr+IO.cc index 99f947bf..4c9b20e0 100644 --- a/dev/kernel/src/DriveMgr+IO.cc +++ b/dev/kernel/src/DriveMgr+IO.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -20,77 +20,70 @@ /// Useful macros. #define rtl_nefs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS) -#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS) +#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS) -namespace Kernel -{ - /// @brief Read from newfs disk. - /// @param Mnt mounted interface. - /// @param DrvTrait drive info - /// @param DrvIndex drive index. - /// @return - Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) - { - if (!Mnt) - return 1; +namespace Kernel { +/// @brief Read from newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) { + if (!Mnt) return 1; - DrvTrait.fPacket.fPacketGood = false; + DrvTrait.fPacket.fPacketGood = false; - switch (DrvIndex) - { - case MountpointInterface::kDriveIndexA: { - rtl_nefs_read(A, DrvTrait.fPacket, Mnt); - break; - } - case MountpointInterface::kDriveIndexB: { - rtl_nefs_read(B, DrvTrait.fPacket, Mnt); - break; - } - case MountpointInterface::kDriveIndexC: { - rtl_nefs_read(C, DrvTrait.fPacket, Mnt); - break; - } - case MountpointInterface::kDriveIndexD: { - rtl_nefs_read(D, DrvTrait.fPacket, Mnt); - break; - } - } + switch (DrvIndex) { + case MountpointInterface::kDriveIndexA: { + rtl_nefs_read(A, DrvTrait.fPacket, Mnt); + break; + } + case MountpointInterface::kDriveIndexB: { + rtl_nefs_read(B, DrvTrait.fPacket, Mnt); + break; + } + case MountpointInterface::kDriveIndexC: { + rtl_nefs_read(C, DrvTrait.fPacket, Mnt); + break; + } + case MountpointInterface::kDriveIndexD: { + rtl_nefs_read(D, DrvTrait.fPacket, Mnt); + break; + } + } - return DrvTrait.fPacket.fPacketGood; - } + return DrvTrait.fPacket.fPacketGood; +} - /// @brief Write to newfs disk. - /// @param Mnt mounted interface. - /// @param DrvTrait drive info - /// @param DrvIndex drive index. - /// @return - Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) - { - if (!Mnt) - return 1; +/// @brief Write to newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) { + if (!Mnt) return 1; - DrvTrait.fPacket.fPacketGood = false; + DrvTrait.fPacket.fPacketGood = false; - switch (DrvIndex) - { - case MountpointInterface::kDriveIndexA: { - rtl_nefs_write(A, DrvTrait.fPacket, Mnt); - break; - } - case MountpointInterface::kDriveIndexB: { - rtl_nefs_write(B, DrvTrait.fPacket, Mnt); - break; - } - case MountpointInterface::kDriveIndexC: { - rtl_nefs_write(C, DrvTrait.fPacket, Mnt); - break; - } - case MountpointInterface::kDriveIndexD: { - rtl_nefs_write(D, DrvTrait.fPacket, Mnt); - break; - } - } + switch (DrvIndex) { + case MountpointInterface::kDriveIndexA: { + rtl_nefs_write(A, DrvTrait.fPacket, Mnt); + break; + } + case MountpointInterface::kDriveIndexB: { + rtl_nefs_write(B, DrvTrait.fPacket, Mnt); + break; + } + case MountpointInterface::kDriveIndexC: { + rtl_nefs_write(C, DrvTrait.fPacket, Mnt); + break; + } + case MountpointInterface::kDriveIndexD: { + rtl_nefs_write(D, DrvTrait.fPacket, Mnt); + break; + } + } - return DrvTrait.fPacket.fPacketGood; - } -} // namespace Kernel \ No newline at end of file + return DrvTrait.fPacket.fPacketGood; +} +} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index b5a8e9e4..763096b3 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -1,16 +1,16 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include +#include #include #include #include -#include -#include -#include #include +#include #include /***********************************************************************************/ @@ -18,233 +18,211 @@ /// @brief Drive Manager of kernel. /***********************************************************************************/ -namespace Kernel -{ +namespace Kernel { #if defined(__ATA_PIO__) || defined(__ATA_DMA__) - STATIC UInt16 kATAIO = 0U; - STATIC UInt8 kATAMaster = 0U; +STATIC UInt16 kATAIO = 0U; +STATIC UInt8 kATAMaster = 0U; #endif #if defined(__AHCI__) - STATIC UInt16 kAHCIPortsImplemented = 0UL; +STATIC UInt16 kAHCIPortsImplemented = 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) - { +/// @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); + drv_std_read(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize); #elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_read(pckt.fPacketLba, kATAIO, kATAMaster, (Char*)pckt.fPacketContent, kATASectorSize, pckt.fPacketSize); + 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; - } +} + +/// @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; + } #ifdef __AHCI__ - drv_std_write(pckt.fPacketLba, (Char*)pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize); + drv_std_write(pckt.fPacketLba, (Char*) pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize); #elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_write(pckt.fPacketLba, kATAIO, kATAMaster, (Char*)pckt.fPacketContent, kATASectorSize, pckt.fPacketSize); + 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) - { - NE_UNUSED(pckt); +/// @brief Executes a disk check on the ATA drive. +/// @param pckt the packet to read. +/// @return +Void io_drv_init(DriveTrait::DrivePacket pckt) { + NE_UNUSED(pckt); #if defined(__ATA_PIO__) || defined(__ATA_DMA__) - kATAMaster = 0; - kATAIO = 0; + kATAMaster = 0; + kATAIO = 0; - kATAMaster = YES; - kATAIO = ATA_PRIMARY_IO; + kATAMaster = YES; + kATAIO = ATA_PRIMARY_IO; - if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) - { - pckt.fPacketGood = YES; - return; - } + if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) { + pckt.fPacketGood = YES; + return; + } - kATAMaster = NO; - kATAIO = ATA_SECONDARY_IO; + kATAMaster = NO; + kATAIO = ATA_SECONDARY_IO; - if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) - { - pckt.fPacketGood = YES; - return; - } + if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) { + pckt.fPacketGood = YES; + return; + } - pckt.fPacketGood = YES; + pckt.fPacketGood = YES; #elif defined(__AHCI__) - kAHCIPortsImplemented = 0; + kAHCIPortsImplemented = 0; - if (drv_std_init(kAHCIPortsImplemented)) - { - pckt.fPacketGood = YES; - } -#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) - } + if (drv_std_init(kAHCIPortsImplemented)) { + pckt.fPacketGood = YES; + } +#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"; - } +const Char* io_drv_kind(Void) { + return "ATA-PIO"; +} #elif defined(__ATA_DMA__) - const Char* io_drv_kind(Void) - { - return "ATA-DMA"; - } +const Char* io_drv_kind(Void) { + return "ATA-DMA"; +} #elif defined(__AHCI__) - const Char* io_drv_kind(Void) - { - return "AHCI"; - } +const Char* io_drv_kind(Void) { + return "AHCI"; +} #else - const Char* io_drv_kind(Void) - { - return "null"; - } +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 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; +/// @brief Makes a new drive. +/// @return the new blank drive. +DriveTrait io_construct_blank_drive() noexcept { + DriveTrait trait; - constexpr auto kBlankDrive = "/media/blank/"; + constexpr auto kBlankDrive = "/media/blank/"; - rt_copy_memory((VoidPtr)kBlankDrive, trait.fName, rt_string_len(kBlankDrive)); - trait.fKind = kInvalidDrive; + 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; + 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 << "Construct: " << trait.fName << "\r"; + kout << "Construct: " << trait.fName << "\r"; - return trait; - } + return trait; +} - namespace Detail - { - Void io_detect_drive(DriveTrait& trait) - { - trait.fInit(trait.fPacket); +namespace Detail { + Void io_detect_drive(DriveTrait& trait) { + trait.fInit(trait.fPacket); - EPM_PART_BLOCK block_struct; + EPM_PART_BLOCK block_struct; - trait.fPacket.fPacketLba = kEPMBootBlockLba; - trait.fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); - trait.fPacket.fPacketContent = &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")); + rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime, + rt_string_len("fs/detect-packet")); - trait.fInput(trait.fPacket); + trait.fInput(trait.fPacket); - if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) - { - trait.fPacket.fPacketReadOnly = NO; - trait.fKind = kMassStorageDrive | kEPMDrive; + if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) { + trait.fPacket.fPacketReadOnly = NO; + trait.fKind = kMassStorageDrive | kEPMDrive; - kout << "Disk is EPM formatted.\r"; + kout << "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.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; + 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")); + rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime, + rt_string_len("fs/detect-packet")); - trait.fInput(trait.fPacket); + trait.fInput(trait.fPacket); - if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0) - { - trait.fPacket.fPacketReadOnly = NO; - trait.fKind = kMassStorageDrive | kGPTDrive; + if (rt_string_cmp(gpt_struct.Signature, kMagicGPT, kMagicLenGPT) == 0) { + trait.fPacket.fPacketReadOnly = NO; + trait.fKind = kMassStorageDrive | kGPTDrive; - kout << "Disk is GPT formatted.\r"; + kout << "Disk is GPT formatted.\r"; - trait.fSectorSz = gpt_struct.SizeOfEntries; - trait.fLbaEnd = gpt_struct.LastGPTEntry; - trait.fLbaStart = gpt_struct.FirstGPTEntry; - } - else - { - kout << "Disk is unformatted.\r"; + trait.fSectorSz = gpt_struct.SizeOfEntries; + trait.fLbaEnd = gpt_struct.LastGPTEntry; + trait.fLbaStart = gpt_struct.FirstGPTEntry; + } else { + kout << "Disk is unformatted.\r"; - trait.fPacket.fPacketReadOnly = YES; - trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive; - } - } + trait.fPacket.fPacketReadOnly = YES; + trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive; + } + } - rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime, - rt_string_len("*/*")); + rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime, rt_string_len("*/*")); - trait.fPacket.fPacketLba = 0; - trait.fPacket.fPacketSize = 0UL; - trait.fPacket.fPacketContent = nullptr; - } - } // namespace Detail + trait.fPacket.fPacketLba = 0; + trait.fPacket.fPacketSize = 0UL; + trait.fPacket.fPacketContent = nullptr; + } +} // namespace Detail - /// @brief Fetches the main drive. - /// @return the new drive. (returns kEPMDrive if EPM formatted) - DriveTrait io_construct_main_drive() noexcept - { - DriveTrait trait; +/// @brief Fetches the main drive. +/// @return the new drive. (returns kEPMDrive if EPM formatted) +DriveTrait io_construct_main_drive() noexcept { + DriveTrait trait; - constexpr auto kMainDrive = "/media/main/"; + constexpr auto kMainDrive = "/media/main/"; - rt_copy_memory((VoidPtr)kMainDrive, trait.fName, rt_string_len(kMainDrive)); + rt_copy_memory((VoidPtr) kMainDrive, trait.fName, rt_string_len(kMainDrive)); - MUST_PASS(trait.fName[0] != 0); + 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; + 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; - kout << "Detecting partition scheme of: " << trait.fName << ".\r"; + kout << "Detecting partition scheme of: " << trait.fName << ".\r"; - Detail::io_detect_drive(trait); + Detail::io_detect_drive(trait); - return trait; - } -} // namespace Kernel + return trait; +} +} // namespace Kernel diff --git a/dev/kernel/src/ErrorOr.cc b/dev/kernel/src/ErrorOr.cc index 97c19ca3..69668b2f 100644 --- a/dev/kernel/src/ErrorOr.cc +++ b/dev/kernel/src/ErrorOr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/FS/Ext2+FileMgr.cc b/dev/kernel/src/FS/Ext2+FileMgr.cc index cb17b587..a55d917a 100644 --- a/dev/kernel/src/FS/Ext2+FileMgr.cc +++ b/dev/kernel/src/FS/Ext2+FileMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,5 +10,5 @@ #include #include -#endif // ifdef __FSKIT_INCLUDES_EXT2__ -#endif // ifndef __NE_MINIMAL_OS__ +#endif // ifdef __FSKIT_INCLUDES_EXT2__ +#endif // ifndef __NE_MINIMAL_OS__ diff --git a/dev/kernel/src/FS/Ext2.cc b/dev/kernel/src/FS/Ext2.cc index 8331f506..b6d04f46 100644 --- a/dev/kernel/src/FS/Ext2.cc +++ b/dev/kernel/src/FS/Ext2.cc @@ -1,21 +1,21 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifdef __FSKIT_INCLUDES_EXT2__ -#include -#include #include +#include #include +#include +#include #include -#include #include +#include #include -#include -#include -#include +#include +#include -#endif // ifdef __FSKIT_INCLUDES_EXT2__ +#endif // ifdef __FSKIT_INCLUDES_EXT2__ diff --git a/dev/kernel/src/FS/HeFS+FileMgr.cc b/dev/kernel/src/FS/HeFS+FileMgr.cc index e6719e1b..e0b92a8d 100644 --- a/dev/kernel/src/FS/HeFS+FileMgr.cc +++ b/dev/kernel/src/FS/HeFS+FileMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,5 +10,5 @@ #include #include -#endif // ifdef __FSKIT_INCLUDES_HEFS__ -#endif // ifndef __NE_MINIMAL_OS__ +#endif // ifdef __FSKIT_INCLUDES_HEFS__ +#endif // ifndef __NE_MINIMAL_OS__ diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 7864bc6f..88837273 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -1,714 +1,669 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifdef __FSKIT_INCLUDES_HEFS__ -#include -#include #include -#include -#include -#include -#include -#include #include #include +#include #include #include +#include +#include +#include +#include +#include +#include + +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, Lba& start); + + /// @brief Get the index node of a file or directory. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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* hefs_fetch_index_node( + HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, + UInt8 kind, SizeT* cnt) noexcept; + + /// @brief Get the index node size. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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 SizeT + hefs_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, + const Utf16Char* file_name, UInt8 kind) noexcept; + + /// @brief Allocate a new index node. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read/write from. + /// @param parent_dir_name The name of the parent directory. + /// @return Status, see err_global_get(). + STATIC ATTRIBUTE(unused) _Output BOOL + hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, + const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; + + /// @brief Balance RB-Tree of the filesystem. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read/write from. + /// @return Status, see err_global_get(). + STATIC ATTRIBUTE(unused) _Output BOOL + hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt); + + /// @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, Lba& start) { + start = dir->fNext; + + if (dir->fColor == kHeFSBlack && start == 0) { + if (dir->fParent != 0) start = dir->fParent; + } else if (dir->fColor == kHeFSRed && start == 0) { + if (dir->fChild != 0) + start = dir->fChild; + else if (dir->fNext != 0) + start = dir->fNext; + else if (dir->fPrev != 0) + start = dir->fPrev; + else + start = dir->fParent; + } + } + + /***********************************************************************************/ + /// @brief Rotate the RB-Tree to the left. + /// @internal + /***********************************************************************************/ + STATIC ATTRIBUTE(unused) _Output Void + hefsi_rotate_left(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) { + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!parent) { + kout << "Error: Failed to allocate memory for index node.\r"; + return; + } + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fInput(mnt->fPacket); + + HEFS_INDEX_NODE_DIRECTORY* grand_parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!grand_parent) { + delete parent; + kout << "Error: Failed to allocate memory for index node.\r"; + + return; + } + + mnt->fPacket.fPacketLba = parent->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = grand_parent; + + mnt->fInput(mnt->fPacket); + + dir->fParent = parent->fParent; + parent->fParent = start; + parent->fNext = dir->fChild; + dir->fChild = dir->fParent; + + mnt->fPacket.fPacketLba = parent->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = grand_parent; + + mnt->fOutput(mnt->fPacket); + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fOutput(mnt->fPacket); + + delete parent; + parent = nullptr; + + delete grand_parent; + grand_parent = nullptr; + + dir->fColor = kHeFSBlack; + } + + /***********************************************************************************/ + /// @brief Rotate the RB-Tree to the right. + /// @internal + /***********************************************************************************/ + STATIC ATTRIBUTE(unused) _Output Void + hefsi_rotate_right(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) { + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!parent) { + kout << "Error: Failed to allocate memory for index node.\r"; + + return; + } + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fInput(mnt->fPacket); + + parent->fParent = dir->fParent; + dir->fParent = parent->fParent; + dir->fNext = parent->fChild; + parent->fChild = start; + + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fOutput(mnt->fPacket); + + delete parent; + parent = nullptr; + + dir->fColor = kHeFSBlack; + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fOutput(mnt->fPacket); + } + + /// @brief Get the index node size. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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 SizeT + hefs_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, + const Utf16Char* file_name, UInt8 kind) noexcept { + if (root && mnt) { + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + SizeT sz = 0UL; + + auto start = root->fStartIND; + auto end = root->fEndIND; + + auto hop_watch = 0; + + while (YES) { + if (start > end) { + kout << "Error: Invalid start/end values.\r"; + break; + } + + if (hop_watch > 100) { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) { + delete node; + delete dir; + + dir = nullptr; + node = nullptr; + + err_global_get() = kErrorFileNotFound; + + return 0; + } + + if (dir->fKind == kHeFSFileKindDirectory) { + if (KStringBuilder::Equals(dir_name, dir->fName) || + KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) { + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { + if (dir->fIndexNodeStart[inode_index]) { + mnt->fPacket.fPacketLba = dir->fIndexNodeStart[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + mnt->fInput(mnt->fPacket); + } else if (dir->fIndexNodeEnd[inode_index]) { + mnt->fPacket.fPacketLba = dir->fIndexNodeEnd[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + mnt->fInput(mnt->fPacket); + } + + if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) { + if (node->fKind == kHeFSFileKindDirectory) { + sz += hefs_fetch_index_node_size(root, mnt, dir_name, file_name, kind); + } else { + sz = node->fSize; + } + + return sz; + } + } + } + } + } + + err_global_get() = kErrorSuccess; + return sz; + } + + err_global_get() = kErrorFileNotFound; + return 0; + } + + /// @brief Get the index node of a file or directory. + /// @param root The root node of the filesystem. + /// @param mnt The drive 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* hefs_fetch_index_node( + HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, + UInt8 kind, SizeT* cnt) noexcept { + if (root && mnt) { + HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt]; + + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!node) { + kout << "Error: Failed to allocate memory for index node.\r"; + return nullptr; + } + + auto start = root->fStartIND; + auto end = root->fEndIND; + + auto start_cnt = 0UL; + + auto hop_watch = 0; + + while (YES) { + if (start > end) { + kout << "Error: Invalid start/end values.\r"; + break; + } + + if (hop_watch > 100) { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) { + delete node; + delete dir; + + dir = nullptr; + node = nullptr; + + err_global_get() = kErrorFileNotFound; + + return nullptr; + } + + if (dir->fKind == kHeFSFileKindDirectory) { + if (KStringBuilder::Equals(dir_name, dir->fName) || + KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) { + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { + if (dir->fIndexNodeStart[inode_index] != 0 || dir->fIndexNodeEnd[inode_index] != 0) { + mnt->fPacket.fPacketLba = (!dir->fIndexNodeStart[inode_index]) + ? dir->fIndexNodeEnd[inode_index] + : dir->fIndexNodeStart[inode_index]; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; + + mnt->fInput(mnt->fPacket); + + if (mnt->fPacket.fPacketGood) { + if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) { + delete dir; + dir = nullptr; + + node_arr[start_cnt] = *node; + ++start_cnt; + + if (start_cnt > *cnt) { + delete node; + return node_arr; + } + } + } else { + err_global_get() = kErrorDiskIsCorrupted; + + delete dir; + delete node; + delete[] node_arr; + + dir = nullptr; + node = nullptr; + node_arr = nullptr; + + return nullptr; + } + } + } + } + } + + hefsi_traverse_tree(dir, start); + } + + delete dir; + delete node; + delete[] node_arr; + + dir = nullptr; + node = nullptr; + node_arr = nullptr; + } + + kout << "Error: Failed to find index node.\r"; + + err_global_get() = kErrorFileNotFound; + + return nullptr; + } + + /// @brief Allocate a new index node. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read from. + /// @param parent_dir_name The name of the parent directory. + /// @return Status, see err_global_get(). + STATIC ATTRIBUTE(unused) _Output BOOL + hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, + const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept { + if (root && mnt) { + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + auto start = root->fStartIND; + + auto hop_watch = 0; + + while (YES) { + if (hop_watch > 100) { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (KStringBuilder::Equals(dir->fName, parent_dir_name)) { + for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) { + if (dir->fIndexNodeStart[inode_index] != 0 || dir->fIndexNodeEnd[inode_index] != 0) { + HEFS_INDEX_NODE prev_node; + + auto lba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] + : dir->fIndexNodeStart[inode_index]; + + mnt->fPacket.fPacketLba = lba; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = &prev_node; + + mnt->fInput(mnt->fPacket); + + if (prev_node.fDeleted > 0 && !prev_node.fAccessed) { + mnt->fPacket.fPacketLba = lba; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); + mnt->fPacket.fPacketContent = node; -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, Lba& start); - - /// @brief Get the index node of a file or directory. - /// @param root The root node of the filesystem. - /// @param mnt The drive 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* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind, SizeT* cnt) noexcept; - - /// @brief Get the index node size. - /// @param root The root node of the filesystem. - /// @param mnt The drive 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 SizeT hefs_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept; - - /// @brief Allocate a new index node. - /// @param root The root node of the filesystem. - /// @param mnt The drive to read/write from. - /// @param parent_dir_name The name of the parent directory. - /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) _Output BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept; - - /// @brief Balance RB-Tree of the filesystem. - /// @param root The root node of the filesystem. - /// @param mnt The drive to read/write from. - /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt); - - /// @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, Lba& start) - { - start = dir->fNext; - - if (dir->fColor == kHeFSBlack && start == 0) - { - if (dir->fParent != 0) - start = dir->fParent; - } - else if (dir->fColor == kHeFSRed && start == 0) - { - if (dir->fChild != 0) - start = dir->fChild; - else if (dir->fNext != 0) - start = dir->fNext; - else if (dir->fPrev != 0) - start = dir->fPrev; - else - start = dir->fParent; - } - } - - /***********************************************************************************/ - /// @brief Rotate the RB-Tree to the left. - /// @internal - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_left(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) - { - HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); - - if (!parent) - { - kout << "Error: Failed to allocate memory for index node.\r"; - return; - } - - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = parent; - - mnt->fInput(mnt->fPacket); - - HEFS_INDEX_NODE_DIRECTORY* grand_parent = new HEFS_INDEX_NODE_DIRECTORY(); - - if (!grand_parent) - { - delete parent; - kout << "Error: Failed to allocate memory for index node.\r"; - - return; - } - - mnt->fPacket.fPacketLba = parent->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = grand_parent; - - mnt->fInput(mnt->fPacket); - - dir->fParent = parent->fParent; - parent->fParent = start; - parent->fNext = dir->fChild; - dir->fChild = dir->fParent; - - mnt->fPacket.fPacketLba = parent->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = grand_parent; - - mnt->fOutput(mnt->fPacket); - - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = parent; - - mnt->fOutput(mnt->fPacket); - - delete parent; - parent = nullptr; - - delete grand_parent; - grand_parent = nullptr; - - dir->fColor = kHeFSBlack; - } - - /***********************************************************************************/ - /// @brief Rotate the RB-Tree to the right. - /// @internal - /***********************************************************************************/ - STATIC ATTRIBUTE(unused) _Output Void hefsi_rotate_right(HEFS_INDEX_NODE_DIRECTORY* dir, Lba& start, DriveTrait* mnt) - { - HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); - - if (!parent) - { - kout << "Error: Failed to allocate memory for index node.\r"; - - return; - } - - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = parent; - - mnt->fInput(mnt->fPacket); - - parent->fParent = dir->fParent; - dir->fParent = parent->fParent; - dir->fNext = parent->fChild; - parent->fChild = start; - - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = parent; - - mnt->fOutput(mnt->fPacket); - - delete parent; - parent = nullptr; - - dir->fColor = kHeFSBlack; - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fOutput(mnt->fPacket); - } - - /// @brief Get the index node size. - /// @param root The root node of the filesystem. - /// @param mnt The drive 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 SizeT hefs_fetch_index_node_size(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind) noexcept - { - if (root && mnt) - { - HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); - HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); - - SizeT sz = 0UL; - - auto start = root->fStartIND; - auto end = root->fEndIND; - - auto hop_watch = 0; - - while (YES) - { - if (start > end) - { - kout << "Error: Invalid start/end values.\r"; - break; - } - - if (hop_watch > 100) - { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - - if (start == 0) - { - ++hop_watch; - start = root->fStartIND; - } - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fInput(mnt->fPacket); - - if (!mnt->fPacket.fPacketGood) - { - delete node; - delete dir; - - dir = nullptr; - node = nullptr; - - err_global_get() = kErrorFileNotFound; - - return 0; - } - - if (dir->fKind == kHeFSFileKindDirectory) - { - if (KStringBuilder::Equals(dir_name, dir->fName) || - KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) - { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) - { - if (dir->fIndexNodeStart[inode_index]) - { - mnt->fPacket.fPacketLba = dir->fIndexNodeStart[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - mnt->fInput(mnt->fPacket); - } - else if (dir->fIndexNodeEnd[inode_index]) - { - mnt->fPacket.fPacketLba = dir->fIndexNodeEnd[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - mnt->fInput(mnt->fPacket); - } - - if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) - { - if (node->fKind == kHeFSFileKindDirectory) - { - sz += hefs_fetch_index_node_size(root, mnt, dir_name, file_name, kind); - } - else - { - sz = node->fSize; - } - - return sz; - } - } - } - } - } - - err_global_get() = kErrorSuccess; - return sz; - } - - err_global_get() = kErrorFileNotFound; - return 0; - } - - /// @brief Get the index node of a file or directory. - /// @param root The root node of the filesystem. - /// @param mnt The drive 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* hefs_fetch_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name, const Utf16Char* file_name, UInt8 kind, SizeT* cnt) noexcept - { - if (root && mnt) - { - HEFS_INDEX_NODE* node_arr = new HEFS_INDEX_NODE[*cnt]; - - HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); - HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); - - if (!node) - { - kout << "Error: Failed to allocate memory for index node.\r"; - return nullptr; - } - - auto start = root->fStartIND; - auto end = root->fEndIND; - - auto start_cnt = 0UL; - - auto hop_watch = 0; - - while (YES) - { - if (start > end) - { - kout << "Error: Invalid start/end values.\r"; - break; - } - - if (hop_watch > 100) - { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - - if (start == 0) - { - ++hop_watch; - start = root->fStartIND; - } - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fInput(mnt->fPacket); - - if (!mnt->fPacket.fPacketGood) - { - delete node; - delete dir; - - dir = nullptr; - node = nullptr; - - err_global_get() = kErrorFileNotFound; - - return nullptr; - } - - if (dir->fKind == kHeFSFileKindDirectory) - { - if (KStringBuilder::Equals(dir_name, dir->fName) || - KStringBuilder::Equals(dir_name, kHeFSSearchAllStr)) - { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) - { - if (dir->fIndexNodeStart[inode_index] != 0 || - dir->fIndexNodeEnd[inode_index] != 0) - { - mnt->fPacket.fPacketLba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] : dir->fIndexNodeStart[inode_index]; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - - mnt->fInput(mnt->fPacket); - - if (mnt->fPacket.fPacketGood) - { - if (KStringBuilder::Equals(file_name, node->fName) && node->fKind == kind) - { - delete dir; - dir = nullptr; - - node_arr[start_cnt] = *node; - ++start_cnt; - - if (start_cnt > *cnt) - { - delete node; - return node_arr; - } - } - } - else - { - err_global_get() = kErrorDiskIsCorrupted; - - delete dir; - delete node; - delete[] node_arr; - - dir = nullptr; - node = nullptr; - node_arr = nullptr; - - return nullptr; - } - } - } - } - } - - hefsi_traverse_tree(dir, start); - } - - delete dir; - delete node; - delete[] node_arr; - - dir = nullptr; - node = nullptr; - node_arr = nullptr; - } - - kout << "Error: Failed to find index node.\r"; - - err_global_get() = kErrorFileNotFound; - - return nullptr; - } - - /// @brief Allocate a new index node. - /// @param root The root node of the filesystem. - /// @param mnt The drive to read from. - /// @param parent_dir_name The name of the parent directory. - /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) _Output BOOL hefs_allocate_index_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* parent_dir_name, HEFS_INDEX_NODE* node) noexcept - { - if (root && mnt) - { - HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); - - auto start = root->fStartIND; - - auto hop_watch = 0; - - while (YES) - { - if (hop_watch > 100) - { - kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; - break; - } - - if (start == 0) - { - ++hop_watch; - start = root->fStartIND; - } - - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; - - mnt->fInput(mnt->fPacket); - - if (KStringBuilder::Equals(dir->fName, parent_dir_name)) - { - for (SizeT inode_index = 0UL; inode_index < kHeFSBlockCount; inode_index += 2) - { - if (dir->fIndexNodeStart[inode_index] != 0 || - dir->fIndexNodeEnd[inode_index] != 0) - { - HEFS_INDEX_NODE prev_node; - - auto lba = (!dir->fIndexNodeStart[inode_index]) ? dir->fIndexNodeEnd[inode_index] : dir->fIndexNodeStart[inode_index]; - - mnt->fPacket.fPacketLba = lba; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = &prev_node; - - mnt->fInput(mnt->fPacket); - - if (prev_node.fDeleted > 0 && - !prev_node.fAccessed) - { - mnt->fPacket.fPacketLba = lba; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE); - mnt->fPacket.fPacketContent = node; - - mnt->fOutput(mnt->fPacket); + mnt->fOutput(mnt->fPacket); - if (mnt->fPacket.fPacketGood) - { - delete dir; - dir = nullptr; + if (mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - return YES; - } - } - } - } - } + return YES; + } + } + } + } + } - hefsi_traverse_tree(dir, start); - } + hefsi_traverse_tree(dir, start); + } - delete dir; - dir = nullptr; + delete dir; + dir = nullptr; - return YES; - } + return YES; + } - return NO; - } + return NO; + } - /// @brief Balance RB-Tree of the filesystem. - /// @param root The root node of the filesystem. - /// @param mnt The drive to read/write from. - /// @return Status, see err_global_get(). - STATIC ATTRIBUTE(unused) _Output BOOL hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt) - { - if (root && mnt) - { - HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); - HEFS_INDEX_NODE_DIRECTORY* dir_parent = new HEFS_INDEX_NODE_DIRECTORY(); + /// @brief Balance RB-Tree of the filesystem. + /// @param root The root node of the filesystem. + /// @param mnt The drive to read/write from. + /// @return Status, see err_global_get(). + STATIC ATTRIBUTE(unused) _Output BOOL + hefsi_balance_filesystem(HEFS_BOOT_NODE* root, DriveTrait* mnt) { + if (root && mnt) { + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + HEFS_INDEX_NODE_DIRECTORY* dir_parent = new HEFS_INDEX_NODE_DIRECTORY(); - auto start = root->fStartIND; + auto start = root->fStartIND; - while (YES) - { - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; + while (YES) { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; - mnt->fInput(mnt->fPacket); + mnt->fInput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) - { - delete dir; - dir = nullptr; + if (!mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - err_global_get() = kErrorDiskIsCorrupted; + err_global_get() = kErrorDiskIsCorrupted; - return NO; - } + return NO; + } - if (start == root->fStartIND) - { - dir->fColor = kHeFSBlack; + if (start == root->fStartIND) { + dir->fColor = kHeFSBlack; - mnt->fPacket.fPacketLba = start; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir; + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; - mnt->fOutput(mnt->fPacket); - } + mnt->fOutput(mnt->fPacket); + } - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_parent; + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; - mnt->fInput(mnt->fPacket); + mnt->fInput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) - { - delete dir; - dir = nullptr; + if (!mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - err_global_get() = kErrorDiskIsCorrupted; + err_global_get() = kErrorDiskIsCorrupted; - return NO; - } + return NO; + } - HEFS_INDEX_NODE_DIRECTORY dir_uncle{}; + HEFS_INDEX_NODE_DIRECTORY dir_uncle{}; - mnt->fPacket.fPacketLba = dir_parent->fNext; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = &dir_uncle; + mnt->fPacket.fPacketLba = dir_parent->fNext; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = &dir_uncle; - mnt->fInput(mnt->fPacket); + mnt->fInput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) - { - delete dir; - dir = nullptr; + if (!mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - err_global_get() = kErrorDiskIsCorrupted; + err_global_get() = kErrorDiskIsCorrupted; - return NO; - } + return NO; + } - if (dir_uncle.fColor == kHeFSRed) - { - dir_parent->fColor = kHeFSBlack; - dir_uncle.fColor = kHeFSBlack; + if (dir_uncle.fColor == kHeFSRed) { + dir_parent->fColor = kHeFSBlack; + dir_uncle.fColor = kHeFSBlack; - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_parent; + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; - mnt->fOutput(mnt->fPacket); + mnt->fOutput(mnt->fPacket); - mnt->fPacket.fPacketLba = dir_uncle.fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = &dir_uncle; + mnt->fPacket.fPacketLba = dir_uncle.fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = &dir_uncle; - mnt->fOutput(mnt->fPacket); + mnt->fOutput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) - { - delete dir; - dir = nullptr; + if (!mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - err_global_get() = kErrorDiskIsCorrupted; + err_global_get() = kErrorDiskIsCorrupted; - return NO; - } + return NO; + } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, start); - continue; - } - else - { - if (dir_parent->fNext == start) - { - hefsi_rotate_left(dir, start, mnt); - hefsi_traverse_tree(dir, start); + continue; + } else { + if (dir_parent->fNext == start) { + hefsi_rotate_left(dir, start, mnt); + hefsi_traverse_tree(dir, start); - continue; - } + continue; + } - dir_parent->fColor = kHeFSBlack; + dir_parent->fColor = kHeFSBlack; - mnt->fPacket.fPacketLba = dir->fParent; - mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); - mnt->fPacket.fPacketContent = dir_parent; + mnt->fPacket.fPacketLba = dir->fParent; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir_parent; - mnt->fOutput(mnt->fPacket); + mnt->fOutput(mnt->fPacket); - if (!mnt->fPacket.fPacketGood) - { - delete dir; - dir = nullptr; + if (!mnt->fPacket.fPacketGood) { + delete dir; + dir = nullptr; - err_global_get() = kErrorDiskIsCorrupted; + err_global_get() = kErrorDiskIsCorrupted; - return NO; - } + return NO; + } - hefsi_rotate_right(dir, start, mnt); - hefsi_traverse_tree(dir, start); + hefsi_rotate_right(dir, start, mnt); + hefsi_traverse_tree(dir, start); - continue; - } + continue; + } - hefsi_traverse_tree(dir, start); - } + hefsi_traverse_tree(dir, start); + } - delete dir; - dir = nullptr; + delete dir; + dir = nullptr; - return YES; - } + return YES; + } - return NO; - } - } // namespace Detail -} // namespace Kernel + return NO; + } +} // namespace Detail +} // namespace Kernel -/// @note HeFS will allocate inodes and ind in advance, to avoid having to allocate them in real-time. +/// @note HeFS 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+HeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool HeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name) - { - NE_UNUSED(drive); - NE_UNUSED(end_lba); - NE_UNUSED(flags); - NE_UNUSED(part_name); - - return NO; - } - - /// @brief Make a EPM+HeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool HeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name) - { - NE_UNUSED(drive); - NE_UNUSED(end_lba); - NE_UNUSED(flags); - NE_UNUSED(part_name); - - return NO; - } -} // namespace Kernel - -#endif // ifdef __FSKIT_INCLUDES_HEFS__ +namespace Kernel { +/// @brief Make a EPM+HeFS drive out of the disk. +/// @param drive The drive to write on. +/// @return If it was sucessful, see err_local_get(). +_Output Bool HeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, + _Input const Lba end_lba, _Input const Int32 flags, + const Char* part_name) { + NE_UNUSED(drive); + NE_UNUSED(end_lba); + NE_UNUSED(flags); + NE_UNUSED(part_name); + + return NO; +} + +/// @brief Make a EPM+HeFS drive out of the disk. +/// @param drive The drive to write on. +/// @return If it was sucessful, see err_local_get(). +_Output Bool HeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, + _Input const Lba end_lba, _Input const Int32 flags, + const Char* part_name) { + NE_UNUSED(drive); + NE_UNUSED(end_lba); + NE_UNUSED(flags); + NE_UNUSED(part_name); + + return NO; +} +} // namespace Kernel + +#endif // ifdef __FSKIT_INCLUDES_HEFS__ diff --git a/dev/kernel/src/FS/NeFS+FileMgr.cc b/dev/kernel/src/FS/NeFS+FileMgr.cc index 348ae61b..56fc2dbb 100644 --- a/dev/kernel/src/FS/NeFS+FileMgr.cc +++ b/dev/kernel/src/FS/NeFS+FileMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,233 +13,192 @@ /// @brief NeFS File manager. /// BUGS: 0 -namespace Kernel -{ - /// @brief C++ constructor - NeFileSystemMgr::NeFileSystemMgr() - { - NeFileSystemParser* mParser = new NeFileSystemParser(); - MUST_PASS(mParser); - - kout << "We are done allocating NeFileSystemParser...\r"; - } - - NeFileSystemMgr::~NeFileSystemMgr() - { - if (mParser) - { - kout << "Destroying NeFileSystemParser...\r"; - mm_delete_class(&mParser); - } - } - - /// @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) - 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) - { - return node_cast(mParser->CreateCatalog(path)); - } - - /// @brief Creates a node with is a directory. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) - { - return node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir)); - } - - /// @brief Creates a node with is a alias. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateAlias(const Char* path) - { - return node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); - } - - /// @brief Creates a node with is a page file. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) - { - return 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) - return nullptr; - - if (!r || *r == 0) - return nullptr; - - auto catalog = mParser->GetCatalog(path); - - return node_cast(catalog); - } - - /// @brief Writes to a catalog's fork. - /// @param node the node ptr. - /// @param data the data. - /// @param flags the size. - /// @return - Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) - { - if (!node) - return; - if (!size) - return; - - constexpr auto kDataForkName = kNeFSDataFork; - this->Write(kDataForkName, node, data, flags, size); - } - - /// @brief Read from filesystem fork. - /// @param node the catalog node. - /// @param flags the flags with it. - /// @param sz the size to read. - /// @return - _Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) - { - if (!node) - return nullptr; - if (!size) - 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 (!size || - size > kNeFSForkSize) - return; - - if (!data) - return; - - NE_UNUSED(flags); - - if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) - mParser->WriteCatalog(reinterpret_cast(node)->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 (sz > kNeFSForkSize) - return nullptr; - - if (!sz) - return nullptr; - - NE_UNUSED(flags); - - if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) - return mParser->ReadCatalog(reinterpret_cast(node), (flags & kFileFlagRsrc ? true : false), sz, - name); - - return nullptr; - } - - /// @brief Seek from Catalog. - /// @param node - /// @param off - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) - { - if (!node || off == 0) - return false; - - return mParser->Seek(reinterpret_cast(node), off); - } - - /// @brief Tell where the catalog is. - /// @param node - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output SizeT NeFileSystemMgr::Tell(NodePtr node) - { - if (!node) - return kNPos; - - return mParser->Tell(reinterpret_cast(node)); - } - - /// @brief Rewinds the catalog. - /// @param node - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output Bool NeFileSystemMgr::Rewind(NodePtr node) - { - if (!node) - return false; - - return this->Seek(node, 0); - } - - /// @brief Returns the filesystem parser. - /// @return the Filesystem parser class. - _Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept - { - return mParser; - } -} // namespace Kernel - -#endif // ifdef __FSKIT_INCLUDES_NEFS__ -#endif // ifndef __NE_MINIMAL_OS__ +namespace Kernel { +/// @brief C++ constructor +NeFileSystemMgr::NeFileSystemMgr() { + NeFileSystemParser* mParser = new NeFileSystemParser(); + MUST_PASS(mParser); + + kout << "We are done allocating NeFileSystemParser...\r"; +} + +NeFileSystemMgr::~NeFileSystemMgr() { + if (mParser) { + kout << "Destroying NeFileSystemParser...\r"; + mm_delete_class(&mParser); + } +} + +/// @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) 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) { + return node_cast(mParser->CreateCatalog(path)); +} + +/// @brief Creates a node with is a directory. +/// @param path The filename path. +/// @return The Node pointer. +NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) { + return node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindDir)); +} + +/// @brief Creates a node with is a alias. +/// @param path The filename path. +/// @return The Node pointer. +NodePtr NeFileSystemMgr::CreateAlias(const Char* path) { + return node_cast(mParser->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); +} + +/// @brief Creates a node with is a page file. +/// @param path The filename path. +/// @return The Node pointer. +NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) { + return 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) return nullptr; + + if (!r || *r == 0) return nullptr; + + auto catalog = mParser->GetCatalog(path); + + return node_cast(catalog); +} + +/// @brief Writes to a catalog's fork. +/// @param node the node ptr. +/// @param data the data. +/// @param flags the size. +/// @return +Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, + _Input SizeT size) { + if (!node) return; + if (!size) return; + + constexpr auto kDataForkName = kNeFSDataFork; + this->Write(kDataForkName, node, data, flags, size); +} + +/// @brief Read from filesystem fork. +/// @param node the catalog node. +/// @param flags the flags with it. +/// @param sz the size to read. +/// @return +_Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) { + if (!node) return nullptr; + if (!size) 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 (!size || size > kNeFSForkSize) return; + + if (!data) return; + + NE_UNUSED(flags); + + if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) + mParser->WriteCatalog(reinterpret_cast(node)->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 (sz > kNeFSForkSize) return nullptr; + + if (!sz) return nullptr; + + NE_UNUSED(flags); + + if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) + return mParser->ReadCatalog(reinterpret_cast(node), + (flags & kFileFlagRsrc ? true : false), sz, name); + + return nullptr; +} + +/// @brief Seek from Catalog. +/// @param node +/// @param off +/// @retval true always returns false, this is unimplemented. +/// @retval false always returns this, it is unimplemented. + +_Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) { + if (!node || off == 0) return false; + + return mParser->Seek(reinterpret_cast(node), off); +} + +/// @brief Tell where the catalog is. +/// @param node +/// @retval true always returns false, this is unimplemented. +/// @retval false always returns this, it is unimplemented. + +_Output SizeT NeFileSystemMgr::Tell(NodePtr node) { + if (!node) return kNPos; + + return mParser->Tell(reinterpret_cast(node)); +} + +/// @brief Rewinds the catalog. +/// @param node +/// @retval true always returns false, this is unimplemented. +/// @retval false always returns this, it is unimplemented. + +_Output Bool NeFileSystemMgr::Rewind(NodePtr node) { + if (!node) return false; + + return this->Seek(node, 0); +} + +/// @brief Returns the filesystem parser. +/// @return the Filesystem parser class. +_Output NeFileSystemParser* NeFileSystemMgr::GetParser() noexcept { + return mParser; +} +} // namespace Kernel + +#endif // ifdef __FSKIT_INCLUDES_NEFS__ +#endif // ifndef __NE_MINIMAL_OS__ diff --git a/dev/kernel/src/FS/NeFS.cc b/dev/kernel/src/FS/NeFS.cc index 8ebd551f..d0934f94 100644 --- a/dev/kernel/src/FS/NeFS.cc +++ b/dev/kernel/src/FS/NeFS.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,23 +9,23 @@ #include #include -#include -#include +#include #include +#include +#include #include -#include #include +#include #include -#include -#include -#include +#include +#include using namespace Kernel; #ifdef __NE_NO_BUILTIN__ /***********************************************************************************/ /** - Define those external symbols, to make the editor shutup + Define those external symbols, to make the editor shutup */ /***********************************************************************************/ @@ -60,99 +60,87 @@ STATIC MountpointInterface kMountpoint; /// @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) - { - auto catalog = this->GetCatalog(the_fork.CatalogName); +_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) { + auto catalog = this->GetCatalog(the_fork.CatalogName); - if (!catalog) - return NO; + if (!catalog) return NO; - Lba lba = catalog->DataFork; + Lba lba = catalog->DataFork; - (Void)(kout << "Fork LBA: " << hex_number(lba) << kendl); + (Void)(kout << "Fork LBA: " << hex_number(lba) << kendl); - if (lba < kNeFSCatalogStartAddress) - return NO; + if (lba < kNeFSCatalogStartAddress) return NO; - auto& drv = kMountpoint.A(); + auto& drv = kMountpoint.A(); - Lba lba_prev = lba; + Lba lba_prev = lba; - NEFS_FORK_STRUCT prev_fork; - NEFS_FORK_STRUCT cur_fork; + NEFS_FORK_STRUCT prev_fork; + NEFS_FORK_STRUCT cur_fork; - /// do not check for anything. Loop until we get what we want, that is a free fork zone. - while (drv.fPacket.fPacketGood) - { - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &cur_fork; + /// do not check for anything. Loop until we get what we want, that is a free fork zone. + while (drv.fPacket.fPacketGood) { + drv.fPacket.fPacketLba = lba; + drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &cur_fork; - drv.fInput(drv.fPacket); + drv.fInput(drv.fPacket); - (Void)(kout << "Next fork: " << hex_number(cur_fork.NextSibling) << kendl); + (Void)(kout << "Next fork: " << hex_number(cur_fork.NextSibling) << kendl); - if (cur_fork.Flags & kNeFSFlagCreated) - { - kout << "Error: Fork does exists, not overwriting this one.\r"; + if (cur_fork.Flags & kNeFSFlagCreated) { + kout << "Error: Fork does exists, not overwriting this one.\r"; - /// sanity check. - if (KStringBuilder::Equals(cur_fork.ForkName, the_fork.ForkName) && - KStringBuilder::Equals(cur_fork.CatalogName, the_fork.CatalogName)) - break; + /// sanity check. + 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; + lba_prev = lba; + lba = cur_fork.NextSibling; - prev_fork = cur_fork; - } - else - { - /// This is a check that we have, in order to link the previous fork - /// entry. - if (lba >= kNeFSCatalogStartAddress) - { - drv.fPacket.fPacketLba = lba_prev; - drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &prev_fork; + prev_fork = cur_fork; + } else { + /// This is a check that we have, in order to link the previous fork + /// entry. + if (lba >= kNeFSCatalogStartAddress) { + drv.fPacket.fPacketLba = lba_prev; + drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &prev_fork; - prev_fork.NextSibling = lba; + prev_fork.NextSibling = lba; - /// write to disk. - drv.fOutput(drv.fPacket); - } + /// write to disk. + drv.fOutput(drv.fPacket); + } - break; - } - } + break; + } + } - the_fork.Flags |= kNeFSFlagCreated; - the_fork.DataOffset = lba - sizeof(NEFS_FORK_STRUCT); - the_fork.PreviousSibling = lba_prev; - the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize; + the_fork.Flags |= kNeFSFlagCreated; + the_fork.DataOffset = lba - sizeof(NEFS_FORK_STRUCT); + the_fork.PreviousSibling = lba_prev; + the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize; - drv.fPacket.fPacketLba = lba; - drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &the_fork; + drv.fPacket.fPacketLba = lba; + drv.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &the_fork; - drv.fOutput(drv.fPacket); + drv.fOutput(drv.fPacket); - fs_ifs_write(&kMountpoint, drv, MountpointInterface::kDriveIndexA); + fs_ifs_write(&kMountpoint, drv, MountpointInterface::kDriveIndexA); - /// log what we have now. - (Void)(kout << "Fork offset is at: " << hex_number(the_fork.DataOffset) - << kendl); + /// log what we have now. + (Void)(kout << "Fork offset is at: " << hex_number(the_fork.DataOffset) << kendl); - (Void)(kout << "Wrote fork metadata at: " << hex_number(lba) << kendl); + (Void)(kout << "Wrote fork metadata at: " << hex_number(lba) << kendl); - return YES; - } + return YES; + } - return NO; + return NO; } /***********************************************************************************/ @@ -162,53 +150,46 @@ _Output BOOL NeFileSystemParser::CreateFork(_Input NEFS_FORK_STRUCT& the_fork) /// @return the newly found fork. /***********************************************************************************/ _Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUCT* catalog, - _Input const Char* name, - _Input Boolean is_data) -{ - auto& drive = kMountpoint.A(); - NEFS_FORK_STRUCT* the_fork = nullptr; - - Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork; - - while (lba != 0) - { - drive.fPacket.fPacketLba = lba; - drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drive.fPacket.fPacketContent = (VoidPtr)the_fork; - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, 16); - - 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(the_fork->ForkName, name)) - { - break; - } - - lba = the_fork->NextSibling; - } - - return the_fork; + _Input const Char* name, + _Input Boolean is_data) { + auto& drive = kMountpoint.A(); + NEFS_FORK_STRUCT* the_fork = nullptr; + + Lba lba = is_data ? catalog->DataFork : catalog->ResourceFork; + + while (lba != 0) { + drive.fPacket.fPacketLba = lba; + drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); + drive.fPacket.fPacketContent = (VoidPtr) the_fork; + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, 16); + + 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(the_fork->ForkName, name)) { + break; + } + + lba = the_fork->NextSibling; + } + + return the_fork; } /***********************************************************************************/ @@ -217,9 +198,8 @@ _Output NEFS_FORK_STRUCT* NeFileSystemParser::FindFork(_Input NEFS_CATALOG_STRUC /// @param name /// @return catalog pointer. /***********************************************************************************/ -_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) -{ - return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); +_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name) { + return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); } /***********************************************************************************/ @@ -229,729 +209,668 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char /// @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"; +_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char* name, + _Input const Int32& flags, + _Input const Int32& kind) { + kout << "CreateCatalog(*...*)\r"; - Lba out_lba = 0UL; + Lba out_lba = 0UL; - kout << "Checking for path separator...\r"; + kout << "Checking for path separator...\r"; - /// a directory should have a slash in the end. - if (kind == kNeFSCatalogKindDir && - name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator()) - return nullptr; + /// a directory should have a slash in the end. + if (kind == kNeFSCatalogKindDir && + name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator()) + return nullptr; - /// a file shouldn't have a slash in the end. - if (kind != kNeFSCatalogKindDir && - name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator()) - return nullptr; + /// a file shouldn't have a slash in the end. + if (kind != kNeFSCatalogKindDir && + name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator()) + return nullptr; - NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); + NEFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); - if (catalog_copy) - { - kout << "Catalog already exists: " << name << ".\r"; - err_global_get() = kErrorFileExists; + if (catalog_copy) { + kout << "Catalog already exists: " << name << ".\r"; + err_global_get() = kErrorFileExists; - delete catalog_copy; - catalog_copy = nullptr; + delete catalog_copy; + catalog_copy = nullptr; - return nullptr; - } + return nullptr; + } - Char parent_name[kNeFSCatalogNameLen] = {0}; + Char parent_name[kNeFSCatalogNameLen] = {0}; - for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) - { - parent_name[indexName] = name[indexName]; - } + for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) { + parent_name[indexName] = name[indexName]; + } - if (*parent_name == 0) - { - kout << "Parent name is NUL.\r"; - err_global_get() = kErrorFileNotFound; - return nullptr; - } + if (*parent_name == 0) { + kout << "Parent name is NUL.\r"; + err_global_get() = kErrorFileNotFound; + return nullptr; + } - /// Locate parent catalog, to then allocate right after it. + /// Locate parent catalog, to then allocate right after it. - for (SizeT index_fill = 0; index_fill < rt_string_len(name); ++index_fill) - { - parent_name[index_fill] = name[index_fill]; - } + for (SizeT index_fill = 0; index_fill < rt_string_len(name); ++index_fill) { + parent_name[index_fill] = name[index_fill]; + } - SizeT index_reverse_copy = rt_string_len(parent_name); + SizeT index_reverse_copy = rt_string_len(parent_name); - // zero character it. - parent_name[--index_reverse_copy] = 0; + // zero character it. + parent_name[--index_reverse_copy] = 0; - // mandatory / character, zero it. - parent_name[--index_reverse_copy] = 0; + // mandatory / character, zero it. + parent_name[--index_reverse_copy] = 0; - while (parent_name[index_reverse_copy] != NeFileSystemHelper::Separator()) - { - parent_name[index_reverse_copy] = 0; - --index_reverse_copy; - } + while (parent_name[index_reverse_copy] != NeFileSystemHelper::Separator()) { + parent_name[index_reverse_copy] = 0; + --index_reverse_copy; + } - NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba); + NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba); - auto& drive = kMountpoint.A(); + auto& drive = kMountpoint.A(); - constexpr auto kNeFSCatalogPadding = 4; + constexpr auto kNeFSCatalogPadding = 4; - if (catalog && catalog->Kind == kNeFSCatalogKindFile) - { - kout << "Parent is a file.\r"; - delete catalog; + 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}; + return nullptr; + } else if (!catalog) { + Char part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - drive.fPacket.fPacketContent = part_block; - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = part_block; + drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*)part_block; - out_lba = blk_nefs->StartCatalog; - } + NEFS_ROOT_PARTITION_BLOCK* blk_nefs = (NEFS_ROOT_PARTITION_BLOCK*) part_block; + out_lba = blk_nefs->StartCatalog; + } - if (drive.fPacket.fPacketReadOnly) - return nullptr; + if (drive.fPacket.fPacketReadOnly) return nullptr; - NEFS_CATALOG_STRUCT* child_catalog = new NEFS_CATALOG_STRUCT(); + 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; + 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 = rt_string_len(name); + SizeT i = rt_string_len(name); - // get rid pf \0 - --i; + // get rid pf \0 + --i; - if (kind == kNeFSCatalogKindDir) - --i; + if (kind == kNeFSCatalogKindDir) --i; - while (name[i] != '/') - --i; + while (name[i] != '/') --i; - rt_copy_memory((VoidPtr)(name + i), (VoidPtr)child_catalog->Name, - rt_string_len(name)); + rt_copy_memory((VoidPtr) (name + i), (VoidPtr) child_catalog->Name, rt_string_len(name)); - NEFS_CATALOG_STRUCT temporary_catalog{}; + NEFS_CATALOG_STRUCT temporary_catalog{}; - Lba start_free = out_lba; + Lba start_free = out_lba; - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); - Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; + Char buf_part_block[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - drive.fPacket.fPacketContent = buf_part_block; - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = buf_part_block; + drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*)buf_part_block; + NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) buf_part_block; - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); + drive.fPacket.fPacketLba = start_free; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - if (part_block->FreeCatalog < 1) - { - delete child_catalog; - child_catalog = nullptr; + if (part_block->FreeCatalog < 1) { + delete child_catalog; + child_catalog = nullptr; - return nullptr; - } + return nullptr; + } - kout << "Start finding catalog to allocate or empty space...\r"; + kout << "Start finding catalog to allocate or empty space...\r"; - while (start_free >= part_block->StartCatalog) - { - // ========================== // - // Allocate catalog now... - // ========================== // - if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0) - { - child_catalog->NextSibling = - start_free + (sizeof(NEFS_CATALOG_STRUCT) * kNeFSCatalogPadding); + while (start_free >= part_block->StartCatalog) { + // ========================== // + // Allocate catalog now... + // ========================== // + if ((temporary_catalog.Flags & kNeFSFlagCreated) == 0) { + child_catalog->NextSibling = start_free + (sizeof(NEFS_CATALOG_STRUCT) * kNeFSCatalogPadding); - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); + drive.fPacket.fPacketLba = start_free; - drive.fOutput(drive.fPacket); + drive.fOutput(drive.fPacket); - child_catalog->DataFork = part_block->DiskSize - start_free; - child_catalog->ResourceFork = child_catalog->DataFork; + child_catalog->DataFork = part_block->DiskSize - start_free; + child_catalog->ResourceFork = child_catalog->DataFork; - drive.fPacket.fPacketContent = child_catalog; - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; + drive.fPacket.fPacketContent = child_catalog; + drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); + drive.fPacket.fPacketLba = start_free; - drive.fOutput(drive.fPacket); + drive.fOutput(drive.fPacket); - // Get NeFS partition's block. + // Get NeFS partition's block. - drive.fPacket.fPacketContent = buf_part_block; - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = buf_part_block; + drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - part_block->FreeSectors -= 1; - part_block->CatalogCount += 1; - part_block->FreeCatalog -= 1; + part_block->FreeSectors -= 1; + part_block->CatalogCount += 1; + part_block->FreeCatalog -= 1; - drive.fOutput(drive.fPacket); + drive.fOutput(drive.fPacket); - delete catalog; - catalog = nullptr; + delete catalog; + catalog = nullptr; - NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT(); - rt_copy_memory(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT)); + NEFS_CATALOG_STRUCT* found_catalog = new NEFS_CATALOG_STRUCT(); + rt_copy_memory(&temporary_catalog, found_catalog, sizeof(NEFS_CATALOG_STRUCT)); - return found_catalog; - } - else if ((temporary_catalog.Flags & kNeFSFlagCreated) && - KStringBuilder::Equals(temporary_catalog.Name, name)) - { - rt_copy_memory(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT)); + return found_catalog; + } else if ((temporary_catalog.Flags & kNeFSFlagCreated) && + KStringBuilder::Equals(temporary_catalog.Name, name)) { + rt_copy_memory(&temporary_catalog, child_catalog, sizeof(NEFS_CATALOG_STRUCT)); - return child_catalog; - } + return child_catalog; + } - start_free = start_free + (sizeof(NEFS_CATALOG_STRUCT) * kNeFSCatalogPadding); + start_free = start_free + (sizeof(NEFS_CATALOG_STRUCT) * kNeFSCatalogPadding); - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fPacket.fPacketLba = start_free; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); + drive.fPacket.fPacketLba = start_free; - drive.fInput(drive.fPacket); - } + drive.fInput(drive.fPacket); + } - delete catalog; - return nullptr; + delete catalog; + return nullptr; } -_Output Bool NeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, _Input const Int32 flags, const Char* part_name) -{ - NE_UNUSED(drive); - NE_UNUSED(end_lba); - NE_UNUSED(flags); - NE_UNUSED(part_name); +_Output Bool NeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, + _Input const Lba end_lba, _Input const Int32 flags, + const Char* part_name) { + NE_UNUSED(drive); + NE_UNUSED(end_lba); + NE_UNUSED(flags); + NE_UNUSED(part_name); - (Void)(kout << "FormatGPT: Not implemented yet.\r"); + (Void)(kout << "FormatGPT: Not implemented yet.\r"); - return NO; + return NO; } /// @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::FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name) -{ - if (*part_name == 0 || - endLba == 0) - return false; +bool NeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba endLba, + _Input const Int32 flags, const Char* part_name) { + if (*part_name == 0 || endLba == 0) return false; - // verify disk. - drive->fVerify(drive->fPacket); + // verify disk. + drive->fVerify(drive->fPacket); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); - // if disk isn't good, then error out. - if (false == drive->fPacket.fPacketGood) - { - err_global_get() = kErrorDiskIsCorrupted; - return false; - } + // if disk isn't good, then error out. + if (false == drive->fPacket.fPacketGood) { + err_global_get() = kErrorDiskIsCorrupted; + return false; + } - Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; + Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - Lba start = kNeFSRootCatalogStartAddress; + Lba start = kNeFSRootCatalogStartAddress; - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = start; + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive->fPacket.fPacketLba = start; - drive->fInput(drive->fPacket); + drive->fInput(drive->fPacket); - if (flags & kNeFSPartitionTypeBoot) - { - // make it bootable when needed. - Char buf_epm[kNeFSSectorSz] = {0}; + if (flags & kNeFSPartitionTypeBoot) { + // make it bootable when needed. + Char buf_epm[kNeFSSectorSz] = {0}; - EPM_PART_BLOCK* epm_boot = (EPM_PART_BLOCK*)buf_epm; + EPM_PART_BLOCK* epm_boot = (EPM_PART_BLOCK*) buf_epm; - // Write a new EPM entry. + // Write a new EPM entry. - constexpr auto kFsName = "NeFS"; - constexpr auto kBlockName = "NeKernel:"; + constexpr auto kFsName = "NeFS"; + constexpr auto kBlockName = "NeKernel:"; - epm_boot->FsVersion = kNeFSVersionInteger; - epm_boot->LbaStart = start; - epm_boot->SectorSz = kNeFSSectorSz; + epm_boot->FsVersion = kNeFSVersionInteger; + epm_boot->LbaStart = start; + epm_boot->SectorSz = kNeFSSectorSz; - rt_copy_memory(reinterpret_cast(const_cast(kFsName)), epm_boot->Fs, rt_string_len(kFsName)); - rt_copy_memory(reinterpret_cast(const_cast(kBlockName)), epm_boot->Name, rt_string_len(kBlockName)); - rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epm_boot->Magic, rt_string_len(kEPMMagic)); + rt_copy_memory(reinterpret_cast(const_cast(kFsName)), epm_boot->Fs, + rt_string_len(kFsName)); + rt_copy_memory(reinterpret_cast(const_cast(kBlockName)), epm_boot->Name, + rt_string_len(kBlockName)); + rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epm_boot->Magic, + rt_string_len(kEPMMagic)); - Lba outEpmLba = kEPMBootBlockLba; + Lba outEpmLba = kEPMBootBlockLba; - Char buf[kNeFSSectorSz] = {0}; + Char buf[kNeFSSectorSz] = {0}; - Lba prevStart = 0; - SizeT cnt = 0; + Lba prevStart = 0; + SizeT cnt = 0; - while (drive->fPacket.fPacketGood) - { - drive->fPacket.fPacketContent = buf; - drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); - drive->fPacket.fPacketLba = outEpmLba; + while (drive->fPacket.fPacketGood) { + drive->fPacket.fPacketContent = buf; + drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); + drive->fPacket.fPacketLba = outEpmLba; - drive->fInput(drive->fPacket); + drive->fInput(drive->fPacket); - if (buf[0] == 0) - { - epm_boot->LbaStart = prevStart; + if (buf[0] == 0) { + epm_boot->LbaStart = prevStart; - if (epm_boot->LbaStart) - epm_boot->LbaStart = outEpmLba; + if (epm_boot->LbaStart) epm_boot->LbaStart = outEpmLba; - epm_boot->LbaEnd = endLba; - epm_boot->NumBlocks = cnt; + epm_boot->LbaEnd = endLba; + epm_boot->NumBlocks = cnt; - drive->fPacket.fPacketContent = buf_epm; - drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); - drive->fPacket.fPacketLba = outEpmLba; + drive->fPacket.fPacketContent = buf_epm; + drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); + drive->fPacket.fPacketLba = outEpmLba; - drive->fOutput(drive->fPacket); + drive->fOutput(drive->fPacket); - break; - } - else - { - prevStart = ((EPM_PART_BLOCK*)buf)->LbaStart + ((EPM_PART_BLOCK*)buf)->LbaEnd; - } + break; + } else { + prevStart = ((EPM_PART_BLOCK*) buf)->LbaStart + ((EPM_PART_BLOCK*) buf)->LbaEnd; + } - outEpmLba += sizeof(EPM_PART_BLOCK); - ++cnt; - } - } + outEpmLba += sizeof(EPM_PART_BLOCK); + ++cnt; + } + } - // disk isnt faulty and data has been fetched. - while (drive->fPacket.fPacketGood) - { - NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*)fs_buf; + // disk isnt faulty and data has been fetched. + while (drive->fPacket.fPacketGood) { + NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf; - // check for an empty partition here. - if (part_block->PartitionName[0] == 0 && - rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) - { - // partition is free and valid. + // check for an empty partition here. + if (part_block->PartitionName[0] == 0 && + rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) { + // partition is free and valid. - part_block->Version = kNeFSVersionInteger; + part_block->Version = kNeFSVersionInteger; - const auto kNeFSUntitledHD = part_name; + const auto kNeFSUntitledHD = part_name; - rt_copy_memory((VoidPtr)kNeFSIdent, (VoidPtr)part_block->Ident, - kNeFSIdentLen); + rt_copy_memory((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen); - rt_copy_memory((VoidPtr)kNeFSUntitledHD, (VoidPtr)part_block->PartitionName, - rt_string_len(kNeFSUntitledHD)); + rt_copy_memory((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName, + rt_string_len(kNeFSUntitledHD)); - SizeT sectorCount = drv_get_sector_count(); - SizeT diskSize = drv_get_size(); + SizeT sectorCount = drv_get_sector_count(); + SizeT diskSize = drv_get_size(); - part_block->Kind = kNeFSPartitionTypeStandard; - part_block->StartCatalog = kNeFSCatalogStartAddress; - part_block->Flags = kNeFSPartitionTypeStandard; - part_block->CatalogCount = sectorCount / sizeof(NEFS_CATALOG_STRUCT); - part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT); - part_block->SectorCount = sectorCount; - part_block->DiskSize = diskSize; - part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT); + part_block->Kind = kNeFSPartitionTypeStandard; + part_block->StartCatalog = kNeFSCatalogStartAddress; + part_block->Flags = kNeFSPartitionTypeStandard; + part_block->CatalogCount = sectorCount / sizeof(NEFS_CATALOG_STRUCT); + part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT); + part_block->SectorCount = sectorCount; + part_block->DiskSize = diskSize; + part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT); - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive->fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive->fOutput(drive->fPacket); + drive->fOutput(drive->fPacket); - (Void)(kout << "drive kind: " << drive->fProtocol() << kendl); + (Void)(kout << "drive kind: " << drive->fProtocol() << kendl); - (Void)(kout << "partition name: " << part_block->PartitionName << kendl); - (Void)(kout << "start: " << 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); + (Void)(kout << "partition name: " << part_block->PartitionName << kendl); + (Void)(kout << "start: " << 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); - // write the root catalog. - this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); + // write the root catalog. + this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); - return true; - } + return true; + } - kout << "partition block already exists.\r"; + kout << "partition block already exists.\r"; - start += part_block->DiskSize; + start += part_block->DiskSize; - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = start; + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive->fPacket.fPacketLba = start; - drive->fInput(drive->fPacket); - } + drive->fInput(drive->fPacket); + } - return false; + return false; } /// @brief Writes the data fork into a specific catalog. /// @param catalog the catalog itself /// @param data the data. /// @return if the catalog w rote 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; +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 buf = new UInt8[size_of_data]; - rt_set_memory(buf, 0, size_of_data); + auto buf = new UInt8[size_of_data]; + rt_set_memory(buf, 0, size_of_data); - rt_copy_memory(data, buf, size_of_data); + rt_copy_memory(data, buf, size_of_data); - auto& drive = kMountpoint.A(); + auto& drive = kMountpoint.A(); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); - auto catalog = this->GetCatalog(catalog_name); + auto catalog = this->GetCatalog(catalog_name); - if (!catalog) - { - delete[] buf; - buf = nullptr; - return NO; - } + if (!catalog) { + delete[] buf; + buf = nullptr; + return NO; + } - auto startFork = (!is_rsrc_fork) ? catalog->DataFork - : catalog->ResourceFork; + auto startFork = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; - delete catalog; - catalog = nullptr; + delete catalog; + catalog = nullptr; - NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT(); - NEFS_FORK_STRUCT prev_fork{}; + NEFS_FORK_STRUCT* fork_data_input = new NEFS_FORK_STRUCT(); + NEFS_FORK_STRUCT prev_fork{}; - (Void)(kout << hex_number(startFork) << kendl); + (Void)(kout << hex_number(startFork) << kendl); - // sanity check of the fork position as the condition to run the loop. - while (startFork >= kNeFSCatalogStartAddress) - { - drive.fPacket.fPacketContent = fork_data_input; - drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drive.fPacket.fPacketLba = startFork; + // sanity check of the fork position as the condition to run the loop. + while (startFork >= kNeFSCatalogStartAddress) { + drive.fPacket.fPacketContent = fork_data_input; + drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); + drive.fPacket.fPacketLba = startFork; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - (Void)(kout << hex_number(fork_data_input->DataSize) << kendl); - (Void)(kout << hex_number(size_of_data) << kendl); - (Void)(kout << hex_number(fork_data_input->Flags) << kendl); - (Void)(kout << fork_name << kendl); - (Void)(kout << fork_data_input->ForkName << kendl); - (Void)(kout << fork_data_input->CatalogName << kendl); - (Void)(kout << catalog_name << kendl); + (Void)(kout << hex_number(fork_data_input->DataSize) << kendl); + (Void)(kout << hex_number(size_of_data) << kendl); + (Void)(kout << hex_number(fork_data_input->Flags) << kendl); + (Void)(kout << fork_name << kendl); + (Void)(kout << fork_data_input->ForkName << kendl); + (Void)(kout << fork_data_input->CatalogName << kendl); + (Void)(kout << catalog_name << kendl); - 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) - { - // ===================================================== // - // Store the blob now. - // ===================================================== // + 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) { + // ===================================================== // + // Store the blob now. + // ===================================================== // - drive.fPacket.fPacketContent = buf; - drive.fPacket.fPacketSize = size_of_data; - drive.fPacket.fPacketLba = fork_data_input->DataOffset; + drive.fPacket.fPacketContent = buf; + drive.fPacket.fPacketSize = size_of_data; + drive.fPacket.fPacketLba = fork_data_input->DataOffset; - (Void)(kout << "data offset: " << hex_number(fork_data_input->DataOffset) << kendl); + (Void)(kout << "data offset: " << hex_number(fork_data_input->DataOffset) << kendl); - drive.fOutput(drive.fPacket); + drive.fOutput(drive.fPacket); - (Void)(kout << "wrote data at offset: " << hex_number(fork_data_input->DataOffset) << kendl); + (Void)(kout << "wrote data at offset: " << hex_number(fork_data_input->DataOffset) << kendl); - delete fork_data_input; - delete[] buf; + delete fork_data_input; + delete[] buf; - return true; - } + return true; + } - // stumble upon a fork, store it. + // stumble upon a fork, store it. - prev_fork = *fork_data_input; + prev_fork = *fork_data_input; - startFork = fork_data_input->NextSibling; - } + startFork = fork_data_input->NextSibling; + } - delete[] buf; - delete fork_data_input; + delete[] buf; + delete fork_data_input; - return false; + 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; + 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(); + NEFS_ROOT_PARTITION_BLOCK part{}; + auto& drive = kMountpoint.A(); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); - drive.fPacket.fPacketContent = ∂ - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = ∂ + drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - auto start_catalog_lba = kNeFSCatalogStartAddress; + auto start_catalog_lba = kNeFSCatalogStartAddress; - if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) - { - Char parent_name[kNeFSCatalogNameLen] = {0}; + if (!KStringBuilder::Equals(catalog_name, NeFileSystemHelper::Root()) && local_search) { + Char parent_name[kNeFSCatalogNameLen] = {0}; - for (SizeT indexFill = 0; indexFill < rt_string_len(catalog_name); ++indexFill) - { - parent_name[indexFill] = catalog_name[indexFill]; - } + for (SizeT indexFill = 0; indexFill < rt_string_len(catalog_name); ++indexFill) { + parent_name[indexFill] = catalog_name[indexFill]; + } - SizeT indexReverseCopy = rt_string_len(parent_name); + SizeT indexReverseCopy = rt_string_len(parent_name); - // zero character. - parent_name[--indexReverseCopy] = 0; + // zero character. + parent_name[--indexReverseCopy] = 0; - // mandatory '/' character. - parent_name[--indexReverseCopy] = 0; + // mandatory '/' character. + parent_name[--indexReverseCopy] = 0; - while (parent_name[indexReverseCopy] != NeFileSystemHelper::Separator()) - { - parent_name[indexReverseCopy] = 0; - --indexReverseCopy; - } + while (parent_name[indexReverseCopy] != NeFileSystemHelper::Separator()) { + parent_name[indexReverseCopy] = 0; + --indexReverseCopy; + } - NEFS_CATALOG_STRUCT* parent_catalog = this->FindCatalog(parent_name, out_lba); + NEFS_CATALOG_STRUCT* parent_catalog = this->FindCatalog(parent_name, out_lba); - if (parent_catalog && - !KStringBuilder::Equals(parent_name, NeFileSystemHelper::Root())) - { - start_catalog_lba = parent_catalog->NextSibling; + if (parent_catalog && !KStringBuilder::Equals(parent_name, NeFileSystemHelper::Root())) { + start_catalog_lba = parent_catalog->NextSibling; - delete parent_catalog; - parent_catalog = nullptr; + delete parent_catalog; + parent_catalog = nullptr; - local_search = YES; - } - else if (parent_catalog) - { - start_catalog_lba = parent_catalog->NextSibling; + local_search = YES; + } else if (parent_catalog) { + start_catalog_lba = parent_catalog->NextSibling; - local_search = YES; + local_search = YES; - delete parent_catalog; - parent_catalog = nullptr; - } - else if (!parent_catalog) - { - return nullptr; - } - } + delete parent_catalog; + parent_catalog = nullptr; + } else if (!parent_catalog) { + return nullptr; + } + } - NEFS_CATALOG_STRUCT temporary_catalog{}; + NEFS_CATALOG_STRUCT temporary_catalog{}; - SizeT i = rt_string_len(catalog_name); + SizeT i = rt_string_len(catalog_name); - // get rid of \0 - --i; + // get rid of \0 + --i; - if (catalog_name[i] == '/') - --i; + if (catalog_name[i] == '/') --i; - while (catalog_name[i] != '/') - --i; + while (catalog_name[i] != '/') --i; - const Char* tmp_name = (catalog_name + i); + const Char* tmp_name = (catalog_name + i); kNeFSSearchThroughCatalogList: - while (drive.fPacket.fPacketGood) - { - drive.fPacket.fPacketLba = start_catalog_lba; - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); + while (drive.fPacket.fPacketGood) { + drive.fPacket.fPacketLba = start_catalog_lba; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - if (KStringBuilder::Equals(tmp_name, temporary_catalog.Name)) - { - if (temporary_catalog.Status == kNeFSStatusLocked && - !search_hidden) - { - err_global_get() = kErrorFileLocked; + if (KStringBuilder::Equals(tmp_name, temporary_catalog.Name)) { + if (temporary_catalog.Status == kNeFSStatusLocked && !search_hidden) { + err_global_get() = kErrorFileLocked; - goto NeFSContinueSearch; - } + goto NeFSContinueSearch; + } - /// ignore unallocated catalog, break - if (!(temporary_catalog.Flags & kNeFSFlagCreated)) - { - err_global_get() = kErrorFileNotFound; + /// ignore unallocated catalog, break + if (!(temporary_catalog.Flags & kNeFSFlagCreated)) { + err_global_get() = kErrorFileNotFound; - goto NeFSContinueSearch; - } + goto NeFSContinueSearch; + } - (Void)(kout << "Found available catalog at: " << hex_number(start_catalog_lba) << kendl); - (Void)(kout << "Found available catalog at: " << temporary_catalog.Name << kendl); + (Void)(kout << "Found available catalog at: " << hex_number(start_catalog_lba) << kendl); + (Void)(kout << "Found available catalog at: " << temporary_catalog.Name << kendl); - NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT(); - rt_copy_memory(&temporary_catalog, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT)); + NEFS_CATALOG_STRUCT* catalog_ptr = new NEFS_CATALOG_STRUCT(); + rt_copy_memory(&temporary_catalog, catalog_ptr, sizeof(NEFS_CATALOG_STRUCT)); - out_lba = start_catalog_lba; - return catalog_ptr; - } + out_lba = start_catalog_lba; + return catalog_ptr; + } - NeFSContinueSearch: - start_catalog_lba = temporary_catalog.NextSibling; + NeFSContinueSearch: + start_catalog_lba = temporary_catalog.NextSibling; - if (start_catalog_lba < part.StartCatalog) - break; - } + if (start_catalog_lba < part.StartCatalog) break; + } - if (local_search) - { - local_search = false; - start_catalog_lba = part.StartCatalog; + if (local_search) { + local_search = false; + start_catalog_lba = part.StartCatalog; - goto kNeFSSearchThroughCatalogList; - } + goto kNeFSSearchThroughCatalogList; + } - err_global_get() = kErrorFileNotFound; + err_global_get() = kErrorFileNotFound; - out_lba = 0UL; + out_lba = 0UL; - return nullptr; + return nullptr; } /// @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); +_Output NEFS_CATALOG_STRUCT* NeFileSystemParser::GetCatalog(_Input const Char* name) { + Lba unused = 0; + return this->FindCatalog(name, unused, 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; +_Output Boolean NeFileSystemParser::CloseCatalog(_Input _Output NEFS_CATALOG_STRUCT* catalog) { + if (!catalog) return false; - delete catalog; - catalog = nullptr; + delete catalog; + catalog = nullptr; - return true; + 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; - } +_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); + Lba out_lba = 0; + auto catalog = this->FindCatalog(catalog_name, out_lba); - if (out_lba >= kNeFSCatalogStartAddress || - catalog->Flags & kNeFSFlagCreated) - { - catalog->Flags &= (~kNeFSFlagCreated); - catalog->Flags |= kNeFSFlagDeleted; + if (out_lba >= kNeFSCatalogStartAddress || catalog->Flags & kNeFSFlagCreated) { + catalog->Flags &= (~kNeFSFlagCreated); + catalog->Flags |= kNeFSFlagDeleted; - auto& drive = kMountpoint.A(); + auto& drive = kMountpoint.A(); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); - drive.fPacket.fPacketLba = out_lba; // the catalog position. - drive.fPacket.fPacketSize = - sizeof(NEFS_CATALOG_STRUCT); // size of catalog. roughly the sector size. - drive.fPacket.fPacketContent = catalog; // the catalog itself. + drive.fPacket.fPacketLba = out_lba; // the catalog position. + drive.fPacket.fPacketSize = + sizeof(NEFS_CATALOG_STRUCT); // size of catalog. roughly the sector size. + drive.fPacket.fPacketContent = catalog; // the catalog itself. - drive.fOutput(drive.fPacket); // send packet. + drive.fOutput(drive.fPacket); // send packet. - Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; + Char partitionBlockBuf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; - drive.fPacket.fPacketContent = partitionBlockBuf; - drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = partitionBlockBuf; + drive.fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - NEFS_ROOT_PARTITION_BLOCK* part_block = - reinterpret_cast(partitionBlockBuf); + NEFS_ROOT_PARTITION_BLOCK* part_block = + reinterpret_cast(partitionBlockBuf); - --part_block->CatalogCount; - ++part_block->FreeSectors; + --part_block->CatalogCount; + ++part_block->FreeSectors; - drive.fOutput(drive.fPacket); + drive.fOutput(drive.fPacket); - return true; - } + return true; + } - delete catalog; - catalog = nullptr; + delete catalog; + catalog = nullptr; - return false; + return false; } /// ***************************************************************** /// @@ -966,55 +885,50 @@ _Output Boolean NeFileSystemParser::RemoveCatalog(_Input const Char* catalog_nam /***********************************************************************************/ 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; - } + _Input Bool is_rsrc_fork, _Input SizeT dataSz, + _Input const Char* forkName) { + if (!catalog) { + err_global_get() = kErrorInvalidData; + return nullptr; + } - NE_UNUSED(dataSz); + NE_UNUSED(dataSz); - Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; + Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; - NEFS_FORK_STRUCT* fs_buf = new NEFS_FORK_STRUCT(); - auto& drive = kMountpoint.A(); + NEFS_FORK_STRUCT* fs_buf = new NEFS_FORK_STRUCT(); + auto& drive = kMountpoint.A(); - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); - NEFS_FORK_STRUCT* fs_fork_data = nullptr; + NEFS_FORK_STRUCT* fs_fork_data = nullptr; - while (dataForkLba > kNeFSCatalogStartAddress) - { - drive.fPacket.fPacketLba = dataForkLba; - drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); - drive.fPacket.fPacketContent = fs_buf; + while (dataForkLba > kNeFSCatalogStartAddress) { + drive.fPacket.fPacketLba = dataForkLba; + drive.fPacket.fPacketSize = sizeof(NEFS_FORK_STRUCT); + drive.fPacket.fPacketContent = fs_buf; - drive.fInput(drive.fPacket); + drive.fInput(drive.fPacket); - fs_fork_data = fs_buf; + fs_fork_data = fs_buf; - (Void)(kout << "ForkName: " << fs_fork_data->ForkName << kendl); - (Void)(kout << "CatalogName: " << fs_fork_data->CatalogName << kendl); + (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; + if (KStringBuilder::Equals(forkName, fs_fork_data->ForkName) && + KStringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) + break; - dataForkLba = fs_fork_data->NextSibling; - } + dataForkLba = fs_fork_data->NextSibling; + } - if (dataForkLba < kNeFSCatalogStartAddress) - { - delete fs_buf; - return nullptr; - } + if (dataForkLba < kNeFSCatalogStartAddress) { + delete fs_buf; + return nullptr; + } - return fs_fork_data; + return fs_fork_data; } /***********************************************************************************/ @@ -1024,13 +938,12 @@ VoidPtr NeFileSystemParser::ReadCatalog(_Input _Output NEFS_CATALOG_STRUCT* cata /// @return if the seeking was successful. /***********************************************************************************/ -bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off) -{ - NE_UNUSED(catalog); - NE_UNUSED(off); +bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT off) { + NE_UNUSED(catalog); + NE_UNUSED(off); - err_global_get() = kErrorUnimplemented; - return false; + err_global_get() = kErrorUnimplemented; + return false; } /***********************************************************************************/ @@ -1039,30 +952,27 @@ bool NeFileSystemParser::Seek(_Input _Output NEFS_CATALOG_STRUCT* catalog, SizeT /// @return The position on the file. /***********************************************************************************/ -SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog) -{ - NE_UNUSED(catalog); +SizeT NeFileSystemParser::Tell(_Input _Output NEFS_CATALOG_STRUCT* catalog) { + NE_UNUSED(catalog); - err_global_get() = kErrorUnimplemented; - return 0; + err_global_get() = kErrorUnimplemented; + return 0; } -namespace Kernel::NeFS -{ - /***********************************************************************************/ - /// @brief Construct NeFS drives. - /***********************************************************************************/ - Boolean fs_init_nefs(Void) noexcept - { - kout << "Creating main disk...\r"; +namespace Kernel::NeFS { +/***********************************************************************************/ +/// @brief Construct NeFS drives. +/***********************************************************************************/ +Boolean fs_init_nefs(Void) noexcept { + kout << "Creating main disk...\r"; - kMountpoint.A() = io_construct_main_drive(); + kMountpoint.A() = io_construct_main_drive(); - if (kMountpoint.A().fPacket.fPacketReadOnly == YES) - ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main filesystem cannot be mounted."); + if (kMountpoint.A().fPacket.fPacketReadOnly == YES) + ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main filesystem cannot be mounted."); - return YES; - } -} // namespace Kernel::NeFS + return YES; +} +} // namespace Kernel::NeFS -#endif // ifdef __FSKIT_INCLUDES_NEFS__ +#endif // ifdef __FSKIT_INCLUDES_NEFS__ diff --git a/dev/kernel/src/FileMgr.cc b/dev/kernel/src/FileMgr.cc index 1a1ee6b8..06d19e5b 100644 --- a/dev/kernel/src/FileMgr.cc +++ b/dev/kernel/src/FileMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,43 +12,37 @@ //! @brief File System Manager API. /***********************************************************************************/ -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 +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 index b14f637f..48ee1ec6 100644 --- a/dev/kernel/src/GUIDWizard.cc +++ b/dev/kernel/src/GUIDWizard.cc @@ -1,11 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: GUIDWizard.cc - Purpose: GUID helper code + File: GUIDWizard.cc + Purpose: GUID helper code - Revision History: + Revision History: ------------------------------------------- */ @@ -17,56 +17,49 @@ // @brief Size of UUID. #define kUUIDSize 37 -namespace CF::XRN::Version1 -{ - auto cf_make_sequence(const ArrayList& uuidSeq) -> Ref - { - GUIDSequence* seq = new GUIDSequence(); - MUST_PASS(seq); - - Ref seq_ref{seq}; - - 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& seq) -> ErrorOr> - { - Char buf[kUUIDSize]; - - for (SizeT index = 0; index < 16; ++index) - { - buf[index] = seq.Leak()->fU8[index] + kUUIDAsciiBegin; - } - - for (SizeT index = 16; index < 24; ++index) - { - buf[index] = seq.Leak()->fU16[index] + kUUIDAsciiBegin; - } - - for (SizeT index = 24; index < 28; ++index) - { - buf[index] = seq.Leak()->fU32[index] + kUUIDAsciiBegin; - } - - auto view = KStringBuilder::Construct(buf); - - if (view) - return ErrorOr>{view.Leak()}; - - return ErrorOr>{-1}; - } -} // namespace CF::XRN::Version1 +namespace CF::XRN::Version1 { +auto cf_make_sequence(const ArrayList& uuidSeq) -> Ref { + GUIDSequence* seq = new GUIDSequence(); + MUST_PASS(seq); + + Ref seq_ref{seq}; + + 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& seq) -> ErrorOr> { + Char buf[kUUIDSize]; + + for (SizeT index = 0; index < 16; ++index) { + buf[index] = seq.Leak()->fU8[index] + kUUIDAsciiBegin; + } + + for (SizeT index = 16; index < 24; ++index) { + buf[index] = seq.Leak()->fU16[index] + kUUIDAsciiBegin; + } + + for (SizeT index = 24; index < 28; ++index) { + buf[index] = seq.Leak()->fU32[index] + kUUIDAsciiBegin; + } + + auto view = KStringBuilder::Construct(buf); + + if (view) return ErrorOr>{view.Leak()}; + + return ErrorOr>{-1}; +} +} // namespace CF::XRN::Version1 diff --git a/dev/kernel/src/GUIDWrapper.cc b/dev/kernel/src/GUIDWrapper.cc index f36df112..f87a1bdd 100644 --- a/dev/kernel/src/GUIDWrapper.cc +++ b/dev/kernel/src/GUIDWrapper.cc @@ -1,11 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace CF::XRN -{ -} +namespace CF::XRN {} diff --git a/dev/kernel/src/Gfx/FBDeviceInterface.cc b/dev/kernel/src/Gfx/FBDeviceInterface.cc index b3b52934..185b22b0 100644 --- a/dev/kernel/src/Gfx/FBDeviceInterface.cc +++ b/dev/kernel/src/Gfx/FBDeviceInterface.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,10 +13,8 @@ using namespace Kernel; /// @param In Drive input /// @param Cleanup Drive cleanup. FBDeviceInterface::FBDeviceInterface(void (*out)(IDeviceObject* self, FBDevicePacket* outpacket), - void (*in)(IDeviceObject* self, FBDevicePacket* inpacket)) - : IDeviceObject(out, in) -{ -} + void (*in)(IDeviceObject* self, FBDevicePacket* inpacket)) + : IDeviceObject(out, in) {} /// @brief Class desctructor FBDeviceInterface::~FBDeviceInterface() = default; @@ -24,43 +22,35 @@ 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; +FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) { + if (!pckt) return *this; - if (pckt->fHeight == 0 || pckt->fWidth == 0) - return *this; + if (pckt->fHeight == 0 || pckt->fWidth == 0) return *this; - if (pckt->fX > kHandoverHeader->f_GOP.f_Width || - pckt->fY > kHandoverHeader->f_GOP.f_Height) - return *this; + if (pckt->fX > kHandoverHeader->f_GOP.f_Width || pckt->fY > kHandoverHeader->f_GOP.f_Height) + return *this; - this->fOut(this, pckt); + this->fOut(this, pckt); - return *this; + 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; +FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) { + if (!pckt) return *this; - if (pckt->fX > kHandoverHeader->f_GOP.f_Width || - pckt->fY > kHandoverHeader->f_GOP.f_Height) - return *this; + if (pckt->fX > kHandoverHeader->f_GOP.f_Width || pckt->fY > kHandoverHeader->f_GOP.f_Height) + return *this; - this->fIn(this, pckt); + this->fIn(this, pckt); - return *this; + return *this; } /// @brief Returns the name of the device interface. /// @return it's name as a string. -const Char* FBDeviceInterface::Name() const -{ - return "/dev/fb{}"; +const Char* FBDeviceInterface::Name() const { + return "/dev/fb{}"; } \ No newline at end of file diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 96c80c77..c49c3081 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -#include -#include #include +#include +#include /***********************************************************************************/ ///! @file HardwareThreadScheduler.cc @@ -15,211 +15,190 @@ ///! @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_stack(HAL::StackFramePtr frame); - EXTERN_C Bool mp_register_process(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. - /***********************************************************************************/ - const ThreadID& HardwareThread::ID() noexcept - { - return fID; - } - - /***********************************************************************************/ - //! @brief returns the kind of thread we have. - /***********************************************************************************/ - const ThreadKind& HardwareThread::Kind() noexcept - { - return fKind; - } - - /***********************************************************************************/ - //! @brief is the thread busy? - //! @return whether the thread is busy or not. - /***********************************************************************************/ - Bool HardwareThread::IsBusy() noexcept - { - STATIC Int64 busy_timer = 0U; - constexpr Int64 kTimeoutMax = 0x1000000; // an arbitrary value used to tell if the timeout hasn't been reached yet. - - if (fBusy && (busy_timer > kTimeoutMax)) - { - busy_timer = 0U; - fBusy = No; - - return No; - } - - ++busy_timer; - - 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(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid) - { - if (this->IsBusy()) - return NO; - - this->fStack = frame; - this->fPID = pid; - - this->fStack->BP = reinterpret_cast(image_ptr); - this->fStack->SP = reinterpret_cast(stack_ptr); - - Bool ret = mp_register_process(fStack, this->fPID); - - if (ret) - this->Busy(YES); - - return ret; - } - - /***********************************************************************************/ - ///! @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[fCurrentThread].fStack; - } - - /***********************************************************************************/ - /** - * Get Hardware thread at index. - * @param idx the index - * @return the reference to the hardware thread. - */ - /***********************************************************************************/ - Ref HardwareThreadScheduler::operator[](SizeT idx) - { - if (idx == 0) - { - if (fThreadList[idx].Kind() != kAPSystemReserved) - { - fThreadList[idx].fKind = kAPBoot; - } - } - else if (idx >= kMaxAPInsideSched) - { - static HardwareThread* kFakeThread = nullptr; - return {kFakeThread}; - } - - 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 +namespace Kernel { +/***********************************************************************************/ +/// @note Those symbols are needed in order to switch and validate the stack. +/***********************************************************************************/ + +EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame); +EXTERN_C Bool mp_register_process(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. +/***********************************************************************************/ +const ThreadID& HardwareThread::ID() noexcept { + return fID; +} + +/***********************************************************************************/ +//! @brief returns the kind of thread we have. +/***********************************************************************************/ +const ThreadKind& HardwareThread::Kind() noexcept { + return fKind; +} + +/***********************************************************************************/ +//! @brief is the thread busy? +//! @return whether the thread is busy or not. +/***********************************************************************************/ +Bool HardwareThread::IsBusy() noexcept { + STATIC Int64 busy_timer = 0U; + constexpr Int64 kTimeoutMax = + 0x1000000; // an arbitrary value used to tell if the timeout hasn't been reached yet. + + if (fBusy && (busy_timer > kTimeoutMax)) { + busy_timer = 0U; + fBusy = No; + + return No; + } + + ++busy_timer; + + 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(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, + const ThreadID& pid) { + if (this->IsBusy()) return NO; + + this->fStack = frame; + this->fPID = pid; + + this->fStack->BP = reinterpret_cast(image_ptr); + this->fStack->SP = reinterpret_cast(stack_ptr); + + Bool ret = mp_register_process(fStack, this->fPID); + + if (ret) this->Busy(YES); + + return ret; +} + +/***********************************************************************************/ +///! @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[fCurrentThread].fStack; +} + +/***********************************************************************************/ +/** + * Get Hardware thread at index. + * @param idx the index + * @return the reference to the hardware thread. + */ +/***********************************************************************************/ +Ref HardwareThreadScheduler::operator[](SizeT idx) { + if (idx == 0) { + if (fThreadList[idx].Kind() != kAPSystemReserved) { + fThreadList[idx].fKind = kAPBoot; + } + } else if (idx >= kMaxAPInsideSched) { + static HardwareThread* kFakeThread = nullptr; + return {kFakeThread}; + } + + 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/IDylibObject.cc b/dev/kernel/src/IDylibObject.cc index ef4d5ecf..6def3fcf 100644 --- a/dev/kernel/src/IDylibObject.cc +++ b/dev/kernel/src/IDylibObject.cc @@ -7,7 +7,7 @@ * ======================================================== */ -#include #include +#include using namespace Kernel; diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index 9b0b1ab8..f064dbac 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -1,15 +1,15 @@ /* * ======================================================== * -* NeKernel + * NeKernel * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. * * ======================================================== */ #include -#include #include +#include #include #include #include @@ -18,15 +18,15 @@ 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 + 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 + 07/28/24: Replace rt_library_free with rtl_fini_dylib_pef - 10/8/24: FIX: Fix log comment. + 10/8/24: FIX: Fix log comment. ------------------------------------------- */ @@ -41,47 +41,42 @@ using namespace Kernel; /** @brief Library initializer. */ /***********************************************************************************/ -EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) -{ - IDylibRef dll_obj = tls_new_class(); +EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) { + IDylibRef dll_obj = tls_new_class(); - if (!dll_obj) - { - process.Crash(); - return nullptr; - } + if (!dll_obj) { + process.Crash(); + return nullptr; + } - dll_obj->Mount(new IPEFDylibObject::DLL_TRAITS()); + dll_obj->Mount(new IPEFDylibObject::DLL_TRAITS()); - if (!dll_obj->Get()) - { - tls_delete_class(dll_obj); - dll_obj = nullptr; + if (!dll_obj->Get()) { + tls_delete_class(dll_obj); + dll_obj = nullptr; - process.Crash(); + process.Crash(); - return nullptr; - } + return nullptr; + } - dll_obj->Get()->ImageObject = - process.Image.fBlob; + dll_obj->Get()->ImageObject = process.Image.fBlob; - if (!dll_obj->Get()->ImageObject) - { - delete dll_obj->Get(); + if (!dll_obj->Get()->ImageObject) { + delete dll_obj->Get(); - tls_delete_class(dll_obj); - dll_obj = nullptr; + tls_delete_class(dll_obj); + dll_obj = nullptr; - process.Crash(); + process.Crash(); - return nullptr; - } + return nullptr; + } - dll_obj->Get()->ImageEntrypointOffset = - dll_obj->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); + dll_obj->Get()->ImageEntrypointOffset = + dll_obj->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); - return dll_obj; + return dll_obj; } /***********************************************************************************/ @@ -91,21 +86,19 @@ EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) /** @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); +EXTERN_C Void rtl_fini_dylib_pef(USER_PROCESS& process, IDylibRef dll_obj, BOOL* successful) { + MUST_PASS(successful); - // sanity check (will also trigger a bug check if this fails) - if (dll_obj == nullptr) - { - *successful = false; - process.Crash(); - } + // 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; + delete dll_obj->Get(); + delete dll_obj; - dll_obj = nullptr; + dll_obj = nullptr; - *successful = true; + *successful = true; } diff --git a/dev/kernel/src/IndexableProperty.cc b/dev/kernel/src/IndexableProperty.cc index 05440ee9..8dd216c8 100644 --- a/dev/kernel/src/IndexableProperty.cc +++ b/dev/kernel/src/IndexableProperty.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -14,44 +14,36 @@ #define kMaxLenIndexer (256U) -namespace Kernel -{ - namespace Indexer - { - Index& IndexableProperty::Leak() noexcept - { - return fIndex; - } - - Void IndexableProperty::AddFlag(Int16 flag) - { - fFlags |= flag; - } - - Void IndexableProperty::RemoveFlag(Int16 flag) - { - fFlags &= flag; - } - - Int16 IndexableProperty::HasFlag(Int16 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.AddFlag(kIndexerClaimed); - rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen); - - (Void)(kout << "FSKit: Indexed new file: " << filename << kendl); - } - } - } // namespace Indexer -} // namespace Kernel +namespace Kernel { +namespace Indexer { + Index& IndexableProperty::Leak() noexcept { + return fIndex; + } + + Void IndexableProperty::AddFlag(Int16 flag) { + fFlags |= flag; + } + + Void IndexableProperty::RemoveFlag(Int16 flag) { + fFlags &= flag; + } + + Int16 IndexableProperty::HasFlag(Int16 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.AddFlag(kIndexerClaimed); + rt_copy_memory((VoidPtr) indexer.Leak().Path, (VoidPtr) filename, filenameLen); + + (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 index 187da6fd..5939e207 100644 --- a/dev/kernel/src/Json.cc +++ b/dev/kernel/src/Json.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/KPC.cc b/dev/kernel/src/KPC.cc index 0e6c45bb..8937d19a 100644 --- a/dev/kernel/src/KPC.cc +++ b/dev/kernel/src/KPC.cc @@ -1,45 +1,39 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -#include #include +#include -namespace Kernel -{ - STATIC Bool kRaiseOnBugCheck = false; +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]; +/// @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 (ptr == nullptr) goto bug_check_fail; - if (!mm_is_valid_heap(ptr)) - goto bug_check_fail; + if (!mm_is_valid_heap(ptr)) goto bug_check_fail; - delete[] ptr; + delete[] ptr; - return Yes; + return Yes; - bug_check_fail: - if (ptr) - delete[] ptr; +bug_check_fail: + if (ptr) delete[] ptr; - ptr = nullptr; + ptr = nullptr; - if (kRaiseOnBugCheck) - { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR); - } + if (kRaiseOnBugCheck) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR); + } - return No; - } -} // namespace Kernel + return No; +} +} // namespace Kernel diff --git a/dev/kernel/src/KString.cc b/dev/kernel/src/KString.cc index cb21e003..a13bb364 100644 --- a/dev/kernel/src/KString.cc +++ b/dev/kernel/src/KString.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,221 +10,171 @@ /// @file KString.cc /// @brief Kernel String manipulation file. -namespace Kernel -{ - Char* KString::Data() - { - return this->fData; - } - - const Char* KString::CData() const - { - return const_cast(this->fData); - } - - Size KString::Length() const - { - return this->fDataSz; - } - - bool KString::operator==(const KString& 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; - } - - bool KString::operator==(const Char* rhs) const - { - if (rt_string_len(rhs) != this->Length()) - return false; - - for (Size index = 0; index < rt_string_len(rhs); ++index) - { - if (rhs[index] != this->fData[index]) - return false; - } - - return true; - } - - bool KString::operator!=(const KString& 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; - } - - bool KString::operator!=(const Char* rhs) const - { - if (rt_string_len(rhs) != this->Length()) - return false; - - for (Size index = 0; index < rt_string_len(rhs); ++index) - { - if (rhs[index] == this->fData[index]) - return false; - } - - return true; - } - - ErrorOr KStringBuilder::Construct(const Char* data) - { - if (!data || *data == 0) - return {}; - - KString* view = new KString(rt_string_len(data)); - (*view) += data; - - return ErrorOr(*view); - } - - const Char* KStringBuilder::FromBool(const Char* fmt, bool i) - { - if (!fmt) - return ("?"); - - const Char* boolean_expr = i ? "YES" : "NO"; - Char* ret = (Char*)RTL_ALLOCA(rt_string_len(boolean_expr) + rt_string_len(fmt)); - - if (!ret) - return ("?"); - - const auto fmt_len = rt_string_len(fmt); - const auto res_len = rt_string_len(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; - } - - bool KStringBuilder::Equals(const Char* lhs, const Char* rhs) - { - if (rt_string_len(rhs) != rt_string_len(lhs)) - return false; - - for (Size index = 0; index < rt_string_len(rhs); ++index) - { - if (rhs[index] != lhs[index]) - return false; - } - - return true; - } - - /// @note This is unsafe!!! - bool KStringBuilder::Equals(const Utf16Char* lhs, const Utf16Char* rhs) - { - for (Size index = 0; index < wrt_string_len(rhs); ++index) - { - if (rhs[index] != lhs[index]) - return false; - } - - return true; - } - - bool KStringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) - { - for (Size index = 0; rhs[index] != 0; ++index) - { - if (rhs[index] != lhs[index]) - return false; - } - - return true; - } - - const Char* KStringBuilder::Format(const Char* fmt, const Char* fmt2) - { - if (!fmt || !fmt2) - return ("?"); - - Char* ret = - (Char*)RTL_ALLOCA(sizeof(char) * (rt_string_len(fmt2) + rt_string_len(fmt))); - - if (!ret) - return ("?"); - - const auto len = rt_string_len(fmt); - - for (Size idx = 0; idx < len; ++idx) - { - if (fmt[idx] == '%' && idx < rt_string_len(fmt) && fmt[idx] == 's') - { - Size result_cnt = idx; - - for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx) - { - ret[result_cnt] = fmt2[y_idx]; - ++result_cnt; - } - } - - ret[idx] = fmt[idx]; - } - - return ret; - } - - STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur) - { - SizeT sz_rhs = rt_string_len(rhs); - SizeT rhs_i = 0; - - for (; rhs_i < sz_rhs; ++rhs_i) - { - lhs[rhs_i + cur] = rhs[rhs_i]; - } - } - - KString& KString::operator+=(const Char* rhs) - { - rt_string_append(this->fData, rhs, this->fCur); - this->fCur += rt_string_len(rhs); - - return *this; - } - - KString& KString::operator+=(const KString& rhs) - { - if (rt_string_len(rhs.fData) > this->Length()) - return *this; - - rt_string_append(this->fData, const_cast(rhs.fData), this->fCur); - this->fCur += rt_string_len(const_cast(rhs.fData)); - - return *this; - } -} // namespace Kernel +namespace Kernel { +Char* KString::Data() { + return this->fData; +} + +const Char* KString::CData() const { + return const_cast(this->fData); +} + +Size KString::Length() const { + return this->fDataSz; +} + +bool KString::operator==(const KString& 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; +} + +bool KString::operator==(const Char* rhs) const { + if (rt_string_len(rhs) != this->Length()) return false; + + for (Size index = 0; index < rt_string_len(rhs); ++index) { + if (rhs[index] != this->fData[index]) return false; + } + + return true; +} + +bool KString::operator!=(const KString& 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; +} + +bool KString::operator!=(const Char* rhs) const { + if (rt_string_len(rhs) != this->Length()) return false; + + for (Size index = 0; index < rt_string_len(rhs); ++index) { + if (rhs[index] == this->fData[index]) return false; + } + + return true; +} + +ErrorOr KStringBuilder::Construct(const Char* data) { + if (!data || *data == 0) return {}; + + KString* view = new KString(rt_string_len(data)); + (*view) += data; + + return ErrorOr(*view); +} + +const Char* KStringBuilder::FromBool(const Char* fmt, bool i) { + if (!fmt) return ("?"); + + const Char* boolean_expr = i ? "YES" : "NO"; + Char* ret = (Char*) RTL_ALLOCA(rt_string_len(boolean_expr) + rt_string_len(fmt)); + + if (!ret) return ("?"); + + const auto fmt_len = rt_string_len(fmt); + const auto res_len = rt_string_len(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; +} + +bool KStringBuilder::Equals(const Char* lhs, const Char* rhs) { + if (rt_string_len(rhs) != rt_string_len(lhs)) return false; + + for (Size index = 0; index < rt_string_len(rhs); ++index) { + if (rhs[index] != lhs[index]) return false; + } + + return true; +} + +/// @note This is unsafe!!! +bool KStringBuilder::Equals(const Utf16Char* lhs, const Utf16Char* rhs) { + for (Size index = 0; index < wrt_string_len(rhs); ++index) { + if (rhs[index] != lhs[index]) return false; + } + + return true; +} + +bool KStringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) { + for (Size index = 0; rhs[index] != 0; ++index) { + if (rhs[index] != lhs[index]) return false; + } + + return true; +} + +const Char* KStringBuilder::Format(const Char* fmt, const Char* fmt2) { + if (!fmt || !fmt2) return ("?"); + + Char* ret = (Char*) RTL_ALLOCA(sizeof(char) * (rt_string_len(fmt2) + rt_string_len(fmt))); + + if (!ret) return ("?"); + + const auto len = rt_string_len(fmt); + + for (Size idx = 0; idx < len; ++idx) { + if (fmt[idx] == '%' && idx < rt_string_len(fmt) && fmt[idx] == 's') { + Size result_cnt = idx; + + for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx) { + ret[result_cnt] = fmt2[y_idx]; + ++result_cnt; + } + } + + ret[idx] = fmt[idx]; + } + + return ret; +} + +STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur) { + SizeT sz_rhs = rt_string_len(rhs); + SizeT rhs_i = 0; + + for (; rhs_i < sz_rhs; ++rhs_i) { + lhs[rhs_i + cur] = rhs[rhs_i]; + } +} + +KString& KString::operator+=(const Char* rhs) { + rt_string_append(this->fData, rhs, this->fCur); + this->fCur += rt_string_len(rhs); + + return *this; +} + +KString& KString::operator+=(const KString& rhs) { + if (rt_string_len(rhs.fData) > this->Length()) return *this; + + rt_string_append(this->fData, const_cast(rhs.fData), this->fCur); + this->fCur += rt_string_len(const_cast(rhs.fData)); + + return *this; +} +} // namespace Kernel diff --git a/dev/kernel/src/KernelProcessScheduler.cc b/dev/kernel/src/KernelProcessScheduler.cc index a1185a91..d0abfce0 100644 --- a/dev/kernel/src/KernelProcessScheduler.cc +++ b/dev/kernel/src/KernelProcessScheduler.cc @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - FILE: KernelProcessScheduler.cc - PURPOSE: Privileged/Ring-0 process scheduler. + FILE: KernelProcessScheduler.cc + PURPOSE: Privileged/Ring-0 process scheduler. ------------------------------------------- */ @@ -15,6 +15,4 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ -namespace Kernel -{ -} // namespace Kernel \ No newline at end of file +namespace Kernel {} // namespace Kernel \ No newline at end of file diff --git a/dev/kernel/src/LockDelegate.cc b/dev/kernel/src/LockDelegate.cc index 6afce8a2..d02de3e4 100644 --- a/dev/kernel/src/LockDelegate.cc +++ b/dev/kernel/src/LockDelegate.cc @@ -1,12 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - /// @note Leave it empty for now. -} // namespace Kernel +namespace Kernel { +/// @note Leave it empty for now. +} // namespace Kernel diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc index 2f70d85f..cb33753d 100644 --- a/dev/kernel/src/MemoryMgr.cc +++ b/dev/kernel/src/MemoryMgr.cc @@ -1,296 +1,274 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ +#include #include #include #include #include #include #include -#include /* ------------------------------------------- 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 MemoryMgr.h header. (amlal) - 27/01/25: REFACTOR: Reworked code as the memory manager. - 25/03/25: REFACTOR: Refactor MemoryMgr code and log freed address location. + 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 MemoryMgr.h header. (amlal) + 27/01/25: REFACTOR: Reworked code as the memory manager. + 25/03/25: REFACTOR: Refactor MemoryMgr code and log freed address location. ------------------------------------------- */ //! @file MemoryMgr.cc //! @brief Heap algorithm that serves as the main memory manager. -#define kMemoryMgrMagic (0xD4D75) +#define kMemoryMgrMagic (0xD4D75) #define kMemoryMgrAlignSz (4) -namespace Kernel -{ - /// @brief Implementation details. - namespace Detail - { - struct PACKED MM_INFORMATION_BLOCK; +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[kMemoryMgrAlignSz]; + }; + + /// @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_heap_address(VoidPtr heap_ptr) -> Bool { + if (!heap_ptr) return false; + + IntPtr base_heap = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK); + + /// Add that check in case we're having an integer underflow. /// + + if (base_heap < 0) { + return false; + } + + return true; + } - /// @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; + typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR; +} // namespace Detail - ///! @brief Is the heap present? - UInt8 fPresent : 1; +/// @brief Declare a new size for ptr_heap. +/// @param ptr_heap the pointer. +/// @return Newly allocated heap header. +_Output auto mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) -> VoidPtr { + if (Detail::mm_check_heap_address(ptr_heap) == No) return nullptr; - /// @brief Is this value writable? - UInt8 fWriteRead : 1; + if (!ptr_heap || new_sz < 1) return nullptr; - /// @brief Is this value owned by the user? - UInt8 fUser : 1; + kout << "This function is not implemented by the kernel yet.\r"; - /// @brief Is this a page pointer? - UInt8 fPage : 1; + ke_panic(RUNTIME_CHECK_INVALID); - /// @brief 32-bit CRC checksum. - UInt32 fCRC32; + return nullptr; +} - /// @brief 64-bit Allocation flags. - UInt16 fFlags; +/// @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_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { + auto sz_fix = sz; - /// @brief 64-bit pointer size. - SizeT fSize; + if (sz_fix == 0) return nullptr; - /// @brief 64-bit target offset pointer. - UIntPtr fOffset; + sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK); - /// @brief Padding. - UInt32 fPad; + PageMgr page_mgr; + auto wrapper = page_mgr.Request(wr, user, No, sz_fix, pad_amount); - /// @brief Padding bytes for header. - UInt8 fPadding[kMemoryMgrAlignSz]; - }; + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast(wrapper.VirtualAddress() + + sizeof(Detail::MM_INFORMATION_BLOCK)); - /// @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_heap_address(VoidPtr heap_ptr) -> Bool - { - if (!heap_ptr) - return false; + heap_info_ptr->fSize = sz_fix; + heap_info_ptr->fMagic = kMemoryMgrMagic; + heap_info_ptr->fCRC32 = 0; // dont fill it for now. + heap_info_ptr->fOffset = + reinterpret_cast(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; - IntPtr base_heap = ((IntPtr)heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK); + rt_set_memory(heap_info_ptr->fPadding, 0, kMemoryMgrAlignSz); - /// Add that check in case we're having an integer underflow. /// + auto result = reinterpret_cast(heap_info_ptr->fOffset); - if (base_heap < 0) - { - return false; - } + (Void)(kout << "Registered heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) + << kendl); - return true; - } + return result; +} - typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR; - } // namespace Detail +/// @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_heap_address(heap_ptr) == No) return kErrorHeapNotPresent; - /// @brief Declare a new size for ptr_heap. - /// @param ptr_heap the pointer. - /// @return Newly allocated heap header. - _Output auto mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) -> VoidPtr - { - if (Detail::mm_check_heap_address(ptr_heap) == No) - return nullptr; + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast((UIntPtr) heap_ptr - + sizeof(Detail::MM_INFORMATION_BLOCK)); - if (!ptr_heap || new_sz < 1) - return nullptr; + if (!heap_info_ptr) return kErrorHeapNotPresent; - kout << "This function is not implemented by the kernel yet.\r"; + heap_info_ptr->fPage = true; - ke_panic(RUNTIME_CHECK_INVALID); + (Void)(kout << "Registered page address: " << hex_number(reinterpret_cast(heap_info_ptr)) + << kendl); - return nullptr; - } + return kErrorSuccess; +} - /// @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_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) - { - auto sz_fix = sz; +/// @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_make_flags(VoidPtr heap_ptr, UInt64 flags) { + if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent; - if (sz_fix == 0) - return nullptr; + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast((UIntPtr) heap_ptr - + sizeof(Detail::MM_INFORMATION_BLOCK)); - sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK); - - PageMgr page_mgr; - auto wrapper = page_mgr.Request(wr, user, No, sz_fix, pad_amount); + if (!heap_info_ptr) return kErrorHeapNotPresent; - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - wrapper.VirtualAddress() + sizeof(Detail::MM_INFORMATION_BLOCK)); - - heap_info_ptr->fSize = sz_fix; - heap_info_ptr->fMagic = kMemoryMgrMagic; - heap_info_ptr->fCRC32 = 0; // dont fill it for now. - heap_info_ptr->fOffset = reinterpret_cast(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; + heap_info_ptr->fFlags = flags; - rt_set_memory(heap_info_ptr->fPadding, 0, kMemoryMgrAlignSz); + return kErrorSuccess; +} - auto result = reinterpret_cast(heap_info_ptr->fOffset); +/// @brief Gets the flags of a heap header. +/// @param heap_ptr the pointer to get. +_Output UInt64 mm_get_flags(VoidPtr heap_ptr) { + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast((UIntPtr) heap_ptr - + sizeof(Detail::MM_INFORMATION_BLOCK)); - (Void)(kout << "Registered heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); + if (!heap_info_ptr) return kErrorHeapNotPresent; + + return heap_info_ptr->fFlags; +} - return result; - } +/// @brief Declare pointer as free. +/// @param heap_ptr the pointer. +/// @return +_Output Int32 mm_delete_heap(VoidPtr heap_ptr) { + if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent; + + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast((UIntPtr) (heap_ptr) - + sizeof(Detail::MM_INFORMATION_BLOCK)); + + if (heap_info_ptr && heap_info_ptr->fMagic == kMemoryMgrMagic) { + 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 << "Address has been successfully freed: " << hex_number((UIntPtr) heap_info_ptr) + << kendl); + + PTEWrapper page_wrapper( + No, No, No, + reinterpret_cast(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); + Ref pte_address{page_wrapper}; + + PageMgr page_mgr; + page_mgr.Free(pte_address); + + return kErrorSuccess; + } + + return kErrorInternal; +} - /// @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_heap_address(heap_ptr) == No) - return kErrorHeapNotPresent; - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::MM_INFORMATION_BLOCK)); - - if (!heap_info_ptr) - return kErrorHeapNotPresent; - - heap_info_ptr->fPage = true; - - (Void)(kout << "Registered page address: " << hex_number(reinterpret_cast(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_make_flags(VoidPtr heap_ptr, UInt64 flags) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return kErrorHeapNotPresent; - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (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_flags(VoidPtr heap_ptr) - { - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (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_delete_heap(VoidPtr heap_ptr) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return kErrorHeapNotPresent; - - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)(heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); - - if (heap_info_ptr && heap_info_ptr->fMagic == kMemoryMgrMagic) - { - 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 << "Address has been successfully freed: " << hex_number((UIntPtr)heap_info_ptr) << kendl); - - PTEWrapper page_wrapper(No, No, No, reinterpret_cast(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); - Ref pte_address{page_wrapper}; - - PageMgr page_mgr; - page_mgr.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_heap(VoidPtr heap_ptr) - { - if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) - { - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (UIntPtr)(heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); - - return (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kMemoryMgrMagic); - } - - 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_heap(VoidPtr heap_ptr) - { - if (heap_ptr) - { - Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - (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 && kMemoryMgrMagic == 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 +/// @brief Check if pointer is a valid Kernel pointer. +/// @param heap_ptr the pointer +/// @return if it exists. +_Output Boolean mm_is_valid_heap(VoidPtr heap_ptr) { + if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) { + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast((UIntPtr) (heap_ptr) - + sizeof(Detail::MM_INFORMATION_BLOCK)); + + return (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kMemoryMgrMagic); + } + + 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_heap(VoidPtr heap_ptr) { + if (heap_ptr) { + Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast((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 && kMemoryMgrMagic == 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/MutableArray.cc b/dev/kernel/src/MutableArray.cc index aa18ac39..4b07f9ae 100644 --- a/dev/kernel/src/MutableArray.cc +++ b/dev/kernel/src/MutableArray.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/Network/IPAddr.cc b/dev/kernel/src/Network/IPAddr.cc index 02e2c258..4437df22 100644 --- a/dev/kernel/src/Network/IPAddr.cc +++ b/dev/kernel/src/Network/IPAddr.cc @@ -1,129 +1,100 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -namespace Kernel -{ - Char* RawIPAddress::Address() - { - return fAddr; - } - - RawIPAddress::RawIPAddress(char 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; - } - - Char& RawIPAddress::operator[](const Size& index) - { - kout << "[RawIPAddress::operator[]] Fetching Index...\r"; - - static char IP_PLACEHOLDER = '0'; - if (index > 4) - return IP_PLACEHOLDER; - - return fAddr[index]; - } - - RawIPAddress6::RawIPAddress6(char bytes[8]) - { - rt_copy_memory(bytes, fAddr, 8); - } - - char& RawIPAddress6::operator[](const Size& index) - { - kout << "[RawIPAddress6::operator[]] Fetching Index...\r"; - - static char IP_PLACEHOLDER = '0'; - if (index > 8) - return IP_PLACEHOLDER; - - return fAddr[index]; - } - - bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) - { - for (SizeT index = 0; index < 8; ++index) - { - if (ipv6.fAddr[index] != fAddr[index]) - return false; - } - - return true; - } - - bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) - { - for (SizeT index = 0; index < 8; ++index) - { - if (ipv6.fAddr[index] == fAddr[index]) - return false; - } - - return true; - } - - ErrorOr IPFactory::ToKString(Ref& ipv6) - { - auto str = KStringBuilder::Construct(ipv6.Leak().Address()); - return str; - } - - ErrorOr IPFactory::ToKString(Ref& ipv4) - { - auto str = KStringBuilder::Construct(ipv4.Leak().Address()); - return str; - } - - bool IPFactory::IpCheckVersion4(const Char* ip) - { - if (!ip) - return NO; - - Int32 cnter = 0; - - for (SizeT base = 0; base < rt_string_len(ip); ++base) - { - if (ip[base] == '.') - { - cnter = 0; - } - else - { - if (cnter == 3) - return false; - - ++cnter; - } - } - - return true; - } -} // namespace Kernel +namespace Kernel { +Char* RawIPAddress::Address() { + return fAddr; +} + +RawIPAddress::RawIPAddress(char 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; +} + +Char& RawIPAddress::operator[](const Size& index) { + kout << "[RawIPAddress::operator[]] Fetching Index...\r"; + + static char IP_PLACEHOLDER = '0'; + if (index > 4) return IP_PLACEHOLDER; + + return fAddr[index]; +} + +RawIPAddress6::RawIPAddress6(char bytes[8]) { + rt_copy_memory(bytes, fAddr, 8); +} + +char& RawIPAddress6::operator[](const Size& index) { + kout << "[RawIPAddress6::operator[]] Fetching Index...\r"; + + static char IP_PLACEHOLDER = '0'; + if (index > 8) return IP_PLACEHOLDER; + + return fAddr[index]; +} + +bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) { + for (SizeT index = 0; index < 8; ++index) { + if (ipv6.fAddr[index] != fAddr[index]) return false; + } + + return true; +} + +bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) { + for (SizeT index = 0; index < 8; ++index) { + if (ipv6.fAddr[index] == fAddr[index]) return false; + } + + return true; +} + +ErrorOr IPFactory::ToKString(Ref& ipv6) { + auto str = KStringBuilder::Construct(ipv6.Leak().Address()); + return str; +} + +ErrorOr IPFactory::ToKString(Ref& ipv4) { + auto str = KStringBuilder::Construct(ipv4.Leak().Address()); + return str; +} + +bool IPFactory::IpCheckVersion4(const Char* ip) { + if (!ip) return NO; + + Int32 cnter = 0; + + for (SizeT base = 0; base < rt_string_len(ip); ++base) { + if (ip[base] == '.') { + cnter = 0; + } else { + if (cnter == 3) return false; + + ++cnter; + } + } + + return true; +} +} // namespace Kernel diff --git a/dev/kernel/src/Network/IPCAddr.cc b/dev/kernel/src/Network/IPCAddr.cc index 80a14264..4c1dd500 100644 --- a/dev/kernel/src/Network/IPCAddr.cc +++ b/dev/kernel/src/Network/IPCAddr.cc @@ -4,29 +4,24 @@ ------------------------------------------- */ -#include #include #include +#include -namespace Kernel -{ - bool IPC_ADDR::operator==(const IPC_ADDR& addr) noexcept - { - return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam; - } +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==(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!=(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 +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/IPCMsg.cc b/dev/kernel/src/Network/IPCMsg.cc index 06073214..b3c9d9fd 100644 --- a/dev/kernel/src/Network/IPCMsg.cc +++ b/dev/kernel/src/Network/IPCMsg.cc @@ -1,125 +1,106 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include #include +#include + +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(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; + + 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; + + rt_copy_memory(src->IpcData, target->IpcData, src->IpcMsgSz); + + return Yes; + } -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(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; - - 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; - - rt_copy_memory(src->IpcData, target->IpcData, src->IpcMsgSz); - - return Yes; - } - - return No; - } -} // namespace Kernel + return No; +} +} // namespace Kernel diff --git a/dev/kernel/src/Network/MACAddressGetter.cc b/dev/kernel/src/Network/MACAddressGetter.cc index 192dbc70..736e1e27 100644 --- a/dev/kernel/src/Network/MACAddressGetter.cc +++ b/dev/kernel/src/Network/MACAddressGetter.cc @@ -1,15 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - Array& MacAddressGetter::AsBytes() - { - return this->fMacAddress; - } -} // namespace Kernel +namespace Kernel { +Array& MacAddressGetter::AsBytes() { + return this->fMacAddress; +} +} // namespace Kernel diff --git a/dev/kernel/src/Network/NetworkDevice.cc b/dev/kernel/src/Network/NetworkDevice.cc index d7d78c28..6f77a244 100644 --- a/dev/kernel/src/Network/NetworkDevice.cc +++ b/dev/kernel/src/Network/NetworkDevice.cc @@ -1,36 +1,29 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -namespace Kernel -{ - /// \brief Getter for fNetworkName. - /// \return Network device name. - const Char* NetworkDevice::Name() const - { - return this->fNetworkName; - } - - /// \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) > cNetworkNameLen) - return NO; - - rt_copy_memory((VoidPtr)name, - (VoidPtr)this->fNetworkName, rt_string_len(name)); - - return YES; - } -} // namespace Kernel +namespace Kernel { +/// \brief Getter for fNetworkName. +/// \return Network device name. +const Char* NetworkDevice::Name() const { + return this->fNetworkName; +} + +/// \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) > cNetworkNameLen) return NO; + + rt_copy_memory((VoidPtr) name, (VoidPtr) this->fNetworkName, rt_string_len(name)); + + return YES; +} +} // namespace Kernel diff --git a/dev/kernel/src/New+Delete.cc b/dev/kernel/src/New+Delete.cc index d0abb20d..96e7ab64 100644 --- a/dev/kernel/src/New+Delete.cc +++ b/dev/kernel/src/New+Delete.cc @@ -1,60 +1,48 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include #include -void* operator new[](size_t sz) -{ - if (sz == 0) - ++sz; +void* operator new[](size_t sz) { + if (sz == 0) ++sz; - return Kernel::mm_new_heap(sz, true, false); + return Kernel::mm_new_heap(sz, true, false); } -void* operator new(size_t sz) -{ - if (sz == 0) - ++sz; +void* operator new(size_t sz) { + if (sz == 0) ++sz; - return Kernel::mm_new_heap(sz, true, false); + return Kernel::mm_new_heap(sz, true, false); } -void operator delete[](void* ptr) -{ - if (ptr == nullptr) - return; +void operator delete[](void* ptr) { + if (ptr == nullptr) return; - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_heap(ptr); } -void operator delete(void* ptr) -{ - if (ptr == nullptr) - return; +void operator delete(void* ptr) { + if (ptr == nullptr) return; - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_heap(ptr); } -void operator delete(void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; +void operator delete(void* ptr, size_t sz) { + if (ptr == nullptr) return; - NE_UNUSED(sz); + NE_UNUSED(sz); - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_heap(ptr); } -void operator delete[](void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; +void operator delete[](void* ptr, size_t sz) { + if (ptr == nullptr) return; - NE_UNUSED(sz); + NE_UNUSED(sz); - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_heap(ptr); } diff --git a/dev/kernel/src/OwnPtr.cc b/dev/kernel/src/OwnPtr.cc index 9623d4a4..8fd2b985 100644 --- a/dev/kernel/src/OwnPtr.cc +++ b/dev/kernel/src/OwnPtr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index 668dd916..7a75f386 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,260 +9,226 @@ #include #include #include +#include #include #include -#include /// @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. - /***********************************************************************************/ - UInt32 ldr_get_platform(void) noexcept - { +#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap" +#define kPefNameSymbol "__PEFProgramName" + +namespace Kernel { +namespace Detail { + /***********************************************************************************/ + /// @brief Get the PEF platform signature according to the compiled architecture. + /***********************************************************************************/ + UInt32 ldr_get_platform(void) noexcept { #if defined(__NE_32X0__) - return kPefArch32x0; + return kPefArch32x0; #elif defined(__NE_64X0__) - return kPefArch64x0; + return kPefArch64x0; #elif defined(__NE_AMD64__) - return kPefArchAMD64; + return kPefArchAMD64; #elif defined(__NE_PPC64__) - return kPefArchPowerPC; + return kPefArchPowerPC; #elif defined(__NE_ARM64__) - return kPefArchARM64; + 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); - fBad = false; - } - - /***********************************************************************************/ - /// @brief PEF loader constructor. - /// @param path the filesystem path. - /***********************************************************************************/ - PEFLoader::PEFLoader(const Char* path) - : fCachedBlob(nullptr), fFatBinary(false), fBad(false) - { - fFile.New(const_cast(path), kRestrictRB); - fPath = KStringBuilder::Construct(path).Leak(); - - auto kPefHeader = "PEF_CONTAINER"; - - fCachedBlob = fFile->Read(kPefHeader, mib_cast(16)); - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - 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] && container->Abi == kPefAbi) - { - return; - } - else if (container->Magic[4] == kPefMagic[0] && - container->Magic[3] == kPefMagic[1] && - container->Magic[2] == kPefMagic[2] && - container->Magic[1] == kPefMagic[3] && - container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) - { - /// This is a fat binary. - this->fFatBinary = true; - return; - } - - fBad = true; - - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - kout << "PEFLoader: warn: Executable format error!\r"; - - fCachedBlob = nullptr; - } - - /***********************************************************************************/ - /// @brief PEF destructor. - /***********************************************************************************/ - PEFLoader::~PEFLoader() - { - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - fFile.Delete(); - } - - /***********************************************************************************/ - /// @brief Finds the symbol according to it's name. - /// @param name name of symbol. - /// @param kind kind of symbol we want. - /***********************************************************************************/ - VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) - { - if (!fCachedBlob || fBad || !name) - return nullptr; - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - auto blob = fFile->Read(name, mib_cast(16)); - - PEFCommandHeader* container_header = reinterpret_cast(blob); - - constexpr auto cMangleCharacter = '$'; - const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; - - ErrorOr error_or_symbol; - - switch (kind) - { - case kPefCode: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[0]); // code symbol. - break; - } - case kPefData: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[1]); // data symbol. - break; - } - case kPefZero: { - error_or_symbol = KStringBuilder::Construct(cContainerKinds[2]); // block starting symbol. - break; - } - default: - return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were - // a user process. - } - - Char* unconst_symbol = const_cast(name); - - for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) - { - if (unconst_symbol[i] == ' ') - { - unconst_symbol[i] = cMangleCharacter; - } - } - - error_or_symbol.Leak().Leak() += name; - - for (SizeT index = 0; index < container->Count; ++index) - { - if (KStringBuilder::Equals(container_header->Name, - error_or_symbol.Leak().Leak().CData())) - { - if (container_header->Kind == kind) - { - if (container_header->Cpu != Detail::ldr_get_platform()) - { - if (!this->fFatBinary) - { - mm_delete_heap(blob); - return nullptr; - } - } - - Char* container_blob_value = new Char[container_header->Size]; - - rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); - mm_delete_heap(blob); - - kout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; - - return container_blob_value; - } - } - } - - mm_delete_heap(blob); - return nullptr; - } - - /// @brief Finds the executable entrypoint. - /// @return - ErrorOr PEFLoader::FindStart() - { - if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) - return ErrorOr(sym); - - return ErrorOr(kErrorExecutable); - } - - /// @brief Tells if the executable is loaded or not. - /// @return - bool PEFLoader::IsLoaded() noexcept - { - return !fBad && fCachedBlob; - } - - const Char* PEFLoader::Path() - { - return fPath.Leak().CData(); - } - - const Char* PEFLoader::AsString() - { + 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); + fBad = false; +} + +/***********************************************************************************/ +/// @brief PEF loader constructor. +/// @param path the filesystem path. +/***********************************************************************************/ +PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) { + fFile.New(const_cast(path), kRestrictRB); + fPath = KStringBuilder::Construct(path).Leak(); + + auto kPefHeader = "PEF_CONTAINER"; + + fCachedBlob = fFile->Read(kPefHeader, mib_cast(16)); + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + 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] && + container->Abi == kPefAbi) { + return; + } else if (container->Magic[4] == kPefMagic[0] && container->Magic[3] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && container->Magic[1] == kPefMagic[3] && + container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) { + /// This is a fat binary. + this->fFatBinary = true; + return; + } + + fBad = true; + + if (fCachedBlob) mm_delete_heap(fCachedBlob); + + kout << "PEFLoader: warn: Executable format error!\r"; + + fCachedBlob = nullptr; +} + +/***********************************************************************************/ +/// @brief PEF destructor. +/***********************************************************************************/ +PEFLoader::~PEFLoader() { + if (fCachedBlob) mm_delete_heap(fCachedBlob); + + fFile.Delete(); +} + +/***********************************************************************************/ +/// @brief Finds the symbol according to it's name. +/// @param name name of symbol. +/// @param kind kind of symbol we want. +/***********************************************************************************/ +VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) { + if (!fCachedBlob || fBad || !name) return nullptr; + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + auto blob = fFile->Read(name, mib_cast(16)); + + PEFCommandHeader* container_header = reinterpret_cast(blob); + + constexpr auto cMangleCharacter = '$'; + const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + + ErrorOr error_or_symbol; + + switch (kind) { + case kPefCode: { + error_or_symbol = KStringBuilder::Construct(cContainerKinds[0]); // code symbol. + break; + } + case kPefData: { + error_or_symbol = KStringBuilder::Construct(cContainerKinds[1]); // data symbol. + break; + } + case kPefZero: { + error_or_symbol = KStringBuilder::Construct(cContainerKinds[2]); // block starting symbol. + break; + } + default: + return nullptr; // prevent that from the kernel's mode perspective, let that happen if it + // were a user process. + } + + Char* unconst_symbol = const_cast(name); + + for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) { + if (unconst_symbol[i] == ' ') { + unconst_symbol[i] = cMangleCharacter; + } + } + + error_or_symbol.Leak().Leak() += name; + + for (SizeT index = 0; index < container->Count; ++index) { + if (KStringBuilder::Equals(container_header->Name, error_or_symbol.Leak().Leak().CData())) { + if (container_header->Kind == kind) { + if (container_header->Cpu != Detail::ldr_get_platform()) { + if (!this->fFatBinary) { + mm_delete_heap(blob); + return nullptr; + } + } + + Char* container_blob_value = new Char[container_header->Size]; + + rt_copy_memory((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value, + container_header->Size); + mm_delete_heap(blob); + + kout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; + + return container_blob_value; + } + } + } + + mm_delete_heap(blob); + return nullptr; +} + +/// @brief Finds the executable entrypoint. +/// @return +ErrorOr PEFLoader::FindStart() { + if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return ErrorOr(sym); + + return ErrorOr(kErrorExecutable); +} + +/// @brief Tells if the executable is loaded or not. +/// @return +bool PEFLoader::IsLoaded() noexcept { + return !fBad && fCachedBlob; +} + +const Char* PEFLoader::Path() { + return fPath.Leak().CData(); +} + +const Char* PEFLoader::AsString() { #ifdef __32x0__ - return "32x0 PEF executable."; + return "32x0 PEF executable."; #elif defined(__64x0__) - return "64x0 PEF executable."; + return "64x0 PEF executable."; #elif defined(__x86_64__) - return "x86_64 PEF executable."; + return "x86_64 PEF executable."; #elif defined(__aarch64__) - return "AARCH64 PEF executable."; + return "AARCH64 PEF executable."; #elif defined(__powerpc64__) - return "POWER64 PEF executable."; + return "POWER64 PEF executable."; #else - return "???? PEF executable."; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ - } - - const Char* PEFLoader::MIME() - { - return kPefApplicationMime; - } - - ErrorOr PEFLoader::GetBlob() - { - return ErrorOr{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 id = UserProcessScheduler::The().Spawn(reinterpret_cast(exec.FindSymbol(kPefNameSymbol, kPefData)), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - - if (id != kSchedInvalidPID) - { - UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; - UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData); - UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData); - } - - return id; - } - } // namespace Utils -} // namespace Kernel + return "???? PEF executable."; +#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ +} + +const Char* PEFLoader::MIME() { + return kPefApplicationMime; +} + +ErrorOr PEFLoader::GetBlob() { + return ErrorOr{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 id = UserProcessScheduler::The().Spawn( + reinterpret_cast(exec.FindSymbol(kPefNameSymbol, kPefData)), + errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); + + if (id != kSchedInvalidPID) { + UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind; + UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = + *(UIntPtr*) exec.FindSymbol(kPefStackSizeSymbol, kPefData); + UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = + *(UIntPtr*) exec.FindSymbol(kPefHeapSizeSymbol, kPefData); + } + + return id; + } +} // namespace Utils +} // namespace Kernel diff --git a/dev/kernel/src/PRDT.cc b/dev/kernel/src/PRDT.cc index ed8edb8d..f7380d2d 100644 --- a/dev/kernel/src/PRDT.cc +++ b/dev/kernel/src/PRDT.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,17 +8,15 @@ #include #include -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& prd) - { - prd.Leak().fPhysAddress = 0x0; - prd.Leak().fSectorCount = 0x0; - prd.Leak().fEndBit = 0x0; - } -} // namespace Kernel +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& 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 index 8778a855..7e385f26 100644 --- a/dev/kernel/src/PageMgr.cc +++ b/dev/kernel/src/PageMgr.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,100 +11,85 @@ #include #elif defined(__NE_ARM64__) #include -#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() - { +#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() { #ifndef __NE_MINIMAL_OS__ - hal_flush_tlb(); -#endif // !__NE_MINIMAL_OS__ - } - - /// @brief Reclaim freed page. - /// @return - Bool PTEWrapper::Reclaim() - { - if (!this->fPresent) - { - this->fPresent = true; - return true; - } - - return false; - } - - /// @brief Request a PTE. - /// @param Rw r/w? - /// @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(ptr)}; - } - - /// @brief Disable BitMap. - /// @param wrapper the wrapper. - /// @return If the page bitmap was cleared or not. - Bool PageMgr::Free(Ref& 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 + hal_flush_tlb(); +#endif // !__NE_MINIMAL_OS__ +} + +/// @brief Reclaim freed page. +/// @return +Bool PTEWrapper::Reclaim() { + if (!this->fPresent) { + this->fPresent = true; + return true; + } + + return false; +} + +/// @brief Request a PTE. +/// @param Rw r/w? +/// @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(ptr)}; +} + +/// @brief Disable BitMap. +/// @param wrapper the wrapper. +/// @return If the page bitmap was cleared or not. +Bool PageMgr::Free(Ref& 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 index 325e19af..35ea4195 100644 --- a/dev/kernel/src/Pmm.cc +++ b/dev/kernel/src/Pmm.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,90 +9,75 @@ #if defined(__NE_ARM64__) #include -#endif // defined(__NE_ARM64__) +#endif // defined(__NE_ARM64__) #if defined(__NE_AMD64__) #include -#endif // defined(__NE_AMD64__) +#endif // defined(__NE_AMD64__) -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Pmm constructor. - /***********************************************************************************/ - Pmm::Pmm() - : fPageMgr() - { - kout << "[PMM] Allocate PageMemoryMgr.\r"; - } +namespace Kernel { +/***********************************************************************************/ +/// @brief Pmm constructor. +/***********************************************************************************/ +Pmm::Pmm() : fPageMgr() { + kout << "[PMM] Allocate PageMemoryMgr.\r"; +} - Pmm::~Pmm() = default; +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 Pmm::RequestPage(Boolean user, Boolean readWrite) - { - PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize, 0); +/***********************************************************************************/ +/// @param If this returns Null pointer, enter emergency mode. +/// @param user is this a user page? +/// @param readWrite is it r/w? +/***********************************************************************************/ +Ref 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 {}; - } + if (pt.fPresent) { + kout << "[PMM]: Allocation failed.\r"; + return {}; + } - return Ref(pt); - } + return Ref(pt); +} - Boolean Pmm::FreePage(Ref PageRef) - { - if (!PageRef) - return false; +Boolean Pmm::FreePage(Ref PageRef) { + if (!PageRef) return false; - PageRef.Leak().fPresent = false; + PageRef.Leak().fPresent = false; - return true; - } + return true; +} - Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; +Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) { + if (!PageRef) return false; - PageRef.Leak().fPresent = Enable; + PageRef.Leak().fPresent = Enable; - return true; - } + return true; +} - Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; +Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) { + if (!PageRef) return false; - PageRef.Leak().fRw = Enable; + PageRef.Leak().fRw = Enable; - return true; - } + return true; +} - Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; +Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) { + if (!PageRef) return false; - PageRef.Leak().fRw = Enable; + PageRef.Leak().fRw = Enable; - return true; - } + return true; +} - Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; +Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) { + if (!PageRef) return false; - PageRef.Leak().fShareable = Enable; + PageRef.Leak().fShareable = Enable; - return true; - } -} // namespace Kernel + return true; +} +} // namespace Kernel diff --git a/dev/kernel/src/ProcessTeam.cc b/dev/kernel/src/ProcessTeam.cc index 2fcc115e..7acbcf8d 100644 --- a/dev/kernel/src/ProcessTeam.cc +++ b/dev/kernel/src/ProcessTeam.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,49 +11,43 @@ #include -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].Status = ProcessStatusKind::kKilled; - } - - this->mProcessCount = 0UL; - } - - /***********************************************************************************/ - /// @brief Process list array getter. - /// @return The list of process to schedule. - /***********************************************************************************/ - - Array& 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& UserProcessTeam::AsRef() - { - return this->mCurrentProcess; - } -} // namespace Kernel +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].Status = ProcessStatusKind::kKilled; + } + + this->mProcessCount = 0UL; +} + +/***********************************************************************************/ +/// @brief Process list array getter. +/// @return The list of process to schedule. +/***********************************************************************************/ + +Array& 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& UserProcessTeam::AsRef() { + return this->mCurrentProcess; +} +} // namespace Kernel // last rev 05-03-24 diff --git a/dev/kernel/src/Property.cc b/dev/kernel/src/Property.cc index 8aee4618..62aa6ef2 100644 --- a/dev/kernel/src/Property.cc +++ b/dev/kernel/src/Property.cc @@ -1,45 +1,41 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace 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(KString& name) - { - return this->fName && this->fName == name; - } - - /***********************************************************************************/ - /// @brief Gets the key (name) of property. - /***********************************************************************************/ - KString& Property::GetKey() - { - return this->fName; - } - - /***********************************************************************************/ - /// @brief Gets the value of the property. - /***********************************************************************************/ - PropertyId& Property::GetValue() - { - return fValue; - } -} // namespace CF +namespace 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(KString& name) { + return this->fName && this->fName == name; +} + +/***********************************************************************************/ +/// @brief Gets the key (name) of property. +/***********************************************************************************/ +KString& Property::GetKey() { + return this->fName; +} + +/***********************************************************************************/ +/// @brief Gets the value of the property. +/***********************************************************************************/ +PropertyId& Property::GetValue() { + return fValue; +} +} // namespace CF diff --git a/dev/kernel/src/Ref.cc b/dev/kernel/src/Ref.cc index 7c01ea18..c185952b 100644 --- a/dev/kernel/src/Ref.cc +++ b/dev/kernel/src/Ref.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/SoftwareTimer.cc b/dev/kernel/src/SoftwareTimer.cc index 35d9c6f1..535bec9e 100644 --- a/dev/kernel/src/SoftwareTimer.cc +++ b/dev/kernel/src/SoftwareTimer.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -10,30 +10,24 @@ using namespace Kernel; -SoftwareTimer::SoftwareTimer(Int64 seconds) - : fWaitFor(seconds) -{ - fDigitalTimer = new UIntPtr(); - MUST_PASS(fDigitalTimer); +SoftwareTimer::SoftwareTimer(Int64 seconds) : fWaitFor(seconds) { + fDigitalTimer = new UIntPtr(); + MUST_PASS(fDigitalTimer); } -SoftwareTimer::~SoftwareTimer() -{ - delete fDigitalTimer; - fDigitalTimer = nullptr; +SoftwareTimer::~SoftwareTimer() { + delete fDigitalTimer; + fDigitalTimer = nullptr; - fWaitFor = 0; + fWaitFor = 0; } -BOOL SoftwareTimer::Wait() noexcept -{ - if (fWaitFor < 1) - return NO; +BOOL SoftwareTimer::Wait() noexcept { + if (fWaitFor < 1) return NO; - while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) - { - ++(*fDigitalTimer); - } + while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) { + ++(*fDigitalTimer); + } - return YES; + return YES; } diff --git a/dev/kernel/src/Storage/AHCIDeviceInterface.cc b/dev/kernel/src/Storage/AHCIDeviceInterface.cc index c5f43bf6..d5c1e5c6 100644 --- a/dev/kernel/src/Storage/AHCIDeviceInterface.cc +++ b/dev/kernel/src/Storage/AHCIDeviceInterface.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,95 +12,78 @@ using namespace Kernel; /// @param Out Drive output /// @param In Drive input /// @param Cleanup Drive cleanup. -AHCIDeviceInterface::AHCIDeviceInterface(void (*out)(IDeviceObject* self, MountpointInterface* outpacket), - void (*in)(IDeviceObject* self, MountpointInterface* inpacket)) - : IDeviceObject(out, in) -{ -} +AHCIDeviceInterface::AHCIDeviceInterface(void (*out)(IDeviceObject* self, + MountpointInterface* outpacket), + void (*in)(IDeviceObject* self, + MountpointInterface* inpacket)) + : IDeviceObject(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 "/dev/sda{}"; +const Char* AHCIDeviceInterface::Name() const { + return "/dev/sda{}"; } /// @brief Output operator. /// @param mnt the disk mountpoint. /// @return the class itself after operation. -AHCIDeviceInterface& AHCIDeviceInterface::operator<<(MountpointInterface* 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&)IDeviceObject::operator<<( - mnt); +AHCIDeviceInterface& AHCIDeviceInterface::operator<<(MountpointInterface* 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&) IDeviceObject::operator<<(mnt); } /// @brief Input operator. /// @param mnt the disk mountpoint. /// @return the class itself after operation. -AHCIDeviceInterface& AHCIDeviceInterface::operator>>(MountpointInterface* 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&)IDeviceObject::operator>>( - mnt); +AHCIDeviceInterface& AHCIDeviceInterface::operator>>(MountpointInterface* 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&) IDeviceObject::operator>>(mnt); } -const UInt16& AHCIDeviceInterface::GetPortsImplemented() -{ - return this->fPortsImplemented; +const UInt16& AHCIDeviceInterface::GetPortsImplemented() { + return this->fPortsImplemented; } -Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi) -{ - MUST_PASS(pi > 0); - this->fPortsImplemented = pi; +Void AHCIDeviceInterface::SetPortsImplemented(const UInt16& pi) { + MUST_PASS(pi > 0); + this->fPortsImplemented = pi; } -const UInt32& AHCIDeviceInterface::GetIndex() -{ - return this->fDriveIndex; +const UInt32& AHCIDeviceInterface::GetIndex() { + return this->fDriveIndex; } -Void AHCIDeviceInterface::SetIndex(const UInt32& drv) -{ - MUST_PASS(MountpointInterface::kDriveIndexInvalid != drv); - this->fDriveIndex = drv; +Void AHCIDeviceInterface::SetIndex(const UInt32& drv) { + MUST_PASS(MountpointInterface::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 index 3fe331dd..f38d5359 100644 --- a/dev/kernel/src/Storage/ATADeviceInterface.cc +++ b/dev/kernel/src/Storage/ATADeviceInterface.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,107 +12,85 @@ using namespace Kernel; /// @param Out Drive output /// @param In Drive input /// @param Cleanup Drive cleanup. -ATADeviceInterface::ATADeviceInterface( - void (*Out)(IDeviceObject*, MountpointInterface* outpacket), - void (*In)(IDeviceObject*, MountpointInterface* inpacket)) - : IDeviceObject(Out, In) -{ -} +ATADeviceInterface::ATADeviceInterface(void (*Out)(IDeviceObject*, MountpointInterface* outpacket), + void (*In)(IDeviceObject*, MountpointInterface* inpacket)) + : IDeviceObject(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 "/dev/hda{}"; +const Char* ATADeviceInterface::Name() const { + return "/dev/hda{}"; } /// @brief Output operator. /// @param Data the disk mountpoint. /// @return the class itself after operation. -ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* 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&)IDeviceObject::operator<<( - Data); +ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* 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&) IDeviceObject::operator<<(Data); } /// @brief Input operator. /// @param Data the disk mountpoint. /// @return the class itself after operation. -ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* 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&)IDeviceObject::operator>>( - Data); +ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* 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&) IDeviceObject::operator>>(Data); } -const UInt32& ATADeviceInterface::GetIndex() -{ - return this->fDriveIndex; +const UInt32& ATADeviceInterface::GetIndex() { + return this->fDriveIndex; } -Void ATADeviceInterface::SetIndex(const UInt32& drv) -{ - MUST_PASS(MountpointInterface::kDriveIndexInvalid != drv); - this->fDriveIndex = drv; +Void ATADeviceInterface::SetIndex(const UInt32& drv) { + MUST_PASS(MountpointInterface::kDriveIndexInvalid != drv); + this->fDriveIndex = drv; } -const UInt16& ATADeviceInterface::GetIO() -{ - return this->fIO; +const UInt16& ATADeviceInterface::GetIO() { + return this->fIO; } -Void ATADeviceInterface::SetIO(const UInt16& drv) -{ - MUST_PASS(0xFFFF != drv); - this->fIO = drv; +Void ATADeviceInterface::SetIO(const UInt16& drv) { + MUST_PASS(0xFFFF != drv); + this->fIO = drv; } -const UInt16& ATADeviceInterface::GetMaster() -{ - return this->fIO; +const UInt16& ATADeviceInterface::GetMaster() { + return this->fIO; } -Void ATADeviceInterface::SetMaster(const UInt16& drv) -{ - MUST_PASS(0xFFFF != drv); - this->fMaster = drv; +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 index 14c9722f..edec6d6d 100644 --- a/dev/kernel/src/Storage/NVMEDeviceInterface.cc +++ b/dev/kernel/src/Storage/NVMEDeviceInterface.cc @@ -1,28 +1,23 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(IDeviceObject*, MountpointInterface* outpacket), - void (*in)(IDeviceObject*, MountpointInterface* inpacket), - void (*cleanup)(void)) - : IDeviceObject(out, in), fCleanup(cleanup) - { - } +namespace Kernel { +NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(IDeviceObject*, + MountpointInterface* outpacket), + void (*in)(IDeviceObject*, MountpointInterface* inpacket), + void (*cleanup)(void)) + : IDeviceObject(out, in), fCleanup(cleanup) {} - NVMEDeviceInterface::~NVMEDeviceInterface() - { - if (fCleanup) - fCleanup(); - } +NVMEDeviceInterface::~NVMEDeviceInterface() { + if (fCleanup) fCleanup(); +} - const Char* NVMEDeviceInterface::Name() const - { - return ("/dev/nvme{}"); - } -} // namespace Kernel +const Char* NVMEDeviceInterface::Name() const { + return ("/dev/nvme{}"); +} +} // namespace Kernel diff --git a/dev/kernel/src/Storage/SCSIDeviceInterface.cc b/dev/kernel/src/Storage/SCSIDeviceInterface.cc index 85432822..6f26f486 100644 --- a/dev/kernel/src/Storage/SCSIDeviceInterface.cc +++ b/dev/kernel/src/Storage/SCSIDeviceInterface.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/kernel/src/Stream.cc b/dev/kernel/src/Stream.cc index 0be3e844..8fd4dab3 100644 --- a/dev/kernel/src/Stream.cc +++ b/dev/kernel/src/Stream.cc @@ -1,11 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: Stream.cc - Purpose: Stream object + File: Stream.cc + Purpose: Stream object - Revision History: + Revision History: ------------------------------------------- */ diff --git a/dev/kernel/src/Swap/DiskSwap.cc b/dev/kernel/src/Swap/DiskSwap.cc index a2703394..118be0f6 100644 --- a/dev/kernel/src/Swap/DiskSwap.cc +++ b/dev/kernel/src/Swap/DiskSwap.cc @@ -1,67 +1,57 @@ /* ------------------------------------------- - Copyright (C) 2024-2025 Amlal El Mahrouss Labs, all rights reserved. + Copyright (C) 2024-2025 Amlal El Mahrouss Labs, all rights reserved. ------------------------------------------- */ -#include #include +#include -namespace Kernel -{ - /***********************************************************************************/ - /// @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; +namespace Kernel { +/***********************************************************************************/ +/// @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 (*fork_name == 0) return NO; - if (!data) - return NO; + if (!data) return NO; - FileStream file(kSwapPageFilePath, kRestrictWRB); + FileStream file(kSwapPageFilePath, kRestrictWRB); - ErrorOr ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz); + ErrorOr ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data->fBlobSz); - if (ret.Error()) - return NO; + if (ret.Error()) return NO; - return YES; - } + 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; +/***********************************************************************************/ +/// @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 (*fork_name == 0) return nullptr; - if (data_len > kSwapBlockMaxSize) - return nullptr; + if (data_len > kSwapBlockMaxSize) return nullptr; - if (data_len == 0) - return nullptr; + if (data_len == 0) return nullptr; - FileStream file(kSwapPageFilePath, kRestrictRB); + FileStream file(kSwapPageFilePath, kRestrictRB); - VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len); + VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len); - return reinterpret_cast(blob); - } -} // namespace Kernel + return reinterpret_cast(blob); +} +} // namespace Kernel diff --git a/dev/kernel/src/ThreadLocalStorage.cc b/dev/kernel/src/ThreadLocalStorage.cc index a6c12142..e248e67c 100644 --- a/dev/kernel/src/ThreadLocalStorage.cc +++ b/dev/kernel/src/ThreadLocalStorage.cc @@ -1,16 +1,16 @@ /* * ======================================================== * -* NeKernel + * NeKernel * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. * * ======================================================== */ -#include #include #include #include +#include /***********************************************************************************/ /// @bugs: 0 @@ -26,19 +26,16 @@ using namespace Kernel; * @return if the cookie is enabled, true; false otherwise */ -Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) -{ - if (!tib_ptr || - !tib_ptr->Record) - return false; +Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) { + if (!tib_ptr || !tib_ptr->Record) return false; - ICodec encoder; - const Char* tib_as_bytes = encoder.AsBytes(tib_ptr); + ICodec encoder; + const Char* tib_as_bytes = encoder.AsBytes(tib_ptr); - kout << "TLS: Validating the TIB...\r"; + kout << "TLS: Validating the TIB...\r"; - return tib_as_bytes[kCookieMag0Idx] == kCookieMag0 && tib_as_bytes[kCookieMag1Idx] == kCookieMag1 && - tib_as_bytes[kCookieMag2Idx] == kCookieMag2; + return tib_as_bytes[kCookieMag0Idx] == kCookieMag0 && + tib_as_bytes[kCookieMag1Idx] == kCookieMag1 && tib_as_bytes[kCookieMag2Idx] == kCookieMag2; } /** @@ -46,22 +43,19 @@ Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) * @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; - } +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(tib_ptr); + THREAD_INFORMATION_BLOCK* tib = reinterpret_cast(tib_ptr); - if (!tls_check_tib(tib)) - { - kout << "TLS: Failed because of an invalid TIB...\r"; - return No; - } + if (!tls_check_tib(tib)) { + kout << "TLS: Failed because of an invalid TIB...\r"; + return No; + } - kout << "TLS Pass.\r"; - return Yes; + kout << "TLS Pass.\r"; + return Yes; } diff --git a/dev/kernel/src/Timer.cc b/dev/kernel/src/Timer.cc index c2202373..826be99a 100644 --- a/dev/kernel/src/Timer.cc +++ b/dev/kernel/src/Timer.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -13,7 +13,6 @@ using namespace Kernel; /// @brief Unimplemented as it is an interface. -BOOL TimerInterface::Wait() noexcept -{ - return NO; +BOOL TimerInterface::Wait() noexcept { + return NO; } diff --git a/dev/kernel/src/User.cc b/dev/kernel/src/User.cc index 421850f7..54f3853d 100644 --- a/dev/kernel/src/User.cc +++ b/dev/kernel/src/User.cc @@ -10,186 +10,161 @@ * ======================================================== */ -#include -#include -#include #include +#include #include +#include +#include -#define kStdUserType (0xEE) +#define kStdUserType (0xEE) #define kSuperUserType (0xEF) /// @file User.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 - //////////////////////////////////////////////////////////// - Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length) - { - if (!password || !user) - return 1; +namespace Kernel { +namespace Detail { + //////////////////////////////////////////////////////////// + /// \brief Constructs a password by hashing the password. + /// \param password password to hash. + /// \return the hashed password + //////////////////////////////////////////////////////////// + Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length) { + if (!password || !user) return 1; + + kout << "cred_construct_token: Hashing user password...\r"; + + for (SizeT i_pass = 0UL; i_pass < length; ++i_pass) { + Char cur_chr = in_password[i_pass]; + + if (cur_chr == 0) break; + + password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType); + } + + kout << "cred_construct_token: Hashed user password.\r"; + + return 0; + } +} // 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((VoidPtr) user_name, this->mUserName, rt_string_len(user_name)); +} + +//////////////////////////////////////////////////////////// +/// @brief User ring constructor. +//////////////////////////////////////////////////////////// +User::User(const UserRingKind& ring_kind, const Char* user_name) : mUserRing(ring_kind) { + rt_copy_memory((VoidPtr) user_name, this->mUserName, rt_string_len(user_name)); +} + +//////////////////////////////////////////////////////////// +/// @brief User destructor class. +//////////////////////////////////////////////////////////// +User::~User() = default; + +Bool User::Save(const UserPublicKey password_to_fill) noexcept { + if (!password_to_fill || *password_to_fill == 0) return No; + + SizeT len = rt_string_len(password_to_fill); - kout << "cred_construct_token: Hashing user password...\r"; + UserPublicKey password = new UserPublicKeyType[len]; - for (SizeT i_pass = 0UL; i_pass < length; ++i_pass) - { - Char cur_chr = in_password[i_pass]; + MUST_PASS(password); - if (cur_chr == 0) - break; + rt_set_memory(password, 0, len); - password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType); - } + // fill data first, generate hash. + // return false on error. - kout << "cred_construct_token: Hashed user password.\r"; + rt_copy_memory((VoidPtr) password_to_fill, password, len); - return 0; - } - } // namespace Detail + if (!Detail::cred_construct_token(password, password_to_fill, this, len)) { + delete[] password; + password = nullptr; - //////////////////////////////////////////////////////////// - /// @brief User ring constructor. - //////////////////////////////////////////////////////////// - User::User(const Int32& sel, const Char* user_name) - : mUserRing((UserRingKind)sel) - { - MUST_PASS(sel >= 0); - rt_copy_memory((VoidPtr)user_name, this->mUserName, rt_string_len(user_name)); - } + return No; + } - //////////////////////////////////////////////////////////// - /// @brief User ring constructor. - //////////////////////////////////////////////////////////// - User::User(const UserRingKind& ring_kind, const Char* user_name) - : mUserRing(ring_kind) - { - rt_copy_memory((VoidPtr)user_name, this->mUserName, rt_string_len(user_name)); - } + // then store password. - //////////////////////////////////////////////////////////// - /// @brief User destructor class. - //////////////////////////////////////////////////////////// - User::~User() = default; + rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill)); - Bool User::Save(const UserPublicKey password_to_fill) noexcept - { - if (!password_to_fill || - *password_to_fill == 0) - return No; + delete[] password; + password = nullptr; - SizeT len = rt_string_len(password_to_fill); + kout << "User::Save: Saved password successfully...\r"; - UserPublicKey password = new UserPublicKeyType[len]; + return Yes; +} - MUST_PASS(password); +Bool User::Matches(const UserPublicKey password_to_fill) noexcept { + if (!password_to_fill || *password_to_fill) return No; - rt_set_memory(password, 0, len); + SizeT len = rt_string_len(password_to_fill); - // fill data first, generate hash. - // return false on error. - - rt_copy_memory((VoidPtr)password_to_fill, password, len); - - if (!Detail::cred_construct_token(password, password_to_fill, this, len)) - { - delete[] password; - password = nullptr; - - return No; - } - - // then store password. - - rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill)); - - delete[] password; - password = nullptr; - - kout << "User::Save: Saved password successfully...\r"; - - return Yes; - } - - Bool User::Matches(const UserPublicKey password_to_fill) noexcept - { - if (!password_to_fill || - *password_to_fill) - return No; - - SizeT len = rt_string_len(password_to_fill); - - Char* password = new Char[len]; - MUST_PASS(password); + Char* password = new Char[len]; + MUST_PASS(password); - // fill data first, generate hash. - // return false on error. + // fill data first, generate hash. + // return false on error. - rt_copy_memory((VoidPtr)password_to_fill, password, len); + rt_copy_memory((VoidPtr) password_to_fill, password, len); - if (!Detail::cred_construct_token(password, password_to_fill, this, len)) - { - delete[] password; - password = nullptr; + if (!Detail::cred_construct_token(password, password_to_fill, this, len)) { + delete[] password; + password = nullptr; - return No; - } + return No; + } - kout << "User::Matches: Validating hashed passwords...\r"; + kout << "User::Matches: Validating hashed passwords...\r"; - // now check if the password matches. - if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0) - { - kout << "User::Matches: Password matches.\r"; - return Yes; - } + // now check if the password matches. + if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0) { + kout << "User::Matches: Password matches.\r"; + return Yes; + } - kout << "User::Matches: Password doesn't match.\r"; - return No; - } + kout << "User::Matches: Password doesn't match.\r"; + return No; +} - Bool User::operator==(const User& lhs) - { - return lhs.mUserRing == this->mUserRing; - } +Bool User::operator==(const User& lhs) { + return lhs.mUserRing == this->mUserRing; +} - 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. - //////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +/// @brief Returns the user's name. +//////////////////////////////////////////////////////////// - Char* User::Name() noexcept - { - return this->mUserName; - } +Char* User::Name() noexcept { + return this->mUserName; +} - //////////////////////////////////////////////////////////// - /// @brief Returns the user's ring. - /// @return The king of ring the user is attached to. - //////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////// +/// @brief Returns the user's ring. +/// @return The king of ring the user is attached to. +//////////////////////////////////////////////////////////// - const UserRingKind& User::Ring() noexcept - { - return this->mUserRing; - } +const UserRingKind& User::Ring() noexcept { + return this->mUserRing; +} - Bool User::IsStdUser() noexcept - { - return this->Ring() == UserRingKind::kRingStdUser; - } +Bool User::IsStdUser() noexcept { + return this->Ring() == UserRingKind::kRingStdUser; +} - Bool User::IsSuperUser() noexcept - { - return this->Ring() == UserRingKind::kRingSuperUser; - } -} // namespace Kernel +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 index d6be0f5f..ae7bbfb8 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -1,9 +1,9 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - FILE: UserProcessScheduler.cc - PURPOSE: Low level/Ring-3 process scheduler. + FILE: UserProcessScheduler.cc + PURPOSE: Low level/Ring-3 process scheduler. ------------------------------------------- */ @@ -13,734 +13,656 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) /***********************************************************************************/ -#include +#include #include #include -#include +#include #include +#include #include -#include ///! BUGS: 0 -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Exit Code global variable. - /***********************************************************************************/ - - STATIC UInt32 kLastExitCode = 0U; - - STATIC BOOL kCurrentlySwitching = No; - - /***********************************************************************************/ - /// @brief Scheduler itself. - /***********************************************************************************/ - - STATIC UserProcessScheduler kScheduler; - - 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. - - const UInt32& sched_get_exit_code(void) noexcept - { - return kLastExitCode; - } - - /***********************************************************************************/ - /// @brief Crashes the current process. - /***********************************************************************************/ - - Void USER_PROCESS::Crash() - { - if (this->Status != ProcessStatusKind::kRunning) - return; - - (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); - this->Exit(-kErrorProcessFault); - } - - /***********************************************************************************/ - /// @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. - /***********************************************************************************/ - - const UInt32& USER_PROCESS::GetExitCode() noexcept - { - return this->fLastExitCode; - } - - /***********************************************************************************/ - /// @brief Error code variable getter. - /***********************************************************************************/ - - Int32& USER_PROCESS::GetLocalCode() noexcept - { - return this->fLocalCode; - } - - /***********************************************************************************/ - /// @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. */ - /***********************************************************************************/ - - STATIC USER_PROCESS::USER_HEAP_TREE* sched_try_go_upper_heap_tree(USER_PROCESS::USER_HEAP_TREE* tree) - { - if (tree) - { - tree = tree->MemoryNext; - - if (!tree) - { - return nullptr; - } - } - - return tree; - } - - /***********************************************************************************/ - /** @brief Allocate pointer to heap tree. */ - /***********************************************************************************/ - - ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) - { - if (this->UsedMemory > kSchedMaxMemoryLimit) - return ErrorOr(-kErrorHeapOutOfMemory); +namespace Kernel { +/***********************************************************************************/ +/// @brief Exit Code global variable. +/***********************************************************************************/ + +STATIC UInt32 kLastExitCode = 0U; + +STATIC BOOL kCurrentlySwitching = No; + +/***********************************************************************************/ +/// @brief Scheduler itself. +/***********************************************************************************/ + +STATIC UserProcessScheduler kScheduler; + +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. + +const UInt32& sched_get_exit_code(void) noexcept { + return kLastExitCode; +} + +/***********************************************************************************/ +/// @brief Crashes the current process. +/***********************************************************************************/ + +Void USER_PROCESS::Crash() { + if (this->Status != ProcessStatusKind::kRunning) return; + + (Void)(kout << this->Name << ": crashed, error id: " << number(-kErrorProcessFault) << kendl); + this->Exit(-kErrorProcessFault); +} + +/***********************************************************************************/ +/// @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. +/***********************************************************************************/ + +const UInt32& USER_PROCESS::GetExitCode() noexcept { + return this->fLastExitCode; +} + +/***********************************************************************************/ +/// @brief Error code variable getter. +/***********************************************************************************/ + +Int32& USER_PROCESS::GetLocalCode() noexcept { + return this->fLocalCode; +} + +/***********************************************************************************/ +/// @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. */ +/***********************************************************************************/ + +STATIC USER_PROCESS::USER_HEAP_TREE* sched_try_go_upper_heap_tree( + USER_PROCESS::USER_HEAP_TREE* tree) { + if (tree) { + tree = tree->MemoryNext; + + if (!tree) { + return nullptr; + } + } + + return tree; +} + +/***********************************************************************************/ +/** @brief Allocate pointer to heap tree. */ +/***********************************************************************************/ + +ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { + if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr(-kErrorHeapOutOfMemory); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto vm_register = hal_read_cr3(); - hal_write_cr3(this->VMRegister); + auto vm_register = hal_read_cr3(); + hal_write_cr3(this->VMRegister); - auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); + auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); - hal_write_cr3(vm_register); + hal_write_cr3(vm_register); #else - auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); + auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); #endif - if (!this->HeapTree) - { - this->HeapTree = new USER_HEAP_TREE(); - - this->HeapTree->MemoryColor = USER_HEAP_TREE::kBlackMemory; - - this->HeapTree->MemoryEntryPad = pad_amount; - this->HeapTree->MemoryEntrySize = sz; - - this->HeapTree->MemoryEntry = ptr; - - this->HeapTree->MemoryPrev = nullptr; - this->HeapTree->MemoryNext = nullptr; - this->HeapTree->MemoryParent = nullptr; - this->HeapTree->MemoryChild = nullptr; - } - else - { - USER_HEAP_TREE* entry = this->HeapTree; - USER_HEAP_TREE* prev_entry = entry; - - BOOL is_parent = NO; - - while (entry) - { - if (entry->MemoryEntrySize < 1) - break; - - prev_entry = entry; - - if (entry->MemoryNext) - { - is_parent = NO; - entry = entry->MemoryNext; - } - else if (entry->MemoryChild) - { - entry = entry->MemoryChild; - is_parent = YES; - } - else - { - entry = entry->MemoryParent; - entry = sched_try_go_upper_heap_tree(entry); - } - } - - if (!entry) - entry = new USER_HEAP_TREE(); - - entry->MemoryEntry = ptr; - entry->MemoryEntrySize = sz; - entry->MemoryEntryPad = pad_amount; - - if (is_parent) - { - entry->MemoryParent = prev_entry; - prev_entry->MemoryChild = entry; - - prev_entry->MemoryColor = USER_HEAP_TREE::kBlackMemory; - entry->MemoryColor = USER_HEAP_TREE::kRedMemory; - } - else - { - prev_entry->MemoryNext = entry; - entry->MemoryPrev = prev_entry; - } - } - - this->UsedMemory += sz; - - return ErrorOr(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. */ - /***********************************************************************************/ - - STATIC Void sched_free_heap_tree(USER_PROCESS::USER_HEAP_TREE* memory_heap_list) - { - // Deleting memory lists. Make sure to free all of them. - while (memory_heap_list) - { - if (memory_heap_list->MemoryEntry) - { - MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry)); - } - - auto next = memory_heap_list->MemoryNext; - - mm_delete_heap(memory_heap_list); - - if (memory_heap_list->MemoryChild) - sched_free_heap_tree(memory_heap_list->MemoryChild); - - memory_heap_list = 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->fLastExitCode = exit_code; - - kLastExitCode = exit_code; - - auto memory_heap_list = this->HeapTree; + if (!this->HeapTree) { + this->HeapTree = new USER_HEAP_TREE(); + + this->HeapTree->MemoryColor = USER_HEAP_TREE::kBlackMemory; + + this->HeapTree->MemoryEntryPad = pad_amount; + this->HeapTree->MemoryEntrySize = sz; + + this->HeapTree->MemoryEntry = ptr; + + this->HeapTree->MemoryPrev = nullptr; + this->HeapTree->MemoryNext = nullptr; + this->HeapTree->MemoryParent = nullptr; + this->HeapTree->MemoryChild = nullptr; + } else { + USER_HEAP_TREE* entry = this->HeapTree; + USER_HEAP_TREE* prev_entry = entry; + + BOOL is_parent = NO; + + while (entry) { + if (entry->MemoryEntrySize < 1) break; + + prev_entry = entry; + + if (entry->MemoryNext) { + is_parent = NO; + entry = entry->MemoryNext; + } else if (entry->MemoryChild) { + entry = entry->MemoryChild; + is_parent = YES; + } else { + entry = entry->MemoryParent; + entry = sched_try_go_upper_heap_tree(entry); + } + } + + if (!entry) entry = new USER_HEAP_TREE(); + + entry->MemoryEntry = ptr; + entry->MemoryEntrySize = sz; + entry->MemoryEntryPad = pad_amount; + + if (is_parent) { + entry->MemoryParent = prev_entry; + prev_entry->MemoryChild = entry; + + prev_entry->MemoryColor = USER_HEAP_TREE::kBlackMemory; + entry->MemoryColor = USER_HEAP_TREE::kRedMemory; + } else { + prev_entry->MemoryNext = entry; + entry->MemoryPrev = prev_entry; + } + } + + this->UsedMemory += sz; + + return ErrorOr(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. */ +/***********************************************************************************/ + +STATIC Void sched_free_heap_tree(USER_PROCESS::USER_HEAP_TREE* memory_heap_list) { + // Deleting memory lists. Make sure to free all of them. + while (memory_heap_list) { + if (memory_heap_list->MemoryEntry) { + MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry)); + } + + auto next = memory_heap_list->MemoryNext; + + mm_delete_heap(memory_heap_list); + + if (memory_heap_list->MemoryChild) sched_free_heap_tree(memory_heap_list->MemoryChild); + + memory_heap_list = 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->fLastExitCode = exit_code; + + kLastExitCode = exit_code; + + auto memory_heap_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto pd = hal_read_cr3(); - hal_write_cr3(this->VMRegister); + auto pd = hal_read_cr3(); + hal_write_cr3(this->VMRegister); #endif - sched_free_heap_tree(memory_heap_list); + sched_free_heap_tree(memory_heap_list); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - hal_write_cr3(pd); + 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); + //! 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_heap(this->Image.fCode)) - mm_delete_heap(this->Image.fCode); + //! Delete image if not done already. + if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode)) mm_delete_heap(this->Image.fCode); - //! Delete blob too. - if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob)) - mm_delete_heap(this->Image.fBlob); + //! Delete blob too. + if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob)) mm_delete_heap(this->Image.fBlob); - //! Delete stack frame. - if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) - mm_delete_heap((VoidPtr)this->StackFrame); + //! Delete stack frame. + if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) + mm_delete_heap((VoidPtr) this->StackFrame); - //! Delete stack reserve. - if (this->StackReserve && mm_is_valid_heap(this->StackReserve)) - mm_delete_heap(reinterpret_cast(this->StackReserve)); + //! Delete stack reserve. + if (this->StackReserve && mm_is_valid_heap(this->StackReserve)) + mm_delete_heap(reinterpret_cast(this->StackReserve)); - //! Avoid use after free. - this->Image.fBlob = nullptr; - this->Image.fCode = nullptr; - this->StackFrame = nullptr; - this->StackReserve = nullptr; + //! Avoid use after free. + this->Image.fBlob = nullptr; + this->Image.fCode = nullptr; + this->StackFrame = nullptr; + this->StackReserve = nullptr; - if (this->Kind == kExecutableDylibKind) - { - Bool success = false; + if (this->Kind == kExecutableDylibKind) { + Bool success = false; - rtl_fini_dylib_pef(*this, reinterpret_cast(this->DylibDelegate), &success); + rtl_fini_dylib_pef(*this, reinterpret_cast(this->DylibDelegate), &success); - if (!success) - { - ke_panic(RUNTIME_CHECK_PROCESS); - } + if (!success) { + ke_panic(RUNTIME_CHECK_PROCESS); + } - this->DylibDelegate = nullptr; - } + this->DylibDelegate = nullptr; + } - this->ProcessId = 0UL; - this->Status = ProcessStatusKind::kFinished; + this->ProcessId = 0UL; + this->Status = ProcessStatusKind::kFinished; - --this->ParentTeam->mProcessCount; - } + --this->ParentTeam->mProcessCount; +} - /***********************************************************************************/ - /// @brief Add process to team. - /// @param process the process *Ref* class. - /// @return the process index inside the team. - /***********************************************************************************/ +/***********************************************************************************/ +/// @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; - } +ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image) { + if (!name || !code) { + return -kErrorProcessFault; + } - if (*name == 0) - { - return -kErrorProcessFault; - } + if (*name == 0) { + return -kErrorProcessFault; + } - ProcessID pid = this->mTeam.mProcessCount; + ProcessID pid = this->mTeam.mProcessCount; - if (pid > kSchedProcessLimitPerTeam) - { - return -kErrorProcessFault; - } + if (pid > kSchedProcessLimitPerTeam) { + return -kErrorProcessFault; + } - ++this->mTeam.mProcessCount; + ++this->mTeam.mProcessCount; - USER_PROCESS& process = this->mTeam.mProcessList[pid]; + USER_PROCESS& process = this->mTeam.mProcessList[pid]; - process.Image.fCode = code; - process.Image.fBlob = image; + process.Image.fCode = code; + process.Image.fBlob = image; - SizeT len = rt_string_len(name); + SizeT len = rt_string_len(name); - if (len > kSchedNameLen) - { - return -kErrorProcessFault; - } + if (len > kSchedNameLen) { + return -kErrorProcessFault; + } - rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); + rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.VMRegister = new PDE(); + process.VMRegister = new PDE(); - if (!process.VMRegister) - { - process.Crash(); - return -kErrorProcessFault; - } + if (!process.VMRegister) { + process.Crash(); + return -kErrorProcessFault; + } - UInt32 flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; + UInt32 flags = HAL::kMMFlagsPresent; + flags |= HAL::kMMFlagsWr; + flags |= HAL::kMMFlagsUser; - HAL::mm_map_page((VoidPtr)process.VMRegister, process.VMRegister, flags); -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + HAL::mm_map_page((VoidPtr) process.VMRegister, process.VMRegister, flags); +#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.StackFrame = new HAL::StackFrame(); + process.StackFrame = new HAL::StackFrame(); - if (!process.StackFrame) - { - process.Crash(); - return -kErrorProcessFault; - } + if (!process.StackFrame) { + process.Crash(); + return -kErrorProcessFault; + } - rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame)); + rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame)); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; - - HAL::mm_map_page((VoidPtr)process.StackFrame, process.StackFrame, flags); -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - - // React according to process kind. - switch (process.Kind) - { - case USER_PROCESS::kExecutableDylibKind: { - process.DylibDelegate = rtl_init_dylib_pef(process); - MUST_PASS(process.DylibDelegate); - break; - } - case USER_PROCESS::kExecutableKind: { - break; - } - default: { - (Void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl); - break; - } - } - - process.StackReserve = new UInt8[process.StackSize]; - - if (!process.StackReserve) - { - process.Crash(); - return -kErrorProcessFault; - } - - rt_set_memory(process.StackReserve, 0, process.StackSize); + flags = HAL::kMMFlagsPresent; + flags |= HAL::kMMFlagsWr; + flags |= HAL::kMMFlagsUser; + + HAL::mm_map_page((VoidPtr) process.StackFrame, process.StackFrame, flags); +#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + + // React according to process kind. + switch (process.Kind) { + case USER_PROCESS::kExecutableDylibKind: { + process.DylibDelegate = rtl_init_dylib_pef(process); + MUST_PASS(process.DylibDelegate); + break; + } + case USER_PROCESS::kExecutableKind: { + break; + } + default: { + (Void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl); + break; + } + } + + process.StackReserve = new UInt8[process.StackSize]; + + if (!process.StackReserve) { + process.Crash(); + return -kErrorProcessFault; + } + + rt_set_memory(process.StackReserve, 0, process.StackSize); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; + flags = HAL::kMMFlagsPresent; + flags |= HAL::kMMFlagsWr; + flags |= HAL::kMMFlagsUser; + + HAL::mm_map_page((VoidPtr) process.StackReserve, process.StackReserve, flags); +#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + + process.ParentTeam = &mTeam; + + process.ProcessId = pid; + process.Status = ProcessStatusKind::kStarting; + process.PTime = (UIntPtr) AffinityKind::kStandard; + + (Void)(kout << "PID: " << number(process.ProcessId) << kendl); + (Void)(kout << "Name: " << process.Name << kendl); + + return pid; +} + +/***********************************************************************************/ +/// @brief Retrieves the singleton of the process scheduler. +/***********************************************************************************/ + +UserProcessScheduler& UserProcessScheduler::The() { + 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(0); +} + +/// @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 { + SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many + //! things we have scheduled. + + if (mTeam.mProcessCount < 1) { + return 0UL; + } + + kCurrentlySwitching = Yes; + + 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)) { + // Set current process header. + this->CurrentProcess() = process; + + process.PTime = static_cast(process.Affinity); + + // tell helper to find a core to schedule on. + BOOL ret = UserProcessHelper::Switch(process.Image.fCode, + &process.StackReserve[process.StackSize - 1], + process.StackFrame, process.ProcessId); + + if (!ret) { + if (process.Affinity == AffinityKind::kRealTime) continue; + + kout << "The process: " << process.Name << ", is not valid! Crashing it...\r"; + + process.Crash(); + } + } else { + --process.PTime; + } + } + + kCurrentlySwitching = No; + + return process_index; +} + +/// @brief Gets the current scheduled team. +/// @return +UserProcessTeam& UserProcessScheduler::CurrentTeam() { + 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; + + if (kCurrentlySwitching) return No; + + kScheduler.mTeam = team; + + return Yes; +} + +/// @brief Gets current running process. +/// @return +Ref& UserProcessScheduler::CurrentProcess() { + return mTeam.AsRef(); +} + +/// @brief Current proccess id getter. +/// @return USER_PROCESS ID integer. +ErrorOr UserProcessHelper::TheCurrentPID() { + if (!kScheduler.CurrentProcess()) return ErrorOr{-kErrorProcessFault}; + + kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; + return ErrorOr{kScheduler.CurrentProcess().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.Status == ProcessStatusKind::kKilled || + process.Status == ProcessStatusKind::kFinished || + process.Status == ProcessStatusKind::kStarting || + process.Status == ProcessStatusKind::kFrozen) + return No; + + if (process.Status == ProcessStatusKind::kInvalid) return No; + + if (!process.Image.fCode) return No; + + if (!process.Name[0]) return No; + + // real time processes shouldn't wait that much. + if (process.Affinity == AffinityKind::kRealTime) return Yes; + + return process.PTime < 1; +} + +/***********************************************************************************/ +/** + * @brief Start scheduling current AP. + */ +/***********************************************************************************/ + +SizeT UserProcessHelper::StartScheduling() { + return kScheduler.Run(); +} + +/***********************************************************************************/ +/** + * \brief Does a context switch in a CPU. + * \param the_stack the stackframe of the running app. + * \param new_pid the process's PID. + */ +/***********************************************************************************/ + +Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr frame_ptr, + PID new_pid) { + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { + if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid || + HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot) + continue; + + // A fallback is a special core for real-time tasks which needs immediate execution. + if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPRealTime) { + if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity != + AffinityKind::kRealTime) + continue; + + if (HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid)) { + HardwareThreadScheduler::The()[index].Leak()->fPTime = + UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; - HAL::mm_map_page((VoidPtr)process.StackReserve, process.StackReserve, flags); -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - process.ParentTeam = &mTeam; + return YES; + } - process.ProcessId = pid; - process.Status = ProcessStatusKind::kStarting; - process.PTime = (UIntPtr)AffinityKind::kStandard; + continue; + } - (Void)(kout << "PID: " << number(process.ProcessId) << kendl); - (Void)(kout << "Name: " << process.Name << kendl); + if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity == + AffinityKind::kRealTime) + continue; - return pid; - } + //////////////////////////////////////////////////////////// + /// Prepare task switch. /// + //////////////////////////////////////////////////////////// - /***********************************************************************************/ - /// @brief Retrieves the singleton of the process scheduler. - /***********************************************************************************/ + Bool ret = + HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid); - UserProcessScheduler& UserProcessScheduler::The() - { - return kScheduler; - } + //////////////////////////////////////////////////////////// + /// Rollback on fail. /// + //////////////////////////////////////////////////////////// - /***********************************************************************************/ + if (!ret) continue; - /// @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. + UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid; - /***********************************************************************************/ + HardwareThreadScheduler::The()[index].Leak()->fPTime = + UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; + HardwareThreadScheduler::The()[index].Leak()->Wake(YES); - 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(0); - } + return Yes; + } - /// @brief Is it a user scheduler? + return No; +} - Bool UserProcessScheduler::IsUser() - { - return Yes; - } +//////////////////////////////////////////////////////////// +/// @brief this checks if any process is on the team. +//////////////////////////////////////////////////////////// +UserProcessScheduler::operator bool() { + return mTeam.AsArray().Count() > 0; +} - /// @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 - { - SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - - if (mTeam.mProcessCount < 1) - { - return 0UL; - } - - kCurrentlySwitching = Yes; - - 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)) - { - // Set current process header. - this->CurrentProcess() = process; - - process.PTime = static_cast(process.Affinity); - - // tell helper to find a core to schedule on. - BOOL ret = UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame, - process.ProcessId); - - if (!ret) - { - if (process.Affinity == AffinityKind::kRealTime) - continue; - - kout << "The process: " << process.Name << ", is not valid! Crashing it...\r"; - - process.Crash(); - } - } - else - { - --process.PTime; - } - } - - kCurrentlySwitching = No; - - return process_index; - } - - /// @brief Gets the current scheduled team. - /// @return - UserProcessTeam& UserProcessScheduler::CurrentTeam() - { - 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; - - if (kCurrentlySwitching) - return No; - - kScheduler.mTeam = team; - - return Yes; - } - - /// @brief Gets current running process. - /// @return - Ref& UserProcessScheduler::CurrentProcess() - { - return mTeam.AsRef(); - } - - /// @brief Current proccess id getter. - /// @return USER_PROCESS ID integer. - ErrorOr UserProcessHelper::TheCurrentPID() - { - if (!kScheduler.CurrentProcess()) - return ErrorOr{-kErrorProcessFault}; - - kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return ErrorOr{kScheduler.CurrentProcess().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.Status == ProcessStatusKind::kKilled || - process.Status == ProcessStatusKind::kFinished || - process.Status == ProcessStatusKind::kStarting || - process.Status == ProcessStatusKind::kFrozen) - return No; - - if (process.Status == ProcessStatusKind::kInvalid) - return No; - - if (!process.Image.fCode) - return No; - - if (!process.Name[0]) - return No; - - // real time processes shouldn't wait that much. - if (process.Affinity == AffinityKind::kRealTime) - return Yes; - - return process.PTime < 1; - } - - /***********************************************************************************/ - /** - * @brief Start scheduling current AP. - */ - /***********************************************************************************/ - - SizeT UserProcessHelper::StartScheduling() - { - return kScheduler.Run(); - } - - /***********************************************************************************/ - /** - * \brief Does a context switch in a CPU. - * \param the_stack the stackframe of the running app. - * \param new_pid the process's PID. - */ - /***********************************************************************************/ - - Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr frame_ptr, PID new_pid) - { - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) - { - if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid || - HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot) - continue; - - // A fallback is a special core for real-time tasks which needs immediate execution. - if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPRealTime) - { - if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity != AffinityKind::kRealTime) - continue; - - if (HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid)) - { - HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; - - UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - - return YES; - } - - continue; - } - - if (UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].Affinity == AffinityKind::kRealTime) - continue; - - //////////////////////////////////////////////////////////// - /// Prepare task switch. /// - //////////////////////////////////////////////////////////// - - Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid); - - //////////////////////////////////////////////////////////// - /// Rollback on fail. /// - //////////////////////////////////////////////////////////// - - if (!ret) - continue; - - UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid; - - HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; - HardwareThreadScheduler::The()[index].Leak()->Wake(YES); - - return Yes; - } - - return No; - } - - //////////////////////////////////////////////////////////// - /// @brief this checks if any process is on the team. - //////////////////////////////////////////////////////////// - UserProcessScheduler::operator bool() - { - return mTeam.AsArray().Count() > 0; - } - - //////////////////////////////////////////////////////////// - /// @brief this checks if no process is on the team. - //////////////////////////////////////////////////////////// - Bool UserProcessScheduler::operator!() - { - return mTeam.AsArray().Count() == 0; - } -} // namespace Kernel +//////////////////////////////////////////////////////////// +/// @brief this checks if no process is on the team. +//////////////////////////////////////////////////////////// +Bool UserProcessScheduler::operator!() { + return mTeam.AsArray().Count() == 0; +} +} // namespace Kernel diff --git a/dev/kernel/src/Utils.cc b/dev/kernel/src/Utils.cc index f5e61ddf..eed6f076 100644 --- a/dev/kernel/src/Utils.cc +++ b/dev/kernel/src/Utils.cc @@ -1,224 +1,189 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) - { - Int32 counter = 0; +namespace Kernel { +Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size) { + Int32 counter = 0; - for (Size index = 0; index < size; ++index) - { - if (src[index] != cmp[index]) - ++counter; - } + for (Size index = 0; index < size; ++index) { + if (src[index] != cmp[index]) ++counter; + } - return counter; - } + return counter; +} + +Void rt_zero_memory(voidPtr pointer, Size len) { + rt_set_memory(pointer, 0, len); +} + +SizeT rt_string_len(const Char* str, SizeT _len) { + SizeT len{0}; + + do { + if (len > _len) { + return _len; + } + + ++len; + } while (str[len] != '\0'); + + return len; +} + +Size rt_string_len(const Char* ptr) { + SizeT cnt{0}; + + while (ptr[cnt] != 0) ++cnt; + + return cnt; +} + +voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) { + UInt32* start = reinterpret_cast(src); + + while (len) { + *start = value; + ++start; + --len; + } - Void rt_zero_memory(voidPtr pointer, Size len) - { - rt_set_memory(pointer, 0, len); - } + return (voidPtr) start; +} + +Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) { + Char* srcChr = reinterpret_cast(src); + Char* dstChar = reinterpret_cast(dst); + SizeT index = 0; - SizeT rt_string_len(const Char* str, SizeT _len) - { - SizeT len{0}; + while (index < len) { + dstChar[index] = srcChr[index]; + srcChr[index] = 0; - do - { - if (len > _len) - { - return _len; - } + ++index; + } - ++len; - } while (str[len] != '\0'); + return 0; +} + +Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len) { + char* srcChr = reinterpret_cast(src); + char* dstChar = reinterpret_cast(dst); + Size index = 0; + + while (index < len) { + dstChar[index] = srcChr[index]; + ++index; + } + + dstChar[index] = 0; + + return index; +} - return len; - } +const Char* rt_alloc_string(const Char* src) { + const Char* string = new Char[rt_string_len(src) + 1]; - Size rt_string_len(const Char* ptr) - { - SizeT cnt{0}; + if (!string) return nullptr; - while (ptr[cnt] != 0) - ++cnt; - - return cnt; - } - - voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) - { - UInt32* start = reinterpret_cast(src); - - while (len) - { - *start = value; - ++start; - --len; - } - - return (voidPtr)start; - } - - Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) - { - Char* srcChr = reinterpret_cast(src); - Char* dstChar = reinterpret_cast(dst); - SizeT index = 0; - - while (index < len) - { - dstChar[index] = srcChr[index]; - srcChr[index] = 0; - - ++index; - } - - return 0; - } - - Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len) - { - char* srcChr = reinterpret_cast(src); - char* dstChar = reinterpret_cast(dst); - Size index = 0; - - while (index < len) - { - dstChar[index] = srcChr[index]; - ++index; - } - - dstChar[index] = 0; - - return index; - } - - const Char* rt_alloc_string(const Char* src) - { - const Char* string = new Char[rt_string_len(src) + 1]; - - if (!string) - return nullptr; - - voidPtr v_src = reinterpret_cast(const_cast(src)); - voidPtr v_dst = reinterpret_cast(const_cast(string)); - - rt_copy_memory(v_src, v_dst, rt_string_len(src) + 1); - - return string; - } - - Int32 rt_to_uppercase(Int32 character) - { - if (character >= 'a' && character <= 'z') - return character - 0x20; - - return character; - } - - Int32 rt_is_alnum(Int32 character) - { - return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9'); - } - - Int32 rt_to_lower(Int32 character) - { - if (character >= 'A' && character <= 'Z') - return character + 0x20; - - return character; - } + voidPtr v_src = reinterpret_cast(const_cast(src)); + voidPtr v_dst = reinterpret_cast(const_cast(string)); - Boolean rt_is_space(Char chr) - { - return chr == ' '; - } - - Boolean rt_is_newln(Char chr) - { - return chr == '\n'; - } - - VoidPtr rt_string_in_string(const Char* in, const Char* needle) - { - for (SizeT i = 0; i < rt_string_len(in); ++i) - { - if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0) - return reinterpret_cast(const_cast(in + i)); - } - - return nullptr; - } - - Char rt_to_char(UInt64 base, Int32 limit) - { - Char kNumbers[17] = "0123456789ABCDEF"; - return kNumbers[base % limit]; - } + rt_copy_memory(v_src, v_dst, rt_string_len(src) + 1); - Bool rt_to_string(Char* str, UInt64 base, Int32 limit) - { + return string; +} + +Int32 rt_to_uppercase(Int32 character) { + if (character >= 'a' && character <= 'z') return character - 0x20; + + return character; +} + +Int32 rt_is_alnum(Int32 character) { + return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9'); +} + +Int32 rt_to_lower(Int32 character) { + if (character >= 'A' && character <= 'Z') return character + 0x20; + + return character; +} + +Boolean rt_is_space(Char chr) { + return chr == ' '; +} + +Boolean rt_is_newln(Char chr) { + return chr == '\n'; +} + +VoidPtr rt_string_in_string(const Char* in, const Char* needle) { + for (SizeT i = 0; i < rt_string_len(in); ++i) { + if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0) + return reinterpret_cast(const_cast(in + i)); + } + + return nullptr; +} + +Char rt_to_char(UInt64 base, Int32 limit) { + Char kNumbers[17] = "0123456789ABCDEF"; + return kNumbers[base % limit]; +} + +Bool rt_to_string(Char* str, UInt64 base, Int32 limit) { #ifdef __NE_AMD64__ - auto i = 0; + auto i = 0; - auto final_number = base; + auto final_number = base; - auto mult = 1; - auto elems = 0L; + auto mult = 1; + auto elems = 0L; - base /= 10; + base /= 10; - while (base > 0) - { - elems++; - mult *= 10; - base /= 10; - } + while (base > 0) { + elems++; + mult *= 10; + base /= 10; + } - while (elems > -1) - { - final_number = (final_number % mult) * 10 + final_number / mult; - str[i] = rt_to_char(final_number, limit); + while (elems > -1) { + final_number = (final_number % mult) * 10 + final_number / mult; + str[i] = rt_to_char(final_number, limit); - --elems; - ++i; - } + --elems; + ++i; + } #endif - return YES; - } + return YES; +} - /// @brief Checks for a string start at the character. +/// @brief Checks for a string start at the character. - Char* rt_string_has_char(Char* str, Char chr) - { - while (*str != chr) - { - ++str; +Char* rt_string_has_char(Char* str, Char chr) { + while (*str != chr) { + ++str; - if (*str == 0) - return nullptr; - } + if (*str == 0) return nullptr; + } - return str; - } -} // namespace Kernel + return str; +} +} // namespace Kernel -EXTERN_C void* memset(void* dst, int c, long long unsigned int len) -{ - return Kernel::rt_set_memory(dst, c, len); +EXTERN_C void* memset(void* dst, int c, long long unsigned int len) { + return Kernel::rt_set_memory(dst, c, len); } -EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) -{ - Kernel::rt_copy_memory(const_cast(src), dst, len); - return dst; +EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len) { + Kernel::rt_copy_memory(const_cast(src), dst, len); + return dst; } diff --git a/dev/kernel/src/Variant.cc b/dev/kernel/src/Variant.cc index 239b73fa..5dd39926 100644 --- a/dev/kernel/src/Variant.cc +++ b/dev/kernel/src/Variant.cc @@ -1,43 +1,38 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - const Char* Variant::ToString() - { - switch (fKind) - { - case VariantKind::kXML: - return ("Class:{XML}"); - 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}"); - } - } +namespace Kernel { +const Char* Variant::ToString() { + switch (fKind) { + case VariantKind::kXML: + return ("Class:{XML}"); + 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 Return variant's kind. +Variant::VariantKind& Variant::Kind() { + return this->fKind; +} - /// @brief Leak variant's instance. - VoidPtr Variant::Leak() - { - return this->fPtr; - } -} // namespace Kernel +/// @brief Leak variant's instance. +VoidPtr Variant::Leak() { + return this->fPtr; +} +} // namespace Kernel diff --git a/dev/kernel/src/WideUtils.cc b/dev/kernel/src/WideUtils.cc index a935c2d4..e6c5a533 100644 --- a/dev/kernel/src/WideUtils.cc +++ b/dev/kernel/src/WideUtils.cc @@ -1,20 +1,17 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include -namespace Kernel -{ - Size wrt_string_len(const Utf16Char* str) - { - SizeT len{0}; +namespace Kernel { +Size wrt_string_len(const Utf16Char* str) { + SizeT len{0}; - while (str[len] != 0) - ++len; + while (str[len] != 0) ++len; - return len; - } -} // namespace Kernel \ No newline at end of file + return len; +} +} // namespace Kernel \ No newline at end of file diff --git a/dev/modules/ACPI/ACPI.h b/dev/modules/ACPI/ACPI.h index 305c061c..40b393d5 100644 --- a/dev/modules/ACPI/ACPI.h +++ b/dev/modules/ACPI/ACPI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,83 +8,76 @@ #define __ACPI__ /** - https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html + https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html */ #include #define SDT_OBJECT : public Kernel::SDT -namespace Kernel -{ - class PACKED SDT - { - public: - Char Signature[4]; - UInt32 Length; - UInt8 Revision; - Char Checksum; - Char OemId[6]; - Char OemTableId[8]; - UInt32 OemRev; - UInt32 CreatorID; - UInt32 CreatorRevision; - }; +namespace Kernel { +class PACKED SDT { + public: + Char Signature[4]; + UInt32 Length; + UInt8 Revision; + Char Checksum; + Char OemId[6]; + Char OemTableId[8]; + UInt32 OemRev; + UInt32 CreatorID; + UInt32 CreatorRevision; +}; - class PACKED RSDP : public SDT - { - public: - UInt32 RsdtAddress; - UIntPtr XsdtAddress; - UInt8 ExtendedChecksum; - UInt8 Reserved0[3]; - }; +class PACKED RSDP : public SDT { + public: + UInt32 RsdtAddress; + UIntPtr XsdtAddress; + UInt8 ExtendedChecksum; + UInt8 Reserved0[3]; +}; - class PACKED ConfigHeader - { - public: - UInt64 BaseAddress; - UInt16 PciSegGroup; - UInt8 StartBus; - UInt8 EndBus; - UInt32 Reserved; - }; +class PACKED ConfigHeader { + public: + UInt64 BaseAddress; + UInt16 PciSegGroup; + UInt8 StartBus; + UInt8 EndBus; + UInt32 Reserved; +}; - enum ACPI_ADDRESS_SPACE_KIND : UInt8 - { - eSystemMemory = 0, - eSystemIO = 1, - ePci = 2, - eController = 3, - eSmBus = 4, - eCount = 5, - eInvalid = 0xFF, - }; +enum ACPI_ADDRESS_SPACE_KIND : UInt8 { + eSystemMemory = 0, + eSystemIO = 1, + ePci = 2, + eController = 3, + eSmBus = 4, + eCount = 5, + eInvalid = 0xFF, +}; - class PACKED ACPI_ADDRESS final - { - public: - UInt8 AddressSpaceId; - UInt8 RegisterBitWidth; - UInt8 RegisterBitOffset; - UInt8 Reserved; - UIntPtr Address; - }; +class PACKED ACPI_ADDRESS final { + public: + UInt8 AddressSpaceId; + UInt8 RegisterBitWidth; + UInt8 RegisterBitOffset; + UInt8 Reserved; + UIntPtr Address; +}; - class PACKED RSDT final - { - public: - Char Signature[4]; - UInt32 Length; - UInt8 Revision; - Char Checksum; - Char OemId[6]; - Char OemTableId[8]; - UInt32 OemRev; - UInt32 CreatorID; - UInt32 CreatorRevision; - UInt32 AddressArr[1]; - }; -} // namespace Kernel +class PACKED RSDT final { + public: + Char Signature[4]; + UInt32 Length; + UInt8 Revision; + Char Checksum; + Char OemId[6]; + Char OemTableId[8]; + UInt32 OemRev; + UInt32 CreatorID; + UInt32 CreatorRevision; + UInt32 AddressArr[1]; +}; +} // namespace Kernel -#endif // !__ACPI__ +#endif // !__ACPI__ diff --git a/dev/modules/ACPI/ACPIFactoryInterface.h b/dev/modules/ACPI/ACPIFactoryInterface.h index 10b8ccf1..0a10ffc2 100644 --- a/dev/modules/ACPI/ACPIFactoryInterface.h +++ b/dev/modules/ACPI/ACPIFactoryInterface.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,52 +8,50 @@ #define __MOD_ACPI_H__ #include -#include -#include #include +#include #include +#include #include -namespace Kernel -{ - class PowerFactory; - class ACPIFactoryInterface; - - typedef ACPIFactoryInterface PowerFactoryInterface; - - class ACPIFactoryInterface final NE_POWER_FACTORY - { - public: - explicit ACPIFactoryInterface(voidPtr rsp_ptr); - ~ACPIFactoryInterface() = default; - - ACPIFactoryInterface& operator=(const ACPIFactoryInterface&) = default; - ACPIFactoryInterface(const ACPIFactoryInterface&) = default; - - public: - Bool Shutdown(); // shutdown - Void Reboot(); // soft-reboot - - public: - /// @brief Descriptor find factory. - /// @param signature The signature of the descriptor table (MADT, ACPI...) - /// @return the blob inside an ErrorOr object. - ErrorOr Find(const Char* signature); - - /// @brief Checksum factory. - /// @param checksum the data to checksum - /// @param len it's size - /// @return if it succeed - bool Checksum(const Char* checksum, SSizeT len); // watch for collides! - - public: - ErrorOr operator[](const Char* signature); - - private: - VoidPtr fRsdp{nullptr}; // pointer to root descriptor. - SizeT fEntries{0UL}; // number of entries, -1 tells that no invalid entries were - // found. - }; -} // namespace Kernel - -#endif // !__MOD_ACPI_H__ +namespace Kernel { +class PowerFactory; +class ACPIFactoryInterface; + +typedef ACPIFactoryInterface PowerFactoryInterface; + +class ACPIFactoryInterface final NE_POWER_FACTORY { + public: + explicit ACPIFactoryInterface(voidPtr rsp_ptr); + ~ACPIFactoryInterface() = default; + + ACPIFactoryInterface& operator=(const ACPIFactoryInterface&) = default; + ACPIFactoryInterface(const ACPIFactoryInterface&) = default; + + public: + Bool Shutdown(); // shutdown + Void Reboot(); // soft-reboot + + public: + /// @brief Descriptor find factory. + /// @param signature The signature of the descriptor table (MADT, ACPI...) + /// @return the blob inside an ErrorOr object. + ErrorOr Find(const Char* signature); + + /// @brief Checksum factory. + /// @param checksum the data to checksum + /// @param len it's size + /// @return if it succeed + bool Checksum(const Char* checksum, SSizeT len); // watch for collides! + + public: + ErrorOr operator[](const Char* signature); + + private: + VoidPtr fRsdp{nullptr}; // pointer to root descriptor. + SizeT fEntries{0UL}; // number of entries, -1 tells that no invalid entries were + // found. +}; +} // namespace Kernel + +#endif // !__MOD_ACPI_H__ diff --git a/dev/modules/AHCI/AHCI.h b/dev/modules/AHCI/AHCI.h index 1c0f3b00..98fb3d60 100644 --- a/dev/modules/AHCI/AHCI.h +++ b/dev/modules/AHCI/AHCI.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: AHCI.h - Purpose: AHCI protocol defines. + File: AHCI.h + Purpose: AHCI protocol defines. - Revision History: + Revision History: - 03/02/24: Added file (amlel) + 03/02/24: Added file (amlel) ------------------------------------------- */ @@ -27,315 +27,300 @@ struct FisRegD2H; struct FisRegH2D; /// @brief Frame information type. -enum -{ - kFISTypeRegH2D = 0x27, // Register FIS - host to device - kFISTypeRegD2H = 0x34, // Register FIS - device to host - kFISTypeDMAAct = 0x39, // DMA activate FIS - device to host - kFISTypeDMASetup = 0x41, // DMA setup FIS - bidirectional - kFISTypeData = 0x46, // Data FIS - bidirectional - kFISTypeBIST = 0x58, // BIST activate FIS - bidirectional - kFISTypePIOSetup = 0x5F, // PIO setup FIS - device to host - kFISTypeDevBits = 0xA1, // Set device bits FIS - device to host +enum { + kFISTypeRegH2D = 0x27, // Register FIS - host to device + kFISTypeRegD2H = 0x34, // Register FIS - device to host + kFISTypeDMAAct = 0x39, // DMA activate FIS - device to host + kFISTypeDMASetup = 0x41, // DMA setup FIS - bidirectional + kFISTypeData = 0x46, // Data FIS - bidirectional + kFISTypeBIST = 0x58, // BIST activate FIS - bidirectional + kFISTypePIOSetup = 0x5F, // PIO setup FIS - device to host + kFISTypeDevBits = 0xA1, // Set device bits FIS - device to host }; -enum -{ - kAHCICmdIdentify = 0xEC, - kAHCICmdReadDma = 0xC8, - kAHCICmdReadDmaEx = 0x25, - kAHCICmdWriteDma = 0xCA, - kAHCICmdWriteDmaEx = 0x35 +enum { + kAHCICmdIdentify = 0xEC, + kAHCICmdReadDma = 0xC8, + kAHCICmdReadDmaEx = 0x25, + kAHCICmdWriteDma = 0xCA, + kAHCICmdWriteDmaEx = 0x35 }; -typedef struct FisRegH2D final -{ - // DWORD 0 - Kernel::UInt8 FisType; // FIS_TYPE_REG_H2D - - Kernel::UInt8 PortMul : 4; // Port multiplier - Kernel::UInt8 Reserved0 : 3; // Reserved - Kernel::UInt8 CmdOrCtrl : 1; // 1: Command, 0: Control - - Kernel::UInt8 Command; // Command register - Kernel::UInt8 FeatureLow; // Feature register, 7:0 - - // DWORD 1 - Kernel::UInt8 Lba0; // LBA low register, 7:0 - Kernel::UInt8 Lba1; // LBA mid register, 15:8 - Kernel::UInt8 Lba2; // LBA high register, 23:16 - Kernel::UInt8 Device; // Device register - - // DWORD 2 - Kernel::UInt8 Lba3; // LBA register, 31:24 - Kernel::UInt8 Lba4; // LBA register, 39:32 - Kernel::UInt8 Lba5; // LBA register, 47:40 - Kernel::UInt8 FeatureHigh; // Feature register, 15:8 - - // DWORD 3 - Kernel::UInt8 CountLow; // Count register, 7:0 - Kernel::UInt8 CountHigh; // Count register, 15:8 - Kernel::UInt8 Icc; // Isochronous command completion - Kernel::UInt8 Control; // Control register - - // DWORD 4 - Kernel::UInt8 Reserved1[4]; // Reserved +typedef struct FisRegH2D final { + // DWORD 0 + Kernel::UInt8 FisType; // FIS_TYPE_REG_H2D + + Kernel::UInt8 PortMul : 4; // Port multiplier + Kernel::UInt8 Reserved0 : 3; // Reserved + Kernel::UInt8 CmdOrCtrl : 1; // 1: Command, 0: Control + + Kernel::UInt8 Command; // Command register + Kernel::UInt8 FeatureLow; // Feature register, 7:0 + + // DWORD 1 + Kernel::UInt8 Lba0; // LBA low register, 7:0 + Kernel::UInt8 Lba1; // LBA mid register, 15:8 + Kernel::UInt8 Lba2; // LBA high register, 23:16 + Kernel::UInt8 Device; // Device register + + // DWORD 2 + Kernel::UInt8 Lba3; // LBA register, 31:24 + Kernel::UInt8 Lba4; // LBA register, 39:32 + Kernel::UInt8 Lba5; // LBA register, 47:40 + Kernel::UInt8 FeatureHigh; // Feature register, 15:8 + + // DWORD 3 + Kernel::UInt8 CountLow; // Count register, 7:0 + Kernel::UInt8 CountHigh; // Count register, 15:8 + Kernel::UInt8 Icc; // Isochronous command completion + Kernel::UInt8 Control; // Control register + + // DWORD 4 + Kernel::UInt8 Reserved1[4]; // Reserved } FisRegH2D; -typedef struct FisRegD2H final -{ - // DWORD 0 - Kernel::UInt8 FisType; // FIS_TYPE_REG_D2H - - Kernel::UInt8 PortMul : 4; // Port multiplier - Kernel::UInt8 Reserved0 : 2; // Reserved - Kernel::UInt8 IE : 1; // Interrupt bit - Kernel::UInt8 Reserved1 : 1; // Reserved - - Kernel::UInt8 Status; // Status register - Kernel::UInt8 Error; // Error register - - // DWORD 1 - Kernel::UInt8 Lba0; // LBA low register, 7:0 - Kernel::UInt8 Lba1; // LBA mid register, 15:8 - Kernel::UInt8 Lba2; // LBA high register, 23:16 - Kernel::UInt8 Device; // Device register - - // DWORD 2 - Kernel::UInt8 Lba3; // LBA register, 31:24 - Kernel::UInt8 Lba4; // LBA register, 39:32 - Kernel::UInt8 Lba5; // LBA register, 47:40 - Kernel::UInt8 Rsv2; // Reserved - - // DWORD 3 - Kernel::UInt8 CountLow; // Count register, 7:0 - Kernel::UInt8 CountHigh; // Count register, 15:8 - Kernel::UInt8 Rsv3[2]; // Reserved - - // DWORD 4 - Kernel::UInt8 Rsv4[4]; // Reserved +typedef struct FisRegD2H final { + // DWORD 0 + Kernel::UInt8 FisType; // FIS_TYPE_REG_D2H + + Kernel::UInt8 PortMul : 4; // Port multiplier + Kernel::UInt8 Reserved0 : 2; // Reserved + Kernel::UInt8 IE : 1; // Interrupt bit + Kernel::UInt8 Reserved1 : 1; // Reserved + + Kernel::UInt8 Status; // Status register + Kernel::UInt8 Error; // Error register + + // DWORD 1 + Kernel::UInt8 Lba0; // LBA low register, 7:0 + Kernel::UInt8 Lba1; // LBA mid register, 15:8 + Kernel::UInt8 Lba2; // LBA high register, 23:16 + Kernel::UInt8 Device; // Device register + + // DWORD 2 + Kernel::UInt8 Lba3; // LBA register, 31:24 + Kernel::UInt8 Lba4; // LBA register, 39:32 + Kernel::UInt8 Lba5; // LBA register, 47:40 + Kernel::UInt8 Rsv2; // Reserved + + // DWORD 3 + Kernel::UInt8 CountLow; // Count register, 7:0 + Kernel::UInt8 CountHigh; // Count register, 15:8 + Kernel::UInt8 Rsv3[2]; // Reserved + + // DWORD 4 + Kernel::UInt8 Rsv4[4]; // Reserved } FisRegD2H; -typedef struct FisData final -{ - // DWORD 0 - Kernel::UInt8 FisType; // FIS_TYPE_DATA +typedef struct FisData final { + // DWORD 0 + Kernel::UInt8 FisType; // FIS_TYPE_DATA - Kernel::UInt8 PortMul : 4; // Port multiplier - Kernel::UInt8 Reserved0 : 4; // Reserved + Kernel::UInt8 PortMul : 4; // Port multiplier + Kernel::UInt8 Reserved0 : 4; // Reserved - Kernel::UInt8 Reserved1[2]; // Reserved + Kernel::UInt8 Reserved1[2]; // Reserved - // DWORD 1 ~ N - Kernel::UInt32 Data[1]; // Payload + // DWORD 1 ~ N + Kernel::UInt32 Data[1]; // Payload } FisData; -typedef struct FisPioSetup final -{ - // DWORD 0 - Kernel::UInt8 FisType; // FIS_TYPE_PIO_SETUP - - Kernel::UInt8 PortMul : 4; // Port multiplier - Kernel::UInt8 Reserved0 : 1; // Reserved - Kernel::UInt8 DTD : 1; // Data transfer direction, 1 - device to host - Kernel::UInt8 IE : 1; // Interrupt bit - Kernel::UInt8 Reserved1 : 1; - - Kernel::UInt8 Status; // Status register - Kernel::UInt8 Error; // Error register - - // DWORD 1 - Kernel::UInt8 Lba0; // LBA low register, 7:0 - Kernel::UInt8 Lba1; // LBA mid register, 15:8 - Kernel::UInt8 Lba2; // LBA high register, 23:16 - Kernel::UInt8 Device; // Device register - - // DWORD 2 - Kernel::UInt8 Lba3; // LBA register, 31:24 - Kernel::UInt8 Lba4; // LBA register, 39:32 - Kernel::UInt8 Lba5; // LBA register, 47:40 - Kernel::UInt8 Rsv2; // Reserved - - // DWORD 3 - Kernel::UInt8 CountLow; // Count register, 7:0 - Kernel::UInt8 CountHigh; // Count register, 15:8 - Kernel::UInt8 Rsv3; // Reserved - Kernel::UInt8 EStatus; // New value of status register - - // DWORD 4 - Kernel::UInt16 TranferCount; // Transfer count - Kernel::UInt8 Rsv4[2]; // Reserved +typedef struct FisPioSetup final { + // DWORD 0 + Kernel::UInt8 FisType; // FIS_TYPE_PIO_SETUP + + Kernel::UInt8 PortMul : 4; // Port multiplier + Kernel::UInt8 Reserved0 : 1; // Reserved + Kernel::UInt8 DTD : 1; // Data transfer direction, 1 - device to host + Kernel::UInt8 IE : 1; // Interrupt bit + Kernel::UInt8 Reserved1 : 1; + + Kernel::UInt8 Status; // Status register + Kernel::UInt8 Error; // Error register + + // DWORD 1 + Kernel::UInt8 Lba0; // LBA low register, 7:0 + Kernel::UInt8 Lba1; // LBA mid register, 15:8 + Kernel::UInt8 Lba2; // LBA high register, 23:16 + Kernel::UInt8 Device; // Device register + + // DWORD 2 + Kernel::UInt8 Lba3; // LBA register, 31:24 + Kernel::UInt8 Lba4; // LBA register, 39:32 + Kernel::UInt8 Lba5; // LBA register, 47:40 + Kernel::UInt8 Rsv2; // Reserved + + // DWORD 3 + Kernel::UInt8 CountLow; // Count register, 7:0 + Kernel::UInt8 CountHigh; // Count register, 15:8 + Kernel::UInt8 Rsv3; // Reserved + Kernel::UInt8 EStatus; // New value of status register + + // DWORD 4 + Kernel::UInt16 TranferCount; // Transfer count + Kernel::UInt8 Rsv4[2]; // Reserved } FisPioSetup; -typedef struct FisDmaSetup final -{ - // DWORD 0 - Kernel::UInt8 FisType; // FIS_TYPE_DMA_SETUP +typedef struct FisDmaSetup final { + // DWORD 0 + Kernel::UInt8 FisType; // FIS_TYPE_DMA_SETUP - Kernel::UInt8 PortMul : 4; // Port multiplier - Kernel::UInt8 Reserved0 : 1; // Reserved - Kernel::UInt8 DTD : 1; // Data transfer direction, 1 - device to host - Kernel::UInt8 IE : 1; // Interrupt bit - Kernel::UInt8 AutoEnable : 1; // Auto-activate. Specifies if DMA Activate FIS is needed + Kernel::UInt8 PortMul : 4; // Port multiplier + Kernel::UInt8 Reserved0 : 1; // Reserved + Kernel::UInt8 DTD : 1; // Data transfer direction, 1 - device to host + Kernel::UInt8 IE : 1; // Interrupt bit + Kernel::UInt8 AutoEnable : 1; // Auto-activate. Specifies if DMA Activate FIS is needed - Kernel::UInt8 Reserved1[2]; // Reserved + Kernel::UInt8 Reserved1[2]; // Reserved - // DWORD 1&2 - volatile Kernel::UInt64 DmaBufferId; // DMA Buffer Identifier. Used to Identify DMA buffer in - // host memory. SATA Spec says host specific and not in - // Spec. Trying AHCI spec might work. + // DWORD 1&2 + volatile Kernel::UInt64 DmaBufferId; // DMA Buffer Identifier. Used to Identify DMA buffer in + // host memory. SATA Spec says host specific and not in + // Spec. Trying AHCI spec might work. - // DWORD 3 - Kernel::UInt32 Rsvd; // More reserved + // DWORD 3 + Kernel::UInt32 Rsvd; // More reserved - // DWORD 4 - Kernel::UInt32 DmabufOffset; // Byte offset into buffer. First 2 bits must be 0 + // DWORD 4 + Kernel::UInt32 DmabufOffset; // Byte offset into buffer. First 2 bits must be 0 - // DWORD 5 - Kernel::UInt32 TransferCount; // Number of bytes to transfer. Bit 0 must be 0 + // DWORD 5 + Kernel::UInt32 TransferCount; // Number of bytes to transfer. Bit 0 must be 0 - // DWORD 6 - Kernel::UInt32 Reserved3; // Reserved + // DWORD 6 + Kernel::UInt32 Reserved3; // Reserved } FisDmaSetup; -typedef struct FisDevBits final -{ - // DWORD 0 - Kernel::UInt8 FisType; // FIS_TYPE_DMA_SETUP (A1h) +typedef struct FisDevBits final { + // DWORD 0 + Kernel::UInt8 FisType; // FIS_TYPE_DMA_SETUP (A1h) - Kernel::UInt8 Reserved0 : 5; // Reserved - Kernel::UInt8 R0 : 1; - Kernel::UInt8 IE : 1; - Kernel::UInt8 N : 1; + Kernel::UInt8 Reserved0 : 5; // Reserved + Kernel::UInt8 R0 : 1; + Kernel::UInt8 IE : 1; + Kernel::UInt8 N : 1; - Kernel::UInt8 StatusLow : 3; - Kernel::UInt8 R1 : 1; - Kernel::UInt8 StatusHigh : 3; + Kernel::UInt8 StatusLow : 3; + Kernel::UInt8 R1 : 1; + Kernel::UInt8 StatusHigh : 3; - Kernel::UInt8 R2 : 1; - Kernel::UInt8 Error; + Kernel::UInt8 R2 : 1; + Kernel::UInt8 Error; - // DWORD 1 - Kernel::UInt32 Act; + // DWORD 1 + Kernel::UInt32 Act; } FisDevBits; /// \brief Enable AHCI device bit in GHC register. #ifndef kSATAGHC_AE #define kSATAGHC_AE (31) -#endif //! ifndef kSATAGHC_AE - -typedef struct HbaPort final -{ - Kernel::UInt32 Clb; // 0x00, command list base address, 1K-byte aligned - Kernel::UInt32 Clbu; // 0x04, command list base address upper 32 bits - Kernel::UInt32 Fb; // 0x08, FIS base address, 256-byte aligned - Kernel::UInt32 Fbu; // 0x0C, FIS base address upper 32 bits - Kernel::UInt32 Is; // 0x10, interrupt status - Kernel::UInt32 Ie; // 0x14, interrupt enable - Kernel::UInt32 Cmd; // 0x18, command and status - Kernel::UInt32 Reserved0; // 0x1C, Reserved - Kernel::UInt32 Tfd; // 0x20, task file data - Kernel::UInt32 Sig; // 0x24, signature - Kernel::UInt32 Ssts; // 0x28, SATA status (SCR0:SStatus) - Kernel::UInt32 Sctl; // 0x2C, SATA control (SCR2:SControl) - Kernel::UInt32 Serr; // 0x30, SATA error (SCR1:SError) - Kernel::UInt32 Sact; // 0x34, SATA active (SCR3:SActive) - Kernel::UInt32 Ci; // 0x38, command issue - Kernel::UInt32 Sntf; // 0x3C, SATA notification (SCR4:SNotification) - Kernel::UInt32 Fbs; // 0x40, FIS-based switch control - Kernel::UInt32 Reserved1[11]; // 0x44 ~ 0x6F, Reserved - Kernel::UInt32 Vendor[4]; // 0x70 ~ 0x7F, vendor specific +#endif //! ifndef kSATAGHC_AE + +typedef struct HbaPort final { + Kernel::UInt32 Clb; // 0x00, command list base address, 1K-byte aligned + Kernel::UInt32 Clbu; // 0x04, command list base address upper 32 bits + Kernel::UInt32 Fb; // 0x08, FIS base address, 256-byte aligned + Kernel::UInt32 Fbu; // 0x0C, FIS base address upper 32 bits + Kernel::UInt32 Is; // 0x10, interrupt status + Kernel::UInt32 Ie; // 0x14, interrupt enable + Kernel::UInt32 Cmd; // 0x18, command and status + Kernel::UInt32 Reserved0; // 0x1C, Reserved + Kernel::UInt32 Tfd; // 0x20, task file data + Kernel::UInt32 Sig; // 0x24, signature + Kernel::UInt32 Ssts; // 0x28, SATA status (SCR0:SStatus) + Kernel::UInt32 Sctl; // 0x2C, SATA control (SCR2:SControl) + Kernel::UInt32 Serr; // 0x30, SATA error (SCR1:SError) + Kernel::UInt32 Sact; // 0x34, SATA active (SCR3:SActive) + Kernel::UInt32 Ci; // 0x38, command issue + Kernel::UInt32 Sntf; // 0x3C, SATA notification (SCR4:SNotification) + Kernel::UInt32 Fbs; // 0x40, FIS-based switch control + Kernel::UInt32 Reserved1[11]; // 0x44 ~ 0x6F, Reserved + Kernel::UInt32 Vendor[4]; // 0x70 ~ 0x7F, vendor specific } HbaPort; -typedef struct HbaMem final -{ - // 0x00 - 0x2B, Generic Host Control - Kernel::UInt32 Cap; // 0x00, Host capability - Kernel::UInt32 Ghc; // 0x04, Global host control - Kernel::UInt32 Is; // 0x08, Interrupt status - Kernel::UInt32 Pi; // 0x0C, Port implemented - Kernel::UInt32 Vs; // 0x10, Version - Kernel::UInt32 Ccc_ctl; // 0x14, Command completion coalescing control - Kernel::UInt32 Ccc_pts; // 0x18, Command completion coalescing ports - Kernel::UInt32 Em_loc; // 0x1C, Enclosure management location - Kernel::UInt32 Em_ctl; // 0x20, Enclosure management control - Kernel::UInt32 Cap2; // 0x24, Host capabilities extended - Kernel::UInt32 Bohc; // 0x28, BIOS/OS handoff control and status - - Kernel::UInt8 Resv0[0xA0 - 0x2C]; - Kernel::UInt8 Vendor[0x100 - 0xA0]; - - HbaPort Ports[1]; // 1 ~ 32, 32 is the max ahci devices per controller. +typedef struct HbaMem final { + // 0x00 - 0x2B, Generic Host Control + Kernel::UInt32 Cap; // 0x00, Host capability + Kernel::UInt32 Ghc; // 0x04, Global host control + Kernel::UInt32 Is; // 0x08, Interrupt status + Kernel::UInt32 Pi; // 0x0C, Port implemented + Kernel::UInt32 Vs; // 0x10, Version + Kernel::UInt32 Ccc_ctl; // 0x14, Command completion coalescing control + Kernel::UInt32 Ccc_pts; // 0x18, Command completion coalescing ports + Kernel::UInt32 Em_loc; // 0x1C, Enclosure management location + Kernel::UInt32 Em_ctl; // 0x20, Enclosure management control + Kernel::UInt32 Cap2; // 0x24, Host capabilities extended + Kernel::UInt32 Bohc; // 0x28, BIOS/OS handoff control and status + + Kernel::UInt8 Resv0[0xA0 - 0x2C]; + Kernel::UInt8 Vendor[0x100 - 0xA0]; + + HbaPort Ports[1]; // 1 ~ 32, 32 is the max ahci devices per controller. } HbaMem; typedef HbaMem* HbaMemRef; -typedef struct HbaCmdHeader final -{ - // DW0 - union { - struct - { - Kernel::UInt8 Cfl : 5; // Command FIS length in DWORDS, 2 ~ 16 - Kernel::UInt8 Atapi : 1; // ATAPI - Kernel::UInt8 Write : 1; // Write, 1: H2D, 0: D2H - Kernel::UInt8 Prefetchable : 1; // Prefetchable - - Kernel::UInt8 Reset : 1; // Reset - Kernel::UInt8 BIST : 1; // BIST - Kernel::UInt8 Clear : 1; // Clear busy upon R_OK - Kernel::UInt8 Reserved0 : 1; // Reserved - Kernel::UInt8 Pmp : 4; // Port multiplier port - } Struc; - - Kernel::UInt16 Flags; - }; - - Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries - Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred - - Kernel::UInt32 Ctba; // Command table descriptor base address - Kernel::UInt32 Ctbau; // Command table descriptor base address upper 32 bits - - Kernel::UInt32 Rsv[4]; +typedef struct HbaCmdHeader final { + // DW0 + union { + struct { + Kernel::UInt8 Cfl : 5; // Command FIS length in DWORDS, 2 ~ 16 + Kernel::UInt8 Atapi : 1; // ATAPI + Kernel::UInt8 Write : 1; // Write, 1: H2D, 0: D2H + Kernel::UInt8 Prefetchable : 1; // Prefetchable + + Kernel::UInt8 Reset : 1; // Reset + Kernel::UInt8 BIST : 1; // BIST + Kernel::UInt8 Clear : 1; // Clear busy upon R_OK + Kernel::UInt8 Reserved0 : 1; // Reserved + Kernel::UInt8 Pmp : 4; // Port multiplier port + } Struc; + + Kernel::UInt16 Flags; + }; + + Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries + Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred + + Kernel::UInt32 Ctba; // Command table descriptor base address + Kernel::UInt32 Ctbau; // Command table descriptor base address upper 32 bits + + Kernel::UInt32 Rsv[4]; } ATTRIBUTE(packed, aligned(32)) HbaCmdHeader; -typedef struct HbaFis final -{ - // 0x00 - FisDmaSetup Dsfis; // DMA Setup FIS - Kernel::UInt8 Pad0[4]; - // 0x20 - FisPioSetup Psfis; // PIO Setup FIS - Kernel::UInt8 Pad1[12]; - // 0x40 - FisRegD2H Rfis; // Register – Device to Host FIS - Kernel::UInt8 Pad2[4]; - // 0x58 - FisDevBits Sdbfis; // Set Device Bit FIS - // 0x60 - Kernel::UInt8 Ufis[64]; - // 0xA0 - Kernel::UInt8 Rsv[0x100 - 0xA0]; +typedef struct HbaFis final { + // 0x00 + FisDmaSetup Dsfis; // DMA Setup FIS + Kernel::UInt8 Pad0[4]; + // 0x20 + FisPioSetup Psfis; // PIO Setup FIS + Kernel::UInt8 Pad1[12]; + // 0x40 + FisRegD2H Rfis; // Register – Device to Host FIS + Kernel::UInt8 Pad2[4]; + // 0x58 + FisDevBits Sdbfis; // Set Device Bit FIS + // 0x60 + Kernel::UInt8 Ufis[64]; + // 0xA0 + Kernel::UInt8 Rsv[0x100 - 0xA0]; } HbaFis; -typedef struct HbaPrdtEntry final -{ - Kernel::UInt32 Dba; // Data base address - Kernel::UInt32 Dbau; // Data base address upper 32 bits - Kernel::UInt32 Reserved0; // Reserved - // DW3 - Kernel::UInt32 Dbc : 22; // Byte count, 4M max - Kernel::UInt32 Reserved1 : 9; // Reserved - Kernel::UInt32 Ie : 1; // Interrupt on completion +typedef struct HbaPrdtEntry final { + Kernel::UInt32 Dba; // Data base address + Kernel::UInt32 Dbau; // Data base address upper 32 bits + Kernel::UInt32 Reserved0; // Reserved + // DW3 + Kernel::UInt32 Dbc : 22; // Byte count, 4M max + Kernel::UInt32 Reserved1 : 9; // Reserved + Kernel::UInt32 Ie : 1; // Interrupt on completion } HbaPrdtEntry; -typedef struct HbaCmdTbl final -{ - Kernel::UInt8 Cfis[64]; // Command FIS - Kernel::UInt8 Acmd[16]; // ATAPI command, 12 or 16 bytes - Kernel::UInt8 Rsv[48]; // Reserved - struct HbaPrdtEntry Prdt[1]; // Physical region descriptor table entries, 0 ~ 65535 +typedef struct HbaCmdTbl final { + Kernel::UInt8 Cfis[64]; // Command FIS + Kernel::UInt8 Acmd[16]; // ATAPI command, 12 or 16 bytes + Kernel::UInt8 Rsv[48]; // Reserved + struct HbaPrdtEntry Prdt[1]; // Physical region descriptor table entries, 0 ~ 65535 } HbaCmdTbl; /// @brief Initializes an AHCI disk. @@ -351,7 +336,8 @@ Kernel::Boolean drv_std_detected(Kernel::Void); /// @param sector_sz /// @param buf_sz /// @return -Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT sector_sz, Kernel::SizeT buf_sz); +Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT sector_sz, + Kernel::SizeT buf_sz); /// @brief Write to AHCI disk. /// @param lba @@ -359,7 +345,8 @@ Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT s /// @param sector_sz /// @param buf_sz /// @return -Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT sector_sz, Kernel::SizeT buf_sz); +Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buf, Kernel::SizeT sector_sz, + Kernel::SizeT buf_sz); /// @brief Gets the sector count from AHCI disk. Kernel::SizeT drv_get_sector_count(); diff --git a/dev/modules/APM/APM.h b/dev/modules/APM/APM.h index 122fe4fe..3dbd5e8f 100644 --- a/dev/modules/APM/APM.h +++ b/dev/modules/APM/APM.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,30 +8,28 @@ #include -namespace Kernel -{ - typedef Int32 APMPowerCmd; - - enum - { - kAPMPowerCommandInvalid = 0x00, - kAPMPowerCommandStop = 0x01, - kAPMPowerCommandStart = 0x02, - kAPMPowerCommandSleep = 0x04, - kAPMPowerCommandWakeup = 0x06, - kAPMPowerCommandShutdown = 0x07, - kAPMPowerCommandReboot = 0x08, - }; - - /// @brief Send a APM command into it's own DMA space. - /// @param base_dma the DMA base address. - /// @param cmd the command. - /// @return status code. - EXTERN_C Int32 apm_send_dma_command(Ptr64 register_addr, APMPowerCmd value); - - /// @brief Send a APM command into it's own 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, APMPowerCmd value); -} // namespace Kernel +namespace Kernel { +typedef Int32 APMPowerCmd; + +enum { + kAPMPowerCommandInvalid = 0x00, + kAPMPowerCommandStop = 0x01, + kAPMPowerCommandStart = 0x02, + kAPMPowerCommandSleep = 0x04, + kAPMPowerCommandWakeup = 0x06, + kAPMPowerCommandShutdown = 0x07, + kAPMPowerCommandReboot = 0x08, +}; + +/// @brief Send a APM command into it's own DMA space. +/// @param base_dma the DMA base address. +/// @param cmd the command. +/// @return status code. +EXTERN_C Int32 apm_send_dma_command(Ptr64 register_addr, APMPowerCmd value); + +/// @brief Send a APM command into it's own 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, APMPowerCmd value); +} // namespace Kernel diff --git a/dev/modules/ATA/ATA.h b/dev/modules/ATA/ATA.h index f915da6b..bd21d106 100644 --- a/dev/modules/ATA/ATA.h +++ b/dev/modules/ATA/ATA.h @@ -1,13 +1,13 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: Defines.h - Purpose: ATA header. + File: Defines.h + Purpose: ATA header. - Revision History: + Revision History: - 03/02/24: Added file (amlel) + 03/02/24: Added file (amlel) ------------------------------------------- */ @@ -17,100 +17,100 @@ #include ///! Status register -#define ATA_SR_BSY 0x80 +#define ATA_SR_BSY 0x80 #define ATA_SR_DRDY 0x40 -#define ATA_SR_DF 0x20 -#define ATA_SR_DSC 0x10 -#define ATA_SR_DRQ 0x08 +#define ATA_SR_DF 0x20 +#define ATA_SR_DSC 0x10 +#define ATA_SR_DRQ 0x08 #define ATA_SR_CORR 0x04 -#define ATA_SR_IDX 0x02 -#define ATA_SR_ERR 0x01 +#define ATA_SR_IDX 0x02 +#define ATA_SR_ERR 0x01 ///! Error register -#define ATA_ER_BBK 0x80 -#define ATA_ER_UNC 0x40 -#define ATA_ER_MC 0x20 -#define ATA_ER_IDNF 0x10 -#define ATA_ER_MCR 0x08 -#define ATA_ER_ABRT 0x04 +#define ATA_ER_BBK 0x80 +#define ATA_ER_UNC 0x40 +#define ATA_ER_MC 0x20 +#define ATA_ER_IDNF 0x10 +#define ATA_ER_MCR 0x08 +#define ATA_ER_ABRT 0x04 #define ATA_ER_TK0NF 0x02 -#define ATA_ER_AMNF 0x01 - -#define ATA_CMD_READ_PIO 0x20 -#define ATA_CMD_READ_PIO_EXT 0x24 -#define ATA_CMD_READ_DMA 0xC8 -#define ATA_CMD_READ_DMA_EXT 0x25 -#define ATA_CMD_WRITE_PIO 0x30 -#define ATA_CMD_WRITE_PIO_EXT 0x34 -#define ATA_CMD_WRITE_DMA 0xCA -#define ATA_CMD_WRITE_DMA_EXT 0x35 -#define ATA_CMD_CACHE_FLUSH 0xE7 +#define ATA_ER_AMNF 0x01 + +#define ATA_CMD_READ_PIO 0x20 +#define ATA_CMD_READ_PIO_EXT 0x24 +#define ATA_CMD_READ_DMA 0xC8 +#define ATA_CMD_READ_DMA_EXT 0x25 +#define ATA_CMD_WRITE_PIO 0x30 +#define ATA_CMD_WRITE_PIO_EXT 0x34 +#define ATA_CMD_WRITE_DMA 0xCA +#define ATA_CMD_WRITE_DMA_EXT 0x35 +#define ATA_CMD_CACHE_FLUSH 0xE7 #define ATA_CMD_CACHE_FLUSH_EXT 0xEA -#define ATA_CMD_PACKET 0xA0 +#define ATA_CMD_PACKET 0xA0 #define ATA_CMD_IDENTIFY_PACKET 0xA1 -#define ATA_CMD_IDENTIFY 0xEC +#define ATA_CMD_IDENTIFY 0xEC ///! ident offsets, use with data that we got from ATA_CMD_IDENTIFY. -#define ATA_IDENT_DEVICE_TYPE 0 -#define ATA_IDENT_CYLINDERS 2 -#define ATA_IDENT_HEADS 6 -#define ATA_IDENT_SECTORS 12 -#define ATA_IDENT_SERIAL 20 -#define ATA_IDENT_MODEL 54 +#define ATA_IDENT_DEVICE_TYPE 0 +#define ATA_IDENT_CYLINDERS 2 +#define ATA_IDENT_HEADS 6 +#define ATA_IDENT_SECTORS 12 +#define ATA_IDENT_SERIAL 20 +#define ATA_IDENT_MODEL 54 #define ATA_IDENT_CAPABILITIES 98 -#define ATA_IDENT_FIELDVALID 106 -#define ATA_IDENT_MAX_LBA 120 -#define ATA_IDENT_COMMANDSETS 164 -#define ATA_IDENT_MAX_LBA_EXT 200 +#define ATA_IDENT_FIELDVALID 106 +#define ATA_IDENT_MAX_LBA 120 +#define ATA_IDENT_COMMANDSETS 164 +#define ATA_IDENT_MAX_LBA_EXT 200 #define ATA_REG_SET_FEATURES 0xEF #define ATA_MASTER 0x00 -#define ATA_SLAVE 0x01 +#define ATA_SLAVE 0x01 ///! Register -#define ATA_REG_DATA 0x00 -#define ATA_REG_ERROR 0x01 -#define ATA_REG_FEATURES 0x01 -#define ATA_REG_SEC_COUNT0 0x02 -#define ATA_REG_LBA0 0x03 -#define ATA_REG_LBA1 0x04 -#define ATA_REG_LBA2 0x05 -#define ATA_REG_HDDEVSEL 0x06 -#define ATA_REG_COMMAND 0x07 -#define ATA_REG_STATUS 0x07 -#define ATA_REG_SEC_COUNT1 0x08 -#define ATA_REG_LBA3 0x09 -#define ATA_REG_LBA4 0x0A -#define ATA_REG_LBA5 0x0B -#define ATA_REG_CONTROL 0x0C -#define ATA_REG_ALT_STATUS 0x0C +#define ATA_REG_DATA 0x00 +#define ATA_REG_ERROR 0x01 +#define ATA_REG_FEATURES 0x01 +#define ATA_REG_SEC_COUNT0 0x02 +#define ATA_REG_LBA0 0x03 +#define ATA_REG_LBA1 0x04 +#define ATA_REG_LBA2 0x05 +#define ATA_REG_HDDEVSEL 0x06 +#define ATA_REG_COMMAND 0x07 +#define ATA_REG_STATUS 0x07 +#define ATA_REG_SEC_COUNT1 0x08 +#define ATA_REG_LBA3 0x09 +#define ATA_REG_LBA4 0x0A +#define ATA_REG_LBA5 0x0B +#define ATA_REG_CONTROL 0x0C +#define ATA_REG_ALT_STATUS 0x0C #define ATA_REG_DEV_ADDRESS 0x0D #define ATA_REG_NEIN 0x01 -#define ATA_PRIMARY_IO 0x1F0 -#define ATA_SECONDARY_IO 0x170 -#define ATA_PRIMARY_DCR_AS 0x3F6 +#define ATA_PRIMARY_IO 0x1F0 +#define ATA_SECONDARY_IO 0x170 +#define ATA_PRIMARY_DCR_AS 0x3F6 #define ATA_SECONDARY_DCR_AS 0x376 ///! Irq -#define ATA_PRIMARY_IRQ 14 +#define ATA_PRIMARY_IRQ 14 #define ATA_SECONDARY_IRQ 15 ///! Channels -#define ATA_PRIMARY 0x00 +#define ATA_PRIMARY 0x00 #define ATA_SECONDARY 0x01 -#define ATA_CYL_LOW 3 -#define ATA_CYL_MID 4 +#define ATA_CYL_LOW 3 +#define ATA_CYL_MID 4 #define ATA_CYL_HIGH 5 ///! IO Direction -#define ATA_READ 0x00 +#define ATA_READ 0x00 #define ATA_WRITE 0x013 -#define ATA_PRIMARY_SEL 0xA0 +#define ATA_PRIMARY_SEL 0xA0 #define ATA_SECONDARY_SEL 0xB0 ///! ATA address register. @@ -123,18 +123,18 @@ #define kATASectorSize (512U) -enum -{ - kATADevicePATA, - kATADeviceSATA, - kATADevicePATA_PI, - kATADeviceSATA_PI, - kATADeviceCount, +enum { + kATADevicePATA, + kATADeviceSATA, + kATADevicePATA_PI, + kATADeviceSATA_PI, + kATADeviceCount, }; #if defined(__ATA_PIO__) || defined(__ATA_DMA__) -Kernel::Boolean drv_std_init(Kernel::UInt16 in_bus, Kernel::UInt8 drive, Kernel::UInt16& out_bus, Kernel::UInt8& out_master); +Kernel::Boolean drv_std_init(Kernel::UInt16 in_bus, Kernel::UInt8 drive, Kernel::UInt16& out_bus, + Kernel::UInt8& out_master); Kernel::Boolean drv_std_detected(Kernel::Void); @@ -142,9 +142,11 @@ Kernel::Void drv_std_select(Kernel::UInt16 bus); Kernel::Boolean drv_std_wait_io(Kernel::UInt16 io); -Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::UInt16 io, Kernel::UInt8 is_master, Kernel::Char* buf, Kernel::SizeT sec_sz, Kernel::SizeT buf_sz); +Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::UInt16 io, Kernel::UInt8 is_master, + Kernel::Char* buf, Kernel::SizeT sec_sz, Kernel::SizeT buf_sz); -Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::UInt16 io, Kernel::UInt8 is_master, Kernel::Char* buf, Kernel::SizeT sec_sz, Kernel::SizeT buf_sz); +Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::UInt16 io, Kernel::UInt8 is_master, + Kernel::Char* buf, Kernel::SizeT sec_sz, Kernel::SizeT buf_sz); /// @brief get sector count. Kernel::SizeT drv_get_sector_count(); @@ -152,4 +154,4 @@ Kernel::SizeT drv_get_sector_count(); /// @brief get device size. Kernel::SizeT drv_get_size(); -#endif // ifdef __NEOSKRNL__ \ No newline at end of file +#endif // ifdef __NEOSKRNL__ \ No newline at end of file diff --git a/dev/modules/CoreGfx/CoreAccess.h b/dev/modules/CoreGfx/CoreAccess.h index c60505c5..6417db07 100644 --- a/dev/modules/CoreGfx/CoreAccess.h +++ b/dev/modules/CoreGfx/CoreAccess.h @@ -1,41 +1,33 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. ------------------------------------------- */ #ifndef CORE_GFX_ACCESSIBILITY_H #define CORE_GFX_ACCESSIBILITY_H -#include +#include #include +#include #include #include -#include -namespace FB -{ - using namespace Kernel; +namespace FB { +using namespace Kernel; - /// @brief common User interface class. - class FBAccessibilty final - { - explicit FBAccessibilty() = default; - ~FBAccessibilty() = default; +/// @brief common User interface class. +class FBAccessibilty final { + explicit FBAccessibilty() = default; + ~FBAccessibilty() = default; - public: - NE_COPY_DELETE(FBAccessibilty) + public: + NE_COPY_DELETE(FBAccessibilty) - static UInt64 Width() noexcept - { - return kHandoverHeader->f_GOP.f_Width; - } + static UInt64 Width() noexcept { return kHandoverHeader->f_GOP.f_Width; } - static UInt64 Height() noexcept - { - return kHandoverHeader->f_GOP.f_Height; - } - }; -} // namespace FB + static UInt64 Height() noexcept { return kHandoverHeader->f_GOP.f_Height; } +}; +} // namespace FB -#endif // !CORE_GFX_ACCESSIBILITY_H_ +#endif // !CORE_GFX_ACCESSIBILITY_H_ diff --git a/dev/modules/CoreGfx/CoreGfx.h b/dev/modules/CoreGfx/CoreGfx.h index 2e555c08..2ab8d6e8 100644 --- a/dev/modules/CoreGfx/CoreGfx.h +++ b/dev/modules/CoreGfx/CoreGfx.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -18,100 +18,77 @@ #ifdef __NE_AMD64__ /// @brief Performs Alpha drawing on the framebuffer. -#define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ - { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ - { \ - *(((Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - i + \ - 4 * u))) |= (reg_ptr)[kCGCursor]; \ - \ - ++kCGCursor; \ - } \ - } +#define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \ + *(((Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \ + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) |= \ + (reg_ptr)[kCGCursor]; \ + \ + ++kCGCursor; \ + } \ + } /// @brief Performs drawing on the framebuffer. -#define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ - { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ - { \ - *(((Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - i + \ - 4 * u))) = (reg_ptr)[kCGCursor]; \ - \ - ++kCGCursor; \ - } \ - } - -#define FBDrawBitMapInRegionToRgn(_Rgn, reg_ptr, height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ - { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ - { \ - *(((Kernel::UInt32*)(_Rgn + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - i + \ - 4 * u))) = (reg_ptr)[kCGCursor]; \ - \ - ++kCGCursor; \ - } \ - } +#define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \ + *(((Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \ + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) = \ + (reg_ptr)[kCGCursor]; \ + \ + ++kCGCursor; \ + } \ + } + +#define FBDrawBitMapInRegionToRgn(_Rgn, reg_ptr, height, width, base_x, base_y) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \ + *(((Kernel::UInt32*) (_Rgn + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) = \ + (reg_ptr)[kCGCursor]; \ + \ + ++kCGCursor; \ + } \ + } /// @brief Cleans a resource. -#define FBClearRegion(height, width, base_x, base_y) \ - for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) \ - { \ - for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) \ - { \ - *(((volatile Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - i + \ - 4 * u))) = fb_get_clear_clr(); \ - } \ - } +#define FBClearRegion(height, width, base_x, base_y) \ + for (Kernel::UInt32 i = base_x; i < (width + base_x); ++i) { \ + for (Kernel::UInt32 u = base_y; u < (height + base_y); ++u) { \ + *(((volatile Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \ + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * i + 4 * u))) = \ + fb_get_clear_clr(); \ + } \ + } /// @brief Draws inside a zone. -#define FBDrawInRegion(clr, height, width, base_x, base_y) \ - for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ - { \ - for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ - { \ - *(((volatile Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - x_base + \ - 4 * y_base))) = clr; \ - } \ - } +#define FBDrawInRegion(clr, height, width, base_x, base_y) \ + for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) { \ + for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) { \ + *(((volatile Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \ + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * x_base + \ + 4 * y_base))) = clr; \ + } \ + } /// @brief Draws inside a zone. -#define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y) \ - for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ - { \ - for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ - { \ - *(((volatile Kernel::UInt32*)(_Rgn + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - x_base + \ - 4 * y_base))) = clr[kCGCursor]; \ - ++kCGCursor; \ - } \ - } - -#define FBDrawInRegionA(clr, height, width, base_x, base_y) \ - for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) \ - { \ - for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) \ - { \ - *(((volatile Kernel::UInt32*)(kHandoverHeader->f_GOP.f_The + \ - 4 * kHandoverHeader->f_GOP.f_PixelPerLine * \ - x_base + \ - 4 * y_base))) |= clr; \ - } \ - } +#define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y) \ + for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) { \ + for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) { \ + *(((volatile Kernel::UInt32*) (_Rgn + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * x_base + \ + 4 * y_base))) = clr[kCGCursor]; \ + ++kCGCursor; \ + } \ + } + +#define FBDrawInRegionA(clr, height, width, base_x, base_y) \ + for (Kernel::UInt32 x_base = base_x; x_base < (width + base_x); ++x_base) { \ + for (Kernel::UInt32 y_base = base_y; y_base < (height + base_y); ++y_base) { \ + *(((volatile Kernel::UInt32*) (kHandoverHeader->f_GOP.f_The + \ + 4 * kHandoverHeader->f_GOP.f_PixelPerLine * x_base + \ + 4 * y_base))) |= clr; \ + } \ + } #else #define FBDrawBitMapInRegionA(reg_ptr, height, width, base_x, base_y) #define FBDrawBitMapInRegion(reg_ptr, height, width, base_x, base_y) @@ -127,17 +104,15 @@ #define FBDrawInRegion(clr, height, width, base_x, base_y) #define FBDrawInRegionToRgn(_Rgn, clr, height, width, base_x, base_y) #define FBDrawInRegionA(clr, height, width, base_x, base_y) -#endif // __NE_AMD64__ +#endif // __NE_AMD64__ #ifndef CORE_GFX_ACCESSIBILITY_H #include -#endif // ifndef CORE_GFX_ACCESSIBILITY_H - -namespace FB -{ - inline Void fb_clear_video() noexcept - { - FBDrawInRegion(fb_get_clear_clr(), FB::FBAccessibilty::Height(), FB::FBAccessibilty::Width(), - 0, 0); - } -} // namespace FB \ No newline at end of file +#endif // ifndef CORE_GFX_ACCESSIBILITY_H + +namespace FB { +inline Void fb_clear_video() noexcept { + FBDrawInRegion(fb_get_clear_clr(), FB::FBAccessibilty::Height(), FB::FBAccessibilty::Width(), 0, + 0); +} +} // namespace FB \ No newline at end of file diff --git a/dev/modules/CoreGfx/MathGfx.h b/dev/modules/CoreGfx/MathGfx.h index f03e2f19..0b483fad 100644 --- a/dev/modules/CoreGfx/MathGfx.h +++ b/dev/modules/CoreGfx/MathGfx.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright Amlal El Mahrouss. + Copyright Amlal El Mahrouss. ------------------------------------------- */ @@ -9,21 +9,19 @@ /// @file MathMgr.h /// @brief Linear interpolation implementation. -namespace UI -{ +namespace UI { #ifdef NE_CORE_GFX_USE_DOUBLE - typedef double fb_real_t; +typedef double fb_real_t; #else - typedef float fb_real_t; +typedef float fb_real_t; #endif - /// @brief Linear interpolation equation solver. - /// @param from where to start - /// @param to to which value. - /// @param stat - /// @return Linear interop value. - inline fb_real_t fb_math_lerp(fb_real_t to, fb_real_t from, fb_real_t stat) - { - return (from) + (to - from) * stat; - } -} // namespace UI \ No newline at end of file +/// @brief Linear interpolation equation solver. +/// @param from where to start +/// @param to to which value. +/// @param stat +/// @return Linear interop value. +inline fb_real_t fb_math_lerp(fb_real_t to, fb_real_t from, fb_real_t stat) { + return (from) + (to - from) * stat; +} +} // namespace UI \ No newline at end of file diff --git a/dev/modules/CoreGfx/TextGfx.h b/dev/modules/CoreGfx/TextGfx.h index 09d9dad3..e19b4743 100644 --- a/dev/modules/CoreGfx/TextGfx.h +++ b/dev/modules/CoreGfx/TextGfx.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,176 +9,175 @@ #include #include -#define kFontSizeX 8 -#define kFontSizeY 8 +#define kFontSizeX 8 +#define kFontSizeY 8 #define kFontNOFChars 128 inline const Kernel::UInt8 kFontBitmap[kFontNOFChars][kFontSizeX] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) - {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) - {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") - {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) - {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) - {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) - {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) - {0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') - {0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() - {0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) - {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) - {0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) - {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) - {0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) - {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) - {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) - {0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) - {0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) - {0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) - {0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) - {0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) - {0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) - {0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) - {0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) - {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) - {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) - {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) - {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) - {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) - {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) - {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) - {0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) - {0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) - {0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) - {0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) - {0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) - {0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) - {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) - {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) - {0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) - {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) - {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) - {0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) - {0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) - {0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) - {0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) - {0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) - {0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) - {0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) - {0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) - {0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) - {0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) - {0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) - {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) - {0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) - {0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) - {0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) - {0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) - {0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) - {0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) - {0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) - {0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) - {0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) - {0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) - {0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) - {0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) - {0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) - {0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) - {0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) - {0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) - {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) - {0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) - {0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) - {0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) - {0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) - {0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) - {0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) - {0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) - {0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) - {0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) - {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) - {0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) - {0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) - {0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) - {0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) - {0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) - {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) - {0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) - {0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) - {0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) - {0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) - {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) - {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) - {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + {0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + {0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + {0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + {0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + {0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + {0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + {0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + {0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + {0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + {0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + {0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + {0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + {0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + {0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + {0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + {0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + {0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + {0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + {0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + {0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + {0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + {0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + {0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + {0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + {0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + {0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + {0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + {0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + {0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + {0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + {0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + {0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + {0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + {0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + {0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + {0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + {0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + {0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + {0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + {0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + {0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + {0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + {0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + {0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + {0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + {0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + {0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + {0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + {0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + {0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + {0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + {0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + {0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + {0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + {0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + {0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + {0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + {0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + {0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + {0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + {0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + {0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F }; -inline Kernel::Void fb_render_string_for_bitmap(const Kernel::UInt8* bitmap, const Kernel::SizeT x_sz, const Kernel::SizeT y_sz, Kernel::Int32& x_dst, Kernel::Int32& y_dst, Kernel::Int32& color) -{ - Kernel::SizeT x, y; - Kernel::SizeT set; +inline Kernel::Void fb_render_string_for_bitmap(const Kernel::UInt8* bitmap, + const Kernel::SizeT x_sz, const Kernel::SizeT y_sz, + Kernel::Int32& x_dst, Kernel::Int32& y_dst, + Kernel::Int32& color) { + Kernel::SizeT x, y; + Kernel::SizeT set; - x = 0; - y = 0; - set = 0; + x = 0; + y = 0; + set = 0; - for (; y < y_sz; ++y) - { - for (x = 0; x < x_sz; ++x) - { - set = bitmap[x] & (1 << y); + for (; y < y_sz; ++y) { + for (x = 0; x < x_sz; ++x) { + set = bitmap[x] & (1 << y); - if (set) - { - FBDrawInRegion(color, 1, 1, ((x_dst) + x), ((y_dst) + y)); - } - } - } + if (set) { + FBDrawInRegion(color, 1, 1, ((x_dst) + x), ((y_dst) + y)); + } + } + } } -inline Kernel::Void fb_render_string(const Kernel::Char* text, Kernel::Int32 x_dst, Kernel::Int32 y_dst, Kernel::Int32 color) -{ +inline Kernel::Void fb_render_string(const Kernel::Char* text, Kernel::Int32 x_dst, + Kernel::Int32 y_dst, Kernel::Int32 color) { #ifndef __BOOTZ__ - auto len = Kernel::rt_string_len(text); + auto len = Kernel::rt_string_len(text); #else - auto len = StrLen(text); + auto len = StrLen(text); #endif - for (Kernel::SizeT i = 0; i < len; ++i) - { - fb_render_string_for_bitmap(&kFontBitmap[(Kernel::UInt8)text[i]][0], kFontSizeX, kFontSizeY, x_dst, y_dst, color); - y_dst += kFontSizeY; - } + for (Kernel::SizeT i = 0; i < len; ++i) { + fb_render_string_for_bitmap(&kFontBitmap[(Kernel::UInt8) text[i]][0], kFontSizeX, kFontSizeY, + x_dst, y_dst, color); + y_dst += kFontSizeY; + } } diff --git a/dev/modules/HPET/Defines.h b/dev/modules/HPET/Defines.h index 88e43758..49f17f99 100644 --- a/dev/modules/HPET/Defines.h +++ b/dev/modules/HPET/Defines.h @@ -1,11 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: HPET.h - Purpose: HPET builtin. + File: HPET.h + Purpose: HPET builtin. - Revision History: + Revision History: ------------------------------------------- */ @@ -14,29 +14,26 @@ #include #include -namespace Kernel -{ - struct PACKED HPETAddressStructure final - { - Kernel::UInt8 AddressSpaceId; // 0 - system memory, 1 - system I/O - Kernel::UInt8 RegisterBitWidth; - Kernel::UInt8 RegisterBitOffset; - Kernel::UInt8 Reserved; - Kernel::UInt64 Address; - }; - - struct PACKED HPETHeader final : public SDT - { - Kernel::UInt8 HardwareRevId; - Kernel::UInt8 ComparatorCount : 5; - Kernel::UInt8 CounterSize : 1; - Kernel::UInt8 Reserved : 1; - Kernel::UInt8 LegacyReplacement : 1; - Kernel::UInt16 PciVendorId; - HPETAddressStructure Address; - Kernel::UInt8 HpetNumber; - Kernel::UInt16 MinimumTick; - Kernel::UInt8 PageProtection; - }; - -} // namespace Kernel +namespace Kernel { +struct PACKED HPETAddressStructure final { + Kernel::UInt8 AddressSpaceId; // 0 - system memory, 1 - system I/O + Kernel::UInt8 RegisterBitWidth; + Kernel::UInt8 RegisterBitOffset; + Kernel::UInt8 Reserved; + Kernel::UInt64 Address; +}; + +struct PACKED HPETHeader final : public SDT { + Kernel::UInt8 HardwareRevId; + Kernel::UInt8 ComparatorCount : 5; + Kernel::UInt8 CounterSize : 1; + Kernel::UInt8 Reserved : 1; + Kernel::UInt8 LegacyReplacement : 1; + Kernel::UInt16 PciVendorId; + HPETAddressStructure Address; + Kernel::UInt8 HpetNumber; + Kernel::UInt16 MinimumTick; + Kernel::UInt8 PageProtection; +}; + +} // namespace Kernel diff --git a/dev/modules/LTE/LTE.h b/dev/modules/LTE/LTE.h index 2c1abf08..45dec6bc 100644 --- a/dev/modules/LTE/LTE.h +++ b/dev/modules/LTE/LTE.h @@ -22,19 +22,13 @@ Kernel::Boolean lte_turn_on_sim(Kernel::Int32 simSlot); Kernel::Boolean lte_turn_off_sim(Kernel::Int32 simSlot); /// @brief Send AT command. -Kernel::Boolean lte_send_at_command(Kernel::Char* buf, - Kernel::Size bufReadSz, - Kernel::Int32 simSlot); - -Kernel::Boolean lte_write_sim_file(Kernel::Char* file, - Kernel::VoidPtr buf, - Kernel::Size bufSz, - Kernel::Size offset, - Kernel::Int32 simSlot); - -Kernel::VoidPtr lte_read_sim_file(Kernel::Char* file, - Kernel::Size bufSz, - Kernel::Size offset, - Kernel::Int32 simSlot); - -#endif // ifndef _INC_NETWORK_LTE_H_ +Kernel::Boolean lte_send_at_command(Kernel::Char* buf, Kernel::Size bufReadSz, + Kernel::Int32 simSlot); + +Kernel::Boolean lte_write_sim_file(Kernel::Char* file, Kernel::VoidPtr buf, Kernel::Size bufSz, + Kernel::Size offset, Kernel::Int32 simSlot); + +Kernel::VoidPtr lte_read_sim_file(Kernel::Char* file, Kernel::Size bufSz, Kernel::Size offset, + Kernel::Int32 simSlot); + +#endif // ifndef _INC_NETWORK_LTE_H_ diff --git a/dev/modules/MBCI/MBCI.h b/dev/modules/MBCI/MBCI.h index ebc73f69..1038f17c 100644 --- a/dev/modules/MBCI/MBCI.h +++ b/dev/modules/MBCI/MBCI.h @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef _INC_MODULE_MBCI_H_ #define _INC_MODULE_MBCI_H_ -#include #include +#include #include /// @file MBCI.h @@ -26,106 +26,98 @@ */ #define kMBCIZeroSz (8) -#define kMBCIESBSz (64) - -namespace Kernel -{ - struct IMBCIHost; - - enum - { - kMBCISpeedDeviceInvalid, - kMBCILowSpeedDevice, - kMBCIHighSpeedDevice, - kMBCISpeedDeviceCount, - }; - - /// @brief MBCI Host header. - struct PACKED IMBCIHost final - { - UInt32 Magic; - UInt32 HostId; - UInt16 VendorId; - UInt16 DeviceId; - UInt8 MemoryType; - UInt16 HostType; - UInt16 HostFlags; - UInt8 Error; - UInt32 MMIOTest; - UInt16 State; - UInt8 Status; - UInt8 InterruptEnable; - UInt64 BaseAddressRegister; - UInt64 BaseAddressRegisterSize; - UInt32 CommandIssue; - UInt8 Esb[kMBCIESBSz]; // Extended Signature Block - UInt8 Zero[kMBCIZeroSz]; - }; - - /// @brief MBCI host flags. - enum MBCIHostFlags - { - kMBCIHostFlagsSupportsNothing, // Invalid MBCI device. - kMBCIHostFlagsSupportsAPM, // FW's Advanced Power Management. - kMBCIHostFlagsSupportsDaisyChain, // Is daisy chained. - kMBCIHostFlagsSupportsHWInterrupts, // Has HW interrupts. - kMBCIHostFlagsSupportsDMA, // Has DMA. - kMBCIHostFlagsExtended, // Extended flags table. - }; - - /// @brief MBCI host kind. - enum MBCIHostKind - { - kMBCIHostKindHardDisk, - kMBCIHostKindOpticalDisk, - kMBCIHostKindKeyboardLow, - kMBCIHostKindMouseLow, - kMBCIHostKindMouseHigh, - kMBCIHostKindKeyboardHigh, - kMBCIHostKindNetworkInterface, - kMBCIHostKindDaisyChain, - kMBCIHostKindStartExtended, // Extended vendor table limit. - }; - - enum MBCIHostState - { - kMBCIHostStateInvalid, - kMBCIHostStateReset, - kMBCIHostStateSuccess, - kMBCIHostStateReady, - kMBCIHostStateDmaStart, - kMBCIHostStateDmaEnd, - kMBCIHostStateFail, - kMBCIHostStateCount, - }; - - /// @brief An AuthKey is a context used to tokenize data for an MBCI packet. - typedef UInt32 MBCIAuthKeyType; - - /// @brief Read Auth key for MBCI host. - /// @param host the mbci host to get the key on. - /// @return the 24-bit key. - inline MBCIAuthKeyType mbci_read_auth_key(_Input volatile struct IMBCIHost* host) - { - constexpr auto const kChallengeMBCI = 0xdeadbeef; - - host->MMIOTest = kChallengeMBCI; - - if (host->MMIOTest == kChallengeMBCI) - { - return (host->Esb[kMBCIESBSz - 1] << 16) | (host->Esb[kMBCIESBSz - 2] << 8) | (host->Esb[kMBCIESBSz - 3] & 0xFF); - } - - return kChallengeMBCI; - } - - inline BOOL mbci_test_mmio(_Input volatile struct IMBCIHost* host) - { - constexpr auto const kChallengeMBCI = 0xdeadbeef; - - host->MMIOTest = kChallengeMBCI; - return host->MMIOTest == kChallengeMBCI; - } -} // namespace Kernel - -#endif // ifndef _INC_MODULE_MBCI_H_ \ No newline at end of file +#define kMBCIESBSz (64) + +namespace Kernel { +struct IMBCIHost; + +enum { + kMBCISpeedDeviceInvalid, + kMBCILowSpeedDevice, + kMBCIHighSpeedDevice, + kMBCISpeedDeviceCount, +}; + +/// @brief MBCI Host header. +struct PACKED IMBCIHost final { + UInt32 Magic; + UInt32 HostId; + UInt16 VendorId; + UInt16 DeviceId; + UInt8 MemoryType; + UInt16 HostType; + UInt16 HostFlags; + UInt8 Error; + UInt32 MMIOTest; + UInt16 State; + UInt8 Status; + UInt8 InterruptEnable; + UInt64 BaseAddressRegister; + UInt64 BaseAddressRegisterSize; + UInt32 CommandIssue; + UInt8 Esb[kMBCIESBSz]; // Extended Signature Block + UInt8 Zero[kMBCIZeroSz]; +}; + +/// @brief MBCI host flags. +enum MBCIHostFlags { + kMBCIHostFlagsSupportsNothing, // Invalid MBCI device. + kMBCIHostFlagsSupportsAPM, // FW's Advanced Power Management. + kMBCIHostFlagsSupportsDaisyChain, // Is daisy chained. + kMBCIHostFlagsSupportsHWInterrupts, // Has HW interrupts. + kMBCIHostFlagsSupportsDMA, // Has DMA. + kMBCIHostFlagsExtended, // Extended flags table. +}; + +/// @brief MBCI host kind. +enum MBCIHostKind { + kMBCIHostKindHardDisk, + kMBCIHostKindOpticalDisk, + kMBCIHostKindKeyboardLow, + kMBCIHostKindMouseLow, + kMBCIHostKindMouseHigh, + kMBCIHostKindKeyboardHigh, + kMBCIHostKindNetworkInterface, + kMBCIHostKindDaisyChain, + kMBCIHostKindStartExtended, // Extended vendor table limit. +}; + +enum MBCIHostState { + kMBCIHostStateInvalid, + kMBCIHostStateReset, + kMBCIHostStateSuccess, + kMBCIHostStateReady, + kMBCIHostStateDmaStart, + kMBCIHostStateDmaEnd, + kMBCIHostStateFail, + kMBCIHostStateCount, +}; + +/// @brief An AuthKey is a context used to tokenize data for an MBCI packet. +typedef UInt32 MBCIAuthKeyType; + +/// @brief Read Auth key for MBCI host. +/// @param host the mbci host to get the key on. +/// @return the 24-bit key. +inline MBCIAuthKeyType mbci_read_auth_key(_Input volatile struct IMBCIHost* host) { + constexpr auto const kChallengeMBCI = 0xdeadbeef; + + host->MMIOTest = kChallengeMBCI; + + if (host->MMIOTest == kChallengeMBCI) { + return (host->Esb[kMBCIESBSz - 1] << 16) | (host->Esb[kMBCIESBSz - 2] << 8) | + (host->Esb[kMBCIESBSz - 3] & 0xFF); + } + + return kChallengeMBCI; +} + +inline BOOL mbci_test_mmio(_Input volatile struct IMBCIHost* host) { + constexpr auto const kChallengeMBCI = 0xdeadbeef; + + host->MMIOTest = kChallengeMBCI; + return host->MMIOTest == kChallengeMBCI; +} +} // namespace Kernel + +#endif // ifndef _INC_MODULE_MBCI_H_ \ No newline at end of file diff --git a/dev/modules/NVME/NVME.h b/dev/modules/NVME/NVME.h index f58aacf9..6572187b 100644 --- a/dev/modules/NVME/NVME.h +++ b/dev/modules/NVME/NVME.h @@ -1,11 +1,11 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - Revision History: + Revision History: - ??/??/24: Added file (amlel) - 23 Jul 24: Update filename to Defines.h and using NE_ALIGN_NVME for NVME structs. (amlel) + ??/??/24: Added file (amlel) + 23 Jul 24: Update filename to Defines.h and using NE_ALIGN_NVME for NVME structs. (amlel) ------------------------------------------- */ @@ -19,95 +19,86 @@ #define NE_ALIGN_NVME ATTRIBUTE(aligned(sizeof(Kernel::UInt32))) -namespace Kernel -{ - struct NE_ALIGN_NVME HAL_NVME_BAR_0 final - { - UInt32 fCapabilities; - UInt32 fVersion; - UInt32 fIntMaskSet; - UInt32 fIntMaskClr; - UInt32 fContrlConf; - UInt32 fContrlStat; - UInt32 fAdminQueueAttr; - UInt32 fAdminSubmissionQueue; - UInt32 fAdminCompletionQueue; - }; - - struct NE_ALIGN_NVME HAL_NVME_QUEUE final - { - UInt32 fOpcode; - UInt32 fNSID; - UInt32 fReserved[3]; - UInt32 fMetadataPtr[5]; - UInt32 fDataPtr[9]; - UInt32 CommandSpecific[15]; - }; - - enum - { - kInvalidNVME = 0xFF, - kCreateCompletionQueueNVME = 0x05, - kCreateSubmissionQueueNVME = 0x01, - kIdentifyNVME = 0x06, - kReadNVME = 0x02, - kWriteNVME = 0x01, - kCountNVME = 5, - }; - - /// @brief Creates an admin command for a DMA operation. - template - inline Bool nvme_create_admin_command(HAL_NVME_QUEUE* entry, UInt32 nsid, UInt32 prpTransfer[3], UInt32 startingLba[2], UInt32 lowTransferBlocks) - { - if (entry == nullptr) - return false; - - entry->CommandSpecific[9] = startingLba[0]; - entry->CommandSpecific[10] = startingLba[1]; - - entry->CommandSpecific[11] = lowTransferBlocks; - - entry->CommandSpecific[5] = prpTransfer[0]; - entry->CommandSpecific[6] = prpTransfer[1]; - entry->CommandSpecific[7] = prpTransfer[2]; - - entry->CommandSpecific[0] = nsid; - - return true; - } - - /// @brief Creates an I/O command for a DMA operation. - template - inline Bool nvme_create_io_command(HAL_NVME_QUEUE* entry, UInt64 baseAddress, UInt32 identLoAndQueueSizeHi, UInt32 flagsLoAndQueueComplIdHi, UInt32 identify, Bool provideIdentify = false, Bool namespaceIdentify = false) - { - if (entry == nullptr) - return false; - - if (baseAddress == 0) - return false; - - entry->fOpcode = Opcode; - - entry->CommandSpecific[5] = (baseAddress & 0xFF); - entry->CommandSpecific[6] = static_cast(baseAddress); - - if (!provideIdentify) - { - entry->CommandSpecific[9] = identLoAndQueueSizeHi; - entry->CommandSpecific[10] = flagsLoAndQueueComplIdHi; - } - else - { - entry->CommandSpecific[9] = identify; - - if (namespaceIdentify) - { - entry->CommandSpecific[0] = 1; - } - } - - return true; - } -} // namespace Kernel - -#endif // ifndef __MODULE_NVME_H__ +namespace Kernel { +struct NE_ALIGN_NVME HAL_NVME_BAR_0 final { + UInt32 fCapabilities; + UInt32 fVersion; + UInt32 fIntMaskSet; + UInt32 fIntMaskClr; + UInt32 fContrlConf; + UInt32 fContrlStat; + UInt32 fAdminQueueAttr; + UInt32 fAdminSubmissionQueue; + UInt32 fAdminCompletionQueue; +}; + +struct NE_ALIGN_NVME HAL_NVME_QUEUE final { + UInt32 fOpcode; + UInt32 fNSID; + UInt32 fReserved[3]; + UInt32 fMetadataPtr[5]; + UInt32 fDataPtr[9]; + UInt32 CommandSpecific[15]; +}; + +enum { + kInvalidNVME = 0xFF, + kCreateCompletionQueueNVME = 0x05, + kCreateSubmissionQueueNVME = 0x01, + kIdentifyNVME = 0x06, + kReadNVME = 0x02, + kWriteNVME = 0x01, + kCountNVME = 5, +}; + +/// @brief Creates an admin command for a DMA operation. +template +inline Bool nvme_create_admin_command(HAL_NVME_QUEUE* entry, UInt32 nsid, UInt32 prpTransfer[3], + UInt32 startingLba[2], UInt32 lowTransferBlocks) { + if (entry == nullptr) return false; + + entry->CommandSpecific[9] = startingLba[0]; + entry->CommandSpecific[10] = startingLba[1]; + + entry->CommandSpecific[11] = lowTransferBlocks; + + entry->CommandSpecific[5] = prpTransfer[0]; + entry->CommandSpecific[6] = prpTransfer[1]; + entry->CommandSpecific[7] = prpTransfer[2]; + + entry->CommandSpecific[0] = nsid; + + return true; +} + +/// @brief Creates an I/O command for a DMA operation. +template +inline Bool nvme_create_io_command(HAL_NVME_QUEUE* entry, UInt64 baseAddress, + UInt32 identLoAndQueueSizeHi, UInt32 flagsLoAndQueueComplIdHi, + UInt32 identify, Bool provideIdentify = false, + Bool namespaceIdentify = false) { + if (entry == nullptr) return false; + + if (baseAddress == 0) return false; + + entry->fOpcode = Opcode; + + entry->CommandSpecific[5] = (baseAddress & 0xFF); + entry->CommandSpecific[6] = static_cast(baseAddress); + + if (!provideIdentify) { + entry->CommandSpecific[9] = identLoAndQueueSizeHi; + entry->CommandSpecific[10] = flagsLoAndQueueComplIdHi; + } else { + entry->CommandSpecific[9] = identify; + + if (namespaceIdentify) { + entry->CommandSpecific[0] = 1; + } + } + + return true; +} +} // namespace Kernel + +#endif // ifndef __MODULE_NVME_H__ diff --git a/dev/modules/Power/PowerFactory.h b/dev/modules/Power/PowerFactory.h index c1bad49b..8cd414c5 100644 --- a/dev/modules/Power/PowerFactory.h +++ b/dev/modules/Power/PowerFactory.h @@ -1,37 +1,32 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -#include -#include #include +#include #include +#include #define NE_POWER_FACTORY : public PowerFactory -namespace Kernel -{ - class PowerFactory; - - class PowerFactory - { - public: - explicit PowerFactory() = default; - virtual ~PowerFactory() = default; - - PowerFactory& operator=(const PowerFactory&) = default; - PowerFactory(const PowerFactory&) = default; - - public: - Bool Shutdown() - { - return NO; - }; // shutdown - Void Reboot(){}; // soft-reboot - }; -} // namespace Kernel \ No newline at end of file +namespace Kernel { +class PowerFactory; + +class PowerFactory { + public: + explicit PowerFactory() = default; + virtual ~PowerFactory() = default; + + PowerFactory& operator=(const PowerFactory&) = default; + PowerFactory(const PowerFactory&) = default; + + public: + Bool Shutdown() { return NO; }; // shutdown + Void Reboot() {}; // soft-reboot +}; +} // namespace Kernel \ No newline at end of file diff --git a/dev/modules/SCSI/SCSI.h b/dev/modules/SCSI/SCSI.h index f843aa02..e0137f3c 100644 --- a/dev/modules/SCSI/SCSI.h +++ b/dev/modules/SCSI/SCSI.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,11 +11,10 @@ /// @file SCSI.h /// @brief Small Computer System Interface device. -namespace Kernel -{ - template - using scsi_packet_type = Kernel::UInt16[PacketBitLen]; - using scsi_packet_type_12 = scsi_packet_type<12>; +namespace Kernel { +template +using scsi_packet_type = Kernel::UInt16[PacketBitLen]; +using scsi_packet_type_12 = scsi_packet_type<12>; - extern const scsi_packet_type<12> kCDRomPacketTemplate; -} // namespace Kernel \ No newline at end of file +extern const scsi_packet_type<12> kCDRomPacketTemplate; +} // namespace Kernel \ No newline at end of file diff --git a/dev/modules/XHCI/XHCI.h b/dev/modules/XHCI/XHCI.h index a3fc8c81..0d2851d7 100644 --- a/dev/modules/XHCI/XHCI.h +++ b/dev/modules/XHCI/XHCI.h @@ -1,14 +1,14 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - File: Defines.h - Purpose: XHCI (and backwards) header. + File: Defines.h + Purpose: XHCI (and backwards) header. - Revision History: + Revision History: - 01/02/24: Added file (amlel) - 03/02/24: Update filename to Defines.h (amlel) + 01/02/24: Added file (amlel) + 03/02/24: Update filename to Defines.h (amlel) ------------------------------------------- */ @@ -18,53 +18,49 @@ using namespace Kernel; -#define kUSBCommand (UInt16)0x0 -#define kUSBStatus (UInt16)0x2 -#define kUSBInterruptEnable (UInt16)0x4 -#define kUSBFrameNum (UInt16)0x6 -#define kUSBFrameListBaseAddress (UInt16)0x8 -#define kUSBFrameModifyStart (UInt16)0xC -#define kUSBPort1StatusCtrl (UInt16)0x10 -#define kUSBPort2StatusCtrl (UInt16)0x12 +#define kUSBCommand (UInt16) 0x0 +#define kUSBStatus (UInt16) 0x2 +#define kUSBInterruptEnable (UInt16) 0x4 +#define kUSBFrameNum (UInt16) 0x6 +#define kUSBFrameListBaseAddress (UInt16) 0x8 +#define kUSBFrameModifyStart (UInt16) 0xC +#define kUSBPort1StatusCtrl (UInt16) 0x10 +#define kUSBPort2StatusCtrl (UInt16) 0x12 -typedef struct USBCommandRegister final -{ - UInt8 mReserved[8]; // Reserved - UInt8 - mMaxPacket; // 0 = Max packet size 32 bits 1 = Max packet size 64 bits - UInt8 mConfigure; - UInt8 mSoftwareDebug; - UInt8 mGlobalResume; - UInt8 mGlobalSuspend; - UInt8 mHostCtrlReset; - UInt8 mRun; // 1 = Controller execute frame list entries +typedef struct USBCommandRegister final { + UInt8 mReserved[8]; // Reserved + UInt8 mMaxPacket; // 0 = Max packet size 32 bits 1 = Max packet size 64 bits + UInt8 mConfigure; + UInt8 mSoftwareDebug; + UInt8 mGlobalResume; + UInt8 mGlobalSuspend; + UInt8 mHostCtrlReset; + UInt8 mRun; // 1 = Controller execute frame list entries } USBCommandRegister; -typedef struct USBStatusRegister final -{ - UInt8 mReserved[8]; // Reserved - UInt8 mHalted; // 1 = bit 0 in CMD is zero 0 = bit 0 in CMD is 1 - UInt8 mProcessError; - UInt8 mSystemError; - UInt8 mResumeDetected; - UInt8 mErrorInterrupt; - UInt8 mInterrupt; +typedef struct USBStatusRegister final { + UInt8 mReserved[8]; // Reserved + UInt8 mHalted; // 1 = bit 0 in CMD is zero 0 = bit 0 in CMD is 1 + UInt8 mProcessError; + UInt8 mSystemError; + UInt8 mResumeDetected; + UInt8 mErrorInterrupt; + UInt8 mInterrupt; } USBStatusRegister; -typedef struct USBInterruptEnableRegister final -{ - UInt8 mReserved[4]; // Reserved - UInt8 mShortPacket; // 1=Enable interrupt 0=Disable interrupt - UInt8 mComplete; // 1=Enable interrupt 0=Disable interrupt - UInt8 mResume; // 1=Enable interrupt 0=Disable interrupt - UInt8 mTimeoutCRC; // 1=Enable interrupt 0=Disable interrupt +typedef struct USBInterruptEnableRegister final { + UInt8 mReserved[4]; // Reserved + UInt8 mShortPacket; // 1=Enable interrupt 0=Disable interrupt + UInt8 mComplete; // 1=Enable interrupt 0=Disable interrupt + UInt8 mResume; // 1=Enable interrupt 0=Disable interrupt + UInt8 mTimeoutCRC; // 1=Enable interrupt 0=Disable interrupt } USBInterruptEnableRegister; /* - Some terminology: + Some terminology: - Frame Number: Number of processed entry of the Frame List. - Frame List Base Address: - 32-bit physical adress of Frame List. Remember that first 12 bytes are + Frame Number: Number of processed entry of the Frame List. + Frame List Base Address: + 32-bit physical adress of Frame List. Remember that first 12 bytes are always 0. The Frame List must contain 1024 entries. */ diff --git a/dev/user/Macros.h b/dev/user/Macros.h index a0dfcb00..0bb98a59 100644 --- a/dev/user/Macros.h +++ b/dev/user/Macros.h @@ -19,7 +19,7 @@ Purpose: libsci Macros header. #define ATTRIBUTE(X) __attribute__((X)) #define IMPORT_CXX extern "C++" -#define IMPORT_C extern "C" +#define IMPORT_C extern "C" #define DEPRECATED ATTRIBUTE(deprecated) @@ -42,12 +42,12 @@ typedef void Void; #endif #define YES true -#define NO false +#define NO false typedef __UINT64_TYPE__ UInt64; typedef __UINT32_TYPE__ UInt32; typedef __UINT16_TYPE__ UInt16; -typedef __UINT8_TYPE__ UInt8; +typedef __UINT8_TYPE__ UInt8; typedef __SIZE_TYPE__ SizeT; @@ -56,29 +56,29 @@ typedef __INT32_TYPE__ SInt32; typedef __INT16_TYPE__ SInt16; typedef __INT8_TYPE__ SInt8; -typedef void* VoidPtr; +typedef void* VoidPtr; typedef __UINTPTR_TYPE__ UIntPtr; -typedef char Char; +typedef char Char; #ifdef __cplusplus typedef decltype(nullptr) nullPtr; -typedef nullPtr NullPtr; +typedef nullPtr NullPtr; -#define SCI_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; +#define SCI_COPY_DELETE(KLASS) \ + KLASS& operator=(const KLASS&) = delete; \ + KLASS(const KLASS&) = delete; -#define SCI_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; +#define SCI_COPY_DEFAULT(KLASS) \ + KLASS& operator=(const KLASS&) = default; \ + KLASS(const KLASS&) = default; -#define SCI_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; +#define SCI_MOVE_DELETE(KLASS) \ + KLASS& operator=(KLASS&&) = delete; \ + KLASS(KLASS&&) = delete; -#define SCI_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; +#define SCI_MOVE_DEFAULT(KLASS) \ + KLASS& operator=(KLASS&&) = default; \ + KLASS(KLASS&&) = default; #endif @@ -87,9 +87,8 @@ IMPORT_C void _rtl_assert(Bool expr, const Char* origin); #define MUST_PASS(X) _rtl_assert(X, __FILE__) #ifndef ARRAY_SIZE -#define ARRAY_SIZE(X) \ - (((sizeof(X) / sizeof(*(X))) / \ - (static_cast(!(sizeof(X) % sizeof(*(X))))))) +#define ARRAY_SIZE(X) \ + (((sizeof(X) / sizeof(*(X))) / (static_cast(!(sizeof(X) % sizeof(*(X))))))) #endif #ifndef KIB @@ -97,31 +96,31 @@ IMPORT_C void _rtl_assert(Bool expr, const Char* origin); #endif #ifndef kib_cast -#define kib_cast(X) (UInt64)((X)*1024) +#define kib_cast(X) (UInt64)((X) * 1024) #endif #ifndef MIB -#define MIB(X) (UInt64)((UInt64)KIB(X) / 1024) +#define MIB(X) (UInt64)((UInt64) KIB(X) / 1024) #endif #ifndef mib_cast -#define mib_cast(X) (UInt64)((UInt64)kib_cast(X) * 1024) +#define mib_cast(X) (UInt64)((UInt64) kib_cast(X) * 1024) #endif #ifndef GIB -#define GIB(X) (UInt64)((UInt64)MIB(X) / 1024) +#define GIB(X) (UInt64)((UInt64) MIB(X) / 1024) #endif #ifndef gib_cast -#define gib_cast(X) (UInt64)((UInt64)mib_cast(X) * 1024) +#define gib_cast(X) (UInt64)((UInt64) mib_cast(X) * 1024) #endif #ifndef TIB -#define TIB(X) (UInt64)((UInt64)GIB(X) / 1024) +#define TIB(X) (UInt64)((UInt64) GIB(X) / 1024) #endif #ifndef tib_cast -#define tib_cast(X) ((UInt64)gib_cast(X) * 1024) +#define tib_cast(X) ((UInt64) gib_cast(X) * 1024) #endif -#define SCI_UNUSED(X) ((void)X) +#define SCI_UNUSED(X) ((void) X) diff --git a/dev/user/Opts.h b/dev/user/Opts.h index 09a77570..474fe1b7 100644 --- a/dev/user/Opts.h +++ b/dev/user/Opts.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ diff --git a/dev/user/ProcessCodes.h b/dev/user/ProcessCodes.h index 1b1b955b..74b50c68 100644 --- a/dev/user/ProcessCodes.h +++ b/dev/user/ProcessCodes.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,46 +12,46 @@ /// @brief Process Codes type and values. /// @author Amlal El Mahrouss (amlal@nekernel.org) -#define err_local_ok() (kLastError == kErrorSuccess) +#define err_local_ok() (kLastError == kErrorSuccess) #define err_local_fail() (kLastError != kErrorSuccess) -#define err_local_get() (kLastError) +#define err_local_get() (kLastError) typedef SInt32 ErrRef; -inline constexpr ErrRef kErrorSuccess = 0; -inline constexpr ErrRef kErrorExecutable = 33; -inline constexpr ErrRef kErrorExecutableLib = 34; -inline constexpr ErrRef kErrorFileNotFound = 35; -inline constexpr ErrRef kErrorDirectoryNotFound = 36; -inline constexpr ErrRef kErrorDiskReadOnly = 37; -inline constexpr ErrRef kErrorDiskIsFull = 38; -inline constexpr ErrRef kErrorProcessFault = 39; -inline constexpr ErrRef kErrorSocketHangUp = 40; +inline constexpr ErrRef kErrorSuccess = 0; +inline constexpr ErrRef kErrorExecutable = 33; +inline constexpr ErrRef kErrorExecutableLib = 34; +inline constexpr ErrRef kErrorFileNotFound = 35; +inline constexpr ErrRef kErrorDirectoryNotFound = 36; +inline constexpr ErrRef kErrorDiskReadOnly = 37; +inline constexpr ErrRef kErrorDiskIsFull = 38; +inline constexpr ErrRef kErrorProcessFault = 39; +inline constexpr ErrRef kErrorSocketHangUp = 40; inline constexpr ErrRef kErrorThreadLocalStorage = 41; -inline constexpr ErrRef kErrorMath = 42; -inline constexpr ErrRef kErrorNoNetwork = 43; -inline constexpr ErrRef kErrorHeapOutOfMemory = 44; -inline constexpr ErrRef kErrorNoSuchDisk = 45; -inline constexpr ErrRef kErrorFileExists = 46; -inline constexpr ErrRef kErrorFormatFailed = 47; -inline constexpr ErrRef kErrorNetworkTimeout = 48; -inline constexpr ErrRef kErrorInternal = 49; -inline constexpr ErrRef kErrorForkAlreadyExists = 50; -inline constexpr ErrRef kErrorOutOfTeamSlot = 51; -inline constexpr ErrRef kErrorHeapNotPresent = 52; -inline constexpr ErrRef kErrorNoEntrypoint = 53; -inline constexpr ErrRef kErrorDiskIsCorrupted = 54; -inline constexpr ErrRef kErrorDisk = 55; -inline constexpr ErrRef kErrorInvalidData = 56; -inline constexpr ErrRef kErrorAsync = 57; -inline constexpr ErrRef kErrorNonBlocking = 58; -inline constexpr ErrRef kErrorIPC = 59; -inline constexpr ErrRef kErrorSign = 60; -inline constexpr ErrRef kErrorInvalidCreds = 61; -inline constexpr ErrRef kErrorCDTrayBroken = 62; -inline constexpr ErrRef kErrorUnrecoverableDisk = 63; -inline constexpr ErrRef kErrorFileLocked = 64; -inline constexpr ErrRef kErrorUnimplemented = -1; +inline constexpr ErrRef kErrorMath = 42; +inline constexpr ErrRef kErrorNoNetwork = 43; +inline constexpr ErrRef kErrorHeapOutOfMemory = 44; +inline constexpr ErrRef kErrorNoSuchDisk = 45; +inline constexpr ErrRef kErrorFileExists = 46; +inline constexpr ErrRef kErrorFormatFailed = 47; +inline constexpr ErrRef kErrorNetworkTimeout = 48; +inline constexpr ErrRef kErrorInternal = 49; +inline constexpr ErrRef kErrorForkAlreadyExists = 50; +inline constexpr ErrRef kErrorOutOfTeamSlot = 51; +inline constexpr ErrRef kErrorHeapNotPresent = 52; +inline constexpr ErrRef kErrorNoEntrypoint = 53; +inline constexpr ErrRef kErrorDiskIsCorrupted = 54; +inline constexpr ErrRef kErrorDisk = 55; +inline constexpr ErrRef kErrorInvalidData = 56; +inline constexpr ErrRef kErrorAsync = 57; +inline constexpr ErrRef kErrorNonBlocking = 58; +inline constexpr ErrRef kErrorIPC = 59; +inline constexpr ErrRef kErrorSign = 60; +inline constexpr ErrRef kErrorInvalidCreds = 61; +inline constexpr ErrRef kErrorCDTrayBroken = 62; +inline constexpr ErrRef kErrorUnrecoverableDisk = 63; +inline constexpr ErrRef kErrorFileLocked = 64; +inline constexpr ErrRef kErrorUnimplemented = -1; /// @brief The last error reported by the system to the process. IMPORT_C ErrRef kLastError; diff --git a/dev/user/SystemCalls.h b/dev/user/SystemCalls.h index cfbd99a8..1e391d8a 100644 --- a/dev/user/SystemCalls.h +++ b/dev/user/SystemCalls.h @@ -94,7 +94,8 @@ IMPORT_C UInt64 IoSeekFile(_Input Ref file_desc, UInt64 file_offset); // Process API. // ------------------------------------------------------------------------ -/// @brief Spawns a Thread Information Block and Global Information Block inside the current process. +/// @brief Spawns a Thread Information Block and Global Information Block inside the current +/// process. /// @param process_id Target Process ID, must be valid. /// @return > 0 error ocurred or already present, = 0 success. IMPORT_C UInt32 RtlSpawnIB(UIntPtr process_id); @@ -102,7 +103,8 @@ IMPORT_C UInt32 RtlSpawnIB(UIntPtr process_id); /// @brief Spawns a process with a unique pid (stored as UIntPtr). /// @param process_path process filesystem path. /// @return > 0 process was created. -IMPORT_C UIntPtr RtlSpawnProcess(const Char* process_path, SizeT argc, Char** argv, Char** envp, SizeT envp_len); +IMPORT_C UIntPtr RtlSpawnProcess(const Char* process_path, SizeT argc, Char** argv, Char** envp, + SizeT envp_len); /// @brief Exits a process with an exit_code. /// @return if it has succeeded true, otherwise false. @@ -269,14 +271,13 @@ IMPORT_C VoidPtr EvtDispatchEvent(_Input const Char* event_name, _Input VoidPtr // Power API. // ------------------------------------------------------------------------------------------ // -enum -{ - kPowerCodeInvalid, - kPowerCodeShutdown, - kPowerCodeReboot, - kPowerCodeSleep, - kPowerCodeWake, - kPowerCodeCount, +enum { + kPowerCodeInvalid, + kPowerCodeShutdown, + kPowerCodeReboot, + kPowerCodeSleep, + kPowerCodeWake, + kPowerCodeCount, }; IMPORT_C SInt32 PwrReadCode(_Output SInt32& code); @@ -346,4 +347,4 @@ IMPORT_C Char* StrFmt(const Char* fmt, ...); IMPORT_C UInt64 StrMathToNumber(const Char* in, const Char** endp, const SInt16 base); -#endif // ifndef SCI_SCI_H +#endif // ifndef SCI_SCI_H diff --git a/dev/user/src/SystemCalls.cc b/dev/user/src/SystemCalls.cc index 6b32bd70..d8366d42 100644 --- a/dev/user/src/SystemCalls.cc +++ b/dev/user/src/SystemCalls.cc @@ -1,114 +1,95 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ -#include #include +#include /// @file SystemCalls.cc /// @brief Source file for the memory functions of the user.sys. /// @brief Copy memory region. -IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) -{ - if (!len || - !dest || - !src) - { - return nullptr; - } - - for (SizeT i = 0; i < len; i++) - { - ((Char*)dest)[i] = ((Char*)src)[i]; - } - - return dest; +IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) { + if (!len || !dest || !src) { + return nullptr; + } + + for (SizeT i = 0; i < len; i++) { + ((Char*) dest)[i] = ((Char*) src)[i]; + } + + return dest; } /// @brief Get string length. -IMPORT_C SInt64 MmStrLen(const Char* in) -{ - if (!in) - return 0; +IMPORT_C SInt64 MmStrLen(const Char* in) { + if (!in) return 0; - SizeT len{0}; + SizeT len{0}; - do - { - ++len; - } while (in[len] != '\0'); + do { + ++len; + } while (in[len] != '\0'); - return len; + return len; } /// @brief Fill memory region **dest** with **value**. -IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value) -{ - if (!len || - !dest) - { - return nullptr; - } - - for (SizeT i = 0; i < len; i++) - { - ((Char*)dest)[i] = value; - } - - return dest; +IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value) { + if (!len || !dest) { + return nullptr; + } + + for (SizeT i = 0; i < len; i++) { + ((Char*) dest)[i] = value; + } + + return dest; } -IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) -{ - return sci_syscall_arg_3(1, reinterpret_cast(const_cast(path)), - reinterpret_cast(const_cast(drv_letter))); +IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) { + return sci_syscall_arg_3(1, reinterpret_cast(const_cast(path)), + reinterpret_cast(const_cast(drv_letter))); } -IMPORT_C Void IoCloseFile(_Input Ref desc) -{ - sci_syscall_arg_2(2, desc); +IMPORT_C Void IoCloseFile(_Input Ref desc) { + sci_syscall_arg_2(2, desc); } -IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) -{ - auto ret = (UInt64*)sci_syscall_arg_3(3, reinterpret_cast(desc), - reinterpret_cast(&off)); +IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) { + auto ret = (UInt64*) sci_syscall_arg_3(3, reinterpret_cast(desc), + reinterpret_cast(&off)); - MUST_PASS((*ret) != ~0UL); - return *ret; + MUST_PASS((*ret) != ~0UL); + return *ret; } -IMPORT_C UInt64 IoTellFile(_Input Ref desc) -{ - auto ret = (UInt64*)sci_syscall_arg_2(4, reinterpret_cast(desc)); - return *ret; +IMPORT_C UInt64 IoTellFile(_Input Ref desc) { + auto ret = (UInt64*) sci_syscall_arg_2(4, reinterpret_cast(desc)); + return *ret; } /// @brief Print to the file descriptor. /// @param desc the file descriptor. -IMPORT_C SInt32 PrintOut(_Input IORef desc, const char* fmt, ...) -{ - va_list args; +IMPORT_C SInt32 PrintOut(_Input IORef desc, const char* fmt, ...) { + va_list args; - va_start(args, fmt); + va_start(args, fmt); - auto ret = (UInt64*)sci_syscall_arg_4(5, reinterpret_cast(desc), - reinterpret_cast(const_cast(fmt)), args); + auto ret = (UInt64*) sci_syscall_arg_4(5, reinterpret_cast(desc), + reinterpret_cast(const_cast(fmt)), args); - va_end(args); + va_end(args); - return *ret; + return *ret; } /// @internal -IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) -{ - if (!expr) - { - PrintOut(nullptr, "Assertion failed: %s\r", origin); - PrintOut(nullptr, "Origin: %s\r", origin); - } +IMPORT_C Void _rtl_assert(Bool expr, const Char* origin) { + if (!expr) { + PrintOut(nullptr, "Assertion failed: %s\r", origin); + PrintOut(nullptr, "Origin: %s\r", origin); + } } \ No newline at end of file diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Array.h b/public/frameworks/CoreFoundation.fwrk/headers/Array.h index e9a36ac4..0b4a8dbf 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Array.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Array.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -8,64 +8,45 @@ #include -namespace CF -{ - template - class CFArray final - { - public: - explicit CFArray() = default; - ~CFArray() = default; - - CFArray& operator=(const CFArray&) = default; - CFArray(const CFArray&) = default; - - T& operator[](SizeT at) - { - MUST_PASS(at < this->Count()); - return fArray[at]; - } - - Bool Empty() - { - return this->Count() > 0; - } - - SizeT Capacity() - { - return N; - } - - SizeT Count() - { - auto cnt = 0UL; - - for (auto i = 0UL; i < N; ++i) - { - if (fArray[i]) - ++cnt; - } - - return cnt; - } - - const T* CData() - { - return fArray; - } - - operator bool() - { - return !Empty(); - } - - private: - T fArray[N] = {nullptr}; - }; - - template - auto make_array(ValueType val) - { - return CFArray{val}; - } -} // namespace CF +namespace CF { +template +class CFArray final { + public: + explicit CFArray() = default; + ~CFArray() = default; + + CFArray& operator=(const CFArray&) = default; + CFArray(const CFArray&) = default; + + T& operator[](SizeT at) { + MUST_PASS(at < this->Count()); + return fArray[at]; + } + + Bool Empty() { return this->Count() > 0; } + + SizeT Capacity() { return N; } + + SizeT Count() { + auto cnt = 0UL; + + for (auto i = 0UL; i < N; ++i) { + if (fArray[i]) ++cnt; + } + + return cnt; + } + + const T* CData() { return fArray; } + + operator bool() { return !Empty(); } + + private: + T fArray[N] = {nullptr}; +}; + +template +auto make_array(ValueType val) { + return CFArray{val}; +} +} // namespace CF diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Atom.h b/public/frameworks/CoreFoundation.fwrk/headers/Atom.h index 923d6bce..f279f0b1 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Atom.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Atom.h @@ -1,47 +1,33 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #pragma once #include -namespace CF -{ - template - class CFAtom final - { - public: - explicit CFAtom() = default; - ~CFAtom() = default; - - public: - CFAtom& operator=(const CFAtom&) = delete; - CFAtom(const CFAtom&) = delete; - - public: - T operator[](SizeT bit) - { - return (fArrayOfAtoms & (1 << bit)); - } - - void operator|(SizeT bit) - { - fArrayOfAtoms |= (1 << bit); - } - - friend Boolean operator==(CFAtom& atomic, const T& idx) - { - return atomic[idx] == idx; - } - - friend Boolean operator!=(CFAtom& atomic, const T& idx) - { - return atomic[idx] == idx; - } - - private: - T fArrayOfAtoms; - }; -} // namespace CF +namespace CF { +template +class CFAtom final { + public: + explicit CFAtom() = default; + ~CFAtom() = default; + + public: + CFAtom& operator=(const CFAtom&) = delete; + CFAtom(const CFAtom&) = delete; + + public: + T operator[](SizeT bit) { return (fArrayOfAtoms & (1 << bit)); } + + void operator|(SizeT bit) { fArrayOfAtoms |= (1 << bit); } + + friend Boolean operator==(CFAtom& atomic, const T& idx) { return atomic[idx] == idx; } + + friend Boolean operator!=(CFAtom& atomic, const T& idx) { return atomic[idx] == idx; } + + private: + T fArrayOfAtoms; +}; +} // namespace CF diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h b/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h index b1c37635..194b7bb7 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Foundation.h @@ -1,10 +1,10 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - FILE: Foundation.h - PURPOSE: Foundation header of the CF framework. + FILE: Foundation.h + PURPOSE: Foundation header of the CF framework. ------------------------------------------- */ @@ -12,68 +12,64 @@ #include -namespace CF -{ - class CFString; - class CFGUID; - class CFProperty; - class CFObject; +namespace CF { +class CFString; +class CFGUID; +class CFProperty; +class CFObject; - template - class CFRef; - class CFFont; - struct CFPoint; - struct CFRect; - struct CFColor; +template +class CFRef; +class CFFont; +struct CFPoint; +struct CFRect; +struct CFColor; #ifndef __LP64__ - typedef SInt32 CFInteger; - typedef float CFReal; +typedef SInt32 CFInteger; +typedef float CFReal; #else - typedef SInt64 CFInteger; - typedef double CFReal; +typedef SInt64 CFInteger; +typedef double CFReal; #endif - typedef SInt32 CFInteger32; - typedef SInt64 CFInteger64; +typedef SInt32 CFInteger32; +typedef SInt64 CFInteger64; - typedef Char CFChar8; - typedef char16_t CFChar16; +typedef Char CFChar8; +typedef char16_t CFChar16; - struct CFPoint - { - CFInteger64 x_1{0UL}; - CFInteger64 y_1{0UL}; +struct CFPoint { + CFInteger64 x_1{0UL}; + CFInteger64 y_1{0UL}; - CFInteger64 x_2{0UL}; - CFInteger64 y_2{0UL}; - CFReal ang{0UL}; + CFInteger64 x_2{0UL}; + CFInteger64 y_2{0UL}; + CFReal ang{0UL}; - operator bool(); + operator bool(); - /// @brief Check if point is within the current CFPoint. - /// @param point the current point to check. - /// @retval true if point is within this point. - /// @retval validations failed. - bool IsWithin(CFPoint& point); - }; + /// @brief Check if point is within the current CFPoint. + /// @param point the current point to check. + /// @retval true if point is within this point. + /// @retval validations failed. + bool IsWithin(CFPoint& point); +}; - struct CFColor final - { - CFInteger64 r, g, b, a{0}; - }; +struct CFColor final { + CFInteger64 r, g, b, a{0}; +}; - struct CFRect final - { - CFInteger64 x{0UL}; - CFInteger64 y{0UL}; +struct CFRect final { + CFInteger64 x{0UL}; + CFInteger64 y{0UL}; - CFInteger64 width{0UL}; - CFInteger64 height{0UL}; + CFInteger64 width{0UL}; + CFInteger64 height{0UL}; - operator bool(); + operator bool(); - BOOL SizeMatches(CFRect& rect) noexcept; - BOOL PositionMatches(CFRect& rect) noexcept; - }; -} // namespace CF \ No newline at end of file + BOOL SizeMatches(CFRect& rect) noexcept; + BOOL PositionMatches(CFRect& rect) noexcept; +}; +} // namespace CF \ No newline at end of file diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Object.h b/public/frameworks/CoreFoundation.fwrk/headers/Object.h index 733512b1..1692f20e 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Object.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Object.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -11,16 +11,14 @@ #define CF_OBJECT : public CF::CFObject -namespace CF -{ - class CFObject; +namespace CF { +class CFObject; - class CFObject - { - public: - explicit CFObject() = default; - virtual ~CFObject() = default; +class CFObject { + public: + explicit CFObject() = default; + virtual ~CFObject() = default; - SCI_COPY_DEFAULT(CFObject); - }; -} // namespace CF \ No newline at end of file + SCI_COPY_DEFAULT(CFObject); +}; +} // namespace CF \ No newline at end of file diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Property.h b/public/frameworks/CoreFoundation.fwrk/headers/Property.h index b999c54e..58e881e5 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Property.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Property.h @@ -1,53 +1,51 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef _PROPS_H #define _PROPS_H -#include #include +#include #define kMaxPropLen (256U) -namespace CF -{ - class CFString; - class CFProperty; - class CFGUID; - - template - class CFArray; - - /// @brief handle to anything (number, ptr, string...) - using CFPropertyId = UIntPtr; - - /// @brief User property class. - /// @example /prop/foo or /prop/bar - class CFProperty final CF_OBJECT - { - public: - CFProperty(); - virtual ~CFProperty(); - - public: - CFProperty& operator=(const CFProperty&) = default; - CFProperty(const CFProperty&) = default; - - Bool StringEquals(CFString& name); - CFPropertyId& GetValue(); - CFString& GetKey(); - - private: - CFString* fName{nullptr}; - CFPropertyId fValue{0UL}; - Ref fGUID{}; - }; - - template - using CFPropertyArray = CFArray; -} // namespace CF - -#endif // !CFKIT_PROPS_H +namespace CF { +class CFString; +class CFProperty; +class CFGUID; + +template +class CFArray; + +/// @brief handle to anything (number, ptr, string...) +using CFPropertyId = UIntPtr; + +/// @brief User property class. +/// @example /prop/foo or /prop/bar +class CFProperty final CF_OBJECT { + public: + CFProperty(); + virtual ~CFProperty(); + + public: + CFProperty& operator=(const CFProperty&) = default; + CFProperty(const CFProperty&) = default; + + Bool StringEquals(CFString& name); + CFPropertyId& GetValue(); + CFString& GetKey(); + + private: + CFString* fName{nullptr}; + CFPropertyId fValue{0UL}; + Ref fGUID{}; +}; + +template +using CFPropertyArray = CFArray; +} // namespace CF + +#endif // !CFKIT_PROPS_H diff --git a/public/frameworks/CoreFoundation.fwrk/headers/Ref.h b/public/frameworks/CoreFoundation.fwrk/headers/Ref.h index 2a4ec452..c18c6161 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/Ref.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/Ref.h @@ -1,110 +1,81 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #ifndef _REF_H_ #define _REF_H_ -#include #include +#include + +namespace CF { +template +class CFRef; + +template +class CFRef final CF_OBJECT { + public: + CFRef() = default; + + ~CFRef() { + if (MmGetHeapFlags(fClass) != -1) delete fClass; + } + + public: + CFRef(T* cls) : fClass(cls) {} + + CFRef(T cls) : fClass(&cls) {} + + CFRef& operator=(T ref) { + if (!fClass) return *this; + + fClass = &ref; + return *this; + } + + public: + T operator->() const { + MUST_PASS(*fClass); + return *fClass; + } + + T& Leak() noexcept { return *fClass; } + + T& TryLeak() const noexcept { + MUST_PASS(*fClass); + return *fClass; + } + + T operator*() { return *fClass; } + + operator bool() noexcept { return fClass; } + + private: + T* fClass{nullptr}; +}; + +template +class CFNonNullRef final { + public: + CFNonNullRef() = delete; + CFNonNullRef(nullPtr) = delete; + + CFNonNullRef(T* ref) : fRef(ref) { MUST_PASS(ref); } + + CFRef& operator->() { + MUST_PASS(fRef); + return fRef; + } + + CFNonNullRef& operator=(const CFNonNullRef& ref) = delete; + CFNonNullRef(const CFNonNullRef& ref) = default; + + private: + CFRef fRef{nullptr}; +}; +} // namespace CF -namespace CF -{ - template - class CFRef; - - template - class CFRef final CF_OBJECT - { - public: - CFRef() = default; - - ~CFRef() - { - if (MmGetHeapFlags(fClass) != -1) - delete fClass; - } - - public: - CFRef(T* cls) - : fClass(cls) - { - } - - CFRef(T cls) - : fClass(&cls) - { - } - - CFRef& operator=(T ref) - { - if (!fClass) - return *this; - - fClass = &ref; - return *this; - } - - public: - T operator->() const - { - MUST_PASS(*fClass); - return *fClass; - } - - T& Leak() noexcept - { - return *fClass; - } - - T& TryLeak() const noexcept - { - MUST_PASS(*fClass); - return *fClass; - } - - T operator*() - { - return *fClass; - } - - operator bool() noexcept - { - return fClass; - } - - private: - T* fClass{nullptr}; - }; - - template - class CFNonNullRef final - { - public: - CFNonNullRef() = delete; - CFNonNullRef(nullPtr) = delete; - - CFNonNullRef(T* ref) - : fRef(ref) - { - MUST_PASS(ref); - } - - CFRef& operator->() - { - MUST_PASS(fRef); - return fRef; - } - - CFNonNullRef& operator=(const CFNonNullRef& ref) = delete; - CFNonNullRef(const CFNonNullRef& ref) = default; - - private: - CFRef fRef{nullptr}; - }; -} // namespace CF - -#endif // ifndef _NEWKIT_REF_H_ +#endif // ifndef _NEWKIT_REF_H_ diff --git a/public/frameworks/CoreFoundation.fwrk/headers/String.h b/public/frameworks/CoreFoundation.fwrk/headers/String.h index e420ac91..c28c05cd 100644 --- a/public/frameworks/CoreFoundation.fwrk/headers/String.h +++ b/public/frameworks/CoreFoundation.fwrk/headers/String.h @@ -1,7 +1,7 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -9,12 +9,10 @@ #include -namespace CF -{ - class CFString; +namespace CF { +class CFString; - class CFString final CF_OBJECT - { - public: - }; -} // namespace CF \ No newline at end of file +class CFString final CF_OBJECT { + public: +}; +} // namespace CF \ No newline at end of file diff --git a/public/frameworks/CoreFoundation.fwrk/src/Foundation.cc b/public/frameworks/CoreFoundation.fwrk/src/Foundation.cc index 89adf665..a4b84abf 100644 --- a/public/frameworks/CoreFoundation.fwrk/src/Foundation.cc +++ b/public/frameworks/CoreFoundation.fwrk/src/Foundation.cc @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2024 Amlal El Mahrouss, all rights reserved + Copyright (C) 2024 Amlal El Mahrouss, all rights reserved ------------------------------------------- */ @@ -9,25 +9,22 @@ /***********************************************************************************/ /// @brief returns true if the proportions are valid. /***********************************************************************************/ -CF::CFRect::operator bool() -{ - return width > 0 && height > 0; +CF::CFRect::operator bool() { + return width > 0 && height > 0; } /***********************************************************************************/ /// @brief returns true if size matches. /***********************************************************************************/ -BOOL CF::CFRect::SizeMatches(CF::CFRect& rect) noexcept -{ - return rect.height == height && rect.width == width; +BOOL CF::CFRect::SizeMatches(CF::CFRect& rect) noexcept { + return rect.height == height && rect.width == width; } /***********************************************************************************/ /// @brief returns true if position matches. /***********************************************************************************/ -BOOL CF::CFRect::PositionMatches(CF::CFRect& rect) noexcept -{ - return rect.y == y && rect.x == x; +BOOL CF::CFRect::PositionMatches(CF::CFRect& rect) noexcept { + return rect.y == y && rect.x == x; } /***********************************************************************************/ @@ -36,16 +33,14 @@ BOOL CF::CFRect::PositionMatches(CF::CFRect& rect) noexcept /// @retval true if point is within this point. /// @retval the validations have failed, false otherwise true. /***********************************************************************************/ -BOOL CF::CFPoint::IsWithin(CF::CFPoint& withinOf) -{ - return x_1 >= withinOf.x_1 && x_2 <= (withinOf.x_2) && - y_1 >= withinOf.y_1 && y_2 <= (withinOf.y_2); +BOOL CF::CFPoint::IsWithin(CF::CFPoint& withinOf) { + return x_1 >= withinOf.x_1 && x_2 <= (withinOf.x_2) && y_1 >= withinOf.y_1 && + y_2 <= (withinOf.y_2); } /***********************************************************************************/ /// @brief if Point object is correctly set up. /***********************************************************************************/ -CF::CFPoint::operator bool() -{ - return x_1 > x_2 && y_1 > y_2; +CF::CFPoint::operator bool() { + return x_1 > x_2 && y_1 > y_2; } \ No newline at end of file diff --git a/public/frameworks/DiskImage.fwrk/headers/DiskImage.h b/public/frameworks/DiskImage.fwrk/headers/DiskImage.h index c0566485..78b39bf8 100644 --- a/public/frameworks/DiskImage.fwrk/headers/DiskImage.h +++ b/public/frameworks/DiskImage.fwrk/headers/DiskImage.h @@ -1,51 +1,49 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + + FILE: DiskImage.h + PURPOSE: Disk Imaging framework. - FILE: DiskImage.h - PURPOSE: Disk Imaging framework. - ------------------------------------------- */ #pragma once #include -#define kDISectorSz (512) -#define kDIMinDiskSz mib_cast(1) +#define kDISectorSz (512) +#define kDIMinDiskSz mib_cast(1) #define kDIDefaultOutputName "disk.eimg" -#define kDIDefaultDiskName "Disk" -#define kDISuccessStatus (0) -#define kDIFailureStatus (1) +#define kDIDefaultDiskName "Disk" +#define kDISuccessStatus (0) +#define kDIFailureStatus (1) #define kDIDiskNameLen (16) -#define kDIOutNameLen (256) - -namespace DI -{ - /// @brief Disk Image file structure. - /// @param disk_name Disk partition name. - /// @param sector_sz Disk sector_sz. - /// @param block_cnt Disk block count. - /// @param disk_sz Disk size. - /// @param out_name Output file name. - struct DI_DISK_IMAGE - { - Char disk_name[kDIDiskNameLen] = kDIDefaultDiskName; - SInt32 sector_sz = kDISectorSz; - SInt32 block_cnt = 0; - SizeT disk_sz = kDIMinDiskSz; - Char out_name[kDIOutNameLen] = kDIDefaultOutputName; - }; - - /// @brief Format with an EPM partition. - /// @param img disk image structure. - /// @return Status code upon completion. - SInt32 DIFormatPartitionEPM(struct DI_DISK_IMAGE& img) noexcept; - - /// @brief NeFS format over EPM. - /// @param img disk image structure. - /// @return Status code upon completion. - SInt32 DIFormatFilesystemNeFS(struct DI_DISK_IMAGE& img) noexcept; - -} // namespace DI +#define kDIOutNameLen (256) + +namespace DI { +/// @brief Disk Image file structure. +/// @param disk_name Disk partition name. +/// @param sector_sz Disk sector_sz. +/// @param block_cnt Disk block count. +/// @param disk_sz Disk size. +/// @param out_name Output file name. +struct DI_DISK_IMAGE { + Char disk_name[kDIDiskNameLen] = kDIDefaultDiskName; + SInt32 sector_sz = kDISectorSz; + SInt32 block_cnt = 0; + SizeT disk_sz = kDIMinDiskSz; + Char out_name[kDIOutNameLen] = kDIDefaultOutputName; +}; + +/// @brief Format with an EPM partition. +/// @param img disk image structure. +/// @return Status code upon completion. +SInt32 DIFormatPartitionEPM(struct DI_DISK_IMAGE& img) noexcept; + +/// @brief NeFS format over EPM. +/// @param img disk image structure. +/// @return Status code upon completion. +SInt32 DIFormatFilesystemNeFS(struct DI_DISK_IMAGE& img) noexcept; + +} // namespace DI diff --git a/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc b/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc index 4d2a6694..a1182e64 100644 --- a/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc +++ b/public/frameworks/DiskImage.fwrk/src/DiskImage+EPM.cc @@ -1,53 +1,46 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - FILE: DiskImage+EPM.cc - PURPOSE: Disk Imaging framework. + FILE: DiskImage+EPM.cc + PURPOSE: Disk Imaging framework. ------------------------------------------- */ #include -#include #include +#include /// @brief EPM format disk /// @param img disk image structure. /// @return Status code upon completion. -SInt32 DI::DIFormatPartitionEPM(struct DI_DISK_IMAGE& img) noexcept -{ - if (!img.sector_sz || (img.sector_sz % 512 != 0)) - return kDIFailureStatus; +SInt32 DI::DIFormatPartitionEPM(struct DI_DISK_IMAGE& img) noexcept { + if (!img.sector_sz || (img.sector_sz % 512 != 0)) return kDIFailureStatus; - if (*img.out_name == 0 || - *img.disk_name == 0) - return kDIFailureStatus; + if (*img.out_name == 0 || *img.disk_name == 0) return kDIFailureStatus; - struct ::EPM_PART_BLOCK block - { - }; + struct ::EPM_PART_BLOCK block {}; - block.NumBlocks = img.block_cnt; - block.SectorSz = img.sector_sz; - block.Version = kEPMRevisionBcd; - block.LbaStart = sizeof(struct ::EPM_PART_BLOCK); - block.LbaEnd = img.disk_sz - block.LbaStart; - block.FsVersion = kNeFSVersionInteger; + block.NumBlocks = img.block_cnt; + block.SectorSz = img.sector_sz; + block.Version = kEPMRevisionBcd; + block.LbaStart = sizeof(struct ::EPM_PART_BLOCK); + block.LbaEnd = img.disk_sz - block.LbaStart; + block.FsVersion = kNeFSVersionInteger; - ::MmCopyMemory(block.Name, (VoidPtr)img.disk_name, ::MmStrLen(img.disk_name)); - ::MmCopyMemory(block.Magic, (VoidPtr)kEPMMagic86, ::MmStrLen(kEPMMagic86)); + ::MmCopyMemory(block.Name, (VoidPtr) img.disk_name, ::MmStrLen(img.disk_name)); + ::MmCopyMemory(block.Magic, (VoidPtr) kEPMMagic86, ::MmStrLen(kEPMMagic86)); - IORef handle = IoOpenFile(img.out_name, nullptr); + IORef handle = IoOpenFile(img.out_name, nullptr); - if (!handle) - return kDIFailureStatus; + if (!handle) return kDIFailureStatus; - ::IoWriteFile(handle, (Char*)&block, sizeof(struct ::EPM_PART_BLOCK)); + ::IoWriteFile(handle, (Char*) &block, sizeof(struct ::EPM_PART_BLOCK)); - ::IoCloseFile(handle); + ::IoCloseFile(handle); - handle = nullptr; + handle = nullptr; - return kDISuccessStatus; + return kDISuccessStatus; } diff --git a/public/frameworks/DiskImage.fwrk/src/DiskImage+NeFS.cc b/public/frameworks/DiskImage.fwrk/src/DiskImage+NeFS.cc index 4928c878..bee84cca 100644 --- a/public/frameworks/DiskImage.fwrk/src/DiskImage+NeFS.cc +++ b/public/frameworks/DiskImage.fwrk/src/DiskImage+NeFS.cc @@ -1,64 +1,57 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - FILE: DiskImage+NeFS.cc - PURPOSE: Disk Imaging framework. + FILE: DiskImage+NeFS.cc + PURPOSE: Disk Imaging framework. ------------------------------------------- */ #include -#include #include +#include /// @brief NeFS format over EPM. /// @param img disk image structure. /// @return Status code upon completion. -SInt32 DI::DIFormatFilesystemNeFS(struct DI_DISK_IMAGE& img) noexcept -{ - if (!img.sector_sz || (img.sector_sz % 512 != 0)) - return kDIFailureStatus; +SInt32 DI::DIFormatFilesystemNeFS(struct DI_DISK_IMAGE& img) noexcept { + if (!img.sector_sz || (img.sector_sz % 512 != 0)) return kDIFailureStatus; - if (*img.out_name == 0 || - *img.disk_name == 0) - return kDIFailureStatus; + if (*img.out_name == 0 || *img.disk_name == 0) return kDIFailureStatus; - struct ::NEFS_ROOT_PARTITION_BLOCK rpb - { - }; + struct ::NEFS_ROOT_PARTITION_BLOCK rpb {}; - ::MmCopyMemory(rpb.PartitionName, (VoidPtr)img.disk_name, ::MmStrLen(img.disk_name)); - ::MmCopyMemory(rpb.Ident, (VoidPtr)kNeFSIdent, ::MmStrLen(kNeFSIdent)); + ::MmCopyMemory(rpb.PartitionName, (VoidPtr) img.disk_name, ::MmStrLen(img.disk_name)); + ::MmCopyMemory(rpb.Ident, (VoidPtr) kNeFSIdent, ::MmStrLen(kNeFSIdent)); - rpb.Version = kNeFSVersionInteger; - rpb.EpmBlock = kEPMBootBlockLba; + rpb.Version = kNeFSVersionInteger; + rpb.EpmBlock = kEPMBootBlockLba; - rpb.StartCatalog = kNeFSCatalogStartAddress; - rpb.CatalogCount = 0; + rpb.StartCatalog = kNeFSCatalogStartAddress; + rpb.CatalogCount = 0; - rpb.DiskSize = img.disk_sz; + rpb.DiskSize = img.disk_sz; - rpb.SectorSize = img.sector_sz; - rpb.SectorCount = rpb.DiskSize / rpb.SectorSize; + rpb.SectorSize = img.sector_sz; + rpb.SectorCount = rpb.DiskSize / rpb.SectorSize; - rpb.FreeSectors = rpb.SectorCount; - rpb.FreeCatalog = rpb.DiskSize / sizeof(NEFS_CATALOG_STRUCT); + rpb.FreeSectors = rpb.SectorCount; + rpb.FreeCatalog = rpb.DiskSize / sizeof(NEFS_CATALOG_STRUCT); - IORef handle = IoOpenFile(img.out_name, nullptr); + IORef handle = IoOpenFile(img.out_name, nullptr); - if (!handle) - return kDIFailureStatus; + if (!handle) return kDIFailureStatus; - UInt64 p_prev = ::IoTellFile(handle); + UInt64 p_prev = ::IoTellFile(handle); - ::IoWriteFile(handle, (Char*)&rpb, sizeof(struct ::NEFS_ROOT_PARTITION_BLOCK)); + ::IoWriteFile(handle, (Char*) &rpb, sizeof(struct ::NEFS_ROOT_PARTITION_BLOCK)); - ::IoSeekFile(handle, p_prev); + ::IoSeekFile(handle, p_prev); - ::IoCloseFile(handle); + ::IoCloseFile(handle); - handle = nullptr; + handle = nullptr; - return kDISuccessStatus; + return kDISuccessStatus; } \ No newline at end of file diff --git a/public/frameworks/KernelTest.fwrk/headers/KernelTest.h b/public/frameworks/KernelTest.fwrk/headers/KernelTest.h index e3200032..808d127e 100644 --- a/public/frameworks/KernelTest.fwrk/headers/KernelTest.h +++ b/public/frameworks/KernelTest.fwrk/headers/KernelTest.h @@ -1,6 +1,6 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ @@ -12,27 +12,24 @@ /// @file KernelTest.h #define KT_TEST_VERSION_BCD (0x0001) -#define KT_TEST_VERSION "0.0.1" +#define KT_TEST_VERSION "0.0.1" #define KT_TEST_FAILURE (1) #define KT_TEST_SUCCESS (0) #define KT_DECL_TEST(NAME, FN) \ - class KT_##NAME final \ - { \ - public: \ - void Run(); \ - const char* ToString(); \ - }; \ - inline void KT_##NAME::Run() \ - { \ - MUST_PASS(FN() == true); \ - } \ - inline const char* KT_##NAME::ToString() \ - { \ - return #FN; \ - } + class KT_##NAME final { \ + public: \ + void Run(); \ + const char* ToString(); \ + }; \ + inline void KT_##NAME::Run() { \ + MUST_PASS(FN() == true); \ + } \ + inline const char* KT_##NAME::ToString() { \ + return #FN; \ + } KT_DECL_TEST(ALWAYS_BREAK, []() -> bool { return false; }); KT_DECL_TEST(ALWAYS_GOOD, []() -> bool { return true; }); \ No newline at end of file diff --git a/public/tools/cc/src/CommandLine.cc b/public/tools/cc/src/CommandLine.cc index d9420c47..719a1555 100644 --- a/public/tools/cc/src/CommandLine.cc +++ b/public/tools/cc/src/CommandLine.cc @@ -8,8 +8,8 @@ /// @brief Placeholder program. -SInt32 main(SInt32 argc, Char* argv[]) -{ - PrintOut(nullptr, "cc: A C++ compiler to be installed.\rcc: This program is present as a placeholder."); - return EXIT_FAILURE; +SInt32 main(SInt32 argc, Char* argv[]) { + PrintOut(nullptr, + "cc: A C++ compiler to be installed.\rcc: This program is present as a placeholder."); + return EXIT_FAILURE; } diff --git a/public/tools/diutil/src/CommandLine.cc b/public/tools/diutil/src/CommandLine.cc index ef0aaa2e..dd23f532 100644 --- a/public/tools/diutil/src/CommandLine.cc +++ b/public/tools/diutil/src/CommandLine.cc @@ -1,67 +1,58 @@ /* ------------------------------------------- - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - FILE: CommandLine.cc - PURPOSE: DIUTIL CLI. + FILE: CommandLine.cc + PURPOSE: DIUTIL CLI. ------------------------------------------- */ #include static const Char kDiskName[kDIDiskNameLen] = "Empty Disk"; -static SInt32 kDiskSectorSz = kDISectorSz; -static SizeT kDiskSz = gib_cast(4); -static const Char kOutDisk[kDIOutNameLen] = "disk.eimg"; +static SInt32 kDiskSectorSz = kDISectorSz; +static SizeT kDiskSz = gib_cast(4); +static const Char kOutDisk[kDIOutNameLen] = "disk.eimg"; /// @brief Disk Utility entrypoint. -SInt32 _NeMain(SInt32 argc, Char** argv) -{ - for (SInt32 arg = 0; arg < argc; ++arg) - { - const Char* arg_s = argv[arg]; - - if (MmCmpMemory((VoidPtr)arg_s, (VoidPtr) "-diutil-output-name", MmStrLen("-diutil-output-name") == 0)) - { - if ((arg + 1) < argc) - { - MmCopyMemory((VoidPtr)kOutDisk, argv[arg + 1], kDIDiskNameLen); - } - } - else if (MmCmpMemory((VoidPtr)arg_s, (VoidPtr) "-diutil-output-size", MmStrLen("-diutil-output-size") == 0)) - { - if ((arg + 1) < argc) - { - kDiskSz = StrMathToNumber(argv[arg + 1], nullptr, 10); - } - } - else if (MmCmpMemory((VoidPtr)arg_s, (VoidPtr) "-diutil-sector-size", MmStrLen("-diutil-sector-size") == 0)) - { - if ((arg + 1) < argc) - { - kDiskSectorSz = StrMathToNumber(argv[arg + 1], nullptr, 10); - } - } - else if (MmCmpMemory((VoidPtr)arg_s, (VoidPtr) "-diutil-part-name", MmStrLen("-diutil-part-name") == 0)) - { - if ((arg + 1) < argc) - { - MmCopyMemory((VoidPtr)kDiskName, argv[arg + 1], kDIDiskNameLen); - } - } - } - - // create disk image, by appending an EPM partition to it. - - DI::DI_DISK_IMAGE img{}; - - img.disk_sz = kDiskSz; - img.sector_sz = kDiskSectorSz; - img.block_cnt = 0; - - MmCopyMemory((VoidPtr)img.disk_name, (VoidPtr)kDiskName, kDIDiskNameLen); - MmCopyMemory((VoidPtr)img.out_name, (VoidPtr)kOutDisk, kDIDiskNameLen); - - // format disk image to explicit partition map. - return DI::DIFormatPartitionEPM(img); +SInt32 _NeMain(SInt32 argc, Char** argv) { + for (SInt32 arg = 0; arg < argc; ++arg) { + const Char* arg_s = argv[arg]; + + if (MmCmpMemory((VoidPtr) arg_s, (VoidPtr) "-diutil-output-name", + MmStrLen("-diutil-output-name") == 0)) { + if ((arg + 1) < argc) { + MmCopyMemory((VoidPtr) kOutDisk, argv[arg + 1], kDIDiskNameLen); + } + } else if (MmCmpMemory((VoidPtr) arg_s, (VoidPtr) "-diutil-output-size", + MmStrLen("-diutil-output-size") == 0)) { + if ((arg + 1) < argc) { + kDiskSz = StrMathToNumber(argv[arg + 1], nullptr, 10); + } + } else if (MmCmpMemory((VoidPtr) arg_s, (VoidPtr) "-diutil-sector-size", + MmStrLen("-diutil-sector-size") == 0)) { + if ((arg + 1) < argc) { + kDiskSectorSz = StrMathToNumber(argv[arg + 1], nullptr, 10); + } + } else if (MmCmpMemory((VoidPtr) arg_s, (VoidPtr) "-diutil-part-name", + MmStrLen("-diutil-part-name") == 0)) { + if ((arg + 1) < argc) { + MmCopyMemory((VoidPtr) kDiskName, argv[arg + 1], kDIDiskNameLen); + } + } + } + + // create disk image, by appending an EPM partition to it. + + DI::DI_DISK_IMAGE img{}; + + img.disk_sz = kDiskSz; + img.sector_sz = kDiskSectorSz; + img.block_cnt = 0; + + MmCopyMemory((VoidPtr) img.disk_name, (VoidPtr) kDiskName, kDIDiskNameLen); + MmCopyMemory((VoidPtr) img.out_name, (VoidPtr) kOutDisk, kDIDiskNameLen); + + // format disk image to explicit partition map. + return DI::DIFormatPartitionEPM(img); } \ No newline at end of file diff --git a/public/tools/diutil/vendor/Dialogs.h b/public/tools/diutil/vendor/Dialogs.h index fd64026b..ce50b811 100644 --- a/public/tools/diutil/vendor/Dialogs.h +++ b/public/tools/diutil/vendor/Dialogs.h @@ -16,45 +16,45 @@ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif -#include #include -#include -#include // IFileDialog #include +#include +#include // IFileDialog #include -#include // std::async -#include // GetUserProfileDirectory() +#include // GetUserProfileDirectory() +#include +#include // std::async #elif __EMSCRIPTEN__ #include #else #ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 // for popen() +#define _POSIX_C_SOURCE 2 // for popen() #endif #ifdef __APPLE__ #ifndef _DARWIN_C_SOURCE #define _DARWIN_C_SOURCE #endif #endif -#include // popen() -#include // std::getenv() -#include // fcntl() -#include // read(), pipe(), dup2(), getuid() -#include // ::kill, std::signal -#include // stat() -#include // waitpid() -#include // getpwnam() +#include // fcntl() +#include // getpwnam() +#include // stat() +#include // waitpid() +#include // read(), pipe(), dup2(), getuid() +#include // ::kill, std::signal +#include // popen() +#include // std::getenv() #endif -#include // std::string -#include // std::shared_ptr -#include // std::ostream -#include // std::map -#include // std::set -#include // std::regex -#include // std::mutex, std::this_thread -#include // std::chrono +#include // std::chrono +#include // std::ostream +#include // std::map +#include // std::shared_ptr +#include // std::regex +#include // std::set +#include // std::string +#include // std::mutex, std::this_thread // Versions of mingw64 g++ up to 9.3.0 do not have a complete IFileDialog #ifndef PFD_HAS_IFILEDIALOG @@ -67,1915 +67,1672 @@ #endif #endif -namespace pfd -{ - - enum class button - { - cancel = -1, - ok, - yes, - no, - abort, - retry, - ignore, - }; - - enum class choice - { - ok = 0, - ok_cancel, - yes_no, - yes_no_cancel, - retry_cancel, - abort_retry_ignore, - }; - - enum class icon - { - info = 0, - warning, - error, - question, - }; - - // Additional option flags for various dialog constructors - enum class opt : uint8_t - { - none = 0, - // For file open, allow multiselect. - multiselect = 0x1, - // For file save, force overwrite and disable the confirmation dialog. - force_overwrite = 0x2, - // For folder select, force path to be the provided argument instead - // of the last opened directory, which is the Microsoft-recommended, - // user-friendly behaviour. - force_path = 0x4, - }; - - inline opt operator|(opt a, opt b) - { - return opt(uint8_t(a) | uint8_t(b)); - } - inline bool operator&(opt a, opt b) - { - return bool(uint8_t(a) & uint8_t(b)); - } - - // The settings class, only exposing to the user a way to set verbose mode - // and to force a rescan of installed desktop helpers (zenity, kdialog…). - class settings - { - public: - static bool available(); - - static void verbose(bool value); - static void rescan(); - - protected: - explicit settings(bool resync = false); - - bool check_program(std::string const& program); - - inline bool is_osascript() const; - inline bool is_zenity() const; - inline bool is_kdialog() const; - - enum class flag - { - is_scanned = 0, - is_verbose, - - has_zenity, - has_matedialog, - has_qarma, - has_kdialog, - is_vista, - - max_flag, - }; - - // Static array of flags for internal state - bool const& flags(flag in_flag) const; - - // Non-const getter for the static array of flags - bool& flags(flag in_flag); - }; - - // Internal classes, not to be used by client applications - namespace internal - { - - // Process wait timeout, in milliseconds - static int const default_wait_timeout = 20; - - class executor - { - friend class dialog; - - public: - // High level function to get the result of a command - std::string result(int* exit_code = nullptr); - - // High level function to abort - bool kill(); +namespace pfd { + +enum class button { + cancel = -1, + ok, + yes, + no, + abort, + retry, + ignore, +}; + +enum class choice { + ok = 0, + ok_cancel, + yes_no, + yes_no_cancel, + retry_cancel, + abort_retry_ignore, +}; + +enum class icon { + info = 0, + warning, + error, + question, +}; + +// Additional option flags for various dialog constructors +enum class opt : uint8_t { + none = 0, + // For file open, allow multiselect. + multiselect = 0x1, + // For file save, force overwrite and disable the confirmation dialog. + force_overwrite = 0x2, + // For folder select, force path to be the provided argument instead + // of the last opened directory, which is the Microsoft-recommended, + // user-friendly behaviour. + force_path = 0x4, +}; + +inline opt operator|(opt a, opt b) { + return opt(uint8_t(a) | uint8_t(b)); +} +inline bool operator&(opt a, opt b) { + return bool(uint8_t(a) & uint8_t(b)); +} + +// The settings class, only exposing to the user a way to set verbose mode +// and to force a rescan of installed desktop helpers (zenity, kdialog…). +class settings { + public: + static bool available(); + + static void verbose(bool value); + static void rescan(); + + protected: + explicit settings(bool resync = false); + + bool check_program(std::string const& program); + + inline bool is_osascript() const; + inline bool is_zenity() const; + inline bool is_kdialog() const; + + enum class flag { + is_scanned = 0, + is_verbose, + + has_zenity, + has_matedialog, + has_qarma, + has_kdialog, + is_vista, + + max_flag, + }; + + // Static array of flags for internal state + bool const& flags(flag in_flag) const; + + // Non-const getter for the static array of flags + bool& flags(flag in_flag); +}; + +// Internal classes, not to be used by client applications +namespace internal { + + // Process wait timeout, in milliseconds + static int const default_wait_timeout = 20; + + class executor { + friend class dialog; + + public: + // High level function to get the result of a command + std::string result(int* exit_code = nullptr); + + // High level function to abort + bool kill(); #if _WIN32 - void start_func(std::function const& fun); - static BOOL CALLBACK enum_windows_callback(HWND hwnd, LPARAM lParam); + void start_func(std::function const& fun); + static BOOL CALLBACK enum_windows_callback(HWND hwnd, LPARAM lParam); #elif __EMSCRIPTEN__ - void start(int exit_code); + void start(int exit_code); #else - void start_process(std::vector const& command); + void start_process(std::vector const& command); #endif - ~executor(); + ~executor(); - protected: - bool ready(int timeout = default_wait_timeout); - void stop(); + protected: + bool ready(int timeout = default_wait_timeout); + void stop(); - private: - bool m_running = false; - std::string m_stdout; - int m_exit_code = -1; + private: + bool m_running = false; + std::string m_stdout; + int m_exit_code = -1; #if _WIN32 - std::future m_future; - std::set m_windows; - std::condition_variable m_cond; - std::mutex m_mutex; - DWORD m_tid; + std::future m_future; + std::set m_windows; + std::condition_variable m_cond; + std::mutex m_mutex; + DWORD m_tid; #elif __EMSCRIPTEN__ || __NX__ - // FIXME: do something + // FIXME: do something #else - pid_t m_pid = 0; - int m_fd = -1; + pid_t m_pid = 0; + int m_fd = -1; #endif - }; + }; - class platform - { - protected: + class platform { + protected: #if _WIN32 - // Helper class around LoadLibraryA() and GetProcAddress() with some safety - class dll - { - public: - dll(std::string const& name); - ~dll(); - - template - class proc - { - public: - proc(dll const& lib, std::string const& sym) - : m_proc(reinterpret_cast((void*)::GetProcAddress(lib.handle, sym.c_str()))) - { - } - - operator bool() const - { - return m_proc != nullptr; - } - operator T*() const - { - return m_proc; - } - - private: - T* m_proc; - }; - - private: - HMODULE handle; - }; - - // Helper class around CoInitialize() and CoUnInitialize() - class ole32_dll : public dll - { - public: - ole32_dll(); - ~ole32_dll(); - bool is_initialized(); - - private: - HRESULT m_state; - }; - - // Helper class around CreateActCtx() and ActivateActCtx() - class new_style_context - { - public: - new_style_context(); - ~new_style_context(); - - private: - HANDLE create(); - ULONG_PTR m_cookie = 0; - }; + // Helper class around LoadLibraryA() and GetProcAddress() with some safety + class dll { + public: + dll(std::string const& name); + ~dll(); + + template + class proc { + public: + proc(dll const& lib, std::string const& sym) + : m_proc(reinterpret_cast((void*) ::GetProcAddress(lib.handle, sym.c_str()))) {} + + operator bool() const { return m_proc != nullptr; } + operator T*() const { return m_proc; } + + private: + T* m_proc; + }; + + private: + HMODULE handle; + }; + + // Helper class around CoInitialize() and CoUnInitialize() + class ole32_dll : public dll { + public: + ole32_dll(); + ~ole32_dll(); + bool is_initialized(); + + private: + HRESULT m_state; + }; + + // Helper class around CreateActCtx() and ActivateActCtx() + class new_style_context { + public: + new_style_context(); + ~new_style_context(); + + private: + HANDLE create(); + ULONG_PTR m_cookie = 0; + }; #endif - }; - - class dialog : protected settings, protected platform - { - public: - bool ready(int timeout = default_wait_timeout) const; - bool kill() const; - - protected: - explicit dialog(); - - std::vector desktop_helper() const; - static std::string buttons_to_name(choice _choice); - static std::string get_icon_name(icon _icon); - - std::string powershell_quote(std::string const& str) const; - std::string osascript_quote(std::string const& str) const; - std::string shell_quote(std::string const& str) const; - - // Keep handle to executing command - std::shared_ptr m_async; - }; - - class file_dialog : public dialog - { - protected: - enum type - { - open, - save, - folder, - }; - - file_dialog(type in_type, - std::string const& title, - std::string const& default_path = "", - std::vector const& filters = {}, - opt options = opt::none); - - protected: - std::string string_result(); - std::vector vector_result(); + }; + + class dialog : protected settings, protected platform { + public: + bool ready(int timeout = default_wait_timeout) const; + bool kill() const; + + protected: + explicit dialog(); + + std::vector desktop_helper() const; + static std::string buttons_to_name(choice _choice); + static std::string get_icon_name(icon _icon); + + std::string powershell_quote(std::string const& str) const; + std::string osascript_quote(std::string const& str) const; + std::string shell_quote(std::string const& str) const; + + // Keep handle to executing command + std::shared_ptr m_async; + }; + + class file_dialog : public dialog { + protected: + enum type { + open, + save, + folder, + }; + + file_dialog(type in_type, std::string const& title, std::string const& default_path = "", + std::vector const& filters = {}, opt options = opt::none); + + protected: + std::string string_result(); + std::vector vector_result(); #if _WIN32 - static int CALLBACK bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData); + static int CALLBACK bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData); #if PFD_HAS_IFILEDIALOG - std::string select_folder_vista(IFileDialog* ifd, bool force_path); + std::string select_folder_vista(IFileDialog* ifd, bool force_path); #endif - std::wstring m_wtitle; - std::wstring m_wdefault_path; + std::wstring m_wtitle; + std::wstring m_wdefault_path; - std::vector m_vector_result; + std::vector m_vector_result; #endif - }; - - } // namespace internal - - // - // The path class provides some platform-specific path constants - // - - class path : protected internal::platform - { - public: - static std::string home(); - static std::string separator(); - }; - - // - // The notify widget - // - - class notify : public internal::dialog - { - public: - notify(std::string const& title, - std::string const& message, - icon _icon = icon::info); - }; - - // - // The message widget - // - - class message : public internal::dialog - { - public: - message(std::string const& title, - std::string const& text, - choice _choice = choice::ok_cancel, - icon _icon = icon::info); - - button result(); - - private: - // Some extra logic to map the exit code to button number - std::map m_mappings; - }; - - // - // The open_file, save_file, and open_folder widgets - // - - class open_file : public internal::file_dialog - { - public: - open_file(std::string const& title, - std::string const& default_path = "", - std::vector const& filters = {"All Files", "*"}, - opt options = opt::none); + }; + +} // namespace internal + +// +// The path class provides some platform-specific path constants +// + +class path : protected internal::platform { + public: + static std::string home(); + static std::string separator(); +}; + +// +// The notify widget +// + +class notify : public internal::dialog { + public: + notify(std::string const& title, std::string const& message, icon _icon = icon::info); +}; + +// +// The message widget +// + +class message : public internal::dialog { + public: + message(std::string const& title, std::string const& text, choice _choice = choice::ok_cancel, + icon _icon = icon::info); + + button result(); + + private: + // Some extra logic to map the exit code to button number + std::map m_mappings; +}; + +// +// The open_file, save_file, and open_folder widgets +// + +class open_file : public internal::file_dialog { + public: + open_file(std::string const& title, std::string const& default_path = "", + std::vector const& filters = {"All Files", "*"}, opt options = opt::none); #if defined(__has_cpp_attribute) #if __has_cpp_attribute(deprecated) - // Backwards compatibility - [[deprecated("Use pfd::opt::multiselect instead of allow_multiselect")]] + // Backwards compatibility + [[deprecated("Use pfd::opt::multiselect instead of allow_multiselect")]] #endif #endif - open_file(std::string const& title, - std::string const& default_path, - std::vector const& filters, - bool allow_multiselect); - - std::vector result(); - }; - - class save_file : public internal::file_dialog - { - public: - save_file(std::string const& title, - std::string const& default_path = "", - std::vector const& filters = {"All Files", "*"}, - opt options = opt::none); + open_file(std::string const& title, std::string const& default_path, + std::vector const& filters, bool allow_multiselect); + + std::vector result(); +}; + +class save_file : public internal::file_dialog { + public: + save_file(std::string const& title, std::string const& default_path = "", + std::vector const& filters = {"All Files", "*"}, opt options = opt::none); #if defined(__has_cpp_attribute) #if __has_cpp_attribute(deprecated) - // Backwards compatibility - [[deprecated("Use pfd::opt::force_overwrite instead of confirm_overwrite")]] + // Backwards compatibility + [[deprecated("Use pfd::opt::force_overwrite instead of confirm_overwrite")]] #endif #endif - save_file(std::string const& title, - std::string const& default_path, - std::vector const& filters, - bool confirm_overwrite); - - std::string result(); - }; - - class select_folder : public internal::file_dialog - { - public: - select_folder(std::string const& title, - std::string const& default_path = "", - opt options = opt::none); - - std::string result(); - }; - - // - // Below this are all the method implementations. You may choose to define the - // macro PFD_SKIP_IMPLEMENTATION everywhere before including this header except - // in one place. This may reduce compilation times. - // + save_file(std::string const& title, std::string const& default_path, + std::vector const& filters, bool confirm_overwrite); + + std::string result(); +}; + +class select_folder : public internal::file_dialog { + public: + select_folder(std::string const& title, std::string const& default_path = "", + opt options = opt::none); + + std::string result(); +}; + +// +// Below this are all the method implementations. You may choose to define the +// macro PFD_SKIP_IMPLEMENTATION everywhere before including this header except +// in one place. This may reduce compilation times. +// #if !defined PFD_SKIP_IMPLEMENTATION - // internal free functions implementations +// internal free functions implementations - namespace internal - { +namespace internal { #if _WIN32 - static inline std::wstring str2wstr(std::string const& str) - { - int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0); - std::wstring ret(len, '\0'); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), (LPWSTR)ret.data(), (int)ret.size()); - return ret; - } - - static inline std::string wstr2str(std::wstring const& str) - { - int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0, nullptr, nullptr); - std::string ret(len, '\0'); - WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int)str.size(), (LPSTR)ret.data(), (int)ret.size(), nullptr, nullptr); - return ret; - } - - static inline bool is_vista() - { - OSVERSIONINFOEXW osvi; - memset(&osvi, 0, sizeof(osvi)); - DWORDLONG const mask = VerSetConditionMask( - VerSetConditionMask( - VerSetConditionMask( - 0, VER_MAJORVERSION, VER_GREATER_EQUAL), - VER_MINORVERSION, VER_GREATER_EQUAL), - VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - osvi.dwOSVersionInfoSize = sizeof(osvi); - osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA); - osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA); - osvi.wServicePackMajor = 0; - - return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, mask) != FALSE; - } + static inline std::wstring str2wstr(std::string const& str) { + int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int) str.size(), nullptr, 0); + std::wstring ret(len, '\0'); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int) str.size(), (LPWSTR) ret.data(), + (int) ret.size()); + return ret; + } + + static inline std::string wstr2str(std::wstring const& str) { + int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int) str.size(), nullptr, 0, nullptr, + nullptr); + std::string ret(len, '\0'); + WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (int) str.size(), (LPSTR) ret.data(), + (int) ret.size(), nullptr, nullptr); + return ret; + } + + static inline bool is_vista() { + OSVERSIONINFOEXW osvi; + memset(&osvi, 0, sizeof(osvi)); + DWORDLONG const mask = VerSetConditionMask( + VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + osvi.dwOSVersionInfoSize = sizeof(osvi); + osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA); + osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA); + osvi.wServicePackMajor = 0; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, + mask) != FALSE; + } #endif - // This is necessary until C++20 which will have std::string::ends_with() etc. + // This is necessary until C++20 which will have std::string::ends_with() etc. - static inline bool ends_with(std::string const& str, std::string const& suffix) - { - return suffix.size() <= str.size() && - str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; - } + static inline bool ends_with(std::string const& str, std::string const& suffix) { + return suffix.size() <= str.size() && + str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; + } - static inline bool starts_with(std::string const& str, std::string const& prefix) - { - return prefix.size() <= str.size() && - str.compare(0, prefix.size(), prefix) == 0; - } + static inline bool starts_with(std::string const& str, std::string const& prefix) { + return prefix.size() <= str.size() && str.compare(0, prefix.size(), prefix) == 0; + } - // This is necessary until C++17 which will have std::filesystem::is_directory + // This is necessary until C++17 which will have std::filesystem::is_directory - static inline bool is_directory(std::string const& path) - { + static inline bool is_directory(std::string const& path) { #if _WIN32 - auto attr = GetFileAttributesA(path.c_str()); - return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY); + auto attr = GetFileAttributesA(path.c_str()); + return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY); #elif __EMSCRIPTEN__ - // TODO - return false; + // TODO + return false; #else - struct stat s; - return stat(path.c_str(), &s) == 0 && S_ISDIR(s.st_mode); + struct stat s; + return stat(path.c_str(), &s) == 0 && S_ISDIR(s.st_mode); #endif - } + } - // This is necessary because getenv is not thread-safe + // This is necessary because getenv is not thread-safe - static inline std::string getenv(std::string const& str) - { + static inline std::string getenv(std::string const& str) { #if _MSC_VER - char* buf = nullptr; - size_t size = 0; - if (_dupenv_s(&buf, &size, str.c_str()) == 0 && buf) - { - std::string ret(buf); - free(buf); - return ret; - } - return ""; + char* buf = nullptr; + size_t size = 0; + if (_dupenv_s(&buf, &size, str.c_str()) == 0 && buf) { + std::string ret(buf); + free(buf); + return ret; + } + return ""; #else - auto buf = std::getenv(str.c_str()); - return buf ? buf : ""; + auto buf = std::getenv(str.c_str()); + return buf ? buf : ""; #endif - } + } - } // namespace internal +} // namespace internal - // settings implementation +// settings implementation - inline settings::settings(bool resync) - { - flags(flag::is_scanned) &= !resync; +inline settings::settings(bool resync) { + flags(flag::is_scanned) &= !resync; - if (flags(flag::is_scanned)) - return; + if (flags(flag::is_scanned)) return; - auto pfd_verbose = internal::getenv("PFD_VERBOSE"); - auto match_no = std::regex("(|0|no|false)", std::regex_constants::icase); - if (!std::regex_match(pfd_verbose, match_no)) - flags(flag::is_verbose) = true; + auto pfd_verbose = internal::getenv("PFD_VERBOSE"); + auto match_no = std::regex("(|0|no|false)", std::regex_constants::icase); + if (!std::regex_match(pfd_verbose, match_no)) flags(flag::is_verbose) = true; #if _WIN32 - flags(flag::is_vista) = internal::is_vista(); + flags(flag::is_vista) = internal::is_vista(); #elif !__APPLE__ - flags(flag::has_zenity) = check_program("zenity"); - flags(flag::has_matedialog) = check_program("matedialog"); - flags(flag::has_qarma) = check_program("qarma"); - flags(flag::has_kdialog) = check_program("kdialog"); - - // If multiple helpers are available, try to default to the best one - if (flags(flag::has_zenity) && flags(flag::has_kdialog)) - { - auto desktop_name = internal::getenv("XDG_SESSION_DESKTOP"); - if (desktop_name == std::string("gnome")) - flags(flag::has_kdialog) = false; - else if (desktop_name == std::string("KDE")) - flags(flag::has_zenity) = false; - } + flags(flag::has_zenity) = check_program("zenity"); + flags(flag::has_matedialog) = check_program("matedialog"); + flags(flag::has_qarma) = check_program("qarma"); + flags(flag::has_kdialog) = check_program("kdialog"); + + // If multiple helpers are available, try to default to the best one + if (flags(flag::has_zenity) && flags(flag::has_kdialog)) { + auto desktop_name = internal::getenv("XDG_SESSION_DESKTOP"); + if (desktop_name == std::string("gnome")) + flags(flag::has_kdialog) = false; + else if (desktop_name == std::string("KDE")) + flags(flag::has_zenity) = false; + } #endif - flags(flag::is_scanned) = true; - } + flags(flag::is_scanned) = true; +} - inline bool settings::available() - { +inline bool settings::available() { #if _WIN32 - return true; + return true; #elif __APPLE__ - return true; + return true; #elif __EMSCRIPTEN__ - // FIXME: Return true after implementation is complete. - return false; + // FIXME: Return true after implementation is complete. + return false; #else - settings tmp; - return tmp.flags(flag::has_zenity) || - tmp.flags(flag::has_matedialog) || - tmp.flags(flag::has_qarma) || - tmp.flags(flag::has_kdialog); + settings tmp; + return tmp.flags(flag::has_zenity) || tmp.flags(flag::has_matedialog) || + tmp.flags(flag::has_qarma) || tmp.flags(flag::has_kdialog); #endif - } +} - inline void settings::verbose(bool value) - { - settings().flags(flag::is_verbose) = value; - } +inline void settings::verbose(bool value) { + settings().flags(flag::is_verbose) = value; +} - inline void settings::rescan() - { - settings(/* resync = */ true); - } +inline void settings::rescan() { + settings(/* resync = */ true); +} - // Check whether a program is present using “which”. - inline bool settings::check_program(std::string const& program) - { +// Check whether a program is present using “which”. +inline bool settings::check_program(std::string const& program) { #if _WIN32 - (void)program; - return false; + (void) program; + return false; #elif __EMSCRIPTEN__ - (void)program; - return false; + (void) program; + return false; #else - int exit_code = -1; - internal::executor async; - async.start_process({"/bin/sh", "-c", "which " + program}); - async.result(&exit_code); - return exit_code == 0; + int exit_code = -1; + internal::executor async; + async.start_process({"/bin/sh", "-c", "which " + program}); + async.result(&exit_code); + return exit_code == 0; #endif - } +} - inline bool settings::is_osascript() const - { +inline bool settings::is_osascript() const { #if __APPLE__ - return true; + return true; #else - return false; + return false; #endif - } - - inline bool settings::is_zenity() const - { - return flags(flag::has_zenity) || - flags(flag::has_matedialog) || - flags(flag::has_qarma); - } - - inline bool settings::is_kdialog() const - { - return flags(flag::has_kdialog); - } - - inline bool const& settings::flags(flag in_flag) const - { - static bool flags[size_t(flag::max_flag)]; - return flags[size_t(in_flag)]; - } - - inline bool& settings::flags(flag in_flag) - { - return const_cast(static_cast(this)->flags(in_flag)); - } - - // path implementation - inline std::string path::home() - { +} + +inline bool settings::is_zenity() const { + return flags(flag::has_zenity) || flags(flag::has_matedialog) || flags(flag::has_qarma); +} + +inline bool settings::is_kdialog() const { + return flags(flag::has_kdialog); +} + +inline bool const& settings::flags(flag in_flag) const { + static bool flags[size_t(flag::max_flag)]; + return flags[size_t(in_flag)]; +} + +inline bool& settings::flags(flag in_flag) { + return const_cast(static_cast(this)->flags(in_flag)); +} + +// path implementation +inline std::string path::home() { #if _WIN32 - // First try the USERPROFILE environment variable - auto user_profile = internal::getenv("USERPROFILE"); - if (user_profile.size() > 0) - return user_profile; - // Otherwise, try GetUserProfileDirectory() - HANDLE token = nullptr; - DWORD len = MAX_PATH; - char buf[MAX_PATH] = {'\0'}; - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) - { - dll userenv("userenv.dll"); - dll::proc get_user_profile_directory(userenv, "GetUserProfileDirectoryA"); - get_user_profile_directory(token, buf, &len); - CloseHandle(token); - if (*buf) - return buf; - } + // First try the USERPROFILE environment variable + auto user_profile = internal::getenv("USERPROFILE"); + if (user_profile.size() > 0) return user_profile; + // Otherwise, try GetUserProfileDirectory() + HANDLE token = nullptr; + DWORD len = MAX_PATH; + char buf[MAX_PATH] = {'\0'}; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { + dll userenv("userenv.dll"); + dll::proc get_user_profile_directory( + userenv, "GetUserProfileDirectoryA"); + get_user_profile_directory(token, buf, &len); + CloseHandle(token); + if (*buf) return buf; + } #elif __EMSCRIPTEN__ - return "/"; + return "/"; #else - // First try the HOME environment variable - auto home = internal::getenv("HOME"); - if (home.size() > 0) - return home; - // Otherwise, try getpwuid_r() - size_t len = 4096; + // First try the HOME environment variable + auto home = internal::getenv("HOME"); + if (home.size() > 0) return home; + // Otherwise, try getpwuid_r() + size_t len = 4096; #if defined(_SC_GETPW_R_SIZE_MAX) - auto size_max = sysconf(_SC_GETPW_R_SIZE_MAX); - if (size_max != -1) - len = size_t(size_max); + auto size_max = sysconf(_SC_GETPW_R_SIZE_MAX); + if (size_max != -1) len = size_t(size_max); #endif - std::vector buf(len); - struct passwd pwd, *result; - if (getpwuid_r(getuid(), &pwd, buf.data(), buf.size(), &result) == 0) - return result->pw_dir; + std::vector buf(len); + struct passwd pwd, *result; + if (getpwuid_r(getuid(), &pwd, buf.data(), buf.size(), &result) == 0) return result->pw_dir; #endif - return "/"; - } + return "/"; +} - inline std::string path::separator() - { +inline std::string path::separator() { #if _WIN32 - return "\\"; + return "\\"; #else - return "/"; + return "/"; #endif - } +} - // executor implementation +// executor implementation - inline std::string internal::executor::result(int* exit_code /* = nullptr */) - { - stop(); - if (exit_code) - *exit_code = m_exit_code; - return m_stdout; - } +inline std::string internal::executor::result(int* exit_code /* = nullptr */) { + stop(); + if (exit_code) *exit_code = m_exit_code; + return m_stdout; +} - inline bool internal::executor::kill() - { +inline bool internal::executor::kill() { #if _WIN32 - if (m_future.valid()) - { - // Close all windows that weren’t open when we started the future - auto previous_windows = m_windows; - EnumWindows(&enum_windows_callback, (LPARAM)this); - for (auto hwnd : m_windows) - if (previous_windows.find(hwnd) == previous_windows.end()) - { - SendMessage(hwnd, WM_CLOSE, 0, 0); - // Also send IDNO in case of a Yes/No or Abort/Retry/Ignore messagebox - SendMessage(hwnd, WM_COMMAND, IDNO, 0); - } - } + if (m_future.valid()) { + // Close all windows that weren’t open when we started the future + auto previous_windows = m_windows; + EnumWindows(&enum_windows_callback, (LPARAM) this); + for (auto hwnd : m_windows) + if (previous_windows.find(hwnd) == previous_windows.end()) { + SendMessage(hwnd, WM_CLOSE, 0, 0); + // Also send IDNO in case of a Yes/No or Abort/Retry/Ignore messagebox + SendMessage(hwnd, WM_COMMAND, IDNO, 0); + } + } #elif __EMSCRIPTEN__ || __NX__ - // FIXME: do something - return false; // cannot kill + // FIXME: do something + return false; // cannot kill #else - ::kill(m_pid, SIGKILL); + ::kill(m_pid, SIGKILL); #endif - stop(); - return true; - } + stop(); + return true; +} #if _WIN32 - inline BOOL CALLBACK internal::executor::enum_windows_callback(HWND hwnd, LPARAM lParam) - { - auto that = (executor*)lParam; - - DWORD pid; - auto tid = GetWindowThreadProcessId(hwnd, &pid); - if (tid == that->m_tid) - that->m_windows.insert(hwnd); - return TRUE; - } +inline BOOL CALLBACK internal::executor::enum_windows_callback(HWND hwnd, LPARAM lParam) { + auto that = (executor*) lParam; + + DWORD pid; + auto tid = GetWindowThreadProcessId(hwnd, &pid); + if (tid == that->m_tid) that->m_windows.insert(hwnd); + return TRUE; +} #endif #if _WIN32 - inline void internal::executor::start_func(std::function const& fun) - { - stop(); - - auto trampoline = [fun, this]() { - // Save our thread id so that the caller can cancel us - m_tid = GetCurrentThreadId(); - EnumWindows(&enum_windows_callback, (LPARAM)this); - m_cond.notify_all(); - return fun(&m_exit_code); - }; - - std::unique_lock lock(m_mutex); - m_future = std::async(std::launch::async, trampoline); - m_cond.wait(lock); - m_running = true; - } +inline void internal::executor::start_func(std::function const& fun) { + stop(); + + auto trampoline = [fun, this]() { + // Save our thread id so that the caller can cancel us + m_tid = GetCurrentThreadId(); + EnumWindows(&enum_windows_callback, (LPARAM) this); + m_cond.notify_all(); + return fun(&m_exit_code); + }; + + std::unique_lock lock(m_mutex); + m_future = std::async(std::launch::async, trampoline); + m_cond.wait(lock); + m_running = true; +} #elif __EMSCRIPTEN__ - inline void internal::executor::start(int exit_code) - { - m_exit_code = exit_code; - } +inline void internal::executor::start(int exit_code) { + m_exit_code = exit_code; +} #else - inline void internal::executor::start_process(std::vector const& command) - { - stop(); - m_stdout.clear(); - m_exit_code = -1; - - int in[2], out[2]; - if (pipe(in) != 0 || pipe(out) != 0) - return; - - m_pid = fork(); - if (m_pid < 0) - return; - - close(in[m_pid ? 0 : 1]); - close(out[m_pid ? 1 : 0]); - - if (m_pid == 0) - { - dup2(in[0], STDIN_FILENO); - dup2(out[1], STDOUT_FILENO); - - // Ignore stderr so that it doesn’t pollute the console (e.g. GTK+ errors from zenity) - int fd = open("/dev/null", O_WRONLY); - dup2(fd, STDERR_FILENO); - close(fd); - - std::vector args; - std::transform(command.cbegin(), command.cend(), std::back_inserter(args), - [](std::string const& s) { return const_cast(s.c_str()); }); - args.push_back(nullptr); // null-terminate argv[] - - execvp(args[0], args.data()); - exit(1); - } - - close(in[1]); - m_fd = out[0]; - auto flags = fcntl(m_fd, F_GETFL); - fcntl(m_fd, F_SETFL, flags | O_NONBLOCK); - - m_running = true; - } +inline void internal::executor::start_process(std::vector const& command) { + stop(); + m_stdout.clear(); + m_exit_code = -1; + + int in[2], out[2]; + if (pipe(in) != 0 || pipe(out) != 0) return; + + m_pid = fork(); + if (m_pid < 0) return; + + close(in[m_pid ? 0 : 1]); + close(out[m_pid ? 1 : 0]); + + if (m_pid == 0) { + dup2(in[0], STDIN_FILENO); + dup2(out[1], STDOUT_FILENO); + + // Ignore stderr so that it doesn’t pollute the console (e.g. GTK+ errors from zenity) + int fd = open("/dev/null", O_WRONLY); + dup2(fd, STDERR_FILENO); + close(fd); + + std::vector args; + std::transform(command.cbegin(), command.cend(), std::back_inserter(args), + [](std::string const& s) { return const_cast(s.c_str()); }); + args.push_back(nullptr); // null-terminate argv[] + + execvp(args[0], args.data()); + exit(1); + } + + close(in[1]); + m_fd = out[0]; + auto flags = fcntl(m_fd, F_GETFL); + fcntl(m_fd, F_SETFL, flags | O_NONBLOCK); + + m_running = true; +} #endif - inline internal::executor::~executor() - { - stop(); - } +inline internal::executor::~executor() { + stop(); +} - inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) - { - if (!m_running) - return true; +inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) { + if (!m_running) return true; #if _WIN32 - if (m_future.valid()) - { - auto status = m_future.wait_for(std::chrono::milliseconds(timeout)); - if (status != std::future_status::ready) - { - // On Windows, we need to run the message pump. If the async - // thread uses a Windows API dialog, it may be attached to the - // main thread and waiting for messages that only we can dispatch. - MSG msg; - while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return false; - } - - m_stdout = m_future.get(); - } + if (m_future.valid()) { + auto status = m_future.wait_for(std::chrono::milliseconds(timeout)); + if (status != std::future_status::ready) { + // On Windows, we need to run the message pump. If the async + // thread uses a Windows API dialog, it may be attached to the + // main thread and waiting for messages that only we can dispatch. + MSG msg; + while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return false; + } + + m_stdout = m_future.get(); + } #elif __EMSCRIPTEN__ || __NX__ - // FIXME: do something - (void)timeout; + // FIXME: do something + (void) timeout; #else - char buf[BUFSIZ]; - ssize_t received = read(m_fd, buf, BUFSIZ); // Flawfinder: ignore - if (received > 0) - { - m_stdout += std::string(buf, received); - return false; - } - - // Reap child process if it is dead. It is possible that the system has already reaped it - // (this happens when the calling application handles or ignores SIG_CHLD) and results in - // waitpid() failing with ECHILD. Otherwise we assume the child is running and we sleep for - // a little while. - int status; - pid_t child = waitpid(m_pid, &status, WNOHANG); - if (child != m_pid && (child >= 0 || errno != ECHILD)) - { - // FIXME: this happens almost always at first iteration - std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); - return false; - } - - close(m_fd); - m_exit_code = WEXITSTATUS(status); + char buf[BUFSIZ]; + ssize_t received = read(m_fd, buf, BUFSIZ); // Flawfinder: ignore + if (received > 0) { + m_stdout += std::string(buf, received); + return false; + } + + // Reap child process if it is dead. It is possible that the system has already reaped it + // (this happens when the calling application handles or ignores SIG_CHLD) and results in + // waitpid() failing with ECHILD. Otherwise we assume the child is running and we sleep for + // a little while. + int status; + pid_t child = waitpid(m_pid, &status, WNOHANG); + if (child != m_pid && (child >= 0 || errno != ECHILD)) { + // FIXME: this happens almost always at first iteration + std::this_thread::sleep_for(std::chrono::milliseconds(timeout)); + return false; + } + + close(m_fd); + m_exit_code = WEXITSTATUS(status); #endif - m_running = false; - return true; - } + m_running = false; + return true; +} - inline void internal::executor::stop() - { - // Loop until the user closes the dialog - while (!ready()) - ; - } +inline void internal::executor::stop() { + // Loop until the user closes the dialog + while (!ready()); +} - // dll implementation +// dll implementation #if _WIN32 - inline internal::platform::dll::dll(std::string const& name) - : handle(::LoadLibraryA(name.c_str())) - { - } +inline internal::platform::dll::dll(std::string const& name) + : handle(::LoadLibraryA(name.c_str())) {} - inline internal::platform::dll::~dll() - { - if (handle) - ::FreeLibrary(handle); - } -#endif // _WIN32 +inline internal::platform::dll::~dll() { + if (handle) ::FreeLibrary(handle); +} +#endif // _WIN32 - // ole32_dll implementation +// ole32_dll implementation #if _WIN32 - inline internal::platform::ole32_dll::ole32_dll() - : dll("ole32.dll") - { - // Use COINIT_MULTITHREADED because COINIT_APARTMENTTHREADED causes crashes. - // See https://github.com/samhocevar/portable-file-dialogs/issues/51 - auto coinit = proc(*this, "CoInitializeEx"); - m_state = coinit(nullptr, COINIT_MULTITHREADED); - } - - inline internal::platform::ole32_dll::~ole32_dll() - { - if (is_initialized()) - proc(*this, "CoUninitialize")(); - } - - inline bool internal::platform::ole32_dll::is_initialized() - { - return m_state == S_OK || m_state == S_FALSE; - } +inline internal::platform::ole32_dll::ole32_dll() : dll("ole32.dll") { + // Use COINIT_MULTITHREADED because COINIT_APARTMENTTHREADED causes crashes. + // See https://github.com/samhocevar/portable-file-dialogs/issues/51 + auto coinit = proc(*this, "CoInitializeEx"); + m_state = coinit(nullptr, COINIT_MULTITHREADED); +} + +inline internal::platform::ole32_dll::~ole32_dll() { + if (is_initialized()) proc(*this, "CoUninitialize")(); +} + +inline bool internal::platform::ole32_dll::is_initialized() { + return m_state == S_OK || m_state == S_FALSE; +} #endif - // new_style_context implementation +// new_style_context implementation #if _WIN32 - inline internal::platform::new_style_context::new_style_context() - { - // Only create one activation context for the whole app lifetime. - static HANDLE hctx = create(); - - if (hctx != INVALID_HANDLE_VALUE) - ActivateActCtx(hctx, &m_cookie); - } - - inline internal::platform::new_style_context::~new_style_context() - { - DeactivateActCtx(0, m_cookie); - } - - inline HANDLE internal::platform::new_style_context::create() - { - // This “hack” seems to be necessary for this code to work on windows XP. - // Without it, dialogs do not show and close immediately. GetError() - // returns 0 so I don’t know what causes this. I was not able to reproduce - // this behavior on Windows 7 and 10 but just in case, let it be here for - // those versions too. - // This hack is not required if other dialogs are used (they load comdlg32 - // automatically), only if message boxes are used. - dll comdlg32("comdlg32.dll"); - - // Using approach as shown here: https://stackoverflow.com/a/10444161 - UINT len = ::GetSystemDirectoryA(nullptr, 0); - std::string sys_dir(len, '\0'); - ::GetSystemDirectoryA(&sys_dir[0], len); - - ACTCTXA act_ctx = - { - // Do not set flag ACTCTX_FLAG_SET_PROCESS_DEFAULT, since it causes a - // crash with error “default context is already set”. - sizeof(act_ctx), - ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID, - "shell32.dll", - 0, - 0, - sys_dir.c_str(), - (LPCSTR)124, - nullptr, - 0, - }; - - return ::CreateActCtxA(&act_ctx); - } -#endif // _WIN32 - - // dialog implementation - - inline bool internal::dialog::ready(int timeout /* = default_wait_timeout */) const - { - return m_async->ready(timeout); - } - - inline bool internal::dialog::kill() const - { - return m_async->kill(); - } - - inline internal::dialog::dialog() - : m_async(std::make_shared()) - { - } - - inline std::vector internal::dialog::desktop_helper() const - { +inline internal::platform::new_style_context::new_style_context() { + // Only create one activation context for the whole app lifetime. + static HANDLE hctx = create(); + + if (hctx != INVALID_HANDLE_VALUE) ActivateActCtx(hctx, &m_cookie); +} + +inline internal::platform::new_style_context::~new_style_context() { + DeactivateActCtx(0, m_cookie); +} + +inline HANDLE internal::platform::new_style_context::create() { + // This “hack” seems to be necessary for this code to work on windows XP. + // Without it, dialogs do not show and close immediately. GetError() + // returns 0 so I don’t know what causes this. I was not able to reproduce + // this behavior on Windows 7 and 10 but just in case, let it be here for + // those versions too. + // This hack is not required if other dialogs are used (they load comdlg32 + // automatically), only if message boxes are used. + dll comdlg32("comdlg32.dll"); + + // Using approach as shown here: https://stackoverflow.com/a/10444161 + UINT len = ::GetSystemDirectoryA(nullptr, 0); + std::string sys_dir(len, '\0'); + ::GetSystemDirectoryA(&sys_dir[0], len); + + ACTCTXA act_ctx = { + // Do not set flag ACTCTX_FLAG_SET_PROCESS_DEFAULT, since it causes a + // crash with error “default context is already set”. + sizeof(act_ctx), + ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID, + "shell32.dll", + 0, + 0, + sys_dir.c_str(), + (LPCSTR) 124, + nullptr, + 0, + }; + + return ::CreateActCtxA(&act_ctx); +} +#endif // _WIN32 + +// dialog implementation + +inline bool internal::dialog::ready(int timeout /* = default_wait_timeout */) const { + return m_async->ready(timeout); +} + +inline bool internal::dialog::kill() const { + return m_async->kill(); +} + +inline internal::dialog::dialog() : m_async(std::make_shared()) {} + +inline std::vector internal::dialog::desktop_helper() const { #if __APPLE__ - return {"osascript"}; + return {"osascript"}; #else - return {flags(flag::has_zenity) ? "zenity" - : flags(flag::has_matedialog) ? "matedialog" - : flags(flag::has_qarma) ? "qarma" - : flags(flag::has_kdialog) ? "kdialog" - : "echo"}; + return {flags(flag::has_zenity) ? "zenity" + : flags(flag::has_matedialog) ? "matedialog" + : flags(flag::has_qarma) ? "qarma" + : flags(flag::has_kdialog) ? "kdialog" + : "echo"}; #endif - } - - inline std::string internal::dialog::buttons_to_name(choice _choice) - { - switch (_choice) - { - case choice::ok_cancel: - return "okcancel"; - case choice::yes_no: - return "yesno"; - case choice::yes_no_cancel: - return "yesnocancel"; - case choice::retry_cancel: - return "retrycancel"; - case choice::abort_retry_ignore: - return "abortretryignore"; - /* case choice::ok: */ default: - return "ok"; - } - } - - inline std::string internal::dialog::get_icon_name(icon _icon) - { - switch (_icon) - { - case icon::warning: - return "warning"; - case icon::error: - return "error"; - case icon::question: - return "question"; - // Zenity wants "information" but WinForms wants "info" - /* case icon::info: */ default: +} + +inline std::string internal::dialog::buttons_to_name(choice _choice) { + switch (_choice) { + case choice::ok_cancel: + return "okcancel"; + case choice::yes_no: + return "yesno"; + case choice::yes_no_cancel: + return "yesnocancel"; + case choice::retry_cancel: + return "retrycancel"; + case choice::abort_retry_ignore: + return "abortretryignore"; + /* case choice::ok: */ default: + return "ok"; + } +} + +inline std::string internal::dialog::get_icon_name(icon _icon) { + switch (_icon) { + case icon::warning: + return "warning"; + case icon::error: + return "error"; + case icon::question: + return "question"; + // Zenity wants "information" but WinForms wants "info" + /* case icon::info: */ default: #if _WIN32 - return "info"; + return "info"; #else - return "information"; + return "information"; #endif - } - } - - // This is only used for debugging purposes - inline std::ostream& operator<<(std::ostream& s, std::vector const& v) - { - int not_first = 0; - for (auto& e : v) - s << (not_first++ ? " " : "") << e; - return s; - } - - // Properly quote a string for Powershell: replace ' or " with '' or "" - // FIXME: we should probably get rid of newlines! - // FIXME: the \" sequence seems unsafe, too! - // XXX: this is no longer used but I would like to keep it around just in case - inline std::string internal::dialog::powershell_quote(std::string const& str) const - { - return "'" + std::regex_replace(str, std::regex("['\"]"), "$&$&") + "'"; - } - - // Properly quote a string for osascript: replace \ or " with \\ or \" - // XXX: this also used to replace ' with \' when popen was used, but it would be - // smarter to do shell_quote(osascript_quote(...)) if this is needed again. - inline std::string internal::dialog::osascript_quote(std::string const& str) const - { - return "\"" + std::regex_replace(str, std::regex("[\\\\\"]"), "\\$&") + "\""; - } - - // Properly quote a string for the shell: just replace ' with '\'' - // XXX: this is no longer used but I would like to keep it around just in case - inline std::string internal::dialog::shell_quote(std::string const& str) const - { - return "'" + std::regex_replace(str, std::regex("'"), "'\\''") + "'"; - } - - // file_dialog implementation - - inline internal::file_dialog::file_dialog(type in_type, - std::string const& title, - std::string const& default_path /* = "" */, - std::vector const& filters /* = {} */, - opt options /* = opt::none */) - { + } +} + +// This is only used for debugging purposes +inline std::ostream& operator<<(std::ostream& s, std::vector const& v) { + int not_first = 0; + for (auto& e : v) s << (not_first++ ? " " : "") << e; + return s; +} + +// Properly quote a string for Powershell: replace ' or " with '' or "" +// FIXME: we should probably get rid of newlines! +// FIXME: the \" sequence seems unsafe, too! +// XXX: this is no longer used but I would like to keep it around just in case +inline std::string internal::dialog::powershell_quote(std::string const& str) const { + return "'" + std::regex_replace(str, std::regex("['\"]"), "$&$&") + "'"; +} + +// Properly quote a string for osascript: replace \ or " with \\ or \" +// XXX: this also used to replace ' with \' when popen was used, but it would be +// smarter to do shell_quote(osascript_quote(...)) if this is needed again. +inline std::string internal::dialog::osascript_quote(std::string const& str) const { + return "\"" + std::regex_replace(str, std::regex("[\\\\\"]"), "\\$&") + "\""; +} + +// Properly quote a string for the shell: just replace ' with '\'' +// XXX: this is no longer used but I would like to keep it around just in case +inline std::string internal::dialog::shell_quote(std::string const& str) const { + return "'" + std::regex_replace(str, std::regex("'"), "'\\''") + "'"; +} + +// file_dialog implementation + +inline internal::file_dialog::file_dialog(type in_type, std::string const& title, + std::string const& default_path /* = "" */, + std::vector const& filters /* = {} */, + opt options /* = opt::none */) { #if _WIN32 - std::string filter_list; - std::regex whitespace(" *"); - for (size_t i = 0; i + 1 < filters.size(); i += 2) - { - filter_list += filters[i] + '\0'; - filter_list += std::regex_replace(filters[i + 1], whitespace, ";") + '\0'; - } - filter_list += '\0'; - - m_async->start_func([this, in_type, title, default_path, filter_list, - options](int* exit_code) -> std::string { - (void)exit_code; - m_wtitle = internal::str2wstr(title); - m_wdefault_path = internal::str2wstr(default_path); - auto wfilter_list = internal::str2wstr(filter_list); - - // Initialise COM. This is required for the new folder selection window, - // (see https://github.com/samhocevar/portable-file-dialogs/pull/21) - // and to avoid random crashes with GetOpenFileNameW() (see - // https://github.com/samhocevar/portable-file-dialogs/issues/51) - ole32_dll ole32; - - // Folder selection uses a different method - if (in_type == type::folder) - { + std::string filter_list; + std::regex whitespace(" *"); + for (size_t i = 0; i + 1 < filters.size(); i += 2) { + filter_list += filters[i] + '\0'; + filter_list += std::regex_replace(filters[i + 1], whitespace, ";") + '\0'; + } + filter_list += '\0'; + + m_async->start_func( + [this, in_type, title, default_path, filter_list, options](int* exit_code) -> std::string { + (void) exit_code; + m_wtitle = internal::str2wstr(title); + m_wdefault_path = internal::str2wstr(default_path); + auto wfilter_list = internal::str2wstr(filter_list); + + // Initialise COM. This is required for the new folder selection window, + // (see https://github.com/samhocevar/portable-file-dialogs/pull/21) + // and to avoid random crashes with GetOpenFileNameW() (see + // https://github.com/samhocevar/portable-file-dialogs/issues/51) + ole32_dll ole32; + + // Folder selection uses a different method + if (in_type == type::folder) { #if PFD_HAS_IFILEDIALOG - if (flags(flag::is_vista)) - { - // On Vista and higher we should be able to use IFileDialog for folder selection - IFileDialog* ifd; - HRESULT hr = dll::proc(ole32, "CoCreateInstance")(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ifd)); - - // In case CoCreateInstance fails (which it should not), try legacy approach - if (SUCCEEDED(hr)) - return select_folder_vista(ifd, options & opt::force_path); - } + if (flags(flag::is_vista)) { + // On Vista and higher we should be able to use IFileDialog for folder selection + IFileDialog* ifd; + HRESULT hr = dll::proc( + ole32, "CoCreateInstance")(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&ifd)); + + // In case CoCreateInstance fails (which it should not), try legacy approach + if (SUCCEEDED(hr)) return select_folder_vista(ifd, options & opt::force_path); + } #endif - BROWSEINFOW bi; - memset(&bi, 0, sizeof(bi)); - - bi.lpfn = &bffcallback; - bi.lParam = (LPARAM)this; - - if (flags(flag::is_vista)) - { - if (ole32.is_initialized()) - bi.ulFlags |= BIF_NEWDIALOGSTYLE; - bi.ulFlags |= BIF_EDITBOX; - bi.ulFlags |= BIF_STATUSTEXT; - } - - auto* list = SHBrowseForFolderW(&bi); - std::string ret; - if (list) - { - auto buffer = new wchar_t[MAX_PATH]; - SHGetPathFromIDListW(list, buffer); - dll::proc(ole32, "CoTaskMemFree")(list); - ret = internal::wstr2str(buffer); - delete[] buffer; - } - return ret; - } - - OPENFILENAMEW ofn; - memset(&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(OPENFILENAMEW); - ofn.hwndOwner = GetActiveWindow(); - - ofn.lpstrFilter = wfilter_list.c_str(); - - auto woutput = std::wstring(MAX_PATH * 256, L'\0'); - ofn.lpstrFile = (LPWSTR)woutput.data(); - ofn.nMaxFile = (DWORD)woutput.size(); - if (!m_wdefault_path.empty()) - { - // If a directory was provided, use it as the initial directory. If - // a valid path was provided, use it as the initial file. Otherwise, - // let the Windows API decide. - auto path_attr = GetFileAttributesW(m_wdefault_path.c_str()); - if (path_attr != INVALID_FILE_ATTRIBUTES && (path_attr & FILE_ATTRIBUTE_DIRECTORY)) - ofn.lpstrInitialDir = m_wdefault_path.c_str(); - else if (m_wdefault_path.size() <= woutput.size()) - //second argument is size of buffer, not length of string - StringCchCopyW(ofn.lpstrFile, MAX_PATH * 256 + 1, m_wdefault_path.c_str()); - else - { - ofn.lpstrFileTitle = (LPWSTR)m_wdefault_path.data(); - ofn.nMaxFileTitle = (DWORD)m_wdefault_path.size(); - } - } - ofn.lpstrTitle = m_wtitle.c_str(); - ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER; - - dll comdlg32("comdlg32.dll"); - - // Apply new visual style (required for windows XP) - new_style_context ctx; - - if (in_type == type::save) - { - if (!(options & opt::force_overwrite)) - ofn.Flags |= OFN_OVERWRITEPROMPT; - - dll::proc get_save_file_name(comdlg32, "GetSaveFileNameW"); - if (get_save_file_name(&ofn) == 0) - return ""; - return internal::wstr2str(woutput.c_str()); - } - else - { - if (options & opt::multiselect) - ofn.Flags |= OFN_ALLOWMULTISELECT; - ofn.Flags |= OFN_PATHMUSTEXIST; - - dll::proc get_open_file_name(comdlg32, "GetOpenFileNameW"); - if (get_open_file_name(&ofn) == 0) - return ""; - } - - std::string prefix; - for (wchar_t const* p = woutput.c_str(); *p;) - { - auto filename = internal::wstr2str(p); - p += wcslen(p); - // In multiselect mode, we advance p one wchar further and - // check for another filename. If there is one and the - // prefix is empty, it means we just read the prefix. - if ((options & opt::multiselect) && *++p && prefix.empty()) - { - prefix = filename + "/"; - continue; - } - - m_vector_result.push_back(prefix + filename); - } - - return ""; - }); + BROWSEINFOW bi; + memset(&bi, 0, sizeof(bi)); + + bi.lpfn = &bffcallback; + bi.lParam = (LPARAM) this; + + if (flags(flag::is_vista)) { + if (ole32.is_initialized()) bi.ulFlags |= BIF_NEWDIALOGSTYLE; + bi.ulFlags |= BIF_EDITBOX; + bi.ulFlags |= BIF_STATUSTEXT; + } + + auto* list = SHBrowseForFolderW(&bi); + std::string ret; + if (list) { + auto buffer = new wchar_t[MAX_PATH]; + SHGetPathFromIDListW(list, buffer); + dll::proc(ole32, "CoTaskMemFree")(list); + ret = internal::wstr2str(buffer); + delete[] buffer; + } + return ret; + } + + OPENFILENAMEW ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(OPENFILENAMEW); + ofn.hwndOwner = GetActiveWindow(); + + ofn.lpstrFilter = wfilter_list.c_str(); + + auto woutput = std::wstring(MAX_PATH * 256, L'\0'); + ofn.lpstrFile = (LPWSTR) woutput.data(); + ofn.nMaxFile = (DWORD) woutput.size(); + if (!m_wdefault_path.empty()) { + // If a directory was provided, use it as the initial directory. If + // a valid path was provided, use it as the initial file. Otherwise, + // let the Windows API decide. + auto path_attr = GetFileAttributesW(m_wdefault_path.c_str()); + if (path_attr != INVALID_FILE_ATTRIBUTES && (path_attr & FILE_ATTRIBUTE_DIRECTORY)) + ofn.lpstrInitialDir = m_wdefault_path.c_str(); + else if (m_wdefault_path.size() <= woutput.size()) + // second argument is size of buffer, not length of string + StringCchCopyW(ofn.lpstrFile, MAX_PATH * 256 + 1, m_wdefault_path.c_str()); + else { + ofn.lpstrFileTitle = (LPWSTR) m_wdefault_path.data(); + ofn.nMaxFileTitle = (DWORD) m_wdefault_path.size(); + } + } + ofn.lpstrTitle = m_wtitle.c_str(); + ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER; + + dll comdlg32("comdlg32.dll"); + + // Apply new visual style (required for windows XP) + new_style_context ctx; + + if (in_type == type::save) { + if (!(options & opt::force_overwrite)) ofn.Flags |= OFN_OVERWRITEPROMPT; + + dll::proc get_save_file_name(comdlg32, "GetSaveFileNameW"); + if (get_save_file_name(&ofn) == 0) return ""; + return internal::wstr2str(woutput.c_str()); + } else { + if (options & opt::multiselect) ofn.Flags |= OFN_ALLOWMULTISELECT; + ofn.Flags |= OFN_PATHMUSTEXIST; + + dll::proc get_open_file_name(comdlg32, "GetOpenFileNameW"); + if (get_open_file_name(&ofn) == 0) return ""; + } + + std::string prefix; + for (wchar_t const* p = woutput.c_str(); *p;) { + auto filename = internal::wstr2str(p); + p += wcslen(p); + // In multiselect mode, we advance p one wchar further and + // check for another filename. If there is one and the + // prefix is empty, it means we just read the prefix. + if ((options & opt::multiselect) && *++p && prefix.empty()) { + prefix = filename + "/"; + continue; + } + + m_vector_result.push_back(prefix + filename); + } + + return ""; + }); #elif __EMSCRIPTEN__ - // FIXME: do something - (void)in_type; - (void)title; - (void)default_path; - (void)filters; - (void)options; + // FIXME: do something + (void) in_type; + (void) title; + (void) default_path; + (void) filters; + (void) options; #else - auto command = desktop_helper(); - - if (is_osascript()) - { - std::string script = "set ret to choose"; - switch (in_type) - { - case type::save: - script += " file name"; - break; - case type::open: - default: - script += " file"; - if (options & opt::multiselect) - script += " with multiple selections allowed"; - break; - case type::folder: - script += " folder"; - break; - } - - if (default_path.size()) - { - if (in_type == type::folder || is_directory(default_path)) - script += " default location "; - else - script += " default name "; - script += osascript_quote(default_path); - } - - script += " with prompt " + osascript_quote(title); - - if (in_type == type::open) - { - // Concatenate all user-provided filter patterns - std::string patterns; - for (size_t i = 0; i < filters.size() / 2; ++i) - patterns += " " + filters[2 * i + 1]; - - // Split the pattern list to check whether "*" is in there; if it - // is, we have to disable filters because there is no mechanism in - // OS X for the user to override the filter. - std::regex sep("\\s+"); - std::string filter_list; - bool has_filter = true; - std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1); - std::sregex_token_iterator end; - for (; iter != end; ++iter) - { - auto pat = iter->str(); - if (pat == "*" || pat == "*.*") - has_filter = false; - else if (internal::starts_with(pat, "*.")) - filter_list += "," + osascript_quote(pat.substr(2, pat.size() - 2)); - } - - if (has_filter && filter_list.size() > 0) - { - // There is a weird AppleScript bug where file extensions of length != 3 are - // ignored, e.g. type{"txt"} works, but type{"json"} does not. Fortunately if - // the whole list starts with a 3-character extension, everything works again. - // We use "///" for such an extension because we are sure it cannot appear in - // an actual filename. - script += " of type {\"///\"" + filter_list + "}"; - } - } - - if (in_type == type::open && (options & opt::multiselect)) - { - script += "\nset s to \"\""; - script += "\nrepeat with i in ret"; - script += "\n set s to s & (POSIX path of i) & \"\\n\""; - script += "\nend repeat"; - script += "\ncopy s to stdout"; - } - else - { - script += "\nPOSIX path of ret"; - } - - command.push_back("-e"); - command.push_back(script); - } - else if (is_zenity()) - { - command.push_back("--file-selection"); - - // If the default path is a directory, make sure it ends with "/" otherwise zenity will - // open the file dialog in the parent directory. - auto filename_arg = "--filename=" + default_path; - if (in_type != type::folder && !ends_with(default_path, "/") && internal::is_directory(default_path)) - filename_arg += "/"; - command.push_back(filename_arg); - - command.push_back("--title"); - command.push_back(title); - command.push_back("--separator=\n"); - - for (size_t i = 0; i < filters.size() / 2; ++i) - { - command.push_back("--file-filter"); - command.push_back(filters[2 * i] + "|" + filters[2 * i + 1]); - } - - if (in_type == type::save) - command.push_back("--save"); - if (in_type == type::folder) - command.push_back("--directory"); - if (!(options & opt::force_overwrite)) - command.push_back("--confirm-overwrite"); - if (options & opt::multiselect) - command.push_back("--multiple"); - } - else if (is_kdialog()) - { - switch (in_type) - { - case type::save: - command.push_back("--getsavefilename"); - break; - case type::open: - command.push_back("--getopenfilename"); - break; - case type::folder: - command.push_back("--getexistingdirectory"); - break; - } - if (options & opt::multiselect) - { - command.push_back("--multiple"); - command.push_back("--separate-output"); - } - - command.push_back(default_path); - - std::string filter; - for (size_t i = 0; i < filters.size() / 2; ++i) - filter += (i == 0 ? "" : " | ") + filters[2 * i] + "(" + filters[2 * i + 1] + ")"; - command.push_back(filter); - - command.push_back("--title"); - command.push_back(title); - } - - if (flags(flag::is_verbose)) - std::cerr << "pfd: " << command << std::endl; - - m_async->start_process(command); + auto command = desktop_helper(); + + if (is_osascript()) { + std::string script = "set ret to choose"; + switch (in_type) { + case type::save: + script += " file name"; + break; + case type::open: + default: + script += " file"; + if (options & opt::multiselect) script += " with multiple selections allowed"; + break; + case type::folder: + script += " folder"; + break; + } + + if (default_path.size()) { + if (in_type == type::folder || is_directory(default_path)) + script += " default location "; + else + script += " default name "; + script += osascript_quote(default_path); + } + + script += " with prompt " + osascript_quote(title); + + if (in_type == type::open) { + // Concatenate all user-provided filter patterns + std::string patterns; + for (size_t i = 0; i < filters.size() / 2; ++i) patterns += " " + filters[2 * i + 1]; + + // Split the pattern list to check whether "*" is in there; if it + // is, we have to disable filters because there is no mechanism in + // OS X for the user to override the filter. + std::regex sep("\\s+"); + std::string filter_list; + bool has_filter = true; + std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1); + std::sregex_token_iterator end; + for (; iter != end; ++iter) { + auto pat = iter->str(); + if (pat == "*" || pat == "*.*") + has_filter = false; + else if (internal::starts_with(pat, "*.")) + filter_list += "," + osascript_quote(pat.substr(2, pat.size() - 2)); + } + + if (has_filter && filter_list.size() > 0) { + // There is a weird AppleScript bug where file extensions of length != 3 are + // ignored, e.g. type{"txt"} works, but type{"json"} does not. Fortunately if + // the whole list starts with a 3-character extension, everything works again. + // We use "///" for such an extension because we are sure it cannot appear in + // an actual filename. + script += " of type {\"///\"" + filter_list + "}"; + } + } + + if (in_type == type::open && (options & opt::multiselect)) { + script += "\nset s to \"\""; + script += "\nrepeat with i in ret"; + script += "\n set s to s & (POSIX path of i) & \"\\n\""; + script += "\nend repeat"; + script += "\ncopy s to stdout"; + } else { + script += "\nPOSIX path of ret"; + } + + command.push_back("-e"); + command.push_back(script); + } else if (is_zenity()) { + command.push_back("--file-selection"); + + // If the default path is a directory, make sure it ends with "/" otherwise zenity will + // open the file dialog in the parent directory. + auto filename_arg = "--filename=" + default_path; + if (in_type != type::folder && !ends_with(default_path, "/") && + internal::is_directory(default_path)) + filename_arg += "/"; + command.push_back(filename_arg); + + command.push_back("--title"); + command.push_back(title); + command.push_back("--separator=\n"); + + for (size_t i = 0; i < filters.size() / 2; ++i) { + command.push_back("--file-filter"); + command.push_back(filters[2 * i] + "|" + filters[2 * i + 1]); + } + + if (in_type == type::save) command.push_back("--save"); + if (in_type == type::folder) command.push_back("--directory"); + if (!(options & opt::force_overwrite)) command.push_back("--confirm-overwrite"); + if (options & opt::multiselect) command.push_back("--multiple"); + } else if (is_kdialog()) { + switch (in_type) { + case type::save: + command.push_back("--getsavefilename"); + break; + case type::open: + command.push_back("--getopenfilename"); + break; + case type::folder: + command.push_back("--getexistingdirectory"); + break; + } + if (options & opt::multiselect) { + command.push_back("--multiple"); + command.push_back("--separate-output"); + } + + command.push_back(default_path); + + std::string filter; + for (size_t i = 0; i < filters.size() / 2; ++i) + filter += (i == 0 ? "" : " | ") + filters[2 * i] + "(" + filters[2 * i + 1] + ")"; + command.push_back(filter); + + command.push_back("--title"); + command.push_back(title); + } + + if (flags(flag::is_verbose)) std::cerr << "pfd: " << command << std::endl; + + m_async->start_process(command); #endif - } +} - inline std::string internal::file_dialog::string_result() - { +inline std::string internal::file_dialog::string_result() { #if _WIN32 - return m_async->result(); + return m_async->result(); #else - auto ret = m_async->result(); - // Strip potential trailing newline (zenity). Also strip trailing slash - // added by osascript for consistency with other backends. - while (!ret.empty() && (ret.back() == '\n' || ret.back() == '/')) - ret.pop_back(); - return ret; + auto ret = m_async->result(); + // Strip potential trailing newline (zenity). Also strip trailing slash + // added by osascript for consistency with other backends. + while (!ret.empty() && (ret.back() == '\n' || ret.back() == '/')) ret.pop_back(); + return ret; #endif - } +} - inline std::vector internal::file_dialog::vector_result() - { +inline std::vector internal::file_dialog::vector_result() { #if _WIN32 - m_async->result(); - return m_vector_result; + m_async->result(); + return m_vector_result; #else - std::vector ret; - auto result = m_async->result(); - for (;;) - { - // Split result along newline characters - auto i = result.find('\n'); - if (i == 0 || i == std::string::npos) - break; - ret.push_back(result.substr(0, i)); - result = result.substr(i + 1, result.size()); - } - return ret; + std::vector ret; + auto result = m_async->result(); + for (;;) { + // Split result along newline characters + auto i = result.find('\n'); + if (i == 0 || i == std::string::npos) break; + ret.push_back(result.substr(0, i)); + result = result.substr(i + 1, result.size()); + } + return ret; #endif - } +} #if _WIN32 - // Use a static function to pass as BFFCALLBACK for legacy folder select - inline int CALLBACK internal::file_dialog::bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData) - { - auto inst = (file_dialog*)pData; - switch (uMsg) - { - case BFFM_INITIALIZED: - SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM)inst->m_wdefault_path.c_str()); - break; - } - return 0; - } +// Use a static function to pass as BFFCALLBACK for legacy folder select +inline int CALLBACK internal::file_dialog::bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData) { + auto inst = (file_dialog*) pData; + switch (uMsg) { + case BFFM_INITIALIZED: + SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM) inst->m_wdefault_path.c_str()); + break; + } + return 0; +} #if PFD_HAS_IFILEDIALOG - inline std::string internal::file_dialog::select_folder_vista(IFileDialog* ifd, bool force_path) - { - std::string result; - - IShellItem* folder; - - // Load library at runtime so app doesn't link it at load time (which will fail on windows XP) - dll shell32("shell32.dll"); - dll::proc - create_item(shell32, "SHCreateItemFromParsingName"); - - if (!create_item) - return ""; - - auto hr = create_item(m_wdefault_path.c_str(), - nullptr, - IID_PPV_ARGS(&folder)); - - // Set default folder if found. This only sets the default folder. If - // Windows has any info about the most recently selected folder, it - // will display it instead. Generally, calling SetFolder() to set the - // current directory “is not a good or expected user experience and - // should therefore be avoided”: - // https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfolder - if (SUCCEEDED(hr)) - { - if (force_path) - ifd->SetFolder(folder); - else - ifd->SetDefaultFolder(folder); - folder->Release(); - } - - // Set the dialog title and option to select folders - ifd->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM); - ifd->SetTitle(m_wtitle.c_str()); - - hr = ifd->Show(GetActiveWindow()); - if (SUCCEEDED(hr)) - { - IShellItem* item; - hr = ifd->GetResult(&item); - if (SUCCEEDED(hr)) - { - wchar_t* wname = nullptr; - // This is unlikely to fail because we use FOS_FORCEFILESYSTEM, but try - // to output a debug message just in case. - if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &wname))) - { - result = internal::wstr2str(std::wstring(wname)); - dll::proc(ole32_dll(), "CoTaskMemFree")(wname); - } - else - { - if (SUCCEEDED(item->GetDisplayName(SIGDN_NORMALDISPLAY, &wname))) - { - auto name = internal::wstr2str(std::wstring(wname)); - dll::proc(ole32_dll(), "CoTaskMemFree")(wname); - std::cerr << "pfd: failed to get path for " << name << std::endl; - } - else - std::cerr << "pfd: item of unknown type selected" << std::endl; - } - - item->Release(); - } - } - - ifd->Release(); - - return result; - } +inline std::string internal::file_dialog::select_folder_vista(IFileDialog* ifd, bool force_path) { + std::string result; + + IShellItem* folder; + + // Load library at runtime so app doesn't link it at load time (which will fail on windows XP) + dll shell32("shell32.dll"); + dll::proc create_item( + shell32, "SHCreateItemFromParsingName"); + + if (!create_item) return ""; + + auto hr = create_item(m_wdefault_path.c_str(), nullptr, IID_PPV_ARGS(&folder)); + + // Set default folder if found. This only sets the default folder. If + // Windows has any info about the most recently selected folder, it + // will display it instead. Generally, calling SetFolder() to set the + // current directory “is not a good or expected user experience and + // should therefore be avoided”: + // https://docs.microsoft.com/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfolder + if (SUCCEEDED(hr)) { + if (force_path) + ifd->SetFolder(folder); + else + ifd->SetDefaultFolder(folder); + folder->Release(); + } + + // Set the dialog title and option to select folders + ifd->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM); + ifd->SetTitle(m_wtitle.c_str()); + + hr = ifd->Show(GetActiveWindow()); + if (SUCCEEDED(hr)) { + IShellItem* item; + hr = ifd->GetResult(&item); + if (SUCCEEDED(hr)) { + wchar_t* wname = nullptr; + // This is unlikely to fail because we use FOS_FORCEFILESYSTEM, but try + // to output a debug message just in case. + if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &wname))) { + result = internal::wstr2str(std::wstring(wname)); + dll::proc(ole32_dll(), "CoTaskMemFree")(wname); + } else { + if (SUCCEEDED(item->GetDisplayName(SIGDN_NORMALDISPLAY, &wname))) { + auto name = internal::wstr2str(std::wstring(wname)); + dll::proc(ole32_dll(), "CoTaskMemFree")(wname); + std::cerr << "pfd: failed to get path for " << name << std::endl; + } else + std::cerr << "pfd: item of unknown type selected" << std::endl; + } + + item->Release(); + } + } + + ifd->Release(); + + return result; +} #endif #endif - // notify implementation +// notify implementation - inline notify::notify(std::string const& title, - std::string const& message, - icon _icon /* = icon::info */) - { - if (_icon == icon::question) // Not supported by notifications - _icon = icon::info; +inline notify::notify(std::string const& title, std::string const& message, + icon _icon /* = icon::info */) { + if (_icon == icon::question) // Not supported by notifications + _icon = icon::info; #if _WIN32 - // Use a static shared pointer for notify_icon so that we can delete - // it whenever we need to display a new one, and we can also wait - // until the program has finished running. - struct notify_icon_data : public NOTIFYICONDATAW - { - ~notify_icon_data() - { - Shell_NotifyIconW(NIM_DELETE, this); - } - }; - - static std::shared_ptr nid; - - // Release the previous notification icon, if any, and allocate a new - // one. Note that std::make_shared() does value initialization, so there - // is no need to memset the structure. - nid = nullptr; - nid = std::make_shared(); - - // For XP support - nid->cbSize = NOTIFYICONDATAW_V2_SIZE; - nid->hWnd = nullptr; - nid->uID = 0; - - // Flag Description: - // - NIF_ICON The hIcon member is valid. - // - NIF_MESSAGE The uCallbackMessage member is valid. - // - NIF_TIP The szTip member is valid. - // - NIF_STATE The dwState and dwStateMask members are valid. - // - NIF_INFO Use a balloon ToolTip instead of a standard ToolTip. The szInfo, uTimeout, szInfoTitle, and dwInfoFlags members are valid. - // - NIF_GUID Reserved. - nid->uFlags = NIF_MESSAGE | NIF_ICON | NIF_INFO; - - // Flag Description - // - NIIF_ERROR An error icon. - // - NIIF_INFO An information icon. - // - NIIF_NONE No icon. - // - NIIF_WARNING A warning icon. - // - NIIF_ICON_MASK Version 6.0. Reserved. - // - NIIF_NOSOUND Version 6.0. Do not play the associated sound. Applies only to balloon ToolTips - switch (_icon) - { - case icon::warning: - nid->dwInfoFlags = NIIF_WARNING; - break; - case icon::error: - nid->dwInfoFlags = NIIF_ERROR; - break; - /* case icon::info: */ default: - nid->dwInfoFlags = NIIF_INFO; - break; - } - - ENUMRESNAMEPROC icon_enum_callback = [](HMODULE, LPCTSTR, LPTSTR lpName, LONG_PTR lParam) -> BOOL { - ((NOTIFYICONDATAW*)lParam)->hIcon = ::LoadIcon(GetModuleHandle(nullptr), lpName); - return false; - }; - - nid->hIcon = ::LoadIcon(nullptr, IDI_APPLICATION); - ::EnumResourceNames(nullptr, RT_GROUP_ICON, icon_enum_callback, (LONG_PTR)nid.get()); - - nid->uTimeout = 5000; - - StringCchCopyW(nid->szInfoTitle, ARRAYSIZE(nid->szInfoTitle), internal::str2wstr(title).c_str()); - StringCchCopyW(nid->szInfo, ARRAYSIZE(nid->szInfo), internal::str2wstr(message).c_str()); - - // Display the new icon - Shell_NotifyIconW(NIM_ADD, nid.get()); + // Use a static shared pointer for notify_icon so that we can delete + // it whenever we need to display a new one, and we can also wait + // until the program has finished running. + struct notify_icon_data : public NOTIFYICONDATAW { + ~notify_icon_data() { Shell_NotifyIconW(NIM_DELETE, this); } + }; + + static std::shared_ptr nid; + + // Release the previous notification icon, if any, and allocate a new + // one. Note that std::make_shared() does value initialization, so there + // is no need to memset the structure. + nid = nullptr; + nid = std::make_shared(); + + // For XP support + nid->cbSize = NOTIFYICONDATAW_V2_SIZE; + nid->hWnd = nullptr; + nid->uID = 0; + + // Flag Description: + // - NIF_ICON The hIcon member is valid. + // - NIF_MESSAGE The uCallbackMessage member is valid. + // - NIF_TIP The szTip member is valid. + // - NIF_STATE The dwState and dwStateMask members are valid. + // - NIF_INFO Use a balloon ToolTip instead of a standard ToolTip. The szInfo, uTimeout, + // szInfoTitle, and dwInfoFlags members are valid. + // - NIF_GUID Reserved. + nid->uFlags = NIF_MESSAGE | NIF_ICON | NIF_INFO; + + // Flag Description + // - NIIF_ERROR An error icon. + // - NIIF_INFO An information icon. + // - NIIF_NONE No icon. + // - NIIF_WARNING A warning icon. + // - NIIF_ICON_MASK Version 6.0. Reserved. + // - NIIF_NOSOUND Version 6.0. Do not play the associated sound. Applies only to balloon + // ToolTips + switch (_icon) { + case icon::warning: + nid->dwInfoFlags = NIIF_WARNING; + break; + case icon::error: + nid->dwInfoFlags = NIIF_ERROR; + break; + /* case icon::info: */ default: + nid->dwInfoFlags = NIIF_INFO; + break; + } + + ENUMRESNAMEPROC icon_enum_callback = [](HMODULE, LPCTSTR, LPTSTR lpName, + LONG_PTR lParam) -> BOOL { + ((NOTIFYICONDATAW*) lParam)->hIcon = ::LoadIcon(GetModuleHandle(nullptr), lpName); + return false; + }; + + nid->hIcon = ::LoadIcon(nullptr, IDI_APPLICATION); + ::EnumResourceNames(nullptr, RT_GROUP_ICON, icon_enum_callback, (LONG_PTR) nid.get()); + + nid->uTimeout = 5000; + + StringCchCopyW(nid->szInfoTitle, ARRAYSIZE(nid->szInfoTitle), internal::str2wstr(title).c_str()); + StringCchCopyW(nid->szInfo, ARRAYSIZE(nid->szInfo), internal::str2wstr(message).c_str()); + + // Display the new icon + Shell_NotifyIconW(NIM_ADD, nid.get()); #elif __EMSCRIPTEN__ - // FIXME: do something - (void)title; - (void)message; + // FIXME: do something + (void) title; + (void) message; #else - auto command = desktop_helper(); - - if (is_osascript()) - { - command.push_back("-e"); - command.push_back("display notification " + osascript_quote(message) + - " with title " + osascript_quote(title)); - } - else if (is_zenity()) - { - command.push_back("--notification"); - command.push_back("--window-icon"); - command.push_back(get_icon_name(_icon)); - command.push_back("--text"); - command.push_back(title + "\n" + message); - } - else if (is_kdialog()) - { - command.push_back("--icon"); - command.push_back(get_icon_name(_icon)); - command.push_back("--title"); - command.push_back(title); - command.push_back("--passivepopup"); - command.push_back(message); - command.push_back("5"); - } - - if (flags(flag::is_verbose)) - std::cerr << "pfd: " << command << std::endl; - - m_async->start_process(command); + auto command = desktop_helper(); + + if (is_osascript()) { + command.push_back("-e"); + command.push_back("display notification " + osascript_quote(message) + " with title " + + osascript_quote(title)); + } else if (is_zenity()) { + command.push_back("--notification"); + command.push_back("--window-icon"); + command.push_back(get_icon_name(_icon)); + command.push_back("--text"); + command.push_back(title + "\n" + message); + } else if (is_kdialog()) { + command.push_back("--icon"); + command.push_back(get_icon_name(_icon)); + command.push_back("--title"); + command.push_back(title); + command.push_back("--passivepopup"); + command.push_back(message); + command.push_back("5"); + } + + if (flags(flag::is_verbose)) std::cerr << "pfd: " << command << std::endl; + + m_async->start_process(command); #endif - } +} - // message implementation +// message implementation - inline message::message(std::string const& title, - std::string const& text, - choice _choice /* = choice::ok_cancel */, - icon _icon /* = icon::info */) - { +inline message::message(std::string const& title, std::string const& text, + choice _choice /* = choice::ok_cancel */, icon _icon /* = icon::info */) { #if _WIN32 - // Use MB_SYSTEMMODAL rather than MB_TOPMOST to ensure the message window is brought - // to front. See https://github.com/samhocevar/portable-file-dialogs/issues/52 - UINT style = MB_SYSTEMMODAL; - switch (_icon) - { - case icon::warning: - style |= MB_ICONWARNING; - break; - case icon::error: - style |= MB_ICONERROR; - break; - case icon::question: - style |= MB_ICONQUESTION; - break; - /* case icon::info: */ default: - style |= MB_ICONINFORMATION; - break; - } - - switch (_choice) - { - case choice::ok_cancel: - style |= MB_OKCANCEL; - break; - case choice::yes_no: - style |= MB_YESNO; - break; - case choice::yes_no_cancel: - style |= MB_YESNOCANCEL; - break; - case choice::retry_cancel: - style |= MB_RETRYCANCEL; - break; - case choice::abort_retry_ignore: - style |= MB_ABORTRETRYIGNORE; - break; - /* case choice::ok: */ default: - style |= MB_OK; - break; - } - - m_mappings[IDCANCEL] = button::cancel; - m_mappings[IDOK] = button::ok; - m_mappings[IDYES] = button::yes; - m_mappings[IDNO] = button::no; - m_mappings[IDABORT] = button::abort; - m_mappings[IDRETRY] = button::retry; - m_mappings[IDIGNORE] = button::ignore; - - m_async->start_func([text, title, style](int* exit_code) -> std::string { - auto wtext = internal::str2wstr(text); - auto wtitle = internal::str2wstr(title); - // Apply new visual style (required for all Windows versions) - new_style_context ctx; - *exit_code = MessageBoxW(GetActiveWindow(), wtext.c_str(), wtitle.c_str(), style); - return ""; - }); + // Use MB_SYSTEMMODAL rather than MB_TOPMOST to ensure the message window is brought + // to front. See https://github.com/samhocevar/portable-file-dialogs/issues/52 + UINT style = MB_SYSTEMMODAL; + switch (_icon) { + case icon::warning: + style |= MB_ICONWARNING; + break; + case icon::error: + style |= MB_ICONERROR; + break; + case icon::question: + style |= MB_ICONQUESTION; + break; + /* case icon::info: */ default: + style |= MB_ICONINFORMATION; + break; + } + + switch (_choice) { + case choice::ok_cancel: + style |= MB_OKCANCEL; + break; + case choice::yes_no: + style |= MB_YESNO; + break; + case choice::yes_no_cancel: + style |= MB_YESNOCANCEL; + break; + case choice::retry_cancel: + style |= MB_RETRYCANCEL; + break; + case choice::abort_retry_ignore: + style |= MB_ABORTRETRYIGNORE; + break; + /* case choice::ok: */ default: + style |= MB_OK; + break; + } + + m_mappings[IDCANCEL] = button::cancel; + m_mappings[IDOK] = button::ok; + m_mappings[IDYES] = button::yes; + m_mappings[IDNO] = button::no; + m_mappings[IDABORT] = button::abort; + m_mappings[IDRETRY] = button::retry; + m_mappings[IDIGNORE] = button::ignore; + + m_async->start_func([text, title, style](int* exit_code) -> std::string { + auto wtext = internal::str2wstr(text); + auto wtitle = internal::str2wstr(title); + // Apply new visual style (required for all Windows versions) + new_style_context ctx; + *exit_code = MessageBoxW(GetActiveWindow(), wtext.c_str(), wtitle.c_str(), style); + return ""; + }); #elif __EMSCRIPTEN__ - std::string full_message; - switch (_icon) - { - case icon::warning: - full_message = "⚠️"; - break; - case icon::error: - full_message = "⛔"; - break; - case icon::question: - full_message = "❓"; - break; - /* case icon::info: */ default: - full_message = "ℹ"; - break; - } - - full_message += ' ' + title + "\n\n" + text; - - // This does not really start an async task; it just passes the - // EM_ASM_INT return value to a fake start() function. - m_async->start(EM_ASM_INT( - { - if ($1) - return window.confirm(UTF8ToString($0)) ? 0 : -1; - alert(UTF8ToString($0)); - return 0; - }, - full_message.c_str(), _choice == choice::ok_cancel)); + std::string full_message; + switch (_icon) { + case icon::warning: + full_message = "⚠️"; + break; + case icon::error: + full_message = "⛔"; + break; + case icon::question: + full_message = "❓"; + break; + /* case icon::info: */ default: + full_message = "ℹ"; + break; + } + + full_message += ' ' + title + "\n\n" + text; + + // This does not really start an async task; it just passes the + // EM_ASM_INT return value to a fake start() function. + m_async->start(EM_ASM_INT( + { + if ($1) return window.confirm(UTF8ToString($0)) ? 0 : -1; + alert(UTF8ToString($0)); + return 0; + }, + full_message.c_str(), _choice == choice::ok_cancel)); #else - auto command = desktop_helper(); - - if (is_osascript()) - { - std::string script = "display dialog " + osascript_quote(text) + - " with title " + osascript_quote(title); - auto if_cancel = button::cancel; - switch (_choice) - { - case choice::ok_cancel: - script += "buttons {\"OK\", \"Cancel\"}" - " default button \"OK\"" - " cancel button \"Cancel\""; - break; - case choice::yes_no: - script += "buttons {\"Yes\", \"No\"}" - " default button \"Yes\"" - " cancel button \"No\""; - if_cancel = button::no; - break; - case choice::yes_no_cancel: - script += "buttons {\"Yes\", \"No\", \"Cancel\"}" - " default button \"Yes\"" - " cancel button \"Cancel\""; - break; - case choice::retry_cancel: - script += "buttons {\"Retry\", \"Cancel\"}" - " default button \"Retry\"" - " cancel button \"Cancel\""; - break; - case choice::abort_retry_ignore: - script += "buttons {\"Abort\", \"Retry\", \"Ignore\"}" - " default button \"Abort\"" - " cancel button \"Retry\""; - if_cancel = button::retry; - break; - case choice::ok: - default: - script += "buttons {\"OK\"}" - " default button \"OK\"" - " cancel button \"OK\""; - if_cancel = button::ok; - break; - } - m_mappings[1] = if_cancel; - m_mappings[256] = if_cancel; // XXX: I think this was never correct - script += " with icon "; - switch (_icon) - { -#define PFD_OSX_ICON(n) "alias ((path to library folder from system domain) as text " \ - "& \"CoreServices:CoreTypes.bundle:Contents:Resources:" n ".icns\")" - case icon::info: - default: - script += PFD_OSX_ICON("ToolBarInfo"); - break; - case icon::warning: - script += "caution"; - break; - case icon::error: - script += "stop"; - break; - case icon::question: - script += PFD_OSX_ICON("GenericQuestionMarkIcon"); - break; + auto command = desktop_helper(); + + if (is_osascript()) { + std::string script = + "display dialog " + osascript_quote(text) + " with title " + osascript_quote(title); + auto if_cancel = button::cancel; + switch (_choice) { + case choice::ok_cancel: + script += + "buttons {\"OK\", \"Cancel\"}" + " default button \"OK\"" + " cancel button \"Cancel\""; + break; + case choice::yes_no: + script += + "buttons {\"Yes\", \"No\"}" + " default button \"Yes\"" + " cancel button \"No\""; + if_cancel = button::no; + break; + case choice::yes_no_cancel: + script += + "buttons {\"Yes\", \"No\", \"Cancel\"}" + " default button \"Yes\"" + " cancel button \"Cancel\""; + break; + case choice::retry_cancel: + script += + "buttons {\"Retry\", \"Cancel\"}" + " default button \"Retry\"" + " cancel button \"Cancel\""; + break; + case choice::abort_retry_ignore: + script += + "buttons {\"Abort\", \"Retry\", \"Ignore\"}" + " default button \"Abort\"" + " cancel button \"Retry\""; + if_cancel = button::retry; + break; + case choice::ok: + default: + script += + "buttons {\"OK\"}" + " default button \"OK\"" + " cancel button \"OK\""; + if_cancel = button::ok; + break; + } + m_mappings[1] = if_cancel; + m_mappings[256] = if_cancel; // XXX: I think this was never correct + script += " with icon "; + switch (_icon) { +#define PFD_OSX_ICON(n) \ + "alias ((path to library folder from system domain) as text " \ + "& \"CoreServices:CoreTypes.bundle:Contents:Resources:" n ".icns\")" + case icon::info: + default: + script += PFD_OSX_ICON("ToolBarInfo"); + break; + case icon::warning: + script += "caution"; + break; + case icon::error: + script += "stop"; + break; + case icon::question: + script += PFD_OSX_ICON("GenericQuestionMarkIcon"); + break; #undef PFD_OSX_ICON - } - - command.push_back("-e"); - command.push_back(script); - } - else if (is_zenity()) - { - switch (_choice) - { - case choice::ok_cancel: - command.insert(command.end(), {"--question", "--cancel-label=Cancel", "--ok-label=OK"}); - break; - case choice::yes_no: - // Do not use standard --question because it causes “No” to return -1, - // which is inconsistent with the “Yes/No/Cancel” mode below. - command.insert(command.end(), {"--question", "--switch", "--extra-button=No", "--extra-button=Yes"}); - break; - case choice::yes_no_cancel: - command.insert(command.end(), {"--question", "--switch", "--extra-button=Cancel", "--extra-button=No", "--extra-button=Yes"}); - break; - case choice::retry_cancel: - command.insert(command.end(), {"--question", "--switch", "--extra-button=Cancel", "--extra-button=Retry"}); - break; - case choice::abort_retry_ignore: - command.insert(command.end(), {"--question", "--switch", "--extra-button=Ignore", "--extra-button=Abort", "--extra-button=Retry"}); - break; - case choice::ok: - default: - switch (_icon) - { - case icon::error: - command.push_back("--error"); - break; - case icon::warning: - command.push_back("--warning"); - break; - default: - command.push_back("--info"); - break; - } - } - - command.insert(command.end(), {"--title", title, - "--width=300", "--height=0", // sensible defaults - "--no-markup", // do not interpret text as Pango markup - "--text", text, - "--icon-name=dialog-" + get_icon_name(_icon)}); - } - else if (is_kdialog()) - { - if (_choice == choice::ok) - { - switch (_icon) - { - case icon::error: - command.push_back("--error"); - break; - case icon::warning: - command.push_back("--sorry"); - break; - default: - command.push_back("--msgbox"); - break; - } - } - else - { - std::string flag = "--"; - if (_icon == icon::warning || _icon == icon::error) - flag += "warning"; - flag += "yesno"; - if (_choice == choice::yes_no_cancel) - flag += "cancel"; - command.push_back(flag); - if (_choice == choice::yes_no || _choice == choice::yes_no_cancel) - { - m_mappings[0] = button::yes; - m_mappings[256] = button::no; - } - } - - command.push_back(text); - command.push_back("--title"); - command.push_back(title); - - // Must be after the above part - if (_choice == choice::ok_cancel) - command.insert(command.end(), {"--yes-label", "OK", "--no-label", "Cancel"}); - } - - if (flags(flag::is_verbose)) - std::cerr << "pfd: " << command << std::endl; - - m_async->start_process(command); + } + + command.push_back("-e"); + command.push_back(script); + } else if (is_zenity()) { + switch (_choice) { + case choice::ok_cancel: + command.insert(command.end(), {"--question", "--cancel-label=Cancel", "--ok-label=OK"}); + break; + case choice::yes_no: + // Do not use standard --question because it causes “No” to return -1, + // which is inconsistent with the “Yes/No/Cancel” mode below. + command.insert(command.end(), + {"--question", "--switch", "--extra-button=No", "--extra-button=Yes"}); + break; + case choice::yes_no_cancel: + command.insert(command.end(), {"--question", "--switch", "--extra-button=Cancel", + "--extra-button=No", "--extra-button=Yes"}); + break; + case choice::retry_cancel: + command.insert(command.end(), + {"--question", "--switch", "--extra-button=Cancel", "--extra-button=Retry"}); + break; + case choice::abort_retry_ignore: + command.insert(command.end(), {"--question", "--switch", "--extra-button=Ignore", + "--extra-button=Abort", "--extra-button=Retry"}); + break; + case choice::ok: + default: + switch (_icon) { + case icon::error: + command.push_back("--error"); + break; + case icon::warning: + command.push_back("--warning"); + break; + default: + command.push_back("--info"); + break; + } + } + + command.insert(command.end(), + {"--title", title, "--width=300", "--height=0", // sensible defaults + "--no-markup", // do not interpret text as Pango markup + "--text", text, "--icon-name=dialog-" + get_icon_name(_icon)}); + } else if (is_kdialog()) { + if (_choice == choice::ok) { + switch (_icon) { + case icon::error: + command.push_back("--error"); + break; + case icon::warning: + command.push_back("--sorry"); + break; + default: + command.push_back("--msgbox"); + break; + } + } else { + std::string flag = "--"; + if (_icon == icon::warning || _icon == icon::error) flag += "warning"; + flag += "yesno"; + if (_choice == choice::yes_no_cancel) flag += "cancel"; + command.push_back(flag); + if (_choice == choice::yes_no || _choice == choice::yes_no_cancel) { + m_mappings[0] = button::yes; + m_mappings[256] = button::no; + } + } + + command.push_back(text); + command.push_back("--title"); + command.push_back(title); + + // Must be after the above part + if (_choice == choice::ok_cancel) + command.insert(command.end(), {"--yes-label", "OK", "--no-label", "Cancel"}); + } + + if (flags(flag::is_verbose)) std::cerr << "pfd: " << command << std::endl; + + m_async->start_process(command); #endif - } - - inline button message::result() - { - int exit_code; - auto ret = m_async->result(&exit_code); - // osascript will say "button returned:Cancel\n" - // and others will just say "Cancel\n" - if (internal::ends_with(ret, "Cancel\n")) - return button::cancel; - if (internal::ends_with(ret, "OK\n")) - return button::ok; - if (internal::ends_with(ret, "Yes\n")) - return button::yes; - if (internal::ends_with(ret, "No\n")) - return button::no; - if (internal::ends_with(ret, "Abort\n")) - return button::abort; - if (internal::ends_with(ret, "Retry\n")) - return button::retry; - if (internal::ends_with(ret, "Ignore\n")) - return button::ignore; - if (m_mappings.count(exit_code) != 0) - return m_mappings[exit_code]; - return exit_code == 0 ? button::ok : button::cancel; - } - - // open_file implementation - - inline open_file::open_file(std::string const& title, - std::string const& default_path /* = "" */, - std::vector const& filters /* = { "All Files", "*" } */, - opt options /* = opt::none */) - : file_dialog(type::open, title, default_path, filters, options) - { - } - - inline open_file::open_file(std::string const& title, - std::string const& default_path, - std::vector const& filters, - bool allow_multiselect) - : open_file(title, default_path, filters, (allow_multiselect ? opt::multiselect : opt::none)) - { - } - - inline std::vector open_file::result() - { - return vector_result(); - } - - // save_file implementation - - inline save_file::save_file(std::string const& title, - std::string const& default_path /* = "" */, - std::vector const& filters /* = { "All Files", "*" } */, - opt options /* = opt::none */) - : file_dialog(type::save, title, default_path, filters, options) - { - } - - inline save_file::save_file(std::string const& title, - std::string const& default_path, - std::vector const& filters, - bool confirm_overwrite) - : save_file(title, default_path, filters, (confirm_overwrite ? opt::none : opt::force_overwrite)) - { - } - - inline std::string save_file::result() - { - return string_result(); - } - - // select_folder implementation - - inline select_folder::select_folder(std::string const& title, - std::string const& default_path /* = "" */, - opt options /* = opt::none */) - : file_dialog(type::folder, title, default_path, {}, options) - { - } - - inline std::string select_folder::result() - { - return string_result(); - } - -#endif // PFD_SKIP_IMPLEMENTATION - -} // namespace pfd \ No newline at end of file +} + +inline button message::result() { + int exit_code; + auto ret = m_async->result(&exit_code); + // osascript will say "button returned:Cancel\n" + // and others will just say "Cancel\n" + if (internal::ends_with(ret, "Cancel\n")) return button::cancel; + if (internal::ends_with(ret, "OK\n")) return button::ok; + if (internal::ends_with(ret, "Yes\n")) return button::yes; + if (internal::ends_with(ret, "No\n")) return button::no; + if (internal::ends_with(ret, "Abort\n")) return button::abort; + if (internal::ends_with(ret, "Retry\n")) return button::retry; + if (internal::ends_with(ret, "Ignore\n")) return button::ignore; + if (m_mappings.count(exit_code) != 0) return m_mappings[exit_code]; + return exit_code == 0 ? button::ok : button::cancel; +} + +// open_file implementation + +inline open_file::open_file(std::string const& title, std::string const& default_path /* = "" */, + std::vector const& filters /* = { "All Files", "*" } */, + opt options /* = opt::none */) + : file_dialog(type::open, title, default_path, filters, options) {} + +inline open_file::open_file(std::string const& title, std::string const& default_path, + std::vector const& filters, bool allow_multiselect) + : open_file(title, default_path, filters, (allow_multiselect ? opt::multiselect : opt::none)) {} + +inline std::vector open_file::result() { + return vector_result(); +} + +// save_file implementation + +inline save_file::save_file(std::string const& title, std::string const& default_path /* = "" */, + std::vector const& filters /* = { "All Files", "*" } */, + opt options /* = opt::none */) + : file_dialog(type::save, title, default_path, filters, options) {} + +inline save_file::save_file(std::string const& title, std::string const& default_path, + std::vector const& filters, bool confirm_overwrite) + : save_file(title, default_path, filters, + (confirm_overwrite ? opt::none : opt::force_overwrite)) {} + +inline std::string save_file::result() { + return string_result(); +} + +// select_folder implementation + +inline select_folder::select_folder(std::string const& title, + std::string const& default_path /* = "" */, + opt options /* = opt::none */) + : file_dialog(type::folder, title, default_path, {}, options) {} + +inline std::string select_folder::result() { + return string_result(); +} + +#endif // PFD_SKIP_IMPLEMENTATION + +} // namespace pfd \ No newline at end of file diff --git a/public/tools/ld.dyn/src/CommandLine.cc b/public/tools/ld.dyn/src/CommandLine.cc index 90a79796..377f22fa 100644 --- a/public/tools/ld.dyn/src/CommandLine.cc +++ b/public/tools/ld.dyn/src/CommandLine.cc @@ -8,40 +8,34 @@ /// @brief Library loader. -#define DYNLIB_FLAG "-dyn" - -SInt32 _NeMain(SInt32 argc, Char* argv[]) -{ - SCI_UNUSED(argc); - SCI_UNUSED(argv); - - PrintOut(nullptr, "%s", "ld.dyn: Dynamic Loader.\n"); - PrintOut(nullptr, "%s", "ld.dyn: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); - - for (SInt32 i = 1U; i < argc; ++i) - { - if (MmStrCmp(argv[i], DYNLIB_FLAG) == 0) - { - UIntPtr ret = RtlSpawnProcess(argv[i], 0, nullptr, nullptr, 0); - - if (0 < ret) - { - return RtlSpawnIB(ret); - } - - PrintOut(nullptr, "%s", "ld.dyn: Failed to load the library.\n"); - PrintOut(nullptr, "%s", "ld.dyn: Make sure the library is valid.\n"); - - break; - } - else - { - PrintOut(nullptr, "%s", "ld.dyn: Invalid argument.\n"); - PrintOut(nullptr, "%s", "ld.dyn: Use -dyn to load a dynamic library.\n"); - - break; - } - } - - return EXIT_FAILURE; +#define DYNLIB_FLAG "-dyn" + +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); + + PrintOut(nullptr, "%s", "ld.dyn: Dynamic Loader.\n"); + PrintOut(nullptr, "%s", "ld.dyn: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); + + for (SInt32 i = 1U; i < argc; ++i) { + if (MmStrCmp(argv[i], DYNLIB_FLAG) == 0) { + UIntPtr ret = RtlSpawnProcess(argv[i], 0, nullptr, nullptr, 0); + + if (0 < ret) { + return RtlSpawnIB(ret); + } + + PrintOut(nullptr, "%s", "ld.dyn: Failed to load the library.\n"); + PrintOut(nullptr, "%s", "ld.dyn: Make sure the library is valid.\n"); + + break; + } else { + PrintOut(nullptr, "%s", "ld.dyn: Invalid argument.\n"); + PrintOut(nullptr, "%s", "ld.dyn: Use -dyn to load a dynamic library.\n"); + + break; + } + } + + return EXIT_FAILURE; } diff --git a/public/tools/ld.fwrk/src/CommandLine.cc b/public/tools/ld.fwrk/src/CommandLine.cc index cdb57133..0fbaaf2e 100644 --- a/public/tools/ld.fwrk/src/CommandLine.cc +++ b/public/tools/ld.fwrk/src/CommandLine.cc @@ -8,13 +8,12 @@ /// @brief This program loads a code framework into Kernel's memory. -SInt32 _NeMain(SInt32 argc, Char* argv[]) -{ - SCI_UNUSED(argc); - SCI_UNUSED(argv); +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); - PrintOut(nullptr, "%s", "ld.fwrk: Framework Loader.\n"); - PrintOut(nullptr, "%s", "ld.fwrk: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); + PrintOut(nullptr, "%s", "ld.fwrk: Framework Loader.\n"); + PrintOut(nullptr, "%s", "ld.fwrk: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); - return EXIT_FAILURE; + return EXIT_FAILURE; } diff --git a/public/tools/mk.fwrk/Common.h b/public/tools/mk.fwrk/Common.h index 09e374ee..be016be6 100644 --- a/public/tools/mk.fwrk/Common.h +++ b/public/tools/mk.fwrk/Common.h @@ -1,12 +1,12 @@ /** - Sat Oct 26 07:03:28 AM CEST 2024 - (c) Amlal El Mahrouss. + Sat Oct 26 07:03:28 AM CEST 2024 + (c) Amlal El Mahrouss. */ #ifndef APPS_COMMON_H #define APPS_COMMON_H -#include #include +#include -#endif // APPS_COMMON_H +#endif // APPS_COMMON_H diff --git a/public/tools/mk.fwrk/Framework.h b/public/tools/mk.fwrk/Framework.h index ab03d0bc..9beb6da4 100644 --- a/public/tools/mk.fwrk/Framework.h +++ b/public/tools/mk.fwrk/Framework.h @@ -1,6 +1,6 @@ /** - Thu Oct 17 07:57:43 CEST 2024 - (c) Amlal El Mahrouss. + Thu Oct 17 07:57:43 CEST 2024 + (c) Amlal El Mahrouss. */ #ifndef APPS_FRAMEWORK_H @@ -11,7 +11,7 @@ #define kExecDirectory "bin/" #define kRsrcDirectory "xml/" #define kRootDirectory "/" -#define kFKExtension ".fwrk" -#define kAppExtension ".app" +#define kFKExtension ".fwrk" +#define kAppExtension ".app" -#endif // !APPS_FRAMEWORK_H +#endif // !APPS_FRAMEWORK_H diff --git a/public/tools/mk.fwrk/Steps.h b/public/tools/mk.fwrk/Steps.h index 51927def..3017b92e 100644 --- a/public/tools/mk.fwrk/Steps.h +++ b/public/tools/mk.fwrk/Steps.h @@ -1,6 +1,6 @@ /** - Thu Oct 17 07:57:43 CEST 2024 - (c) Amlal El Mahrouss. + Thu Oct 17 07:57:43 CEST 2024 + (c) Amlal El Mahrouss. */ #ifndef APPS_STEPS_H @@ -10,23 +10,22 @@ #include #define kStepsExtension ".stp" -#define kStepsStrLen (256U) +#define kStepsStrLen (256U) -#define kStepsMagic " pls" +#define kStepsMagic " pls" #define kStepsMagicLen (4U) -#define kStepsVersion (0x0100) +#define kStepsVersion (0x0100) #define kStepsMime "ne-application-kind/steps" -struct STEPS_COMMON_RECORD final -{ - Char magic[kStepsMagicLen]; - Char name[kStepsStrLen]; - Char company[kStepsStrLen]; - Char author[kStepsStrLen]; - SInt32 version; - SInt32 pages; - SInt32 check_page, eula_page; +struct STEPS_COMMON_RECORD final { + Char magic[kStepsMagicLen]; + Char name[kStepsStrLen]; + Char company[kStepsStrLen]; + Char author[kStepsStrLen]; + SInt32 version; + SInt32 pages; + SInt32 check_page, eula_page; }; -#endif // ifndef APPS_STEPS_H \ No newline at end of file +#endif // ifndef APPS_STEPS_H \ No newline at end of file diff --git a/public/tools/mk.fwrk/src/CommandLine.cc b/public/tools/mk.fwrk/src/CommandLine.cc index 8f142dfb..202f21bb 100644 --- a/public/tools/mk.fwrk/src/CommandLine.cc +++ b/public/tools/mk.fwrk/src/CommandLine.cc @@ -13,107 +13,97 @@ /// @brief This program makes a framework/app/steps directory for NeKernel OS. -static const Char* kStepsName = "Steps"; +static const Char* kStepsName = "Steps"; static const Char* kStepsAuthor = "John Doe"; static const Char* kStepsCompany = "Company, Inc"; -SInt32 _NeMain(SInt32 argc, Char* argv[]) -{ - CF::CFArray files; +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + CF::CFArray files; - auto ext = kFKExtension; + auto ext = kFKExtension; - for (SInt32 i = 2UL; i < argc; ++i) - { - if (MmStrCmp(argv[i], "-h") == 0) - { - PrintOut(nullptr, "%s", "make_app: Framework/Application Creation Tool.\n"); - PrintOut(nullptr, "%s", "make_app: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); + for (SInt32 i = 2UL; i < argc; ++i) { + if (MmStrCmp(argv[i], "-h") == 0) { + PrintOut(nullptr, "%s", "make_app: Framework/Application Creation Tool.\n"); + PrintOut(nullptr, "%s", "make_app: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); - PrintOut(nullptr, "%s", "make_app: -a: Application Directory.\n"); - PrintOut(nullptr, "%s", "make_app: -s: Steps (Setup pages) Directory.\n"); - PrintOut(nullptr, "%s", "make_app: -f: Framework Directory.\n"); + PrintOut(nullptr, "%s", "make_app: -a: Application Directory.\n"); + PrintOut(nullptr, "%s", "make_app: -s: Steps (Setup pages) Directory.\n"); + PrintOut(nullptr, "%s", "make_app: -f: Framework Directory.\n"); - return kErrorSuccess; - } + return kErrorSuccess; + } - if (MmStrCmp(argv[i], "--author") == 0) - { - MmCopyMemory(const_cast(kStepsAuthor), const_cast(argv[i + 1]), MmStrLen(argv[i + 1])); - continue; - } + if (MmStrCmp(argv[i], "--author") == 0) { + MmCopyMemory(const_cast(kStepsAuthor), const_cast(argv[i + 1]), + MmStrLen(argv[i + 1])); + continue; + } - if (MmStrCmp(argv[i], "--company") == 0) - { - MmCopyMemory(const_cast(kStepsCompany), const_cast(argv[i + 1]), MmStrLen(argv[i + 1])); - continue; - } + if (MmStrCmp(argv[i], "--company") == 0) { + MmCopyMemory(const_cast(kStepsCompany), const_cast(argv[i + 1]), + MmStrLen(argv[i + 1])); + continue; + } - if (MmStrCmp(argv[i], "--name") == 0) - { - MmCopyMemory(const_cast(kStepsName), const_cast(argv[i + 1]), MmStrLen(argv[i + 1])); - continue; - } + if (MmStrCmp(argv[i], "--name") == 0) { + MmCopyMemory(const_cast(kStepsName), const_cast(argv[i + 1]), + MmStrLen(argv[i + 1])); + continue; + } - if (MmStrCmp(argv[i], "-a") == 0) - { - ext = kAppExtension; - continue; - } - else if (MmStrCmp(argv[i], "-s") == 0) - { - ext = kStepsExtension; - continue; - } - else if (MmStrCmp(argv[i], "-f") == 0) - { - ext = kFKExtension; - continue; - } + if (MmStrCmp(argv[i], "-a") == 0) { + ext = kAppExtension; + continue; + } else if (MmStrCmp(argv[i], "-s") == 0) { + ext = kStepsExtension; + continue; + } else if (MmStrCmp(argv[i], "-f") == 0) { + ext = kFKExtension; + continue; + } - files[i] = argv[i]; - } + files[i] = argv[i]; + } - auto path = argv[1]; + auto path = argv[1]; - if (FsCreateDir(path)) - { - FsCreateDir(StrFmt("{}{}", path, kRootDirectory)); - FsCreateDir(StrFmt("{}{}", path, kExecDirectory)); + if (FsCreateDir(path)) { + FsCreateDir(StrFmt("{}{}", path, kRootDirectory)); + FsCreateDir(StrFmt("{}{}", path, kExecDirectory)); - if (MmStrCmp(ext, kStepsExtension) == 0) - { - FsCreateFile(StrFmt("{}{}{}{}", path, kRootDirectory, "_setup")); + if (MmStrCmp(ext, kStepsExtension) == 0) { + FsCreateFile(StrFmt("{}{}{}{}", path, kRootDirectory, "_setup")); - auto handle = IoOpenFile(StrFmt("{}{}{}{}", path, kRootDirectory, "_setup", kStepsExtension), nullptr); + auto handle = + IoOpenFile(StrFmt("{}{}{}{}", path, kRootDirectory, "_setup", kStepsExtension), nullptr); - struct STEPS_COMMON_RECORD record; + struct STEPS_COMMON_RECORD record; - MmFillMemory(&record, sizeof(STEPS_COMMON_RECORD), 0); + MmFillMemory(&record, sizeof(STEPS_COMMON_RECORD), 0); - MmCopyMemory(record.name, const_cast(kStepsName), kStepsStrLen); - MmCopyMemory(record.author, const_cast(kStepsAuthor), kStepsStrLen); - MmCopyMemory(record.company, const_cast(kStepsCompany), kStepsStrLen); + MmCopyMemory(record.name, const_cast(kStepsName), kStepsStrLen); + MmCopyMemory(record.author, const_cast(kStepsAuthor), kStepsStrLen); + MmCopyMemory(record.company, const_cast(kStepsCompany), kStepsStrLen); - MmCopyMemory(record.magic, const_cast(kStepsMagic), kStepsMagicLen); + MmCopyMemory(record.magic, const_cast(kStepsMagic), kStepsMagicLen); - record.version = kStepsVersion; + record.version = kStepsVersion; - IoWriteFile(handle, (void*)&record, sizeof(STEPS_COMMON_RECORD)); - IoCloseFile(handle); + IoWriteFile(handle, (void*) &record, sizeof(STEPS_COMMON_RECORD)); + IoCloseFile(handle); - handle = nullptr; - } + handle = nullptr; + } - for (auto i = 0UL; i < files.Count(); ++i) - { - auto& file = files[i]; + for (auto i = 0UL; i < files.Count(); ++i) { + auto& file = files[i]; - FsCopy(path, StrFmt("{}{}", path, file)); - } + FsCopy(path, StrFmt("{}{}", path, file)); + } - return kErrorSuccess; - } + return kErrorSuccess; + } - return kErrorInternal; + return kErrorInternal; } diff --git a/public/tools/mk.hefs/src/CommandLine.cc b/public/tools/mk.hefs/src/CommandLine.cc index 0c30e1b1..dd8be97f 100644 --- a/public/tools/mk.hefs/src/CommandLine.cc +++ b/public/tools/mk.hefs/src/CommandLine.cc @@ -8,10 +8,9 @@ /// @brief Placeholder program. -SInt32 _NeMain(SInt32 argc, Char* argv[]) -{ - SCI_UNUSED(argc); - SCI_UNUSED(argv); +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); - return EXIT_FAILURE; + return EXIT_FAILURE; } diff --git a/public/tools/mk.nefs/src/CommandLine.cc b/public/tools/mk.nefs/src/CommandLine.cc index 0c30e1b1..dd8be97f 100644 --- a/public/tools/mk.nefs/src/CommandLine.cc +++ b/public/tools/mk.nefs/src/CommandLine.cc @@ -8,10 +8,9 @@ /// @brief Placeholder program. -SInt32 _NeMain(SInt32 argc, Char* argv[]) -{ - SCI_UNUSED(argc); - SCI_UNUSED(argv); +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); - return EXIT_FAILURE; + return EXIT_FAILURE; } diff --git a/public/tools/open/src/CommandLine.cc b/public/tools/open/src/CommandLine.cc index b3779c71..f2378599 100644 --- a/public/tools/open/src/CommandLine.cc +++ b/public/tools/open/src/CommandLine.cc @@ -9,41 +9,39 @@ /// @brief This program opens an application from **OPEN_APP_BASE_PATH** /// @file CommandLine.cc -#define OPEN_APP_APP_FLAG "-a" +#define OPEN_APP_APP_FLAG "-a" #define OPEN_APP_HELP_FLAG "-h" #define OPEN_APP_BASE_PATH "/app/" -SInt32 _NeMain(SInt32 argc, Char* argv[]) -{ - if (argc == 1) - return EXIT_FAILURE; +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + if (argc == 1) return EXIT_FAILURE; - PrintOut(nullptr, "open: Open Loader.\n"); - PrintOut(nullptr, "open: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); + PrintOut(nullptr, "open: Open Loader.\n"); + PrintOut(nullptr, "open: © 2024-2025 Amlal El Mahrouss, All rights reserved.\n"); - for (SInt32 i = 1U; i < argc; ++i) - { - if (MmStrCmp(argv[i], OPEN_APP_HELP_FLAG) == 0) - { - PrintOut(nullptr, "open: %s: Application is being taken as the input (opens a PEF/PE32+ program depending on the CPU architecture).\n", OPEN_APP_APP_FLAG); + for (SInt32 i = 1U; i < argc; ++i) { + if (MmStrCmp(argv[i], OPEN_APP_HELP_FLAG) == 0) { + PrintOut(nullptr, + "open: %s: Application is being taken as the input (opens a PEF/PE32+ program " + "depending on the CPU architecture).\n", + OPEN_APP_APP_FLAG); - return EXIT_SUCCESS; - } - else if (MmStrCmp(argv[i], OPEN_APP_APP_FLAG) == 0) - { - if ((i + 1) == argc) - return EXIT_FAILURE; - else if ((i + 2) == argc) - return EXIT_FAILURE; + return EXIT_SUCCESS; + } else if (MmStrCmp(argv[i], OPEN_APP_APP_FLAG) == 0) { + if ((i + 1) == argc) + return EXIT_FAILURE; + else if ((i + 2) == argc) + return EXIT_FAILURE; - Char base_path[FILE_MAX_LEN] = OPEN_APP_BASE_PATH; - MmCopyMemory(base_path + MmStrLen(OPEN_APP_BASE_PATH), argv[i + 1], MmStrLen(argv[i + 1])); + Char base_path[FILE_MAX_LEN] = OPEN_APP_BASE_PATH; + MmCopyMemory(base_path + MmStrLen(OPEN_APP_BASE_PATH), argv[i + 1], MmStrLen(argv[i + 1])); - UIntPtr ret = RtlSpawnProcess(StrFmt("{}/dist/{]}", base_path, argv[i + 2]), 0, nullptr, nullptr, 0); + UIntPtr ret = + RtlSpawnProcess(StrFmt("{}/dist/{]}", base_path, argv[i + 2]), 0, nullptr, nullptr, 0); - return ret; - } - } + return ret; + } + } - return EXIT_FAILURE; + return EXIT_FAILURE; } -- cgit v1.2.3 From a2bc9eee9184a81d80ab54a09bd239ed26d5293e Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 25 Apr 2025 15:24:52 +0200 Subject: dev, kernel: improve nefs format method, hefs format method. Signed-off-by: Amlal --- dev/boot/BootKit/BootKit.h | 39 +------- dev/kernel/FSKit/HeFS.h | 18 ++-- dev/kernel/FSKit/NeFS.h | 9 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 +- dev/kernel/KernelKit/DriveMgr.h | 2 +- dev/kernel/NewKit/Utils.h | 4 +- dev/kernel/src/FS/HeFS.cc | 98 ++++++++++++++---- dev/kernel/src/FS/NeFS.cc | 167 ++++++++----------------------- dev/kernel/src/WideUtils.cc | 18 +++- docs/tex/hefs.tex | 2 +- modules_pio_x64.sh | 2 +- 11 files changed, 158 insertions(+), 203 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 76821b20..2bf95696 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -275,8 +275,6 @@ class BDiskFormatFactory final { /// @brief Format disk with a specific partition scheme. /// @param part_name partition Name -/// @param blob blos. -/// @param blob_sz n blobs (n * sizeof(blob_struct)). /// @retval True disk has been formatted. /// @retval False failed to format. template @@ -292,42 +290,17 @@ inline Boolean BDiskFormatFactory::Format(const Char* part_name) { return false; } - NEFS_ROOT_PARTITION_BLOCK part{}; - - CopyMem(part.Ident, kNeFSIdent, kNeFSIdentLen - 1); - CopyMem(part.PartitionName, part_name, StrLen(part_name)); - - part.Version = kNeFSVersionInteger; - part.CatalogCount = blob_sz; - part.Kind = BootDev::kSectorSize; - part.SectorSize = kATASectorSize; - part.FreeCatalog = fDiskDev.GetSectorsCount() / sizeof(NEFS_CATALOG_STRUCT); - part.SectorCount = fDiskDev.GetSectorsCount(); - part.FreeSectors = fDiskDev.GetSectorsCount(); - part.StartCatalog = kNeFSCatalogStartAddress; - part.DiskSize = fDiskDev.GetDiskSize(); - part.Flags = kNeFSPartitionTypeBoot | kNeFSPartitionTypeStandard; - - BootTextWriter writer; - - writer << "BootZ: Partition name: " << part.PartitionName << "\r"; - writer << "BootZ: Start: " << part.StartCatalog << "\r"; - writer << "BootZ: Number of catalogs: " << part.CatalogCount << "\r"; - writer << "BootZ: Free catalog: " << part.FreeCatalog << "\r"; - writer << "BootZ: Free sectors: " << part.FreeSectors << "\r"; - writer << "BootZ: Sector size: " << part.SectorSize << "\r"; - EPM_PART_BLOCK epm_boot{}; - const auto kFsName = "NeFS"; + const auto kFsName = "HeFS"; const auto kBlockName = "OS (EPM)"; epm_boot.FsVersion = kNeFSVersionInteger; epm_boot.LbaStart = kNeFSRootCatalogStartAddress; epm_boot.LbaEnd = fDiskDev.GetDiskSize(); - epm_boot.SectorSz = part.SectorSize; + epm_boot.SectorSz = BootDev::kSectorSize; epm_boot.Kind = kEPMNeKernel; - epm_boot.NumBlocks = part.CatalogCount; + epm_boot.NumBlocks = 1; epm_boot.Guid = kEPMNilGuid; @@ -342,11 +315,7 @@ inline Boolean BDiskFormatFactory::Format(const Char* part_name) { fDiskDev.Write((Char*) &epm_boot, sizeof(EPM_PART_BLOCK)); - fDiskDev.Leak().mBase = kNeFSRootCatalogStartAddress; - fDiskDev.Leak().mSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - - fDiskDev.Write((Char*) &part, sizeof(NEFS_ROOT_PARTITION_BLOCK)); - + BootTextWriter writer; writer.Write(L"BootZ: Drive is EPM formatted.\r"); #elif defined(BOOTZ_VEPM_SUPPORT) NE_UNUSED(part_name); diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index e4da9a47..63725f04 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -100,7 +100,7 @@ struct PACKED HEFS_BOOT_NODE final { Kernel::UInt64 fSectorCount; /// @brief Number of sectors in the filesystem. Kernel::UInt64 fSectorSize; /// @brief Size of the sector. Kernel::UInt32 fChecksum; /// @brief Checksum of the boot node. - Kernel::UInt8 fDriveKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical + Kernel::UInt8 fDiskKind; /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical /// Drive, etc). Kernel::UInt8 fEncoding; /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc). Kernel::UInt64 fStartIND; /// @brief Start of the INode tree. @@ -332,7 +332,7 @@ inline const Char* hefs_file_flags_to_string(UInt32 flags) noexcept { } } // namespace Kernel::Detail -namespace Kernel { +namespace Kernel::HeFS { /// @brief HeFS filesystem parser class. /// @details This class is used to parse the HeFS filesystem. class HeFileSystemParser final { @@ -351,17 +351,13 @@ class HeFileSystemParser final { /// @brief Make a EPM+HeFS drive out of the disk. /// @param drive The drive to write on. /// @return If it was sucessful, see err_local_get(). - _Output Bool FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, - _Input const Int32 flags, const Char* part_name); - - /// @brief Make a GPT+HeFS drive out of the disk. - /// @param drive The drive to write on. - /// @return If it was sucessful, see err_local_get(). - _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, - _Input const Int32 flags, const Char* part_name); + _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, + const Utf16Char* part_name); public: UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this /// filesystem is mounted on. }; -} // namespace Kernel \ No newline at end of file + +Boolean fs_init_hefs(Void) noexcept; +} // namespace Kernel::HeFS \ No newline at end of file diff --git a/dev/kernel/FSKit/NeFS.h b/dev/kernel/FSKit/NeFS.h index 425ab051..2235ca4f 100644 --- a/dev/kernel/FSKit/NeFS.h +++ b/dev/kernel/FSKit/NeFS.h @@ -31,6 +31,8 @@ default. #define kNeFSInvalidCatalog (-1) #define kNeFSCatalogNameLen (256) +#define kNeFSVolumeName "NeFS Volume" + #define kNeFSMinimumDiskSize (mib_cast(8)) #define kNeFSSectorSz (512) @@ -305,11 +307,8 @@ class NeFileSystemParser final { /// @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 FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba end_lba, - _Input const Int32 flags, const Char* part_name); - - _Output Bool FormatGPT(_Input _Output DriveTrait* drive, _Input const Lba end_lba, - _Input const Int32 flags, const Char* part_name); + _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, + const Char* part_name); public: UInt32 mDriveIndex{kNeFSSubDriveA}; diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 82020520..8f4b55cb 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -105,7 +105,7 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { hal_pre_init_scheduler(); - Kernel::NeFS::fs_init_nefs(); + Kernel::HeFS::fs_init_hefs(); Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); diff --git a/dev/kernel/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h index e0bed8f5..263b728e 100644 --- a/dev/kernel/KernelKit/DriveMgr.h +++ b/dev/kernel/KernelKit/DriveMgr.h @@ -62,7 +62,7 @@ struct DriveTrait final { } fPacket; Lba fLbaStart{0}, fLbaEnd{0}; - SizeT fSectorSz{512}; + SizeT fSectorSz{kDriveSectorSz}; Void (*fInput)(DrivePacket packet); Void (*fOutput)(DrivePacket packet); diff --git a/dev/kernel/NewKit/Utils.h b/dev/kernel/NewKit/Utils.h index ca1c7d1c..2f0fc60b 100644 --- a/dev/kernel/NewKit/Utils.h +++ b/dev/kernel/NewKit/Utils.h @@ -17,7 +17,6 @@ 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 wrt_string_len(const Utf16Char* 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(Char chr); @@ -27,4 +26,7 @@ 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); + +Int wrt_copy_memory(const voidPtr src, voidPtr dst, Size len); +Size wrt_string_len(const Utf16Char* str); } // namespace Kernel diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 88837273..5beb8b3f 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -4,6 +4,7 @@ ------------------------------------------- */ +#include "NewKit/Defines.h" #ifdef __FSKIT_INCLUDES_HEFS__ #include @@ -636,34 +637,95 @@ namespace Detail { /// real-time. /// @note This is certainly take longer to format a disk with it, but worth-it in the long run. -namespace Kernel { +namespace Kernel::HeFS { /// @brief Make a EPM+HeFS drive out of the disk. /// @param drive The drive to write on. /// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, - _Input const Lba end_lba, _Input const Int32 flags, - const Char* part_name) { +_Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, + const Utf16Char* part_name) { NE_UNUSED(drive); - NE_UNUSED(end_lba); NE_UNUSED(flags); NE_UNUSED(part_name); - return NO; + // verify disk. + drive->fVerify(drive->fPacket); + + // if disk isn't good, then error out. + if (false == drive->fPacket.fPacketGood) { + err_global_get() = kErrorDiskIsCorrupted; + return false; + } + + + HEFS_BOOT_NODE* root = new HEFS_BOOT_NODE(); + + if (!root) { + kout << "Error: Failed to allocate memory for boot node.\r"; + return NO; + } + + rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet")); + + wrt_copy_memory((VoidPtr) part_name, root->fVolName, wrt_string_len(part_name)); + rt_copy_memory((VoidPtr) kHeFSMagic, root->fMagic, sizeof(kHeFSMagic)); + + root->fBadSectors = 0; + + root->fSectorCount = drv_get_sector_count(); + + root->fSectorSize = drive->fSectorSz; + + root->fStartIND = drive->fLbaStart + sizeof(HEFS_BOOT_NODE); + root->fEndIND = drive->fLbaEnd; + + root->fINDCount = root->fEndIND - root->fStartIND; + + root->fDiskSize = drv_get_size(); + root->fDiskStatus = kHeFSStatusUnlocked; + + root->fDiskFlags = flags; + + if (drive->fKind & kMassStorageDrive) { + } else if (drive->fKind & kHeFSOpticalDrive) { + root->fDiskKind = kHeFSOpticalDrive; + } else { + root->fDiskKind = kHeFSUnknown; + } + + root->fReserved = 0; + root->fReserved2 = 0; + root->fReserved3 = 0; + root->fReserved4 = 0; + + root->fChecksum = 0; + + root->fVID = kHeFSInvalidVID; + + drive->fPacket.fPacketLba = drive->fLbaStart; + drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketContent = root; + + drive->fOutput(drive->fPacket); + + return YES; } -/// @brief Make a EPM+HeFS drive out of the disk. -/// @param drive The drive to write on. -/// @return If it was sucessful, see err_local_get(). -_Output Bool HeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, - _Input const Lba end_lba, _Input const Int32 flags, - const Char* part_name) { - NE_UNUSED(drive); - NE_UNUSED(end_lba); - NE_UNUSED(flags); - NE_UNUSED(part_name); +Boolean fs_init_hefs(Void) noexcept { + kout << "Creating main disk...\r"; - return NO; + auto drv = io_construct_main_drive(); + + if (drv.fPacket.fPacketReadOnly == YES) + ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main filesystem cannot be mounted."); + + HeFileSystemParser parser; + parser.Format(&drv, kHeFSEncodingUTF16, kHeFSDefaultVoluneName); + + return YES; } -} // namespace Kernel +} // namespace Kernel::HeFS #endif // ifdef __FSKIT_INCLUDES_HEFS__ diff --git a/dev/kernel/src/FS/NeFS.cc b/dev/kernel/src/FS/NeFS.cc index d0934f94..e0cdc71b 100644 --- a/dev/kernel/src/FS/NeFS.cc +++ b/dev/kernel/src/FS/NeFS.cc @@ -415,25 +415,14 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char return nullptr; } -_Output Bool NeFileSystemParser::FormatGPT(_Input _Output DriveTrait* drive, - _Input const Lba end_lba, _Input const Int32 flags, - const Char* part_name) { - NE_UNUSED(drive); - NE_UNUSED(end_lba); - NE_UNUSED(flags); - NE_UNUSED(part_name); - - (Void)(kout << "FormatGPT: Not implemented yet.\r"); - - return NO; -} - /// @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::FormatEPM(_Input _Output DriveTrait* drive, _Input const Lba endLba, - _Input const Int32 flags, const Char* part_name) { - if (*part_name == 0 || endLba == 0) return false; +bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, + const Char* part_name) { + if (*part_name == 0) return false; + + NE_UNUSED(flags); // verify disk. drive->fVerify(drive->fPacket); @@ -449,7 +438,7 @@ bool NeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, _Input cons Char fs_buf[sizeof(NEFS_ROOT_PARTITION_BLOCK)] = {0}; - Lba start = kNeFSRootCatalogStartAddress; + Lba start = drive->fLbaStart; drive->fPacket.fPacketContent = fs_buf; drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); @@ -457,129 +446,48 @@ bool NeFileSystemParser::FormatEPM(_Input _Output DriveTrait* drive, _Input cons drive->fInput(drive->fPacket); - if (flags & kNeFSPartitionTypeBoot) { - // make it bootable when needed. - Char buf_epm[kNeFSSectorSz] = {0}; - - EPM_PART_BLOCK* epm_boot = (EPM_PART_BLOCK*) buf_epm; - - // Write a new EPM entry. - - constexpr auto kFsName = "NeFS"; - constexpr auto kBlockName = "NeKernel:"; - - epm_boot->FsVersion = kNeFSVersionInteger; - epm_boot->LbaStart = start; - epm_boot->SectorSz = kNeFSSectorSz; - - rt_copy_memory(reinterpret_cast(const_cast(kFsName)), epm_boot->Fs, - rt_string_len(kFsName)); - rt_copy_memory(reinterpret_cast(const_cast(kBlockName)), epm_boot->Name, - rt_string_len(kBlockName)); - rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epm_boot->Magic, - rt_string_len(kEPMMagic)); - - Lba outEpmLba = kEPMBootBlockLba; - - Char buf[kNeFSSectorSz] = {0}; - - Lba prevStart = 0; - SizeT cnt = 0; - - while (drive->fPacket.fPacketGood) { - drive->fPacket.fPacketContent = buf; - drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); - drive->fPacket.fPacketLba = outEpmLba; - - drive->fInput(drive->fPacket); - - if (buf[0] == 0) { - epm_boot->LbaStart = prevStart; - - if (epm_boot->LbaStart) epm_boot->LbaStart = outEpmLba; - - epm_boot->LbaEnd = endLba; - epm_boot->NumBlocks = cnt; - - drive->fPacket.fPacketContent = buf_epm; - drive->fPacket.fPacketSize = sizeof(EPM_PART_BLOCK); - drive->fPacket.fPacketLba = outEpmLba; - - drive->fOutput(drive->fPacket); + NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf; - break; - } else { - prevStart = ((EPM_PART_BLOCK*) buf)->LbaStart + ((EPM_PART_BLOCK*) buf)->LbaEnd; - } - - outEpmLba += sizeof(EPM_PART_BLOCK); - ++cnt; - } - } - - // disk isnt faulty and data has been fetched. - while (drive->fPacket.fPacketGood) { - NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf; - - // check for an empty partition here. - if (part_block->PartitionName[0] == 0 && - rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) { - // partition is free and valid. - - part_block->Version = kNeFSVersionInteger; - - const auto kNeFSUntitledHD = part_name; - - rt_copy_memory((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen); - - rt_copy_memory((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName, - rt_string_len(kNeFSUntitledHD)); + const auto kNeFSUntitledHD = part_name; - SizeT sectorCount = drv_get_sector_count(); - SizeT diskSize = drv_get_size(); + rt_copy_memory((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen); - part_block->Kind = kNeFSPartitionTypeStandard; - part_block->StartCatalog = kNeFSCatalogStartAddress; - part_block->Flags = kNeFSPartitionTypeStandard; - part_block->CatalogCount = sectorCount / sizeof(NEFS_CATALOG_STRUCT); - part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT); - part_block->SectorCount = sectorCount; - part_block->DiskSize = diskSize; - part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT); + rt_copy_memory((VoidPtr) kNeFSUntitledHD, (VoidPtr) part_block->PartitionName, + rt_string_len(kNeFSUntitledHD)); - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = kNeFSRootCatalogStartAddress; + SizeT sectorCount = drv_get_sector_count(); + SizeT diskSize = drv_get_size(); - drive->fOutput(drive->fPacket); + part_block->Version = kNeFSVersionInteger; - (Void)(kout << "drive kind: " << drive->fProtocol() << kendl); + part_block->Kind = kNeFSPartitionTypeStandard; + part_block->StartCatalog = start + sizeof(NEFS_ROOT_PARTITION_BLOCK); + part_block->Flags = 0UL; + part_block->CatalogCount = sectorCount / sizeof(NEFS_CATALOG_STRUCT); + part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT); + part_block->SectorCount = sectorCount; + part_block->DiskSize = diskSize; + part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT); - (Void)(kout << "partition name: " << part_block->PartitionName << kendl); - (Void)(kout << "start: " << 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); - - // write the root catalog. - this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); - - return true; - } + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); + drive->fPacket.fPacketLba = start; - kout << "partition block already exists.\r"; + drive->fOutput(drive->fPacket); - start += part_block->DiskSize; + (Void)(kout << "drive kind: " << drive->fProtocol() << kendl); - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = sizeof(NEFS_ROOT_PARTITION_BLOCK); - drive->fPacket.fPacketLba = start; + (Void)(kout << "partition name: " << part_block->PartitionName << kendl); + (Void)(kout << "start: " << 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); - drive->fInput(drive->fPacket); - } + // write the root catalog. + this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); - return false; + return true; } /// @brief Writes the data fork into a specific catalog. @@ -971,6 +879,9 @@ Boolean fs_init_nefs(Void) noexcept { if (kMountpoint.A().fPacket.fPacketReadOnly == YES) ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main filesystem cannot be mounted."); + NeFileSystemParser parser; + parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName); + return YES; } } // namespace Kernel::NeFS diff --git a/dev/kernel/src/WideUtils.cc b/dev/kernel/src/WideUtils.cc index e6c5a533..0f628e00 100644 --- a/dev/kernel/src/WideUtils.cc +++ b/dev/kernel/src/WideUtils.cc @@ -10,8 +10,24 @@ namespace Kernel { Size wrt_string_len(const Utf16Char* str) { SizeT len{0}; - while (str[len] != 0) ++len; + while (str[len] != u'\0') ++len; return len; } + +Int wrt_copy_memory(const voidPtr src, voidPtr dst, Size len) { + Utf16Char* srcChr = reinterpret_cast(src); + Utf16Char* dstChar = reinterpret_cast(dst); + + Size index = 0; + + while (index < len) { + dstChar[index] = srcChr[index]; + ++index; + } + + dstChar[index] = 0; + + return index; +} } // namespace Kernel \ No newline at end of file diff --git a/docs/tex/hefs.tex b/docs/tex/hefs.tex index d20dfa5e..c9f7886d 100644 --- a/docs/tex/hefs.tex +++ b/docs/tex/hefs.tex @@ -45,7 +45,7 @@ HeFS is a custom filesystem developed as part of the NeKernel project. It offers \verb|fVersion| & \verb|UInt32| & Filesystem version (e.g., 0x0100) \\ \verb|fSectorCount| & \verb|UInt64| & Total sector count \\ \verb|fSectorSize| & \verb|UInt64| & Size of each sector \\ -\verb|fDriveKind| & \verb|UInt8| & Type of drive (e.g., HDD, SSD, USB) \\ +\verb|fDiskKind| & \verb|UInt8| & Type of drive (e.g., HDD, SSD, USB) \\ \verb|fEncoding| & \verb|UInt8| & Encoding mode (UTF-8, UTF-16, etc.) \\ \verb|fStartIND| & \verb|UInt64| & Starting LBA of inode tree \\ \verb|fEndIND| & \verb|UInt64| & Ending LBA of inode tree \\ diff --git a/modules_pio_x64.sh b/modules_pio_x64.sh index 49f0e667..b091704e 100755 --- a/modules_pio_x64.sh +++ b/modules_pio_x64.sh @@ -5,7 +5,7 @@ # 04/05/25: Improve and fix script. cd dev/boot/modules/SysChk -btb amd64-pio-gpt.json +btb amd64-pio-epm.json cd ../ cd BootNet btb amd64.json \ No newline at end of file -- cgit v1.2.3 From a3532ede1996f43acb4c13b6836304892f684427 Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 25 Apr 2025 22:58:15 +0200 Subject: dev: fix readme clone link. Signed-off-by: Amlal --- README.md | 4 ++-- dev/kernel/src/FS/HeFS.cc | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'dev/kernel/src') diff --git a/README.md b/README.md index 02326499..95b25ec3 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ A documentation for NeKernel is available here: https://nekernel-org.github.io/d - [CLANG](https://clang.llvm.org/) - [NASM](https://nasm.us/) - [GIT](https://git-scm.com/) -- [BTB](https://github.com/amlel-el-mahrouss/btb) +- [BTB](https://github.com/nekernel-org/btb) ## Notice for Contributors: @@ -45,7 +45,7 @@ A documentation for NeKernel is available here: https://nekernel-org.github.io/d ## Getting Started: ```sh -git clone git@github.com:amlel-el-mahrouss/nekernel.git +git clone git@github.com:nekernel-org/nekernel.git cd nekernel ./setup_x64.sh ./debug_ata_x64.sh # Generic ATA PIO target diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 5beb8b3f..9037a1e2 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -649,14 +649,13 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input // verify disk. drive->fVerify(drive->fPacket); - + // if disk isn't good, then error out. if (false == drive->fPacket.fPacketGood) { err_global_get() = kErrorDiskIsCorrupted; return false; } - HEFS_BOOT_NODE* root = new HEFS_BOOT_NODE(); if (!root) { -- cgit v1.2.3 From fb423f12385d1bc29fe5b7698b07126a7dcff12e Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 26 Apr 2025 08:34:59 +0200 Subject: dev, kernel: refactor rtl_init_object inside codebase. Signed-off-by: Amlal --- dev/kernel/NewKit/Macros.h | 8 ++++---- dev/kernel/src/Json.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/NewKit/Macros.h b/dev/kernel/NewKit/Macros.h index b89f5d67..e8f18c24 100644 --- a/dev/kernel/NewKit/Macros.h +++ b/dev/kernel/NewKit/Macros.h @@ -141,8 +141,8 @@ #define BOOL Kernel::Boolean -#ifdef rtl_init_object -#undef rtl_init_object -#endif // ifdef rtl_init_object +#ifdef RTL_INIT_OBJECT +#undef RTL_INIT_OBJECT +#endif // ifdef RTL_INIT_OBJECT -#define rtl_init_object(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) +#define RTL_INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/dev/kernel/src/Json.cc b/dev/kernel/src/Json.cc index 5939e207..9264b2b8 100644 --- a/dev/kernel/src/Json.cc +++ b/dev/kernel/src/Json.cc @@ -7,4 +7,4 @@ #include /// @brief Undefined object, is null in length. -rtl_init_object(Kernel::Json::kNull, Kernel::Json); +RTL_INIT_OBJECT(Kernel::Json::kNull, Kernel::Json); -- cgit v1.2.3 From 0af5f147b67140ebb7b561fdde273c5123c61df8 Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 26 Apr 2025 10:37:56 +0200 Subject: dev, kernel: saving work in progress code regarding scheduler and filesystem. Signed-off-by: Amlal --- dev/kernel/FSKit/HeFS.h | 7 +- dev/kernel/KernelKit/CoreProcessScheduler.h | 10 +- dev/kernel/src/FS/HeFS.cc | 280 +++++++++++++++++++++++++++- dev/kernel/src/IPEFDylibObject.cc | 2 +- dev/kernel/src/ProcessTeam.cc | 53 ------ dev/kernel/src/UserProcessScheduler.cc | 4 +- dev/kernel/src/UserProcessTeam.cc | 53 ++++++ 7 files changed, 348 insertions(+), 61 deletions(-) delete mode 100644 dev/kernel/src/ProcessTeam.cc create mode 100644 dev/kernel/src/UserProcessTeam.cc (limited to 'dev/kernel/src') diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 63725f04..895422a6 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -168,7 +168,7 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final { Kernel::UInt32 fChecksum, fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum. - Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps and allocation status. Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). @@ -354,6 +354,11 @@ class HeFileSystemParser final { _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, const Utf16Char* part_name); + _Output Bool CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags, const Utf16Char* dir); + + _Output Bool CreateFile(_Input DriveTrait* drive, _Input const Int32 flags, const Utf16Char* dir, + const Utf16Char* name); + public: UInt32 mDriveIndex{MountpointInterface::kDriveIndexA}; /// @brief The drive index which this /// filesystem is mounted on. diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h index 3b581ffe..42def9fc 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -115,12 +115,18 @@ using ImagePtr = VoidPtr; struct PROCESS_IMAGE final { explicit PROCESS_IMAGE() = default; +private: + friend USER_PROCESS; + friend KERNEL_PROCESS; + friend class UserProcessScheduler; + ImagePtr fCode; ImagePtr fBlob; - Bool HasCode() { return this->fCode != nullptr; } +public: + Bool HasCode() const { return this->fCode != nullptr; } - Bool HasImage() { return this->fBlob != nullptr; } + Bool HasImage() const { return this->fBlob != nullptr; } ErrorOr Leak() { if (this->fCode) { diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 9037a1e2..71d1d1d4 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -4,7 +4,6 @@ ------------------------------------------- */ -#include "NewKit/Defines.h" #ifdef __FSKIT_INCLUDES_HEFS__ #include @@ -289,6 +288,109 @@ namespace Detail { return 0; } + STATIC _Output BOOL hefs_allocate_index_directory_node(HEFS_BOOT_NODE* root, DriveTrait* mnt, + HEFS_INDEX_NODE_DIRECTORY* dir) noexcept { + if (root && mnt) { + HEFS_INDEX_NODE_DIRECTORY* parent = new HEFS_INDEX_NODE_DIRECTORY(); + + if (!parent) { + kout << "Error: Failed to allocate memory for index node.\r"; + return NO; + } + + auto start = root->fStartIND; + + while (YES) { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = parent; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) { + delete parent; + return NO; + } + + if (parent->fDeleted) { + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fOutput(mnt->fPacket); + + return YES; + } + + hefsi_traverse_tree(parent, start); + } + + return YES; + } + + err_global_get() = kErrorFileNotFound; + return NO; + } + + STATIC _Output HEFS_INDEX_NODE_DIRECTORY* hefs_fetch_index_node_directory( + HEFS_BOOT_NODE* root, DriveTrait* mnt, const Utf16Char* dir_name) { + if (root && mnt) { + HEFS_INDEX_NODE_DIRECTORY* dir = new HEFS_INDEX_NODE_DIRECTORY(); + + auto start = root->fStartIND; + auto end = root->fEndIND; + + auto hop_watch = 0; + + while (YES) { + if (start > end) { + kout << "Error: Invalid start/end values.\r"; + break; + } + + if (hop_watch > 100) { + kout << "Error: Hop watch exceeded, filesystem is stalling.\r"; + break; + } + + if (start == 0) { + ++hop_watch; + start = root->fStartIND; + } + + mnt->fPacket.fPacketLba = start; + mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + mnt->fPacket.fPacketContent = dir; + + mnt->fInput(mnt->fPacket); + + if (!mnt->fPacket.fPacketGood) { + delete dir; + + dir = nullptr; + + err_global_get() = kErrorFileNotFound; + + return nullptr; + } + + if (dir->fKind == kHeFSFileKindDirectory) { + if (KStringBuilder::Equals(dir_name, dir->fName)) { + return dir; + } + } + + hefsi_traverse_tree(dir, start); + } + + err_global_get() = kErrorSuccess; + return dir; + } + + err_global_get() = kErrorFileNotFound; + return nullptr; + } + /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. /// @param mnt The drive to read from. @@ -709,7 +811,178 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input drive->fOutput(drive->fPacket); - return YES; + delete root; + root = nullptr; + + if (drive->fPacket.fPacketGood) return YES; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; +} + +/// @brief Create a new directory on the disk. +/// @param drive The drive 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::CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf16Char* dir) { + NE_UNUSED(drive); + NE_UNUSED(flags); + NE_UNUSED(dir); + + HEFS_BOOT_NODE* root = new HEFS_BOOT_NODE(); + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + + if (!root || !node) { + kout << "Error: Failed to allocate memory for boot node.\r"; + + if (node) delete node; + if (root) delete root; + + return NO; + } + + rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE)); + + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet")); + + drive->fPacket.fPacketLba = drive->fLbaStart; + drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketContent = root; + + drive->fInput(drive->fPacket); + + auto dirent = Detail::hefs_fetch_index_node_directory(root, drive, dir); + + if (dirent) { + kout << "Error: Directory already exists.\r"; + + delete dirent; + dirent = nullptr; + + delete node; + delete root; + + return NO; + } + + dirent = new HEFS_INDEX_NODE_DIRECTORY(); + + rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + wrt_copy_memory((VoidPtr) dir, dirent->fName, wrt_string_len(dir)); + + dirent->fAccessed = 0; + dirent->fCreated = 0; + dirent->fDeleted = 0; + dirent->fModified = 0; + dirent->fEntryCount = 0; + dirent->fKind = kHeFSFileKindDirectory; + dirent->fFlags = flags; + dirent->fChecksum = 0; + + if (Detail::hefs_allocate_index_directory_node(root, drive, dirent)) { + delete dirent; + dirent = nullptr; + + delete node; + delete root; + + return YES; + } + + delete dirent; + dirent = nullptr; + + delete node; + delete root; + + return NO; +} + +/// @brief Create a new file on the disk. +/// @param drive The drive 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::CreateFile(_Input DriveTrait* drive, _Input const Int32 flags, + const Utf16Char* dir, const Utf16Char* name) { + NE_UNUSED(drive); + NE_UNUSED(flags); + NE_UNUSED(dir); + NE_UNUSED(name); + + HEFS_BOOT_NODE* root = new HEFS_BOOT_NODE(); + HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); + + if (!root || !node) { + kout << "Error: Failed to allocate memory for boot node.\r"; + + if (node) delete node; + if (root) delete root; + + return NO; + } + + rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + rt_set_memory(node, 0, sizeof(HEFS_INDEX_NODE)); + + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/hefs-packet")); + + drive->fPacket.fPacketLba = drive->fLbaStart; + drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketContent = root; + + drive->fInput(drive->fPacket); + + auto dirent = Detail::hefs_fetch_index_node_directory(root, drive, dir); + + if (!dirent) { + kout << "Error: Directory not found.\r"; + + delete node; + delete root; + + return NO; + } + + delete dirent; + dirent = nullptr; + + if (KStringBuilder::Equals(name, kHeFSSearchAllStr)) { + kout << "Error: Invalid file name.\r"; + + delete node; + delete root; + + return NO; + } + + node->fAccessed = 0; + node->fCreated = 0; + node->fDeleted = 0; + node->fModified = 0; + node->fSize = 0; + node->fKind = kHeFSFileKindRegular; + node->fFlags = flags; + node->fChecksum = 0; + + wrt_copy_memory((VoidPtr) name, node->fName, wrt_string_len(name)); + + if (Detail::hefs_allocate_index_node(root, drive, dir, node)) { + delete node; + delete root; + + return YES; + } + + return NO; } Boolean fs_init_hefs(Void) noexcept { @@ -723,6 +996,9 @@ Boolean fs_init_hefs(Void) noexcept { HeFileSystemParser parser; parser.Format(&drv, kHeFSEncodingUTF16, kHeFSDefaultVoluneName); + parser.CreateDirectory(&drv, kHeFSEncodingUTF16, u"/"); + parser.CreateFile(&drv, kHeFSEncodingUTF16, u"/", u"boot.log"); + return YES; } } // namespace Kernel::HeFS diff --git a/dev/kernel/src/IPEFDylibObject.cc b/dev/kernel/src/IPEFDylibObject.cc index f064dbac..f9cd758c 100644 --- a/dev/kernel/src/IPEFDylibObject.cc +++ b/dev/kernel/src/IPEFDylibObject.cc @@ -60,7 +60,7 @@ EXTERN_C IDylibRef rtl_init_dylib_pef(USER_PROCESS& process) { return nullptr; } - dll_obj->Get()->ImageObject = process.Image.fBlob; + dll_obj->Get()->ImageObject = process.Image.LeakBlob().Leak().Leak(); if (!dll_obj->Get()->ImageObject) { delete dll_obj->Get(); diff --git a/dev/kernel/src/ProcessTeam.cc b/dev/kernel/src/ProcessTeam.cc deleted file mode 100644 index 7acbcf8d..00000000 --- a/dev/kernel/src/ProcessTeam.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file UserProcessTeam.cc -/// @brief Process teams implementation. -/***********************************************************************************/ - -#include - -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].Status = ProcessStatusKind::kKilled; - } - - this->mProcessCount = 0UL; -} - -/***********************************************************************************/ -/// @brief Process list array getter. -/// @return The list of process to schedule. -/***********************************************************************************/ - -Array& 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& UserProcessTeam::AsRef() { - return this->mCurrentProcess; -} -} // namespace Kernel - -// last rev 05-03-24 diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index ae7bbfb8..bc2cc8e2 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -498,7 +498,7 @@ SizeT UserProcessScheduler::Run() noexcept { process.PTime = static_cast(process.Affinity); // tell helper to find a core to schedule on. - BOOL ret = UserProcessHelper::Switch(process.Image.fCode, + BOOL ret = UserProcessHelper::Switch(process.Image.Leak().Leak().Leak(), &process.StackReserve[process.StackSize - 1], process.StackFrame, process.ProcessId); @@ -570,7 +570,7 @@ Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status == ProcessStatusKind::kInvalid) return No; - if (!process.Image.fCode) return No; + if (!process.Image.HasCode()) return No; if (!process.Name[0]) return No; diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc new file mode 100644 index 00000000..7acbcf8d --- /dev/null +++ b/dev/kernel/src/UserProcessTeam.cc @@ -0,0 +1,53 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file UserProcessTeam.cc +/// @brief Process teams implementation. +/***********************************************************************************/ + +#include + +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].Status = ProcessStatusKind::kKilled; + } + + this->mProcessCount = 0UL; +} + +/***********************************************************************************/ +/// @brief Process list array getter. +/// @return The list of process to schedule. +/***********************************************************************************/ + +Array& 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& UserProcessTeam::AsRef() { + return this->mCurrentProcess; +} +} // namespace Kernel + +// last rev 05-03-24 -- cgit v1.2.3 From cddf1926591707121a3c1302a5ef7f5abd030d7e Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 26 Apr 2025 11:12:44 +0200 Subject: dev, kernel: add kernel on when the traversal hits 0 (it should never happen) Signed-off-by: Amlal --- dev/boot/BootKit/BootKit.h | 2 +- dev/kernel/KernelKit/DriveMgr.h | 4 +++ dev/kernel/src/DriveMgr.cc | 4 +++ dev/kernel/src/FS/HeFS.cc | 65 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 9 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 2bf95696..03902363 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -297,7 +297,7 @@ inline Boolean BDiskFormatFactory::Format(const Char* part_name) { epm_boot.FsVersion = kNeFSVersionInteger; epm_boot.LbaStart = kNeFSRootCatalogStartAddress; - epm_boot.LbaEnd = fDiskDev.GetDiskSize(); + epm_boot.LbaEnd = fDiskDev.GetDiskSize() - 1; epm_boot.SectorSz = BootDev::kSectorSize; epm_boot.Kind = kEPMNeKernel; epm_boot.NumBlocks = 1; diff --git a/dev/kernel/KernelKit/DriveMgr.h b/dev/kernel/KernelKit/DriveMgr.h index 263b728e..b40cf0ad 100644 --- a/dev/kernel/KernelKit/DriveMgr.h +++ b/dev/kernel/KernelKit/DriveMgr.h @@ -71,6 +71,10 @@ struct DriveTrait final { const Char* (*fProtocol)(Void); }; +namespace Detail { + Void io_detect_drive(DriveTrait& trait); +} + ///! drive as a device. typedef DriveTrait* DriveTraitPtr; diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index 763096b3..17c6c8cc 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -191,6 +191,10 @@ namespace Detail { trait.fPacket.fPacketReadOnly = YES; trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive; + + trait.fSectorSz = 512; + trait.fLbaEnd = drv_get_sector_count() - 1; + trait.fLbaStart = 0x400; } } diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 71d1d1d4..9333e53c 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -90,6 +90,14 @@ namespace Detail { else start = dir->fParent; } + + if (start == 0) { + kout << "Errror: Something went terribly wrong when traversing the RB-Tree.\r"; + + ke_panic(RUNTIME_CHECK_FILESYSTEM, "RB-Tree traversal failed, critical filesystem error!"); + + return; + } } /***********************************************************************************/ @@ -782,7 +790,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fStartIND = drive->fLbaStart + sizeof(HEFS_BOOT_NODE); root->fEndIND = drive->fLbaEnd; - root->fINDCount = root->fEndIND - root->fStartIND; + root->fINDCount = 0; root->fDiskSize = drv_get_size(); root->fDiskStatus = kHeFSStatusUnlocked; @@ -811,8 +819,40 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input drive->fOutput(drive->fPacket); + if (!drive->fPacket.fPacketGood) { + delete root; + root = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + + HEFS_INDEX_NODE_DIRECTORY* root_dir = new HEFS_INDEX_NODE_DIRECTORY(); + rt_set_memory(root_dir, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); + + wrt_copy_memory((VoidPtr) u"/", root_dir->fName, wrt_string_len(u"/")); + + root_dir->fKind = kHeFSFileKindDirectory; + root_dir->fColor = kHeFSBlack; + root_dir->fParent = 0; // No parent (it's the real root) + root_dir->fChild = 0; // No children yet + root_dir->fNext = 0; // No next + root_dir->fPrev = 0; // No previous + + root_dir->fEntryCount = 0; + + drive->fPacket.fPacketLba = root->fStartIND; + drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + drive->fPacket.fPacketContent = root_dir; + + drive->fOutput(drive->fPacket); + + delete root_dir; delete root; - root = nullptr; + + root = nullptr; + root_dir = nullptr; if (drive->fPacket.fPacketGood) return YES; @@ -827,7 +867,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input /// @param dir The directory to create the file in. /// @return If it was sucessful, see err_local_get(). _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Input const Int32 flags, - const Utf16Char* dir) { + const Utf16Char* dir) { NE_UNUSED(drive); NE_UNUSED(flags); NE_UNUSED(dir); @@ -881,9 +921,15 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu dirent->fDeleted = 0; dirent->fModified = 0; dirent->fEntryCount = 0; - dirent->fKind = kHeFSFileKindDirectory; - dirent->fFlags = flags; - dirent->fChecksum = 0; + + dirent->fParent = 0; // No parent (it's the real root) + dirent->fChild = 0; // No children yet + dirent->fNext = 0; // No next + dirent->fPrev = 0; // No previous + + dirent->fKind = kHeFSFileKindDirectory; + dirent->fFlags = flags; + dirent->fChecksum = 0; if (Detail::hefs_allocate_index_directory_node(root, drive, dirent)) { delete dirent; @@ -994,10 +1040,13 @@ Boolean fs_init_hefs(Void) noexcept { ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main filesystem cannot be mounted."); HeFileSystemParser parser; + parser.Format(&drv, kHeFSEncodingUTF16, kHeFSDefaultVoluneName); - parser.CreateDirectory(&drv, kHeFSEncodingUTF16, u"/"); - parser.CreateFile(&drv, kHeFSEncodingUTF16, u"/", u"boot.log"); + Kernel::Detail::io_detect_drive(drv); + + parser.CreateDirectory(&drv, kHeFSEncodingUTF16, u"boot"); + parser.CreateFile(&drv, kHeFSEncodingUTF16, u"boot", u".hefs"); return YES; } -- cgit v1.2.3 From a02a39e77abf2a71bcd023c33c63d405ef1c3081 Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 26 Apr 2025 11:32:38 +0200 Subject: kernel, hefs: fixing issues with rb-tree, regarding the traversal of inds. Signed-off-by: Amlal --- dev/boot/BootKit/BootKit.h | 4 ++-- dev/kernel/src/FS/HeFS.cc | 40 +++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 21 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/boot/BootKit/BootKit.h b/dev/boot/BootKit/BootKit.h index 03902363..68c7424b 100644 --- a/dev/boot/BootKit/BootKit.h +++ b/dev/boot/BootKit/BootKit.h @@ -295,8 +295,8 @@ inline Boolean BDiskFormatFactory::Format(const Char* part_name) { const auto kFsName = "HeFS"; const auto kBlockName = "OS (EPM)"; - epm_boot.FsVersion = kNeFSVersionInteger; - epm_boot.LbaStart = kNeFSRootCatalogStartAddress; + epm_boot.FsVersion = 0; + epm_boot.LbaStart = 1024; epm_boot.LbaEnd = fDiskDev.GetDiskSize() - 1; epm_boot.SectorSz = BootDev::kSectorSize; epm_boot.Kind = kEPMNeKernel; diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 9333e53c..1da886c4 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -29,7 +29,7 @@ namespace Detail { /// @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, Lba& start); + hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, HEFS_BOOT_NODE* boot, Lba& start); /// @brief Get the index node of a file or directory. /// @param root The root node of the filesystem. @@ -75,7 +75,13 @@ namespace Detail { /// @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, Lba& start) { + hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, HEFS_BOOT_NODE* node, Lba& start) { + NE_UNUSED(node); + + if (!dir) { + ke_panic(RUNTIME_CHECK_FILESYSTEM, "Error: Invalid directory node in RB-Tree traversal.\r"); + } + start = dir->fNext; if (dir->fColor == kHeFSBlack && start == 0) { @@ -92,10 +98,8 @@ namespace Detail { } if (start == 0) { - kout << "Errror: Something went terribly wrong when traversing the RB-Tree.\r"; - - ke_panic(RUNTIME_CHECK_FILESYSTEM, "RB-Tree traversal failed, critical filesystem error!"); - + ke_panic(RUNTIME_CHECK_FILESYSTEM, "Error: Invalid start value in RB-Tree traversal.\r"); + return; } } @@ -330,7 +334,7 @@ namespace Detail { return YES; } - hefsi_traverse_tree(parent, start); + hefsi_traverse_tree(parent, root, start); } return YES; @@ -388,7 +392,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); } err_global_get() = kErrorSuccess; @@ -505,7 +509,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); } delete dir; @@ -588,7 +592,7 @@ namespace Detail { } } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); } delete dir; @@ -695,13 +699,13 @@ namespace Detail { return NO; } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); continue; } else { if (dir_parent->fNext == start) { hefsi_rotate_left(dir, start, mnt); - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); continue; } @@ -724,12 +728,12 @@ namespace Detail { } hefsi_rotate_right(dir, start, mnt); - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); continue; } - hefsi_traverse_tree(dir, start); + hefsi_traverse_tree(dir, root, start); } delete dir; @@ -787,7 +791,7 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root->fSectorSize = drive->fSectorSz; - root->fStartIND = drive->fLbaStart + sizeof(HEFS_BOOT_NODE); + root->fStartIND = drive->fLbaStart + sizeof(HEFS_BOOT_NODE) + sizeof(HEFS_BOOT_NODE); root->fEndIND = drive->fLbaEnd; root->fINDCount = 0; @@ -842,8 +846,8 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root_dir->fEntryCount = 0; - drive->fPacket.fPacketLba = root->fStartIND; - drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); + drive->fPacket.fPacketLba = drive->fLbaStart + sizeof(HEFS_BOOT_NODE) + sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); drive->fPacket.fPacketContent = root_dir; drive->fOutput(drive->fPacket); @@ -1043,8 +1047,6 @@ Boolean fs_init_hefs(Void) noexcept { parser.Format(&drv, kHeFSEncodingUTF16, kHeFSDefaultVoluneName); - Kernel::Detail::io_detect_drive(drv); - parser.CreateDirectory(&drv, kHeFSEncodingUTF16, u"boot"); parser.CreateFile(&drv, kHeFSEncodingUTF16, u"boot", u".hefs"); -- cgit v1.2.3 From 9c33e844d76f9db6d7110de4f05cbe2084cdbca1 Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 26 Apr 2025 13:44:35 +0200 Subject: dev, kernel and user: codebase additions and work in progress 'tactical pause' why? - HeFS's Formating needs some thought before being layed out, that's the kind of thing that bites hard in the ass. - Alongside those changes I improved parts of the kernel too. Signed-off-by: Amlal --- dev/kernel/FSKit/HeFS.h | 10 ++++++ dev/kernel/KernelKit/DeviceMgr.h | 4 +-- dev/kernel/src/DriveMgr.cc | 2 +- dev/kernel/src/FS/HeFS.cc | 51 +++++++++++++++++++++++---- dev/kernel/src/Gfx/FBDeviceInterface.cc | 10 ++---- dev/kernel/src/Storage/AHCIDeviceInterface.cc | 2 +- dev/kernel/src/Storage/ATADeviceInterface.cc | 2 +- dev/kernel/src/Storage/NVMEDeviceInterface.cc | 2 +- dev/user/SystemCalls.h | 10 ++++++ 9 files changed, 73 insertions(+), 20 deletions(-) (limited to 'dev/kernel/src') diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 895422a6..693ec2d3 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -28,6 +28,9 @@ #define kHeFSDefaultVoluneName u"HeFS Volume" +#define kHeFSDIMBootDir u"boot-x/dir" +#define kHeFSDIMBootFile u"boot-x/file" + #define kHeFSSearchAllStr u"*" struct HEFS_BOOT_NODE; @@ -63,6 +66,7 @@ enum { kHeFSEncodingUTF32LE, kHeFSEncodingUTF8BE, kHeFSEncodingUTF8LE, + kHeFSEncodingBinary, kHeFSEncodingCount, }; @@ -135,6 +139,10 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE final { fLinkChecksum; /// @brief Checksum of the file, recovery checksum, block checksum, link /// checksum. + Kernel::Utf16Char fMime[kHeFSFileNameLen]; /// @brief File mime type. + + Kernel::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.) + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps. Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). @@ -168,6 +176,8 @@ struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final { Kernel::UInt32 fChecksum, fIndexNodeChecksum; /// @brief Checksum of the file, index node checksum. + Kernel::Utf16Char fDim[kHeFSFileNameLen]; /// @brief Directiory Immatriculation magic. + Kernel::ATime fCreated, fAccessed, fModified, fDeleted; /// @brief File timestamps and allocation status. Kernel::UInt32 fUID, fGID; /// @brief User ID and Group ID of the file. Kernel::UInt32 fMode; /// @brief File mode. (read, write, execute, etc). diff --git a/dev/kernel/KernelKit/DeviceMgr.h b/dev/kernel/KernelKit/DeviceMgr.h index 8da52699..210cef2a 100644 --- a/dev/kernel/KernelKit/DeviceMgr.h +++ b/dev/kernel/KernelKit/DeviceMgr.h @@ -22,7 +22,7 @@ #include #include -#define kDeviceMgrRootDirPath "/dev/" +#define kDeviceMgrRootDirPath "/devices/" #define NE_DEVICE : public ::Kernel::IDeviceObject @@ -58,7 +58,7 @@ class IDeviceObject { return *this; } - virtual const char* Name() const { return "/dev/null"; } + virtual const char* Name() const { return "/devices/null"; } operator bool() { return fOut && fIn; } diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index 17c6c8cc..46a5c588 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -25,7 +25,7 @@ STATIC UInt8 kATAMaster = 0U; #endif #if defined(__AHCI__) -STATIC UInt16 kAHCIPortsImplemented = 0UL; +STATIC UInt16 kAHCIPortsImplemented [[maybe_unused]] = 0UL; #endif /// @brief reads from an ATA drive. diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 1da886c4..81316ba5 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -756,7 +756,7 @@ namespace Kernel::HeFS { /// @param drive The drive to write on. /// @return If it was sucessful, see err_local_get(). _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const Int32 flags, - const Utf16Char* part_name) { + _Input const Utf16Char* part_name) { NE_UNUSED(drive); NE_UNUSED(flags); NE_UNUSED(part_name); @@ -779,6 +779,34 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + drive->fPacket.fPacketLba = drive->fLbaStart; + drive->fPacket.fPacketSize = sizeof(HEFS_BOOT_NODE); + drive->fPacket.fPacketContent = root; + + drive->fInput(drive->fPacket); + + if (!drive->fPacket.fPacketGood) { + delete root; + root = nullptr; + + err_global_get() = kErrorDiskIsCorrupted; + + return NO; + } + + // Check if the disk is already formatted. + + if (KStringBuilder::Equals(root->fMagic, kHeFSMagic)) { + delete root; + root = nullptr; + + err_global_get() = kErrorSuccess; + + return YES; + } + + rt_set_memory(root, 0, sizeof(HEFS_BOOT_NODE)); + rt_copy_memory((VoidPtr) "fs/hefs-packet", drive->fPacket.fPacketMime, rt_string_len("fs/hefs-packet")); @@ -836,9 +864,10 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input rt_set_memory(root_dir, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); wrt_copy_memory((VoidPtr) u"/", root_dir->fName, wrt_string_len(u"/")); + wrt_copy_memory((VoidPtr) kHeFSDIMBootDir, root_dir->fDim, wrt_string_len(kHeFSDIMBootDir)); root_dir->fKind = kHeFSFileKindDirectory; - root_dir->fColor = kHeFSBlack; + root_dir->fColor = kHeFSBlack; // Every RB-Tree root starts black. (a condition of the algorithm) root_dir->fParent = 0; // No parent (it's the real root) root_dir->fChild = 0; // No children yet root_dir->fNext = 0; // No next @@ -858,6 +887,19 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input root = nullptr; root_dir = nullptr; + // Create the directories, something UNIX inspired but more explicit and forward looking. + + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/boot"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/netdevices"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/binaries"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/users"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/config"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/config/xml"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/config/json"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/devices"); + this->CreateDirectory(drive, kHeFSEncodingUTF16, u"/media"); + this->CreateFile(drive, kHeFSEncodingBinary, u"/", u"mk.hefs"); + if (drive->fPacket.fPacketGood) return YES; err_global_get() = kErrorDiskIsCorrupted; @@ -1036,7 +1078,7 @@ _Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input con } Boolean fs_init_hefs(Void) noexcept { - kout << "Creating main disk...\r"; + kout << "Creating main disk with HeFS in it...\r"; auto drv = io_construct_main_drive(); @@ -1047,9 +1089,6 @@ Boolean fs_init_hefs(Void) noexcept { parser.Format(&drv, kHeFSEncodingUTF16, kHeFSDefaultVoluneName); - parser.CreateDirectory(&drv, kHeFSEncodingUTF16, u"boot"); - parser.CreateFile(&drv, kHeFSEncodingUTF16, u"boot", u".hefs"); - return YES; } } // namespace Kernel::HeFS diff --git a/dev/kernel/src/Gfx/FBDeviceInterface.cc b/dev/kernel/src/Gfx/FBDeviceInterface.cc index 185b22b0..be52655d 100644 --- a/dev/kernel/src/Gfx/FBDeviceInterface.cc +++ b/dev/kernel/src/Gfx/FBDeviceInterface.cc @@ -27,9 +27,6 @@ FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) { if (pckt->fHeight == 0 || pckt->fWidth == 0) return *this; - if (pckt->fX > kHandoverHeader->f_GOP.f_Width || pckt->fY > kHandoverHeader->f_GOP.f_Height) - return *this; - this->fOut(this, pckt); return *this; @@ -40,10 +37,7 @@ FBDeviceInterface& FBDeviceInterface::operator<<(FBDevicePacket* pckt) { /// @return the class itself after operation. FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) { if (!pckt) return *this; - - if (pckt->fX > kHandoverHeader->f_GOP.f_Width || pckt->fY > kHandoverHeader->f_GOP.f_Height) - return *this; - + this->fIn(this, pckt); return *this; @@ -52,5 +46,5 @@ FBDeviceInterface& FBDeviceInterface::operator>>(FBDevicePacket* pckt) { /// @brief Returns the name of the device interface. /// @return it's name as a string. const Char* FBDeviceInterface::Name() const { - return "/dev/fb{}"; + return "/devices/fb{}"; } \ No newline at end of file diff --git a/dev/kernel/src/Storage/AHCIDeviceInterface.cc b/dev/kernel/src/Storage/AHCIDeviceInterface.cc index d5c1e5c6..2d97eee7 100644 --- a/dev/kernel/src/Storage/AHCIDeviceInterface.cc +++ b/dev/kernel/src/Storage/AHCIDeviceInterface.cc @@ -24,7 +24,7 @@ AHCIDeviceInterface::~AHCIDeviceInterface() = default; /// @brief Returns the name of the device interface. /// @return it's name as a string. const Char* AHCIDeviceInterface::Name() const { - return "/dev/sda{}"; + return "/devices/sda{}"; } /// @brief Output operator. diff --git a/dev/kernel/src/Storage/ATADeviceInterface.cc b/dev/kernel/src/Storage/ATADeviceInterface.cc index f38d5359..a66d812b 100644 --- a/dev/kernel/src/Storage/ATADeviceInterface.cc +++ b/dev/kernel/src/Storage/ATADeviceInterface.cc @@ -22,7 +22,7 @@ ATADeviceInterface::~ATADeviceInterface() = default; /// @brief Returns the name of the device interface. /// @return it's name as a string. const Char* ATADeviceInterface::Name() const { - return "/dev/hda{}"; + return "/devices/hda{}"; } /// @brief Output operator. diff --git a/dev/kernel/src/Storage/NVMEDeviceInterface.cc b/dev/kernel/src/Storage/NVMEDeviceInterface.cc index edec6d6d..cff776c9 100644 --- a/dev/kernel/src/Storage/NVMEDeviceInterface.cc +++ b/dev/kernel/src/Storage/NVMEDeviceInterface.cc @@ -18,6 +18,6 @@ NVMEDeviceInterface::~NVMEDeviceInterface() { } const Char* NVMEDeviceInterface::Name() const { - return ("/dev/nvme{}"); + return ("/devices/nvme{}"); } } // namespace Kernel diff --git a/dev/user/SystemCalls.h b/dev/user/SystemCalls.h index 1e391d8a..4ff7de11 100644 --- a/dev/user/SystemCalls.h +++ b/dev/user/SystemCalls.h @@ -60,6 +60,16 @@ IMPORT_C Ref IoOpenFile(const Char* fs_path, const Char* drive_letter); /// @return Function doesn't return a type. IMPORT_C Void IoCloseFile(_Input Ref file_desc); +/// @brief I/O control (ioctl) on a file. +/// @param file_desc the file descriptor. +/// @param ioctl_code the ioctl code. +/// @param in_data the input data. +/// @param out_data the output data. +/// @return the number of bytes written. +/// @note This function is used to control the file descriptor, introduced for HeFS. +IMPORT_C SInt32 IoCTLFile(_Input Ref file_desc, _Input UInt32 ioctl_code, _Input VoidPtr in_data, + _Output VoidPtr out_data); + /// @brief Gets the file mime (if any) /// @param file_desc the file descriptor. IMPORT_C const Char* IoMimeFile(_Input Ref file_desc); -- cgit v1.2.3 From 360c69daf7a83ec31c384390d9ec37064b78b40e Mon Sep 17 00:00:00 2001 From: Amlal Date: Sat, 26 Apr 2025 16:56:37 +0200 Subject: dev, kernel, tooling: add HeFS tooling and early allocation stategy. why? - we need to format it externally too. - a in-kernel format doesn't handle every case. - and i have to fix the createdir, createfile methods for correct inode dir linking. Signed-off-by: Amlal --- .gitignore | 2 + compile_flags.txt | 2 + dev/kernel/FSKit/HeFS.h | 7 +- dev/kernel/src/FS/HeFS.cc | 72 ++++++++++---------- tooling/dist/.keep | 0 tooling/hefs.h | 161 ++++++++++++++++++++++++++++++++++++++++++++ tooling/mkfs.hefs.cc | 165 ++++++++++++++++++++++++++++++++++++++++++++++ tooling/mkfs.hefs.json | 16 +++++ 8 files changed, 389 insertions(+), 36 deletions(-) create mode 100644 tooling/dist/.keep create mode 100644 tooling/hefs.h create mode 100644 tooling/mkfs.hefs.cc create mode 100644 tooling/mkfs.hefs.json (limited to 'dev/kernel/src') diff --git a/.gitignore b/.gitignore index df03c3e1..fc656b48 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ public/frameworks/*/dist/* neoskrnl/neoskrnl.xcodeproj/project.xcworkspace/xcshareddata/ +tooling/dist/mkfs.hefs + html/ latex/ diff --git a/compile_flags.txt b/compile_flags.txt index cef28da1..be8085bd 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -13,6 +13,8 @@ -Ipublic/tools/open -Ipublic/frameworks -Idev/boot/BootKit +-Itooling/ +-I./ -std=c++20 -D__NE_AMD64__ -D__NEOSKRNL__ diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 693ec2d3..a2dd9fe0 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -29,7 +29,10 @@ #define kHeFSDefaultVoluneName u"HeFS Volume" #define kHeFSDIMBootDir u"boot-x/dir" -#define kHeFSDIMBootFile u"boot-x/file" +#define kHeFSMIMEBootFile u"boot-x/file" + +#define kHeFSDIMSystemDir u"system-x/dir" +#define kHeFSMIMESystemFile u"system-x/file" #define kHeFSSearchAllStr u"*" @@ -123,7 +126,7 @@ struct PACKED HEFS_BOOT_NODE final { }; inline constexpr Kernel::ATime kHeFSTimeInvalid = 0x0000000000000000; -inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF; +inline constexpr Kernel::ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1; /// @brief HeFS index node. /// @details This structure is used to store the file information of a file. diff --git a/dev/kernel/src/FS/HeFS.cc b/dev/kernel/src/FS/HeFS.cc index 81316ba5..13d79c8f 100644 --- a/dev/kernel/src/FS/HeFS.cc +++ b/dev/kernel/src/FS/HeFS.cc @@ -78,29 +78,20 @@ namespace Detail { hefsi_traverse_tree(HEFS_INDEX_NODE_DIRECTORY* dir, HEFS_BOOT_NODE* node, Lba& start) { NE_UNUSED(node); - if (!dir) { - ke_panic(RUNTIME_CHECK_FILESYSTEM, "Error: Invalid directory node in RB-Tree traversal.\r"); + if (!dir || !node) { + ke_panic(RUNTIME_CHECK_FILESYSTEM, "Error: Invalid directory node/boot_node in RB-Tree traversal."); } - start = dir->fNext; - - if (dir->fColor == kHeFSBlack && start == 0) { - if (dir->fParent != 0) start = dir->fParent; - } else if (dir->fColor == kHeFSRed && start == 0) { - if (dir->fChild != 0) - start = dir->fChild; - else if (dir->fNext != 0) - start = dir->fNext; - else if (dir->fPrev != 0) - start = dir->fPrev; - else - start = dir->fParent; - } - - if (start == 0) { - ke_panic(RUNTIME_CHECK_FILESYSTEM, "Error: Invalid start value in RB-Tree traversal.\r"); - - return; + if (dir->fChild != 0) { + start = dir->fChild; + } else if (dir->fNext != 0) { + start = dir->fNext; + } else if (dir->fParent != 0) { + start = dir->fParent; + } else if (dir->fPrev != 0) { + start = dir->fPrev; + } else { + start = node->fStartIND; } } @@ -324,13 +315,16 @@ namespace Detail { return NO; } - if (parent->fDeleted) { + if (parent->fDeleted || + !parent->fCreated) { mnt->fPacket.fPacketLba = start; mnt->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); mnt->fPacket.fPacketContent = dir; mnt->fOutput(mnt->fPacket); + hefsi_balance_filesystem(root, mnt); + return YES; } @@ -866,14 +860,14 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input wrt_copy_memory((VoidPtr) u"/", root_dir->fName, wrt_string_len(u"/")); wrt_copy_memory((VoidPtr) kHeFSDIMBootDir, root_dir->fDim, wrt_string_len(kHeFSDIMBootDir)); - root_dir->fKind = kHeFSFileKindDirectory; - root_dir->fColor = kHeFSBlack; // Every RB-Tree root starts black. (a condition of the algorithm) - root_dir->fParent = 0; // No parent (it's the real root) - root_dir->fChild = 0; // No children yet - root_dir->fNext = 0; // No next - root_dir->fPrev = 0; // No previous + root_dir->fKind = kHeFSFileKindDirectory; + root_dir->fColor = kHeFSBlack; // Every RB-Tree root starts black. (a condition of the algorithm) + root_dir->fParent = root->fStartIND; // No parent (it's the real root) + root_dir->fChild = root->fEndIND; // No children yet + root_dir->fNext = 0; // No next + root_dir->fPrev = 0; // No previous - root_dir->fEntryCount = 0; + root_dir->fEntryCount = 1; drive->fPacket.fPacketLba = drive->fLbaStart + sizeof(HEFS_BOOT_NODE) + sizeof(HEFS_BOOT_NODE); drive->fPacket.fPacketSize = sizeof(HEFS_INDEX_NODE_DIRECTORY); @@ -881,6 +875,8 @@ _Output Bool HeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input drive->fOutput(drive->fPacket); + Detail::hefsi_balance_filesystem(root, drive); + delete root_dir; delete root; @@ -942,6 +938,8 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu drive->fInput(drive->fPacket); + Detail::hefsi_balance_filesystem(root, drive); + auto dirent = Detail::hefs_fetch_index_node_directory(root, drive, dir); if (dirent) { @@ -963,20 +961,22 @@ _Output Bool HeFileSystemParser::CreateDirectory(_Input DriveTrait* drive, _Inpu wrt_copy_memory((VoidPtr) dir, dirent->fName, wrt_string_len(dir)); dirent->fAccessed = 0; - dirent->fCreated = 0; + dirent->fCreated = 0; /// TODO: Add the current time. dirent->fDeleted = 0; dirent->fModified = 0; dirent->fEntryCount = 0; - dirent->fParent = 0; // No parent (it's the real root) - dirent->fChild = 0; // No children yet - dirent->fNext = 0; // No next - dirent->fPrev = 0; // No previous + dirent->fParent = root->fStartIND; // No parent (it's the real root) + dirent->fChild = root->fEndIND; // No children yet + dirent->fNext = 0; // No next + dirent->fPrev = 0; // No previous dirent->fKind = kHeFSFileKindDirectory; dirent->fFlags = flags; dirent->fChecksum = 0; + dirent->fEntryCount = 1; + if (Detail::hefs_allocate_index_directory_node(root, drive, dirent)) { delete dirent; dirent = nullptr; @@ -1033,6 +1033,8 @@ _Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input con drive->fInput(drive->fPacket); + Detail::hefsi_balance_filesystem(root, drive); + auto dirent = Detail::hefs_fetch_index_node_directory(root, drive, dir); if (!dirent) { @@ -1077,6 +1079,8 @@ _Output Bool HeFileSystemParser::CreateFile(_Input DriveTrait* drive, _Input con return NO; } +/// @brief Initialize the HeFS filesystem. +/// @return To check its status, see err_local_get(). Boolean fs_init_hefs(Void) noexcept { kout << "Creating main disk with HeFS in it...\r"; diff --git a/tooling/dist/.keep b/tooling/dist/.keep new file mode 100644 index 00000000..e69de29b diff --git a/tooling/hefs.h b/tooling/hefs.h new file mode 100644 index 00000000..a85cb2bc --- /dev/null +++ b/tooling/hefs.h @@ -0,0 +1,161 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include +#include + +#define kHeFSVersion (0x0101) +#define kHeFSMagic " HeFS" +#define kHeFSMagicLen (8) + +#define kHeFSFileNameLen (256U) +#define kHeFSPartNameLen (128U) + +#define kHeFSMinimumDiskSize (gib_cast(4)) + +#define kHeFSDefaultVoluneName u"HeFS Volume" + +#define kHeFSDIMBootDir u"boot-x/dir" +#define kHeFSMIMEBootFile u"boot-x/file" + +#define kHeFSDIMSystemDir u"system-x/dir" +#define kHeFSMIMESystemFile u"system-x/file" + +#define kHeFSSearchAllStr u"*" + +namespace mkfs::hefs { +enum { + 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 = 7, +}; + +enum { + kHeFSStatusUnlocked = 0x18, + kHeFSStatusLocked, + kHeFSStatusError, + kHeFSStatusInvalid, + kHeFSStatusCount, +}; + +enum { + kHeFSEncodingUTF8 = 0x00, + kHeFSEncodingUTF16, + kHeFSEncodingUTF32, + kHeFSEncodingUTF16BE, + kHeFSEncodingUTF16LE, + kHeFSEncodingUTF32BE, + kHeFSEncodingUTF32LE, + kHeFSEncodingUTF8BE, + kHeFSEncodingUTF8LE, + kHeFSEncodingBinary, + kHeFSEncodingCount, +}; + +// Constants +constexpr std::size_t kHeFSBlockCount = 16; + +// Types +using ATime = std::uint64_t; + +inline constexpr uint16_t kHeFSFileKindRegular = 0x00; +inline constexpr uint16_t kHeFSFileKindDirectory = 0x01; +inline constexpr uint16_t kHeFSFileKindBlock = 0x02; +inline constexpr uint16_t kHeFSFileKindCharacter = 0x03; +inline constexpr uint16_t kHeFSFileKindFIFO = 0x04; +inline constexpr uint16_t kHeFSFileKindSocket = 0x05; +inline constexpr uint16_t kHeFSFileKindSymbolicLink = 0x06; +inline constexpr uint16_t kHeFSFileKindUnknown = 0x07; +inline constexpr uint16_t kHeFSFileKindCount = 0x08; + +// Basic Time Constants +inline constexpr ATime kHeFSTimeInvalid = 0x0000000000000000; +inline constexpr ATime kHeFSTimeMax = 0xFFFFFFFFFFFFFFFF - 1; + +// Boot Node (Superblock Equivalent) +struct alignas(8) BootNode { + char magic[kHeFSMagicLen]{}; + char16_t volumeName[kHeFSPartNameLen]{}; + std::uint32_t version{}; + std::uint64_t badSectors{}; + std::uint64_t sectorCount{}; + std::uint64_t sectorSize{}; + std::uint32_t checksum{}; + std::uint8_t diskKind{}; + std::uint8_t encoding{}; + std::uint64_t startIND{}; + std::uint64_t endIND{}; + std::uint64_t indCount{}; + std::uint64_t diskSize{}; + std::uint16_t diskStatus{}; + std::uint16_t diskFlags{}; + std::uint16_t vid{}; + std::uint64_t reserved{}; + std::uint64_t reserved2{}; + std::uint64_t reserved3{}; + std::uint64_t reserved4{}; +}; + +// File Node (Index Node) +struct alignas(8) IndexNode { + char16_t name[kHeFSFileNameLen]{}; + std::uint32_t flags{}; + std::uint16_t kind{}; + std::uint32_t size{}; + std::uint32_t checksum{}; + std::uint32_t recoverChecksum{}; + std::uint32_t blockChecksum{}; + std::uint32_t linkChecksum{}; + char16_t mime[kHeFSFileNameLen]{}; + bool symbolicLink{false}; + ATime created{}; + ATime accessed{}; + ATime modified{}; + ATime deleted{}; + std::uint32_t uid{}; + std::uint32_t gid{}; + std::uint32_t mode{}; + std::uint64_t blockLinkStart[kHeFSBlockCount]{}; + std::uint64_t blockLinkEnd[kHeFSBlockCount]{}; + std::uint64_t blockStart[kHeFSBlockCount]{}; + std::uint64_t blockEnd[kHeFSBlockCount]{}; + std::uint64_t blockRecoveryStart[kHeFSBlockCount]{}; + std::uint64_t blockRecoveryEnd[kHeFSBlockCount]{}; +}; + +// Directory Node (Red-Black Tree Node) +struct alignas(8) IndexNodeDirectory { + char16_t name[kHeFSFileNameLen]{}; + std::uint32_t flags{}; + std::uint16_t kind{}; + std::uint32_t entryCount{}; + std::uint32_t checksum{}; + std::uint32_t indexNodeChecksum{}; + char16_t dim[kHeFSFileNameLen]{}; + ATime created{}; + ATime accessed{}; + ATime modified{}; + ATime deleted{}; + std::uint32_t uid{}; + std::uint32_t gid{}; + std::uint32_t mode{}; + std::uint64_t indexNodeStart[kHeFSBlockCount]{}; + std::uint64_t indexNodeEnd[kHeFSBlockCount]{}; + std::uint8_t color{}; + std::uint64_t next{}; + std::uint64_t prev{}; + std::uint64_t child{}; + std::uint64_t parent{}; +}; + +} // namespace mkfs::hefs diff --git a/tooling/mkfs.hefs.cc b/tooling/mkfs.hefs.cc new file mode 100644 index 00000000..15b18a8a --- /dev/null +++ b/tooling/mkfs.hefs.cc @@ -0,0 +1,165 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +/// @internal +namespace detail { +/// @brief Helper function to get the option value from command line arguments. +template +static std::basic_string get_option(const std::basic_string& args, + const std::basic_string& option) { + size_t pos = args.find(option + CharType('=')); + + if (pos != std::string::npos) { + size_t start = pos + option.length() + 1; + size_t end = args.find(' ', start); + return args.substr(start, end - start); + } + + return std::basic_string{}; +} +} // namespace detail + +static size_t kDiskSize = 1024 * 1024 * 1024 * 4UL; +static uint16_t kVersion = kHeFSVersion; +static std::u16string kLabel = kHeFSDefaultVoluneName; +static size_t kSectorSize = 512; + +int main(int argc, char** argv) { + if (argc < 2) { + std::cerr << "mkfs.hefs: Error: Missing required arguments." << std::endl; + std::cerr << "mkfs.hefs: Usage: mkfs.hefs -L