From 0c211cca4d7a4d836f4cb685345e44f3f2814fd1 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 21 May 2024 09:10:57 +0200 Subject: MHR-23: New CoreSystem calls and refactors. Signed-off-by: Amlal El Mahrouss --- Kernel/Source/AppMain.cxx | 228 ------ Kernel/Source/Array.cxx | 7 - Kernel/Source/ArrayList.cxx | 7 - Kernel/Source/Atom.cxx | 10 - Kernel/Source/CodeManager.cxx | 30 - Kernel/Source/Crc32.cxx | 74 -- Kernel/Source/CxxAbi.cxx | 87 --- Kernel/Source/Defines.cxx | 7 - Kernel/Source/DeviceManager.cxx | 7 - Kernel/Source/DriveManager.cxx | 149 ---- Kernel/Source/ErrorOr.cxx | 12 - Kernel/Source/FS/NewFS.cxx | 943 ------------------------- Kernel/Source/FileManager.cxx | 171 ----- Kernel/Source/Framebuffer.cxx | 96 --- Kernel/Source/GUIDWizard.cxx | 65 -- Kernel/Source/GUIDWrapper.cxx | 11 - Kernel/Source/HError.cxx | 18 - Kernel/Source/IndexableProperty.cxx | 57 -- Kernel/Source/Json.cxx | 12 - Kernel/Source/KernelCheck.cxx | 109 --- Kernel/Source/KernelHeap.cxx | 169 ----- Kernel/Source/LockDelegate.cxx | 12 - Kernel/Source/MutableArray.cxx | 7 - Kernel/Source/Network/IP.cxx | 126 ---- Kernel/Source/Network/IPCEP.cxx | 7 - Kernel/Source/Network/NetworkDevice.cxx | 15 - Kernel/Source/New+Delete.cxx | 50 -- Kernel/Source/NewFS+FileManager.cxx | 89 --- Kernel/Source/NewFS+IO.cxx | 101 --- Kernel/Source/NewFS+Journal.cxx | 22 - Kernel/Source/OwnPtr.cxx | 7 - Kernel/Source/PEFCodeManager.cxx | 226 ------ Kernel/Source/PEFSharedObjectRT.cxx | 107 --- Kernel/Source/PRDT.cxx | 22 - Kernel/Source/PageAllocator.cxx | 52 -- Kernel/Source/PageManager.cxx | 118 ---- Kernel/Source/PermissionSelector.cxx | 47 -- Kernel/Source/Pmm.cxx | 88 --- Kernel/Source/ProcessScheduler.cxx | 416 ----------- Kernel/Source/ProcessTeam.cxx | 31 - Kernel/Source/Property.cxx | 20 - Kernel/Source/Ref.cxx | 7 - Kernel/Source/SMPManager.cxx | 234 ------ Kernel/Source/Semaphore.cxx | 53 -- Kernel/Source/Storage/AHCIDeviceInterface.cxx | 35 - Kernel/Source/Storage/ATADeviceInterface.cxx | 88 --- Kernel/Source/Storage/NVMEDeviceInterface.cxx | 15 - Kernel/Source/Storage/SCSIDeviceInterface.cxx | 11 - Kernel/Source/Stream.cxx | 12 - Kernel/Source/String.cxx | 248 ------- Kernel/Source/ThreadLocalStorage.cxx | 58 -- Kernel/Source/Timer.cxx | 41 -- Kernel/Source/URL.cxx | 96 --- Kernel/Source/UserHeap.cxx | 252 ------- Kernel/Source/Utils.cxx | 253 ------- Kernel/Source/Variant.cxx | 24 - Kernel/Source/compile_flags.txt | 7 - Kernel/Sources/AppMain.cxx | 228 ++++++ Kernel/Sources/Array.cxx | 7 + Kernel/Sources/ArrayList.cxx | 7 + Kernel/Sources/Atom.cxx | 10 + Kernel/Sources/CodeManager.cxx | 30 + Kernel/Sources/Crc32.cxx | 74 ++ Kernel/Sources/CxxAbi.cxx | 87 +++ Kernel/Sources/Defines.cxx | 7 + Kernel/Sources/DeviceManager.cxx | 7 + Kernel/Sources/DriveManager.cxx | 149 ++++ Kernel/Sources/ErrorOr.cxx | 12 + Kernel/Sources/FS/NewFS.cxx | 943 +++++++++++++++++++++++++ Kernel/Sources/FileManager.cxx | 171 +++++ Kernel/Sources/Framebuffer.cxx | 96 +++ Kernel/Sources/GUIDWizard.cxx | 65 ++ Kernel/Sources/GUIDWrapper.cxx | 11 + Kernel/Sources/HError.cxx | 18 + Kernel/Sources/IndexableProperty.cxx | 57 ++ Kernel/Sources/Json.cxx | 12 + Kernel/Sources/KernelCheck.cxx | 109 +++ Kernel/Sources/KernelHeap.cxx | 169 +++++ Kernel/Sources/LockDelegate.cxx | 12 + Kernel/Sources/MutableArray.cxx | 7 + Kernel/Sources/Network/IP.cxx | 126 ++++ Kernel/Sources/Network/IPCEP.cxx | 7 + Kernel/Sources/Network/NetworkDevice.cxx | 15 + Kernel/Sources/New+Delete.cxx | 50 ++ Kernel/Sources/NewFS+FileManager.cxx | 89 +++ Kernel/Sources/NewFS+IO.cxx | 101 +++ Kernel/Sources/NewFS+Journal.cxx | 22 + Kernel/Sources/OwnPtr.cxx | 7 + Kernel/Sources/PEFCodeManager.cxx | 226 ++++++ Kernel/Sources/PEFSharedObjectRT.cxx | 107 +++ Kernel/Sources/PRDT.cxx | 22 + Kernel/Sources/PageAllocator.cxx | 52 ++ Kernel/Sources/PageManager.cxx | 118 ++++ Kernel/Sources/PermissionSelector.cxx | 47 ++ Kernel/Sources/Pmm.cxx | 88 +++ Kernel/Sources/ProcessScheduler.cxx | 416 +++++++++++ Kernel/Sources/ProcessTeam.cxx | 31 + Kernel/Sources/Property.cxx | 20 + Kernel/Sources/Ref.cxx | 7 + Kernel/Sources/SMPManager.cxx | 234 ++++++ Kernel/Sources/Semaphore.cxx | 53 ++ Kernel/Sources/Storage/AHCIDeviceInterface.cxx | 35 + Kernel/Sources/Storage/ATADeviceInterface.cxx | 88 +++ Kernel/Sources/Storage/NVMEDeviceInterface.cxx | 15 + Kernel/Sources/Storage/SCSIDeviceInterface.cxx | 11 + Kernel/Sources/Stream.cxx | 12 + Kernel/Sources/String.cxx | 248 +++++++ Kernel/Sources/ThreadLocalStorage.cxx | 58 ++ Kernel/Sources/Timer.cxx | 41 ++ Kernel/Sources/URL.cxx | 96 +++ Kernel/Sources/UserHeap.cxx | 252 +++++++ Kernel/Sources/Utils.cxx | 253 +++++++ Kernel/Sources/Variant.cxx | 24 + Kernel/Sources/compile_flags.txt | 7 + Kernel/makefile | 6 +- 115 files changed, 5269 insertions(+), 5269 deletions(-) delete mode 100644 Kernel/Source/AppMain.cxx delete mode 100644 Kernel/Source/Array.cxx delete mode 100644 Kernel/Source/ArrayList.cxx delete mode 100644 Kernel/Source/Atom.cxx delete mode 100644 Kernel/Source/CodeManager.cxx delete mode 100644 Kernel/Source/Crc32.cxx delete mode 100644 Kernel/Source/CxxAbi.cxx delete mode 100644 Kernel/Source/Defines.cxx delete mode 100644 Kernel/Source/DeviceManager.cxx delete mode 100644 Kernel/Source/DriveManager.cxx delete mode 100644 Kernel/Source/ErrorOr.cxx delete mode 100644 Kernel/Source/FS/NewFS.cxx delete mode 100644 Kernel/Source/FileManager.cxx delete mode 100644 Kernel/Source/Framebuffer.cxx delete mode 100644 Kernel/Source/GUIDWizard.cxx delete mode 100644 Kernel/Source/GUIDWrapper.cxx delete mode 100644 Kernel/Source/HError.cxx delete mode 100644 Kernel/Source/IndexableProperty.cxx delete mode 100644 Kernel/Source/Json.cxx delete mode 100644 Kernel/Source/KernelCheck.cxx delete mode 100644 Kernel/Source/KernelHeap.cxx delete mode 100644 Kernel/Source/LockDelegate.cxx delete mode 100644 Kernel/Source/MutableArray.cxx delete mode 100644 Kernel/Source/Network/IP.cxx delete mode 100644 Kernel/Source/Network/IPCEP.cxx delete mode 100644 Kernel/Source/Network/NetworkDevice.cxx delete mode 100644 Kernel/Source/New+Delete.cxx delete mode 100644 Kernel/Source/NewFS+FileManager.cxx delete mode 100644 Kernel/Source/NewFS+IO.cxx delete mode 100644 Kernel/Source/NewFS+Journal.cxx delete mode 100644 Kernel/Source/OwnPtr.cxx delete mode 100644 Kernel/Source/PEFCodeManager.cxx delete mode 100644 Kernel/Source/PEFSharedObjectRT.cxx delete mode 100644 Kernel/Source/PRDT.cxx delete mode 100644 Kernel/Source/PageAllocator.cxx delete mode 100644 Kernel/Source/PageManager.cxx delete mode 100644 Kernel/Source/PermissionSelector.cxx delete mode 100644 Kernel/Source/Pmm.cxx delete mode 100644 Kernel/Source/ProcessScheduler.cxx delete mode 100644 Kernel/Source/ProcessTeam.cxx delete mode 100644 Kernel/Source/Property.cxx delete mode 100644 Kernel/Source/Ref.cxx delete mode 100644 Kernel/Source/SMPManager.cxx delete mode 100644 Kernel/Source/Semaphore.cxx delete mode 100644 Kernel/Source/Storage/AHCIDeviceInterface.cxx delete mode 100644 Kernel/Source/Storage/ATADeviceInterface.cxx delete mode 100644 Kernel/Source/Storage/NVMEDeviceInterface.cxx delete mode 100644 Kernel/Source/Storage/SCSIDeviceInterface.cxx delete mode 100644 Kernel/Source/Stream.cxx delete mode 100644 Kernel/Source/String.cxx delete mode 100644 Kernel/Source/ThreadLocalStorage.cxx delete mode 100644 Kernel/Source/Timer.cxx delete mode 100644 Kernel/Source/URL.cxx delete mode 100644 Kernel/Source/UserHeap.cxx delete mode 100644 Kernel/Source/Utils.cxx delete mode 100644 Kernel/Source/Variant.cxx delete mode 100644 Kernel/Source/compile_flags.txt create mode 100644 Kernel/Sources/AppMain.cxx create mode 100644 Kernel/Sources/Array.cxx create mode 100644 Kernel/Sources/ArrayList.cxx create mode 100644 Kernel/Sources/Atom.cxx create mode 100644 Kernel/Sources/CodeManager.cxx create mode 100644 Kernel/Sources/Crc32.cxx create mode 100644 Kernel/Sources/CxxAbi.cxx create mode 100644 Kernel/Sources/Defines.cxx create mode 100644 Kernel/Sources/DeviceManager.cxx create mode 100644 Kernel/Sources/DriveManager.cxx create mode 100644 Kernel/Sources/ErrorOr.cxx create mode 100644 Kernel/Sources/FS/NewFS.cxx create mode 100644 Kernel/Sources/FileManager.cxx create mode 100644 Kernel/Sources/Framebuffer.cxx create mode 100644 Kernel/Sources/GUIDWizard.cxx create mode 100644 Kernel/Sources/GUIDWrapper.cxx create mode 100644 Kernel/Sources/HError.cxx create mode 100644 Kernel/Sources/IndexableProperty.cxx create mode 100644 Kernel/Sources/Json.cxx create mode 100644 Kernel/Sources/KernelCheck.cxx create mode 100644 Kernel/Sources/KernelHeap.cxx create mode 100644 Kernel/Sources/LockDelegate.cxx create mode 100644 Kernel/Sources/MutableArray.cxx create mode 100644 Kernel/Sources/Network/IP.cxx create mode 100644 Kernel/Sources/Network/IPCEP.cxx create mode 100644 Kernel/Sources/Network/NetworkDevice.cxx create mode 100644 Kernel/Sources/New+Delete.cxx create mode 100644 Kernel/Sources/NewFS+FileManager.cxx create mode 100644 Kernel/Sources/NewFS+IO.cxx create mode 100644 Kernel/Sources/NewFS+Journal.cxx create mode 100644 Kernel/Sources/OwnPtr.cxx create mode 100644 Kernel/Sources/PEFCodeManager.cxx create mode 100644 Kernel/Sources/PEFSharedObjectRT.cxx create mode 100644 Kernel/Sources/PRDT.cxx create mode 100644 Kernel/Sources/PageAllocator.cxx create mode 100644 Kernel/Sources/PageManager.cxx create mode 100644 Kernel/Sources/PermissionSelector.cxx create mode 100644 Kernel/Sources/Pmm.cxx create mode 100644 Kernel/Sources/ProcessScheduler.cxx create mode 100644 Kernel/Sources/ProcessTeam.cxx create mode 100644 Kernel/Sources/Property.cxx create mode 100644 Kernel/Sources/Ref.cxx create mode 100644 Kernel/Sources/SMPManager.cxx create mode 100644 Kernel/Sources/Semaphore.cxx create mode 100644 Kernel/Sources/Storage/AHCIDeviceInterface.cxx create mode 100644 Kernel/Sources/Storage/ATADeviceInterface.cxx create mode 100644 Kernel/Sources/Storage/NVMEDeviceInterface.cxx create mode 100644 Kernel/Sources/Storage/SCSIDeviceInterface.cxx create mode 100644 Kernel/Sources/Stream.cxx create mode 100644 Kernel/Sources/String.cxx create mode 100644 Kernel/Sources/ThreadLocalStorage.cxx create mode 100644 Kernel/Sources/Timer.cxx create mode 100644 Kernel/Sources/URL.cxx create mode 100644 Kernel/Sources/UserHeap.cxx create mode 100644 Kernel/Sources/Utils.cxx create mode 100644 Kernel/Sources/Variant.cxx create mode 100644 Kernel/Sources/compile_flags.txt (limited to 'Kernel') diff --git a/Kernel/Source/AppMain.cxx b/Kernel/Source/AppMain.cxx deleted file mode 100644 index e9da459b..00000000 --- a/Kernel/Source/AppMain.cxx +++ /dev/null @@ -1,228 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - - File: AppMain.cxx - Purpose: Kernel main loop. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace NewOS::Detail -{ - /// @brief Filesystem auto mounter, additional checks are also done by the - /// class. - class FilesystemWizard final - { - NewOS::NewFilesystemManager* fNewFS{nullptr}; - - public: - explicit FilesystemWizard() - { - if (NewOS::FilesystemManagerInterface::GetMounted()) - { - /// Mounted partition, cool! - NewOS::kcout - << "New OS: No need to create for a NewFS partition here...\r"; - } - else - { - /// Not mounted partition, auto-mount. - ///! Mounts a NewFS block. - fNewFS = new NewOS::NewFilesystemManager(); - - NewOS::FilesystemManagerInterface::Mount(fNewFS); - - if (fNewFS->GetImpl()) - { - constexpr auto cFolderInfo = "Metadata"; - const auto cDirCount = 8; - const char* cDirStr[cDirCount] = { - "/Boot/", "/System/", "/Support/", "/Applications/", - "/Users/", "/Library/", "/Mount/", "/Assistants/"}; - - for (NewOS::SizeT dirIndx = 0UL; dirIndx < cDirCount; ++dirIndx) - { - auto catalogDir = fNewFS->GetImpl()->GetCatalog(cDirStr[dirIndx]); - - if (catalogDir) - { - delete catalogDir; - continue; - } - - catalogDir = fNewFS->GetImpl()->CreateCatalog(cDirStr[dirIndx], 0, - kNewFSCatalogKindDir); - - NewFork theFork{0}; - - const NewOS::Char* cSrcName = cFolderInfo; - - NewOS::rt_copy_memory((NewOS::VoidPtr)(cSrcName), theFork.ForkName, - NewOS::rt_string_len(cSrcName)); - - NewOS::rt_copy_memory((NewOS::VoidPtr)(catalogDir->Name), - theFork.CatalogName, - NewOS::rt_string_len(catalogDir->Name)); - - delete catalogDir; - - theFork.DataSize = kNewFSForkSize; - theFork.ResourceId = 0; - theFork.ResourceKind = NewOS::kNewFSRsrcForkKind; - theFork.Kind = NewOS::kNewFSDataForkKind; - - NewOS::StringView metadataFolder(kNewFSSectorSz); - - metadataFolder += - "

Kind: folder

\r

Created by: system

\r

Edited by: " - "system

\r

Volume Type: New OS Standard

\r"; - - metadataFolder += "

File name: "; - metadataFolder += cDirStr[dirIndx]; - metadataFolder += "

\r"; - - const NewOS::SizeT metadataSz = kNewFSSectorSz; - - auto catalogSystem = fNewFS->GetImpl()->GetCatalog(cDirStr[dirIndx]); - - fNewFS->GetImpl()->CreateFork(catalogSystem, theFork); - - fNewFS->GetImpl()->WriteCatalog( - catalogSystem, (NewOS::VoidPtr)(metadataFolder.CData()), - metadataSz, cFolderInfo); - - delete catalogSystem; - } - } - - NewCatalog* catalogDisk = - this->fNewFS->GetImpl()->GetCatalog("/Mount/This Disk"); - - const NewOS::Char* cSrcName = "DiskInfo"; - - if (catalogDisk) - { - auto bufferInfoDisk = (NewOS::Char*)this->fNewFS->GetImpl()->ReadCatalog(catalogDisk, kNewFSSectorSz, cSrcName); - NewOS::kcout << bufferInfoDisk << NewOS::end_line(); - - delete bufferInfoDisk; - delete catalogDisk; - } - else - { - catalogDisk = - (NewCatalog*)this->Leak()->CreateAlias("/Mount/This Disk"); - - NewOS::StringView diskFolder(kNewFSSectorSz); - - diskFolder += - "

Kind: alias to disk

\r

Created by: system

\r

Edited " - "by: " - "system

\r

Volume Type: New OS Standard

\r"; - - diskFolder += "

Original Path: "; - diskFolder += NewOS::NewFilesystemHelper::Root(); - diskFolder += "

\r"; - - NewFork theDiskFork{0}; - - NewOS::rt_copy_memory((NewOS::VoidPtr)(cSrcName), theDiskFork.ForkName, - NewOS::rt_string_len(cSrcName)); - - NewOS::rt_copy_memory((NewOS::VoidPtr)(catalogDisk->Name), - theDiskFork.CatalogName, - NewOS::rt_string_len(catalogDisk->Name)); - - theDiskFork.DataSize = kNewFSForkSize; - theDiskFork.ResourceId = 0; - theDiskFork.ResourceKind = NewOS::kNewFSRsrcForkKind; - theDiskFork.Kind = NewOS::kNewFSDataForkKind; - - fNewFS->GetImpl()->CreateFork(catalogDisk, theDiskFork); - fNewFS->GetImpl()->WriteCatalog(catalogDisk, - (NewOS::VoidPtr)diskFolder.CData(), - kNewFSSectorSz, cSrcName); - - delete catalogDisk; - } - } - } - - ~FilesystemWizard() - { - delete fNewFS; - } - - NEWOS_COPY_DEFAULT(FilesystemWizard); - - /// Grab the disk's NewFS reference. - NewOS::NewFilesystemManager* Leak() - { - return fNewFS; - } - }; - - /// @brief System loader entrypoint. - /// @param void no parameters. - /// @return void no return value. - STATIC NewOS::Void AppSystemLoader(NewOS::Void) - { - NewOS::PEFLoader coreGraphicsShLib("/System/CoreGraphics"); - - if (!coreGraphicsShLib.IsLoaded()) - { - NewOS::ke_stop(RUNTIME_CHECK_FAILED); - } - - NewOS::Utils::execute_from_image(coreGraphicsShLib, - NewOS::ProcessHeader::kLibKind); - - NewOS::PEFLoader logonService("/System/Login"); - - if (!logonService.IsLoaded()) - { - NewOS::ke_stop(RUNTIME_CHECK_FAILED); - } - - NewOS::Utils::execute_from_image(logonService, - NewOS::ProcessHeader::kAppKind); - - NewOS::kcout << "SystemLoader: Exiting process, we're done initializing stuff..."; - - NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Exit(0); - } -} // namespace NewOS::Detail - -/// @brief Application entrypoint. -/// @param Void -/// @return Void -EXTERN_C NewOS::Void AppMain(NewOS::Void) -{ - /// Now run kernel loop, until no process are running. - NewOS::Detail::FilesystemWizard wizard; // automatic. - - auto cLoaderName = "SystemLoader"; - NewOS::execute_from_image(NewOS::Detail::AppSystemLoader, cLoaderName); - - while (NewOS::ProcessScheduler::Shared().Leak().Run() > 0) - { - NewOS::kcout << "New OS: Shuting down...\r"; - } -} diff --git a/Kernel/Source/Array.cxx b/Kernel/Source/Array.cxx deleted file mode 100644 index f1df0abe..00000000 --- a/Kernel/Source/Array.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/ArrayList.cxx b/Kernel/Source/ArrayList.cxx deleted file mode 100644 index e96e993c..00000000 --- a/Kernel/Source/ArrayList.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/Atom.cxx b/Kernel/Source/Atom.cxx deleted file mode 100644 index 0619e4ad..00000000 --- a/Kernel/Source/Atom.cxx +++ /dev/null @@ -1,10 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -// @file Atom.cpp -// @brief Atomic primitives diff --git a/Kernel/Source/CodeManager.cxx b/Kernel/Source/CodeManager.cxx deleted file mode 100644 index 358481f6..00000000 --- a/Kernel/Source/CodeManager.cxx +++ /dev/null @@ -1,30 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -namespace NewOS -{ - /// @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. - bool execute_from_image(MainKind main, const char* processName) noexcept - { - if (!main) - return false; - - ProcessHeader proc((VoidPtr)main); - proc.Kind = ProcessHeader::kDriverKind; - rt_copy_memory((VoidPtr)processName, proc.Name, rt_string_len(proc.Name)); - - Ref refProc = proc; - - return ProcessScheduler::Shared().Leak().Add(refProc); - } -} // namespace NewOS \ No newline at end of file diff --git a/Kernel/Source/Crc32.cxx b/Kernel/Source/Crc32.cxx deleted file mode 100644 index 2fd273e0..00000000 --- a/Kernel/Source/Crc32.cxx +++ /dev/null @@ -1,74 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -// @file CRC32.cpp -// @brief Check sequence implementation. - -namespace NewOS -{ - /// @brief The CRC32 table. - UInt kCrcTbl[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 p the data to compute. - /// @param len the length of the data. - /// @return the CRC32. - UInt ke_calculate_crc32(const Char* p, UInt len) noexcept - { - UInt crc = 0xffffffff; - - while (len-- != 0) - crc = kCrcTbl[((UInt8)crc ^ *(p++))] ^ (crc >> 8); - - // return (~crc); also works, does the same thing. - return (crc ^ 0xffffffff); - } -} // namespace NewOS diff --git a/Kernel/Source/CxxAbi.cxx b/Kernel/Source/CxxAbi.cxx deleted file mode 100644 index 9aea8db7..00000000 --- a/Kernel/Source/CxxAbi.cxx +++ /dev/null @@ -1,87 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -atexit_func_entry_t __atexit_funcs[kDSOMaxObjects]; - -uarch_t __atexit_func_count; - -extern "C" void __cxa_pure_virtual() -{ - NewOS::kcout << "New OS: C++ placeholder method.\n"; -} - -extern "C" void ___chkstk_ms() -{ - while (1) - { - asm("cli"); - asm("hlt"); - } -} - -extern "C" int atexit(void (*f)(void*), void* arg, void* dso) -{ - if (__atexit_func_count >= kDSOMaxObjects) - return -1; - - __atexit_funcs[__atexit_func_count].destructor_func = f; - __atexit_funcs[__atexit_func_count].obj_ptr = arg; - __atexit_funcs[__atexit_func_count].dso_handle = dso; - - __atexit_func_count++; - - return 0; -} - -extern "C" void __cxa_finalize(void* f) -{ - uarch_t i = __atexit_func_count; - if (!f) - { - while (i--) - { - if (__atexit_funcs[i].destructor_func) - { - (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].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; - } - - 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 diff --git a/Kernel/Source/Defines.cxx b/Kernel/Source/Defines.cxx deleted file mode 100644 index 919d0fe4..00000000 --- a/Kernel/Source/Defines.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/DeviceManager.cxx b/Kernel/Source/DeviceManager.cxx deleted file mode 100644 index 5679b2af..00000000 --- a/Kernel/Source/DeviceManager.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/DriveManager.cxx b/Kernel/Source/DriveManager.cxx deleted file mode 100644 index 62195b99..00000000 --- a/Kernel/Source/DriveManager.cxx +++ /dev/null @@ -1,149 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include -#include -#include - -/// @file DriveManager.cxx -/// @brief Kernel drive manager. - -namespace NewOS -{ - static UInt16 kATAIO = 0U; - static UInt8 kATAMaster = 0U; - - /// @brief reads from an ATA drive. - /// @param pckt - /// @return - Void ke_drv_input(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - - pckt->fPacketGood = false; - -#ifdef __AHCI__ - drv_std_read(pckt->fLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_read(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); -#endif - - pckt->fPacketGood = true; - } - - /// @brief Writes to an ATA drive. - /// @param pckt - /// @return - Void ke_drv_output(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - - pckt->fPacketGood = false; - -#ifdef __AHCI__ - drv_std_write(pckt->fLba, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_write(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); -#endif - - pckt->fPacketGood = true; - } - - /// @brief Executes a disk check on the ATA drive. - /// @param pckt - /// @return - Void ke_drv_check_disk(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - - pckt->fPacketGood = false; - -#if defined(__ATA_PIO__) || defined(__ATA_DMA__) - kATAMaster = true; - kATAIO = ATA_PRIMARY_IO; - - MUST_PASS(drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)); -#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) - - pckt->fPacketGood = true; - } - -/// @brief Gets the drive kind (ATA, SCSI, AHCI...) -/// @param -/// @return -#ifdef __ATA_PIO__ - const Char* ke_drive_kind(Void) - { - return "ATA-PIO"; - } -#endif - -#ifdef __ATA_DMA__ - const Char* ke_drive_kind(Void) - { - return "ATA-DMA"; - } -#endif - -#ifdef __AHCI__ - const Char* ke_drive_kind(Void) - { - return "AHCI"; - } -#endif - - /// @brief Unimplemented drive. - /// @param pckt - /// @return - Void ke_drv_unimplemented(DriveTrait::DrivePacket* pckt) - { - } - - /// @brief Makes a new drive. - /// @return the new drive. - DriveTrait construct_drive() noexcept - { - DriveTrait trait; - - rt_copy_memory((VoidPtr) "/Mount/Null", trait.fName, rt_string_len("/Mount/Null")); - trait.fKind = kInvalidDrive; - - trait.fInput = ke_drv_unimplemented; - trait.fOutput = ke_drv_unimplemented; - trait.fVerify = ke_drv_unimplemented; - trait.fDriveKind = ke_drive_kind; - - return trait; - } - - /// @brief Fetches the main drive. - /// @return the new drive. - DriveTrait construct_main_drive() noexcept - { - DriveTrait trait; - - rt_copy_memory((VoidPtr) "/Mount/MainDisk/", trait.fName, rt_string_len("/Mount/MainDisk/")); - trait.fKind = kMassStorage | kEPMDrive; - - trait.fInput = ke_drv_input; - trait.fOutput = ke_drv_output; - trait.fVerify = ke_drv_check_disk; - trait.fDriveKind = ke_drive_kind; - - return trait; - } -} // namespace NewOS diff --git a/Kernel/Source/ErrorOr.cxx b/Kernel/Source/ErrorOr.cxx deleted file mode 100644 index 10d6cc8f..00000000 --- a/Kernel/Source/ErrorOr.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -/***********************************************************************************/ -/// @file ErrorOr.cxx /// -/// @brief Error Or Value class. /// -/***********************************************************************************/ diff --git a/Kernel/Source/FS/NewFS.cxx b/Kernel/Source/FS/NewFS.cxx deleted file mode 100644 index 6f19c8ed..00000000 --- a/Kernel/Source/FS/NewFS.cxx +++ /dev/null @@ -1,943 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#ifdef __FSKIT_NEWFS__ - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace NewOS; - -///! BUGS: 0 - -/***********************************************************************************/ -/// This file implements the New File System. -/// New File System implements a B-Tree based algortihm. -/// /Disk -/// /Path1 /Path2 -/// /File.txt /File.pef /File.png <-- symlink. -/// /Path1/File.txt -/***********************************************************************************/ - -STATIC MountpointInterface sMountpointInterface; - -/// @brief Creates a new fork inside the New filesystem partition. -/// @param catalog it's catalog -/// @param theFork the fork itself. -/// @return the fork -_Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, - _Input NewFork& theFork) -{ - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return nullptr; - - if (catalog && theFork.ForkName[0] != 0 && - theFork.DataSize == kNewFSForkSize) - { - Lba lba = (theFork.Kind == kNewFSDataForkKind) ? catalog->DataFork - : catalog->ResourceFork; - - kcout << "Fork Lba: " << hex_number(lba) << endl; - - if (lba <= kNewFSCatalogStartAddress) - return nullptr; - - auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); - - /// special treatment. - rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - NewFork curFork{0}; - NewFork prevFork{0}; - Lba lbaOfPreviousFork = lba; - - /// do not check for anything. Loop until we get what we want, that is a free fork zone. - while (true) - { - if (lba <= kNewFSCatalogStartAddress) - break; - - drv->fPacket.fLba = lba; - drv->fPacket.fPacketSize = sizeof(NewFork); - drv->fPacket.fPacketContent = &curFork; - - drv->fInput(&drv->fPacket); - - kcout << "New OS: Next-Fork: " << hex_number(curFork.NextSibling) << endl; - - if (curFork.Flags == kNewFSFlagCreated) - { - kcout << "New OS: Fork already exists.\r"; - - /// sanity check. - if (StringBuilder::Equals(curFork.ForkName, theFork.ForkName) && - StringBuilder::Equals(curFork.CatalogName, catalog->Name)) - return nullptr; - - kcout << "Next-Fork: " << hex_number(curFork.NextSibling) << endl; - - lbaOfPreviousFork = lba; - lba = curFork.NextSibling; - - prevFork = curFork; - } - else - { - /// This is a check that we have, in order to link the previous fork - /// entry. - if (lba >= kNewFSCatalogStartAddress) - { - drv->fPacket.fLba = lbaOfPreviousFork; - drv->fPacket.fPacketSize = sizeof(NewFork); - drv->fPacket.fPacketContent = &prevFork; - - prevFork.NextSibling = lba; - - /// write to disk. - drv->fOutput(&drv->fPacket); - } - - break; - } - } - - constexpr auto cForkPadding = - 4; /// this value gives us space for the data offset. - - theFork.Flags = kNewFSFlagCreated; - theFork.DataOffset = lba - sizeof(NewFork) * cForkPadding; - theFork.PreviousSibling = lbaOfPreviousFork; - theFork.NextSibling = theFork.DataOffset - theFork.DataSize; - - drv->fPacket.fLba = lba; - drv->fPacket.fPacketSize = sizeof(NewFork); - drv->fPacket.fPacketContent = &theFork; - - drv->fOutput(&drv->fPacket); - - /// log what we have now. - kcout << "New OS: Wrote fork data at: " << hex_number(theFork.DataOffset) - << endl; - - kcout << "New OS: Wrote fork at: " << hex_number(lba) << endl; - - return &theFork; - } - - return nullptr; -} - -/// @brief Find fork inside New filesystem. -/// @param catalog the catalog. -/// @param name the fork name. -/// @return the fork. -_Output NewFork* NewFSParser::FindFork(_Input NewCatalog* catalog, - _Input const Char* name, - Boolean isDataFork) -{ - auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); - NewFork* theFork = nullptr; - - Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; - - while (lba != 0) - { - drv->fPacket.fLba = lba; - drv->fPacket.fPacketSize = sizeof(NewFork); - drv->fPacket.fPacketContent = (VoidPtr)theFork; - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, 16); - - if (auto res = - fs_newfs_read(&sMountpointInterface, *drv, this->fDriveIndex); - res) - { - switch (res) - { - case 1: - DbgLastError() = kErrorDiskReadOnly; - break; - case 2: - DbgLastError() = kErrorDiskIsFull; - break; - DbgLastError() = kErrorNoSuchDisk; - break; - - default: - break; - } - return nullptr; - } - - if (StringBuilder::Equals(theFork->ForkName, name)) - { - break; - } - - lba = theFork->NextSibling; - } - - return theFork; -} - -/// @brief Simpler factory to create a catalog (assumes you want to create a -/// file.) -/// @param name -/// @return catalog pointer. -_Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name) -{ - return this->CreateCatalog(name, 0, kNewFSCatalogKindFile); -} - -/// @brief Creates a new catalog into the disk. -/// @param name the catalog name. -/// @param flags the flags of the catalog. -/// @param kind the catalog kind. -/// @return catalog pointer. -_Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, - _Input const Int32& flags, - _Input const Int32& kind) -{ - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return nullptr; - - Lba outLba = 0UL; - - /// a directory should have a slash in the end. - if (kind == kNewFSCatalogKindDir && - name[rt_string_len(name) - 1] != NewFilesystemHelper::Separator()) - return nullptr; - - /// a file shouldn't have a slash in the end. - if (kind != kNewFSCatalogKindDir && - name[rt_string_len(name) - 1] == NewFilesystemHelper::Separator()) - return nullptr; - - NewCatalog* checkForCpy = this->FindCatalog(name, outLba); - - if (checkForCpy) - { - return checkForCpy; - } - - char parentName[kNewFSNodeNameLen] = {0}; - - for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) - { - parentName[indexName] = name[indexName]; - } - - if (*parentName == 0) - { - DbgLastError() = kErrorFileNotFound; - return nullptr; - } - - /// Locate parent catalog, to then allocate right after it. - - for (SizeT indexFill = 0; indexFill < rt_string_len(name); ++indexFill) - { - parentName[indexFill] = name[indexFill]; - } - - SizeT indexReverseCopy = rt_string_len(parentName); - - // zero character. - parentName[--indexReverseCopy] = 0; - - // mandatory / character. - parentName[--indexReverseCopy] = 0; - - while (parentName[indexReverseCopy] != NewFilesystemHelper::Separator()) - { - parentName[indexReverseCopy] = 0; - --indexReverseCopy; - } - - NewCatalog* catalog = this->FindCatalog(parentName, outLba); - - if (catalog && catalog->Kind == kNewFSCatalogKindFile) - { - delete catalog; - return nullptr; - } - else if (!catalog) - { - outLba = kNewFSCatalogStartAddress; - } - - constexpr SizeT cDefaultForkSize = kNewFSForkSize; - - NewCatalog* catalogChild = new NewCatalog(); - - catalogChild->ResourceForkSize = cDefaultForkSize; - catalogChild->DataForkSize = cDefaultForkSize; - - catalogChild->NextSibling = outLba; - catalogChild->PrevSibling = outLba; - catalogChild->Kind = kind; - catalogChild->Flags = kNewFSFlagCreated; - - rt_copy_memory((VoidPtr)name, (VoidPtr)catalogChild->Name, - rt_string_len(name)); - - UInt16 catalogBuf[kNewFSSectorSz] = {0}; - - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - - Lba startFree = outLba; - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - drive->fPacket.fPacketContent = catalogBuf; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = startFree; - - drive->fInput(&drive->fPacket); - - NewCatalog* nextSibling = (NewCatalog*)catalogBuf; - - startFree = nextSibling->NextSibling; - - catalogChild->PrevSibling = outLba; - - drive->fPacket.fLba = startFree; - drive->fInput(&drive->fPacket); - - while (drive->fPacket.fPacketGood) - { - nextSibling = (NewCatalog*)catalogBuf; - - if (startFree <= kNewFSAddressAsLba) - { - delete catalogChild; - delete catalog; - - return nullptr; - } - - /// allocation or reallocation or catalog... - if (nextSibling->Flags != kNewFSFlagCreated) - { - Char sectorBufPartBlock[kNewFSSectorSz] = {0}; - - drive->fPacket.fPacketContent = sectorBufPartBlock; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = kNewFSAddressAsLba; - - drive->fInput(&drive->fPacket); - - constexpr auto cNewFSCatalogPadding = 4; - - NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBufPartBlock; - - if (partBlock->FreeCatalog < 1) - { - delete catalogChild; - return nullptr; - } - - catalogChild->DataFork = partBlock->DiskSize - partBlock->StartCatalog; - - catalogChild->ResourceFork = catalogChild->DataFork; - - catalogChild->NextSibling = - startFree + (sizeof(NewCatalog) * cNewFSCatalogPadding); - - drive->fPacket.fPacketContent = catalogChild; - drive->fPacket.fPacketSize = sizeof(NewCatalog); - drive->fPacket.fLba = startFree; - - drive->fOutput(&drive->fPacket); - - drive->fPacket.fPacketContent = catalogBuf; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = - startFree - (sizeof(NewCatalog) * cNewFSCatalogPadding); - - drive->fInput(&drive->fPacket); - - nextSibling->NextSibling = startFree; - - drive->fOutput(&drive->fPacket); - - kcout << "New OS: Create new catalog, status: " - << hex_number(catalogChild->Flags) << endl; - kcout << "New OS: Create new catalog, status: " << catalogChild->Name - << endl; - - drive->fPacket.fPacketContent = sectorBufPartBlock; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = kNewFSAddressAsLba; - - drive->fInput(&drive->fPacket); - - partBlock->SectorCount -= 1; - partBlock->CatalogCount += 1; - partBlock->FreeCatalog -= 1; - partBlock->FreeCatalog = catalogChild->NextSibling; - - drive->fOutput(&drive->fPacket); - - delete catalog; - return catalogChild; - } - - constexpr auto cNewFSCatalogPadding = 4; - - //// @note that's how we find the next catalog in the partition block. - startFree = startFree + (sizeof(NewCatalog) * cNewFSCatalogPadding); - - drive->fPacket.fPacketContent = catalogBuf; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = startFree; - - drive->fInput(&drive->fPacket); - } - - delete catalog; - return nullptr; -} - -/// @brief Make a EPM+NewFS drive out of the disk. -/// @param drive The drive to write on. -/// @return If it was sucessful, see DbgLastError(). -bool NewFSParser::Format(_Input _Output DriveTrait* drive) -{ - /// verify disk. - drive->fVerify(&drive->fPacket); - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - /// if disk isn't good, then error out. - if (false == drive->fPacket.fPacketGood) - { - DbgLastError() = kErrorDiskIsCorrupted; - return false; - } - - Char sectorBuf[kNewFSSectorSz] = {0}; - - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = kNewFSAddressAsLba; - - drive->fInput(&drive->fPacket); - - /// disk isnt faulty and data has been fetched. - if (drive->fPacket.fPacketGood) - { - NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBuf; - - /// check for an empty partition here. - if (partBlock->PartitionName[0] == 0 && - rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen)) - { - /// partition is free and valid. - - partBlock->Version = kNewFSVersionInteger; - - const auto cUntitledHD = "New OS HD\0"; - - rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident, - kNewFSIdentLen); - - rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)partBlock->PartitionName, - rt_string_len(cUntitledHD)); - - SizeT catalogCount = 0; - SizeT sectorCount = drv_std_get_sector_count(); - SizeT diskSize = drv_std_get_drv_size(); - - partBlock->Kind = kNewFSPartitionTypeStandard; - partBlock->StartCatalog = kNewFSCatalogStartAddress; - partBlock->Flags = kNewFSPartitionTypeStandard; - partBlock->CatalogCount = sectorCount / sizeof(NewCatalog); - partBlock->SectorCount = sectorCount; - partBlock->DiskSize = diskSize; - partBlock->FreeCatalog = sectorCount / sizeof(NewCatalog); - - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = kNewFSSectorSz; - drive->fPacket.fLba = kNewFSAddressAsLba; - - drive->fOutput(&drive->fPacket); - - kcout << "Drive-Kind: " << drive->fDriveKind() << endl; - - kcout << "Partition-Name: " << partBlock->PartitionName << endl; - kcout << "Start-Catalog: " << hex_number(partBlock->StartCatalog) << endl; - kcout << "Catalog-Count: " << hex_number(partBlock->CatalogCount) << endl; - kcout << "Free-Catalog: " << hex_number(partBlock->FreeCatalog) << endl; - kcout << "Free-Sectors: " << hex_number(partBlock->FreeSectors) << endl; - kcout << "Sector-Size: " << hex_number(partBlock->SectorSize) << endl; - - /// write the root catalog. - this->CreateCatalog(kNewFSRoot, 0, kNewFSCatalogKindDir); - - return true; - } - - kcout << "New OS: PartitionBlock already exists.\r"; - - /// return success as well, do not ignore that partition. - return true; - } - - 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 NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data, SizeT sizeOfData, _Input const char* forkName) -{ - if (sizeOfData > catalog->DataForkSize) - return false; - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return false; - - NewFork* forkData = new NewFork(); - rt_set_memory(forkData, 0, sizeof(NewFork)); - - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - auto startFork = catalog->DataFork; - - rt_copy_memory(catalog->Name, forkData->CatalogName, kNewFSNodeNameLen); - - /// sanity check of the fork position as the condition to run the loop. - while (startFork >= kNewFSCatalogStartAddress) - { - drive->fPacket.fPacketContent = forkData; - drive->fPacket.fPacketSize = sizeof(NewFork); - drive->fPacket.fLba = startFork; - - drive->fInput(&drive->fPacket); - - kcout << "Fork-Name: " << forkData->ForkName << endl; - - /// sanity check the fork. - if (forkData->DataOffset <= kNewFSCatalogStartAddress) - { - DbgLastError() = kErrorDiskIsCorrupted; - - kcout << "New OS: Invalid fork offset.\r"; - - delete forkData; - return false; - } - - if (forkData->Flags != kNewFSFlagUnallocated && - forkData->Flags != kNewFSFlagDeleted && - StringBuilder::Equals(forkData->ForkName, forkName) && - StringBuilder::Equals(forkData->CatalogName, catalog->Name)) - { - drive->fPacket.fPacketContent = data; - drive->fPacket.fPacketSize = sizeOfData; - drive->fPacket.fLba = forkData->DataOffset; - kcout << "Fork-Offset: " << hex_number(forkData->DataOffset) << endl; - - drive->fOutput(&drive->fPacket); - - delete forkData; - return true; - } - else if (auto catalog = this->GetCatalog(forkData->CatalogName); - catalog == nullptr) - { - delete catalog; - drive->fPacket.fPacketContent = data; - drive->fPacket.fPacketSize = sizeOfData; - drive->fPacket.fLba = forkData->DataOffset; - kcout << "Fork-Offset: " << hex_number(forkData->DataOffset) << endl; - - drive->fOutput(&drive->fPacket); - - delete forkData; - return true; - } - - startFork = forkData->NextSibling; - } - - delete forkData; - return false; -} - -/// @brief -/// @param catalogName the catalog name. -/// @return the newly found catalog. -_Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName, - Lba& outLba) -{ - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return nullptr; - - Char* sectorBuf = new Char[sizeof(NewPartitionBlock)]; - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); - drive->fPacket.fLba = kNewFSAddressAsLba; - - drive->fInput(&drive->fPacket); - - NewPartitionBlock* part = (NewPartitionBlock*)sectorBuf; - - auto startCatalogList = part->StartCatalog; - const auto cCtartCatalogList = part->StartCatalog; - - auto localSearchFirst = false; - - drive->fPacket.fLba = startCatalogList; - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewCatalog); - - drive->fInput(&drive->fPacket); - - if (!StringBuilder::Equals(catalogName, NewFilesystemHelper::Root())) - { - Char parentName[kNewFSNodeNameLen] = {0}; - - for (SizeT indexFill = 0; indexFill < rt_string_len(catalogName); ++indexFill) - { - parentName[indexFill] = catalogName[indexFill]; - } - - SizeT indexReverseCopy = rt_string_len(parentName); - - // zero character. - parentName[--indexReverseCopy] = 0; - - // mandatory '/' character. - parentName[--indexReverseCopy] = 0; - - while (parentName[indexReverseCopy] != NewFilesystemHelper::Separator()) - { - parentName[indexReverseCopy] = 0; - --indexReverseCopy; - } - - NewCatalog* parentCatalog = this->FindCatalog(parentName, outLba); - - if (parentCatalog && - !StringBuilder::Equals(parentName, NewFilesystemHelper::Root())) - { - startCatalogList = outLba; - delete parentCatalog; - - localSearchFirst = true; - } - else if (parentCatalog) - { - delete parentCatalog; - } - } - -_NewFSSearchThroughCatalogList: - while (drive->fPacket.fPacketGood) - { - NewCatalog* catalog = (NewCatalog*)sectorBuf; - - if (StringBuilder::Equals(catalogName, catalog->Name)) - { - /// ignore unallocated catalog, break - if (catalog->Flags != kNewFSFlagCreated) - { - goto _NewFSContinueSearch; - } - - NewCatalog* catalogPtr = new NewCatalog(); - rt_copy_memory(catalog, catalogPtr, sizeof(NewCatalog)); - - kcout << "New OS: Found catalog at: " << hex_number(startCatalogList) << endl; - - outLba = startCatalogList; - delete[] sectorBuf; - return catalogPtr; - } - - _NewFSContinueSearch: - startCatalogList = catalog->NextSibling; - - if (startCatalogList <= kNewFSAddressAsLba) - break; - - drive->fPacket.fLba = startCatalogList; - drive->fPacket.fPacketContent = sectorBuf; - drive->fPacket.fPacketSize = sizeof(NewCatalog); - - drive->fInput(&drive->fPacket); - } - - if (localSearchFirst) - { - localSearchFirst = false; - startCatalogList = cCtartCatalogList; - - goto _NewFSSearchThroughCatalogList; - } - - outLba = 0UL; - delete[] sectorBuf; - - return nullptr; -} - -/// @brief -/// @param name -/// @return -_Output NewCatalog* NewFSParser::GetCatalog(_Input const char* name) -{ - Lba unused = 0; - return this->FindCatalog(name, unused); -} - -/// @brief -/// @param catalog -/// @return -Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) -{ - if (!catalog) - return false; - - delete catalog; - catalog = nullptr; - - return true; -} - -/// @brief Mark catalog as removed. -/// @param catalog The catalog structure. -/// @return if the catalog was removed or not. -Boolean NewFSParser::RemoveCatalog(_Input const Char* catalogName) -{ - if (!catalogName || - StringBuilder::Equals(catalogName, NewFilesystemHelper::Root())) - { - DbgLastError() = kErrorInternal; - return false; - } - - Lba outLba = 0; - auto catalog = this->FindCatalog(catalogName, outLba); - - if (outLba >= kNewFSCatalogStartAddress || - catalog->Flags == kNewFSFlagCreated) - { - catalog->Flags = kNewFSFlagDeleted; - - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - drive->fPacket.fLba = outLba; // the catalog position. - drive->fPacket.fPacketSize = - sizeof(NewCatalog); // size of catalog. roughly the sector size. - drive->fPacket.fPacketContent = catalog; // the catalog itself. - - drive->fOutput(&drive->fPacket); // send packet. - - Char partitionBlockBuf[sizeof(NewPartitionBlock)] = {0}; - - drive->fPacket.fLba = kNewFSAddressAsLba; - drive->fPacket.fPacketContent = partitionBlockBuf; - drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); - - drive->fInput(&drive->fPacket); - - NewPartitionBlock* partBlock = - reinterpret_cast(partitionBlockBuf); - - ++partBlock->FreeCatalog; - --partBlock->CatalogCount; - - drive->fOutput(&drive->fPacket); - - return true; - } - - delete catalog; - return false; -} - -/// ***************************************************************** /// -/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead. -/// ***************************************************************** /// - -/***********************************************************************************/ -/// @brief Read the catalog data fork. -/// @param catalog -/// @param dataSz -/// @return -/***********************************************************************************/ - -VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, - _Input SizeT dataSz, - _Input const char* forkName) -{ - if (!catalog) - { - DbgLastError() = kErrorFileNotFound; - return nullptr; - } - - if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) - return nullptr; - - Lba dataForkLba = catalog->DataFork; - Size dataForkSize = catalog->DataForkSize; - - kcout << "Found-Catalog: " << catalog->Name - << ", Data-Fork: " << hex_number(dataForkLba) << endl; - - Char* sectorBuf = new Char[sizeof(NewFork)]; - auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); - - rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/newfs-packet")); - - NewFork* forkData = nullptr; - - while (dataForkLba >= kNewFSCatalogStartAddress) - { - drive->fPacket.fLba = dataForkLba; - drive->fPacket.fPacketSize = sizeof(NewFork); - drive->fPacket.fPacketContent = sectorBuf; - - drive->fInput(&drive->fPacket); - - forkData = (NewFork*)sectorBuf; - - kcout << "Fork-Name: " << forkData->ForkName << endl; - - if (forkData->DataOffset <= kNewFSCatalogStartAddress) - { - delete[] sectorBuf; - - kcout << "Fail-Data-Offset: " << hex_number(forkData->DataOffset) << endl; - - return nullptr; - } - - if (StringBuilder::Equals(forkName, forkData->ForkName) && - StringBuilder::Equals(catalog->Name, forkData->CatalogName)) - break; - - dataForkLba = forkData->NextSibling; - } - - if (dataForkLba <= kNewFSCatalogStartAddress) - { - delete[] sectorBuf; - return nullptr; - } - - Char* forkBuf = new Char[dataSz]; - - drive->fPacket.fLba = forkData->DataOffset; - drive->fPacket.fPacketSize = dataSz; - drive->fPacket.fPacketContent = forkBuf; - - drive->fInput(&drive->fPacket); - - delete[] sectorBuf; - return forkBuf; -} - -/***********************************************************************************/ -/// @brief Seek in the data fork. -/// @param catalog the catalog offset. -/// @param off where to seek. -/// @return if the seeking was successful. -/***********************************************************************************/ - -bool NewFSParser::Seek(_Input _Output NewCatalog* catalog, SizeT off) -{ - if (!catalog) - { - DbgLastError() = kErrorFileNotFound; - return false; - } - - DbgLastError() = kErrorUnimplemented; - return false; -} - -/***********************************************************************************/ -/// @brief Tell where we are inside the data fork. -/// @param catalog -/// @return The position on the file. -/***********************************************************************************/ - -SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) -{ - if (!catalog) - { - DbgLastError() = kErrorFileNotFound; - return 0; - } - - DbgLastError() = kErrorUnimplemented; - return 0; -} - -namespace NewOS::Detail -{ - /***********************************************************************************/ - /// @brief Construct NewFS drives. - /***********************************************************************************/ - Boolean fs_init_newfs(Void) noexcept - { - sMountpointInterface.A() = construct_main_drive(); - sMountpointInterface.B() = construct_drive(); - sMountpointInterface.C() = construct_drive(); - sMountpointInterface.D() = construct_drive(); - - sMountpointInterface.A().fVerify(&sMountpointInterface.A().fPacket); - - Char partitionBlockBuf[sizeof(NewPartitionBlock)] = {0}; - - sMountpointInterface.A().fPacket.fLba = kNewFSAddressAsLba; - sMountpointInterface.A().fPacket.fPacketContent = partitionBlockBuf; - sMountpointInterface.A().fPacket.fPacketSize = sizeof(NewPartitionBlock); - - sMountpointInterface.A().fInput(&sMountpointInterface.A().fPacket); - - NewPartitionBlock* partBlock = - reinterpret_cast(partitionBlockBuf); - - if (!StringBuilder::Equals(partBlock->Ident, kNewFSIdent)) - { - kcout << "New OS: New FS Partition is corrupt.\r"; - return false; - } - - kcout << "New OS: Read partition: " << partBlock->PartitionName << ", with success!\r"; - - return true; - } -} // namespace NewOS::Detail - -#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Source/FileManager.cxx b/Kernel/Source/FileManager.cxx deleted file mode 100644 index 1aeae426..00000000 --- a/Kernel/Source/FileManager.cxx +++ /dev/null @@ -1,171 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -/// BUGS: 0 -//! @brief File manager for NewOS. - -namespace NewOS -{ - static FilesystemManagerInterface* kMounted = nullptr; - - /// @brief FilesystemManager getter. - /// @return The mounted filesystem. - FilesystemManagerInterface* FilesystemManagerInterface::GetMounted() - { - return kMounted; - } - - /// @brief Unmount filesystem. - /// @return The unmounted filesystem. - FilesystemManagerInterface* FilesystemManagerInterface::Unmount() - { - if (kMounted) - { - auto mount = kMounted; - kMounted = nullptr; - - return mount; - } - - return nullptr; - } - - /// @brief Mount filesystem. - /// @param mountPtr The filesystem to mount. - /// @return if it succeeded true, otherwise false. - bool FilesystemManagerInterface::Mount(FilesystemManagerInterface* mountPtr) - { - if (kMounted == nullptr) - { - kMounted = mountPtr; - return true; - } - - return false; - } - -#ifdef __FSKIT_NEWFS__ - /// @brief Opens a new file. - /// @param path - /// @param r - /// @return - NodePtr NewFilesystemManager::Open(const char* path, const char* r) - { - if (!path || *path == 0) - return nullptr; - - if (!r || *r == 0) - return nullptr; - - auto catalog = fImpl->GetCatalog(path); - - if (catalog->Kind != kNewFSCatalogKindFile) - { - fImpl->CloseCatalog(catalog); - return nullptr; - } - - 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 NewFilesystemManager::Write(NodePtr node, VoidPtr data, Int32 flags, SizeT size) - { - if (!size || - size > kNewFSForkSize) - return; - - if (!data) - return; - - NEWOS_UNUSED(flags); - - auto dataForkName = "FileData"; - - if ((reinterpret_cast(node))->Kind == kNewFSCatalogKindFile) - fImpl->WriteCatalog(reinterpret_cast(node), data, size, - dataForkName); - } - - /// @brief Read from filesystem fork. - /// @param node the catalog node. - /// @param flags the flags with it. - /// @param sz the size to read. - /// @return - VoidPtr NewFilesystemManager::Read(NodePtr node, Int32 flags, SizeT sz) - { - if (sz > kNewFSForkSize) - return nullptr; - - if (!sz) - return nullptr; - - NEWOS_UNUSED(flags); - - auto dataForkName = "FileData"; - - if ((reinterpret_cast(node))->Kind == kNewFSCatalogKindFile) - return fImpl->ReadCatalog(reinterpret_cast(node), sz, - dataForkName); - - 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. - - bool NewFilesystemManager::Seek(NodePtr node, SizeT off) - { - if (!node || off == 0) - return false; - - return fImpl->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. - - SizeT NewFilesystemManager::Tell(NodePtr node) - { - if (!node) - return kNPos; - - return fImpl->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. - - bool NewFilesystemManager::Rewind(NodePtr node) - { - if (!node) - return false; - - return this->Seek(node, 0); - } - - /// @brief Returns the filesystem parser. - /// @return the Filesystem parser class. - NewFSParser* NewFilesystemManager::GetImpl() noexcept - { - return fImpl; - } -#endif // __FSKIT_NEWFS__ -} // namespace NewOS diff --git a/Kernel/Source/Framebuffer.cxx b/Kernel/Source/Framebuffer.cxx deleted file mode 100644 index 5428ca91..00000000 --- a/Kernel/Source/Framebuffer.cxx +++ /dev/null @@ -1,96 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - - File: Framebuffer.cxx - Purpose: Framebuffer object - - Revision History: - - 01/02/24: Added file (amlel) - 02/02/24: Add documentation (amlel) - -------------------------------------------- */ - -#include - -/** - * @brief Framebuffer object implementation. - * - */ - -using namespace NewOS; - -namespace NewOS -{ - const UInt32 kRgbRed = 0x000000FF; - const UInt32 kRgbGreen = 0x0000FF00; - const UInt32 kRgbBlue = 0x00FF0000; - const UInt32 kRgbBlack = 0x00000000; - const UInt32 kRgbWhite = 0xFFFFFFFF; -} // namespace NewOS - -/** - * @brief Get Pixel at - * - * @param pos position of pixel. - * @return volatile* - */ -volatile UIntPtr* Framebuffer::operator[](const UIntPtr& pos) -{ - return (UIntPtr*)(fFrameBufferAddr->fBase * pos); -} - -/// @brief Boolean operator. -Framebuffer::operator bool() -{ - return fFrameBufferAddr.Leak()->fBase != 0 && - fColour != FramebufferColorKind::INVALID && - fFrameBufferAddr.Leak()->fBase != kBadPtr; -} - -/// @brief Set color kind of framebuffer. -/// @param colour -/// @return -const FramebufferColorKind& Framebuffer::Color( - const FramebufferColorKind& colour) -{ - if (fColour != FramebufferColorKind::INVALID && - colour != FramebufferColorKind::INVALID) - { - fColour = colour; - } - - return fColour; -} - -/// @brief Leak framebuffer context. -/// @return The reference of the framebuffer context. -Ref& Framebuffer::Leak() -{ - return this->fFrameBufferAddr; -} - -Framebuffer& Framebuffer::DrawRect(SizeT width, SizeT height, SizeT x, SizeT y, UInt32 color) -{ - for (NewOS::SizeT i = x; i < width + x; ++i) - { - for (NewOS::SizeT u = y; u < height + y; ++u) - { - *(((volatile NewOS::UInt32*)(fFrameBufferAddr.Leak()->fBase + - 4 * fFrameBufferAddr.Leak()->fBpp * i + - 4 * u))) = color; - } - } - - return *this; -} - -Framebuffer& Framebuffer::PutPixel(SizeT x, SizeT y, UInt32 color) -{ - *(((volatile NewOS::UInt32*)(fFrameBufferAddr.Leak()->fBase + - 4 * fFrameBufferAddr.Leak()->fBpp * x + - 4 * y))) = color; - - return *this; -} \ No newline at end of file diff --git a/Kernel/Source/GUIDWizard.cxx b/Kernel/Source/GUIDWizard.cxx deleted file mode 100644 index d434e497..00000000 --- a/Kernel/Source/GUIDWizard.cxx +++ /dev/null @@ -1,65 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - - File: GUIDWizard.cxx - Purpose: GUID helper code - - Revision History: - -------------------------------------------- */ - -#include -#include - -// begin of ascii 'readable' characters. (A, C, C, 1, 2) -#define kAsciiBegin 47 -// @brief Size of UUID. -#define kUUIDSize 37 - -namespace NewOS::XRN::Version1 -{ - auto make_sequence(const ArrayList& uuidSeq) -> Ref - { - GUIDSequence* seq = new GUIDSequence(); - MUST_PASS(seq); - - Ref sequenceReference{seq, true}; - - sequenceReference->fMs1 |= uuidSeq[0]; - sequenceReference->fMs2 |= uuidSeq[1]; - sequenceReference->fMs3 |= uuidSeq[2]; - sequenceReference->fMs3 |= uuidSeq[3]; - - return sequenceReference; - } - - // @brief Tries to make a guid out of a string. - // This function is not complete for now - auto try_guid_to_string(Ref& seq) -> ErrorOr> - { - Char buf[kUUIDSize]; - - for (SizeT index = 0; index < 16; ++index) - { - buf[index] = seq->u8[index] + kAsciiBegin; - } - - for (SizeT index = 16; index < 24; ++index) - { - buf[index] = seq->u16[index] + kAsciiBegin; - } - - for (SizeT index = 24; index < 28; ++index) - { - buf[index] = seq->u32[index] + kAsciiBegin; - } - - auto view = StringBuilder::Construct(buf); - - if (view) - return ErrorOr>{view.Leak()}; - - return ErrorOr>{-1}; - } -} // namespace NewOS::XRN::Version1 diff --git a/Kernel/Source/GUIDWrapper.cxx b/Kernel/Source/GUIDWrapper.cxx deleted file mode 100644 index b1f1d3cf..00000000 --- a/Kernel/Source/GUIDWrapper.cxx +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS::XRN -{ -} diff --git a/Kernel/Source/HError.cxx b/Kernel/Source/HError.cxx deleted file mode 100644 index 8527a683..00000000 --- a/Kernel/Source/HError.cxx +++ /dev/null @@ -1,18 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS -{ - /// @brief Doea a system wide bug check. - /// @param void no params. - /// @return if error-free: true, otherwise false. - Boolean ke_bug_check(void) noexcept - { - return true; - } -} // namespace NewOS diff --git a/Kernel/Source/IndexableProperty.cxx b/Kernel/Source/IndexableProperty.cxx deleted file mode 100644 index 16694f52..00000000 --- a/Kernel/Source/IndexableProperty.cxx +++ /dev/null @@ -1,57 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -//! @brief Filesystem Indexer. - -#include -#include -#include -#include - -/// @brief File Indexer. -/// BUGS: 0 - -#define kMaxLenIndexer 256 - -namespace NewOS -{ - namespace Indexer - { - IndexProperty& IndexableProperty::LeakProperty() 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 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) - { - if (!indexer.HasFlag(kIndexerClaimed)) - { - indexer.AddFlag(kIndexerClaimed); - rt_copy_memory((VoidPtr)indexer.LeakProperty().Path, (VoidPtr)filename, filenameLen); - - kcout << "New OS: FSKit: index new file: " << filename << endl; - } - } - } // namespace Indexer -} // namespace NewOS diff --git a/Kernel/Source/Json.cxx b/Kernel/Source/Json.cxx deleted file mode 100644 index b0e4050f..00000000 --- a/Kernel/Source/Json.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -using namespace NewOS; - -/// @brief Undefined object, is null in length. -INIT(NewOS::JsonType::kUndefined, NewOS::JsonType); diff --git a/Kernel/Source/KernelCheck.cxx b/Kernel/Source/KernelCheck.cxx deleted file mode 100644 index b59417d4..00000000 --- a/Kernel/Source/KernelCheck.cxx +++ /dev/null @@ -1,109 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include -#include - -extern "C" [[noreturn]] void ke_wait_for_debugger() -{ - while (true) - { - NewOS::HAL::rt_cli(); - NewOS::HAL::rt_halt(); - } -} - -/* Each error code is attributed with an ID, which will prompt a string onto the - * screen. Wait for debugger... */ - -namespace NewOS -{ - void ke_stop(const NewOS::Int& id) - { - kcout << "*** STOP *** \r"; - kcout << "*** Kernel has trigerred a runtime stop. *** \r"; - - switch (id) - { - case RUNTIME_CHECK_PROCESS: { - kcout << "*** CAUSE: RUNTIME_CHECK_PROCESS *** \r"; - kcout << "*** WHAT: BAD DRIVER. *** \r"; - break; - } - case RUNTIME_CHECK_ACPI: { - kcout << "*** CAUSE: RUNTIME_CHECK_ACPI *** \r"; - kcout << "*** WHAT: ACPI ERROR, UNSTABLE STATE. *** \r"; - break; - } - case RUNTIME_CHECK_POINTER: { - kcout << "*** CAUSE: RUNTIME_CHECK_POINTER *** \r"; - kcout << "*** WHAT: HEAP CRC32 ERROR, UNSTABLE STATE. *** \r"; - break; - } - case RUNTIME_CHECK_BAD_BEHAVIOR: { - kcout << "*** CAUSE: RUNTIME_CHECK_BAD_BEHAVIOR *** \r"; - kcout << "*** WHAT: KERNEL BECAME UNSTABLE. *** \r"; - break; - } - case RUNTIME_CHECK_BOOTSTRAP: { - kcout << "*** CAUSE: RUNTIME_CHECK_BOOTSTRAP *** \r"; - kcout << "*** WHAT: INVALID BOOT SEQUENCE. *** \r"; - break; - } - case RUNTIME_CHECK_HANDSHAKE: { - kcout << "*** CAUSE: RUNTIME_CHECK_HANDSHAKE *** \r"; - kcout << "*** WHAT: BAD HANDSHAKE. *** \r"; - break; - } - case RUNTIME_CHECK_IPC: { - kcout << "*** CAUSE: RUNTIME_CHECK_IPC *** \r"; - kcout << "*** WHAT: RICH CALL VIOLATION. *** \r"; - break; - } - case RUNTIME_CHECK_INVALID_PRIVILEGE: { - kcout << "*** CAUSE: RUNTIME_CHECK_INVALID_PRIVILEGE *** \r"; - kcout << "*** WHAT: HYPERVISOR POLICY VIOLATION. *** \r"; - break; - case RUNTIME_CHECK_UNEXCPECTED: { - kcout << "*** CAUSE: RUNTIME_CHECK_UNEXCPECTED *** \r"; - kcout << "*** WHAT: CATASROPHIC FAILURE! *** \r"; - break; - } - case RUNTIME_CHECK_FAILED: { - kcout << "*** CAUSE: RUNTIME_CHECK_FAILED *** \r"; - kcout << "*** WHAT: ASSERTION FAILED! *** \r"; - break; - } - default: { - kcout << "*** CAUSE: RUNTIME_CHECK_GENERIC *** \r"; - break; - } - } - }; - - DumpManager::Dump(); - -#ifdef __DEBUG__ - ke_wait_for_debugger(); -#endif // ifdef __DEBUG__ - } - - void ke_runtime_check(bool expr, const char* file, const char* line) - { - if (!expr) - { -#ifdef __DEBUG__ - kcout << "New Kernel: File: " << file << "\r"; - kcout << "New Kernel: Line: " << line << "\r"; - -#endif // __DEBUG__ - - NewOS::ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed - } - } -} // namespace NewOS diff --git a/Kernel/Source/KernelHeap.cxx b/Kernel/Source/KernelHeap.cxx deleted file mode 100644 index a8ca467e..00000000 --- a/Kernel/Source/KernelHeap.cxx +++ /dev/null @@ -1,169 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include -#include -#include - -//! @file KernelHeap.cxx -//! @brief Kernel allocator. - -#define kKernelHeapMagic (0xD4D7D5) -#define kKernelHeapHeaderPaddingSz (16U) - -namespace NewOS -{ - STATIC SizeT kHeapCount = 0UL; - STATIC PageManager kHeapPageManager; - - namespace Detail - { - /// @brief Kernel heap information block. - /// Located before the address bytes. - /// | HIB | ADDRESS | - struct PACKED HeapInformationBlock final - { - ///! @brief 32-bit value which contains the magic number of the executable. - UInt32 fMagic; - ///! @brief Boolean value which tells if the pointer is allocated. - Boolean fPresent; - ///! @brief 32-bit CRC checksum - UInt32 fCRC32; - /// @brief 64-bit pointer size. - SizeT fTargetPtrSize; - /// @brief 64-bit target pointer. - UIntPtr fTargetPtr; - UInt8 fPadding[kKernelHeapHeaderPaddingSz]; - }; - - typedef HeapInformationBlock* HeapInformationBlockPtr; - } // namespace Detail - - /// @brief allocate chunk of memory. - /// @param sz size of pointer - /// @param rw read write (true to enable it) - /// @param user is it accesible by user processes? - /// @return the pointer - VoidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user) - { - if (sz == 0) - ++sz; - - auto wrapper = kHeapPageManager.Request(rw, user, false, sz); - - Detail::HeapInformationBlockPtr heapInfo = - reinterpret_cast( - wrapper.VirtualAddress()); - - heapInfo->fTargetPtrSize = sz; - heapInfo->fMagic = kKernelHeapMagic; - heapInfo->fCRC32 = 0; // dont fill it for now. - heapInfo->fTargetPtr = wrapper.VirtualAddress(); - - ++kHeapCount; - - return reinterpret_cast(wrapper.VirtualAddress() + - sizeof(Detail::HeapInformationBlock)); - } - - /// @brief Declare pointer as free. - /// @param heapPtr the pointer. - /// @return - Int32 ke_delete_ke_heap(VoidPtr heapPtr) - { - if (kHeapCount < 1) - return -kErrorInternal; - if (((IntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)) <= 0) - return -kErrorInternal; - if (((IntPtr)heapPtr - kBadPtr) < 0) - return -kErrorInternal; - - Detail::HeapInformationBlockPtr virtualAddress = - reinterpret_cast( - (UIntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)); - - if (virtualAddress && virtualAddress->fMagic == kKernelHeapMagic) - { - if (!virtualAddress->fPresent) - { - return -kErrorHeapNotPresent; - } - - if (virtualAddress->fCRC32 != 0) - { - if (virtualAddress->fCRC32 != - ke_calculate_crc32((Char*)virtualAddress->fTargetPtr, - virtualAddress->fTargetPtrSize)) - { - ke_stop(RUNTIME_CHECK_POINTER); - } - } - - virtualAddress->fTargetPtrSize = 0UL; - virtualAddress->fPresent = false; - virtualAddress->fTargetPtr = 0; - virtualAddress->fCRC32 = 0; - virtualAddress->fMagic = 0; - - PTEWrapper pageWrapper(false, false, false, (UIntPtr)virtualAddress); - Ref pteAddress{&pageWrapper}; - - kHeapPageManager.Free(pteAddress); - - --kHeapCount; - return 0; - } - - return -kErrorInternal; - } - - /// @brief Check if pointer is a valid kernel pointer. - /// @param heapPtr the pointer - /// @return if it exists. - Boolean ke_is_valid_heap(VoidPtr heapPtr) - { - if (kHeapCount < 1) - return false; - - if (heapPtr) - { - Detail::HeapInformationBlockPtr virtualAddress = - reinterpret_cast( - (UIntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)); - - if (virtualAddress->fPresent && virtualAddress->fMagic == kKernelHeapMagic) - { - return true; - } - } - - return false; - } - - /// @brief Protect the heap with a CRC value. - /// @param heapPtr HIB pointer. - /// @return if it valid: point has crc now., otherwise fail. - Boolean ke_protect_ke_heap(VoidPtr heapPtr) - { - if (heapPtr) - { - Detail::HeapInformationBlockPtr virtualAddress = - reinterpret_cast( - (UIntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)); - - if (virtualAddress->fPresent && kKernelHeapMagic == virtualAddress->fMagic) - { - virtualAddress->fCRC32 = - ke_calculate_crc32((Char*)virtualAddress->fTargetPtr, virtualAddress->fTargetPtrSize); - return true; - } - } - - return false; - } -} // namespace NewOS diff --git a/Kernel/Source/LockDelegate.cxx b/Kernel/Source/LockDelegate.cxx deleted file mode 100644 index c7e6234b..00000000 --- a/Kernel/Source/LockDelegate.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS -{ - /// Leave it empty for now. -} // namespace NewOS \ No newline at end of file diff --git a/Kernel/Source/MutableArray.cxx b/Kernel/Source/MutableArray.cxx deleted file mode 100644 index 195ca6d9..00000000 --- a/Kernel/Source/MutableArray.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/Network/IP.cxx b/Kernel/Source/Network/IP.cxx deleted file mode 100644 index 1e438766..00000000 --- a/Kernel/Source/Network/IP.cxx +++ /dev/null @@ -1,126 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -namespace NewOS -{ - 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) - { - kcout << "[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) - { - kcout << "[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::ToStringView(Ref ipv6) - { - auto str = StringBuilder::Construct(ipv6.Leak().Address()); - return str; - } - - ErrorOr IPFactory::ToStringView(Ref ipv4) - { - auto str = StringBuilder::Construct(ipv4.Leak().Address()); - return str; - } - - bool IPFactory::IpCheckVersion4(const char* ip) - { - int cnter = 0; - - for (Size base = 0; base < rt_string_len(ip); ++base) - { - if (ip[base] == '.') - { - cnter = 0; - } - else - { - if (cnter == 3) - return false; - - ++cnter; - } - } - - return true; - } -} // namespace NewOS diff --git a/Kernel/Source/Network/IPCEP.cxx b/Kernel/Source/Network/IPCEP.cxx deleted file mode 100644 index ba537e95..00000000 --- a/Kernel/Source/Network/IPCEP.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/Network/NetworkDevice.cxx b/Kernel/Source/Network/NetworkDevice.cxx deleted file mode 100644 index 54d24b07..00000000 --- a/Kernel/Source/Network/NetworkDevice.cxx +++ /dev/null @@ -1,15 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS -{ - const char* NetworkDevice::Name() const - { - return "NetworkDevice"; - } -} // namespace NewOS diff --git a/Kernel/Source/New+Delete.cxx b/Kernel/Source/New+Delete.cxx deleted file mode 100644 index d709aaee..00000000 --- a/Kernel/Source/New+Delete.cxx +++ /dev/null @@ -1,50 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -void* operator new[](size_t sz) -{ - if (sz == 0) - ++sz; - - return NewOS::ke_new_ke_heap(sz, true, false); -} - -void* operator new(size_t sz) -{ - if (sz == 0) - ++sz; - - return NewOS::ke_new_ke_heap(sz, true, false); -} - -void operator delete[](void* ptr) -{ - if (ptr == nullptr) - return; - - NewOS::ke_delete_ke_heap(ptr); -} - -void operator delete(void* ptr) -{ - if (ptr == nullptr) - return; - - NewOS::ke_delete_ke_heap(ptr); -} - -void operator delete(void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; - - NEWOS_UNUSED(sz); - - NewOS::ke_delete_ke_heap(ptr); -} diff --git a/Kernel/Source/NewFS+FileManager.cxx b/Kernel/Source/NewFS+FileManager.cxx deleted file mode 100644 index 3434edea..00000000 --- a/Kernel/Source/NewFS+FileManager.cxx +++ /dev/null @@ -1,89 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -#ifdef __FSKIT_NEWFS__ - -/// @brief NewFS File manager. -/// BUGS: 0 - -namespace NewOS -{ - /// @brief C++ constructor - NewFilesystemManager::NewFilesystemManager() - { - MUST_PASS(Detail::fs_init_newfs()); - fImpl = new NewFSParser(); - } - - NewFilesystemManager::~NewFilesystemManager() - { - if (fImpl) - { - delete fImpl; - } - } - - /// @brief Removes a node from the filesystem. - /// @param fileName The filename - /// @return If it was deleted or not. - bool NewFilesystemManager::Remove(const char* fileName) - { - if (fileName == nullptr || *fileName == 0) - return false; - - return fImpl->RemoveCatalog(fileName); - } - - /// @brief Creates a node with the specified. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NewFilesystemManager::Create(const char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNewFSCatalogKindFile)); - } - - /// @brief Creates a node with is a directory. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NewFilesystemManager::CreateDirectory(const char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNewFSCatalogKindDir)); - } - - /// @brief Creates a node with is a alias. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NewFilesystemManager::CreateAlias(const char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNewFSCatalogKindAlias)); - } - - /// @brief Gets the root directory. - /// @return - const char* NewFilesystemHelper::Root() - { - return kNewFSRoot; - } - - /// @brief Gets the up-dir directory. - /// @return - const char* NewFilesystemHelper::UpDir() - { - return kNewFSUpDir; - } - - /// @brief Gets the separator character. - /// @return - const char NewFilesystemHelper::Separator() - { - return kNewFSSeparator; - } -} // namespace NewOS - -#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Source/NewFS+IO.cxx b/Kernel/Source/NewFS+IO.cxx deleted file mode 100644 index 5dfd77b0..00000000 --- a/Kernel/Source/NewFS+IO.cxx +++ /dev/null @@ -1,101 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -/************************************************************* - * - * File: NewFS+IO.cxx - * Purpose: Filesystem to mountpoint interface. - * Date: 3/26/24 - * - * Copyright SoftwareLabs, all rights reserved. - * - *************************************************************/ - -#ifdef __FSKIT_NEWFS__ - -#include - -/// Useful macros. - -#define NEWFS_WRITE(DRV, TRAITS, MP) (MP->DRV()).fOutput(&TRAITS) -#define NEWFS_READ(DRV, TRAITS, MP) (MP->DRV()).fInput(&TRAITS) - -using namespace NewOS; - -/// @brief Read from newfs disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_newfs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) -{ - if (!Mnt) - return -1; - - DrvTrait.fPacket.fPacketGood = false; - - switch (DrvIndex) - { - case kNewFSSubDriveA: { - NEWFS_READ(A, DrvTrait.fPacket, Mnt); - break; - } - case kNewFSSubDriveB: { - NEWFS_READ(B, DrvTrait.fPacket, Mnt); - break; - } - case kNewFSSubDriveC: { - NEWFS_READ(C, DrvTrait.fPacket, Mnt); - break; - } - case kNewFSSubDriveD: { - NEWFS_READ(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood; -} - -/// @brief Write to newfs disk. -/// @param Mnt mounted interface. -/// @param DrvTrait drive info -/// @param DrvIndex drive index. -/// @return -Int32 fs_newfs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) -{ - if (!Mnt) - return -1; - - DrvTrait.fPacket.fPacketGood = false; - - switch (DrvIndex) - { - case kNewFSSubDriveA: { - NEWFS_WRITE(A, DrvTrait.fPacket, Mnt); - break; - } - case kNewFSSubDriveB: { - NEWFS_WRITE(B, DrvTrait.fPacket, Mnt); - break; - } - case kNewFSSubDriveC: { - NEWFS_WRITE(C, DrvTrait.fPacket, Mnt); - break; - } - case kNewFSSubDriveD: { - NEWFS_WRITE(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood; -} - -#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Source/NewFS+Journal.cxx b/Kernel/Source/NewFS+Journal.cxx deleted file mode 100644 index 57f76fd4..00000000 --- a/Kernel/Source/NewFS+Journal.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -#ifdef __FSKIT_NEWFS__ - -///! BUGS: 0 -///! @file NewFS+Journal.cxx -///! @brief Journaling for NewFS. - -namespace NewOS::Journal -{ -} // namespace NewOS::Journal - -using namespace NewOS; - -#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Source/OwnPtr.cxx b/Kernel/Source/OwnPtr.cxx deleted file mode 100644 index cfbdf3b9..00000000 --- a/Kernel/Source/OwnPtr.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/PEFCodeManager.cxx b/Kernel/Source/PEFCodeManager.cxx deleted file mode 100644 index 6fa7e6a1..00000000 --- a/Kernel/Source/PEFCodeManager.cxx +++ /dev/null @@ -1,226 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace NewOS -{ - namespace Detail - { - /// @brief Get the PEF platform signature according to the compiled backebnd - UInt32 rt_get_pef_platform(void) noexcept - { -#ifdef __32x0__ - return kPefArch32x0; -#elif defined(__64x0__) - return kPefArch64x0; -#elif defined(__x86_64__) - return kPefArchAMD64; -#elif defined(__powerpc64__) - return kPefArchPowerPC; -#else - return kPefArchInvalid; -#endif // __32x0__ || __64x0__ || __x86_64__ - } - } // namespace Detail - - /// @brief PEF loader constructor w/ blob. - /// @param 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), fBad(false), fFatBinary(false) - { - OwnPtr> file; - - file.New(const_cast(path), kRestrictRB); - - if (StringBuilder::Equals(file->MIME(), this->MIME())) - { - fPath = StringBuilder::Construct(path).Leak(); - - fCachedBlob = file->Read(); - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - if (container->Cpu == Detail::rt_get_pef_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[0] && container->Abi == kPefAbi) - { - /// This is a fat binary. - this->fFatBinary = true; - return; - } - - kcout << "CodeManager: Warning: Executable format error!\n"; - fBad = true; - - ke_delete_ke_heap(fCachedBlob); - - fCachedBlob = nullptr; - } - } - - /// @brief PEF destructor. - PEFLoader::~PEFLoader() - { - if (fCachedBlob) - ke_delete_ke_heap(fCachedBlob); - } - - VoidPtr PEFLoader::FindSymbol(const char* name, Int32 kind) - { - if (!fCachedBlob || fBad) - return nullptr; - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - PEFCommandHeader* container_header = reinterpret_cast( - (UIntPtr)fCachedBlob + sizeof(PEFContainer)); - - constexpr auto cMangleCharacter = '$'; - const char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; - - ErrorOr errOrSym; - - switch (kind) - { - case kPefCode: { - errOrSym = StringBuilder::Construct(cContainerKinds[0]); // code symbol. - break; - } - case kPefData: { - errOrSym = StringBuilder::Construct(cContainerKinds[1]); // data symbol. - break; - } - case kPefZero: { - errOrSym = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol. - break; - } - default: - return nullptr; - } - - char* unconstSymbol = const_cast(name); - - for (SizeT i = 0UL; i < rt_string_len(unconstSymbol, kPefNameLen); ++i) - { - if (unconstSymbol[i] == ' ') - { - unconstSymbol[i] = cMangleCharacter; - } - } - - errOrSym.Leak().Leak() += name; - - for (SizeT index = 0; index < container->Count; ++index) - { - if (StringBuilder::Equals(container_header->Name, - errOrSym.Leak().Leak().CData())) - { - if (container_header->Kind == kind) - { - if (container_header->Cpu != Detail::rt_get_pef_platform()) - { - if (!this->fFatBinary) - return nullptr; - } - - return (VoidPtr)(static_cast(fCachedBlob) + - container_header->Offset); - } - } - } - - 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; - } - - namespace Utils - { - bool execute_from_image(PEFLoader& exec, const Int32& procKind) noexcept - { - auto errOrStart = exec.FindStart(); - - if (errOrStart.Error() != 0) - return false; - - ProcessHeader proc(errOrStart.Leak().Leak()); - Ref refProc = proc; - - proc.Kind = procKind; - - return ProcessScheduler::Shared().Leak().Add(refProc); - } - } // namespace Utils - - const char* PEFLoader::Path() - { - return fPath.Leak().CData(); - } - - const char* PEFLoader::FormatAsString() - { -#ifdef __32x0__ - return "32x0 PEF."; -#elif defined(__64x0__) - return "64x0 PEF."; -#elif defined(__x86_64__) - return "x86_64 PEF."; -#elif defined(__powerpc64__) - return "POWER PEF."; -#else - return "Unknown PEF."; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ - } - - const char* PEFLoader::MIME() - { - return kPefApplicationMime; - } -} // namespace NewOS diff --git a/Kernel/Source/PEFSharedObjectRT.cxx b/Kernel/Source/PEFSharedObjectRT.cxx deleted file mode 100644 index 20af1b98..00000000 --- a/Kernel/Source/PEFSharedObjectRT.cxx +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ======================================================== - * - * NewOS - * Copyright SoftwareLabs, all rights reserved. - * - * ======================================================== - */ - -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------- - - Revision History: - - 01/02/24: Rework shared library ABI, except a rt_library_init and - rt_library_free (amlel) 15/02/24: Breaking changes, changed the name of the - routines. (amlel) - - ------------------------------------------- */ - -using namespace NewOS; - -/***********************************************************************************/ -/// @file SharedObjectRT.cxx -/// @brief Shared Object runtime. -/***********************************************************************************/ - -/***********************************************************************************/ -/* @brief Library runtime initializer. */ -/***********************************************************************************/ - -EXTERN_C SharedObjectPtr rt_library_init(void) -{ - SharedObjectPtr library = tls_new_class(); - - if (!library) - { - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - - return nullptr; - } - - library->Mount(tls_new_class()); - - if (!library->Get()) - { - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - - return nullptr; - } - - library->Get()->fImageObject = - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Image; - - if (!library->Get()->fImageObject) - { - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - - return nullptr; - } - - library->Get()->fImageEntrypointOffset = - library->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); - - return library; -} - -/***********************************************************************************/ -/* @brief Ends the library. */ -/* @note Please check if the lib got freed! */ -/* @param SharedObjectPtr the library to free. */ -/***********************************************************************************/ - -EXTERN_C Void rt_library_free(SharedObjectPtr lib, bool* successful) -{ - MUST_PASS(successful); - - // sanity check (will also trigger a bug check if this fails) - if (lib == nullptr) - { - *successful = false; - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - } - - delete lib->Get(); - delete lib; - - lib = nullptr; - - *successful = true; -} - -/***********************************************************************************/ - -/// @brief Unimplemented function (crashes by default) -/// @param -EXTERN_C void __mh_purecall(void) -{ - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - return; -} diff --git a/Kernel/Source/PRDT.cxx b/Kernel/Source/PRDT.cxx deleted file mode 100644 index 11165a40..00000000 --- a/Kernel/Source/PRDT.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -namespace NewOS -{ - /// @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 NewOS diff --git a/Kernel/Source/PageAllocator.cxx b/Kernel/Source/PageAllocator.cxx deleted file mode 100644 index d3a4d4e2..00000000 --- a/Kernel/Source/PageAllocator.cxx +++ /dev/null @@ -1,52 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -/// @brief Internal namespace, used internally by kernel. -namespace NewOS::Detail -{ - VoidPtr create_page_wrapper(Boolean rw, Boolean user, SizeT pageSz) - { - auto addr = HAL::hal_alloc_page(rw, user, pageSz); - - if (addr == kBadAddress) - { - kcout << "[create_page_wrapper] kBadAddress returned\n"; - ke_stop(RUNTIME_CHECK_POINTER); - } - - return addr; - } - - void exec_disable(UIntPtr VirtualAddr) - { - PTE* VirtualAddrTable = reinterpret_cast(VirtualAddr); - MUST_PASS(!VirtualAddrTable->Accessed); - VirtualAddrTable->ExecDisable = true; - - hal_flush_tlb(); - } - - bool page_disable(UIntPtr VirtualAddr) - { - if (VirtualAddr) - { - auto VirtualAddrTable = (PTE*)(VirtualAddr); - MUST_PASS(!VirtualAddrTable->Accessed); - - VirtualAddrTable->Present = false; - - hal_flush_tlb(); - - return true; - } - - return false; - } -} // namespace NewOS::Detail diff --git a/Kernel/Source/PageManager.cxx b/Kernel/Source/PageManager.cxx deleted file mode 100644 index 990b2546..00000000 --- a/Kernel/Source/PageManager.cxx +++ /dev/null @@ -1,118 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -#ifdef __x86_64__ -#include -#endif // ifdef __x86_64__ - -//! null deref will throw (Page Zero detected, aborting app!) -#define kProtectedRegionEnd (512) - -namespace NewOS -{ - 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() - { - } - - /// @brief Flush virtual address. - /// @param VirtAddr - void PageManager::FlushTLB(UIntPtr VirtAddr) - { - if (VirtAddr == kBadAddress) - return; - - hal_flush_tlb(); - } - - /// @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 PageManager::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz) - { - // Store PTE wrapper right after PTE. - VoidPtr ptr = NewOS::HAL::hal_alloc_page(Rw, User, Sz); - - return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast(ptr)}; - } - - /// @brief Disable PTE. - /// @param wrapper the wrapper. - /// @return - bool PageManager::Free(Ref& wrapper) - { - if (wrapper) - { - if (!Detail::page_disable(wrapper->VirtualAddress())) - return false; - return true; - } - - return false; - } - - /// @brief Virtual PTE address. - /// @return The virtual address of the page. - const 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) - { - this->fExecDisable = enable; - } - - const bool& PTEWrapper::NoExecute() - { - return this->fExecDisable; - } -} // namespace NewOS diff --git a/Kernel/Source/PermissionSelector.cxx b/Kernel/Source/PermissionSelector.cxx deleted file mode 100644 index cb44b237..00000000 --- a/Kernel/Source/PermissionSelector.cxx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ======================================================== - * - * NewOS - * Copyright SoftwareLabs, all rights reserved. - * - * File: PermissionSelector.cpp - * Purpose: Permission selectors. - * - * ======================================================== - */ - -#include -#include - -/// bugs 0 - -namespace NewOS -{ - PermissionSelector::PermissionSelector(const Int32& sel) - : fRing((RingKind)sel) - { - MUST_PASS(sel > 0); - } - - PermissionSelector::PermissionSelector(const RingKind& ringKind) - : fRing(ringKind) - { - } - - PermissionSelector::~PermissionSelector() = default; - - bool PermissionSelector::operator==(const PermissionSelector& lhs) - { - return lhs.fRing == this->fRing; - } - - bool PermissionSelector::operator!=(const PermissionSelector& lhs) - { - return lhs.fRing != this->fRing; - } - - const RingKind& PermissionSelector::Ring() noexcept - { - return this->fRing; - } -} // namespace NewOS diff --git a/Kernel/Source/Pmm.cxx b/Kernel/Source/Pmm.cxx deleted file mode 100644 index 0641f457..00000000 --- a/Kernel/Source/Pmm.cxx +++ /dev/null @@ -1,88 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include - -namespace NewOS -{ - /// @brief Pmm constructor. - Pmm::Pmm() - : fPageManager() - { - kcout << "[PMM] Allocate PageMemoryManager"; - } - - Pmm::~Pmm() = default; - - /* 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 = fPageManager.Leak().Request(user, readWrite, false, kPTESize); - - if (pt.fPresent) - { - kcout << "[PMM]: Allocation was successful.\r"; - return Ref(pt); - } - - kcout << "[PMM]: Allocation failed.\r"; - - return {}; - } - - Boolean Pmm::FreePage(Ref PageRef) - { - if (!PageRef) - return false; - - PageRef.Leak().fPresent = false; - - return true; - } - - Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fPresent = Enable; - - return true; - } - - Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fRw = Enable; - - return true; - } - - Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fRw = Enable; - - return true; - } - - Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) - { - if (!PageRef) - return false; - - PageRef.Leak().fShareable = Enable; - - return true; - } -} // namespace NewOS diff --git a/Kernel/Source/ProcessScheduler.cxx b/Kernel/Source/ProcessScheduler.cxx deleted file mode 100644 index 1e4537f1..00000000 --- a/Kernel/Source/ProcessScheduler.cxx +++ /dev/null @@ -1,416 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file ProcessScheduler.cxx -/// @brief MicroKernel process scheduler. -/***********************************************************************************/ - -#include -#include -#include -#include -#include - -///! BUGS: 0 - -/***********************************************************************************/ -/* This file handles the process scheduling. -/***********************************************************************************/ - -namespace NewOS -{ - /***********************************************************************************/ - /// @brief Exit Code global - /***********************************************************************************/ - - STATIC Int32 kLastExitCode = 0U; - - /// @brief Gets the latest exit code. - /// @note Not thread-safe. - const Int32& rt_get_exit_code() noexcept - { - return kLastExitCode; - } - - /***********************************************************************************/ - /// @brief crash current process. - /***********************************************************************************/ - - void ProcessHeader::Crash() - { - kcout << this->Name << ": crashed. (id = " << number(39); - kcout << ")\r"; - - if (this->Ring != kRingUserKind) - { - MUST_PASS(ke_bug_check()); - } - - this->Exit(kErrorProcessFault); - } - - void ProcessHeader::Wake(const bool should_wakeup) - { - this->Status = - should_wakeup ? ProcessStatus::kRunning : ProcessStatus::kFrozen; - } - - /***********************************************************************************/ - - VoidPtr ProcessHeader::New(const SizeT& sz) - { - if (this->FreeMemory < 1) - { - DbgLastError() = kErrorHeapOutOfMemory; - this->Crash(); /// out of memory. - - return nullptr; - } - - if (this->HeapCursor) - { - VoidPtr ptr = this->HeapCursor; - this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor + (sizeof(sz))); - - ++this->UsedMemory; - --this->FreeMemory; - - return ptr; - } - - return nullptr; - } - - /***********************************************************************************/ - - /* @brief checks if runtime pointer is in region. */ - bool rt_is_in_pool(VoidPtr pool_ptr, VoidPtr pool, const SizeT& sz) - { - UIntPtr* _pool_ptr = (UIntPtr*)pool_ptr; - UIntPtr* _pool = (UIntPtr*)pool; - - for (SizeT index = sz; _pool[sz] != kUserHeapMag; --index) - { - if (&_pool[index] > &_pool_ptr[sz]) - continue; - - if (_pool[index] == _pool_ptr[index]) - return true; - } - - return false; - } - - /* @brief free pointer from usage. */ - Boolean ProcessHeader::Delete(VoidPtr ptr, const SizeT& sz) - { - if (sz < 1 || this->HeapCursor == this->HeapPtr) - return false; - - // also check for the amount of allocations we've done so far. - if (this->UsedMemory < 1) - return false; - - if (rt_is_in_pool(ptr, this->HeapCursor, this->UsedMemory)) - { - this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor - (sizeof(sz))); - rt_zero_memory(ptr, sz); - - ++this->FreeMemory; - --this->UsedMemory; - - return true; - } - - return false; - } - - /// @brief process name getter. - const Char* ProcessHeader::GetName() - { - return this->Name; - } - - /// @brief process selector getter. - const ProcessSelector& ProcessHeader::GetSelector() - { - return this->Selector; - } - - /// @brief process status getter. - const ProcessStatus& ProcessHeader::GetStatus() - { - return this->Status; - } - - /***********************************************************************************/ - - /** - @brief Affinity is the time slot allowed for the process. - */ - const AffinityKind& ProcessHeader::GetAffinity() - { - return this->Affinity; - } - - /** - @brief Standard exit proc. - */ - void ProcessHeader::Exit(Int32 exit_code) - { - if (this->ProcessId != - ProcessScheduler::Shared().Leak().GetCurrent().Leak().ProcessId) - ke_stop(RUNTIME_CHECK_PROCESS); - - if (this->Ring == (Int32)ProcessSelector::kRingKernel && - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Ring > 0) - ke_stop(RUNTIME_CHECK_PROCESS); - - kLastExitCode = exit_code; - - if (this->Ring != (Int32)ProcessSelector::kRingDriver) - { - if (this->HeapPtr) - rt_free_heap(this->HeapPtr); - - this->HeapPtr = nullptr; - this->HeapCursor = nullptr; - - this->FreeMemory = 0UL; - this->UsedMemory = 0UL; - } - - //! Delete image if not done already. - if (this->Image) - ke_delete_ke_heap(this->Image); - if (this->StackFrame) - ke_delete_ke_heap((VoidPtr)this->StackFrame); - - this->Image = nullptr; - this->StackFrame = nullptr; - - ProcessScheduler::Shared().Leak().Remove(this->ProcessId); - } - - /// @brief Add process to list. - /// @param process - /// @return - SizeT ProcessScheduler::Add(Ref& process) - { - if (!process) - return -1; - - if (!process.Leak().Image) - { - if (process.Leak().Kind != ProcessHeader::kLibKind) - { - return -kErrorNoEntrypoint; - } - } - - if (!mTeam.AsArray().Count() > kSchedProcessLimitPerTeam) - return -kErrorOutOfTeamSlot; - - if (process.Leak().Ring != (Int32)ProcessSelector::kRingKernel) - return -1; - - kcout << "ProcessScheduler::Add(Ref& process)\r"; - - /// Create heap according to type of process. - if (process.Leak().Kind == ProcessHeader::kAppKind) - process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw); - else if (process.Leak().Kind == ProcessHeader::kLibKind) - process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw | kUserHeapShared); - else - process.Leak().HeapPtr = rt_new_heap(kUserHeapDriver | kUserHeapRw); - - process.Leak().StackFrame = reinterpret_cast( - ke_new_ke_heap(sizeof(HAL::StackFrame), true, false)); - - MUST_PASS(process.Leak().StackFrame); - - mTeam.AsArray().Add(process); - - process.Leak().ProcessId = mTeam.AsArray().Count() - 1; - process.Leak().HeapCursor = process.Leak().HeapPtr; - - return mTeam.AsArray().Count() - 1; - } - - /// @brief Remove process from list. - /// @param process - /// @return - bool ProcessScheduler::Remove(SizeT process) - { - if (process > mTeam.AsArray().Count()) - return false; - - kcout << "ProcessScheduler::Remove(SizeT process)\r"; - - return mTeam.AsArray().Remove(process); - } - - /// @brief Run scheduler. - /// @return - SizeT ProcessScheduler::Run() noexcept - { - SizeT processIndex = 0; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - - for (; processIndex < mTeam.AsArray().Count(); ++processIndex) - { - auto process = mTeam.AsArray()[processIndex]; - - MUST_PASS(process); //! no need for a MUST_PASS(process.Leak());, it is - //! recursive because of the nature of the class; - - //! run any process needed to be scheduled. - if (ProcessHelper::CanBeScheduled(process.Leak())) - { - auto unwrapped_process = *process.Leak(); - - unwrapped_process.PTime = 0; - - // set the current process. - mTeam.AsRef() = unwrapped_process; - - // tell helper to find a core to schedule on. - ProcessHelper::Switch(mTeam.AsRef().Leak().StackFrame, - mTeam.AsRef().Leak().ProcessId); - } - else - { - // otherwise increment the P-time. - ++mTeam.AsRef().Leak().PTime; - } - } - - return processIndex; - } - - /// @brief Gets the current scheduled team. - /// @return - ProcessTeam& ProcessScheduler::CurrentTeam() - { - return mTeam; - } - - /// @brief Shared instance of the process scheduler. - /// @return - Ref ProcessScheduler::Shared() - { - static ProcessScheduler ref; - return {ref}; - } - - /// @brief Gets current running process. - /// @return - Ref& ProcessScheduler::GetCurrent() - { - return mTeam.AsRef(); - } - - /// @brief Current proccess id getter. - /// @return Process ID integer. - PID& ProcessHelper::GetCurrentPID() - { - kcout << "ProcessHelper::GetCurrentPID: Leaking ProcessId...\r"; - return ProcessScheduler::Shared().Leak().GetCurrent().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 ProcessHelper::CanBeScheduled(Ref& process) - { - if (process.Leak().Status == ProcessStatus::kFrozen || - process.Leak().Status == ProcessStatus::kDead) - return false; - - if (process.Leak().GetStatus() == ProcessStatus::kStarting) - { - if (process.Leak().PTime < static_cast(kSchedMinMicroTime)) - { - process.Leak().Status = ProcessStatus::kRunning; - process.Leak().Affinity = AffinityKind::kHartStandard; - - return true; - } - - ++process.Leak().PTime; - } - - return process.Leak().PTime > static_cast(kSchedMinMicroTime); - } - - /** - * @brief Spin scheduler class. - */ - - bool ProcessHelper::StartScheduling() - { - if (ProcessHelper::CanBeScheduled( - ProcessScheduler::Shared().Leak().GetCurrent())) - { - --ProcessScheduler::Shared().Leak().GetCurrent().Leak().PTime; - return false; - } - - auto processRef = ProcessScheduler::Shared().Leak(); - - if (!processRef) - return false; // we have nothing to schedule. simply return. - - SizeT ret = processRef.Run(); - - kcout << StringBuilder::FromInt( - "ProcessHelper::StartScheduling() Iterated over {%} jobs inside team.\r", ret); - - return true; - } - - /** - * \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 ProcessHelper::Switch(HAL::StackFrame* the_stack, const PID& new_pid) - { - if (!the_stack || new_pid < 0) - return false; - - for (SizeT index = 0UL; index < SMPManager::Shared().Leak().Count(); ++index) - { - if (SMPManager::Shared().Leak()[index].Leak().Kind() == kInvalidHart) - continue; - - if (SMPManager::Shared().Leak()[index].Leak().StackFrame() == the_stack) - { - SMPManager::Shared().Leak()[index].Leak().Busy(false); - continue; - } - - if (SMPManager::Shared().Leak()[index].Leak().IsBusy()) - continue; - - if (SMPManager::Shared().Leak()[index].Leak().Kind() != - ThreadKind::kHartBoot && - SMPManager::Shared().Leak()[index].Leak().Kind() != - ThreadKind::kHartSystemReserved) - { - SMPManager::Shared().Leak()[index].Leak().Busy(true); - ProcessHelper::GetCurrentPID() = new_pid; - - return SMPManager::Shared().Leak()[index].Leak().Switch(the_stack); - } - } - - return false; - } -} // namespace NewOS diff --git a/Kernel/Source/ProcessTeam.cxx b/Kernel/Source/ProcessTeam.cxx deleted file mode 100644 index 7e311399..00000000 --- a/Kernel/Source/ProcessTeam.cxx +++ /dev/null @@ -1,31 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file ProcessTeam.cxx -/// @brief Process teams implementation. -/***********************************************************************************/ - -#include - -namespace NewOS -{ - /// @brief Process list array getter. - /// @return The list of process to schedule. - MutableArray>& ProcessTeam::AsArray() - { - return mProcessList; - } - - /// @brief Current process getter. - /// @return The current process header. - Ref& ProcessTeam::AsRef() - { - return mCurrentProcess; - } -} // namespace NewOS - -// last rev 05-03-24 diff --git a/Kernel/Source/Property.cxx b/Kernel/Source/Property.cxx deleted file mode 100644 index 0c5c5fab..00000000 --- a/Kernel/Source/Property.cxx +++ /dev/null @@ -1,20 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS -{ - bool Property::StringEquals(StringView& name) - { - return fName && this->fName == name; - } - - const PropertyId& Property::GetPropertyById() - { - return fAction; - } -} // namespace NewOS diff --git a/Kernel/Source/Ref.cxx b/Kernel/Source/Ref.cxx deleted file mode 100644 index 01883e07..00000000 --- a/Kernel/Source/Ref.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/SMPManager.cxx b/Kernel/Source/SMPManager.cxx deleted file mode 100644 index 90a9d440..00000000 --- a/Kernel/Source/SMPManager.cxx +++ /dev/null @@ -1,234 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -///! BUGS: 0 - -///! @file SMPManager.cxx -///! @brief This file handles multi processing in NewOS. -///! @brief Multi processing is needed for multi-tasking operations. - -namespace NewOS -{ - ///! A HardwareThread class takes care of it's owned hardware thread. - ///! It has a stack for it's core. - - ///! @brief constructor - HardwareThread::HardwareThread() = default; - - ///! @brief destructor - HardwareThread::~HardwareThread() = default; - - //! @brief returns the id - - const ThreadID& HardwareThread::ID() noexcept - { - return fID; - } - - //! @brief returns the kind - - const ThreadKind& HardwareThread::Kind() noexcept - { - return fKind; - } - - //! @brief is the core busy? - - bool HardwareThread::IsBusy() noexcept - { - return fBusy; - } - - /// @brief Get processor stack frame. - - HAL::StackFramePtr HardwareThread::StackFrame() noexcept - { - MUST_PASS(fStack); - return fStack; - } - - void HardwareThread::Busy(const bool busy) noexcept - { - fBusy = busy; - } - - HardwareThread::operator bool() - { - return fStack; - } - - /// @brief Wakeup the processor. - - void HardwareThread::Wake(const bool wakeup) noexcept - { - fWakeup = wakeup; - - if (!fWakeup) - rt_hang_thread(fStack); - else - rt_wakeup_thread(fStack); - } - - extern bool rt_check_stack(HAL::StackFramePtr stackPtr); - - /// @brief Switch to hardware thread. - /// @param stack the new hardware thread. - /// @retval true stack was changed, code is running. - /// @retval false stack is invalid, previous code is running. - bool HardwareThread::Switch(HAL::StackFramePtr stack) - { - if (!rt_check_stack(stack)) - return false; - - if (!fStack) - { - fStack = stack; - } - else - { - /// Keep the arguments, switch the base pointer, stack pointer - /// fs and gs registers. - - fStack->Rbp = stack->Rbp; - fStack->Rsp = stack->Rsp; - fStack->Fs = stack->Fs; - fStack->Gs = stack->Gs; - } - - rt_do_context_switch(fStack); - return true; - } - - ///! @brief Tells if processor is waked up. - bool HardwareThread::IsWakeup() noexcept - { - return fWakeup; - } - - //! @brief Constructor and destructor - - ///! @brief Default constructor. - SMPManager::SMPManager() = default; - - ///! @brief Default destructor. - SMPManager::~SMPManager() = default; - - /// @brief Shared singleton function - Ref SMPManager::Shared() - { - static SMPManager manager; - return {manager}; - } - - /// @brief Get Stack Frame of Core - HAL::StackFramePtr SMPManager::GetStackFrame() noexcept - { - if (fThreadList[fCurrentThread].Leak() && - ProcessHelper::GetCurrentPID() == - fThreadList[fCurrentThread].Leak().Leak().fPID) - return fThreadList[fCurrentThread].Leak().Leak().fStack; - - return nullptr; - } - - /// @brief Finds and switch to a free core. - bool SMPManager::Switch(HAL::StackFramePtr stack) - { - if (stack == nullptr) - return false; - - for (SizeT idx = 0; idx < kMaxHarts; ++idx) - { - // stack != nullptr -> if core is used, then continue. - if (!fThreadList[idx].Leak() || - !fThreadList[idx].Leak().Leak().IsWakeup() || - fThreadList[idx].Leak().Leak().IsBusy()) - continue; - - // to avoid any null deref. - if (!fThreadList[idx].Leak().Leak().fStack) - continue; - if (fThreadList[idx].Leak().Leak().fStack->Rsp == 0) - continue; - if (fThreadList[idx].Leak().Leak().fStack->Rbp == 0) - continue; - - fThreadList[idx].Leak().Leak().Busy(true); - - fThreadList[idx].Leak().Leak().fID = idx; - - /// I figured out this: - /// Allocate stack - /// Set APIC base to stack - /// Do stuff and relocate stack based on this code. - /// - Amlel - rt_copy_memory(stack, fThreadList[idx].Leak().Leak().fStack, - sizeof(HAL::StackFrame)); - - fThreadList[idx].Leak().Leak().fPID = ProcessHelper::GetCurrentPID(); - - fThreadList[idx].Leak().Leak().Busy(false); - - return true; - } - - return false; - } - - /** - * Index Hardware thread - * @param idx the index - * @return the reference to the hardware thread. - */ - Ref SMPManager::operator[](const SizeT& idx) - { - if (idx == 0) - { - if (fThreadList[idx].Leak().Leak().Kind() != kHartSystemReserved) - { - fThreadList[idx].Leak().Leak().fKind = kHartBoot; - } - } - else if (idx >= kMaxHarts) - { - HardwareThread fakeThread; - fakeThread.fKind = kInvalidHart; - - return {fakeThread}; - } - - return fThreadList[idx].Leak(); - } - - /** - * Check if thread pool isn't empty. - * @return - */ - SMPManager::operator bool() noexcept - { - return !fThreadList.Empty(); - } - - /** - * Reverse operator bool - * @return - */ - bool SMPManager::operator!() noexcept - { - return fThreadList.Empty(); - } - - /// @brief Returns the amount of core present. - /// @return the number of cores. - SizeT SMPManager::Count() noexcept - { - return fThreadList.Count(); - } -} // namespace NewOS diff --git a/Kernel/Source/Semaphore.cxx b/Kernel/Source/Semaphore.cxx deleted file mode 100644 index 7bd1d513..00000000 --- a/Kernel/Source/Semaphore.cxx +++ /dev/null @@ -1,53 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -namespace NewOS -{ - bool Semaphore::Unlock() noexcept - { - if (fLockingProcess) - fLockingProcess = nullptr; - - return fLockingProcess == nullptr; - } - - bool Semaphore::Lock(ProcessHeader* process) - { - if (!process || fLockingProcess) - return false; - - fLockingProcess = process; - - return true; - } - - bool Semaphore::IsLocked() const - { - return fLockingProcess; - } - - bool Semaphore::LockOrWait(ProcessHeader* process, const Int64& seconds) - { - if (process == nullptr) - return false; - - HardwareTimer timer(Seconds(seconds)); - timer.Wait(); - - return this->Lock(process); - } - - void Semaphore::Sync() noexcept - { - while (fLockingProcess) - { - } - } -} // namespace NewOS diff --git a/Kernel/Source/Storage/AHCIDeviceInterface.cxx b/Kernel/Source/Storage/AHCIDeviceInterface.cxx deleted file mode 100644 index b0431cb1..00000000 --- a/Kernel/Source/Storage/AHCIDeviceInterface.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -using namespace NewOS; - -/// @brief Class constructor -/// @param Out Disk output -/// @param In Disk input -/// @param Cleanup Disk cleanup. -AHCIDeviceInterface::AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)) - : DeviceInterface(Out, In), fCleanup(Cleanup) -{ -} - -/// @brief Class desctructor -AHCIDeviceInterface::~AHCIDeviceInterface() -{ - MUST_PASS(fCleanup); - if (fCleanup) - fCleanup(); -} - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const char* AHCIDeviceInterface::Name() const -{ - return "AHCIDeviceInterface"; -} diff --git a/Kernel/Source/Storage/ATADeviceInterface.cxx b/Kernel/Source/Storage/ATADeviceInterface.cxx deleted file mode 100644 index 0f7d22c1..00000000 --- a/Kernel/Source/Storage/ATADeviceInterface.cxx +++ /dev/null @@ -1,88 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -using namespace NewOS; - -/// @brief Class constructor -/// @param Out Disk output -/// @param In Disk input -/// @param Cleanup Disk cleanup. -ATADeviceInterface::ATADeviceInterface( - void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)) - : DeviceInterface(Out, In), fCleanup(Cleanup) -{ -} - -/// @brief Class desctructor -ATADeviceInterface::~ATADeviceInterface() -{ - MUST_PASS(fCleanup); - if (fCleanup) - fCleanup(); -} - -/// @brief Returns the name of the device interface. -/// @return it's name as a string. -const char* ATADeviceInterface::Name() const -{ - return "ATADeviceInterface"; -} - -/// @brief Output operator. -/// @param Data -/// @return -ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data) -{ - if (!Data) - return *this; - - for (SizeT driveCount = 0; driveCount < kDriveManagerCount; ++driveCount) - { - auto interface = Data->GetAddressOf(driveCount); - if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) - { - continue; - } - else if ((interface) && - rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) - { - return *this; - } - } - - return (ATADeviceInterface&)DeviceInterface::operator<<( - Data); -} - -/// @brief Input operator. -/// @param Data -/// @return -ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* Data) -{ - if (!Data) - return *this; - - for (SizeT driveCount = 0; driveCount < kDriveManagerCount; ++driveCount) - { - auto interface = Data->GetAddressOf(driveCount); - if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) - { - continue; - } - else if ((interface) && - rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) - { - return *this; - } - } - - return (ATADeviceInterface&)DeviceInterface::operator>>( - Data); -} diff --git a/Kernel/Source/Storage/NVMEDeviceInterface.cxx b/Kernel/Source/Storage/NVMEDeviceInterface.cxx deleted file mode 100644 index 22c9c9d0..00000000 --- a/Kernel/Source/Storage/NVMEDeviceInterface.cxx +++ /dev/null @@ -1,15 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS -{ - const char* NVMEDeviceInterface::Name() const - { - return ("NVMEDeviceInterface"); - } -} // namespace NewOS diff --git a/Kernel/Source/Storage/SCSIDeviceInterface.cxx b/Kernel/Source/Storage/SCSIDeviceInterface.cxx deleted file mode 100644 index b64681d3..00000000 --- a/Kernel/Source/Storage/SCSIDeviceInterface.cxx +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -///! @brief ATAPI SCSI packet. -const scsi_packet_type kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; diff --git a/Kernel/Source/Stream.cxx b/Kernel/Source/Stream.cxx deleted file mode 100644 index f21ef4d7..00000000 --- a/Kernel/Source/Stream.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - - File: Stream.cxx - Purpose: Stream object - - Revision History: - -------------------------------------------- */ - -#include diff --git a/Kernel/Source/String.cxx b/Kernel/Source/String.cxx deleted file mode 100644 index 4b6ea365..00000000 --- a/Kernel/Source/String.cxx +++ /dev/null @@ -1,248 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -namespace NewOS -{ - Char* StringView::Data() - { - return fData; - } - - const Char* StringView::CData() - { - return fData; - } - - Size StringView::Length() const - { - return rt_string_len(fData); - } - - bool StringView::operator==(const StringView& rhs) const - { - if (rhs.Length() != this->Length()) - return false; - - for (Size index = 0; index < this->Length(); ++index) - { - if (rhs.fData[index] != fData[index]) - return false; - } - - return true; - } - - bool StringView::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] != fData[index]) - return false; - } - - return true; - } - - bool StringView::operator!=(const StringView& rhs) const - { - if (rhs.Length() != this->Length()) - return false; - - for (Size index = 0; index < rhs.Length(); ++index) - { - if (rhs.fData[index] == fData[index]) - return false; - } - - return true; - } - - bool StringView::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] == fData[index]) - return false; - } - - return true; - } - - ErrorOr StringBuilder::Construct(const Char* data) - { - if (!data || *data == 0) - return {}; - - StringView view(rt_string_len(data)); - - view += data; - - return ErrorOr(view); - } - - const char* StringBuilder::FromInt(const char* fmt, int i) - { - if (!fmt) - return ("-1"); - - char* ret = (char*)Alloca(sizeof(char) * 8 + rt_string_len(fmt)); - - if (!ret) - return ("-1"); - - Char result[8]; - - if (!rt_to_string(result, sizeof(int), i)) - { - return ("-1"); - } - - const auto fmt_len = rt_string_len(fmt); - const auto res_len = rt_string_len(result); - - 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] = result[y_idx]; - ++result_cnt; - } - - break; - } - - ret[idx] = fmt[idx]; - } - - return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */ - } - - const char* StringBuilder::FromBool(const char* fmt, bool i) - { - if (!fmt) - return ("?"); - - const char* boolean_expr = i ? "true" : "false"; - char* ret = (char*)Alloca((sizeof(char) * i) ? 4 : 5 + 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 StringBuilder::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; - } - - const char* StringBuilder::Format(const char* fmt, const char* fmt2) - { - if (!fmt || !fmt2) - return ("?"); - - char* ret = - (char*)Alloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt2)); - - if (!ret) - return ("?"); - - for (Size idx = 0; idx < rt_string_len(fmt); ++idx) - { - if (fmt[idx] == '%') - { - 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; - } - - break; - } - - ret[idx] = fmt[idx]; - } - - return ret; - } - - static void string_append(char* lhs, char* rhs, int cur) - { - if (lhs && rhs) - { - SizeT sz_rhs = rt_string_len(rhs); - - if (sz_rhs == 0) - return; - - rt_copy_memory(rhs, lhs + cur, sz_rhs); - } - } - - StringView& StringView::operator+=(const Char* rhs) - { - string_append(this->fData, const_cast(rhs), this->fCur); - this->fCur += rt_string_len(rhs); - - return *this; - } - - StringView& StringView::operator+=(const StringView& rhs) - { - if (rt_string_len(rhs.fData) > rt_string_len(this->fData)) - return *this; - - string_append(this->fData, const_cast(rhs.fData), this->fCur); - this->fCur += rt_string_len(const_cast(rhs.fData)); - - return *this; - } -} // namespace NewOS diff --git a/Kernel/Source/ThreadLocalStorage.cxx b/Kernel/Source/ThreadLocalStorage.cxx deleted file mode 100644 index c31ae1c2..00000000 --- a/Kernel/Source/ThreadLocalStorage.cxx +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ======================================================== - * - * NewOS - * Copyright SoftwareLabs, all rights reserved. - * - * ======================================================== - */ - -#include -#include - -///! BUGS: 0 - -/***********************************************************************************/ -/// @file ThreadLocalStorage.cxx -/// @brief TLS implementation in kernel. -/***********************************************************************************/ - -using namespace NewOS; - -/** - * @brief Check for cookie inside TIB. - * @param tib the TIB to check. - * @return if the cookie is enabled. - */ - -Boolean tls_check_tib(ThreadInformationBlock* tib) -{ - if (!tib) - return false; - - Encoder encoder; - const char* tibAsBytes = encoder.AsBytes(tib); - - kcout << "New OS: Checking for a valid cookie...\r"; - - return tibAsBytes[0] == kCookieMag0 && tibAsBytes[1] == kCookieMag1 && - tibAsBytes[2] == kCookieMag2; -} - -/** - * @brief System call implementation of the TLS check. - * @param stackPtr The call frame. - * @return - */ -EXTERN_C Void tls_check_syscall_impl(NewOS::HAL::StackFramePtr stackPtr) noexcept -{ - ThreadInformationBlock* tib = (ThreadInformationBlock*)stackPtr->Gs; - - if (!tls_check_tib(tib)) - { - kcout << "New OS: Verification failed, Crashing...\r"; - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - } - - kcout << "New OS: Verification succeeded! Keeping on...\r"; -} diff --git a/Kernel/Source/Timer.cxx b/Kernel/Source/Timer.cxx deleted file mode 100644 index 0495677c..00000000 --- a/Kernel/Source/Timer.cxx +++ /dev/null @@ -1,41 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -///! BUGS: 0 -///! @file Timer.cxx - -using namespace NewOS; - -/// @brief Unimplemented as it is an interface. -Int32 HardwareTimerInterface::Wait() noexcept -{ - return kErrorUnimplemented; -} - -/// @brief HardwareTimer class, meant to be generic. - -HardwareTimer::HardwareTimer(Int64 seconds) - : fWaitFor(seconds) -{ -} -HardwareTimer::~HardwareTimer() -{ - fWaitFor = 0; -} - -Int32 HardwareTimer::Wait() noexcept -{ - if (fWaitFor < 1) - return -1; - - while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) - { - } - - return 0; -} diff --git a/Kernel/Source/URL.cxx b/Kernel/Source/URL.cxx deleted file mode 100644 index 1b223938..00000000 --- a/Kernel/Source/URL.cxx +++ /dev/null @@ -1,96 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -/// BUGS: 0 - -namespace NewOS -{ - URL::URL(StringView& strUrl) - : fUrlView(strUrl, false) - { - } - - URL::~URL() = default; - - /// @brief internal and reserved protocols by kernel. - constexpr const char* kURLProtocols[] = { - "file", // Filesystem protocol - "mup", // Mahrouss update protocol - "param", // Mahrouss parameter protocol. - }; - - constexpr const int kUrlOutSz = 1; //! such as: :// - constexpr const int kProtosCount = 3; - constexpr const int kRangeSz = 4096; - - ErrorOr url_extract_location(const char* url) - { - if (!url || *url == 0 || rt_string_len(url, kRangeSz) > kRangeSz) - return ErrorOr{-1}; - - StringView view(rt_string_len(url)); - - SizeT i = 0; - bool scheme_found = false; - - for (; i < rt_string_len(url); ++i) - { - if (!scheme_found) - { - for (int y = 0; kProtosCount; ++y) - { - if (rt_string_in_string(view.CData(), kURLProtocols[y])) - { - i += rt_string_len(kURLProtocols[y]) + kUrlOutSz; - scheme_found = true; - - break; - } - } - } - - view.Data()[i] = url[i]; - } - - return ErrorOr(view); - } - - ErrorOr url_extract_protocol(const char* url) - { - if (!url || *url == 0 || rt_string_len(url, kRangeSz) > kRangeSz) - return ErrorOr{-1}; - - ErrorOr view{-1}; - - return view; - } - - Ref> URL::Location() noexcept - { - const char* src = fUrlView.Leak().CData(); - auto loc = url_extract_location(src); - - if (!loc) - return {}; - - return Ref>(loc); - } - - Ref> URL::Protocol() noexcept - { - const char* src = fUrlView.Leak().CData(); - auto loc = url_extract_protocol(src); - - if (!loc) - return {}; - - return Ref>(loc); - } -} // namespace NewOS diff --git a/Kernel/Source/UserHeap.cxx b/Kernel/Source/UserHeap.cxx deleted file mode 100644 index 02c4c753..00000000 --- a/Kernel/Source/UserHeap.cxx +++ /dev/null @@ -1,252 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -#define kHeapHeaderPaddingSz (16U) - -/// @file UserHeap.cxx -/// @brief User Heap Manager, Process heap allocator. -/// @note if you want to look at the kernel allocator, please look for -/// KernelHeap.cxx -/// BUGS: 0 - -namespace NewOS -{ - /** - * @brief Process Heap Header - * @note Allocated per process, it denotes the user's heap. - */ - struct UserHeapHeader final - { - UInt32 fMagic; - Int32 fFlags; - Boolean fFree; - UInt8 fPadding[kHeapHeaderPaddingSz]; - }; - - /** - * @brief User Heap Manager class, takes care of allocating the process pools. - * @note This rely on Virtual Memory! Consider adding good vmem support when - * @note porting to a new arch. - */ - class UserHeapManager final - { - public: - UserHeapManager() = delete; - ~UserHeapManager() = default; - - public: - STATIC SizeT& Count() - { - return s_NumPools; - } - STATIC Ref& Leak() - { - return s_Pmm; - } - STATIC Boolean& IsEnabled() - { - return s_PoolsAreEnabled; - } - STATIC MutableArray>& The() - { - return s_Pool; - } - - private: - STATIC Size s_NumPools; - STATIC Ref s_Pmm; - - private: - STATIC Boolean s_PoolsAreEnabled; - STATIC MutableArray> s_Pool; - }; - - //! declare fields - - SizeT UserHeapManager::s_NumPools = 0UL; - Ref UserHeapManager::s_Pmm; - Boolean UserHeapManager::s_PoolsAreEnabled = true; - MutableArray> UserHeapManager::s_Pool; - - STATIC VoidPtr ke_find_unused_heap(Int32 flags); - STATIC Void ke_free_heap_internal(VoidPtr vaddr); - STATIC VoidPtr ke_make_heap_internal(VoidPtr vaddr, Int32 flags); - STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr); - - /// @brief Find an unused heap header to allocate on. - /// @param flags the flags to use. - /// @return VoidPtr the heap pointer. - STATIC VoidPtr ke_find_unused_heap(Int32 flags) - { - for (SizeT index = 0; index < kUserHeapMaxSz; ++index) - { - if (UserHeapManager::The()[index] && - !UserHeapManager::The()[index].Leak().Leak().Present()) - { - UserHeapManager::Leak().Leak().TogglePresent( - UserHeapManager::The()[index].Leak().Leak(), true); - kcout << "[ke_find_unused_heap] Done, trying to make a pool now...\r"; - - return ke_make_heap_internal( - (VoidPtr)UserHeapManager::The()[index].Leak().Leak().VirtualAddress(), - flags); - } - } - - return nullptr; - } - - /// @brief Makes a new heap for the process to use. - /// @param virtualAddress the virtual address of the process. - /// @param flags the flags. - /// @return - STATIC VoidPtr ke_make_heap_internal(VoidPtr virtualAddress, Int32 flags) - { - if (virtualAddress) - { - UserHeapHeader* poolHdr = reinterpret_cast(virtualAddress); - - if (!poolHdr->fFree) - { - kcout - << "[ke_make_heap_internal] poolHdr->fFree, HeapPtr already exists\n"; - return nullptr; - } - - poolHdr->fFlags = flags; - poolHdr->fMagic = kUserHeapMag; - poolHdr->fFree = false; - - kcout << "[ke_make_heap_internal] New allocation has been done.\n"; - return reinterpret_cast( - (reinterpret_cast(virtualAddress) + sizeof(UserHeapHeader))); - } - - kcout << "[ke_make_heap_internal] Address is invalid"; - return nullptr; - } - - /// @brief Internally makrs the heap as free. - /// This is done by setting the fFree bit to true - /// @param virtualAddress - /// @return - STATIC Void ke_free_heap_internal(VoidPtr virtualAddress) - { - UserHeapHeader* poolHdr = reinterpret_cast( - reinterpret_cast(virtualAddress) - sizeof(UserHeapHeader)); - - if (poolHdr->fMagic == kUserHeapMag) - { - if (!poolHdr->fFree) - { - ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); - return; - } - - poolHdr->fFree = true; - poolHdr->fFlags = 0; - - kcout << "[ke_free_heap_internal] Successfully marked header as free!\r"; - } - } - - /** - * @brief Check for the ptr and frees it. - * - * @param index Where to look at. - * @param ptr The ptr to check. - * @return Boolean true if successful. - */ - STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr) - { - if (UserHeapManager::The()[index]) - { - // ErrorOr<>::operator Boolean - /// if (address matches) - /// -> Free heap. - if (UserHeapManager::The()[index].Leak().Leak().VirtualAddress() == - (UIntPtr)ptr) - { - UserHeapManager::Leak().Leak().FreePage( - UserHeapManager::The()[index].Leak().Leak()); - - --UserHeapManager::Count(); - - ke_free_heap_internal(ptr); - ptr = nullptr; - - return true; - } - } - - return false; - } - - /// @brief Creates a new pool pointer. - /// @param flags the flags attached to it. - /// @return a pool pointer with selected permissions. - VoidPtr rt_new_heap(Int32 flags) - { - if (!UserHeapManager::IsEnabled()) - return nullptr; - - if (UserHeapManager::Count() > kUserHeapMaxSz) - return nullptr; - - if (VoidPtr ret = ke_find_unused_heap(flags)) - return ret; - - // this wasn't set to true - auto ref_page = UserHeapManager::Leak().Leak().RequestPage( - ((flags & kUserHeapUser)), (flags & kUserHeapRw)); - - if (ref_page) - { - ///! reserve page. - UserHeapManager::The()[UserHeapManager::Count()].Leak() = ref_page; - auto& ref = UserHeapManager::Count(); - - ++ref; // increment the number of addresses we have now. - - // finally make the pool address. - return ke_make_heap_internal( - reinterpret_cast(ref_page.Leak().VirtualAddress()), flags); - } - - return nullptr; - } - - /// @brief free a pool pointer. - /// @param ptr The pool pointer to free. - /// @return status code - Int32 rt_free_heap(VoidPtr ptr) - { - if (!UserHeapManager::IsEnabled()) - return -1; - - if (ptr) - { - SizeT base = UserHeapManager::Count(); - - if (ke_check_and_free_heap(base, ptr)) - return 0; - - for (SizeT index = 0; index < kUserHeapMaxSz; ++index) - { - if (ke_check_and_free_heap(index, ptr)) - return 0; - - --base; - } - } - - return -1; - } -} // namespace NewOS diff --git a/Kernel/Source/Utils.cxx b/Kernel/Source/Utils.cxx deleted file mode 100644 index 1814c72e..00000000 --- a/Kernel/Source/Utils.cxx +++ /dev/null @@ -1,253 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include -#include -#include - -namespace NewOS -{ - Int 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; - } - - return counter; - } - - void rt_zero_memory(voidPtr pointer, Size len) - { - rt_set_memory(pointer, 0, len); - } - - Size rt_string_len(const Char* str, SizeT _len) - { - if (*str == '\0') - return 0; - - Size len{0}; - while (str[len] != '\0') - { - if (len > _len) - { - break; - } - - ++len; - } - - return len; - } - - Size rt_string_len(const Char* ptr) - { - if (!ptr) - return 0; - - SizeT cnt = 0; - - while (*ptr != (Char)0) - { - ++ptr; - ++cnt; - } - - return cnt; - } - - voidPtr rt_set_memory(voidPtr src, char value, Size len) - { - if (!src || len < 1) - return nullptr; - char* start = reinterpret_cast(src); - - while (len) - { - *start = value; - ++start; - --len; - } - - return (voidPtr)start; - } - - Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) - { - if (len < 1) - return -2; - if (!src || !dst) - return -1; - - char* srcChr = reinterpret_cast(src); - char* dstChar = reinterpret_cast(dst); - Size 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) - { - if (len < 1) - return -2; - - char* srcChr = reinterpret_cast(src); - char* dstChar = reinterpret_cast(dst); - Size index = 0; - - while (index < len) - { - dstChar[index] = srcChr[index]; - ++index; - } - - return index; - } - - const Char* alloc_string(const Char* text) - { - if (!text) - return nullptr; - - const Char* string = new Char[rt_string_len(text)]; - if (!string) - return nullptr; - - voidPtr vText = reinterpret_cast(const_cast(text)); - voidPtr vStr = reinterpret_cast(const_cast(string)); - rt_copy_memory(vText, vStr, rt_string_len(text)); - - return string; - } - - Int rt_to_uppercase(Int character) - { - if (character >= 'a' && character <= 'z') - return character - 0x20; - - return character; - } - - Int rt_to_lower(Int character) - { - if (character >= 'A' && character <= 'Z') - return character + 0x20; - - return character; - } - - bool rt_to_string(Char* str, Int limit, Int base) - { - if (limit == 0) - return false; - - Int copy_limit = limit; - Int cnt = 0; - Int ret = base; - - while (limit != 1) - { - ret = ret % 10; - str[cnt] = ret; - - ++cnt; - --limit; - --ret; - } - - str[copy_limit] = '\0'; - return true; - } - - Boolean is_space(Char chr) - { - return chr == ' '; - } - - Boolean is_newln(Char chr) - { - return chr == '\n'; - } - - voidPtr rt_string_in_string(const char* in, const char* needle) - { - for (size_t 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; - } - - // @brief Checks for a string start at the character. - - char* rt_string_has_char(char* str, const char chr) - { - while (*str != chr) - { - ++str; - - if (*str == 0) - return nullptr; - } - - return str; - } -} // namespace NewOS - -//////////////////////////////////////////////////////////////////////////////////////// -/// Exported C functions -//////////////////////////////////////////////////////////////////////////////////////// - -/// @brief memset in C++ -EXTERN_C void memset(void* dst, char src, size_t len) -{ - NewOS::rt_set_memory(dst, src, len); -} - -/// @brief memcpy in C++ -EXTERN_C void memcpy(void* dst, void* src, size_t len) -{ - NewOS::rt_copy_memory(src, dst, len); -} - -/// @brief memmove in C++ -EXTERN_C void* memmove(void* dst, void* src, size_t len) -{ - NewOS::rt_copy_memory(src, dst, len); - return dst; -} - -/// @brief strlen definition in C++. -EXTERN_C size_t strlen(const char* whatToCheck) -{ - return NewOS::rt_string_len(whatToCheck); -} - -/// @brief memcmp in C++ -EXTERN_C NewOS::SizeT memcmp(void* dst, void* src, size_t len) -{ - return NewOS::rt_string_cmp((char*)src, (char*)dst, len); -} - -/// @brief strcmp in C++ -EXTERN_C NewOS::SizeT strcmp(char* dst, char* src, size_t len) -{ - return NewOS::rt_string_cmp(src, dst, len); -} diff --git a/Kernel/Source/Variant.cxx b/Kernel/Source/Variant.cxx deleted file mode 100644 index 94f1991e..00000000 --- a/Kernel/Source/Variant.cxx +++ /dev/null @@ -1,24 +0,0 @@ -/* ------------------------------------------- - - Copyright SoftwareLabs - -------------------------------------------- */ - -#include - -namespace NewOS -{ - const Char* Variant::ToString() - { - switch (fKind) - { - case VariantKind::kString: - return ("Class:{String}"); - case VariantKind::kPointer: - return ("Memory:{Pointer}"); - default: - return ("Memory:{Undefined}"); - } - } - -} // namespace NewOS diff --git a/Kernel/Source/compile_flags.txt b/Kernel/Source/compile_flags.txt deleted file mode 100644 index 1f54e6fb..00000000 --- a/Kernel/Source/compile_flags.txt +++ /dev/null @@ -1,7 +0,0 @@ --nostdlib --ffreestanding --std=c++20 --I../ --I$(HOME)/ --D__FSKIT_NEWFS__ --D__NEWOS_AMD64__ diff --git a/Kernel/Sources/AppMain.cxx b/Kernel/Sources/AppMain.cxx new file mode 100644 index 00000000..e9da459b --- /dev/null +++ b/Kernel/Sources/AppMain.cxx @@ -0,0 +1,228 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + + File: AppMain.cxx + Purpose: Kernel main loop. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NewOS::Detail +{ + /// @brief Filesystem auto mounter, additional checks are also done by the + /// class. + class FilesystemWizard final + { + NewOS::NewFilesystemManager* fNewFS{nullptr}; + + public: + explicit FilesystemWizard() + { + if (NewOS::FilesystemManagerInterface::GetMounted()) + { + /// Mounted partition, cool! + NewOS::kcout + << "New OS: No need to create for a NewFS partition here...\r"; + } + else + { + /// Not mounted partition, auto-mount. + ///! Mounts a NewFS block. + fNewFS = new NewOS::NewFilesystemManager(); + + NewOS::FilesystemManagerInterface::Mount(fNewFS); + + if (fNewFS->GetImpl()) + { + constexpr auto cFolderInfo = "Metadata"; + const auto cDirCount = 8; + const char* cDirStr[cDirCount] = { + "/Boot/", "/System/", "/Support/", "/Applications/", + "/Users/", "/Library/", "/Mount/", "/Assistants/"}; + + for (NewOS::SizeT dirIndx = 0UL; dirIndx < cDirCount; ++dirIndx) + { + auto catalogDir = fNewFS->GetImpl()->GetCatalog(cDirStr[dirIndx]); + + if (catalogDir) + { + delete catalogDir; + continue; + } + + catalogDir = fNewFS->GetImpl()->CreateCatalog(cDirStr[dirIndx], 0, + kNewFSCatalogKindDir); + + NewFork theFork{0}; + + const NewOS::Char* cSrcName = cFolderInfo; + + NewOS::rt_copy_memory((NewOS::VoidPtr)(cSrcName), theFork.ForkName, + NewOS::rt_string_len(cSrcName)); + + NewOS::rt_copy_memory((NewOS::VoidPtr)(catalogDir->Name), + theFork.CatalogName, + NewOS::rt_string_len(catalogDir->Name)); + + delete catalogDir; + + theFork.DataSize = kNewFSForkSize; + theFork.ResourceId = 0; + theFork.ResourceKind = NewOS::kNewFSRsrcForkKind; + theFork.Kind = NewOS::kNewFSDataForkKind; + + NewOS::StringView metadataFolder(kNewFSSectorSz); + + metadataFolder += + "

Kind: folder

\r

Created by: system

\r

Edited by: " + "system

\r

Volume Type: New OS Standard

\r"; + + metadataFolder += "

File name: "; + metadataFolder += cDirStr[dirIndx]; + metadataFolder += "

\r"; + + const NewOS::SizeT metadataSz = kNewFSSectorSz; + + auto catalogSystem = fNewFS->GetImpl()->GetCatalog(cDirStr[dirIndx]); + + fNewFS->GetImpl()->CreateFork(catalogSystem, theFork); + + fNewFS->GetImpl()->WriteCatalog( + catalogSystem, (NewOS::VoidPtr)(metadataFolder.CData()), + metadataSz, cFolderInfo); + + delete catalogSystem; + } + } + + NewCatalog* catalogDisk = + this->fNewFS->GetImpl()->GetCatalog("/Mount/This Disk"); + + const NewOS::Char* cSrcName = "DiskInfo"; + + if (catalogDisk) + { + auto bufferInfoDisk = (NewOS::Char*)this->fNewFS->GetImpl()->ReadCatalog(catalogDisk, kNewFSSectorSz, cSrcName); + NewOS::kcout << bufferInfoDisk << NewOS::end_line(); + + delete bufferInfoDisk; + delete catalogDisk; + } + else + { + catalogDisk = + (NewCatalog*)this->Leak()->CreateAlias("/Mount/This Disk"); + + NewOS::StringView diskFolder(kNewFSSectorSz); + + diskFolder += + "

Kind: alias to disk

\r

Created by: system

\r

Edited " + "by: " + "system

\r

Volume Type: New OS Standard

\r"; + + diskFolder += "

Original Path: "; + diskFolder += NewOS::NewFilesystemHelper::Root(); + diskFolder += "

\r"; + + NewFork theDiskFork{0}; + + NewOS::rt_copy_memory((NewOS::VoidPtr)(cSrcName), theDiskFork.ForkName, + NewOS::rt_string_len(cSrcName)); + + NewOS::rt_copy_memory((NewOS::VoidPtr)(catalogDisk->Name), + theDiskFork.CatalogName, + NewOS::rt_string_len(catalogDisk->Name)); + + theDiskFork.DataSize = kNewFSForkSize; + theDiskFork.ResourceId = 0; + theDiskFork.ResourceKind = NewOS::kNewFSRsrcForkKind; + theDiskFork.Kind = NewOS::kNewFSDataForkKind; + + fNewFS->GetImpl()->CreateFork(catalogDisk, theDiskFork); + fNewFS->GetImpl()->WriteCatalog(catalogDisk, + (NewOS::VoidPtr)diskFolder.CData(), + kNewFSSectorSz, cSrcName); + + delete catalogDisk; + } + } + } + + ~FilesystemWizard() + { + delete fNewFS; + } + + NEWOS_COPY_DEFAULT(FilesystemWizard); + + /// Grab the disk's NewFS reference. + NewOS::NewFilesystemManager* Leak() + { + return fNewFS; + } + }; + + /// @brief System loader entrypoint. + /// @param void no parameters. + /// @return void no return value. + STATIC NewOS::Void AppSystemLoader(NewOS::Void) + { + NewOS::PEFLoader coreGraphicsShLib("/System/CoreGraphics"); + + if (!coreGraphicsShLib.IsLoaded()) + { + NewOS::ke_stop(RUNTIME_CHECK_FAILED); + } + + NewOS::Utils::execute_from_image(coreGraphicsShLib, + NewOS::ProcessHeader::kLibKind); + + NewOS::PEFLoader logonService("/System/Login"); + + if (!logonService.IsLoaded()) + { + NewOS::ke_stop(RUNTIME_CHECK_FAILED); + } + + NewOS::Utils::execute_from_image(logonService, + NewOS::ProcessHeader::kAppKind); + + NewOS::kcout << "SystemLoader: Exiting process, we're done initializing stuff..."; + + NewOS::ProcessScheduler::Shared().Leak().GetCurrent().Leak().Exit(0); + } +} // namespace NewOS::Detail + +/// @brief Application entrypoint. +/// @param Void +/// @return Void +EXTERN_C NewOS::Void AppMain(NewOS::Void) +{ + /// Now run kernel loop, until no process are running. + NewOS::Detail::FilesystemWizard wizard; // automatic. + + auto cLoaderName = "SystemLoader"; + NewOS::execute_from_image(NewOS::Detail::AppSystemLoader, cLoaderName); + + while (NewOS::ProcessScheduler::Shared().Leak().Run() > 0) + { + NewOS::kcout << "New OS: Shuting down...\r"; + } +} diff --git a/Kernel/Sources/Array.cxx b/Kernel/Sources/Array.cxx new file mode 100644 index 00000000..f1df0abe --- /dev/null +++ b/Kernel/Sources/Array.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/ArrayList.cxx b/Kernel/Sources/ArrayList.cxx new file mode 100644 index 00000000..e96e993c --- /dev/null +++ b/Kernel/Sources/ArrayList.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/Atom.cxx b/Kernel/Sources/Atom.cxx new file mode 100644 index 00000000..0619e4ad --- /dev/null +++ b/Kernel/Sources/Atom.cxx @@ -0,0 +1,10 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +// @file Atom.cpp +// @brief Atomic primitives diff --git a/Kernel/Sources/CodeManager.cxx b/Kernel/Sources/CodeManager.cxx new file mode 100644 index 00000000..358481f6 --- /dev/null +++ b/Kernel/Sources/CodeManager.cxx @@ -0,0 +1,30 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +namespace NewOS +{ + /// @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. + bool execute_from_image(MainKind main, const char* processName) noexcept + { + if (!main) + return false; + + ProcessHeader proc((VoidPtr)main); + proc.Kind = ProcessHeader::kDriverKind; + rt_copy_memory((VoidPtr)processName, proc.Name, rt_string_len(proc.Name)); + + Ref refProc = proc; + + return ProcessScheduler::Shared().Leak().Add(refProc); + } +} // namespace NewOS \ No newline at end of file diff --git a/Kernel/Sources/Crc32.cxx b/Kernel/Sources/Crc32.cxx new file mode 100644 index 00000000..2fd273e0 --- /dev/null +++ b/Kernel/Sources/Crc32.cxx @@ -0,0 +1,74 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +// @file CRC32.cpp +// @brief Check sequence implementation. + +namespace NewOS +{ + /// @brief The CRC32 table. + UInt kCrcTbl[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 p the data to compute. + /// @param len the length of the data. + /// @return the CRC32. + UInt ke_calculate_crc32(const Char* p, UInt len) noexcept + { + UInt crc = 0xffffffff; + + while (len-- != 0) + crc = kCrcTbl[((UInt8)crc ^ *(p++))] ^ (crc >> 8); + + // return (~crc); also works, does the same thing. + return (crc ^ 0xffffffff); + } +} // namespace NewOS diff --git a/Kernel/Sources/CxxAbi.cxx b/Kernel/Sources/CxxAbi.cxx new file mode 100644 index 00000000..9aea8db7 --- /dev/null +++ b/Kernel/Sources/CxxAbi.cxx @@ -0,0 +1,87 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +atexit_func_entry_t __atexit_funcs[kDSOMaxObjects]; + +uarch_t __atexit_func_count; + +extern "C" void __cxa_pure_virtual() +{ + NewOS::kcout << "New OS: C++ placeholder method.\n"; +} + +extern "C" void ___chkstk_ms() +{ + while (1) + { + asm("cli"); + asm("hlt"); + } +} + +extern "C" int atexit(void (*f)(void*), void* arg, void* dso) +{ + if (__atexit_func_count >= kDSOMaxObjects) + return -1; + + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = arg; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + + __atexit_func_count++; + + return 0; +} + +extern "C" void __cxa_finalize(void* f) +{ + uarch_t i = __atexit_func_count; + if (!f) + { + while (i--) + { + if (__atexit_funcs[i].destructor_func) + { + (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].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; + } + + 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 diff --git a/Kernel/Sources/Defines.cxx b/Kernel/Sources/Defines.cxx new file mode 100644 index 00000000..919d0fe4 --- /dev/null +++ b/Kernel/Sources/Defines.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/DeviceManager.cxx b/Kernel/Sources/DeviceManager.cxx new file mode 100644 index 00000000..5679b2af --- /dev/null +++ b/Kernel/Sources/DeviceManager.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/DriveManager.cxx b/Kernel/Sources/DriveManager.cxx new file mode 100644 index 00000000..62195b99 --- /dev/null +++ b/Kernel/Sources/DriveManager.cxx @@ -0,0 +1,149 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +/// @file DriveManager.cxx +/// @brief Kernel drive manager. + +namespace NewOS +{ + static UInt16 kATAIO = 0U; + static UInt8 kATAMaster = 0U; + + /// @brief reads from an ATA drive. + /// @param pckt + /// @return + Void ke_drv_input(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + + pckt->fPacketGood = false; + +#ifdef __AHCI__ + drv_std_read(pckt->fLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); +#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) + drv_std_read(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); +#endif + + pckt->fPacketGood = true; + } + + /// @brief Writes to an ATA drive. + /// @param pckt + /// @return + Void ke_drv_output(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + + pckt->fPacketGood = false; + +#ifdef __AHCI__ + drv_std_write(pckt->fLba, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); +#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) + drv_std_write(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); +#endif + + pckt->fPacketGood = true; + } + + /// @brief Executes a disk check on the ATA drive. + /// @param pckt + /// @return + Void ke_drv_check_disk(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + + pckt->fPacketGood = false; + +#if defined(__ATA_PIO__) || defined(__ATA_DMA__) + kATAMaster = true; + kATAIO = ATA_PRIMARY_IO; + + MUST_PASS(drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)); +#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) + + pckt->fPacketGood = true; + } + +/// @brief Gets the drive kind (ATA, SCSI, AHCI...) +/// @param +/// @return +#ifdef __ATA_PIO__ + const Char* ke_drive_kind(Void) + { + return "ATA-PIO"; + } +#endif + +#ifdef __ATA_DMA__ + const Char* ke_drive_kind(Void) + { + return "ATA-DMA"; + } +#endif + +#ifdef __AHCI__ + const Char* ke_drive_kind(Void) + { + return "AHCI"; + } +#endif + + /// @brief Unimplemented drive. + /// @param pckt + /// @return + Void ke_drv_unimplemented(DriveTrait::DrivePacket* pckt) + { + } + + /// @brief Makes a new drive. + /// @return the new drive. + DriveTrait construct_drive() noexcept + { + DriveTrait trait; + + rt_copy_memory((VoidPtr) "/Mount/Null", trait.fName, rt_string_len("/Mount/Null")); + trait.fKind = kInvalidDrive; + + trait.fInput = ke_drv_unimplemented; + trait.fOutput = ke_drv_unimplemented; + trait.fVerify = ke_drv_unimplemented; + trait.fDriveKind = ke_drive_kind; + + return trait; + } + + /// @brief Fetches the main drive. + /// @return the new drive. + DriveTrait construct_main_drive() noexcept + { + DriveTrait trait; + + rt_copy_memory((VoidPtr) "/Mount/MainDisk/", trait.fName, rt_string_len("/Mount/MainDisk/")); + trait.fKind = kMassStorage | kEPMDrive; + + trait.fInput = ke_drv_input; + trait.fOutput = ke_drv_output; + trait.fVerify = ke_drv_check_disk; + trait.fDriveKind = ke_drive_kind; + + return trait; + } +} // namespace NewOS diff --git a/Kernel/Sources/ErrorOr.cxx b/Kernel/Sources/ErrorOr.cxx new file mode 100644 index 00000000..10d6cc8f --- /dev/null +++ b/Kernel/Sources/ErrorOr.cxx @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +/***********************************************************************************/ +/// @file ErrorOr.cxx /// +/// @brief Error Or Value class. /// +/***********************************************************************************/ diff --git a/Kernel/Sources/FS/NewFS.cxx b/Kernel/Sources/FS/NewFS.cxx new file mode 100644 index 00000000..6f19c8ed --- /dev/null +++ b/Kernel/Sources/FS/NewFS.cxx @@ -0,0 +1,943 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#ifdef __FSKIT_NEWFS__ + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace NewOS; + +///! BUGS: 0 + +/***********************************************************************************/ +/// This file implements the New File System. +/// New File System implements a B-Tree based algortihm. +/// /Disk +/// /Path1 /Path2 +/// /File.txt /File.pef /File.png <-- symlink. +/// /Path1/File.txt +/***********************************************************************************/ + +STATIC MountpointInterface sMountpointInterface; + +/// @brief Creates a new fork inside the New filesystem partition. +/// @param catalog it's catalog +/// @param theFork the fork itself. +/// @return the fork +_Output NewFork* NewFSParser::CreateFork(_Input NewCatalog* catalog, + _Input NewFork& theFork) +{ + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) + return nullptr; + + if (catalog && theFork.ForkName[0] != 0 && + theFork.DataSize == kNewFSForkSize) + { + Lba lba = (theFork.Kind == kNewFSDataForkKind) ? catalog->DataFork + : catalog->ResourceFork; + + kcout << "Fork Lba: " << hex_number(lba) << endl; + + if (lba <= kNewFSCatalogStartAddress) + return nullptr; + + auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + /// special treatment. + rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + NewFork curFork{0}; + NewFork prevFork{0}; + Lba lbaOfPreviousFork = lba; + + /// do not check for anything. Loop until we get what we want, that is a free fork zone. + while (true) + { + if (lba <= kNewFSCatalogStartAddress) + break; + + drv->fPacket.fLba = lba; + drv->fPacket.fPacketSize = sizeof(NewFork); + drv->fPacket.fPacketContent = &curFork; + + drv->fInput(&drv->fPacket); + + kcout << "New OS: Next-Fork: " << hex_number(curFork.NextSibling) << endl; + + if (curFork.Flags == kNewFSFlagCreated) + { + kcout << "New OS: Fork already exists.\r"; + + /// sanity check. + if (StringBuilder::Equals(curFork.ForkName, theFork.ForkName) && + StringBuilder::Equals(curFork.CatalogName, catalog->Name)) + return nullptr; + + kcout << "Next-Fork: " << hex_number(curFork.NextSibling) << endl; + + lbaOfPreviousFork = lba; + lba = curFork.NextSibling; + + prevFork = curFork; + } + else + { + /// This is a check that we have, in order to link the previous fork + /// entry. + if (lba >= kNewFSCatalogStartAddress) + { + drv->fPacket.fLba = lbaOfPreviousFork; + drv->fPacket.fPacketSize = sizeof(NewFork); + drv->fPacket.fPacketContent = &prevFork; + + prevFork.NextSibling = lba; + + /// write to disk. + drv->fOutput(&drv->fPacket); + } + + break; + } + } + + constexpr auto cForkPadding = + 4; /// this value gives us space for the data offset. + + theFork.Flags = kNewFSFlagCreated; + theFork.DataOffset = lba - sizeof(NewFork) * cForkPadding; + theFork.PreviousSibling = lbaOfPreviousFork; + theFork.NextSibling = theFork.DataOffset - theFork.DataSize; + + drv->fPacket.fLba = lba; + drv->fPacket.fPacketSize = sizeof(NewFork); + drv->fPacket.fPacketContent = &theFork; + + drv->fOutput(&drv->fPacket); + + /// log what we have now. + kcout << "New OS: Wrote fork data at: " << hex_number(theFork.DataOffset) + << endl; + + kcout << "New OS: Wrote fork at: " << hex_number(lba) << endl; + + return &theFork; + } + + return nullptr; +} + +/// @brief Find fork inside New filesystem. +/// @param catalog the catalog. +/// @param name the fork name. +/// @return the fork. +_Output NewFork* NewFSParser::FindFork(_Input NewCatalog* catalog, + _Input const Char* name, + Boolean isDataFork) +{ + auto drv = sMountpointInterface.GetAddressOf(this->fDriveIndex); + NewFork* theFork = nullptr; + + Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; + + while (lba != 0) + { + drv->fPacket.fLba = lba; + drv->fPacket.fPacketSize = sizeof(NewFork); + drv->fPacket.fPacketContent = (VoidPtr)theFork; + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drv->fPacket.fPacketMime, 16); + + if (auto res = + fs_newfs_read(&sMountpointInterface, *drv, this->fDriveIndex); + res) + { + switch (res) + { + case 1: + DbgLastError() = kErrorDiskReadOnly; + break; + case 2: + DbgLastError() = kErrorDiskIsFull; + break; + DbgLastError() = kErrorNoSuchDisk; + break; + + default: + break; + } + return nullptr; + } + + if (StringBuilder::Equals(theFork->ForkName, name)) + { + break; + } + + lba = theFork->NextSibling; + } + + return theFork; +} + +/// @brief Simpler factory to create a catalog (assumes you want to create a +/// file.) +/// @param name +/// @return catalog pointer. +_Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name) +{ + return this->CreateCatalog(name, 0, kNewFSCatalogKindFile); +} + +/// @brief Creates a new catalog into the disk. +/// @param name the catalog name. +/// @param flags the flags of the catalog. +/// @param kind the catalog kind. +/// @return catalog pointer. +_Output NewCatalog* NewFSParser::CreateCatalog(_Input const char* name, + _Input const Int32& flags, + _Input const Int32& kind) +{ + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) + return nullptr; + + Lba outLba = 0UL; + + /// a directory should have a slash in the end. + if (kind == kNewFSCatalogKindDir && + name[rt_string_len(name) - 1] != NewFilesystemHelper::Separator()) + return nullptr; + + /// a file shouldn't have a slash in the end. + if (kind != kNewFSCatalogKindDir && + name[rt_string_len(name) - 1] == NewFilesystemHelper::Separator()) + return nullptr; + + NewCatalog* checkForCpy = this->FindCatalog(name, outLba); + + if (checkForCpy) + { + return checkForCpy; + } + + char parentName[kNewFSNodeNameLen] = {0}; + + for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) + { + parentName[indexName] = name[indexName]; + } + + if (*parentName == 0) + { + DbgLastError() = kErrorFileNotFound; + return nullptr; + } + + /// Locate parent catalog, to then allocate right after it. + + for (SizeT indexFill = 0; indexFill < rt_string_len(name); ++indexFill) + { + parentName[indexFill] = name[indexFill]; + } + + SizeT indexReverseCopy = rt_string_len(parentName); + + // zero character. + parentName[--indexReverseCopy] = 0; + + // mandatory / character. + parentName[--indexReverseCopy] = 0; + + while (parentName[indexReverseCopy] != NewFilesystemHelper::Separator()) + { + parentName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NewCatalog* catalog = this->FindCatalog(parentName, outLba); + + if (catalog && catalog->Kind == kNewFSCatalogKindFile) + { + delete catalog; + return nullptr; + } + else if (!catalog) + { + outLba = kNewFSCatalogStartAddress; + } + + constexpr SizeT cDefaultForkSize = kNewFSForkSize; + + NewCatalog* catalogChild = new NewCatalog(); + + catalogChild->ResourceForkSize = cDefaultForkSize; + catalogChild->DataForkSize = cDefaultForkSize; + + catalogChild->NextSibling = outLba; + catalogChild->PrevSibling = outLba; + catalogChild->Kind = kind; + catalogChild->Flags = kNewFSFlagCreated; + + rt_copy_memory((VoidPtr)name, (VoidPtr)catalogChild->Name, + rt_string_len(name)); + + UInt16 catalogBuf[kNewFSSectorSz] = {0}; + + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + Lba startFree = outLba; + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + drive->fPacket.fPacketContent = catalogBuf; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = startFree; + + drive->fInput(&drive->fPacket); + + NewCatalog* nextSibling = (NewCatalog*)catalogBuf; + + startFree = nextSibling->NextSibling; + + catalogChild->PrevSibling = outLba; + + drive->fPacket.fLba = startFree; + drive->fInput(&drive->fPacket); + + while (drive->fPacket.fPacketGood) + { + nextSibling = (NewCatalog*)catalogBuf; + + if (startFree <= kNewFSAddressAsLba) + { + delete catalogChild; + delete catalog; + + return nullptr; + } + + /// allocation or reallocation or catalog... + if (nextSibling->Flags != kNewFSFlagCreated) + { + Char sectorBufPartBlock[kNewFSSectorSz] = {0}; + + drive->fPacket.fPacketContent = sectorBufPartBlock; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + constexpr auto cNewFSCatalogPadding = 4; + + NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBufPartBlock; + + if (partBlock->FreeCatalog < 1) + { + delete catalogChild; + return nullptr; + } + + catalogChild->DataFork = partBlock->DiskSize - partBlock->StartCatalog; + + catalogChild->ResourceFork = catalogChild->DataFork; + + catalogChild->NextSibling = + startFree + (sizeof(NewCatalog) * cNewFSCatalogPadding); + + drive->fPacket.fPacketContent = catalogChild; + drive->fPacket.fPacketSize = sizeof(NewCatalog); + drive->fPacket.fLba = startFree; + + drive->fOutput(&drive->fPacket); + + drive->fPacket.fPacketContent = catalogBuf; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = + startFree - (sizeof(NewCatalog) * cNewFSCatalogPadding); + + drive->fInput(&drive->fPacket); + + nextSibling->NextSibling = startFree; + + drive->fOutput(&drive->fPacket); + + kcout << "New OS: Create new catalog, status: " + << hex_number(catalogChild->Flags) << endl; + kcout << "New OS: Create new catalog, status: " << catalogChild->Name + << endl; + + drive->fPacket.fPacketContent = sectorBufPartBlock; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + partBlock->SectorCount -= 1; + partBlock->CatalogCount += 1; + partBlock->FreeCatalog -= 1; + partBlock->FreeCatalog = catalogChild->NextSibling; + + drive->fOutput(&drive->fPacket); + + delete catalog; + return catalogChild; + } + + constexpr auto cNewFSCatalogPadding = 4; + + //// @note that's how we find the next catalog in the partition block. + startFree = startFree + (sizeof(NewCatalog) * cNewFSCatalogPadding); + + drive->fPacket.fPacketContent = catalogBuf; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = startFree; + + drive->fInput(&drive->fPacket); + } + + delete catalog; + return nullptr; +} + +/// @brief Make a EPM+NewFS drive out of the disk. +/// @param drive The drive to write on. +/// @return If it was sucessful, see DbgLastError(). +bool NewFSParser::Format(_Input _Output DriveTrait* drive) +{ + /// verify disk. + drive->fVerify(&drive->fPacket); + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + /// if disk isn't good, then error out. + if (false == drive->fPacket.fPacketGood) + { + DbgLastError() = kErrorDiskIsCorrupted; + return false; + } + + Char sectorBuf[kNewFSSectorSz] = {0}; + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + /// disk isnt faulty and data has been fetched. + if (drive->fPacket.fPacketGood) + { + NewPartitionBlock* partBlock = (NewPartitionBlock*)sectorBuf; + + /// check for an empty partition here. + if (partBlock->PartitionName[0] == 0 && + rt_string_cmp(partBlock->Ident, kNewFSIdent, kNewFSIdentLen)) + { + /// partition is free and valid. + + partBlock->Version = kNewFSVersionInteger; + + const auto cUntitledHD = "New OS HD\0"; + + rt_copy_memory((VoidPtr)kNewFSIdent, (VoidPtr)partBlock->Ident, + kNewFSIdentLen); + + rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)partBlock->PartitionName, + rt_string_len(cUntitledHD)); + + SizeT catalogCount = 0; + SizeT sectorCount = drv_std_get_sector_count(); + SizeT diskSize = drv_std_get_drv_size(); + + partBlock->Kind = kNewFSPartitionTypeStandard; + partBlock->StartCatalog = kNewFSCatalogStartAddress; + partBlock->Flags = kNewFSPartitionTypeStandard; + partBlock->CatalogCount = sectorCount / sizeof(NewCatalog); + partBlock->SectorCount = sectorCount; + partBlock->DiskSize = diskSize; + partBlock->FreeCatalog = sectorCount / sizeof(NewCatalog); + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = kNewFSSectorSz; + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fOutput(&drive->fPacket); + + kcout << "Drive-Kind: " << drive->fDriveKind() << endl; + + kcout << "Partition-Name: " << partBlock->PartitionName << endl; + kcout << "Start-Catalog: " << hex_number(partBlock->StartCatalog) << endl; + kcout << "Catalog-Count: " << hex_number(partBlock->CatalogCount) << endl; + kcout << "Free-Catalog: " << hex_number(partBlock->FreeCatalog) << endl; + kcout << "Free-Sectors: " << hex_number(partBlock->FreeSectors) << endl; + kcout << "Sector-Size: " << hex_number(partBlock->SectorSize) << endl; + + /// write the root catalog. + this->CreateCatalog(kNewFSRoot, 0, kNewFSCatalogKindDir); + + return true; + } + + kcout << "New OS: PartitionBlock already exists.\r"; + + /// return success as well, do not ignore that partition. + return true; + } + + 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 NewFSParser::WriteCatalog(_Input _Output NewCatalog* catalog, voidPtr data, SizeT sizeOfData, _Input const char* forkName) +{ + if (sizeOfData > catalog->DataForkSize) + return false; + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) + return false; + + NewFork* forkData = new NewFork(); + rt_set_memory(forkData, 0, sizeof(NewFork)); + + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + auto startFork = catalog->DataFork; + + rt_copy_memory(catalog->Name, forkData->CatalogName, kNewFSNodeNameLen); + + /// sanity check of the fork position as the condition to run the loop. + while (startFork >= kNewFSCatalogStartAddress) + { + drive->fPacket.fPacketContent = forkData; + drive->fPacket.fPacketSize = sizeof(NewFork); + drive->fPacket.fLba = startFork; + + drive->fInput(&drive->fPacket); + + kcout << "Fork-Name: " << forkData->ForkName << endl; + + /// sanity check the fork. + if (forkData->DataOffset <= kNewFSCatalogStartAddress) + { + DbgLastError() = kErrorDiskIsCorrupted; + + kcout << "New OS: Invalid fork offset.\r"; + + delete forkData; + return false; + } + + if (forkData->Flags != kNewFSFlagUnallocated && + forkData->Flags != kNewFSFlagDeleted && + StringBuilder::Equals(forkData->ForkName, forkName) && + StringBuilder::Equals(forkData->CatalogName, catalog->Name)) + { + drive->fPacket.fPacketContent = data; + drive->fPacket.fPacketSize = sizeOfData; + drive->fPacket.fLba = forkData->DataOffset; + kcout << "Fork-Offset: " << hex_number(forkData->DataOffset) << endl; + + drive->fOutput(&drive->fPacket); + + delete forkData; + return true; + } + else if (auto catalog = this->GetCatalog(forkData->CatalogName); + catalog == nullptr) + { + delete catalog; + drive->fPacket.fPacketContent = data; + drive->fPacket.fPacketSize = sizeOfData; + drive->fPacket.fLba = forkData->DataOffset; + kcout << "Fork-Offset: " << hex_number(forkData->DataOffset) << endl; + + drive->fOutput(&drive->fPacket); + + delete forkData; + return true; + } + + startFork = forkData->NextSibling; + } + + delete forkData; + return false; +} + +/// @brief +/// @param catalogName the catalog name. +/// @return the newly found catalog. +_Output NewCatalog* NewFSParser::FindCatalog(_Input const char* catalogName, + Lba& outLba) +{ + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) + return nullptr; + + Char* sectorBuf = new Char[sizeof(NewPartitionBlock)]; + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); + drive->fPacket.fLba = kNewFSAddressAsLba; + + drive->fInput(&drive->fPacket); + + NewPartitionBlock* part = (NewPartitionBlock*)sectorBuf; + + auto startCatalogList = part->StartCatalog; + const auto cCtartCatalogList = part->StartCatalog; + + auto localSearchFirst = false; + + drive->fPacket.fLba = startCatalogList; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); + + drive->fInput(&drive->fPacket); + + if (!StringBuilder::Equals(catalogName, NewFilesystemHelper::Root())) + { + Char parentName[kNewFSNodeNameLen] = {0}; + + for (SizeT indexFill = 0; indexFill < rt_string_len(catalogName); ++indexFill) + { + parentName[indexFill] = catalogName[indexFill]; + } + + SizeT indexReverseCopy = rt_string_len(parentName); + + // zero character. + parentName[--indexReverseCopy] = 0; + + // mandatory '/' character. + parentName[--indexReverseCopy] = 0; + + while (parentName[indexReverseCopy] != NewFilesystemHelper::Separator()) + { + parentName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NewCatalog* parentCatalog = this->FindCatalog(parentName, outLba); + + if (parentCatalog && + !StringBuilder::Equals(parentName, NewFilesystemHelper::Root())) + { + startCatalogList = outLba; + delete parentCatalog; + + localSearchFirst = true; + } + else if (parentCatalog) + { + delete parentCatalog; + } + } + +_NewFSSearchThroughCatalogList: + while (drive->fPacket.fPacketGood) + { + NewCatalog* catalog = (NewCatalog*)sectorBuf; + + if (StringBuilder::Equals(catalogName, catalog->Name)) + { + /// ignore unallocated catalog, break + if (catalog->Flags != kNewFSFlagCreated) + { + goto _NewFSContinueSearch; + } + + NewCatalog* catalogPtr = new NewCatalog(); + rt_copy_memory(catalog, catalogPtr, sizeof(NewCatalog)); + + kcout << "New OS: Found catalog at: " << hex_number(startCatalogList) << endl; + + outLba = startCatalogList; + delete[] sectorBuf; + return catalogPtr; + } + + _NewFSContinueSearch: + startCatalogList = catalog->NextSibling; + + if (startCatalogList <= kNewFSAddressAsLba) + break; + + drive->fPacket.fLba = startCatalogList; + drive->fPacket.fPacketContent = sectorBuf; + drive->fPacket.fPacketSize = sizeof(NewCatalog); + + drive->fInput(&drive->fPacket); + } + + if (localSearchFirst) + { + localSearchFirst = false; + startCatalogList = cCtartCatalogList; + + goto _NewFSSearchThroughCatalogList; + } + + outLba = 0UL; + delete[] sectorBuf; + + return nullptr; +} + +/// @brief +/// @param name +/// @return +_Output NewCatalog* NewFSParser::GetCatalog(_Input const char* name) +{ + Lba unused = 0; + return this->FindCatalog(name, unused); +} + +/// @brief +/// @param catalog +/// @return +Boolean NewFSParser::CloseCatalog(_Input _Output NewCatalog* catalog) +{ + if (!catalog) + return false; + + delete catalog; + catalog = nullptr; + + return true; +} + +/// @brief Mark catalog as removed. +/// @param catalog The catalog structure. +/// @return if the catalog was removed or not. +Boolean NewFSParser::RemoveCatalog(_Input const Char* catalogName) +{ + if (!catalogName || + StringBuilder::Equals(catalogName, NewFilesystemHelper::Root())) + { + DbgLastError() = kErrorInternal; + return false; + } + + Lba outLba = 0; + auto catalog = this->FindCatalog(catalogName, outLba); + + if (outLba >= kNewFSCatalogStartAddress || + catalog->Flags == kNewFSFlagCreated) + { + catalog->Flags = kNewFSFlagDeleted; + + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + drive->fPacket.fLba = outLba; // the catalog position. + drive->fPacket.fPacketSize = + sizeof(NewCatalog); // size of catalog. roughly the sector size. + drive->fPacket.fPacketContent = catalog; // the catalog itself. + + drive->fOutput(&drive->fPacket); // send packet. + + Char partitionBlockBuf[sizeof(NewPartitionBlock)] = {0}; + + drive->fPacket.fLba = kNewFSAddressAsLba; + drive->fPacket.fPacketContent = partitionBlockBuf; + drive->fPacket.fPacketSize = sizeof(NewPartitionBlock); + + drive->fInput(&drive->fPacket); + + NewPartitionBlock* partBlock = + reinterpret_cast(partitionBlockBuf); + + ++partBlock->FreeCatalog; + --partBlock->CatalogCount; + + drive->fOutput(&drive->fPacket); + + return true; + } + + delete catalog; + return false; +} + +/// ***************************************************************** /// +/// Reading,Seek,Tell are unimplemented on catalogs, refer to forks I/O instead. +/// ***************************************************************** /// + +/***********************************************************************************/ +/// @brief Read the catalog data fork. +/// @param catalog +/// @param dataSz +/// @return +/***********************************************************************************/ + +VoidPtr NewFSParser::ReadCatalog(_Input _Output NewCatalog* catalog, + _Input SizeT dataSz, + _Input const char* forkName) +{ + if (!catalog) + { + DbgLastError() = kErrorFileNotFound; + return nullptr; + } + + if (!sMountpointInterface.GetAddressOf(this->fDriveIndex)) + return nullptr; + + Lba dataForkLba = catalog->DataFork; + Size dataForkSize = catalog->DataForkSize; + + kcout << "Found-Catalog: " << catalog->Name + << ", Data-Fork: " << hex_number(dataForkLba) << endl; + + Char* sectorBuf = new Char[sizeof(NewFork)]; + auto drive = sMountpointInterface.GetAddressOf(this->fDriveIndex); + + rt_copy_memory((VoidPtr) "fs/newfs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/newfs-packet")); + + NewFork* forkData = nullptr; + + while (dataForkLba >= kNewFSCatalogStartAddress) + { + drive->fPacket.fLba = dataForkLba; + drive->fPacket.fPacketSize = sizeof(NewFork); + drive->fPacket.fPacketContent = sectorBuf; + + drive->fInput(&drive->fPacket); + + forkData = (NewFork*)sectorBuf; + + kcout << "Fork-Name: " << forkData->ForkName << endl; + + if (forkData->DataOffset <= kNewFSCatalogStartAddress) + { + delete[] sectorBuf; + + kcout << "Fail-Data-Offset: " << hex_number(forkData->DataOffset) << endl; + + return nullptr; + } + + if (StringBuilder::Equals(forkName, forkData->ForkName) && + StringBuilder::Equals(catalog->Name, forkData->CatalogName)) + break; + + dataForkLba = forkData->NextSibling; + } + + if (dataForkLba <= kNewFSCatalogStartAddress) + { + delete[] sectorBuf; + return nullptr; + } + + Char* forkBuf = new Char[dataSz]; + + drive->fPacket.fLba = forkData->DataOffset; + drive->fPacket.fPacketSize = dataSz; + drive->fPacket.fPacketContent = forkBuf; + + drive->fInput(&drive->fPacket); + + delete[] sectorBuf; + return forkBuf; +} + +/***********************************************************************************/ +/// @brief Seek in the data fork. +/// @param catalog the catalog offset. +/// @param off where to seek. +/// @return if the seeking was successful. +/***********************************************************************************/ + +bool NewFSParser::Seek(_Input _Output NewCatalog* catalog, SizeT off) +{ + if (!catalog) + { + DbgLastError() = kErrorFileNotFound; + return false; + } + + DbgLastError() = kErrorUnimplemented; + return false; +} + +/***********************************************************************************/ +/// @brief Tell where we are inside the data fork. +/// @param catalog +/// @return The position on the file. +/***********************************************************************************/ + +SizeT NewFSParser::Tell(_Input _Output NewCatalog* catalog) +{ + if (!catalog) + { + DbgLastError() = kErrorFileNotFound; + return 0; + } + + DbgLastError() = kErrorUnimplemented; + return 0; +} + +namespace NewOS::Detail +{ + /***********************************************************************************/ + /// @brief Construct NewFS drives. + /***********************************************************************************/ + Boolean fs_init_newfs(Void) noexcept + { + sMountpointInterface.A() = construct_main_drive(); + sMountpointInterface.B() = construct_drive(); + sMountpointInterface.C() = construct_drive(); + sMountpointInterface.D() = construct_drive(); + + sMountpointInterface.A().fVerify(&sMountpointInterface.A().fPacket); + + Char partitionBlockBuf[sizeof(NewPartitionBlock)] = {0}; + + sMountpointInterface.A().fPacket.fLba = kNewFSAddressAsLba; + sMountpointInterface.A().fPacket.fPacketContent = partitionBlockBuf; + sMountpointInterface.A().fPacket.fPacketSize = sizeof(NewPartitionBlock); + + sMountpointInterface.A().fInput(&sMountpointInterface.A().fPacket); + + NewPartitionBlock* partBlock = + reinterpret_cast(partitionBlockBuf); + + if (!StringBuilder::Equals(partBlock->Ident, kNewFSIdent)) + { + kcout << "New OS: New FS Partition is corrupt.\r"; + return false; + } + + kcout << "New OS: Read partition: " << partBlock->PartitionName << ", with success!\r"; + + return true; + } +} // namespace NewOS::Detail + +#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Sources/FileManager.cxx b/Kernel/Sources/FileManager.cxx new file mode 100644 index 00000000..1aeae426 --- /dev/null +++ b/Kernel/Sources/FileManager.cxx @@ -0,0 +1,171 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +/// BUGS: 0 +//! @brief File manager for NewOS. + +namespace NewOS +{ + static FilesystemManagerInterface* kMounted = nullptr; + + /// @brief FilesystemManager getter. + /// @return The mounted filesystem. + FilesystemManagerInterface* FilesystemManagerInterface::GetMounted() + { + return kMounted; + } + + /// @brief Unmount filesystem. + /// @return The unmounted filesystem. + FilesystemManagerInterface* FilesystemManagerInterface::Unmount() + { + if (kMounted) + { + auto mount = kMounted; + kMounted = nullptr; + + return mount; + } + + return nullptr; + } + + /// @brief Mount filesystem. + /// @param mountPtr The filesystem to mount. + /// @return if it succeeded true, otherwise false. + bool FilesystemManagerInterface::Mount(FilesystemManagerInterface* mountPtr) + { + if (kMounted == nullptr) + { + kMounted = mountPtr; + return true; + } + + return false; + } + +#ifdef __FSKIT_NEWFS__ + /// @brief Opens a new file. + /// @param path + /// @param r + /// @return + NodePtr NewFilesystemManager::Open(const char* path, const char* r) + { + if (!path || *path == 0) + return nullptr; + + if (!r || *r == 0) + return nullptr; + + auto catalog = fImpl->GetCatalog(path); + + if (catalog->Kind != kNewFSCatalogKindFile) + { + fImpl->CloseCatalog(catalog); + return nullptr; + } + + 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 NewFilesystemManager::Write(NodePtr node, VoidPtr data, Int32 flags, SizeT size) + { + if (!size || + size > kNewFSForkSize) + return; + + if (!data) + return; + + NEWOS_UNUSED(flags); + + auto dataForkName = "FileData"; + + if ((reinterpret_cast(node))->Kind == kNewFSCatalogKindFile) + fImpl->WriteCatalog(reinterpret_cast(node), data, size, + dataForkName); + } + + /// @brief Read from filesystem fork. + /// @param node the catalog node. + /// @param flags the flags with it. + /// @param sz the size to read. + /// @return + VoidPtr NewFilesystemManager::Read(NodePtr node, Int32 flags, SizeT sz) + { + if (sz > kNewFSForkSize) + return nullptr; + + if (!sz) + return nullptr; + + NEWOS_UNUSED(flags); + + auto dataForkName = "FileData"; + + if ((reinterpret_cast(node))->Kind == kNewFSCatalogKindFile) + return fImpl->ReadCatalog(reinterpret_cast(node), sz, + dataForkName); + + 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. + + bool NewFilesystemManager::Seek(NodePtr node, SizeT off) + { + if (!node || off == 0) + return false; + + return fImpl->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. + + SizeT NewFilesystemManager::Tell(NodePtr node) + { + if (!node) + return kNPos; + + return fImpl->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. + + bool NewFilesystemManager::Rewind(NodePtr node) + { + if (!node) + return false; + + return this->Seek(node, 0); + } + + /// @brief Returns the filesystem parser. + /// @return the Filesystem parser class. + NewFSParser* NewFilesystemManager::GetImpl() noexcept + { + return fImpl; + } +#endif // __FSKIT_NEWFS__ +} // namespace NewOS diff --git a/Kernel/Sources/Framebuffer.cxx b/Kernel/Sources/Framebuffer.cxx new file mode 100644 index 00000000..5428ca91 --- /dev/null +++ b/Kernel/Sources/Framebuffer.cxx @@ -0,0 +1,96 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + + File: Framebuffer.cxx + Purpose: Framebuffer object + + Revision History: + + 01/02/24: Added file (amlel) + 02/02/24: Add documentation (amlel) + +------------------------------------------- */ + +#include + +/** + * @brief Framebuffer object implementation. + * + */ + +using namespace NewOS; + +namespace NewOS +{ + const UInt32 kRgbRed = 0x000000FF; + const UInt32 kRgbGreen = 0x0000FF00; + const UInt32 kRgbBlue = 0x00FF0000; + const UInt32 kRgbBlack = 0x00000000; + const UInt32 kRgbWhite = 0xFFFFFFFF; +} // namespace NewOS + +/** + * @brief Get Pixel at + * + * @param pos position of pixel. + * @return volatile* + */ +volatile UIntPtr* Framebuffer::operator[](const UIntPtr& pos) +{ + return (UIntPtr*)(fFrameBufferAddr->fBase * pos); +} + +/// @brief Boolean operator. +Framebuffer::operator bool() +{ + return fFrameBufferAddr.Leak()->fBase != 0 && + fColour != FramebufferColorKind::INVALID && + fFrameBufferAddr.Leak()->fBase != kBadPtr; +} + +/// @brief Set color kind of framebuffer. +/// @param colour +/// @return +const FramebufferColorKind& Framebuffer::Color( + const FramebufferColorKind& colour) +{ + if (fColour != FramebufferColorKind::INVALID && + colour != FramebufferColorKind::INVALID) + { + fColour = colour; + } + + return fColour; +} + +/// @brief Leak framebuffer context. +/// @return The reference of the framebuffer context. +Ref& Framebuffer::Leak() +{ + return this->fFrameBufferAddr; +} + +Framebuffer& Framebuffer::DrawRect(SizeT width, SizeT height, SizeT x, SizeT y, UInt32 color) +{ + for (NewOS::SizeT i = x; i < width + x; ++i) + { + for (NewOS::SizeT u = y; u < height + y; ++u) + { + *(((volatile NewOS::UInt32*)(fFrameBufferAddr.Leak()->fBase + + 4 * fFrameBufferAddr.Leak()->fBpp * i + + 4 * u))) = color; + } + } + + return *this; +} + +Framebuffer& Framebuffer::PutPixel(SizeT x, SizeT y, UInt32 color) +{ + *(((volatile NewOS::UInt32*)(fFrameBufferAddr.Leak()->fBase + + 4 * fFrameBufferAddr.Leak()->fBpp * x + + 4 * y))) = color; + + return *this; +} \ No newline at end of file diff --git a/Kernel/Sources/GUIDWizard.cxx b/Kernel/Sources/GUIDWizard.cxx new file mode 100644 index 00000000..d434e497 --- /dev/null +++ b/Kernel/Sources/GUIDWizard.cxx @@ -0,0 +1,65 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + + File: GUIDWizard.cxx + Purpose: GUID helper code + + Revision History: + +------------------------------------------- */ + +#include +#include + +// begin of ascii 'readable' characters. (A, C, C, 1, 2) +#define kAsciiBegin 47 +// @brief Size of UUID. +#define kUUIDSize 37 + +namespace NewOS::XRN::Version1 +{ + auto make_sequence(const ArrayList& uuidSeq) -> Ref + { + GUIDSequence* seq = new GUIDSequence(); + MUST_PASS(seq); + + Ref sequenceReference{seq, true}; + + sequenceReference->fMs1 |= uuidSeq[0]; + sequenceReference->fMs2 |= uuidSeq[1]; + sequenceReference->fMs3 |= uuidSeq[2]; + sequenceReference->fMs3 |= uuidSeq[3]; + + return sequenceReference; + } + + // @brief Tries to make a guid out of a string. + // This function is not complete for now + auto try_guid_to_string(Ref& seq) -> ErrorOr> + { + Char buf[kUUIDSize]; + + for (SizeT index = 0; index < 16; ++index) + { + buf[index] = seq->u8[index] + kAsciiBegin; + } + + for (SizeT index = 16; index < 24; ++index) + { + buf[index] = seq->u16[index] + kAsciiBegin; + } + + for (SizeT index = 24; index < 28; ++index) + { + buf[index] = seq->u32[index] + kAsciiBegin; + } + + auto view = StringBuilder::Construct(buf); + + if (view) + return ErrorOr>{view.Leak()}; + + return ErrorOr>{-1}; + } +} // namespace NewOS::XRN::Version1 diff --git a/Kernel/Sources/GUIDWrapper.cxx b/Kernel/Sources/GUIDWrapper.cxx new file mode 100644 index 00000000..b1f1d3cf --- /dev/null +++ b/Kernel/Sources/GUIDWrapper.cxx @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS::XRN +{ +} diff --git a/Kernel/Sources/HError.cxx b/Kernel/Sources/HError.cxx new file mode 100644 index 00000000..8527a683 --- /dev/null +++ b/Kernel/Sources/HError.cxx @@ -0,0 +1,18 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS +{ + /// @brief Doea a system wide bug check. + /// @param void no params. + /// @return if error-free: true, otherwise false. + Boolean ke_bug_check(void) noexcept + { + return true; + } +} // namespace NewOS diff --git a/Kernel/Sources/IndexableProperty.cxx b/Kernel/Sources/IndexableProperty.cxx new file mode 100644 index 00000000..16694f52 --- /dev/null +++ b/Kernel/Sources/IndexableProperty.cxx @@ -0,0 +1,57 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +//! @brief Filesystem Indexer. + +#include +#include +#include +#include + +/// @brief File Indexer. +/// BUGS: 0 + +#define kMaxLenIndexer 256 + +namespace NewOS +{ + namespace Indexer + { + IndexProperty& IndexableProperty::LeakProperty() 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 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) + { + if (!indexer.HasFlag(kIndexerClaimed)) + { + indexer.AddFlag(kIndexerClaimed); + rt_copy_memory((VoidPtr)indexer.LeakProperty().Path, (VoidPtr)filename, filenameLen); + + kcout << "New OS: FSKit: index new file: " << filename << endl; + } + } + } // namespace Indexer +} // namespace NewOS diff --git a/Kernel/Sources/Json.cxx b/Kernel/Sources/Json.cxx new file mode 100644 index 00000000..b0e4050f --- /dev/null +++ b/Kernel/Sources/Json.cxx @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +using namespace NewOS; + +/// @brief Undefined object, is null in length. +INIT(NewOS::JsonType::kUndefined, NewOS::JsonType); diff --git a/Kernel/Sources/KernelCheck.cxx b/Kernel/Sources/KernelCheck.cxx new file mode 100644 index 00000000..b59417d4 --- /dev/null +++ b/Kernel/Sources/KernelCheck.cxx @@ -0,0 +1,109 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include +#include + +extern "C" [[noreturn]] void ke_wait_for_debugger() +{ + while (true) + { + NewOS::HAL::rt_cli(); + NewOS::HAL::rt_halt(); + } +} + +/* Each error code is attributed with an ID, which will prompt a string onto the + * screen. Wait for debugger... */ + +namespace NewOS +{ + void ke_stop(const NewOS::Int& id) + { + kcout << "*** STOP *** \r"; + kcout << "*** Kernel has trigerred a runtime stop. *** \r"; + + switch (id) + { + case RUNTIME_CHECK_PROCESS: { + kcout << "*** CAUSE: RUNTIME_CHECK_PROCESS *** \r"; + kcout << "*** WHAT: BAD DRIVER. *** \r"; + break; + } + case RUNTIME_CHECK_ACPI: { + kcout << "*** CAUSE: RUNTIME_CHECK_ACPI *** \r"; + kcout << "*** WHAT: ACPI ERROR, UNSTABLE STATE. *** \r"; + break; + } + case RUNTIME_CHECK_POINTER: { + kcout << "*** CAUSE: RUNTIME_CHECK_POINTER *** \r"; + kcout << "*** WHAT: HEAP CRC32 ERROR, UNSTABLE STATE. *** \r"; + break; + } + case RUNTIME_CHECK_BAD_BEHAVIOR: { + kcout << "*** CAUSE: RUNTIME_CHECK_BAD_BEHAVIOR *** \r"; + kcout << "*** WHAT: KERNEL BECAME UNSTABLE. *** \r"; + break; + } + case RUNTIME_CHECK_BOOTSTRAP: { + kcout << "*** CAUSE: RUNTIME_CHECK_BOOTSTRAP *** \r"; + kcout << "*** WHAT: INVALID BOOT SEQUENCE. *** \r"; + break; + } + case RUNTIME_CHECK_HANDSHAKE: { + kcout << "*** CAUSE: RUNTIME_CHECK_HANDSHAKE *** \r"; + kcout << "*** WHAT: BAD HANDSHAKE. *** \r"; + break; + } + case RUNTIME_CHECK_IPC: { + kcout << "*** CAUSE: RUNTIME_CHECK_IPC *** \r"; + kcout << "*** WHAT: RICH CALL VIOLATION. *** \r"; + break; + } + case RUNTIME_CHECK_INVALID_PRIVILEGE: { + kcout << "*** CAUSE: RUNTIME_CHECK_INVALID_PRIVILEGE *** \r"; + kcout << "*** WHAT: HYPERVISOR POLICY VIOLATION. *** \r"; + break; + case RUNTIME_CHECK_UNEXCPECTED: { + kcout << "*** CAUSE: RUNTIME_CHECK_UNEXCPECTED *** \r"; + kcout << "*** WHAT: CATASROPHIC FAILURE! *** \r"; + break; + } + case RUNTIME_CHECK_FAILED: { + kcout << "*** CAUSE: RUNTIME_CHECK_FAILED *** \r"; + kcout << "*** WHAT: ASSERTION FAILED! *** \r"; + break; + } + default: { + kcout << "*** CAUSE: RUNTIME_CHECK_GENERIC *** \r"; + break; + } + } + }; + + DumpManager::Dump(); + +#ifdef __DEBUG__ + ke_wait_for_debugger(); +#endif // ifdef __DEBUG__ + } + + void ke_runtime_check(bool expr, const char* file, const char* line) + { + if (!expr) + { +#ifdef __DEBUG__ + kcout << "New Kernel: File: " << file << "\r"; + kcout << "New Kernel: Line: " << line << "\r"; + +#endif // __DEBUG__ + + NewOS::ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed + } + } +} // namespace NewOS diff --git a/Kernel/Sources/KernelHeap.cxx b/Kernel/Sources/KernelHeap.cxx new file mode 100644 index 00000000..a8ca467e --- /dev/null +++ b/Kernel/Sources/KernelHeap.cxx @@ -0,0 +1,169 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +//! @file KernelHeap.cxx +//! @brief Kernel allocator. + +#define kKernelHeapMagic (0xD4D7D5) +#define kKernelHeapHeaderPaddingSz (16U) + +namespace NewOS +{ + STATIC SizeT kHeapCount = 0UL; + STATIC PageManager kHeapPageManager; + + namespace Detail + { + /// @brief Kernel heap information block. + /// Located before the address bytes. + /// | HIB | ADDRESS | + struct PACKED HeapInformationBlock final + { + ///! @brief 32-bit value which contains the magic number of the executable. + UInt32 fMagic; + ///! @brief Boolean value which tells if the pointer is allocated. + Boolean fPresent; + ///! @brief 32-bit CRC checksum + UInt32 fCRC32; + /// @brief 64-bit pointer size. + SizeT fTargetPtrSize; + /// @brief 64-bit target pointer. + UIntPtr fTargetPtr; + UInt8 fPadding[kKernelHeapHeaderPaddingSz]; + }; + + typedef HeapInformationBlock* HeapInformationBlockPtr; + } // namespace Detail + + /// @brief allocate chunk of memory. + /// @param sz size of pointer + /// @param rw read write (true to enable it) + /// @param user is it accesible by user processes? + /// @return the pointer + VoidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user) + { + if (sz == 0) + ++sz; + + auto wrapper = kHeapPageManager.Request(rw, user, false, sz); + + Detail::HeapInformationBlockPtr heapInfo = + reinterpret_cast( + wrapper.VirtualAddress()); + + heapInfo->fTargetPtrSize = sz; + heapInfo->fMagic = kKernelHeapMagic; + heapInfo->fCRC32 = 0; // dont fill it for now. + heapInfo->fTargetPtr = wrapper.VirtualAddress(); + + ++kHeapCount; + + return reinterpret_cast(wrapper.VirtualAddress() + + sizeof(Detail::HeapInformationBlock)); + } + + /// @brief Declare pointer as free. + /// @param heapPtr the pointer. + /// @return + Int32 ke_delete_ke_heap(VoidPtr heapPtr) + { + if (kHeapCount < 1) + return -kErrorInternal; + if (((IntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)) <= 0) + return -kErrorInternal; + if (((IntPtr)heapPtr - kBadPtr) < 0) + return -kErrorInternal; + + Detail::HeapInformationBlockPtr virtualAddress = + reinterpret_cast( + (UIntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)); + + if (virtualAddress && virtualAddress->fMagic == kKernelHeapMagic) + { + if (!virtualAddress->fPresent) + { + return -kErrorHeapNotPresent; + } + + if (virtualAddress->fCRC32 != 0) + { + if (virtualAddress->fCRC32 != + ke_calculate_crc32((Char*)virtualAddress->fTargetPtr, + virtualAddress->fTargetPtrSize)) + { + ke_stop(RUNTIME_CHECK_POINTER); + } + } + + virtualAddress->fTargetPtrSize = 0UL; + virtualAddress->fPresent = false; + virtualAddress->fTargetPtr = 0; + virtualAddress->fCRC32 = 0; + virtualAddress->fMagic = 0; + + PTEWrapper pageWrapper(false, false, false, (UIntPtr)virtualAddress); + Ref pteAddress{&pageWrapper}; + + kHeapPageManager.Free(pteAddress); + + --kHeapCount; + return 0; + } + + return -kErrorInternal; + } + + /// @brief Check if pointer is a valid kernel pointer. + /// @param heapPtr the pointer + /// @return if it exists. + Boolean ke_is_valid_heap(VoidPtr heapPtr) + { + if (kHeapCount < 1) + return false; + + if (heapPtr) + { + Detail::HeapInformationBlockPtr virtualAddress = + reinterpret_cast( + (UIntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)); + + if (virtualAddress->fPresent && virtualAddress->fMagic == kKernelHeapMagic) + { + return true; + } + } + + return false; + } + + /// @brief Protect the heap with a CRC value. + /// @param heapPtr HIB pointer. + /// @return if it valid: point has crc now., otherwise fail. + Boolean ke_protect_ke_heap(VoidPtr heapPtr) + { + if (heapPtr) + { + Detail::HeapInformationBlockPtr virtualAddress = + reinterpret_cast( + (UIntPtr)heapPtr - sizeof(Detail::HeapInformationBlock)); + + if (virtualAddress->fPresent && kKernelHeapMagic == virtualAddress->fMagic) + { + virtualAddress->fCRC32 = + ke_calculate_crc32((Char*)virtualAddress->fTargetPtr, virtualAddress->fTargetPtrSize); + return true; + } + } + + return false; + } +} // namespace NewOS diff --git a/Kernel/Sources/LockDelegate.cxx b/Kernel/Sources/LockDelegate.cxx new file mode 100644 index 00000000..c7e6234b --- /dev/null +++ b/Kernel/Sources/LockDelegate.cxx @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS +{ + /// Leave it empty for now. +} // namespace NewOS \ No newline at end of file diff --git a/Kernel/Sources/MutableArray.cxx b/Kernel/Sources/MutableArray.cxx new file mode 100644 index 00000000..195ca6d9 --- /dev/null +++ b/Kernel/Sources/MutableArray.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/Network/IP.cxx b/Kernel/Sources/Network/IP.cxx new file mode 100644 index 00000000..1e438766 --- /dev/null +++ b/Kernel/Sources/Network/IP.cxx @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +namespace NewOS +{ + 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) + { + kcout << "[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) + { + kcout << "[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::ToStringView(Ref ipv6) + { + auto str = StringBuilder::Construct(ipv6.Leak().Address()); + return str; + } + + ErrorOr IPFactory::ToStringView(Ref ipv4) + { + auto str = StringBuilder::Construct(ipv4.Leak().Address()); + return str; + } + + bool IPFactory::IpCheckVersion4(const char* ip) + { + int cnter = 0; + + for (Size base = 0; base < rt_string_len(ip); ++base) + { + if (ip[base] == '.') + { + cnter = 0; + } + else + { + if (cnter == 3) + return false; + + ++cnter; + } + } + + return true; + } +} // namespace NewOS diff --git a/Kernel/Sources/Network/IPCEP.cxx b/Kernel/Sources/Network/IPCEP.cxx new file mode 100644 index 00000000..ba537e95 --- /dev/null +++ b/Kernel/Sources/Network/IPCEP.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/Network/NetworkDevice.cxx b/Kernel/Sources/Network/NetworkDevice.cxx new file mode 100644 index 00000000..54d24b07 --- /dev/null +++ b/Kernel/Sources/Network/NetworkDevice.cxx @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS +{ + const char* NetworkDevice::Name() const + { + return "NetworkDevice"; + } +} // namespace NewOS diff --git a/Kernel/Sources/New+Delete.cxx b/Kernel/Sources/New+Delete.cxx new file mode 100644 index 00000000..d709aaee --- /dev/null +++ b/Kernel/Sources/New+Delete.cxx @@ -0,0 +1,50 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +void* operator new[](size_t sz) +{ + if (sz == 0) + ++sz; + + return NewOS::ke_new_ke_heap(sz, true, false); +} + +void* operator new(size_t sz) +{ + if (sz == 0) + ++sz; + + return NewOS::ke_new_ke_heap(sz, true, false); +} + +void operator delete[](void* ptr) +{ + if (ptr == nullptr) + return; + + NewOS::ke_delete_ke_heap(ptr); +} + +void operator delete(void* ptr) +{ + if (ptr == nullptr) + return; + + NewOS::ke_delete_ke_heap(ptr); +} + +void operator delete(void* ptr, size_t sz) +{ + if (ptr == nullptr) + return; + + NEWOS_UNUSED(sz); + + NewOS::ke_delete_ke_heap(ptr); +} diff --git a/Kernel/Sources/NewFS+FileManager.cxx b/Kernel/Sources/NewFS+FileManager.cxx new file mode 100644 index 00000000..3434edea --- /dev/null +++ b/Kernel/Sources/NewFS+FileManager.cxx @@ -0,0 +1,89 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +#ifdef __FSKIT_NEWFS__ + +/// @brief NewFS File manager. +/// BUGS: 0 + +namespace NewOS +{ + /// @brief C++ constructor + NewFilesystemManager::NewFilesystemManager() + { + MUST_PASS(Detail::fs_init_newfs()); + fImpl = new NewFSParser(); + } + + NewFilesystemManager::~NewFilesystemManager() + { + if (fImpl) + { + delete fImpl; + } + } + + /// @brief Removes a node from the filesystem. + /// @param fileName The filename + /// @return If it was deleted or not. + bool NewFilesystemManager::Remove(const char* fileName) + { + if (fileName == nullptr || *fileName == 0) + return false; + + return fImpl->RemoveCatalog(fileName); + } + + /// @brief Creates a node with the specified. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NewFilesystemManager::Create(const char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNewFSCatalogKindFile)); + } + + /// @brief Creates a node with is a directory. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NewFilesystemManager::CreateDirectory(const char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNewFSCatalogKindDir)); + } + + /// @brief Creates a node with is a alias. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NewFilesystemManager::CreateAlias(const char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNewFSCatalogKindAlias)); + } + + /// @brief Gets the root directory. + /// @return + const char* NewFilesystemHelper::Root() + { + return kNewFSRoot; + } + + /// @brief Gets the up-dir directory. + /// @return + const char* NewFilesystemHelper::UpDir() + { + return kNewFSUpDir; + } + + /// @brief Gets the separator character. + /// @return + const char NewFilesystemHelper::Separator() + { + return kNewFSSeparator; + } +} // namespace NewOS + +#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Sources/NewFS+IO.cxx b/Kernel/Sources/NewFS+IO.cxx new file mode 100644 index 00000000..5dfd77b0 --- /dev/null +++ b/Kernel/Sources/NewFS+IO.cxx @@ -0,0 +1,101 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +/************************************************************* + * + * File: NewFS+IO.cxx + * Purpose: Filesystem to mountpoint interface. + * Date: 3/26/24 + * + * Copyright SoftwareLabs, all rights reserved. + * + *************************************************************/ + +#ifdef __FSKIT_NEWFS__ + +#include + +/// Useful macros. + +#define NEWFS_WRITE(DRV, TRAITS, MP) (MP->DRV()).fOutput(&TRAITS) +#define NEWFS_READ(DRV, TRAITS, MP) (MP->DRV()).fInput(&TRAITS) + +using namespace NewOS; + +/// @brief Read from newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_newfs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) +{ + if (!Mnt) + return -1; + + DrvTrait.fPacket.fPacketGood = false; + + switch (DrvIndex) + { + case kNewFSSubDriveA: { + NEWFS_READ(A, DrvTrait.fPacket, Mnt); + break; + } + case kNewFSSubDriveB: { + NEWFS_READ(B, DrvTrait.fPacket, Mnt); + break; + } + case kNewFSSubDriveC: { + NEWFS_READ(C, DrvTrait.fPacket, Mnt); + break; + } + case kNewFSSubDriveD: { + NEWFS_READ(D, DrvTrait.fPacket, Mnt); + break; + } + } + + return DrvTrait.fPacket.fPacketGood; +} + +/// @brief Write to newfs disk. +/// @param Mnt mounted interface. +/// @param DrvTrait drive info +/// @param DrvIndex drive index. +/// @return +Int32 fs_newfs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex) +{ + if (!Mnt) + return -1; + + DrvTrait.fPacket.fPacketGood = false; + + switch (DrvIndex) + { + case kNewFSSubDriveA: { + NEWFS_WRITE(A, DrvTrait.fPacket, Mnt); + break; + } + case kNewFSSubDriveB: { + NEWFS_WRITE(B, DrvTrait.fPacket, Mnt); + break; + } + case kNewFSSubDriveC: { + NEWFS_WRITE(C, DrvTrait.fPacket, Mnt); + break; + } + case kNewFSSubDriveD: { + NEWFS_WRITE(D, DrvTrait.fPacket, Mnt); + break; + } + } + + return DrvTrait.fPacket.fPacketGood; +} + +#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Sources/NewFS+Journal.cxx b/Kernel/Sources/NewFS+Journal.cxx new file mode 100644 index 00000000..57f76fd4 --- /dev/null +++ b/Kernel/Sources/NewFS+Journal.cxx @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +#ifdef __FSKIT_NEWFS__ + +///! BUGS: 0 +///! @file NewFS+Journal.cxx +///! @brief Journaling for NewFS. + +namespace NewOS::Journal +{ +} // namespace NewOS::Journal + +using namespace NewOS; + +#endif // ifdef __FSKIT_NEWFS__ diff --git a/Kernel/Sources/OwnPtr.cxx b/Kernel/Sources/OwnPtr.cxx new file mode 100644 index 00000000..cfbdf3b9 --- /dev/null +++ b/Kernel/Sources/OwnPtr.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/PEFCodeManager.cxx b/Kernel/Sources/PEFCodeManager.cxx new file mode 100644 index 00000000..6fa7e6a1 --- /dev/null +++ b/Kernel/Sources/PEFCodeManager.cxx @@ -0,0 +1,226 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NewOS +{ + namespace Detail + { + /// @brief Get the PEF platform signature according to the compiled backebnd + UInt32 rt_get_pef_platform(void) noexcept + { +#ifdef __32x0__ + return kPefArch32x0; +#elif defined(__64x0__) + return kPefArch64x0; +#elif defined(__x86_64__) + return kPefArchAMD64; +#elif defined(__powerpc64__) + return kPefArchPowerPC; +#else + return kPefArchInvalid; +#endif // __32x0__ || __64x0__ || __x86_64__ + } + } // namespace Detail + + /// @brief PEF loader constructor w/ blob. + /// @param 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), fBad(false), fFatBinary(false) + { + OwnPtr> file; + + file.New(const_cast(path), kRestrictRB); + + if (StringBuilder::Equals(file->MIME(), this->MIME())) + { + fPath = StringBuilder::Construct(path).Leak(); + + fCachedBlob = file->Read(); + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + if (container->Cpu == Detail::rt_get_pef_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[0] && container->Abi == kPefAbi) + { + /// This is a fat binary. + this->fFatBinary = true; + return; + } + + kcout << "CodeManager: Warning: Executable format error!\n"; + fBad = true; + + ke_delete_ke_heap(fCachedBlob); + + fCachedBlob = nullptr; + } + } + + /// @brief PEF destructor. + PEFLoader::~PEFLoader() + { + if (fCachedBlob) + ke_delete_ke_heap(fCachedBlob); + } + + VoidPtr PEFLoader::FindSymbol(const char* name, Int32 kind) + { + if (!fCachedBlob || fBad) + return nullptr; + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + PEFCommandHeader* container_header = reinterpret_cast( + (UIntPtr)fCachedBlob + sizeof(PEFContainer)); + + constexpr auto cMangleCharacter = '$'; + const char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + + ErrorOr errOrSym; + + switch (kind) + { + case kPefCode: { + errOrSym = StringBuilder::Construct(cContainerKinds[0]); // code symbol. + break; + } + case kPefData: { + errOrSym = StringBuilder::Construct(cContainerKinds[1]); // data symbol. + break; + } + case kPefZero: { + errOrSym = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol. + break; + } + default: + return nullptr; + } + + char* unconstSymbol = const_cast(name); + + for (SizeT i = 0UL; i < rt_string_len(unconstSymbol, kPefNameLen); ++i) + { + if (unconstSymbol[i] == ' ') + { + unconstSymbol[i] = cMangleCharacter; + } + } + + errOrSym.Leak().Leak() += name; + + for (SizeT index = 0; index < container->Count; ++index) + { + if (StringBuilder::Equals(container_header->Name, + errOrSym.Leak().Leak().CData())) + { + if (container_header->Kind == kind) + { + if (container_header->Cpu != Detail::rt_get_pef_platform()) + { + if (!this->fFatBinary) + return nullptr; + } + + return (VoidPtr)(static_cast(fCachedBlob) + + container_header->Offset); + } + } + } + + 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; + } + + namespace Utils + { + bool execute_from_image(PEFLoader& exec, const Int32& procKind) noexcept + { + auto errOrStart = exec.FindStart(); + + if (errOrStart.Error() != 0) + return false; + + ProcessHeader proc(errOrStart.Leak().Leak()); + Ref refProc = proc; + + proc.Kind = procKind; + + return ProcessScheduler::Shared().Leak().Add(refProc); + } + } // namespace Utils + + const char* PEFLoader::Path() + { + return fPath.Leak().CData(); + } + + const char* PEFLoader::FormatAsString() + { +#ifdef __32x0__ + return "32x0 PEF."; +#elif defined(__64x0__) + return "64x0 PEF."; +#elif defined(__x86_64__) + return "x86_64 PEF."; +#elif defined(__powerpc64__) + return "POWER PEF."; +#else + return "Unknown PEF."; +#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ + } + + const char* PEFLoader::MIME() + { + return kPefApplicationMime; + } +} // namespace NewOS diff --git a/Kernel/Sources/PEFSharedObjectRT.cxx b/Kernel/Sources/PEFSharedObjectRT.cxx new file mode 100644 index 00000000..20af1b98 --- /dev/null +++ b/Kernel/Sources/PEFSharedObjectRT.cxx @@ -0,0 +1,107 @@ +/* + * ======================================================== + * + * NewOS + * Copyright SoftwareLabs, all rights reserved. + * + * ======================================================== + */ + +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------- + + Revision History: + + 01/02/24: Rework shared library ABI, except a rt_library_init and + rt_library_free (amlel) 15/02/24: Breaking changes, changed the name of the + routines. (amlel) + + ------------------------------------------- */ + +using namespace NewOS; + +/***********************************************************************************/ +/// @file SharedObjectRT.cxx +/// @brief Shared Object runtime. +/***********************************************************************************/ + +/***********************************************************************************/ +/* @brief Library runtime initializer. */ +/***********************************************************************************/ + +EXTERN_C SharedObjectPtr rt_library_init(void) +{ + SharedObjectPtr library = tls_new_class(); + + if (!library) + { + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + + return nullptr; + } + + library->Mount(tls_new_class()); + + if (!library->Get()) + { + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + + return nullptr; + } + + library->Get()->fImageObject = + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Image; + + if (!library->Get()->fImageObject) + { + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + + return nullptr; + } + + library->Get()->fImageEntrypointOffset = + library->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); + + return library; +} + +/***********************************************************************************/ +/* @brief Ends the library. */ +/* @note Please check if the lib got freed! */ +/* @param SharedObjectPtr the library to free. */ +/***********************************************************************************/ + +EXTERN_C Void rt_library_free(SharedObjectPtr lib, bool* successful) +{ + MUST_PASS(successful); + + // sanity check (will also trigger a bug check if this fails) + if (lib == nullptr) + { + *successful = false; + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + } + + delete lib->Get(); + delete lib; + + lib = nullptr; + + *successful = true; +} + +/***********************************************************************************/ + +/// @brief Unimplemented function (crashes by default) +/// @param +EXTERN_C void __mh_purecall(void) +{ + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + return; +} diff --git a/Kernel/Sources/PRDT.cxx b/Kernel/Sources/PRDT.cxx new file mode 100644 index 00000000..11165a40 --- /dev/null +++ b/Kernel/Sources/PRDT.cxx @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +namespace NewOS +{ + /// @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 NewOS diff --git a/Kernel/Sources/PageAllocator.cxx b/Kernel/Sources/PageAllocator.cxx new file mode 100644 index 00000000..d3a4d4e2 --- /dev/null +++ b/Kernel/Sources/PageAllocator.cxx @@ -0,0 +1,52 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +/// @brief Internal namespace, used internally by kernel. +namespace NewOS::Detail +{ + VoidPtr create_page_wrapper(Boolean rw, Boolean user, SizeT pageSz) + { + auto addr = HAL::hal_alloc_page(rw, user, pageSz); + + if (addr == kBadAddress) + { + kcout << "[create_page_wrapper] kBadAddress returned\n"; + ke_stop(RUNTIME_CHECK_POINTER); + } + + return addr; + } + + void exec_disable(UIntPtr VirtualAddr) + { + PTE* VirtualAddrTable = reinterpret_cast(VirtualAddr); + MUST_PASS(!VirtualAddrTable->Accessed); + VirtualAddrTable->ExecDisable = true; + + hal_flush_tlb(); + } + + bool page_disable(UIntPtr VirtualAddr) + { + if (VirtualAddr) + { + auto VirtualAddrTable = (PTE*)(VirtualAddr); + MUST_PASS(!VirtualAddrTable->Accessed); + + VirtualAddrTable->Present = false; + + hal_flush_tlb(); + + return true; + } + + return false; + } +} // namespace NewOS::Detail diff --git a/Kernel/Sources/PageManager.cxx b/Kernel/Sources/PageManager.cxx new file mode 100644 index 00000000..990b2546 --- /dev/null +++ b/Kernel/Sources/PageManager.cxx @@ -0,0 +1,118 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +#ifdef __x86_64__ +#include +#endif // ifdef __x86_64__ + +//! null deref will throw (Page Zero detected, aborting app!) +#define kProtectedRegionEnd (512) + +namespace NewOS +{ + 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() + { + } + + /// @brief Flush virtual address. + /// @param VirtAddr + void PageManager::FlushTLB(UIntPtr VirtAddr) + { + if (VirtAddr == kBadAddress) + return; + + hal_flush_tlb(); + } + + /// @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 PageManager::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz) + { + // Store PTE wrapper right after PTE. + VoidPtr ptr = NewOS::HAL::hal_alloc_page(Rw, User, Sz); + + return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast(ptr)}; + } + + /// @brief Disable PTE. + /// @param wrapper the wrapper. + /// @return + bool PageManager::Free(Ref& wrapper) + { + if (wrapper) + { + if (!Detail::page_disable(wrapper->VirtualAddress())) + return false; + return true; + } + + return false; + } + + /// @brief Virtual PTE address. + /// @return The virtual address of the page. + const 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) + { + this->fExecDisable = enable; + } + + const bool& PTEWrapper::NoExecute() + { + return this->fExecDisable; + } +} // namespace NewOS diff --git a/Kernel/Sources/PermissionSelector.cxx b/Kernel/Sources/PermissionSelector.cxx new file mode 100644 index 00000000..cb44b237 --- /dev/null +++ b/Kernel/Sources/PermissionSelector.cxx @@ -0,0 +1,47 @@ +/* + * ======================================================== + * + * NewOS + * Copyright SoftwareLabs, all rights reserved. + * + * File: PermissionSelector.cpp + * Purpose: Permission selectors. + * + * ======================================================== + */ + +#include +#include + +/// bugs 0 + +namespace NewOS +{ + PermissionSelector::PermissionSelector(const Int32& sel) + : fRing((RingKind)sel) + { + MUST_PASS(sel > 0); + } + + PermissionSelector::PermissionSelector(const RingKind& ringKind) + : fRing(ringKind) + { + } + + PermissionSelector::~PermissionSelector() = default; + + bool PermissionSelector::operator==(const PermissionSelector& lhs) + { + return lhs.fRing == this->fRing; + } + + bool PermissionSelector::operator!=(const PermissionSelector& lhs) + { + return lhs.fRing != this->fRing; + } + + const RingKind& PermissionSelector::Ring() noexcept + { + return this->fRing; + } +} // namespace NewOS diff --git a/Kernel/Sources/Pmm.cxx b/Kernel/Sources/Pmm.cxx new file mode 100644 index 00000000..0641f457 --- /dev/null +++ b/Kernel/Sources/Pmm.cxx @@ -0,0 +1,88 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include + +namespace NewOS +{ + /// @brief Pmm constructor. + Pmm::Pmm() + : fPageManager() + { + kcout << "[PMM] Allocate PageMemoryManager"; + } + + Pmm::~Pmm() = default; + + /* 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 = fPageManager.Leak().Request(user, readWrite, false, kPTESize); + + if (pt.fPresent) + { + kcout << "[PMM]: Allocation was successful.\r"; + return Ref(pt); + } + + kcout << "[PMM]: Allocation failed.\r"; + + return {}; + } + + Boolean Pmm::FreePage(Ref PageRef) + { + if (!PageRef) + return false; + + PageRef.Leak().fPresent = false; + + return true; + } + + Boolean Pmm::TogglePresent(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fPresent = Enable; + + return true; + } + + Boolean Pmm::ToggleUser(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fRw = Enable; + + return true; + } + + Boolean Pmm::ToggleRw(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fRw = Enable; + + return true; + } + + Boolean Pmm::ToggleShare(Ref PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef.Leak().fShareable = Enable; + + return true; + } +} // namespace NewOS diff --git a/Kernel/Sources/ProcessScheduler.cxx b/Kernel/Sources/ProcessScheduler.cxx new file mode 100644 index 00000000..1e4537f1 --- /dev/null +++ b/Kernel/Sources/ProcessScheduler.cxx @@ -0,0 +1,416 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file ProcessScheduler.cxx +/// @brief MicroKernel process scheduler. +/***********************************************************************************/ + +#include +#include +#include +#include +#include + +///! BUGS: 0 + +/***********************************************************************************/ +/* This file handles the process scheduling. +/***********************************************************************************/ + +namespace NewOS +{ + /***********************************************************************************/ + /// @brief Exit Code global + /***********************************************************************************/ + + STATIC Int32 kLastExitCode = 0U; + + /// @brief Gets the latest exit code. + /// @note Not thread-safe. + const Int32& rt_get_exit_code() noexcept + { + return kLastExitCode; + } + + /***********************************************************************************/ + /// @brief crash current process. + /***********************************************************************************/ + + void ProcessHeader::Crash() + { + kcout << this->Name << ": crashed. (id = " << number(39); + kcout << ")\r"; + + if (this->Ring != kRingUserKind) + { + MUST_PASS(ke_bug_check()); + } + + this->Exit(kErrorProcessFault); + } + + void ProcessHeader::Wake(const bool should_wakeup) + { + this->Status = + should_wakeup ? ProcessStatus::kRunning : ProcessStatus::kFrozen; + } + + /***********************************************************************************/ + + VoidPtr ProcessHeader::New(const SizeT& sz) + { + if (this->FreeMemory < 1) + { + DbgLastError() = kErrorHeapOutOfMemory; + this->Crash(); /// out of memory. + + return nullptr; + } + + if (this->HeapCursor) + { + VoidPtr ptr = this->HeapCursor; + this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor + (sizeof(sz))); + + ++this->UsedMemory; + --this->FreeMemory; + + return ptr; + } + + return nullptr; + } + + /***********************************************************************************/ + + /* @brief checks if runtime pointer is in region. */ + bool rt_is_in_pool(VoidPtr pool_ptr, VoidPtr pool, const SizeT& sz) + { + UIntPtr* _pool_ptr = (UIntPtr*)pool_ptr; + UIntPtr* _pool = (UIntPtr*)pool; + + for (SizeT index = sz; _pool[sz] != kUserHeapMag; --index) + { + if (&_pool[index] > &_pool_ptr[sz]) + continue; + + if (_pool[index] == _pool_ptr[index]) + return true; + } + + return false; + } + + /* @brief free pointer from usage. */ + Boolean ProcessHeader::Delete(VoidPtr ptr, const SizeT& sz) + { + if (sz < 1 || this->HeapCursor == this->HeapPtr) + return false; + + // also check for the amount of allocations we've done so far. + if (this->UsedMemory < 1) + return false; + + if (rt_is_in_pool(ptr, this->HeapCursor, this->UsedMemory)) + { + this->HeapCursor = (VoidPtr)((UIntPtr)this->HeapCursor - (sizeof(sz))); + rt_zero_memory(ptr, sz); + + ++this->FreeMemory; + --this->UsedMemory; + + return true; + } + + return false; + } + + /// @brief process name getter. + const Char* ProcessHeader::GetName() + { + return this->Name; + } + + /// @brief process selector getter. + const ProcessSelector& ProcessHeader::GetSelector() + { + return this->Selector; + } + + /// @brief process status getter. + const ProcessStatus& ProcessHeader::GetStatus() + { + return this->Status; + } + + /***********************************************************************************/ + + /** + @brief Affinity is the time slot allowed for the process. + */ + const AffinityKind& ProcessHeader::GetAffinity() + { + return this->Affinity; + } + + /** + @brief Standard exit proc. + */ + void ProcessHeader::Exit(Int32 exit_code) + { + if (this->ProcessId != + ProcessScheduler::Shared().Leak().GetCurrent().Leak().ProcessId) + ke_stop(RUNTIME_CHECK_PROCESS); + + if (this->Ring == (Int32)ProcessSelector::kRingKernel && + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Ring > 0) + ke_stop(RUNTIME_CHECK_PROCESS); + + kLastExitCode = exit_code; + + if (this->Ring != (Int32)ProcessSelector::kRingDriver) + { + if (this->HeapPtr) + rt_free_heap(this->HeapPtr); + + this->HeapPtr = nullptr; + this->HeapCursor = nullptr; + + this->FreeMemory = 0UL; + this->UsedMemory = 0UL; + } + + //! Delete image if not done already. + if (this->Image) + ke_delete_ke_heap(this->Image); + if (this->StackFrame) + ke_delete_ke_heap((VoidPtr)this->StackFrame); + + this->Image = nullptr; + this->StackFrame = nullptr; + + ProcessScheduler::Shared().Leak().Remove(this->ProcessId); + } + + /// @brief Add process to list. + /// @param process + /// @return + SizeT ProcessScheduler::Add(Ref& process) + { + if (!process) + return -1; + + if (!process.Leak().Image) + { + if (process.Leak().Kind != ProcessHeader::kLibKind) + { + return -kErrorNoEntrypoint; + } + } + + if (!mTeam.AsArray().Count() > kSchedProcessLimitPerTeam) + return -kErrorOutOfTeamSlot; + + if (process.Leak().Ring != (Int32)ProcessSelector::kRingKernel) + return -1; + + kcout << "ProcessScheduler::Add(Ref& process)\r"; + + /// Create heap according to type of process. + if (process.Leak().Kind == ProcessHeader::kAppKind) + process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw); + else if (process.Leak().Kind == ProcessHeader::kLibKind) + process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw | kUserHeapShared); + else + process.Leak().HeapPtr = rt_new_heap(kUserHeapDriver | kUserHeapRw); + + process.Leak().StackFrame = reinterpret_cast( + ke_new_ke_heap(sizeof(HAL::StackFrame), true, false)); + + MUST_PASS(process.Leak().StackFrame); + + mTeam.AsArray().Add(process); + + process.Leak().ProcessId = mTeam.AsArray().Count() - 1; + process.Leak().HeapCursor = process.Leak().HeapPtr; + + return mTeam.AsArray().Count() - 1; + } + + /// @brief Remove process from list. + /// @param process + /// @return + bool ProcessScheduler::Remove(SizeT process) + { + if (process > mTeam.AsArray().Count()) + return false; + + kcout << "ProcessScheduler::Remove(SizeT process)\r"; + + return mTeam.AsArray().Remove(process); + } + + /// @brief Run scheduler. + /// @return + SizeT ProcessScheduler::Run() noexcept + { + SizeT processIndex = 0; //! we store this guy to tell the scheduler how many + //! things we have scheduled. + + for (; processIndex < mTeam.AsArray().Count(); ++processIndex) + { + auto process = mTeam.AsArray()[processIndex]; + + MUST_PASS(process); //! no need for a MUST_PASS(process.Leak());, it is + //! recursive because of the nature of the class; + + //! run any process needed to be scheduled. + if (ProcessHelper::CanBeScheduled(process.Leak())) + { + auto unwrapped_process = *process.Leak(); + + unwrapped_process.PTime = 0; + + // set the current process. + mTeam.AsRef() = unwrapped_process; + + // tell helper to find a core to schedule on. + ProcessHelper::Switch(mTeam.AsRef().Leak().StackFrame, + mTeam.AsRef().Leak().ProcessId); + } + else + { + // otherwise increment the P-time. + ++mTeam.AsRef().Leak().PTime; + } + } + + return processIndex; + } + + /// @brief Gets the current scheduled team. + /// @return + ProcessTeam& ProcessScheduler::CurrentTeam() + { + return mTeam; + } + + /// @brief Shared instance of the process scheduler. + /// @return + Ref ProcessScheduler::Shared() + { + static ProcessScheduler ref; + return {ref}; + } + + /// @brief Gets current running process. + /// @return + Ref& ProcessScheduler::GetCurrent() + { + return mTeam.AsRef(); + } + + /// @brief Current proccess id getter. + /// @return Process ID integer. + PID& ProcessHelper::GetCurrentPID() + { + kcout << "ProcessHelper::GetCurrentPID: Leaking ProcessId...\r"; + return ProcessScheduler::Shared().Leak().GetCurrent().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 ProcessHelper::CanBeScheduled(Ref& process) + { + if (process.Leak().Status == ProcessStatus::kFrozen || + process.Leak().Status == ProcessStatus::kDead) + return false; + + if (process.Leak().GetStatus() == ProcessStatus::kStarting) + { + if (process.Leak().PTime < static_cast(kSchedMinMicroTime)) + { + process.Leak().Status = ProcessStatus::kRunning; + process.Leak().Affinity = AffinityKind::kHartStandard; + + return true; + } + + ++process.Leak().PTime; + } + + return process.Leak().PTime > static_cast(kSchedMinMicroTime); + } + + /** + * @brief Spin scheduler class. + */ + + bool ProcessHelper::StartScheduling() + { + if (ProcessHelper::CanBeScheduled( + ProcessScheduler::Shared().Leak().GetCurrent())) + { + --ProcessScheduler::Shared().Leak().GetCurrent().Leak().PTime; + return false; + } + + auto processRef = ProcessScheduler::Shared().Leak(); + + if (!processRef) + return false; // we have nothing to schedule. simply return. + + SizeT ret = processRef.Run(); + + kcout << StringBuilder::FromInt( + "ProcessHelper::StartScheduling() Iterated over {%} jobs inside team.\r", ret); + + return true; + } + + /** + * \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 ProcessHelper::Switch(HAL::StackFrame* the_stack, const PID& new_pid) + { + if (!the_stack || new_pid < 0) + return false; + + for (SizeT index = 0UL; index < SMPManager::Shared().Leak().Count(); ++index) + { + if (SMPManager::Shared().Leak()[index].Leak().Kind() == kInvalidHart) + continue; + + if (SMPManager::Shared().Leak()[index].Leak().StackFrame() == the_stack) + { + SMPManager::Shared().Leak()[index].Leak().Busy(false); + continue; + } + + if (SMPManager::Shared().Leak()[index].Leak().IsBusy()) + continue; + + if (SMPManager::Shared().Leak()[index].Leak().Kind() != + ThreadKind::kHartBoot && + SMPManager::Shared().Leak()[index].Leak().Kind() != + ThreadKind::kHartSystemReserved) + { + SMPManager::Shared().Leak()[index].Leak().Busy(true); + ProcessHelper::GetCurrentPID() = new_pid; + + return SMPManager::Shared().Leak()[index].Leak().Switch(the_stack); + } + } + + return false; + } +} // namespace NewOS diff --git a/Kernel/Sources/ProcessTeam.cxx b/Kernel/Sources/ProcessTeam.cxx new file mode 100644 index 00000000..7e311399 --- /dev/null +++ b/Kernel/Sources/ProcessTeam.cxx @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file ProcessTeam.cxx +/// @brief Process teams implementation. +/***********************************************************************************/ + +#include + +namespace NewOS +{ + /// @brief Process list array getter. + /// @return The list of process to schedule. + MutableArray>& ProcessTeam::AsArray() + { + return mProcessList; + } + + /// @brief Current process getter. + /// @return The current process header. + Ref& ProcessTeam::AsRef() + { + return mCurrentProcess; + } +} // namespace NewOS + +// last rev 05-03-24 diff --git a/Kernel/Sources/Property.cxx b/Kernel/Sources/Property.cxx new file mode 100644 index 00000000..0c5c5fab --- /dev/null +++ b/Kernel/Sources/Property.cxx @@ -0,0 +1,20 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS +{ + bool Property::StringEquals(StringView& name) + { + return fName && this->fName == name; + } + + const PropertyId& Property::GetPropertyById() + { + return fAction; + } +} // namespace NewOS diff --git a/Kernel/Sources/Ref.cxx b/Kernel/Sources/Ref.cxx new file mode 100644 index 00000000..01883e07 --- /dev/null +++ b/Kernel/Sources/Ref.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/SMPManager.cxx b/Kernel/Sources/SMPManager.cxx new file mode 100644 index 00000000..90a9d440 --- /dev/null +++ b/Kernel/Sources/SMPManager.cxx @@ -0,0 +1,234 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +///! BUGS: 0 + +///! @file SMPManager.cxx +///! @brief This file handles multi processing in NewOS. +///! @brief Multi processing is needed for multi-tasking operations. + +namespace NewOS +{ + ///! A HardwareThread class takes care of it's owned hardware thread. + ///! It has a stack for it's core. + + ///! @brief constructor + HardwareThread::HardwareThread() = default; + + ///! @brief destructor + HardwareThread::~HardwareThread() = default; + + //! @brief returns the id + + const ThreadID& HardwareThread::ID() noexcept + { + return fID; + } + + //! @brief returns the kind + + const ThreadKind& HardwareThread::Kind() noexcept + { + return fKind; + } + + //! @brief is the core busy? + + bool HardwareThread::IsBusy() noexcept + { + return fBusy; + } + + /// @brief Get processor stack frame. + + HAL::StackFramePtr HardwareThread::StackFrame() noexcept + { + MUST_PASS(fStack); + return fStack; + } + + void HardwareThread::Busy(const bool busy) noexcept + { + fBusy = busy; + } + + HardwareThread::operator bool() + { + return fStack; + } + + /// @brief Wakeup the processor. + + void HardwareThread::Wake(const bool wakeup) noexcept + { + fWakeup = wakeup; + + if (!fWakeup) + rt_hang_thread(fStack); + else + rt_wakeup_thread(fStack); + } + + extern bool rt_check_stack(HAL::StackFramePtr stackPtr); + + /// @brief Switch to hardware thread. + /// @param stack the new hardware thread. + /// @retval true stack was changed, code is running. + /// @retval false stack is invalid, previous code is running. + bool HardwareThread::Switch(HAL::StackFramePtr stack) + { + if (!rt_check_stack(stack)) + return false; + + if (!fStack) + { + fStack = stack; + } + else + { + /// Keep the arguments, switch the base pointer, stack pointer + /// fs and gs registers. + + fStack->Rbp = stack->Rbp; + fStack->Rsp = stack->Rsp; + fStack->Fs = stack->Fs; + fStack->Gs = stack->Gs; + } + + rt_do_context_switch(fStack); + return true; + } + + ///! @brief Tells if processor is waked up. + bool HardwareThread::IsWakeup() noexcept + { + return fWakeup; + } + + //! @brief Constructor and destructor + + ///! @brief Default constructor. + SMPManager::SMPManager() = default; + + ///! @brief Default destructor. + SMPManager::~SMPManager() = default; + + /// @brief Shared singleton function + Ref SMPManager::Shared() + { + static SMPManager manager; + return {manager}; + } + + /// @brief Get Stack Frame of Core + HAL::StackFramePtr SMPManager::GetStackFrame() noexcept + { + if (fThreadList[fCurrentThread].Leak() && + ProcessHelper::GetCurrentPID() == + fThreadList[fCurrentThread].Leak().Leak().fPID) + return fThreadList[fCurrentThread].Leak().Leak().fStack; + + return nullptr; + } + + /// @brief Finds and switch to a free core. + bool SMPManager::Switch(HAL::StackFramePtr stack) + { + if (stack == nullptr) + return false; + + for (SizeT idx = 0; idx < kMaxHarts; ++idx) + { + // stack != nullptr -> if core is used, then continue. + if (!fThreadList[idx].Leak() || + !fThreadList[idx].Leak().Leak().IsWakeup() || + fThreadList[idx].Leak().Leak().IsBusy()) + continue; + + // to avoid any null deref. + if (!fThreadList[idx].Leak().Leak().fStack) + continue; + if (fThreadList[idx].Leak().Leak().fStack->Rsp == 0) + continue; + if (fThreadList[idx].Leak().Leak().fStack->Rbp == 0) + continue; + + fThreadList[idx].Leak().Leak().Busy(true); + + fThreadList[idx].Leak().Leak().fID = idx; + + /// I figured out this: + /// Allocate stack + /// Set APIC base to stack + /// Do stuff and relocate stack based on this code. + /// - Amlel + rt_copy_memory(stack, fThreadList[idx].Leak().Leak().fStack, + sizeof(HAL::StackFrame)); + + fThreadList[idx].Leak().Leak().fPID = ProcessHelper::GetCurrentPID(); + + fThreadList[idx].Leak().Leak().Busy(false); + + return true; + } + + return false; + } + + /** + * Index Hardware thread + * @param idx the index + * @return the reference to the hardware thread. + */ + Ref SMPManager::operator[](const SizeT& idx) + { + if (idx == 0) + { + if (fThreadList[idx].Leak().Leak().Kind() != kHartSystemReserved) + { + fThreadList[idx].Leak().Leak().fKind = kHartBoot; + } + } + else if (idx >= kMaxHarts) + { + HardwareThread fakeThread; + fakeThread.fKind = kInvalidHart; + + return {fakeThread}; + } + + return fThreadList[idx].Leak(); + } + + /** + * Check if thread pool isn't empty. + * @return + */ + SMPManager::operator bool() noexcept + { + return !fThreadList.Empty(); + } + + /** + * Reverse operator bool + * @return + */ + bool SMPManager::operator!() noexcept + { + return fThreadList.Empty(); + } + + /// @brief Returns the amount of core present. + /// @return the number of cores. + SizeT SMPManager::Count() noexcept + { + return fThreadList.Count(); + } +} // namespace NewOS diff --git a/Kernel/Sources/Semaphore.cxx b/Kernel/Sources/Semaphore.cxx new file mode 100644 index 00000000..7bd1d513 --- /dev/null +++ b/Kernel/Sources/Semaphore.cxx @@ -0,0 +1,53 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +namespace NewOS +{ + bool Semaphore::Unlock() noexcept + { + if (fLockingProcess) + fLockingProcess = nullptr; + + return fLockingProcess == nullptr; + } + + bool Semaphore::Lock(ProcessHeader* process) + { + if (!process || fLockingProcess) + return false; + + fLockingProcess = process; + + return true; + } + + bool Semaphore::IsLocked() const + { + return fLockingProcess; + } + + bool Semaphore::LockOrWait(ProcessHeader* process, const Int64& seconds) + { + if (process == nullptr) + return false; + + HardwareTimer timer(Seconds(seconds)); + timer.Wait(); + + return this->Lock(process); + } + + void Semaphore::Sync() noexcept + { + while (fLockingProcess) + { + } + } +} // namespace NewOS diff --git a/Kernel/Sources/Storage/AHCIDeviceInterface.cxx b/Kernel/Sources/Storage/AHCIDeviceInterface.cxx new file mode 100644 index 00000000..b0431cb1 --- /dev/null +++ b/Kernel/Sources/Storage/AHCIDeviceInterface.cxx @@ -0,0 +1,35 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +using namespace NewOS; + +/// @brief Class constructor +/// @param Out Disk output +/// @param In Disk input +/// @param Cleanup Disk cleanup. +AHCIDeviceInterface::AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)) + : DeviceInterface(Out, In), fCleanup(Cleanup) +{ +} + +/// @brief Class desctructor +AHCIDeviceInterface::~AHCIDeviceInterface() +{ + MUST_PASS(fCleanup); + if (fCleanup) + fCleanup(); +} + +/// @brief Returns the name of the device interface. +/// @return it's name as a string. +const char* AHCIDeviceInterface::Name() const +{ + return "AHCIDeviceInterface"; +} diff --git a/Kernel/Sources/Storage/ATADeviceInterface.cxx b/Kernel/Sources/Storage/ATADeviceInterface.cxx new file mode 100644 index 00000000..0f7d22c1 --- /dev/null +++ b/Kernel/Sources/Storage/ATADeviceInterface.cxx @@ -0,0 +1,88 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +using namespace NewOS; + +/// @brief Class constructor +/// @param Out Disk output +/// @param In Disk input +/// @param Cleanup Disk cleanup. +ATADeviceInterface::ATADeviceInterface( + void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)) + : DeviceInterface(Out, In), fCleanup(Cleanup) +{ +} + +/// @brief Class desctructor +ATADeviceInterface::~ATADeviceInterface() +{ + MUST_PASS(fCleanup); + if (fCleanup) + fCleanup(); +} + +/// @brief Returns the name of the device interface. +/// @return it's name as a string. +const char* ATADeviceInterface::Name() const +{ + return "ATADeviceInterface"; +} + +/// @brief Output operator. +/// @param Data +/// @return +ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data) +{ + if (!Data) + return *this; + + for (SizeT driveCount = 0; driveCount < kDriveManagerCount; ++driveCount) + { + auto interface = Data->GetAddressOf(driveCount); + if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) + { + continue; + } + else if ((interface) && + rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) + { + return *this; + } + } + + return (ATADeviceInterface&)DeviceInterface::operator<<( + Data); +} + +/// @brief Input operator. +/// @param Data +/// @return +ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* Data) +{ + if (!Data) + return *this; + + for (SizeT driveCount = 0; driveCount < kDriveManagerCount; ++driveCount) + { + auto interface = Data->GetAddressOf(driveCount); + if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0) + { + continue; + } + else if ((interface) && + rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0) + { + return *this; + } + } + + return (ATADeviceInterface&)DeviceInterface::operator>>( + Data); +} diff --git a/Kernel/Sources/Storage/NVMEDeviceInterface.cxx b/Kernel/Sources/Storage/NVMEDeviceInterface.cxx new file mode 100644 index 00000000..22c9c9d0 --- /dev/null +++ b/Kernel/Sources/Storage/NVMEDeviceInterface.cxx @@ -0,0 +1,15 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS +{ + const char* NVMEDeviceInterface::Name() const + { + return ("NVMEDeviceInterface"); + } +} // namespace NewOS diff --git a/Kernel/Sources/Storage/SCSIDeviceInterface.cxx b/Kernel/Sources/Storage/SCSIDeviceInterface.cxx new file mode 100644 index 00000000..b64681d3 --- /dev/null +++ b/Kernel/Sources/Storage/SCSIDeviceInterface.cxx @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +///! @brief ATAPI SCSI packet. +const scsi_packet_type kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, + 0, 12, 0x40, 0, 0}; diff --git a/Kernel/Sources/Stream.cxx b/Kernel/Sources/Stream.cxx new file mode 100644 index 00000000..f21ef4d7 --- /dev/null +++ b/Kernel/Sources/Stream.cxx @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + + File: Stream.cxx + Purpose: Stream object + + Revision History: + +------------------------------------------- */ + +#include diff --git a/Kernel/Sources/String.cxx b/Kernel/Sources/String.cxx new file mode 100644 index 00000000..4b6ea365 --- /dev/null +++ b/Kernel/Sources/String.cxx @@ -0,0 +1,248 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +namespace NewOS +{ + Char* StringView::Data() + { + return fData; + } + + const Char* StringView::CData() + { + return fData; + } + + Size StringView::Length() const + { + return rt_string_len(fData); + } + + bool StringView::operator==(const StringView& rhs) const + { + if (rhs.Length() != this->Length()) + return false; + + for (Size index = 0; index < this->Length(); ++index) + { + if (rhs.fData[index] != fData[index]) + return false; + } + + return true; + } + + bool StringView::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] != fData[index]) + return false; + } + + return true; + } + + bool StringView::operator!=(const StringView& rhs) const + { + if (rhs.Length() != this->Length()) + return false; + + for (Size index = 0; index < rhs.Length(); ++index) + { + if (rhs.fData[index] == fData[index]) + return false; + } + + return true; + } + + bool StringView::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] == fData[index]) + return false; + } + + return true; + } + + ErrorOr StringBuilder::Construct(const Char* data) + { + if (!data || *data == 0) + return {}; + + StringView view(rt_string_len(data)); + + view += data; + + return ErrorOr(view); + } + + const char* StringBuilder::FromInt(const char* fmt, int i) + { + if (!fmt) + return ("-1"); + + char* ret = (char*)Alloca(sizeof(char) * 8 + rt_string_len(fmt)); + + if (!ret) + return ("-1"); + + Char result[8]; + + if (!rt_to_string(result, sizeof(int), i)) + { + return ("-1"); + } + + const auto fmt_len = rt_string_len(fmt); + const auto res_len = rt_string_len(result); + + 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] = result[y_idx]; + ++result_cnt; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */ + } + + const char* StringBuilder::FromBool(const char* fmt, bool i) + { + if (!fmt) + return ("?"); + + const char* boolean_expr = i ? "true" : "false"; + char* ret = (char*)Alloca((sizeof(char) * i) ? 4 : 5 + 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 StringBuilder::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; + } + + const char* StringBuilder::Format(const char* fmt, const char* fmt2) + { + if (!fmt || !fmt2) + return ("?"); + + char* ret = + (char*)Alloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt2)); + + if (!ret) + return ("?"); + + for (Size idx = 0; idx < rt_string_len(fmt); ++idx) + { + if (fmt[idx] == '%') + { + 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; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; + } + + static void string_append(char* lhs, char* rhs, int cur) + { + if (lhs && rhs) + { + SizeT sz_rhs = rt_string_len(rhs); + + if (sz_rhs == 0) + return; + + rt_copy_memory(rhs, lhs + cur, sz_rhs); + } + } + + StringView& StringView::operator+=(const Char* rhs) + { + string_append(this->fData, const_cast(rhs), this->fCur); + this->fCur += rt_string_len(rhs); + + return *this; + } + + StringView& StringView::operator+=(const StringView& rhs) + { + if (rt_string_len(rhs.fData) > rt_string_len(this->fData)) + return *this; + + string_append(this->fData, const_cast(rhs.fData), this->fCur); + this->fCur += rt_string_len(const_cast(rhs.fData)); + + return *this; + } +} // namespace NewOS diff --git a/Kernel/Sources/ThreadLocalStorage.cxx b/Kernel/Sources/ThreadLocalStorage.cxx new file mode 100644 index 00000000..c31ae1c2 --- /dev/null +++ b/Kernel/Sources/ThreadLocalStorage.cxx @@ -0,0 +1,58 @@ +/* + * ======================================================== + * + * NewOS + * Copyright SoftwareLabs, all rights reserved. + * + * ======================================================== + */ + +#include +#include + +///! BUGS: 0 + +/***********************************************************************************/ +/// @file ThreadLocalStorage.cxx +/// @brief TLS implementation in kernel. +/***********************************************************************************/ + +using namespace NewOS; + +/** + * @brief Check for cookie inside TIB. + * @param tib the TIB to check. + * @return if the cookie is enabled. + */ + +Boolean tls_check_tib(ThreadInformationBlock* tib) +{ + if (!tib) + return false; + + Encoder encoder; + const char* tibAsBytes = encoder.AsBytes(tib); + + kcout << "New OS: Checking for a valid cookie...\r"; + + return tibAsBytes[0] == kCookieMag0 && tibAsBytes[1] == kCookieMag1 && + tibAsBytes[2] == kCookieMag2; +} + +/** + * @brief System call implementation of the TLS check. + * @param stackPtr The call frame. + * @return + */ +EXTERN_C Void tls_check_syscall_impl(NewOS::HAL::StackFramePtr stackPtr) noexcept +{ + ThreadInformationBlock* tib = (ThreadInformationBlock*)stackPtr->Gs; + + if (!tls_check_tib(tib)) + { + kcout << "New OS: Verification failed, Crashing...\r"; + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + } + + kcout << "New OS: Verification succeeded! Keeping on...\r"; +} diff --git a/Kernel/Sources/Timer.cxx b/Kernel/Sources/Timer.cxx new file mode 100644 index 00000000..0495677c --- /dev/null +++ b/Kernel/Sources/Timer.cxx @@ -0,0 +1,41 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +///! BUGS: 0 +///! @file Timer.cxx + +using namespace NewOS; + +/// @brief Unimplemented as it is an interface. +Int32 HardwareTimerInterface::Wait() noexcept +{ + return kErrorUnimplemented; +} + +/// @brief HardwareTimer class, meant to be generic. + +HardwareTimer::HardwareTimer(Int64 seconds) + : fWaitFor(seconds) +{ +} +HardwareTimer::~HardwareTimer() +{ + fWaitFor = 0; +} + +Int32 HardwareTimer::Wait() noexcept +{ + if (fWaitFor < 1) + return -1; + + while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) + { + } + + return 0; +} diff --git a/Kernel/Sources/URL.cxx b/Kernel/Sources/URL.cxx new file mode 100644 index 00000000..1b223938 --- /dev/null +++ b/Kernel/Sources/URL.cxx @@ -0,0 +1,96 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +/// BUGS: 0 + +namespace NewOS +{ + URL::URL(StringView& strUrl) + : fUrlView(strUrl, false) + { + } + + URL::~URL() = default; + + /// @brief internal and reserved protocols by kernel. + constexpr const char* kURLProtocols[] = { + "file", // Filesystem protocol + "mup", // Mahrouss update protocol + "param", // Mahrouss parameter protocol. + }; + + constexpr const int kUrlOutSz = 1; //! such as: :// + constexpr const int kProtosCount = 3; + constexpr const int kRangeSz = 4096; + + ErrorOr url_extract_location(const char* url) + { + if (!url || *url == 0 || rt_string_len(url, kRangeSz) > kRangeSz) + return ErrorOr{-1}; + + StringView view(rt_string_len(url)); + + SizeT i = 0; + bool scheme_found = false; + + for (; i < rt_string_len(url); ++i) + { + if (!scheme_found) + { + for (int y = 0; kProtosCount; ++y) + { + if (rt_string_in_string(view.CData(), kURLProtocols[y])) + { + i += rt_string_len(kURLProtocols[y]) + kUrlOutSz; + scheme_found = true; + + break; + } + } + } + + view.Data()[i] = url[i]; + } + + return ErrorOr(view); + } + + ErrorOr url_extract_protocol(const char* url) + { + if (!url || *url == 0 || rt_string_len(url, kRangeSz) > kRangeSz) + return ErrorOr{-1}; + + ErrorOr view{-1}; + + return view; + } + + Ref> URL::Location() noexcept + { + const char* src = fUrlView.Leak().CData(); + auto loc = url_extract_location(src); + + if (!loc) + return {}; + + return Ref>(loc); + } + + Ref> URL::Protocol() noexcept + { + const char* src = fUrlView.Leak().CData(); + auto loc = url_extract_protocol(src); + + if (!loc) + return {}; + + return Ref>(loc); + } +} // namespace NewOS diff --git a/Kernel/Sources/UserHeap.cxx b/Kernel/Sources/UserHeap.cxx new file mode 100644 index 00000000..02c4c753 --- /dev/null +++ b/Kernel/Sources/UserHeap.cxx @@ -0,0 +1,252 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +#define kHeapHeaderPaddingSz (16U) + +/// @file UserHeap.cxx +/// @brief User Heap Manager, Process heap allocator. +/// @note if you want to look at the kernel allocator, please look for +/// KernelHeap.cxx +/// BUGS: 0 + +namespace NewOS +{ + /** + * @brief Process Heap Header + * @note Allocated per process, it denotes the user's heap. + */ + struct UserHeapHeader final + { + UInt32 fMagic; + Int32 fFlags; + Boolean fFree; + UInt8 fPadding[kHeapHeaderPaddingSz]; + }; + + /** + * @brief User Heap Manager class, takes care of allocating the process pools. + * @note This rely on Virtual Memory! Consider adding good vmem support when + * @note porting to a new arch. + */ + class UserHeapManager final + { + public: + UserHeapManager() = delete; + ~UserHeapManager() = default; + + public: + STATIC SizeT& Count() + { + return s_NumPools; + } + STATIC Ref& Leak() + { + return s_Pmm; + } + STATIC Boolean& IsEnabled() + { + return s_PoolsAreEnabled; + } + STATIC MutableArray>& The() + { + return s_Pool; + } + + private: + STATIC Size s_NumPools; + STATIC Ref s_Pmm; + + private: + STATIC Boolean s_PoolsAreEnabled; + STATIC MutableArray> s_Pool; + }; + + //! declare fields + + SizeT UserHeapManager::s_NumPools = 0UL; + Ref UserHeapManager::s_Pmm; + Boolean UserHeapManager::s_PoolsAreEnabled = true; + MutableArray> UserHeapManager::s_Pool; + + STATIC VoidPtr ke_find_unused_heap(Int32 flags); + STATIC Void ke_free_heap_internal(VoidPtr vaddr); + STATIC VoidPtr ke_make_heap_internal(VoidPtr vaddr, Int32 flags); + STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr); + + /// @brief Find an unused heap header to allocate on. + /// @param flags the flags to use. + /// @return VoidPtr the heap pointer. + STATIC VoidPtr ke_find_unused_heap(Int32 flags) + { + for (SizeT index = 0; index < kUserHeapMaxSz; ++index) + { + if (UserHeapManager::The()[index] && + !UserHeapManager::The()[index].Leak().Leak().Present()) + { + UserHeapManager::Leak().Leak().TogglePresent( + UserHeapManager::The()[index].Leak().Leak(), true); + kcout << "[ke_find_unused_heap] Done, trying to make a pool now...\r"; + + return ke_make_heap_internal( + (VoidPtr)UserHeapManager::The()[index].Leak().Leak().VirtualAddress(), + flags); + } + } + + return nullptr; + } + + /// @brief Makes a new heap for the process to use. + /// @param virtualAddress the virtual address of the process. + /// @param flags the flags. + /// @return + STATIC VoidPtr ke_make_heap_internal(VoidPtr virtualAddress, Int32 flags) + { + if (virtualAddress) + { + UserHeapHeader* poolHdr = reinterpret_cast(virtualAddress); + + if (!poolHdr->fFree) + { + kcout + << "[ke_make_heap_internal] poolHdr->fFree, HeapPtr already exists\n"; + return nullptr; + } + + poolHdr->fFlags = flags; + poolHdr->fMagic = kUserHeapMag; + poolHdr->fFree = false; + + kcout << "[ke_make_heap_internal] New allocation has been done.\n"; + return reinterpret_cast( + (reinterpret_cast(virtualAddress) + sizeof(UserHeapHeader))); + } + + kcout << "[ke_make_heap_internal] Address is invalid"; + return nullptr; + } + + /// @brief Internally makrs the heap as free. + /// This is done by setting the fFree bit to true + /// @param virtualAddress + /// @return + STATIC Void ke_free_heap_internal(VoidPtr virtualAddress) + { + UserHeapHeader* poolHdr = reinterpret_cast( + reinterpret_cast(virtualAddress) - sizeof(UserHeapHeader)); + + if (poolHdr->fMagic == kUserHeapMag) + { + if (!poolHdr->fFree) + { + ProcessScheduler::Shared().Leak().GetCurrent().Leak().Crash(); + return; + } + + poolHdr->fFree = true; + poolHdr->fFlags = 0; + + kcout << "[ke_free_heap_internal] Successfully marked header as free!\r"; + } + } + + /** + * @brief Check for the ptr and frees it. + * + * @param index Where to look at. + * @param ptr The ptr to check. + * @return Boolean true if successful. + */ + STATIC Boolean ke_check_and_free_heap(const SizeT& index, VoidPtr ptr) + { + if (UserHeapManager::The()[index]) + { + // ErrorOr<>::operator Boolean + /// if (address matches) + /// -> Free heap. + if (UserHeapManager::The()[index].Leak().Leak().VirtualAddress() == + (UIntPtr)ptr) + { + UserHeapManager::Leak().Leak().FreePage( + UserHeapManager::The()[index].Leak().Leak()); + + --UserHeapManager::Count(); + + ke_free_heap_internal(ptr); + ptr = nullptr; + + return true; + } + } + + return false; + } + + /// @brief Creates a new pool pointer. + /// @param flags the flags attached to it. + /// @return a pool pointer with selected permissions. + VoidPtr rt_new_heap(Int32 flags) + { + if (!UserHeapManager::IsEnabled()) + return nullptr; + + if (UserHeapManager::Count() > kUserHeapMaxSz) + return nullptr; + + if (VoidPtr ret = ke_find_unused_heap(flags)) + return ret; + + // this wasn't set to true + auto ref_page = UserHeapManager::Leak().Leak().RequestPage( + ((flags & kUserHeapUser)), (flags & kUserHeapRw)); + + if (ref_page) + { + ///! reserve page. + UserHeapManager::The()[UserHeapManager::Count()].Leak() = ref_page; + auto& ref = UserHeapManager::Count(); + + ++ref; // increment the number of addresses we have now. + + // finally make the pool address. + return ke_make_heap_internal( + reinterpret_cast(ref_page.Leak().VirtualAddress()), flags); + } + + return nullptr; + } + + /// @brief free a pool pointer. + /// @param ptr The pool pointer to free. + /// @return status code + Int32 rt_free_heap(VoidPtr ptr) + { + if (!UserHeapManager::IsEnabled()) + return -1; + + if (ptr) + { + SizeT base = UserHeapManager::Count(); + + if (ke_check_and_free_heap(base, ptr)) + return 0; + + for (SizeT index = 0; index < kUserHeapMaxSz; ++index) + { + if (ke_check_and_free_heap(index, ptr)) + return 0; + + --base; + } + } + + return -1; + } +} // namespace NewOS diff --git a/Kernel/Sources/Utils.cxx b/Kernel/Sources/Utils.cxx new file mode 100644 index 00000000..1814c72e --- /dev/null +++ b/Kernel/Sources/Utils.cxx @@ -0,0 +1,253 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include +#include +#include + +namespace NewOS +{ + Int 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; + } + + return counter; + } + + void rt_zero_memory(voidPtr pointer, Size len) + { + rt_set_memory(pointer, 0, len); + } + + Size rt_string_len(const Char* str, SizeT _len) + { + if (*str == '\0') + return 0; + + Size len{0}; + while (str[len] != '\0') + { + if (len > _len) + { + break; + } + + ++len; + } + + return len; + } + + Size rt_string_len(const Char* ptr) + { + if (!ptr) + return 0; + + SizeT cnt = 0; + + while (*ptr != (Char)0) + { + ++ptr; + ++cnt; + } + + return cnt; + } + + voidPtr rt_set_memory(voidPtr src, char value, Size len) + { + if (!src || len < 1) + return nullptr; + char* start = reinterpret_cast(src); + + while (len) + { + *start = value; + ++start; + --len; + } + + return (voidPtr)start; + } + + Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) + { + if (len < 1) + return -2; + if (!src || !dst) + return -1; + + char* srcChr = reinterpret_cast(src); + char* dstChar = reinterpret_cast(dst); + Size 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) + { + if (len < 1) + return -2; + + char* srcChr = reinterpret_cast(src); + char* dstChar = reinterpret_cast(dst); + Size index = 0; + + while (index < len) + { + dstChar[index] = srcChr[index]; + ++index; + } + + return index; + } + + const Char* alloc_string(const Char* text) + { + if (!text) + return nullptr; + + const Char* string = new Char[rt_string_len(text)]; + if (!string) + return nullptr; + + voidPtr vText = reinterpret_cast(const_cast(text)); + voidPtr vStr = reinterpret_cast(const_cast(string)); + rt_copy_memory(vText, vStr, rt_string_len(text)); + + return string; + } + + Int rt_to_uppercase(Int character) + { + if (character >= 'a' && character <= 'z') + return character - 0x20; + + return character; + } + + Int rt_to_lower(Int character) + { + if (character >= 'A' && character <= 'Z') + return character + 0x20; + + return character; + } + + bool rt_to_string(Char* str, Int limit, Int base) + { + if (limit == 0) + return false; + + Int copy_limit = limit; + Int cnt = 0; + Int ret = base; + + while (limit != 1) + { + ret = ret % 10; + str[cnt] = ret; + + ++cnt; + --limit; + --ret; + } + + str[copy_limit] = '\0'; + return true; + } + + Boolean is_space(Char chr) + { + return chr == ' '; + } + + Boolean is_newln(Char chr) + { + return chr == '\n'; + } + + voidPtr rt_string_in_string(const char* in, const char* needle) + { + for (size_t 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; + } + + // @brief Checks for a string start at the character. + + char* rt_string_has_char(char* str, const char chr) + { + while (*str != chr) + { + ++str; + + if (*str == 0) + return nullptr; + } + + return str; + } +} // namespace NewOS + +//////////////////////////////////////////////////////////////////////////////////////// +/// Exported C functions +//////////////////////////////////////////////////////////////////////////////////////// + +/// @brief memset in C++ +EXTERN_C void memset(void* dst, char src, size_t len) +{ + NewOS::rt_set_memory(dst, src, len); +} + +/// @brief memcpy in C++ +EXTERN_C void memcpy(void* dst, void* src, size_t len) +{ + NewOS::rt_copy_memory(src, dst, len); +} + +/// @brief memmove in C++ +EXTERN_C void* memmove(void* dst, void* src, size_t len) +{ + NewOS::rt_copy_memory(src, dst, len); + return dst; +} + +/// @brief strlen definition in C++. +EXTERN_C size_t strlen(const char* whatToCheck) +{ + return NewOS::rt_string_len(whatToCheck); +} + +/// @brief memcmp in C++ +EXTERN_C NewOS::SizeT memcmp(void* dst, void* src, size_t len) +{ + return NewOS::rt_string_cmp((char*)src, (char*)dst, len); +} + +/// @brief strcmp in C++ +EXTERN_C NewOS::SizeT strcmp(char* dst, char* src, size_t len) +{ + return NewOS::rt_string_cmp(src, dst, len); +} diff --git a/Kernel/Sources/Variant.cxx b/Kernel/Sources/Variant.cxx new file mode 100644 index 00000000..94f1991e --- /dev/null +++ b/Kernel/Sources/Variant.cxx @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#include + +namespace NewOS +{ + const Char* Variant::ToString() + { + switch (fKind) + { + case VariantKind::kString: + return ("Class:{String}"); + case VariantKind::kPointer: + return ("Memory:{Pointer}"); + default: + return ("Memory:{Undefined}"); + } + } + +} // namespace NewOS diff --git a/Kernel/Sources/compile_flags.txt b/Kernel/Sources/compile_flags.txt new file mode 100644 index 00000000..1f54e6fb --- /dev/null +++ b/Kernel/Sources/compile_flags.txt @@ -0,0 +1,7 @@ +-nostdlib +-ffreestanding +-std=c++20 +-I../ +-I$(HOME)/ +-D__FSKIT_NEWFS__ +-D__NEWOS_AMD64__ diff --git a/Kernel/makefile b/Kernel/makefile index 24c823b4..b7749100 100644 --- a/Kernel/makefile +++ b/Kernel/makefile @@ -50,9 +50,9 @@ WINDRES=x86_64-w64-mingw32-windres .PHONY: newos-amd64-epm newos-amd64-epm: clean $(WINDRES) KernelRsrc.rsrc -O coff -o KernelRsrc.obj - $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard Source/*.cxx) \ - $(wildcard Source/FS/*.cxx) $(wildcard HALKit/AMD64/Storage/*.cxx) \ - $(wildcard HALKit/AMD64/PCI/*.cxx) $(wildcard Source/Network/*.cxx) $(wildcard Source/Storage/*.cxx) \ + $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard Sources/*.cxx) \ + $(wildcard Sources/FS/*.cxx) $(wildcard HALKit/AMD64/Storage/*.cxx) \ + $(wildcard HALKit/AMD64/PCI/*.cxx) $(wildcard Sources/Network/*.cxx) $(wildcard Sources/Storage/*.cxx) \ $(wildcard HALKit/AMD64/*.cxx) $(wildcard HALKit/AMD64/*.cpp) \ $(wildcard HALKit/AMD64/*.s) $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm -- cgit v1.2.3