From d48cbe75ef29a9c67c9d176bf58e56ea6448fb9e Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 21 Oct 2024 20:23:36 +0200 Subject: IMP: Major refactor of header and source files extensions. Signed-off-by: Amlal El Mahrouss --- dev/zka/src/ACPIFactoryInterface.cc | 95 +++ dev/zka/src/ACPIFactoryInterface.cxx | 95 --- dev/zka/src/Array.cc | 7 + dev/zka/src/Array.cxx | 7 - dev/zka/src/ArrayList.cc | 7 + dev/zka/src/ArrayList.cxx | 7 - dev/zka/src/Atom.cc | 10 + dev/zka/src/Atom.cxx | 10 - dev/zka/src/BitMapMgr.cc | 203 +++++ dev/zka/src/BitMapMgr.cxx | 203 ----- dev/zka/src/CRuntime.cc | 69 ++ dev/zka/src/CRuntime.cxx | 69 -- dev/zka/src/CodeMgr.cc | 33 + dev/zka/src/CodeMgr.cxx | 33 - dev/zka/src/Crc32.cc | 83 +++ dev/zka/src/Crc32.cxx | 83 --- dev/zka/src/CxxAbi-AMD64.cc | 90 +++ dev/zka/src/CxxAbi-AMD64.cxx | 90 --- dev/zka/src/CxxAbi-ARM64.cc | 90 +++ dev/zka/src/CxxAbi-ARM64.cxx | 90 --- dev/zka/src/Defines.cc | 7 + dev/zka/src/Defines.cxx | 7 - dev/zka/src/DeviceMgr.cc | 7 + dev/zka/src/DeviceMgr.cxx | 7 - dev/zka/src/DriveMgr.cc | 167 +++++ dev/zka/src/DriveMgr.cxx | 167 ----- dev/zka/src/ErrorOr.cc | 12 + dev/zka/src/ErrorOr.cxx | 12 - dev/zka/src/FS/HPFS.cc | 12 + dev/zka/src/FS/HPFS.cxx | 12 - dev/zka/src/FS/NeFS.cc | 1057 +++++++++++++++++++++++++++ dev/zka/src/FS/NeFS.cxx | 1057 --------------------------- dev/zka/src/FileMgr.cc | 52 ++ dev/zka/src/FileMgr.cxx | 52 -- dev/zka/src/GUIDWizard.cc | 72 ++ dev/zka/src/GUIDWizard.cxx | 72 -- dev/zka/src/GUIDWrapper.cc | 11 + dev/zka/src/GUIDWrapper.cxx | 11 - dev/zka/src/HardwareThreadScheduler.cc | 193 +++++ dev/zka/src/HardwareThreadScheduler.cxx | 193 ----- dev/zka/src/Heap.cc | 265 +++++++ dev/zka/src/Heap.cxx | 265 ------- dev/zka/src/IDLLObject.cc | 15 + dev/zka/src/IDLLObject.cxx | 15 - dev/zka/src/IPEFDLLObject.cc | 102 +++ dev/zka/src/IPEFDLLObject.cxx | 102 --- dev/zka/src/IndexableProperty.cc | 57 ++ dev/zka/src/IndexableProperty.cxx | 57 -- dev/zka/src/Json.cc | 12 + dev/zka/src/Json.cxx | 12 - dev/zka/src/LPC.cc | 34 + dev/zka/src/LPC.cxx | 34 - dev/zka/src/LockDelegate.cc | 12 + dev/zka/src/LockDelegate.cxx | 12 - dev/zka/src/MutableArray.cc | 7 + dev/zka/src/MutableArray.cxx | 7 - dev/zka/src/NeFS+FileMgr.cc | 248 +++++++ dev/zka/src/NeFS+FileMgr.cxx | 248 ------- dev/zka/src/NeFS+IO.cc | 101 +++ dev/zka/src/NeFS+IO.cxx | 101 --- dev/zka/src/Network/IP.cc | 126 ++++ dev/zka/src/Network/IP.cxx | 126 ---- dev/zka/src/Network/IPC.cc | 114 +++ dev/zka/src/Network/IPC.cxx | 114 --- dev/zka/src/Network/NetworkDevice.cc | 35 + dev/zka/src/Network/NetworkDevice.cxx | 35 - dev/zka/src/New+Delete.cc | 50 ++ dev/zka/src/New+Delete.cxx | 50 -- dev/zka/src/OwnPtr.cc | 7 + dev/zka/src/OwnPtr.cxx | 7 - dev/zka/src/PEFCodeMgr.cc | 262 +++++++ dev/zka/src/PEFCodeMgr.cxx | 262 ------- dev/zka/src/PRDT.cc | 22 + dev/zka/src/PRDT.cxx | 22 - dev/zka/src/PageMgr.cc | 110 +++ dev/zka/src/PageMgr.cxx | 110 --- dev/zka/src/Pmm.cc | 94 +++ dev/zka/src/Pmm.cxx | 94 --- dev/zka/src/Property.cc | 27 + dev/zka/src/Property.cxx | 27 - dev/zka/src/Ref.cc | 7 + dev/zka/src/Ref.cxx | 7 - dev/zka/src/Semaphore.cc | 62 ++ dev/zka/src/Semaphore.cxx | 62 -- dev/zka/src/Stop.cc | 126 ++++ dev/zka/src/Stop.cxx | 126 ---- dev/zka/src/Storage/AHCIDeviceInterface.cc | 35 + dev/zka/src/Storage/AHCIDeviceInterface.cxx | 35 - dev/zka/src/Storage/ATADeviceInterface.cc | 88 +++ dev/zka/src/Storage/ATADeviceInterface.cxx | 88 --- dev/zka/src/Storage/NVMEDeviceInterface.cc | 28 + dev/zka/src/Storage/NVMEDeviceInterface.cxx | 28 - dev/zka/src/Storage/SCSIDeviceInterface.cc | 11 + dev/zka/src/Storage/SCSIDeviceInterface.cxx | 11 - dev/zka/src/Stream.cc | 12 + dev/zka/src/Stream.cxx | 12 - dev/zka/src/String.cc | 215 ++++++ dev/zka/src/String.cxx | 215 ------ dev/zka/src/ThreadLocalStorage.cc | 67 ++ dev/zka/src/ThreadLocalStorage.cxx | 67 -- dev/zka/src/Timer.cc | 47 ++ dev/zka/src/Timer.cxx | 47 -- dev/zka/src/User.cc | 138 ++++ dev/zka/src/User.cxx | 138 ---- dev/zka/src/UserProcessScheduler.cc | 592 +++++++++++++++ dev/zka/src/UserProcessScheduler.cxx | 592 --------------- dev/zka/src/UserProcessTeam.cc | 47 ++ dev/zka/src/UserProcessTeam.cxx | 47 -- dev/zka/src/Utils.cc | 212 ++++++ dev/zka/src/Utils.cxx | 212 ------ dev/zka/src/Variant.cc | 33 + dev/zka/src/Variant.cxx | 33 - 112 files changed, 5697 insertions(+), 5697 deletions(-) create mode 100644 dev/zka/src/ACPIFactoryInterface.cc delete mode 100644 dev/zka/src/ACPIFactoryInterface.cxx create mode 100644 dev/zka/src/Array.cc delete mode 100644 dev/zka/src/Array.cxx create mode 100644 dev/zka/src/ArrayList.cc delete mode 100644 dev/zka/src/ArrayList.cxx create mode 100644 dev/zka/src/Atom.cc delete mode 100644 dev/zka/src/Atom.cxx create mode 100644 dev/zka/src/BitMapMgr.cc delete mode 100644 dev/zka/src/BitMapMgr.cxx create mode 100644 dev/zka/src/CRuntime.cc delete mode 100644 dev/zka/src/CRuntime.cxx create mode 100644 dev/zka/src/CodeMgr.cc delete mode 100644 dev/zka/src/CodeMgr.cxx create mode 100644 dev/zka/src/Crc32.cc delete mode 100644 dev/zka/src/Crc32.cxx create mode 100644 dev/zka/src/CxxAbi-AMD64.cc delete mode 100644 dev/zka/src/CxxAbi-AMD64.cxx create mode 100644 dev/zka/src/CxxAbi-ARM64.cc delete mode 100644 dev/zka/src/CxxAbi-ARM64.cxx create mode 100644 dev/zka/src/Defines.cc delete mode 100644 dev/zka/src/Defines.cxx create mode 100644 dev/zka/src/DeviceMgr.cc delete mode 100644 dev/zka/src/DeviceMgr.cxx create mode 100644 dev/zka/src/DriveMgr.cc delete mode 100644 dev/zka/src/DriveMgr.cxx create mode 100644 dev/zka/src/ErrorOr.cc delete mode 100644 dev/zka/src/ErrorOr.cxx create mode 100644 dev/zka/src/FS/HPFS.cc delete mode 100644 dev/zka/src/FS/HPFS.cxx create mode 100644 dev/zka/src/FS/NeFS.cc delete mode 100644 dev/zka/src/FS/NeFS.cxx create mode 100644 dev/zka/src/FileMgr.cc delete mode 100644 dev/zka/src/FileMgr.cxx create mode 100644 dev/zka/src/GUIDWizard.cc delete mode 100644 dev/zka/src/GUIDWizard.cxx create mode 100644 dev/zka/src/GUIDWrapper.cc delete mode 100644 dev/zka/src/GUIDWrapper.cxx create mode 100644 dev/zka/src/HardwareThreadScheduler.cc delete mode 100644 dev/zka/src/HardwareThreadScheduler.cxx create mode 100644 dev/zka/src/Heap.cc delete mode 100644 dev/zka/src/Heap.cxx create mode 100644 dev/zka/src/IDLLObject.cc delete mode 100644 dev/zka/src/IDLLObject.cxx create mode 100644 dev/zka/src/IPEFDLLObject.cc delete mode 100644 dev/zka/src/IPEFDLLObject.cxx create mode 100644 dev/zka/src/IndexableProperty.cc delete mode 100644 dev/zka/src/IndexableProperty.cxx create mode 100644 dev/zka/src/Json.cc delete mode 100644 dev/zka/src/Json.cxx create mode 100644 dev/zka/src/LPC.cc delete mode 100644 dev/zka/src/LPC.cxx create mode 100644 dev/zka/src/LockDelegate.cc delete mode 100644 dev/zka/src/LockDelegate.cxx create mode 100644 dev/zka/src/MutableArray.cc delete mode 100644 dev/zka/src/MutableArray.cxx create mode 100644 dev/zka/src/NeFS+FileMgr.cc delete mode 100644 dev/zka/src/NeFS+FileMgr.cxx create mode 100644 dev/zka/src/NeFS+IO.cc delete mode 100644 dev/zka/src/NeFS+IO.cxx create mode 100644 dev/zka/src/Network/IP.cc delete mode 100644 dev/zka/src/Network/IP.cxx create mode 100644 dev/zka/src/Network/IPC.cc delete mode 100644 dev/zka/src/Network/IPC.cxx create mode 100644 dev/zka/src/Network/NetworkDevice.cc delete mode 100644 dev/zka/src/Network/NetworkDevice.cxx create mode 100644 dev/zka/src/New+Delete.cc delete mode 100644 dev/zka/src/New+Delete.cxx create mode 100644 dev/zka/src/OwnPtr.cc delete mode 100644 dev/zka/src/OwnPtr.cxx create mode 100644 dev/zka/src/PEFCodeMgr.cc delete mode 100644 dev/zka/src/PEFCodeMgr.cxx create mode 100644 dev/zka/src/PRDT.cc delete mode 100644 dev/zka/src/PRDT.cxx create mode 100644 dev/zka/src/PageMgr.cc delete mode 100644 dev/zka/src/PageMgr.cxx create mode 100644 dev/zka/src/Pmm.cc delete mode 100644 dev/zka/src/Pmm.cxx create mode 100644 dev/zka/src/Property.cc delete mode 100644 dev/zka/src/Property.cxx create mode 100644 dev/zka/src/Ref.cc delete mode 100644 dev/zka/src/Ref.cxx create mode 100644 dev/zka/src/Semaphore.cc delete mode 100644 dev/zka/src/Semaphore.cxx create mode 100644 dev/zka/src/Stop.cc delete mode 100644 dev/zka/src/Stop.cxx create mode 100644 dev/zka/src/Storage/AHCIDeviceInterface.cc delete mode 100644 dev/zka/src/Storage/AHCIDeviceInterface.cxx create mode 100644 dev/zka/src/Storage/ATADeviceInterface.cc delete mode 100644 dev/zka/src/Storage/ATADeviceInterface.cxx create mode 100644 dev/zka/src/Storage/NVMEDeviceInterface.cc delete mode 100644 dev/zka/src/Storage/NVMEDeviceInterface.cxx create mode 100644 dev/zka/src/Storage/SCSIDeviceInterface.cc delete mode 100644 dev/zka/src/Storage/SCSIDeviceInterface.cxx create mode 100644 dev/zka/src/Stream.cc delete mode 100644 dev/zka/src/Stream.cxx create mode 100644 dev/zka/src/String.cc delete mode 100644 dev/zka/src/String.cxx create mode 100644 dev/zka/src/ThreadLocalStorage.cc delete mode 100644 dev/zka/src/ThreadLocalStorage.cxx create mode 100644 dev/zka/src/Timer.cc delete mode 100644 dev/zka/src/Timer.cxx create mode 100644 dev/zka/src/User.cc delete mode 100644 dev/zka/src/User.cxx create mode 100644 dev/zka/src/UserProcessScheduler.cc delete mode 100644 dev/zka/src/UserProcessScheduler.cxx create mode 100644 dev/zka/src/UserProcessTeam.cc delete mode 100644 dev/zka/src/UserProcessTeam.cxx create mode 100644 dev/zka/src/Utils.cc delete mode 100644 dev/zka/src/Utils.cxx create mode 100644 dev/zka/src/Variant.cc delete mode 100644 dev/zka/src/Variant.cxx (limited to 'dev/zka/src') diff --git a/dev/zka/src/ACPIFactoryInterface.cc b/dev/zka/src/ACPIFactoryInterface.cc new file mode 100644 index 00000000..c7d2914f --- /dev/null +++ b/dev/zka/src/ACPIFactoryInterface.cc @@ -0,0 +1,95 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include +#include + +namespace Kernel +{ + /// @brief Finds a descriptor table inside ACPI XSDT. + ErrorOr ACPIFactoryInterface::Find(const Char* signature) + { + MUST_PASS(fRsdp); + + if (!signature) + return ErrorOr{-1}; + + if (*signature == 0) + return ErrorOr{-1}; + + RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); + + if (rsp_ptr->Revision <= 1) + return ErrorOr{-1}; + + RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); + + Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt32); + + /*** + crucial to avoid - overflows. + */ + if (num < 1) + { + /// stop here, we should have entries... + ke_stop(RUNTIME_CHECK_ACPI); + return ErrorOr{-1}; + } + + this->fEntries = num; + + kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl; + kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl; + kcout << "ACPI: Signature: " << xsdt->Signature << endl; + kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl; + + const short cAcpiSignatureLength = 4; + + for (Size index = 0; index < this->fEntries; ++index) + { + SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); + + kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl; + kcout << "ACPI: Revision: " << number(sdt->Revision) << endl; + + for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) + { + if (sdt->Signature[signature_index] != signature[signature_index]) + break; + + if (signature_index == (cAcpiSignatureLength - 1)) + { + kcout << "ACPI: Found the SDT" << endl; + return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); + } + } + } + + return ErrorOr{-1}; + } + + /*** + @brief check SDT header + @param checksum the header to checksum + @param len the length of it. +*/ + bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) + { + if (len == 0) + return -1; + + char chr = 0; + + for (int index = 0; index < len; ++index) + { + chr += checksum[index]; + } + + return chr == 0; + } +} // namespace Kernel diff --git a/dev/zka/src/ACPIFactoryInterface.cxx b/dev/zka/src/ACPIFactoryInterface.cxx deleted file mode 100644 index 4a04d7b9..00000000 --- a/dev/zka/src/ACPIFactoryInterface.cxx +++ /dev/null @@ -1,95 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include -#include - -namespace Kernel -{ - /// @brief Finds a descriptor table inside ACPI XSDT. - ErrorOr ACPIFactoryInterface::Find(const Char* signature) - { - MUST_PASS(fRsdp); - - if (!signature) - return ErrorOr{-1}; - - if (*signature == 0) - return ErrorOr{-1}; - - RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - - if (rsp_ptr->Revision <= 1) - return ErrorOr{-1}; - - RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); - - Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt32); - - /*** - crucial to avoid - overflows. - */ - if (num < 1) - { - /// stop here, we should have entries... - ke_stop(RUNTIME_CHECK_ACPI); - return ErrorOr{-1}; - } - - this->fEntries = num; - - kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl; - kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl; - kcout << "ACPI: Signature: " << xsdt->Signature << endl; - kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl; - - const short cAcpiSignatureLength = 4; - - for (Size index = 0; index < this->fEntries; ++index) - { - SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); - - kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl; - kcout << "ACPI: Revision: " << number(sdt->Revision) << endl; - - for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) - { - if (sdt->Signature[signature_index] != signature[signature_index]) - break; - - if (signature_index == (cAcpiSignatureLength - 1)) - { - kcout << "ACPI: Found the SDT" << endl; - return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); - } - } - } - - return ErrorOr{-1}; - } - - /*** - @brief check SDT header - @param checksum the header to checksum - @param len the length of it. -*/ - bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) - { - if (len == 0) - return -1; - - char chr = 0; - - for (int index = 0; index < len; ++index) - { - chr += checksum[index]; - } - - return chr == 0; - } -} // namespace Kernel diff --git a/dev/zka/src/Array.cc b/dev/zka/src/Array.cc new file mode 100644 index 00000000..0bf62d59 --- /dev/null +++ b/dev/zka/src/Array.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/Array.cxx b/dev/zka/src/Array.cxx deleted file mode 100644 index 437cb11b..00000000 --- a/dev/zka/src/Array.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/ArrayList.cc b/dev/zka/src/ArrayList.cc new file mode 100644 index 00000000..6de794be --- /dev/null +++ b/dev/zka/src/ArrayList.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/ArrayList.cxx b/dev/zka/src/ArrayList.cxx deleted file mode 100644 index 27fae68c..00000000 --- a/dev/zka/src/ArrayList.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/Atom.cc b/dev/zka/src/Atom.cc new file mode 100644 index 00000000..20114b7c --- /dev/null +++ b/dev/zka/src/Atom.cc @@ -0,0 +1,10 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +// @file Atom.cpp +// @brief Atomic primitives diff --git a/dev/zka/src/Atom.cxx b/dev/zka/src/Atom.cxx deleted file mode 100644 index bfacfe83..00000000 --- a/dev/zka/src/Atom.cxx +++ /dev/null @@ -1,10 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -// @file Atom.cpp -// @brief Atomic primitives diff --git a/dev/zka/src/BitMapMgr.cc b/dev/zka/src/BitMapMgr.cc new file mode 100644 index 00000000..e97c9bfa --- /dev/null +++ b/dev/zka/src/BitMapMgr.cc @@ -0,0 +1,203 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +#define kBitMapMagic (0x10210) + +#ifdef __ZKA_AMD64__ +#include +#elif defined(__ZKA_ARM64__) +#include +#endif + +#include +#include + +#define cBitMapMagIdx (0) +#define cBitMapSizeIdx (1) +#define cBitMapUsedIdx (2) + +namespace Kernel +{ + namespace HAL + { + namespace Detail + { + /// \brief Proxy Interface to allocate a bitmap. + class IBitMapAllocator final + { + public: + explicit IBitMapAllocator() = default; + ~IBitMapAllocator() = default; + + ZKA_COPY_DELETE(IBitMapAllocator); + + auto IsBitMap(VoidPtr page_ptr) -> Bool + { + if (!page_ptr) + return No; + + UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); + + if (!ptr_bit_set[cBitMapMagIdx] || + ptr_bit_set[cBitMapMagIdx] != kBitMapMagic) + return No; + + return Yes; + } + + auto FreeBitMap(VoidPtr page_ptr) -> Bool + { + if (this->IsBitMap(page_ptr) == No) + return No; + + UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); + + ptr_bit_set[cBitMapMagIdx] = kBitMapMagic; + ptr_bit_set[cBitMapUsedIdx] = No; + + this->GetBitMapStatus(ptr_bit_set); + + mm_map_page(ptr_bit_set, ~eFlagsPresent); + mm_map_page(ptr_bit_set, ~eFlagsWr); + mm_map_page(ptr_bit_set, ~eFlagsUser); + + return Yes; + } + + UInt32 MakeFlags(Bool wr, Bool user) + { + + UInt32 flags = eFlagsPresent; + + if (wr) + flags |= eFlagsWr; + + if (user) + flags |= eFlagsUser; + + return flags; + } + + /// @brief Iterate over availables pages for a free one. + /// @return The new address which was found. + auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr + { + VoidPtr base = reinterpret_cast(((UIntPtr)base_ptr) + kPageSize); + + while (base && size) + { + UIntPtr* ptr_bit_set = reinterpret_cast(base); + + if (ptr_bit_set[cBitMapMagIdx] == kBitMapMagic && + ptr_bit_set[cBitMapSizeIdx] <= size) + { + if (ptr_bit_set[cBitMapUsedIdx] == No) + { + ptr_bit_set[cBitMapSizeIdx] = size; + ptr_bit_set[cBitMapUsedIdx] = Yes; + + this->GetBitMapStatus(ptr_bit_set); + + UInt32 flags = this->MakeFlags(wr, user); + mm_map_page(ptr_bit_set, flags); + + return (VoidPtr)ptr_bit_set; + } + } + else if (ptr_bit_set[cBitMapMagIdx] != kBitMapMagic) + { + UIntPtr* ptr_bit_set = reinterpret_cast(base_ptr); + + ptr_bit_set[cBitMapMagIdx] = kBitMapMagic; + ptr_bit_set[cBitMapSizeIdx] = size; + ptr_bit_set[cBitMapUsedIdx] = Yes; + + this->GetBitMapStatus(ptr_bit_set); + + UInt32 flags = this->MakeFlags(wr, user); + mm_map_page(ptr_bit_set, flags); + + return (VoidPtr)ptr_bit_set; + } + + base = reinterpret_cast(reinterpret_cast(base_ptr) + (ptr_bit_set[0] != kBitMapMagic ? size : ptr_bit_set[1])); + + if ((UIntPtr)base_ptr < (reinterpret_cast(base) + kHandoverHeader->f_BitMapSize)) + return nullptr; + } + + return nullptr; + } + + /// @brief Print Bitmap status + auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void + { + if (!this->IsBitMap(ptr_bit_set)) + { + kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; + return; + } + + kcout << "Magic Number: " << hex_number(ptr_bit_set[cBitMapMagIdx]) << endl; + kcout << "Is Allocated: " << (ptr_bit_set[cBitMapUsedIdx] ? "Yes" : "No") << endl; + kcout << "Size of BitMap (B): " << number(ptr_bit_set[cBitMapSizeIdx]) << endl; + kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[cBitMapSizeIdx])) << endl; + kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[cBitMapSizeIdx])) << endl; + kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[cBitMapSizeIdx])) << endl; + kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[cBitMapSizeIdx])) << endl; + kcout << "Address Of BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; + } + }; + } // namespace Detail + + /// @brief Allocate a new page to be used by the OS. + /// @param wr read/write bit. + /// @param user user bit. + /// @return a new bitmap allocated pointer. + auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr + { + VoidPtr ptr_new = nullptr; + Detail::IBitMapAllocator traits; + + ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user); + + if (!ptr_new) + { + return nullptr; + } + + if (wr) + mm_map_page(ptr_new, eFlagsWr | eFlagsPresent); + else if (user && wr) + mm_map_page(ptr_new, eFlagsUser | eFlagsWr | eFlagsPresent); + else if (user) + mm_map_page(ptr_new, eFlagsUser | eFlagsPresent); + else + mm_map_page(ptr_new, eFlagsPresent); + + return (UIntPtr*)ptr_new; + } + + /// @brief Free Bitmap, and mark it a absent in page terms. + auto mm_free_bitmap(VoidPtr page_ptr) -> Bool + { + if (!page_ptr) + return No; + + Detail::IBitMapAllocator traits; + Bool ret = traits.FreeBitMap(page_ptr); + + if (ret) + { + mm_map_page(page_ptr, ~eFlagsPresent); + } + + return ret; + } + } // namespace HAL +} // namespace Kernel diff --git a/dev/zka/src/BitMapMgr.cxx b/dev/zka/src/BitMapMgr.cxx deleted file mode 100644 index 1f4b4860..00000000 --- a/dev/zka/src/BitMapMgr.cxx +++ /dev/null @@ -1,203 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -#define kBitMapMagic (0x10210) - -#ifdef __ZKA_AMD64__ -#include -#elif defined(__ZKA_ARM64__) -#include -#endif - -#include -#include - -#define cBitMapMagIdx (0) -#define cBitMapSizeIdx (1) -#define cBitMapUsedIdx (2) - -namespace Kernel -{ - namespace HAL - { - namespace Detail - { - /// \brief Proxy Interface to allocate a bitmap. - class IBitMapAllocator final - { - public: - explicit IBitMapAllocator() = default; - ~IBitMapAllocator() = default; - - ZKA_COPY_DELETE(IBitMapAllocator); - - auto IsBitMap(VoidPtr page_ptr) -> Bool - { - if (!page_ptr) - return No; - - UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); - - if (!ptr_bit_set[cBitMapMagIdx] || - ptr_bit_set[cBitMapMagIdx] != kBitMapMagic) - return No; - - return Yes; - } - - auto FreeBitMap(VoidPtr page_ptr) -> Bool - { - if (this->IsBitMap(page_ptr) == No) - return No; - - UIntPtr* ptr_bit_set = reinterpret_cast(page_ptr); - - ptr_bit_set[cBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[cBitMapUsedIdx] = No; - - this->GetBitMapStatus(ptr_bit_set); - - mm_map_page(ptr_bit_set, ~eFlagsPresent); - mm_map_page(ptr_bit_set, ~eFlagsWr); - mm_map_page(ptr_bit_set, ~eFlagsUser); - - return Yes; - } - - UInt32 MakeFlags(Bool wr, Bool user) - { - - UInt32 flags = eFlagsPresent; - - if (wr) - flags |= eFlagsWr; - - if (user) - flags |= eFlagsUser; - - return flags; - } - - /// @brief Iterate over availables pages for a free one. - /// @return The new address which was found. - auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr - { - VoidPtr base = reinterpret_cast(((UIntPtr)base_ptr) + kPageSize); - - while (base && size) - { - UIntPtr* ptr_bit_set = reinterpret_cast(base); - - if (ptr_bit_set[cBitMapMagIdx] == kBitMapMagic && - ptr_bit_set[cBitMapSizeIdx] <= size) - { - if (ptr_bit_set[cBitMapUsedIdx] == No) - { - ptr_bit_set[cBitMapSizeIdx] = size; - ptr_bit_set[cBitMapUsedIdx] = Yes; - - this->GetBitMapStatus(ptr_bit_set); - - UInt32 flags = this->MakeFlags(wr, user); - mm_map_page(ptr_bit_set, flags); - - return (VoidPtr)ptr_bit_set; - } - } - else if (ptr_bit_set[cBitMapMagIdx] != kBitMapMagic) - { - UIntPtr* ptr_bit_set = reinterpret_cast(base_ptr); - - ptr_bit_set[cBitMapMagIdx] = kBitMapMagic; - ptr_bit_set[cBitMapSizeIdx] = size; - ptr_bit_set[cBitMapUsedIdx] = Yes; - - this->GetBitMapStatus(ptr_bit_set); - - UInt32 flags = this->MakeFlags(wr, user); - mm_map_page(ptr_bit_set, flags); - - return (VoidPtr)ptr_bit_set; - } - - base = reinterpret_cast(reinterpret_cast(base_ptr) + (ptr_bit_set[0] != kBitMapMagic ? size : ptr_bit_set[1])); - - if ((UIntPtr)base_ptr < (reinterpret_cast(base) + kHandoverHeader->f_BitMapSize)) - return nullptr; - } - - return nullptr; - } - - /// @brief Print Bitmap status - auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void - { - if (!this->IsBitMap(ptr_bit_set)) - { - kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; - return; - } - - kcout << "Magic Number: " << hex_number(ptr_bit_set[cBitMapMagIdx]) << endl; - kcout << "Is Allocated: " << (ptr_bit_set[cBitMapUsedIdx] ? "Yes" : "No") << endl; - kcout << "Size of BitMap (B): " << number(ptr_bit_set[cBitMapSizeIdx]) << endl; - kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[cBitMapSizeIdx])) << endl; - kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[cBitMapSizeIdx])) << endl; - kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[cBitMapSizeIdx])) << endl; - kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[cBitMapSizeIdx])) << endl; - kcout << "Address Of BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl; - } - }; - } // namespace Detail - - /// @brief Allocate a new page to be used by the OS. - /// @param wr read/write bit. - /// @param user user bit. - /// @return a new bitmap allocated pointer. - auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr - { - VoidPtr ptr_new = nullptr; - Detail::IBitMapAllocator traits; - - ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user); - - if (!ptr_new) - { - return nullptr; - } - - if (wr) - mm_map_page(ptr_new, eFlagsWr | eFlagsPresent); - else if (user && wr) - mm_map_page(ptr_new, eFlagsUser | eFlagsWr | eFlagsPresent); - else if (user) - mm_map_page(ptr_new, eFlagsUser | eFlagsPresent); - else - mm_map_page(ptr_new, eFlagsPresent); - - return (UIntPtr*)ptr_new; - } - - /// @brief Free Bitmap, and mark it a absent in page terms. - auto mm_free_bitmap(VoidPtr page_ptr) -> Bool - { - if (!page_ptr) - return No; - - Detail::IBitMapAllocator traits; - Bool ret = traits.FreeBitMap(page_ptr); - - if (ret) - { - mm_map_page(page_ptr, ~eFlagsPresent); - } - - return ret; - } - } // namespace HAL -} // namespace Kernel diff --git a/dev/zka/src/CRuntime.cc b/dev/zka/src/CRuntime.cc new file mode 100644 index 00000000..4a1de1d7 --- /dev/null +++ b/dev/zka/src/CRuntime.cc @@ -0,0 +1,69 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +/// @brief memset definition in C++. +/// @param dst destination pointer. +/// @param byte value to fill in. +/// @param len length of of src. +EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) +{ + for (size_t i = 0UL; i < len; ++i) + { + ((int*)dst)[i] = byte; + } + + return dst; +} + +/// @brief memcpy definition in C++. +/// @param dst destination pointer. +/// @param src source pointer. +/// @param len length of of src. +EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) +{ + for (size_t i = 0UL; i < len; ++i) + { + ((int*)dst)[i] = ((int*)src)[i]; + } + + return dst; +} + +/// @brief strlen definition in C++. +EXTERN_C size_t strlen(const char* whatToCheck) +{ + SizeT len = 0; + + while (whatToCheck[len] != 0) + { + ++len; + } + + return len; +} + +/// @brief strcmp definition in C++. +EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) +{ + if (!whatToCheck || *whatToCheck == 0) + return 0; + + SizeT len = 0; + + while (whatToCheck[len] == whatToCheckRight[len]) + { + if (whatToCheck[len] == 0) + return 0; + + ++len; + } + + return len; +} diff --git a/dev/zka/src/CRuntime.cxx b/dev/zka/src/CRuntime.cxx deleted file mode 100644 index 75646bbe..00000000 --- a/dev/zka/src/CRuntime.cxx +++ /dev/null @@ -1,69 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -using namespace Kernel; - -/// @brief memset definition in C++. -/// @param dst destination pointer. -/// @param byte value to fill in. -/// @param len length of of src. -EXTERN_C VoidPtr memset(void* dst, int byte, long long unsigned int len) -{ - for (size_t i = 0UL; i < len; ++i) - { - ((int*)dst)[i] = byte; - } - - return dst; -} - -/// @brief memcpy definition in C++. -/// @param dst destination pointer. -/// @param src source pointer. -/// @param len length of of src. -EXTERN_C VoidPtr memcpy(void* dst, const void* src, long long unsigned int len) -{ - for (size_t i = 0UL; i < len; ++i) - { - ((int*)dst)[i] = ((int*)src)[i]; - } - - return dst; -} - -/// @brief strlen definition in C++. -EXTERN_C size_t strlen(const char* whatToCheck) -{ - SizeT len = 0; - - while (whatToCheck[len] != 0) - { - ++len; - } - - return len; -} - -/// @brief strcmp definition in C++. -EXTERN_C int strcmp(const char* whatToCheck, const char* whatToCheckRight) -{ - if (!whatToCheck || *whatToCheck == 0) - return 0; - - SizeT len = 0; - - while (whatToCheck[len] == whatToCheckRight[len]) - { - if (whatToCheck[len] == 0) - return 0; - - ++len; - } - - return len; -} diff --git a/dev/zka/src/CodeMgr.cc b/dev/zka/src/CodeMgr.cc new file mode 100644 index 00000000..130f8cfe --- /dev/null +++ b/dev/zka/src/CodeMgr.cc @@ -0,0 +1,33 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include + +namespace Kernel +{ + /// @brief Executes a new process from a function. Kernel code only. + /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. + /// @param main the start of the process. + /// @return if the process was started or not. + Bool sched_execute_thread(MainKind main, const Char* process_name) noexcept + { + if (!main) + return No; + + UserProcess proc; + proc.SetImageStart(reinterpret_cast(main)); + + proc.Kind = UserProcess::kExectuableKind; + proc.StackSize = kib_cast(32); + + rt_set_memory(proc.Name, 0, kProcessLen); + rt_copy_memory((VoidPtr)process_name, proc.Name, rt_string_len(process_name)); + + return UserProcessScheduler::The().Add(proc) > 0; + } +} // namespace Kernel diff --git a/dev/zka/src/CodeMgr.cxx b/dev/zka/src/CodeMgr.cxx deleted file mode 100644 index 2e0308f3..00000000 --- a/dev/zka/src/CodeMgr.cxx +++ /dev/null @@ -1,33 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include - -namespace Kernel -{ - /// @brief Executes a new process from a function. Kernel code only. - /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible. - /// @param main the start of the process. - /// @return if the process was started or not. - Bool sched_execute_thread(MainKind main, const Char* process_name) noexcept - { - if (!main) - return No; - - UserProcess proc; - proc.SetImageStart(reinterpret_cast(main)); - - proc.Kind = UserProcess::kExectuableKind; - proc.StackSize = kib_cast(32); - - rt_set_memory(proc.Name, 0, kProcessLen); - rt_copy_memory((VoidPtr)process_name, proc.Name, rt_string_len(process_name)); - - return UserProcessScheduler::The().Add(proc) > 0; - } -} // namespace Kernel diff --git a/dev/zka/src/Crc32.cc b/dev/zka/src/Crc32.cc new file mode 100644 index 00000000..bcf04c03 --- /dev/null +++ b/dev/zka/src/Crc32.cc @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +// @file CRC32.cpp +// @brief Check sequence implementation. + +namespace Kernel +{ + /// @brief The CRC32 seed table. + UInt32 kCrcTbl[kCrcCnt] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, + 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, + 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, + 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, + 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, + 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, + 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, + 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, + 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, + 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, + 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, + 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, + 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, + 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, + 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, + 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, + 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, + 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, + 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, + 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, + 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, + 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, + 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, + 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, + 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, + 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, + 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, + 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, + 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, + 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, + 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, + 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, + 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, + 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, + 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, + 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, + 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, + 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, + 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, + 0xAD7D5351L}; + + /// @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 Kernel diff --git a/dev/zka/src/Crc32.cxx b/dev/zka/src/Crc32.cxx deleted file mode 100644 index 4faa78f9..00000000 --- a/dev/zka/src/Crc32.cxx +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -// @file CRC32.cpp -// @brief Check sequence implementation. - -namespace Kernel -{ - /// @brief The CRC32 seed table. - UInt32 kCrcTbl[kCrcCnt] = { - 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, - 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, - 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, - 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, - 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, - 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, - 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, - 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, - 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, - 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, - 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, - 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, - 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, - 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, - 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, - 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, - 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, - 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, - 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, - 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, - 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, - 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, - 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, - 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, - 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, - 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, - 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, - 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, - 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, - 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, - 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, - 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, - 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, - 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, - 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, - 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, - 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, - 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, - 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, - 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, - 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, - 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, - 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, - 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, - 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, - 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, - 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, - 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, - 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, - 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, - 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, - 0xAD7D5351L}; - - /// @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 Kernel diff --git a/dev/zka/src/CxxAbi-AMD64.cc b/dev/zka/src/CxxAbi-AMD64.cc new file mode 100644 index 00000000..9d439d6b --- /dev/null +++ b/dev/zka/src/CxxAbi-AMD64.cc @@ -0,0 +1,90 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#ifdef __ZKA_AMD64__ + +#include +#include +#include + +atexit_func_entry_t __atexit_funcs[kDSOMaxObjects]; + +uarch_t __atexit_func_count; + +/// @brief Dynamic Shared Object Handle. +Kernel::UIntPtr __dso_handle; + +EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) +{ + kcout << "object: " << Kernel::number(reinterpret_cast(self)); + kcout << ", has unimplemented virtual functions.\r"; +} + +EXTERN_C void ___chkstk_ms(void) +{ +} + +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 + +#endif // ifdef __ZKA_AMD64__ diff --git a/dev/zka/src/CxxAbi-AMD64.cxx b/dev/zka/src/CxxAbi-AMD64.cxx deleted file mode 100644 index 32e3ff37..00000000 --- a/dev/zka/src/CxxAbi-AMD64.cxx +++ /dev/null @@ -1,90 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#ifdef __ZKA_AMD64__ - -#include -#include -#include - -atexit_func_entry_t __atexit_funcs[kDSOMaxObjects]; - -uarch_t __atexit_func_count; - -/// @brief Dynamic Shared Object Handle. -Kernel::UIntPtr __dso_handle; - -EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) -{ - kcout << "object: " << Kernel::number(reinterpret_cast(self)); - kcout << ", has unimplemented virtual functions.\r"; -} - -EXTERN_C void ___chkstk_ms(void) -{ -} - -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 - -#endif // ifdef __ZKA_AMD64__ diff --git a/dev/zka/src/CxxAbi-ARM64.cc b/dev/zka/src/CxxAbi-ARM64.cc new file mode 100644 index 00000000..f603f863 --- /dev/null +++ b/dev/zka/src/CxxAbi-ARM64.cc @@ -0,0 +1,90 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#ifdef __ZKA_ARM64__ + +#include +#include +#include + +atexit_func_entry_t __atexit_funcs[kDSOMaxObjects]; + +uarch_t __atexit_func_count; + +/// @brief Dynamic Shared Object Handle. +Kernel::UIntPtr __dso_handle; + +EXTERN_C void __chkstk(void) +{ +} + +EXTERN_C int atexit(void (*f)(void*), 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 + +EXTERN_C Kernel::Void _purecall(void* self) +{ + kcout << "object: " << Kernel::number(reinterpret_cast(self)); + kcout << ", has unimplemented virtual functions.\r"; +} + +#endif // ifdef __ZKA_ARM64__ diff --git a/dev/zka/src/CxxAbi-ARM64.cxx b/dev/zka/src/CxxAbi-ARM64.cxx deleted file mode 100644 index 759c2a7f..00000000 --- a/dev/zka/src/CxxAbi-ARM64.cxx +++ /dev/null @@ -1,90 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#ifdef __ZKA_ARM64__ - -#include -#include -#include - -atexit_func_entry_t __atexit_funcs[kDSOMaxObjects]; - -uarch_t __atexit_func_count; - -/// @brief Dynamic Shared Object Handle. -Kernel::UIntPtr __dso_handle; - -EXTERN_C void __chkstk(void) -{ -} - -EXTERN_C int atexit(void (*f)(void*), 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 - -EXTERN_C Kernel::Void _purecall(void* self) -{ - kcout << "object: " << Kernel::number(reinterpret_cast(self)); - kcout << ", has unimplemented virtual functions.\r"; -} - -#endif // ifdef __ZKA_ARM64__ diff --git a/dev/zka/src/Defines.cc b/dev/zka/src/Defines.cc new file mode 100644 index 00000000..d5ce58ce --- /dev/null +++ b/dev/zka/src/Defines.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/Defines.cxx b/dev/zka/src/Defines.cxx deleted file mode 100644 index fc7d41b5..00000000 --- a/dev/zka/src/Defines.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/DeviceMgr.cc b/dev/zka/src/DeviceMgr.cc new file mode 100644 index 00000000..78058a17 --- /dev/null +++ b/dev/zka/src/DeviceMgr.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/DeviceMgr.cxx b/dev/zka/src/DeviceMgr.cxx deleted file mode 100644 index 1bd775ab..00000000 --- a/dev/zka/src/DeviceMgr.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/DriveMgr.cc b/dev/zka/src/DriveMgr.cc new file mode 100644 index 00000000..9f5201d9 --- /dev/null +++ b/dev/zka/src/DriveMgr.cc @@ -0,0 +1,167 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include + +#include +#include +#include + +/***********************************************************************************/ +/// @file DriveMgr.cxx +/// @brief Drive Manager API. +/***********************************************************************************/ + +namespace Kernel +{ + STATIC UInt16 kATAIO = 0U; + STATIC UInt8 kATAMaster = 0U; + + /// @brief reads from an ATA drive. + /// @param pckt Packet structure (fPacketContent must be non null) + /// @return + Void io_drv_input(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + +#ifdef __AHCI__ + drv_std_read(pckt->fLba, (Char*)pckt->fPacketContent.Leak(), kAHCISectorSize, pckt->fPacketSize); +#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) + drv_std_read(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent.Leak(), kATASectorSize, pckt->fPacketSize); +#endif + } + + /// @brief Writes to an ATA drive. + /// @param pckt the packet to write. + /// @return + Void io_drv_output(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + +#ifdef __AHCI__ + drv_std_write(pckt->fLba, (Char*)pckt->fPacketContent.Leak(), kAHCISectorSize, pckt->fPacketSize); +#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) + drv_std_write(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent.Leak(), kATASectorSize, pckt->fPacketSize); +#endif + } + + /// @brief Executes a disk check on the ATA drive. + /// @param pckt the packet to read. + /// @return + Void io_drv_init(DriveTrait::DrivePacket* pckt) + { + if (!pckt) + { + return; + } + + pckt->fPacketGood = false; + +#if defined(__ATA_PIO__) || defined(__ATA_DMA__) + kATAMaster = true; + kATAIO = ATA_PRIMARY_IO; + + if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) + return; + +#elif defined(__AHCI__) + UInt16 pi = 0; + + if (!drv_std_init(pi)) + return; +#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) + + pckt->fPacketGood = true; + } + +/// @brief Gets the drive kind (ATA, SCSI, AHCI...) +/// @param no arguments. +/// @return no arguments. +#ifdef __ATA_PIO__ + const Char* io_drv_kind(Void) + { + return "ATA-PIO"; + } +#endif +#ifdef __ATA_DMA__ + const Char* io_drv_kind(Void) + { + return "ATA-DMA"; + } +#endif +#ifdef __AHCI__ + const Char* io_drv_kind(Void) + { + return "AHCI"; + } +#endif +#ifdef __ZKA_MINIMAL_OS__ + const Char* io_drv_kind(Void) + { + return "Not Loaded"; + } +#endif +#ifdef __ZKA_ED__ + const Char* io_drv_kind(Void) + { + return "C++ Code Editor"; + } +#endif + + /// @brief Unimplemented drive function. + /// @param pckt the packet to read. + /// @return + Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) + { + ZKA_UNUSED(pckt); + } + + /// @brief Makes a new drive. + /// @return the new blank drive. + DriveTrait io_construct_drive() noexcept + { + DriveTrait trait; + + rt_copy_memory((VoidPtr) "\\Mount\\NUL:", trait.fName, rt_string_len("\\Mount\\NUL:")); + trait.fKind = kInvalidStorage; + + trait.fInput = io_drv_unimplemented; + trait.fOutput = io_drv_unimplemented; + trait.fVerify = io_drv_unimplemented; + trait.fInit = io_drv_unimplemented; + trait.fDriveKind = io_drv_kind; + + return trait; + } + + /// @brief Fetches the main drive. + /// @return the new drive. + DriveTrait io_construct_main_drive() noexcept + { + DriveTrait trait; + + rt_copy_memory((VoidPtr) "\\Mount\\MainDisk:", trait.fName, rt_string_len("\\Mount\\MainDisk:")); + trait.fKind = kMassStorage | kEPMDrive; + + trait.fVerify = io_drv_unimplemented; + trait.fOutput = io_drv_output; + trait.fInput = io_drv_input; + trait.fInit = io_drv_init; + trait.fDriveKind = io_drv_kind; + + kcout << "Constructed drive successfully.\r"; + + return trait; + } +} // namespace Kernel diff --git a/dev/zka/src/DriveMgr.cxx b/dev/zka/src/DriveMgr.cxx deleted file mode 100644 index 4164674b..00000000 --- a/dev/zka/src/DriveMgr.cxx +++ /dev/null @@ -1,167 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include - -#include -#include -#include - -/***********************************************************************************/ -/// @file DriveMgr.cxx -/// @brief Drive Manager API. -/***********************************************************************************/ - -namespace Kernel -{ - STATIC UInt16 kATAIO = 0U; - STATIC UInt8 kATAMaster = 0U; - - /// @brief reads from an ATA drive. - /// @param pckt Packet structure (fPacketContent must be non null) - /// @return - Void io_drv_input(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - -#ifdef __AHCI__ - drv_std_read(pckt->fLba, (Char*)pckt->fPacketContent.Leak(), kAHCISectorSize, pckt->fPacketSize); -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_read(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent.Leak(), kATASectorSize, pckt->fPacketSize); -#endif - } - - /// @brief Writes to an ATA drive. - /// @param pckt the packet to write. - /// @return - Void io_drv_output(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - -#ifdef __AHCI__ - drv_std_write(pckt->fLba, (Char*)pckt->fPacketContent.Leak(), kAHCISectorSize, pckt->fPacketSize); -#elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_write(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent.Leak(), kATASectorSize, pckt->fPacketSize); -#endif - } - - /// @brief Executes a disk check on the ATA drive. - /// @param pckt the packet to read. - /// @return - Void io_drv_init(DriveTrait::DrivePacket* pckt) - { - if (!pckt) - { - return; - } - - pckt->fPacketGood = false; - -#if defined(__ATA_PIO__) || defined(__ATA_DMA__) - kATAMaster = true; - kATAIO = ATA_PRIMARY_IO; - - if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) - return; - -#elif defined(__AHCI__) - UInt16 pi = 0; - - if (!drv_std_init(pi)) - return; -#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) - - pckt->fPacketGood = true; - } - -/// @brief Gets the drive kind (ATA, SCSI, AHCI...) -/// @param no arguments. -/// @return no arguments. -#ifdef __ATA_PIO__ - const Char* io_drv_kind(Void) - { - return "ATA-PIO"; - } -#endif -#ifdef __ATA_DMA__ - const Char* io_drv_kind(Void) - { - return "ATA-DMA"; - } -#endif -#ifdef __AHCI__ - const Char* io_drv_kind(Void) - { - return "AHCI"; - } -#endif -#ifdef __ZKA_MINIMAL_OS__ - const Char* io_drv_kind(Void) - { - return "Not Loaded"; - } -#endif -#ifdef __ZKA_ED__ - const Char* io_drv_kind(Void) - { - return "C++ Code Editor"; - } -#endif - - /// @brief Unimplemented drive function. - /// @param pckt the packet to read. - /// @return - Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) - { - ZKA_UNUSED(pckt); - } - - /// @brief Makes a new drive. - /// @return the new blank drive. - DriveTrait io_construct_drive() noexcept - { - DriveTrait trait; - - rt_copy_memory((VoidPtr) "\\Mount\\NUL:", trait.fName, rt_string_len("\\Mount\\NUL:")); - trait.fKind = kInvalidStorage; - - trait.fInput = io_drv_unimplemented; - trait.fOutput = io_drv_unimplemented; - trait.fVerify = io_drv_unimplemented; - trait.fInit = io_drv_unimplemented; - trait.fDriveKind = io_drv_kind; - - return trait; - } - - /// @brief Fetches the main drive. - /// @return the new drive. - DriveTrait io_construct_main_drive() noexcept - { - DriveTrait trait; - - rt_copy_memory((VoidPtr) "\\Mount\\MainDisk:", trait.fName, rt_string_len("\\Mount\\MainDisk:")); - trait.fKind = kMassStorage | kEPMDrive; - - trait.fVerify = io_drv_unimplemented; - trait.fOutput = io_drv_output; - trait.fInput = io_drv_input; - trait.fInit = io_drv_init; - trait.fDriveKind = io_drv_kind; - - kcout << "Constructed drive successfully.\r"; - - return trait; - } -} // namespace Kernel diff --git a/dev/zka/src/ErrorOr.cc b/dev/zka/src/ErrorOr.cc new file mode 100644 index 00000000..9c10745e --- /dev/null +++ b/dev/zka/src/ErrorOr.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +/***********************************************************************************/ +/// @file ErrorOr.cxx /// +/// @brief ErrorOr container class. /// +/***********************************************************************************/ diff --git a/dev/zka/src/ErrorOr.cxx b/dev/zka/src/ErrorOr.cxx deleted file mode 100644 index 53d60a3d..00000000 --- a/dev/zka/src/ErrorOr.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -/***********************************************************************************/ -/// @file ErrorOr.cxx /// -/// @brief ErrorOr container class. /// -/***********************************************************************************/ diff --git a/dev/zka/src/FS/HPFS.cc b/dev/zka/src/FS/HPFS.cc new file mode 100644 index 00000000..0fb80079 --- /dev/null +++ b/dev/zka/src/FS/HPFS.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#ifdef __FSKIT_INCLUDES_HPFS__ + +#include +#include + +#endif // ifdef __FSKIT_INCLUDES_HPFS__ diff --git a/dev/zka/src/FS/HPFS.cxx b/dev/zka/src/FS/HPFS.cxx deleted file mode 100644 index 56760972..00000000 --- a/dev/zka/src/FS/HPFS.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#ifdef __FSKIT_INCLUDES_HPFS__ - -#include -#include - -#endif // ifdef __FSKIT_INCLUDES_HPFS__ diff --git a/dev/zka/src/FS/NeFS.cc b/dev/zka/src/FS/NeFS.cc new file mode 100644 index 00000000..6fcbb786 --- /dev/null +++ b/dev/zka/src/FS/NeFS.cc @@ -0,0 +1,1057 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#ifdef __FSKIT_USE_NEFS__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __ZKA_MINIMAL_OS__ +using namespace Kernel; + +#ifdef __ZKA_NO_BUILTIN__ +/***********************************************************************************/ +/** + Define those external symbols, to make the editor shutup +*/ +/***********************************************************************************/ + +/***********************************************************************************/ +/// @brief get sector count. +/***********************************************************************************/ +Kernel::SizeT drv_get_sector_count(); + +/***********************************************************************************/ +/// @brief get device size. +/***********************************************************************************/ +Kernel::SizeT drv_get_size(); + +#endif + +///! BUGS: 0 + +/***********************************************************************************/ +/// This file implements the New File System. +/// New File System implements a B-Tree based algortihm. +/// \\ +/// \\Path1\\ \\ath2\\ +/// \\readme.rtf \\ListContents.pef \\readme.lnk <-- symlink. +/// \\Path1\\readme.rtf +/***********************************************************************************/ + +STATIC MountpointInterface sMountpointInterface; + +/***********************************************************************************/ +/// @brief Creates a new fork inside the New filesystem partition. +/// @param catalog it's catalog +/// @param the_fork the fork itself. +/// @return the fork +/***********************************************************************************/ +_Output NFS_FORK_STRUCT* NeFSParser::CreateFork(_Input NFS_CATALOG_STRUCT* catalog, + _Input NFS_FORK_STRUCT& the_fork) +{ + if (catalog && the_fork.ForkName[0] != 0 && + the_fork.DataSize <= kNeFSForkDataSz) + { + Lba lba = (the_fork.Kind == kNeFSDataForkKind) ? catalog->DataFork + : catalog->ResourceFork; + + kcout << "fork lba: " << hex_number(lba) << endl; + + if (lba <= kNeFSCatalogStartAddress) + return nullptr; + + auto drv = sMountpointInterface.A(); + + /// special treatment. + rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + NFS_FORK_STRUCT curFork{0}; + NFS_FORK_STRUCT 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 <= kNeFSCatalogStartAddress) + break; + + drv.fPacket.fLba = lba; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &curFork; + + drv.fInput(&drv.fPacket); + + if (curFork.NextSibling > kBadAddress) + { + kcout << "bad fork: " << hex_number(curFork.NextSibling) << endl; + break; + } + + kcout << "next fork: " << hex_number(curFork.NextSibling) << endl; + + if (curFork.Flags & kNeFSFlagCreated) + { + kcout << "fork already exists.\r"; + + /// sanity check. + if (StringBuilder::Equals(curFork.ForkName, the_fork.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 >= kNeFSCatalogStartAddress) + { + drv.fPacket.fLba = lbaOfPreviousFork; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + 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. + + the_fork.Flags |= kNeFSFlagCreated; + the_fork.DataOffset = lba - sizeof(NFS_FORK_STRUCT); + the_fork.PreviousSibling = lbaOfPreviousFork; + the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize - sizeof(NFS_FORK_STRUCT); + + drv.fPacket.fLba = lba; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = &the_fork; + + drv.fOutput(&drv.fPacket); + + /// log what we have now. + kcout << "Wrote fork data at: " << hex_number(the_fork.DataOffset) + << endl; + + kcout << "Wrote fork at: " << hex_number(lba) << endl; + + return &the_fork; + } + + return nullptr; +} + +/***********************************************************************************/ +/// @brief Find fork inside New filesystem. +/// @param catalog the catalog. +/// @param name the fork name. +/// @return the fork. +/***********************************************************************************/ +_Output NFS_FORK_STRUCT* NeFSParser::FindFork(_Input NFS_CATALOG_STRUCT* catalog, + _Input const Char* name, + Boolean isDataFork) +{ + auto drv = sMountpointInterface.A(); + NFS_FORK_STRUCT* the_fork = nullptr; + + Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; + + while (lba != 0) + { + drv.fPacket.fLba = lba; + drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drv.fPacket.fPacketContent = (VoidPtr)the_fork; + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, 16); + + if (auto res = + fs_newfs_read(&sMountpointInterface, drv, this->fDriveIndex); + res) + { + switch (res) + { + case 1: + ErrLocal() = kErrorDiskReadOnly; + break; + case 2: + ErrLocal() = kErrorDiskIsFull; + break; + ErrLocal() = kErrorNoSuchDisk; + break; + + default: + break; + } + return nullptr; + } + + if (StringBuilder::Equals(the_fork->ForkName, name)) + { + break; + } + + lba = the_fork->NextSibling; + } + + return the_fork; +} + +/***********************************************************************************/ +/// @brief Simpler factory to create a catalog (assumes you want to create a +/// file.) +/// @param name +/// @return catalog pointer. +/***********************************************************************************/ +_Output NFS_CATALOG_STRUCT* NeFSParser::CreateCatalog(_Input const Char* name) +{ + return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); +} + +/***********************************************************************************/ +/// @brief Creates a new catalog into the disk. +/// @param name the catalog name. +/// @param flags the flags of the catalog. +/// @param kind the catalog kind. +/// @return catalog pointer. +/***********************************************************************************/ +_Output NFS_CATALOG_STRUCT* NeFSParser::CreateCatalog(_Input const Char* name, + _Input const Int32& flags, + _Input const Int32& kind) +{ + kcout << "CreateCatalog(...)\r"; + + Lba out_lba = 0UL; + + kcout << "Checking for extension...\r"; + + /// a directory should have a slash in the end. + if (kind == kNeFSCatalogKindDir && + name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator()) + return nullptr; + + /// a file shouldn't have a slash in the end. + if (kind != kNeFSCatalogKindDir && + name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator()) + return nullptr; + + NFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); + + if (catalog_copy) + { + kcout << "Catalog already exists: " << name << ".\r"; + ErrLocal() = kErrorFileExists; + + return catalog_copy; + } + + Char parentName[kNeFSNodeNameLen] = {0}; + + for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) + { + parentName[indexName] = name[indexName]; + } + + if (*parentName == 0) + { + kcout << "Parent name is NUL.\r"; + ErrLocal() = 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 it. + parentName[--indexReverseCopy] = 0; + + // mandatory / character, zero it. + parentName[--indexReverseCopy] = 0; + + while (parentName[indexReverseCopy] != NeFileSystemHelper::Separator()) + { + parentName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NFS_CATALOG_STRUCT* catalog = this->FindCatalog(parentName, out_lba); + + auto drive = sMountpointInterface.A(); + + if (catalog && catalog->Kind == kNeFSCatalogKindFile) + { + kcout << "Parent name is file.\r"; + delete catalog; + return nullptr; + } + else if (!catalog) + { + Char sectorBufPartBlock[kNeFSSectorSz] = {0}; + + drive.fPacket.fPacketContent = sectorBufPartBlock; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + constexpr auto cNeFSCatalogPadding = 4; + + NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; + out_lba = part_block->StartCatalog; + } + + constexpr SizeT cDefaultForkSize = kNeFSForkSize; + + NFS_CATALOG_STRUCT* child_catalog = new NFS_CATALOG_STRUCT(); + + Int32 flagsList = flags; + + child_catalog->ResourceForkSize = cDefaultForkSize; + child_catalog->DataForkSize = cDefaultForkSize; + + child_catalog->NextSibling = out_lba; + child_catalog->PrevSibling = out_lba; + child_catalog->Kind = kind; + child_catalog->Flags = kNeFSFlagCreated | flagsList; + + rt_copy_memory((VoidPtr)name, (VoidPtr)child_catalog->Name, + rt_string_len(name)); + + NFS_CATALOG_STRUCT temporary_catalog; + + Lba start_free = out_lba; + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fLba = start_free; + + drive.fInput(&drive.fPacket); + + NFS_CATALOG_STRUCT* next_sibling = reinterpret_cast(&temporary_catalog); + + start_free = next_sibling->NextSibling; + + child_catalog->PrevSibling = out_lba; + + drive.fPacket.fLba = start_free; + drive.fInput(&drive.fPacket); + + while (drive.fPacket.fPacketGood) + { + next_sibling = reinterpret_cast(&temporary_catalog); + + if (start_free <= kNeFSRootCatalogStartAddress) + { + delete child_catalog; + delete catalog; + + return nullptr; + } + + // ========================== // + // Allocate catalog now... + // ========================== // + if ((next_sibling->Flags & kNeFSFlagCreated) == 0) + { + Char sectorBufPartBlock[kNeFSSectorSz] = {0}; + + drive.fPacket.fPacketContent = sectorBufPartBlock; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + constexpr auto cNeFSCatalogPadding = 4; + + NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; + + if (part_block->FreeCatalog < 1) + { + delete child_catalog; + return nullptr; + } + + child_catalog->DataFork = part_block->DiskSize - start_free; + child_catalog->ResourceFork = child_catalog->DataFork; + + // Write the new catalog next sibling, if we don't know this parent. // + // This is necessary, so that we don't have to get another lba to allocate. // + if (!StringBuilder::Equals(parentName, next_sibling->Name)) + { + child_catalog->NextSibling = + start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); + } + + drive.fPacket.fPacketContent = child_catalog; + drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); + drive.fPacket.fLba = start_free; + + drive.fOutput(&drive.fPacket); + + // Get NeFS partition's block. + + drive.fPacket.fPacketContent = sectorBufPartBlock; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + part_block->FreeSectors -= 1; + part_block->CatalogCount += 1; + part_block->FreeCatalog -= 1; + + drive.fOutput(&drive.fPacket); + + kcout << "Create new catalog, status: " + << hex_number(child_catalog->Flags) << endl; + kcout << "Create new catalog, name: " << child_catalog->Name + << endl; + + delete catalog; + return child_catalog; + } + else if ((next_sibling->Flags & kNeFSFlagCreated) && + StringBuilder::Equals(next_sibling->Name, name)) + { + return next_sibling; + } + + constexpr auto cNeFSCatalogPadding = 4; + + //// @note that's how we find the next catalog in the partition block. + start_free = start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); + + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = kNeFSSectorSz; + drive.fPacket.fLba = start_free; + + drive.fInput(&drive.fPacket); + } + + delete catalog; + return nullptr; +} + +/// @brief Make a EPM+NeFS drive out of the disk. +/// @param drive The drive to write on. +/// @return If it was sucessful, see ErrLocal(). +bool NeFSParser::Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name) +{ + if (*part_name == 0 || + endLba == 0) + return false; + + // verify disk. + drive->fVerify(&drive->fPacket); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + // if disk isn't good, then error out. + if (false == drive->fPacket.fPacketGood) + { + ErrLocal() = kErrorDiskIsCorrupted; + return false; + } + + Char fs_buf[kNeFSSectorSz] = {0}; + + Lba start = kNeFSRootCatalogStartAddress; + + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fLba = start; + + drive->fInput(&drive->fPacket); + + if (flags & kNeFSPartitionTypeBoot) + { + // make it bootable when needed. + Char bufEpmHdr[kNeFSSectorSz] = {0}; + + BOOT_BLOCK_STRUCT* epmBoot = (BOOT_BLOCK_STRUCT*)bufEpmHdr; + + // EPM header. + + constexpr auto cFsName = "NeFS"; + constexpr auto cBlockName = "ZKA:"; + + rt_copy_memory(reinterpret_cast(const_cast(cFsName)), epmBoot->Fs, rt_string_len(cFsName)); + + epmBoot->FsVersion = kNeFSVersionInteger; + epmBoot->LbaStart = start; + epmBoot->SectorSz = kNeFSSectorSz; + + rt_copy_memory(reinterpret_cast(const_cast(cBlockName)), epmBoot->Name, rt_string_len(cBlockName)); + rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epmBoot->Magic, rt_string_len(kEPMMagic)); + + Lba outEpmLba = kEpmBase; + + Char buf[kNeFSSectorSz]; + + Lba prevStart = 0; + SizeT cnt = 0; + + while (drive->fPacket.fPacketGood) + { + drive->fPacket.fPacketContent = buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fLba = outEpmLba; + + drive->fInput(&drive->fPacket); + + if (buf[0] == 0) + { + epmBoot->LbaStart = prevStart; + + if (epmBoot->LbaStart) + epmBoot->LbaStart = outEpmLba; + + epmBoot->LbaEnd = endLba; + epmBoot->NumBlocks = cnt; + + drive->fPacket.fPacketContent = bufEpmHdr; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fLba = outEpmLba; + + drive->fOutput(&drive->fPacket); + + break; + } + else + { + prevStart = ((BOOT_BLOCK_STRUCT*)buf)->LbaStart + ((BOOT_BLOCK_STRUCT*)buf)->LbaEnd; + } + + outEpmLba += sizeof(BOOT_BLOCK_STRUCT); + ++cnt; + } + } + + // disk isnt faulty and data has been fetched. + while (drive->fPacket.fPacketGood) + { + NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)fs_buf; + + // check for an empty partition here. + if (part_block->PartitionName[0] == 0 && + rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) + { + // partition is free and valid. + + part_block->Version = kNeFSVersionInteger; + + const auto cUntitledHD = part_name; + + rt_copy_memory((VoidPtr)kNeFSIdent, (VoidPtr)part_block->Ident, + kNeFSIdentLen); + + rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)part_block->PartitionName, + rt_string_len(cUntitledHD)); + + SizeT catalogCount = 0UL; + + SizeT sectorCount = drv_get_sector_count(); + SizeT diskSize = drv_get_size(); + + part_block->Kind = kNeFSPartitionTypeStandard; + part_block->StartCatalog = kNeFSCatalogStartAddress; + part_block->Flags = kNeFSPartitionTypeStandard; + part_block->CatalogCount = sectorCount / sizeof(NFS_CATALOG_STRUCT); + part_block->SectorCount = sectorCount; + part_block->DiskSize = diskSize; + part_block->FreeCatalog = sectorCount / sizeof(NFS_CATALOG_STRUCT); + + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fLba = kNeFSRootCatalogStartAddress; + + drive->fOutput(&drive->fPacket); + + kcout << "drive kind: " << drive->fDriveKind() << endl; + + kcout << "partition name: " << part_block->PartitionName << endl; + kcout << "start: " << hex_number(part_block->StartCatalog) << endl; + kcout << "number of catalogs: " << hex_number(part_block->CatalogCount) << endl; + kcout << "free catalog: " << hex_number(part_block->FreeCatalog) << endl; + kcout << "free sectors: " << hex_number(part_block->FreeSectors) << endl; + kcout << "sector size: " << hex_number(part_block->SectorSize) << endl; + + // write the root catalog. + this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); + + return true; + } + + kcout << "partition block already exists.\r"; + + start += part_block->DiskSize; + + drive->fPacket.fPacketContent = fs_buf; + drive->fPacket.fPacketSize = kNeFSSectorSz; + drive->fPacket.fLba = start; + + drive->fInput(&drive->fPacket); + } + + 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 NeFSParser::WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, Bool is_rsrc_fork, _Input VoidPtr data, _Input SizeT size_of_data, _Input const Char* forkName) +{ + if (size_of_data > kNeFSForkDataSz || + size_of_data == 0) + return No; + + auto buf = new UInt8[kNeFSForkDataSz]; + rt_set_memory(buf, 0, kNeFSForkDataSz); + + rt_copy_memory(data, buf, size_of_data); + + auto drive = sMountpointInterface.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + auto startFork = (!is_rsrc_fork) ? catalog->DataFork + : catalog->ResourceFork; + + NFS_FORK_STRUCT* fork_data_input = new NFS_FORK_STRUCT(); + NFS_FORK_STRUCT prevFork{}; + + // sanity check of the fork position as the condition to run the loop. + while (startFork >= kNeFSCatalogStartAddress) + { + drive.fPacket.fPacketContent = fork_data_input; + drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drive.fPacket.fLba = startFork; + + drive.fInput(&drive.fPacket); + + // check the fork, if it's position is valid. + if (fork_data_input->DataOffset <= kNeFSCatalogStartAddress) + { + ErrLocal() = kErrorDiskIsCorrupted; + + kcout << "Invalid fork offset.\r"; + + return false; + } + + if (fork_data_input->Flags != kNeFSFlagUnallocated && + fork_data_input->Flags != kNeFSFlagDeleted && + StringBuilder::Equals(fork_data_input->ForkName, forkName) && + StringBuilder::Equals(fork_data_input->CatalogName, catalog->Name) && + fork_data_input->DataSize == size_of_data) + { + // ===================================================== // + // Store the blob now. + // ===================================================== // + + fork_data_input->Flags |= kNeFSFlagCreated; + + drive.fPacket.fPacketContent = buf; + drive.fPacket.fPacketSize = kNeFSForkDataSz; + drive.fPacket.fLba = fork_data_input->DataOffset; + + kcout << "data offset: " << hex_number(fork_data_input->DataOffset) << endl; + + drive.fOutput(&drive.fPacket); + + drive.fPacket.fPacketContent = fork_data_input; + drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drive.fPacket.fLba = startFork - sizeof(NFS_FORK_STRUCT); + + drive.fOutput(&drive.fPacket); + + kcout << "wrote fork at offset: " << hex_number(fork_data_input->DataOffset) << endl; + kcout << "wrote fork at offset: " << hex_number(startFork - sizeof(NFS_FORK_STRUCT)) << endl; + + delete catalog; + + return true; + } + + // stumble upon a fork, store it. + + prevFork = *fork_data_input; + + startFork = fork_data_input->NextSibling; + } + + return false; +} + +/// @brief +/// @param catalogName the catalog name. +/// @return the newly found catalog. +_Output NFS_CATALOG_STRUCT* NeFSParser::FindCatalog(_Input const Char* catalogName, + Lba& out_lba) +{ + kcout << "Start finding catalog...\r"; + + NFS_ROOT_PARTITION_BLOCK fs_buf{0}; + auto drive = sMountpointInterface.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + drive.fPacket.fPacketContent = &fs_buf; + drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); + drive.fPacket.fLba = kNeFSRootCatalogStartAddress; + + drive.fInput(&drive.fPacket); + + NFS_ROOT_PARTITION_BLOCK* part = (NFS_ROOT_PARTITION_BLOCK*)&fs_buf; + + auto startCatalogList = part->StartCatalog; + const auto cCtartCatalogList = startCatalogList; + + auto localSearchFirst = false; + + NFS_CATALOG_STRUCT temporary_catalog{0}; + + drive.fPacket.fLba = startCatalogList; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); + + drive.fInput(&drive.fPacket); + + if (!StringBuilder::Equals(catalogName, NeFileSystemHelper::Root())) + { + Char parentName[kNeFSNodeNameLen] = {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] != NeFileSystemHelper::Separator()) + { + parentName[indexReverseCopy] = 0; + --indexReverseCopy; + } + + NFS_CATALOG_STRUCT* parentCatalog = this->FindCatalog(parentName, out_lba); + + if (parentCatalog && + !StringBuilder::Equals(parentName, NeFileSystemHelper::Root())) + { + startCatalogList = parentCatalog->NextSibling; + delete parentCatalog; + + localSearchFirst = true; + } + else if (parentCatalog) + { + delete parentCatalog; + } + else + { + return nullptr; + } + } + + kcout << "Fetching catalog...\r"; + +NeFSSearchThroughCatalogList: + while (drive.fPacket.fPacketGood) + { + drive.fPacket.fLba = startCatalogList; + drive.fPacket.fPacketContent = &temporary_catalog; + drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); + + drive.fInput(&drive.fPacket); + + NFS_CATALOG_STRUCT* catalog = (NFS_CATALOG_STRUCT*)&temporary_catalog; + + if (StringBuilder::Equals(catalogName, catalog->Name)) + { + /// ignore unallocated catalog, break + if (!(catalog->Flags & kNeFSFlagCreated)) + { + goto NeFSContinueSearch; + } + + NFS_CATALOG_STRUCT* catalogPtr = new NFS_CATALOG_STRUCT(); + rt_copy_memory(catalog, catalogPtr, sizeof(NFS_CATALOG_STRUCT)); + + kcout << "Found catalog at: " << hex_number(startCatalogList) << endl; + kcout << "Found catalog at: " << catalog->Name << endl; + + out_lba = startCatalogList; + return catalogPtr; + } + + NeFSContinueSearch: + startCatalogList = catalog->NextSibling; + + if (startCatalogList <= kNeFSRootCatalogStartAddress) + break; + } + + if (localSearchFirst) + { + localSearchFirst = false; + startCatalogList = cCtartCatalogList; + + goto NeFSSearchThroughCatalogList; + } + + out_lba = 0UL; + return nullptr; +} + +/// @brief Get catalog from filesystem. +/// @param name the catalog's name/ +/// @return +_Output NFS_CATALOG_STRUCT* NeFSParser::GetCatalog(_Input const Char* name) +{ + Lba unused = 0; + return this->FindCatalog(name, unused); +} + +/// @brief Closes a catalog, (frees it). +/// @param catalog the catalog to close. +/// @return +Boolean NeFSParser::CloseCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog) +{ + if (!catalog) + return false; + + delete catalog; + catalog = nullptr; + + return true; +} + +/// @brief Mark catalog as removed. +/// @param catalog The catalog structure. +/// @return if the catalog was removed or not. +Boolean NeFSParser::RemoveCatalog(_Input const Char* catalogName) +{ + if (!catalogName || + StringBuilder::Equals(catalogName, NeFileSystemHelper::Root())) + { + ErrLocal() = kErrorInternal; + return false; + } + + Lba out_lba = 0; + auto catalog = this->FindCatalog(catalogName, out_lba); + + if (out_lba >= kNeFSCatalogStartAddress || + catalog->Flags & kNeFSFlagCreated) + { + catalog->Flags |= kNeFSFlagDeleted; + + auto drive = sMountpointInterface.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + drive.fPacket.fLba = out_lba; // the catalog position. + drive.fPacket.fPacketSize = + sizeof(NFS_CATALOG_STRUCT); // size of catalog. roughly the sector size. + drive.fPacket.fPacketContent = catalog; // the catalog itself. + + drive.fOutput(&drive.fPacket); // send packet. + + Char partitionBlockBuf[sizeof(NFS_ROOT_PARTITION_BLOCK)] = {0}; + + drive.fPacket.fLba = kNeFSRootCatalogStartAddress; + drive.fPacket.fPacketContent = partitionBlockBuf; + drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); + + drive.fInput(&drive.fPacket); + + NFS_ROOT_PARTITION_BLOCK* part_block = + reinterpret_cast(partitionBlockBuf); + + --part_block->CatalogCount; + ++part_block->FreeSectors; + + 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 NeFSParser::ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, + _Input Bool is_rsrc_fork, + _Input SizeT dataSz, + _Input const Char* forkName) +{ + if (!catalog) + { + ErrLocal() = kErrorFileNotFound; + return nullptr; + } + + constexpr auto cNeFSCatalogPadding = 4; + + Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; + Size dataForkSize = (!is_rsrc_fork) ? catalog->DataForkSize : catalog->ResourceForkSize; + + kcout << "catalog " << catalog->Name + << ", fork: " << hex_number(dataForkLba) << endl; + + NFS_FORK_STRUCT* fs_buf = new NFS_FORK_STRUCT(); + auto drive = sMountpointInterface.A(); + + rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, + rt_string_len("fs/nefs-packet")); + + NFS_FORK_STRUCT* fs_fork_data = nullptr; + + while (dataForkLba > kNeFSCatalogStartAddress) + { + drive.fPacket.fLba = dataForkLba; + drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); + drive.fPacket.fPacketContent = fs_buf; + + drive.fInput(&drive.fPacket); + + fs_fork_data = fs_buf; + + kcout << "ForkName: " << fs_fork_data->ForkName << endl; + kcout << "CatalogName: " << fs_fork_data->CatalogName << endl; + + if (StringBuilder::Equals(forkName, fs_fork_data->ForkName) && + StringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) + break; + + dataForkLba = fs_fork_data->NextSibling; + } + + if (dataForkLba < kNeFSCatalogStartAddress) + { + delete fs_buf; + return nullptr; + } + + return fs_fork_data; +} + +/***********************************************************************************/ +/// @brief Seek in the data fork. +/// @param catalog the catalog offset. +/// @param off where to seek. +/// @return if the seeking was successful. +/***********************************************************************************/ + +bool NeFSParser::Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off) +{ + if (!catalog) + { + ErrLocal() = kErrorFileNotFound; + return false; + } + + ErrLocal() = kErrorUnimplemented; + return false; +} + +/***********************************************************************************/ +/// @brief Tell where we are inside the data fork. +/// @param catalog +/// @return The position on the file. +/***********************************************************************************/ + +SizeT NeFSParser::Tell(_Input _Output NFS_CATALOG_STRUCT* catalog) +{ + if (!catalog) + { + ErrLocal() = kErrorFileNotFound; + return 0; + } + + ErrLocal() = kErrorUnimplemented; + return 0; +} + +namespace Kernel::Detail +{ + /***********************************************************************************/ + /// @brief Construct NeFS drives. + /***********************************************************************************/ + Boolean fs_init_newfs(Void) noexcept + { + kcout << "Creating drives...\r"; + + sMountpointInterface.A() = io_construct_main_drive(); + sMountpointInterface.B() = io_construct_drive(); + sMountpointInterface.C() = io_construct_drive(); + sMountpointInterface.D() = io_construct_drive(); + + kcout << "Constructing A:\r"; + + sMountpointInterface.A().fInit(&sMountpointInterface.A().fPacket); + + kcout << "Constructing A: [ OK ]\r"; + + return true; + } +} // namespace Kernel::Detail +#endif // !__ZKA_MINIMAL_OS__ + +#endif // ifdef __FSKIT_USE_NEFS__ diff --git a/dev/zka/src/FS/NeFS.cxx b/dev/zka/src/FS/NeFS.cxx deleted file mode 100644 index 48bd441f..00000000 --- a/dev/zka/src/FS/NeFS.cxx +++ /dev/null @@ -1,1057 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#ifdef __FSKIT_USE_NEFS__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef __ZKA_MINIMAL_OS__ -using namespace Kernel; - -#ifdef __ZKA_NO_BUILTIN__ -/***********************************************************************************/ -/** - Define those external symbols, to make the editor shutup -*/ -/***********************************************************************************/ - -/***********************************************************************************/ -/// @brief get sector count. -/***********************************************************************************/ -Kernel::SizeT drv_get_sector_count(); - -/***********************************************************************************/ -/// @brief get device size. -/***********************************************************************************/ -Kernel::SizeT drv_get_size(); - -#endif - -///! BUGS: 0 - -/***********************************************************************************/ -/// This file implements the New File System. -/// New File System implements a B-Tree based algortihm. -/// \\ -/// \\Path1\\ \\ath2\\ -/// \\readme.rtf \\ListContents.pef \\readme.lnk <-- symlink. -/// \\Path1\\readme.rtf -/***********************************************************************************/ - -STATIC MountpointInterface sMountpointInterface; - -/***********************************************************************************/ -/// @brief Creates a new fork inside the New filesystem partition. -/// @param catalog it's catalog -/// @param the_fork the fork itself. -/// @return the fork -/***********************************************************************************/ -_Output NFS_FORK_STRUCT* NeFSParser::CreateFork(_Input NFS_CATALOG_STRUCT* catalog, - _Input NFS_FORK_STRUCT& the_fork) -{ - if (catalog && the_fork.ForkName[0] != 0 && - the_fork.DataSize <= kNeFSForkDataSz) - { - Lba lba = (the_fork.Kind == kNeFSDataForkKind) ? catalog->DataFork - : catalog->ResourceFork; - - kcout << "fork lba: " << hex_number(lba) << endl; - - if (lba <= kNeFSCatalogStartAddress) - return nullptr; - - auto drv = sMountpointInterface.A(); - - /// special treatment. - rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - NFS_FORK_STRUCT curFork{0}; - NFS_FORK_STRUCT 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 <= kNeFSCatalogStartAddress) - break; - - drv.fPacket.fLba = lba; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &curFork; - - drv.fInput(&drv.fPacket); - - if (curFork.NextSibling > kBadAddress) - { - kcout << "bad fork: " << hex_number(curFork.NextSibling) << endl; - break; - } - - kcout << "next fork: " << hex_number(curFork.NextSibling) << endl; - - if (curFork.Flags & kNeFSFlagCreated) - { - kcout << "fork already exists.\r"; - - /// sanity check. - if (StringBuilder::Equals(curFork.ForkName, the_fork.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 >= kNeFSCatalogStartAddress) - { - drv.fPacket.fLba = lbaOfPreviousFork; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - 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. - - the_fork.Flags |= kNeFSFlagCreated; - the_fork.DataOffset = lba - sizeof(NFS_FORK_STRUCT); - the_fork.PreviousSibling = lbaOfPreviousFork; - the_fork.NextSibling = the_fork.DataOffset - the_fork.DataSize - sizeof(NFS_FORK_STRUCT); - - drv.fPacket.fLba = lba; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = &the_fork; - - drv.fOutput(&drv.fPacket); - - /// log what we have now. - kcout << "Wrote fork data at: " << hex_number(the_fork.DataOffset) - << endl; - - kcout << "Wrote fork at: " << hex_number(lba) << endl; - - return &the_fork; - } - - return nullptr; -} - -/***********************************************************************************/ -/// @brief Find fork inside New filesystem. -/// @param catalog the catalog. -/// @param name the fork name. -/// @return the fork. -/***********************************************************************************/ -_Output NFS_FORK_STRUCT* NeFSParser::FindFork(_Input NFS_CATALOG_STRUCT* catalog, - _Input const Char* name, - Boolean isDataFork) -{ - auto drv = sMountpointInterface.A(); - NFS_FORK_STRUCT* the_fork = nullptr; - - Lba lba = isDataFork ? catalog->DataFork : catalog->ResourceFork; - - while (lba != 0) - { - drv.fPacket.fLba = lba; - drv.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drv.fPacket.fPacketContent = (VoidPtr)the_fork; - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drv.fPacket.fPacketMime, 16); - - if (auto res = - fs_newfs_read(&sMountpointInterface, drv, this->fDriveIndex); - res) - { - switch (res) - { - case 1: - ErrLocal() = kErrorDiskReadOnly; - break; - case 2: - ErrLocal() = kErrorDiskIsFull; - break; - ErrLocal() = kErrorNoSuchDisk; - break; - - default: - break; - } - return nullptr; - } - - if (StringBuilder::Equals(the_fork->ForkName, name)) - { - break; - } - - lba = the_fork->NextSibling; - } - - return the_fork; -} - -/***********************************************************************************/ -/// @brief Simpler factory to create a catalog (assumes you want to create a -/// file.) -/// @param name -/// @return catalog pointer. -/***********************************************************************************/ -_Output NFS_CATALOG_STRUCT* NeFSParser::CreateCatalog(_Input const Char* name) -{ - return this->CreateCatalog(name, 0, kNeFSCatalogKindFile); -} - -/***********************************************************************************/ -/// @brief Creates a new catalog into the disk. -/// @param name the catalog name. -/// @param flags the flags of the catalog. -/// @param kind the catalog kind. -/// @return catalog pointer. -/***********************************************************************************/ -_Output NFS_CATALOG_STRUCT* NeFSParser::CreateCatalog(_Input const Char* name, - _Input const Int32& flags, - _Input const Int32& kind) -{ - kcout << "CreateCatalog(...)\r"; - - Lba out_lba = 0UL; - - kcout << "Checking for extension...\r"; - - /// a directory should have a slash in the end. - if (kind == kNeFSCatalogKindDir && - name[rt_string_len(name) - 1] != NeFileSystemHelper::Separator()) - return nullptr; - - /// a file shouldn't have a slash in the end. - if (kind != kNeFSCatalogKindDir && - name[rt_string_len(name) - 1] == NeFileSystemHelper::Separator()) - return nullptr; - - NFS_CATALOG_STRUCT* catalog_copy = this->FindCatalog(name, out_lba); - - if (catalog_copy) - { - kcout << "Catalog already exists: " << name << ".\r"; - ErrLocal() = kErrorFileExists; - - return catalog_copy; - } - - Char parentName[kNeFSNodeNameLen] = {0}; - - for (SizeT indexName = 0UL; indexName < rt_string_len(name); ++indexName) - { - parentName[indexName] = name[indexName]; - } - - if (*parentName == 0) - { - kcout << "Parent name is NUL.\r"; - ErrLocal() = 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 it. - parentName[--indexReverseCopy] = 0; - - // mandatory / character, zero it. - parentName[--indexReverseCopy] = 0; - - while (parentName[indexReverseCopy] != NeFileSystemHelper::Separator()) - { - parentName[indexReverseCopy] = 0; - --indexReverseCopy; - } - - NFS_CATALOG_STRUCT* catalog = this->FindCatalog(parentName, out_lba); - - auto drive = sMountpointInterface.A(); - - if (catalog && catalog->Kind == kNeFSCatalogKindFile) - { - kcout << "Parent name is file.\r"; - delete catalog; - return nullptr; - } - else if (!catalog) - { - Char sectorBufPartBlock[kNeFSSectorSz] = {0}; - - drive.fPacket.fPacketContent = sectorBufPartBlock; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - constexpr auto cNeFSCatalogPadding = 4; - - NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; - out_lba = part_block->StartCatalog; - } - - constexpr SizeT cDefaultForkSize = kNeFSForkSize; - - NFS_CATALOG_STRUCT* child_catalog = new NFS_CATALOG_STRUCT(); - - Int32 flagsList = flags; - - child_catalog->ResourceForkSize = cDefaultForkSize; - child_catalog->DataForkSize = cDefaultForkSize; - - child_catalog->NextSibling = out_lba; - child_catalog->PrevSibling = out_lba; - child_catalog->Kind = kind; - child_catalog->Flags = kNeFSFlagCreated | flagsList; - - rt_copy_memory((VoidPtr)name, (VoidPtr)child_catalog->Name, - rt_string_len(name)); - - NFS_CATALOG_STRUCT temporary_catalog; - - Lba start_free = out_lba; - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fLba = start_free; - - drive.fInput(&drive.fPacket); - - NFS_CATALOG_STRUCT* next_sibling = reinterpret_cast(&temporary_catalog); - - start_free = next_sibling->NextSibling; - - child_catalog->PrevSibling = out_lba; - - drive.fPacket.fLba = start_free; - drive.fInput(&drive.fPacket); - - while (drive.fPacket.fPacketGood) - { - next_sibling = reinterpret_cast(&temporary_catalog); - - if (start_free <= kNeFSRootCatalogStartAddress) - { - delete child_catalog; - delete catalog; - - return nullptr; - } - - // ========================== // - // Allocate catalog now... - // ========================== // - if ((next_sibling->Flags & kNeFSFlagCreated) == 0) - { - Char sectorBufPartBlock[kNeFSSectorSz] = {0}; - - drive.fPacket.fPacketContent = sectorBufPartBlock; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - constexpr auto cNeFSCatalogPadding = 4; - - NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)sectorBufPartBlock; - - if (part_block->FreeCatalog < 1) - { - delete child_catalog; - return nullptr; - } - - child_catalog->DataFork = part_block->DiskSize - start_free; - child_catalog->ResourceFork = child_catalog->DataFork; - - // Write the new catalog next sibling, if we don't know this parent. // - // This is necessary, so that we don't have to get another lba to allocate. // - if (!StringBuilder::Equals(parentName, next_sibling->Name)) - { - child_catalog->NextSibling = - start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); - } - - drive.fPacket.fPacketContent = child_catalog; - drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); - drive.fPacket.fLba = start_free; - - drive.fOutput(&drive.fPacket); - - // Get NeFS partition's block. - - drive.fPacket.fPacketContent = sectorBufPartBlock; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - part_block->FreeSectors -= 1; - part_block->CatalogCount += 1; - part_block->FreeCatalog -= 1; - - drive.fOutput(&drive.fPacket); - - kcout << "Create new catalog, status: " - << hex_number(child_catalog->Flags) << endl; - kcout << "Create new catalog, name: " << child_catalog->Name - << endl; - - delete catalog; - return child_catalog; - } - else if ((next_sibling->Flags & kNeFSFlagCreated) && - StringBuilder::Equals(next_sibling->Name, name)) - { - return next_sibling; - } - - constexpr auto cNeFSCatalogPadding = 4; - - //// @note that's how we find the next catalog in the partition block. - start_free = start_free + (sizeof(NFS_CATALOG_STRUCT) * cNeFSCatalogPadding); - - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = kNeFSSectorSz; - drive.fPacket.fLba = start_free; - - drive.fInput(&drive.fPacket); - } - - delete catalog; - return nullptr; -} - -/// @brief Make a EPM+NeFS drive out of the disk. -/// @param drive The drive to write on. -/// @return If it was sucessful, see ErrLocal(). -bool NeFSParser::Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name) -{ - if (*part_name == 0 || - endLba == 0) - return false; - - // verify disk. - drive->fVerify(&drive->fPacket); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive->fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - // if disk isn't good, then error out. - if (false == drive->fPacket.fPacketGood) - { - ErrLocal() = kErrorDiskIsCorrupted; - return false; - } - - Char fs_buf[kNeFSSectorSz] = {0}; - - Lba start = kNeFSRootCatalogStartAddress; - - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fLba = start; - - drive->fInput(&drive->fPacket); - - if (flags & kNeFSPartitionTypeBoot) - { - // make it bootable when needed. - Char bufEpmHdr[kNeFSSectorSz] = {0}; - - BOOT_BLOCK_STRUCT* epmBoot = (BOOT_BLOCK_STRUCT*)bufEpmHdr; - - // EPM header. - - constexpr auto cFsName = "NeFS"; - constexpr auto cBlockName = "ZKA:"; - - rt_copy_memory(reinterpret_cast(const_cast(cFsName)), epmBoot->Fs, rt_string_len(cFsName)); - - epmBoot->FsVersion = kNeFSVersionInteger; - epmBoot->LbaStart = start; - epmBoot->SectorSz = kNeFSSectorSz; - - rt_copy_memory(reinterpret_cast(const_cast(cBlockName)), epmBoot->Name, rt_string_len(cBlockName)); - rt_copy_memory(reinterpret_cast(const_cast(kEPMMagic)), epmBoot->Magic, rt_string_len(kEPMMagic)); - - Lba outEpmLba = kEpmBase; - - Char buf[kNeFSSectorSz]; - - Lba prevStart = 0; - SizeT cnt = 0; - - while (drive->fPacket.fPacketGood) - { - drive->fPacket.fPacketContent = buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fLba = outEpmLba; - - drive->fInput(&drive->fPacket); - - if (buf[0] == 0) - { - epmBoot->LbaStart = prevStart; - - if (epmBoot->LbaStart) - epmBoot->LbaStart = outEpmLba; - - epmBoot->LbaEnd = endLba; - epmBoot->NumBlocks = cnt; - - drive->fPacket.fPacketContent = bufEpmHdr; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fLba = outEpmLba; - - drive->fOutput(&drive->fPacket); - - break; - } - else - { - prevStart = ((BOOT_BLOCK_STRUCT*)buf)->LbaStart + ((BOOT_BLOCK_STRUCT*)buf)->LbaEnd; - } - - outEpmLba += sizeof(BOOT_BLOCK_STRUCT); - ++cnt; - } - } - - // disk isnt faulty and data has been fetched. - while (drive->fPacket.fPacketGood) - { - NFS_ROOT_PARTITION_BLOCK* part_block = (NFS_ROOT_PARTITION_BLOCK*)fs_buf; - - // check for an empty partition here. - if (part_block->PartitionName[0] == 0 && - rt_string_cmp(part_block->Ident, kNeFSIdent, kNeFSIdentLen)) - { - // partition is free and valid. - - part_block->Version = kNeFSVersionInteger; - - const auto cUntitledHD = part_name; - - rt_copy_memory((VoidPtr)kNeFSIdent, (VoidPtr)part_block->Ident, - kNeFSIdentLen); - - rt_copy_memory((VoidPtr)cUntitledHD, (VoidPtr)part_block->PartitionName, - rt_string_len(cUntitledHD)); - - SizeT catalogCount = 0UL; - - SizeT sectorCount = drv_get_sector_count(); - SizeT diskSize = drv_get_size(); - - part_block->Kind = kNeFSPartitionTypeStandard; - part_block->StartCatalog = kNeFSCatalogStartAddress; - part_block->Flags = kNeFSPartitionTypeStandard; - part_block->CatalogCount = sectorCount / sizeof(NFS_CATALOG_STRUCT); - part_block->SectorCount = sectorCount; - part_block->DiskSize = diskSize; - part_block->FreeCatalog = sectorCount / sizeof(NFS_CATALOG_STRUCT); - - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fLba = kNeFSRootCatalogStartAddress; - - drive->fOutput(&drive->fPacket); - - kcout << "drive kind: " << drive->fDriveKind() << endl; - - kcout << "partition name: " << part_block->PartitionName << endl; - kcout << "start: " << hex_number(part_block->StartCatalog) << endl; - kcout << "number of catalogs: " << hex_number(part_block->CatalogCount) << endl; - kcout << "free catalog: " << hex_number(part_block->FreeCatalog) << endl; - kcout << "free sectors: " << hex_number(part_block->FreeSectors) << endl; - kcout << "sector size: " << hex_number(part_block->SectorSize) << endl; - - // write the root catalog. - this->CreateCatalog(kNeFSRoot, 0, kNeFSCatalogKindDir); - - return true; - } - - kcout << "partition block already exists.\r"; - - start += part_block->DiskSize; - - drive->fPacket.fPacketContent = fs_buf; - drive->fPacket.fPacketSize = kNeFSSectorSz; - drive->fPacket.fLba = start; - - drive->fInput(&drive->fPacket); - } - - 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 NeFSParser::WriteCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, Bool is_rsrc_fork, _Input VoidPtr data, _Input SizeT size_of_data, _Input const Char* forkName) -{ - if (size_of_data > kNeFSForkDataSz || - size_of_data == 0) - return No; - - auto buf = new UInt8[kNeFSForkDataSz]; - rt_set_memory(buf, 0, kNeFSForkDataSz); - - rt_copy_memory(data, buf, size_of_data); - - auto drive = sMountpointInterface.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - auto startFork = (!is_rsrc_fork) ? catalog->DataFork - : catalog->ResourceFork; - - NFS_FORK_STRUCT* fork_data_input = new NFS_FORK_STRUCT(); - NFS_FORK_STRUCT prevFork{}; - - // sanity check of the fork position as the condition to run the loop. - while (startFork >= kNeFSCatalogStartAddress) - { - drive.fPacket.fPacketContent = fork_data_input; - drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drive.fPacket.fLba = startFork; - - drive.fInput(&drive.fPacket); - - // check the fork, if it's position is valid. - if (fork_data_input->DataOffset <= kNeFSCatalogStartAddress) - { - ErrLocal() = kErrorDiskIsCorrupted; - - kcout << "Invalid fork offset.\r"; - - return false; - } - - if (fork_data_input->Flags != kNeFSFlagUnallocated && - fork_data_input->Flags != kNeFSFlagDeleted && - StringBuilder::Equals(fork_data_input->ForkName, forkName) && - StringBuilder::Equals(fork_data_input->CatalogName, catalog->Name) && - fork_data_input->DataSize == size_of_data) - { - // ===================================================== // - // Store the blob now. - // ===================================================== // - - fork_data_input->Flags |= kNeFSFlagCreated; - - drive.fPacket.fPacketContent = buf; - drive.fPacket.fPacketSize = kNeFSForkDataSz; - drive.fPacket.fLba = fork_data_input->DataOffset; - - kcout << "data offset: " << hex_number(fork_data_input->DataOffset) << endl; - - drive.fOutput(&drive.fPacket); - - drive.fPacket.fPacketContent = fork_data_input; - drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drive.fPacket.fLba = startFork - sizeof(NFS_FORK_STRUCT); - - drive.fOutput(&drive.fPacket); - - kcout << "wrote fork at offset: " << hex_number(fork_data_input->DataOffset) << endl; - kcout << "wrote fork at offset: " << hex_number(startFork - sizeof(NFS_FORK_STRUCT)) << endl; - - delete catalog; - - return true; - } - - // stumble upon a fork, store it. - - prevFork = *fork_data_input; - - startFork = fork_data_input->NextSibling; - } - - return false; -} - -/// @brief -/// @param catalogName the catalog name. -/// @return the newly found catalog. -_Output NFS_CATALOG_STRUCT* NeFSParser::FindCatalog(_Input const Char* catalogName, - Lba& out_lba) -{ - kcout << "Start finding catalog...\r"; - - NFS_ROOT_PARTITION_BLOCK fs_buf{0}; - auto drive = sMountpointInterface.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - drive.fPacket.fPacketContent = &fs_buf; - drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); - drive.fPacket.fLba = kNeFSRootCatalogStartAddress; - - drive.fInput(&drive.fPacket); - - NFS_ROOT_PARTITION_BLOCK* part = (NFS_ROOT_PARTITION_BLOCK*)&fs_buf; - - auto startCatalogList = part->StartCatalog; - const auto cCtartCatalogList = startCatalogList; - - auto localSearchFirst = false; - - NFS_CATALOG_STRUCT temporary_catalog{0}; - - drive.fPacket.fLba = startCatalogList; - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); - - drive.fInput(&drive.fPacket); - - if (!StringBuilder::Equals(catalogName, NeFileSystemHelper::Root())) - { - Char parentName[kNeFSNodeNameLen] = {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] != NeFileSystemHelper::Separator()) - { - parentName[indexReverseCopy] = 0; - --indexReverseCopy; - } - - NFS_CATALOG_STRUCT* parentCatalog = this->FindCatalog(parentName, out_lba); - - if (parentCatalog && - !StringBuilder::Equals(parentName, NeFileSystemHelper::Root())) - { - startCatalogList = parentCatalog->NextSibling; - delete parentCatalog; - - localSearchFirst = true; - } - else if (parentCatalog) - { - delete parentCatalog; - } - else - { - return nullptr; - } - } - - kcout << "Fetching catalog...\r"; - -NeFSSearchThroughCatalogList: - while (drive.fPacket.fPacketGood) - { - drive.fPacket.fLba = startCatalogList; - drive.fPacket.fPacketContent = &temporary_catalog; - drive.fPacket.fPacketSize = sizeof(NFS_CATALOG_STRUCT); - - drive.fInput(&drive.fPacket); - - NFS_CATALOG_STRUCT* catalog = (NFS_CATALOG_STRUCT*)&temporary_catalog; - - if (StringBuilder::Equals(catalogName, catalog->Name)) - { - /// ignore unallocated catalog, break - if (!(catalog->Flags & kNeFSFlagCreated)) - { - goto NeFSContinueSearch; - } - - NFS_CATALOG_STRUCT* catalogPtr = new NFS_CATALOG_STRUCT(); - rt_copy_memory(catalog, catalogPtr, sizeof(NFS_CATALOG_STRUCT)); - - kcout << "Found catalog at: " << hex_number(startCatalogList) << endl; - kcout << "Found catalog at: " << catalog->Name << endl; - - out_lba = startCatalogList; - return catalogPtr; - } - - NeFSContinueSearch: - startCatalogList = catalog->NextSibling; - - if (startCatalogList <= kNeFSRootCatalogStartAddress) - break; - } - - if (localSearchFirst) - { - localSearchFirst = false; - startCatalogList = cCtartCatalogList; - - goto NeFSSearchThroughCatalogList; - } - - out_lba = 0UL; - return nullptr; -} - -/// @brief Get catalog from filesystem. -/// @param name the catalog's name/ -/// @return -_Output NFS_CATALOG_STRUCT* NeFSParser::GetCatalog(_Input const Char* name) -{ - Lba unused = 0; - return this->FindCatalog(name, unused); -} - -/// @brief Closes a catalog, (frees it). -/// @param catalog the catalog to close. -/// @return -Boolean NeFSParser::CloseCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog) -{ - if (!catalog) - return false; - - delete catalog; - catalog = nullptr; - - return true; -} - -/// @brief Mark catalog as removed. -/// @param catalog The catalog structure. -/// @return if the catalog was removed or not. -Boolean NeFSParser::RemoveCatalog(_Input const Char* catalogName) -{ - if (!catalogName || - StringBuilder::Equals(catalogName, NeFileSystemHelper::Root())) - { - ErrLocal() = kErrorInternal; - return false; - } - - Lba out_lba = 0; - auto catalog = this->FindCatalog(catalogName, out_lba); - - if (out_lba >= kNeFSCatalogStartAddress || - catalog->Flags & kNeFSFlagCreated) - { - catalog->Flags |= kNeFSFlagDeleted; - - auto drive = sMountpointInterface.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - drive.fPacket.fLba = out_lba; // the catalog position. - drive.fPacket.fPacketSize = - sizeof(NFS_CATALOG_STRUCT); // size of catalog. roughly the sector size. - drive.fPacket.fPacketContent = catalog; // the catalog itself. - - drive.fOutput(&drive.fPacket); // send packet. - - Char partitionBlockBuf[sizeof(NFS_ROOT_PARTITION_BLOCK)] = {0}; - - drive.fPacket.fLba = kNeFSRootCatalogStartAddress; - drive.fPacket.fPacketContent = partitionBlockBuf; - drive.fPacket.fPacketSize = sizeof(NFS_ROOT_PARTITION_BLOCK); - - drive.fInput(&drive.fPacket); - - NFS_ROOT_PARTITION_BLOCK* part_block = - reinterpret_cast(partitionBlockBuf); - - --part_block->CatalogCount; - ++part_block->FreeSectors; - - 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 NeFSParser::ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog, - _Input Bool is_rsrc_fork, - _Input SizeT dataSz, - _Input const Char* forkName) -{ - if (!catalog) - { - ErrLocal() = kErrorFileNotFound; - return nullptr; - } - - constexpr auto cNeFSCatalogPadding = 4; - - Lba dataForkLba = (!is_rsrc_fork) ? catalog->DataFork : catalog->ResourceFork; - Size dataForkSize = (!is_rsrc_fork) ? catalog->DataForkSize : catalog->ResourceForkSize; - - kcout << "catalog " << catalog->Name - << ", fork: " << hex_number(dataForkLba) << endl; - - NFS_FORK_STRUCT* fs_buf = new NFS_FORK_STRUCT(); - auto drive = sMountpointInterface.A(); - - rt_copy_memory((VoidPtr) "fs/nefs-packet", drive.fPacket.fPacketMime, - rt_string_len("fs/nefs-packet")); - - NFS_FORK_STRUCT* fs_fork_data = nullptr; - - while (dataForkLba > kNeFSCatalogStartAddress) - { - drive.fPacket.fLba = dataForkLba; - drive.fPacket.fPacketSize = sizeof(NFS_FORK_STRUCT); - drive.fPacket.fPacketContent = fs_buf; - - drive.fInput(&drive.fPacket); - - fs_fork_data = fs_buf; - - kcout << "ForkName: " << fs_fork_data->ForkName << endl; - kcout << "CatalogName: " << fs_fork_data->CatalogName << endl; - - if (StringBuilder::Equals(forkName, fs_fork_data->ForkName) && - StringBuilder::Equals(catalog->Name, fs_fork_data->CatalogName)) - break; - - dataForkLba = fs_fork_data->NextSibling; - } - - if (dataForkLba < kNeFSCatalogStartAddress) - { - delete fs_buf; - return nullptr; - } - - return fs_fork_data; -} - -/***********************************************************************************/ -/// @brief Seek in the data fork. -/// @param catalog the catalog offset. -/// @param off where to seek. -/// @return if the seeking was successful. -/***********************************************************************************/ - -bool NeFSParser::Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off) -{ - if (!catalog) - { - ErrLocal() = kErrorFileNotFound; - return false; - } - - ErrLocal() = kErrorUnimplemented; - return false; -} - -/***********************************************************************************/ -/// @brief Tell where we are inside the data fork. -/// @param catalog -/// @return The position on the file. -/***********************************************************************************/ - -SizeT NeFSParser::Tell(_Input _Output NFS_CATALOG_STRUCT* catalog) -{ - if (!catalog) - { - ErrLocal() = kErrorFileNotFound; - return 0; - } - - ErrLocal() = kErrorUnimplemented; - return 0; -} - -namespace Kernel::Detail -{ - /***********************************************************************************/ - /// @brief Construct NeFS drives. - /***********************************************************************************/ - Boolean fs_init_newfs(Void) noexcept - { - kcout << "Creating drives...\r"; - - sMountpointInterface.A() = io_construct_main_drive(); - sMountpointInterface.B() = io_construct_drive(); - sMountpointInterface.C() = io_construct_drive(); - sMountpointInterface.D() = io_construct_drive(); - - kcout << "Constructing A:\r"; - - sMountpointInterface.A().fInit(&sMountpointInterface.A().fPacket); - - kcout << "Constructing A: [ OK ]\r"; - - return true; - } -} // namespace Kernel::Detail -#endif // !__ZKA_MINIMAL_OS__ - -#endif // ifdef __FSKIT_USE_NEFS__ diff --git a/dev/zka/src/FileMgr.cc b/dev/zka/src/FileMgr.cc new file mode 100644 index 00000000..c9591bf0 --- /dev/null +++ b/dev/zka/src/FileMgr.cc @@ -0,0 +1,52 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +/// BUGS: 0 +//! @brief File System Manager API. + +namespace Kernel +{ + STATIC IFilesystemMgr* kMountedFilesystem = nullptr; + + /// @brief FilesystemMgr getter. + /// @return The mounted filesystem. + _Output IFilesystemMgr* IFilesystemMgr::GetMounted() + { + return kMountedFilesystem; + } + + /// @brief Unmount filesystem. + /// @return The unmounted filesystem. + _Output IFilesystemMgr* IFilesystemMgr::Unmount() + { + if (kMountedFilesystem) + { + auto mount = kMountedFilesystem; + kMountedFilesystem = nullptr; + + return mount; + } + + return nullptr; + } + + /// @brief Mount filesystem. + /// @param mount_ptr The filesystem to mount. + /// @return if it succeeded true, otherwise false. + bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr) + { + if (mount_ptr != nullptr) + { + kMountedFilesystem = mount_ptr; + return true; + } + + return false; + } +} // namespace Kernel diff --git a/dev/zka/src/FileMgr.cxx b/dev/zka/src/FileMgr.cxx deleted file mode 100644 index fc51683f..00000000 --- a/dev/zka/src/FileMgr.cxx +++ /dev/null @@ -1,52 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -/// BUGS: 0 -//! @brief File System Manager API. - -namespace Kernel -{ - STATIC IFilesystemMgr* kMountedFilesystem = nullptr; - - /// @brief FilesystemMgr getter. - /// @return The mounted filesystem. - _Output IFilesystemMgr* IFilesystemMgr::GetMounted() - { - return kMountedFilesystem; - } - - /// @brief Unmount filesystem. - /// @return The unmounted filesystem. - _Output IFilesystemMgr* IFilesystemMgr::Unmount() - { - if (kMountedFilesystem) - { - auto mount = kMountedFilesystem; - kMountedFilesystem = nullptr; - - return mount; - } - - return nullptr; - } - - /// @brief Mount filesystem. - /// @param mount_ptr The filesystem to mount. - /// @return if it succeeded true, otherwise false. - bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr) - { - if (mount_ptr != nullptr) - { - kMountedFilesystem = mount_ptr; - return true; - } - - return false; - } -} // namespace Kernel diff --git a/dev/zka/src/GUIDWizard.cc b/dev/zka/src/GUIDWizard.cc new file mode 100644 index 00000000..77635979 --- /dev/null +++ b/dev/zka/src/GUIDWizard.cc @@ -0,0 +1,72 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + + 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 Kernel::XRN::Version1 +{ + auto cf_make_sequence(const ArrayList& uuidSeq) -> Ref + { + GUIDSequence* seq = new GUIDSequence(); + MUST_PASS(seq); + + Ref seq_ref{*seq}; + + seq_ref.Leak().fMs1 = uuidSeq[0]; + seq_ref.Leak().fMs2 = uuidSeq[1]; + seq_ref.Leak().fMs3 = uuidSeq[2]; + seq_ref.Leak().fMs4[0] = uuidSeq[3]; + seq_ref.Leak().fMs4[1] = uuidSeq[4]; + seq_ref.Leak().fMs4[2] = uuidSeq[5]; + seq_ref.Leak().fMs4[3] = uuidSeq[6]; + seq_ref.Leak().fMs4[4] = uuidSeq[7]; + seq_ref.Leak().fMs4[5] = uuidSeq[8]; + seq_ref.Leak().fMs4[6] = uuidSeq[9]; + seq_ref.Leak().fMs4[7] = uuidSeq[10]; + + return seq_ref; + } + + // @brief Tries to make a guid out of a string. + // This function is not complete for now + auto cf_try_guid_to_string(Ref& seq) -> ErrorOr> + { + Char buf[kUUIDSize]; + + for (SizeT index = 0; index < 16; ++index) + { + buf[index] = seq.Leak().u8[index] + kAsciiBegin; + } + + for (SizeT index = 16; index < 24; ++index) + { + buf[index] = seq.Leak().u16[index] + kAsciiBegin; + } + + for (SizeT index = 24; index < 28; ++index) + { + buf[index] = seq.Leak().u32[index] + kAsciiBegin; + } + + auto view = StringBuilder::Construct(buf); + + if (view) + return ErrorOr>{view.Leak()}; + + return ErrorOr>{-1}; + } +} // namespace Kernel::XRN::Version1 diff --git a/dev/zka/src/GUIDWizard.cxx b/dev/zka/src/GUIDWizard.cxx deleted file mode 100644 index a9094215..00000000 --- a/dev/zka/src/GUIDWizard.cxx +++ /dev/null @@ -1,72 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - - 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 Kernel::XRN::Version1 -{ - auto cf_make_sequence(const ArrayList& uuidSeq) -> Ref - { - GUIDSequence* seq = new GUIDSequence(); - MUST_PASS(seq); - - Ref seq_ref{*seq}; - - seq_ref.Leak().fMs1 = uuidSeq[0]; - seq_ref.Leak().fMs2 = uuidSeq[1]; - seq_ref.Leak().fMs3 = uuidSeq[2]; - seq_ref.Leak().fMs4[0] = uuidSeq[3]; - seq_ref.Leak().fMs4[1] = uuidSeq[4]; - seq_ref.Leak().fMs4[2] = uuidSeq[5]; - seq_ref.Leak().fMs4[3] = uuidSeq[6]; - seq_ref.Leak().fMs4[4] = uuidSeq[7]; - seq_ref.Leak().fMs4[5] = uuidSeq[8]; - seq_ref.Leak().fMs4[6] = uuidSeq[9]; - seq_ref.Leak().fMs4[7] = uuidSeq[10]; - - return seq_ref; - } - - // @brief Tries to make a guid out of a string. - // This function is not complete for now - auto cf_try_guid_to_string(Ref& seq) -> ErrorOr> - { - Char buf[kUUIDSize]; - - for (SizeT index = 0; index < 16; ++index) - { - buf[index] = seq.Leak().u8[index] + kAsciiBegin; - } - - for (SizeT index = 16; index < 24; ++index) - { - buf[index] = seq.Leak().u16[index] + kAsciiBegin; - } - - for (SizeT index = 24; index < 28; ++index) - { - buf[index] = seq.Leak().u32[index] + kAsciiBegin; - } - - auto view = StringBuilder::Construct(buf); - - if (view) - return ErrorOr>{view.Leak()}; - - return ErrorOr>{-1}; - } -} // namespace Kernel::XRN::Version1 diff --git a/dev/zka/src/GUIDWrapper.cc b/dev/zka/src/GUIDWrapper.cc new file mode 100644 index 00000000..53d983a1 --- /dev/null +++ b/dev/zka/src/GUIDWrapper.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +namespace Kernel::XRN +{ +} diff --git a/dev/zka/src/GUIDWrapper.cxx b/dev/zka/src/GUIDWrapper.cxx deleted file mode 100644 index 1c0eb5ef..00000000 --- a/dev/zka/src/GUIDWrapper.cxx +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -namespace Kernel::XRN -{ -} diff --git a/dev/zka/src/HardwareThreadScheduler.cc b/dev/zka/src/HardwareThreadScheduler.cc new file mode 100644 index 00000000..37d81f04 --- /dev/null +++ b/dev/zka/src/HardwareThreadScheduler.cc @@ -0,0 +1,193 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include +#include + +///! BUGS: 0 + +///! @file MP.cxx +///! @brief This file handles multi processing in the Kernel. +///! @brief Multi processing is needed for multi-tasking operations. + +namespace Kernel +{ + HardwareThreadScheduler* kHardwareThreadScheduler = nullptr; + + ///! A HardwareThread class takes care of it's owned hardware thread. + ///! It has a stack for it's core. + + ///! @brief C++ constructor. + HardwareThread::HardwareThread() = default; + + ///! @brief C++ destructor. + HardwareThread::~HardwareThread() = default; + + //! @brief returns the id of the thread. + const ThreadID& HardwareThread::ID() noexcept + { + return fID; + } + + //! @brief returns the kind of thread we have. + const ThreadKind& HardwareThread::Kind() noexcept + { + return fKind; + } + + //! @brief is the thread busy? + Bool HardwareThread::IsBusy() noexcept + { + STATIC Int64 busy_timer = 0U; + + if (busy_timer > this->fPTime) + { + busy_timer = 0U; + fBusy = No; + } + + 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) + mp_hang_thread(fStack); + else + mp_wakeup_thread(fStack); + } + + /// @note Those symbols are needed in order to switch and validate the stack. + + EXTERN Bool hal_check_stack(HAL::StackFramePtr stackPtr); + EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr); + + /// @brief Switch to hardware thread. + /// @param stack the new hardware thread. + /// @retval true stack was changed, code is running. + /// @retval false stack is invalid, previous code is running. + Bool HardwareThread::Switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr frame) + { + if (!frame || + !image || + !stack_ptr) + return No; + + if (!this->IsWakeup()) + return No; + + if (this->IsBusy()) + return No; + + fStack = frame; + + Bool ret = mp_register_process(image, stack_ptr, fStack); + + if (ret) + this->Busy(true); + + return ret; + } + + ///! @brief Tells if processor is waked up. + bool HardwareThread::IsWakeup() noexcept + { + return fWakeup; + } + + ///! @brief Constructor and destructors. + + ///! @brief Default constructor. + HardwareThreadScheduler::HardwareThreadScheduler() = default; + + ///! @brief Default destructor. + HardwareThreadScheduler::~HardwareThreadScheduler() = default; + + /// @brief Shared singleton function + HardwareThreadScheduler& HardwareThreadScheduler::The() + { + MUST_PASS(kHardwareThreadScheduler); + return *kHardwareThreadScheduler; + } + + /// @brief Get Stack Frame of Core + HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept + { + return fThreadList[fCurrentThread].fStack; + } + + /** + * Get Hardware thread at index. + * @param idx the index + * @return the reference to the hardware thread. + */ + Ref HardwareThreadScheduler::operator[](const SizeT& idx) + { + if (idx == 0) + { + if (fThreadList[idx].Kind() != kHartSystemReserved) + { + fThreadList[idx].fKind = kHartBoot; + } + } + else if (idx >= cMaxHartInsideSched) + { + static HardwareThread* fakeThread = nullptr; + return {fakeThread}; + } + + return &fThreadList[idx]; + } + + /** + * Check if thread pool isn't empty. + * @return + */ + HardwareThreadScheduler::operator bool() noexcept + { + return !fThreadList.Empty(); + } + + /** + * Reverse operator bool + * @return + */ + bool HardwareThreadScheduler::operator!() noexcept + { + return fThreadList.Empty(); + } + + /// @brief Returns the amount of core present. + /// @return the number of cores. + SizeT HardwareThreadScheduler::Count() noexcept + { + return fThreadList.Capacity(); + } +} // namespace Kernel diff --git a/dev/zka/src/HardwareThreadScheduler.cxx b/dev/zka/src/HardwareThreadScheduler.cxx deleted file mode 100644 index 50a153f1..00000000 --- a/dev/zka/src/HardwareThreadScheduler.cxx +++ /dev/null @@ -1,193 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include -#include - -///! BUGS: 0 - -///! @file MP.cxx -///! @brief This file handles multi processing in the Kernel. -///! @brief Multi processing is needed for multi-tasking operations. - -namespace Kernel -{ - HardwareThreadScheduler* kHardwareThreadScheduler = nullptr; - - ///! A HardwareThread class takes care of it's owned hardware thread. - ///! It has a stack for it's core. - - ///! @brief C++ constructor. - HardwareThread::HardwareThread() = default; - - ///! @brief C++ destructor. - HardwareThread::~HardwareThread() = default; - - //! @brief returns the id of the thread. - const ThreadID& HardwareThread::ID() noexcept - { - return fID; - } - - //! @brief returns the kind of thread we have. - const ThreadKind& HardwareThread::Kind() noexcept - { - return fKind; - } - - //! @brief is the thread busy? - Bool HardwareThread::IsBusy() noexcept - { - STATIC Int64 busy_timer = 0U; - - if (busy_timer > this->fPTime) - { - busy_timer = 0U; - fBusy = No; - } - - 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) - mp_hang_thread(fStack); - else - mp_wakeup_thread(fStack); - } - - /// @note Those symbols are needed in order to switch and validate the stack. - - EXTERN Bool hal_check_stack(HAL::StackFramePtr stackPtr); - EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr); - - /// @brief Switch to hardware thread. - /// @param stack the new hardware thread. - /// @retval true stack was changed, code is running. - /// @retval false stack is invalid, previous code is running. - Bool HardwareThread::Switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr frame) - { - if (!frame || - !image || - !stack_ptr) - return No; - - if (!this->IsWakeup()) - return No; - - if (this->IsBusy()) - return No; - - fStack = frame; - - Bool ret = mp_register_process(image, stack_ptr, fStack); - - if (ret) - this->Busy(true); - - return ret; - } - - ///! @brief Tells if processor is waked up. - bool HardwareThread::IsWakeup() noexcept - { - return fWakeup; - } - - ///! @brief Constructor and destructors. - - ///! @brief Default constructor. - HardwareThreadScheduler::HardwareThreadScheduler() = default; - - ///! @brief Default destructor. - HardwareThreadScheduler::~HardwareThreadScheduler() = default; - - /// @brief Shared singleton function - HardwareThreadScheduler& HardwareThreadScheduler::The() - { - MUST_PASS(kHardwareThreadScheduler); - return *kHardwareThreadScheduler; - } - - /// @brief Get Stack Frame of Core - HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept - { - return fThreadList[fCurrentThread].fStack; - } - - /** - * Get Hardware thread at index. - * @param idx the index - * @return the reference to the hardware thread. - */ - Ref HardwareThreadScheduler::operator[](const SizeT& idx) - { - if (idx == 0) - { - if (fThreadList[idx].Kind() != kHartSystemReserved) - { - fThreadList[idx].fKind = kHartBoot; - } - } - else if (idx >= cMaxHartInsideSched) - { - static HardwareThread* fakeThread = nullptr; - return {fakeThread}; - } - - return &fThreadList[idx]; - } - - /** - * Check if thread pool isn't empty. - * @return - */ - HardwareThreadScheduler::operator bool() noexcept - { - return !fThreadList.Empty(); - } - - /** - * Reverse operator bool - * @return - */ - bool HardwareThreadScheduler::operator!() noexcept - { - return fThreadList.Empty(); - } - - /// @brief Returns the amount of core present. - /// @return the number of cores. - SizeT HardwareThreadScheduler::Count() noexcept - { - return fThreadList.Capacity(); - } -} // namespace Kernel diff --git a/dev/zka/src/Heap.cc b/dev/zka/src/Heap.cc new file mode 100644 index 00000000..45b7aa73 --- /dev/null +++ b/dev/zka/src/Heap.cc @@ -0,0 +1,265 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------- + + Revision History: + 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field. + 20/10/24: Fix mm_new_ and mm_delete_ APIs inside Heap.h header. (amlal) + + ------------------------------------------- */ + +//! @file Heap.cxx +//! @brief Kernel's heap manager, serves as the main memory manager. + +#define kKernelHeapMagic (0xD4D7D5) +#define kKernelAlignSz (__BIGGEST_ALIGNMENT__) + +namespace Kernel +{ + /// @brief Contains data structures and algorithms for the heap. + namespace Detail + { + struct PACKED HEAP_INFORMATION_BLOCK; + + /// @brief Kernel heap information block. + /// Located before the address bytes. + /// | HIB | CLASS/STRUCT/DATA TYPES... | + struct PACKED HEAP_INFORMATION_BLOCK final + { + ///! @brief 32-bit value which contains the magic number of the heap. + UInt32 fMagic : 24; + + ///! @brief Boolean value which tells if the heap is allocated. + Boolean fPresent : 1; + + /// @brief Is this valued owned by the user? + Boolean fWr : 1; + + /// @brief Is this valued owned by the user? + Boolean fUser : 1; + + /// @brief Is this a page pointer? + Boolean fPage : 1; + + ///! @brief 32-bit CRC checksum. + UInt32 fCRC32; + + /// @brief 64-bit pointer size. + SizeT fHeapSize; + + /// @brief 64-bit target pointer. + UIntPtr fHeapPtr; + + /// @brief Padding bytes for header. + UInt8 fPadding[kKernelAlignSz]; + }; + + /// @brief Check for heap address validity. + /// @param heap_ptr The address_ptr to check. + /// @return Bool if the pointer is valid or not. + auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool + { + if (!heap_ptr) + return false; + + /// Add that check in case we're having an integer underflow. /// + + auto base_heap = (IntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK); + + if (base_heap < 0) + { + return false; + } + + return true; + } + + typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR; + } // namespace Detail + + Detail::HEAP_INFORMATION_BLOCK_PTR kLatestAllocation = nullptr; + + /// @brief Declare a new size for ptr_heap. + /// @param ptr_heap the pointer. + /// @return Newly allocated heap header. + VoidPtr mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) + { + if (Detail::mm_check_heap_address(ptr_heap) == No) + return nullptr; + + if (!ptr_heap || new_sz < 1) + return nullptr; + + kcout << "This function is not implemented in the kernel, please refrain from using that.\r"; + ke_stop(RUNTIME_CHECK_PROCESS); + + return nullptr; + } + + /// @brief Allocate chunk of memory. + /// @param sz Size of pointer + /// @param wr Read Write bit. + /// @param user User enable bit. + /// @return The newly allocated pointer. + VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user) + { + auto sz_fix = sz; + + if (sz_fix == 0) + return nullptr; + + sz_fix += sizeof(Detail::HEAP_INFORMATION_BLOCK); + + PageMgr heap_mgr; + auto wrapper = heap_mgr.Request(wr, user, No, sz_fix); + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast( + wrapper.VirtualAddress() + sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + heap_info_ptr->fHeapSize = sz_fix; + heap_info_ptr->fMagic = kKernelHeapMagic; + heap_info_ptr->fCRC32 = No; // dont fill it for now. + heap_info_ptr->fHeapPtr = reinterpret_cast(heap_info_ptr) + sizeof(Detail::HEAP_INFORMATION_BLOCK); + heap_info_ptr->fPage = No; + heap_info_ptr->fWr = wr; + heap_info_ptr->fUser = user; + heap_info_ptr->fPresent = Yes; + + rt_set_memory(heap_info_ptr->fPadding, 0, kKernelAlignSz); + + auto result = reinterpret_cast(heap_info_ptr->fHeapPtr); + + kLatestAllocation = heap_info_ptr; + + return result; + } + + /// @brief Makes a page heap. + /// @param heap_ptr the pointer to make a page heap. + /// @return kErrorSuccess if successful, otherwise an error code. + Int32 mm_make_ke_page(VoidPtr heap_ptr) + { + if (Detail::mm_check_heap_address(heap_ptr) == No) + return -kErrorHeapNotPresent; + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = + reinterpret_cast( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (!heap_ptr) + return -kErrorHeapNotPresent; + + heap_blk->fPage = true; + + return kErrorSuccess; + } + + /// @brief Declare pointer as free. + /// @param heap_ptr the pointer. + /// @return + Int32 mm_delete_heap(VoidPtr heap_ptr) + { + if (Detail::mm_check_heap_address(heap_ptr) == No) + return -kErrorHeapNotPresent; + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = + reinterpret_cast( + (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heap_blk && heap_blk->fMagic == kKernelHeapMagic) + { + if (!heap_blk->fPresent) + { + return -kErrorHeapNotPresent; + } + + if (heap_blk->fCRC32 != 0) + { + if (heap_blk->fCRC32 != + ke_calculate_crc32((Char*)heap_blk->fHeapPtr, + heap_blk->fHeapSize)) + { + if (!heap_blk->fUser) + { + ke_stop(RUNTIME_CHECK_POINTER); + } + } + } + + heap_blk->fHeapSize = 0UL; + heap_blk->fPresent = No; + heap_blk->fHeapPtr = 0; + heap_blk->fCRC32 = 0; + heap_blk->fWr = No; + heap_blk->fUser = No; + heap_blk->fMagic = 0; + + PTEWrapper pageWrapper(No, No, No, reinterpret_cast(heap_blk) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + Ref pteAddress{pageWrapper}; + + kcout << "Freeing pointer address: " << hex_number(reinterpret_cast(heap_blk) - sizeof(Detail::HEAP_INFORMATION_BLOCK)) << endl; + + PageMgr heap_mgr; + heap_mgr.Free(pteAddress); + + return kErrorSuccess; + } + + return -kErrorInternal; + } + + /// @brief Check if pointer is a valid Kernel pointer. + /// @param heap_ptr the pointer + /// @return if it exists. + Boolean mm_is_valid_heap(VoidPtr heap_ptr) + { + if (heap_ptr) + { + Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = + reinterpret_cast( + (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heap_blk && heap_blk->fPresent && heap_blk->fMagic == kKernelHeapMagic) + { + return Yes; + } + } + + return No; + } + + /// @brief Protect the heap with a CRC value. + /// @param heap_ptr HIB pointer. + /// @return if it valid: point has crc now., otherwise fail. + Boolean mm_protect_heap(VoidPtr heap_ptr) + { + if (heap_ptr) + { + Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = + reinterpret_cast( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heap_ptr && heap_blk->fPresent && kKernelHeapMagic == heap_blk->fMagic) + { + heap_blk->fCRC32 = + ke_calculate_crc32((Char*)heap_blk->fHeapPtr, heap_blk->fHeapSize); + + return Yes; + } + } + + return No; + } +} // namespace Kernel diff --git a/dev/zka/src/Heap.cxx b/dev/zka/src/Heap.cxx deleted file mode 100644 index 63e9286a..00000000 --- a/dev/zka/src/Heap.cxx +++ /dev/null @@ -1,265 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------- - - Revision History: - 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field. - 20/10/24: Fix mm_new_ and mm_delete_ APIs inside Heap.hxx header. (amlal) - - ------------------------------------------- */ - -//! @file Heap.cxx -//! @brief Kernel's heap manager, serves as the main memory manager. - -#define kKernelHeapMagic (0xD4D7D5) -#define kKernelAlignSz (__BIGGEST_ALIGNMENT__) - -namespace Kernel -{ - /// @brief Contains data structures and algorithms for the heap. - namespace Detail - { - struct PACKED HEAP_INFORMATION_BLOCK; - - /// @brief Kernel heap information block. - /// Located before the address bytes. - /// | HIB | CLASS/STRUCT/DATA TYPES... | - struct PACKED HEAP_INFORMATION_BLOCK final - { - ///! @brief 32-bit value which contains the magic number of the heap. - UInt32 fMagic : 24; - - ///! @brief Boolean value which tells if the heap is allocated. - Boolean fPresent : 1; - - /// @brief Is this valued owned by the user? - Boolean fWr : 1; - - /// @brief Is this valued owned by the user? - Boolean fUser : 1; - - /// @brief Is this a page pointer? - Boolean fPage : 1; - - ///! @brief 32-bit CRC checksum. - UInt32 fCRC32; - - /// @brief 64-bit pointer size. - SizeT fHeapSize; - - /// @brief 64-bit target pointer. - UIntPtr fHeapPtr; - - /// @brief Padding bytes for header. - UInt8 fPadding[kKernelAlignSz]; - }; - - /// @brief Check for heap address validity. - /// @param heap_ptr The address_ptr to check. - /// @return Bool if the pointer is valid or not. - auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool - { - if (!heap_ptr) - return false; - - /// Add that check in case we're having an integer underflow. /// - - auto base_heap = (IntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK); - - if (base_heap < 0) - { - return false; - } - - return true; - } - - typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR; - } // namespace Detail - - Detail::HEAP_INFORMATION_BLOCK_PTR kLatestAllocation = nullptr; - - /// @brief Declare a new size for ptr_heap. - /// @param ptr_heap the pointer. - /// @return Newly allocated heap header. - VoidPtr mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) - { - if (Detail::mm_check_heap_address(ptr_heap) == No) - return nullptr; - - if (!ptr_heap || new_sz < 1) - return nullptr; - - kcout << "This function is not implemented in the kernel, please refrain from using that.\r"; - ke_stop(RUNTIME_CHECK_PROCESS); - - return nullptr; - } - - /// @brief Allocate chunk of memory. - /// @param sz Size of pointer - /// @param wr Read Write bit. - /// @param user User enable bit. - /// @return The newly allocated pointer. - VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user) - { - auto sz_fix = sz; - - if (sz_fix == 0) - return nullptr; - - sz_fix += sizeof(Detail::HEAP_INFORMATION_BLOCK); - - PageMgr heap_mgr; - auto wrapper = heap_mgr.Request(wr, user, No, sz_fix); - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = - reinterpret_cast( - wrapper.VirtualAddress() + sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - heap_info_ptr->fHeapSize = sz_fix; - heap_info_ptr->fMagic = kKernelHeapMagic; - heap_info_ptr->fCRC32 = No; // dont fill it for now. - heap_info_ptr->fHeapPtr = reinterpret_cast(heap_info_ptr) + sizeof(Detail::HEAP_INFORMATION_BLOCK); - heap_info_ptr->fPage = No; - heap_info_ptr->fWr = wr; - heap_info_ptr->fUser = user; - heap_info_ptr->fPresent = Yes; - - rt_set_memory(heap_info_ptr->fPadding, 0, kKernelAlignSz); - - auto result = reinterpret_cast(heap_info_ptr->fHeapPtr); - - kLatestAllocation = heap_info_ptr; - - return result; - } - - /// @brief Makes a page heap. - /// @param heap_ptr the pointer to make a page heap. - /// @return kErrorSuccess if successful, otherwise an error code. - Int32 mm_make_ke_page(VoidPtr heap_ptr) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return -kErrorHeapNotPresent; - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (!heap_ptr) - return -kErrorHeapNotPresent; - - heap_blk->fPage = true; - - return kErrorSuccess; - } - - /// @brief Declare pointer as free. - /// @param heap_ptr the pointer. - /// @return - Int32 mm_delete_heap(VoidPtr heap_ptr) - { - if (Detail::mm_check_heap_address(heap_ptr) == No) - return -kErrorHeapNotPresent; - - Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = - reinterpret_cast( - (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (heap_blk && heap_blk->fMagic == kKernelHeapMagic) - { - if (!heap_blk->fPresent) - { - return -kErrorHeapNotPresent; - } - - if (heap_blk->fCRC32 != 0) - { - if (heap_blk->fCRC32 != - ke_calculate_crc32((Char*)heap_blk->fHeapPtr, - heap_blk->fHeapSize)) - { - if (!heap_blk->fUser) - { - ke_stop(RUNTIME_CHECK_POINTER); - } - } - } - - heap_blk->fHeapSize = 0UL; - heap_blk->fPresent = No; - heap_blk->fHeapPtr = 0; - heap_blk->fCRC32 = 0; - heap_blk->fWr = No; - heap_blk->fUser = No; - heap_blk->fMagic = 0; - - PTEWrapper pageWrapper(No, No, No, reinterpret_cast(heap_blk) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - Ref pteAddress{pageWrapper}; - - kcout << "Freeing pointer address: " << hex_number(reinterpret_cast(heap_blk) - sizeof(Detail::HEAP_INFORMATION_BLOCK)) << endl; - - PageMgr heap_mgr; - heap_mgr.Free(pteAddress); - - return kErrorSuccess; - } - - return -kErrorInternal; - } - - /// @brief Check if pointer is a valid Kernel pointer. - /// @param heap_ptr the pointer - /// @return if it exists. - Boolean mm_is_valid_heap(VoidPtr heap_ptr) - { - if (heap_ptr) - { - Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = - reinterpret_cast( - (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (heap_blk && heap_blk->fPresent && heap_blk->fMagic == kKernelHeapMagic) - { - return Yes; - } - } - - return No; - } - - /// @brief Protect the heap with a CRC value. - /// @param heap_ptr HIB pointer. - /// @return if it valid: point has crc now., otherwise fail. - Boolean mm_protect_heap(VoidPtr heap_ptr) - { - if (heap_ptr) - { - Detail::HEAP_INFORMATION_BLOCK_PTR heap_blk = - reinterpret_cast( - (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); - - if (heap_ptr && heap_blk->fPresent && kKernelHeapMagic == heap_blk->fMagic) - { - heap_blk->fCRC32 = - ke_calculate_crc32((Char*)heap_blk->fHeapPtr, heap_blk->fHeapSize); - - return Yes; - } - } - - return No; - } -} // namespace Kernel diff --git a/dev/zka/src/IDLLObject.cc b/dev/zka/src/IDLLObject.cc new file mode 100644 index 00000000..4e5f7aa2 --- /dev/null +++ b/dev/zka/src/IDLLObject.cc @@ -0,0 +1,15 @@ +/* + * ======================================================== + * + * minoskrnl + * Copyright ZKA Web Services Co., all rights reserved. + * + * ======================================================== + */ + +#include +#include + +#include + +using namespace Kernel; diff --git a/dev/zka/src/IDLLObject.cxx b/dev/zka/src/IDLLObject.cxx deleted file mode 100644 index a9ab9542..00000000 --- a/dev/zka/src/IDLLObject.cxx +++ /dev/null @@ -1,15 +0,0 @@ -/* - * ======================================================== - * - * minoskrnl - * Copyright ZKA Web Services Co., all rights reserved. - * - * ======================================================== - */ - -#include -#include - -#include - -using namespace Kernel; diff --git a/dev/zka/src/IPEFDLLObject.cc b/dev/zka/src/IPEFDLLObject.cc new file mode 100644 index 00000000..d7fe2948 --- /dev/null +++ b/dev/zka/src/IPEFDLLObject.cc @@ -0,0 +1,102 @@ +/* + * ======================================================== + * + * minoskrnl + * Copyright ZKA Web Services Co., all rights reserved. + * + * ======================================================== + */ + +#include +#include +#include +#include +#include +#include + +/* ------------------------------------------- + + Revision History: + + 01/02/24: Reworked dll ABI, expect a rtl_init_dll and + rtl_fini_dll (amlel) 15/02/24: Breaking changes, changed the name of the + routines. (amlel) + + 07/28/24: Replace rt_library_free with rtl_fini_dll + + 10/8/24: FIX: Fix log comment. + + ------------------------------------------- */ + +using namespace Kernel; + +/***********************************************************************************/ +/// @file PEFSharedObjectRT.cxx +/// @brief PEF's shared object runtime. +/***********************************************************************************/ + +/***********************************************************************************/ +/** @brief Library initializer. */ +/***********************************************************************************/ + +EXTERN_C IDLL rtl_init_dll(UserProcess* header) +{ + IDLL dll_obj = tls_new_class(); + + if (!dll_obj) + { + header->Crash(); + + return nullptr; + } + + dll_obj->Mount(tls_new_class()); + + if (!dll_obj->Get()) + { + header->Crash(); + + return nullptr; + } + + dll_obj->Get()->fImageObject = + header->Image; + + if (!dll_obj->Get()->fImageObject) + { + header->Crash(); + + return nullptr; + } + + dll_obj->Get()->fImageEntrypointOffset = + dll_obj->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); + + return dll_obj; +} + +/***********************************************************************************/ +/** @brief Frees the dll_obj. */ +/** @note Please check if the dll_obj got freed! */ +/** @param dll_obj The dll_obj to free. */ +/** @param successful Reports if successful or not. */ +/***********************************************************************************/ + +EXTERN_C Void rtl_fini_dll(UserProcess* header, IDLL dll_obj, Bool* successful) +{ + MUST_PASS(successful); + + // sanity check (will also trigger a bug check if this fails) + if (dll_obj == nullptr) + { + *successful = false; + header->Crash(); + } + + delete dll_obj->Get(); + delete dll_obj; + + dll_obj = nullptr; + + *successful = true; +} diff --git a/dev/zka/src/IPEFDLLObject.cxx b/dev/zka/src/IPEFDLLObject.cxx deleted file mode 100644 index e2e85dcc..00000000 --- a/dev/zka/src/IPEFDLLObject.cxx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ======================================================== - * - * minoskrnl - * Copyright ZKA Web Services Co., all rights reserved. - * - * ======================================================== - */ - -#include -#include -#include -#include -#include -#include - -/* ------------------------------------------- - - Revision History: - - 01/02/24: Reworked dll ABI, expect a rtl_init_dll and - rtl_fini_dll (amlel) 15/02/24: Breaking changes, changed the name of the - routines. (amlel) - - 07/28/24: Replace rt_library_free with rtl_fini_dll - - 10/8/24: FIX: Fix log comment. - - ------------------------------------------- */ - -using namespace Kernel; - -/***********************************************************************************/ -/// @file PEFSharedObjectRT.cxx -/// @brief PEF's shared object runtime. -/***********************************************************************************/ - -/***********************************************************************************/ -/** @brief Library initializer. */ -/***********************************************************************************/ - -EXTERN_C IDLL rtl_init_dll(UserProcess* header) -{ - IDLL dll_obj = tls_new_class(); - - if (!dll_obj) - { - header->Crash(); - - return nullptr; - } - - dll_obj->Mount(tls_new_class()); - - if (!dll_obj->Get()) - { - header->Crash(); - - return nullptr; - } - - dll_obj->Get()->fImageObject = - header->Image; - - if (!dll_obj->Get()->fImageObject) - { - header->Crash(); - - return nullptr; - } - - dll_obj->Get()->fImageEntrypointOffset = - dll_obj->Load(kPefStart, rt_string_len(kPefStart, 0), kPefCode); - - return dll_obj; -} - -/***********************************************************************************/ -/** @brief Frees the dll_obj. */ -/** @note Please check if the dll_obj got freed! */ -/** @param dll_obj The dll_obj to free. */ -/** @param successful Reports if successful or not. */ -/***********************************************************************************/ - -EXTERN_C Void rtl_fini_dll(UserProcess* header, IDLL dll_obj, Bool* successful) -{ - MUST_PASS(successful); - - // sanity check (will also trigger a bug check if this fails) - if (dll_obj == nullptr) - { - *successful = false; - header->Crash(); - } - - delete dll_obj->Get(); - delete dll_obj; - - dll_obj = nullptr; - - *successful = true; -} diff --git a/dev/zka/src/IndexableProperty.cc b/dev/zka/src/IndexableProperty.cc new file mode 100644 index 00000000..05438467 --- /dev/null +++ b/dev/zka/src/IndexableProperty.cc @@ -0,0 +1,57 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include +#include + +/// @brief File indexer API for fast path access. +/// BUGS: 0 + +#define kMaxLenIndexer (256U) + +namespace Kernel +{ + namespace Indexer + { + IndexProperty& IndexableProperty::Leak() noexcept + { + return fIndex; + } + + Void IndexableProperty::AddFlag(Int16 flag) + { + fFlags |= flag; + } + + Void IndexableProperty::RemoveFlag(Int16 flag) + { + fFlags &= flag; + } + + Int16 IndexableProperty::HasFlag(Int16 flag) + { + return fFlags & flag; + } + + /// @brief Index a file into the indexer instance. + /// @param filename filesystem path to access. + /// @param filenameLen used bytes in path. + /// @param indexer the filesystem indexer. + /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)). + Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) + { + if (!indexer.HasFlag(kIndexerClaimed)) + { + indexer.AddFlag(kIndexerClaimed); + rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen); + + kcout << "FSKit: Indexed new file: " << filename << endl; + } + } + } // namespace Indexer +} // namespace Kernel diff --git a/dev/zka/src/IndexableProperty.cxx b/dev/zka/src/IndexableProperty.cxx deleted file mode 100644 index 7595291c..00000000 --- a/dev/zka/src/IndexableProperty.cxx +++ /dev/null @@ -1,57 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include -#include - -/// @brief File indexer API for fast path access. -/// BUGS: 0 - -#define kMaxLenIndexer (256U) - -namespace Kernel -{ - namespace Indexer - { - IndexProperty& IndexableProperty::Leak() noexcept - { - return fIndex; - } - - Void IndexableProperty::AddFlag(Int16 flag) - { - fFlags |= flag; - } - - Void IndexableProperty::RemoveFlag(Int16 flag) - { - fFlags &= flag; - } - - Int16 IndexableProperty::HasFlag(Int16 flag) - { - return fFlags & flag; - } - - /// @brief Index a file into the indexer instance. - /// @param filename filesystem path to access. - /// @param filenameLen used bytes in path. - /// @param indexer the filesystem indexer. - /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)). - Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer) - { - if (!indexer.HasFlag(kIndexerClaimed)) - { - indexer.AddFlag(kIndexerClaimed); - rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen); - - kcout << "FSKit: Indexed new file: " << filename << endl; - } - } - } // namespace Indexer -} // namespace Kernel diff --git a/dev/zka/src/Json.cc b/dev/zka/src/Json.cc new file mode 100644 index 00000000..4c3f07dc --- /dev/null +++ b/dev/zka/src/Json.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +/// @brief Undefined object, is null in length. +cInitObject(Kernel::JSON::kNull, Kernel::JSON); diff --git a/dev/zka/src/Json.cxx b/dev/zka/src/Json.cxx deleted file mode 100644 index acf46f8a..00000000 --- a/dev/zka/src/Json.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -using namespace Kernel; - -/// @brief Undefined object, is null in length. -cInitObject(Kernel::JSON::kNull, Kernel::JSON); diff --git a/dev/zka/src/LPC.cc b/dev/zka/src/LPC.cc new file mode 100644 index 00000000..a39b0857 --- /dev/null +++ b/dev/zka/src/LPC.cc @@ -0,0 +1,34 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + STATIC Bool kRaiseOnBugCheck = false; + + /// @brief Does a system wide bug check. + /// @param void no params. + /// @return if error-free: false, otherwise true. + Boolean err_bug_check(void) noexcept + { + if (kRaiseOnBugCheck) + { + ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); + } + + return No; + } + + /// @brief Tells if we should raise a bug check not. + /// @param void + /// @return void + Void err_bug_check_raise(Void) noexcept + { + kRaiseOnBugCheck = true; + } +} // namespace Kernel diff --git a/dev/zka/src/LPC.cxx b/dev/zka/src/LPC.cxx deleted file mode 100644 index 5cf64e26..00000000 --- a/dev/zka/src/LPC.cxx +++ /dev/null @@ -1,34 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - STATIC Bool kRaiseOnBugCheck = false; - - /// @brief Does a system wide bug check. - /// @param void no params. - /// @return if error-free: false, otherwise true. - Boolean err_bug_check(void) noexcept - { - if (kRaiseOnBugCheck) - { - ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); - } - - return No; - } - - /// @brief Tells if we should raise a bug check not. - /// @param void - /// @return void - Void err_bug_check_raise(Void) noexcept - { - kRaiseOnBugCheck = true; - } -} // namespace Kernel diff --git a/dev/zka/src/LockDelegate.cc b/dev/zka/src/LockDelegate.cc new file mode 100644 index 00000000..cc2a36b8 --- /dev/null +++ b/dev/zka/src/LockDelegate.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + /// @note Leave it empty for now. +} // namespace Kernel diff --git a/dev/zka/src/LockDelegate.cxx b/dev/zka/src/LockDelegate.cxx deleted file mode 100644 index d101615c..00000000 --- a/dev/zka/src/LockDelegate.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - /// @note Leave it empty for now. -} // namespace Kernel diff --git a/dev/zka/src/MutableArray.cc b/dev/zka/src/MutableArray.cc new file mode 100644 index 00000000..de0523e1 --- /dev/null +++ b/dev/zka/src/MutableArray.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/MutableArray.cxx b/dev/zka/src/MutableArray.cxx deleted file mode 100644 index 48b9c787..00000000 --- a/dev/zka/src/MutableArray.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/NeFS+FileMgr.cc b/dev/zka/src/NeFS+FileMgr.cc new file mode 100644 index 00000000..3cc5400b --- /dev/null +++ b/dev/zka/src/NeFS+FileMgr.cc @@ -0,0 +1,248 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +#ifndef __ZKA_MINIMAL_OS__ +#ifdef __FSKIT_USE_NEFS__ + +/// @brief NeFS File manager. +/// BUGS: 0 + +namespace Kernel +{ + /// @brief C++ constructor + NeFileSystemMgr::NeFileSystemMgr() + { + MUST_PASS(Detail::fs_init_newfs()); + fImpl = mm_new_class(); + MUST_PASS(fImpl); + + kcout << "We are done here... (NeFileSystemMgr).\r"; + } + + NeFileSystemMgr::~NeFileSystemMgr() + { + if (fImpl) + { + kcout << "Destroying FS class (NeFS)...\r"; + + delete fImpl; + fImpl = nullptr; + } + } + + /// @brief Removes a node from the filesystem. + /// @param fileName The filename + /// @return If it was deleted or not. + bool NeFileSystemMgr::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 NeFileSystemMgr::Create(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path)); + } + + /// @brief Creates a node with is a directory. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindDir)); + } + + /// @brief Creates a node with is a alias. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::CreateAlias(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); + } + + /// @brief Creates a node with is a page file. + /// @param path The filename path. + /// @return The Node pointer. + NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) + { + return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindPage)); + } + + /// @brief Gets the root directory. + /// @return + const Char* NeFileSystemHelper::Root() + { + return kNeFSRoot; + } + + /// @brief Gets the up-dir directory. + /// @return + const Char* NeFileSystemHelper::UpDir() + { + return kNeFSUpDir; + } + + /// @brief Gets the separator character. + /// @return + const Char NeFileSystemHelper::Separator() + { + return kNeFSSeparator; + } + + /// @brief Gets the metafile character. + /// @return + const Char NeFileSystemHelper::MetaFile() + { + return kNeFSMetaFilePrefix; + } + + /// @brief Opens a new file. + /// @param path + /// @param r + /// @return + _Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) + { + if (!path || *path == 0) + return nullptr; + + if (!r || *r == 0) + return nullptr; + + auto catalog = fImpl->GetCatalog(path); + + return node_cast(catalog); + } + + /// @brief Writes to a catalog's fork. + /// @param node the node ptr. + /// @param data the data. + /// @param flags the size. + /// @return + Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) + { + if (!node) + return; + if (!size) + return; + + constexpr auto cDataForkName = kNeFSDataFork; + this->Write(cDataForkName, node, data, flags, size); + } + + /// @brief Read from filesystem fork. + /// @param node the catalog node. + /// @param flags the flags with it. + /// @param sz the size to read. + /// @return + _Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) + { + if (!node) + return nullptr; + if (!size) + return nullptr; + + constexpr auto cDataForkName = kNeFSDataFork; + return this->Read(cDataForkName, node, flags, size); + } + + Void NeFileSystemMgr::Write(_Input const Char* name, + _Input NodePtr node, + _Input VoidPtr data, + _Input Int32 flags, + _Input SizeT size) + { + if (!size || + size > kNeFSForkSize) + return; + + if (!data) + return; + + ZKA_UNUSED(flags); + + if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) + fImpl->WriteCatalog(reinterpret_cast(node), (flags & cFileFlagRsrc ? true : false), data, size, + name); + } + + _Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, + _Input NodePtr node, + _Input Int32 flags, + _Input SizeT sz) + { + if (sz > kNeFSForkSize) + return nullptr; + + if (!sz) + return nullptr; + + ZKA_UNUSED(flags); + + if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) + return fImpl->ReadCatalog(reinterpret_cast(node), (flags & cFileFlagRsrc ? true : false), sz, + name); + + return nullptr; + } + + /// @brief Seek from Catalog. + /// @param node + /// @param off + /// @retval true always returns false, this is unimplemented. + /// @retval false always returns this, it is unimplemented. + + _Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) + { + if (!node || off == 0) + return false; + + return 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. + + _Output SizeT NeFileSystemMgr::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. + + _Output Bool NeFileSystemMgr::Rewind(NodePtr node) + { + if (!node) + return false; + + return this->Seek(node, 0); + } + + /// @brief Returns the filesystem parser. + /// @return the Filesystem parser class. + _Output NeFSParser* NeFileSystemMgr::GetParser() noexcept + { + return fImpl; + } +} // namespace Kernel + +#endif // ifdef __FSKIT_USE_NEFS__ +#endif // ifndef __ZKA_MINIMAL_OS__ diff --git a/dev/zka/src/NeFS+FileMgr.cxx b/dev/zka/src/NeFS+FileMgr.cxx deleted file mode 100644 index da5a1285..00000000 --- a/dev/zka/src/NeFS+FileMgr.cxx +++ /dev/null @@ -1,248 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -#ifndef __ZKA_MINIMAL_OS__ -#ifdef __FSKIT_USE_NEFS__ - -/// @brief NeFS File manager. -/// BUGS: 0 - -namespace Kernel -{ - /// @brief C++ constructor - NeFileSystemMgr::NeFileSystemMgr() - { - MUST_PASS(Detail::fs_init_newfs()); - fImpl = mm_new_class(); - MUST_PASS(fImpl); - - kcout << "We are done here... (NeFileSystemMgr).\r"; - } - - NeFileSystemMgr::~NeFileSystemMgr() - { - if (fImpl) - { - kcout << "Destroying FS class (NeFS)...\r"; - - delete fImpl; - fImpl = nullptr; - } - } - - /// @brief Removes a node from the filesystem. - /// @param fileName The filename - /// @return If it was deleted or not. - bool NeFileSystemMgr::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 NeFileSystemMgr::Create(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path)); - } - - /// @brief Creates a node with is a directory. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateDirectory(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindDir)); - } - - /// @brief Creates a node with is a alias. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateAlias(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindAlias)); - } - - /// @brief Creates a node with is a page file. - /// @param path The filename path. - /// @return The Node pointer. - NodePtr NeFileSystemMgr::CreateSwapFile(const Char* path) - { - return node_cast(fImpl->CreateCatalog(path, 0, kNeFSCatalogKindPage)); - } - - /// @brief Gets the root directory. - /// @return - const Char* NeFileSystemHelper::Root() - { - return kNeFSRoot; - } - - /// @brief Gets the up-dir directory. - /// @return - const Char* NeFileSystemHelper::UpDir() - { - return kNeFSUpDir; - } - - /// @brief Gets the separator character. - /// @return - const Char NeFileSystemHelper::Separator() - { - return kNeFSSeparator; - } - - /// @brief Gets the metafile character. - /// @return - const Char NeFileSystemHelper::MetaFile() - { - return kNeFSMetaFilePrefix; - } - - /// @brief Opens a new file. - /// @param path - /// @param r - /// @return - _Output NodePtr NeFileSystemMgr::Open(_Input const Char* path, _Input const Char* r) - { - if (!path || *path == 0) - return nullptr; - - if (!r || *r == 0) - return nullptr; - - auto catalog = fImpl->GetCatalog(path); - - return node_cast(catalog); - } - - /// @brief Writes to a catalog's fork. - /// @param node the node ptr. - /// @param data the data. - /// @param flags the size. - /// @return - Void NeFileSystemMgr::Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) - { - if (!node) - return; - if (!size) - return; - - constexpr auto cDataForkName = kNeFSDataFork; - this->Write(cDataForkName, node, data, flags, size); - } - - /// @brief Read from filesystem fork. - /// @param node the catalog node. - /// @param flags the flags with it. - /// @param sz the size to read. - /// @return - _Output VoidPtr NeFileSystemMgr::Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT size) - { - if (!node) - return nullptr; - if (!size) - return nullptr; - - constexpr auto cDataForkName = kNeFSDataFork; - return this->Read(cDataForkName, node, flags, size); - } - - Void NeFileSystemMgr::Write(_Input const Char* name, - _Input NodePtr node, - _Input VoidPtr data, - _Input Int32 flags, - _Input SizeT size) - { - if (!size || - size > kNeFSForkSize) - return; - - if (!data) - return; - - ZKA_UNUSED(flags); - - if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) - fImpl->WriteCatalog(reinterpret_cast(node), (flags & cFileFlagRsrc ? true : false), data, size, - name); - } - - _Output VoidPtr NeFileSystemMgr::Read(_Input const Char* name, - _Input NodePtr node, - _Input Int32 flags, - _Input SizeT sz) - { - if (sz > kNeFSForkSize) - return nullptr; - - if (!sz) - return nullptr; - - ZKA_UNUSED(flags); - - if ((reinterpret_cast(node))->Kind == kNeFSCatalogKindFile) - return fImpl->ReadCatalog(reinterpret_cast(node), (flags & cFileFlagRsrc ? true : false), sz, - name); - - return nullptr; - } - - /// @brief Seek from Catalog. - /// @param node - /// @param off - /// @retval true always returns false, this is unimplemented. - /// @retval false always returns this, it is unimplemented. - - _Output Bool NeFileSystemMgr::Seek(NodePtr node, SizeT off) - { - if (!node || off == 0) - return false; - - return 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. - - _Output SizeT NeFileSystemMgr::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. - - _Output Bool NeFileSystemMgr::Rewind(NodePtr node) - { - if (!node) - return false; - - return this->Seek(node, 0); - } - - /// @brief Returns the filesystem parser. - /// @return the Filesystem parser class. - _Output NeFSParser* NeFileSystemMgr::GetParser() noexcept - { - return fImpl; - } -} // namespace Kernel - -#endif // ifdef __FSKIT_USE_NEFS__ -#endif // ifndef __ZKA_MINIMAL_OS__ diff --git a/dev/zka/src/NeFS+IO.cc b/dev/zka/src/NeFS+IO.cc new file mode 100644 index 00000000..010ec3f2 --- /dev/null +++ b/dev/zka/src/NeFS+IO.cc @@ -0,0 +1,101 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +/************************************************************* + * + * File: NeFS+IO.cxx + * Purpose: Filesystem to mountpoint interface. + * Date: 3/26/24 + * + * Copyright ZKA Web Services Co., all rights reserved. + * + *************************************************************/ + +#ifdef __FSKIT_USE_NEFS__ + +#include + +/// Useful macros. + +#define NEFS_WRITE(DRV, TRAITS, MP) (MP->DRV()).fOutput(&TRAITS) +#define NEFS_READ(DRV, TRAITS, MP) (MP->DRV()).fInput(&TRAITS) + +using namespace Kernel; + +/// @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 kNeFSSubDriveA: { + NEFS_READ(A, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveB: { + NEFS_READ(B, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveC: { + NEFS_READ(C, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveD: { + NEFS_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 kNeFSSubDriveA: { + NEFS_WRITE(A, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveB: { + NEFS_WRITE(B, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveC: { + NEFS_WRITE(C, DrvTrait.fPacket, Mnt); + break; + } + case kNeFSSubDriveD: { + NEFS_WRITE(D, DrvTrait.fPacket, Mnt); + break; + } + } + + return DrvTrait.fPacket.fPacketGood; +} + +#endif // ifdef __FSKIT_USE_NEFS__ diff --git a/dev/zka/src/NeFS+IO.cxx b/dev/zka/src/NeFS+IO.cxx deleted file mode 100644 index c95d48ce..00000000 --- a/dev/zka/src/NeFS+IO.cxx +++ /dev/null @@ -1,101 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -/************************************************************* - * - * File: NeFS+IO.cxx - * Purpose: Filesystem to mountpoint interface. - * Date: 3/26/24 - * - * Copyright ZKA Web Services Co., all rights reserved. - * - *************************************************************/ - -#ifdef __FSKIT_USE_NEFS__ - -#include - -/// Useful macros. - -#define NEFS_WRITE(DRV, TRAITS, MP) (MP->DRV()).fOutput(&TRAITS) -#define NEFS_READ(DRV, TRAITS, MP) (MP->DRV()).fInput(&TRAITS) - -using namespace Kernel; - -/// @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 kNeFSSubDriveA: { - NEFS_READ(A, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveB: { - NEFS_READ(B, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveC: { - NEFS_READ(C, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveD: { - NEFS_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 kNeFSSubDriveA: { - NEFS_WRITE(A, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveB: { - NEFS_WRITE(B, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveC: { - NEFS_WRITE(C, DrvTrait.fPacket, Mnt); - break; - } - case kNeFSSubDriveD: { - NEFS_WRITE(D, DrvTrait.fPacket, Mnt); - break; - } - } - - return DrvTrait.fPacket.fPacketGood; -} - -#endif // ifdef __FSKIT_USE_NEFS__ diff --git a/dev/zka/src/Network/IP.cc b/dev/zka/src/Network/IP.cc new file mode 100644 index 00000000..b78009dc --- /dev/null +++ b/dev/zka/src/Network/IP.cc @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + char* RawIPAddress::Address() + { + return fAddr; + } + + RawIPAddress::RawIPAddress(char bytes[4]) + { + rt_copy_memory(bytes, fAddr, 4); + } + + bool RawIPAddress::operator==(const RawIPAddress& ipv4) + { + for (Size index = 0; index < 4; ++index) + { + if (ipv4.fAddr[index] != fAddr[index]) + return false; + } + + return true; + } + + bool RawIPAddress::operator!=(const RawIPAddress& ipv4) + { + for (Size index = 0; index < 4; ++index) + { + if (ipv4.fAddr[index] == fAddr[index]) + return false; + } + + return true; + } + + char& RawIPAddress::operator[](const Size& index) + { + 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 Kernel diff --git a/dev/zka/src/Network/IP.cxx b/dev/zka/src/Network/IP.cxx deleted file mode 100644 index d7676592..00000000 --- a/dev/zka/src/Network/IP.cxx +++ /dev/null @@ -1,126 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - char* RawIPAddress::Address() - { - return fAddr; - } - - RawIPAddress::RawIPAddress(char bytes[4]) - { - rt_copy_memory(bytes, fAddr, 4); - } - - bool RawIPAddress::operator==(const RawIPAddress& ipv4) - { - for (Size index = 0; index < 4; ++index) - { - if (ipv4.fAddr[index] != fAddr[index]) - return false; - } - - return true; - } - - bool RawIPAddress::operator!=(const RawIPAddress& ipv4) - { - for (Size index = 0; index < 4; ++index) - { - if (ipv4.fAddr[index] == fAddr[index]) - return false; - } - - return true; - } - - char& RawIPAddress::operator[](const Size& index) - { - 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 Kernel diff --git a/dev/zka/src/Network/IPC.cc b/dev/zka/src/Network/IPC.cc new file mode 100644 index 00000000..3f69bc3c --- /dev/null +++ b/dev/zka/src/Network/IPC.cc @@ -0,0 +1,114 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; + +/// @internal +/// @brief The internal sanitize function. +Bool ipc_int_sanitize_packet(IPC_MESSAGE_STRUCT* pckt) +{ + auto endian = cDeduceEndian(pckt, ((Char*)pckt)[0]); + + switch (endian) + { + case Endian::kEndianBig: { + if (pckt->IpcEndianess == eIPCEPLittleEndian) + goto ipc_check_failed; + + break; + } + case Endian::kEndianLittle: { + if (pckt->IpcEndianess == eIPCEPBigEndian) + goto ipc_check_failed; + + break; + } + case Endian::kEndianMixed: { + if (pckt->IpcEndianess == eIPCEPMixedEndian) + goto ipc_check_failed; + + break; + } + default: + goto ipc_check_failed; + } + + if (pckt->IpcFrom == pckt->IpcTo || + pckt->IpcPacketSize > cXPCOMMsgSize) + { + goto ipc_check_failed; + } + + return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == cXPCOMHeaderMagic; + +ipc_check_failed: + ErrLocal() = kErrorIPC; + return false; +} + +namespace Kernel +{ + /// @brief Sanitize packet function + /// @retval true packet is correct. + /// @retval false packet is incorrect and process has crashed. + Bool ipc_sanitize_packet(IPC_MESSAGE_STRUCT* pckt) + { + if (!pckt || + !ipc_int_sanitize_packet(pckt)) + { + UserProcessScheduler::The().CurrentProcess().Leak().Crash(); + return false; + } + + return true; + } + + /// @brief Construct packet function + /// @retval true packet is correct. + /// @retval false packet is incorrect and process has crashed. + Bool ipc_construct_packet(_Output IPC_MESSAGE_STRUCT** pckt_in) + { + // don't do anything if it's valid already. + if (*pckt_in) + return true; + + // crash process if the packet pointer of pointer is NULL. + if (!pckt_in) + { + UserProcessScheduler::The().CurrentProcess().Leak().Crash(); + return false; + } + + *pckt_in = new IPC_MESSAGE_STRUCT(); + + MUST_PASS((*pckt_in)); + + if (*pckt_in) + { + auto endian = cDeduceEndian((*pckt_in), ((Char*)(*pckt_in))[0]); + + (*pckt_in)->IpcHeaderMagic = cXPCOMHeaderMagic; + + (*pckt_in)->IpcEndianess = static_cast(endian); + (*pckt_in)->IpcPacketSize = sizeof(IPC_MESSAGE_STRUCT); + + (*pckt_in)->IpcTo.UserProcessID = 0; + (*pckt_in)->IpcTo.UserProcessTeam = 0; + + (*pckt_in)->IpcFrom.UserProcessID = Kernel::UserProcessScheduler::The().CurrentProcess().Leak().ProcessId; + (*pckt_in)->IpcFrom.UserProcessTeam = Kernel::UserProcessScheduler::The().CurrentTeam().mTeamId; + + return true; + } + + UserProcessScheduler::The().CurrentProcess().Leak().Crash(); + return false; + } +} // namespace Kernel diff --git a/dev/zka/src/Network/IPC.cxx b/dev/zka/src/Network/IPC.cxx deleted file mode 100644 index feb7822f..00000000 --- a/dev/zka/src/Network/IPC.cxx +++ /dev/null @@ -1,114 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include - -using namespace Kernel; - -/// @internal -/// @brief The internal sanitize function. -Bool ipc_int_sanitize_packet(IPC_MESSAGE_STRUCT* pckt) -{ - auto endian = cDeduceEndian(pckt, ((Char*)pckt)[0]); - - switch (endian) - { - case Endian::kEndianBig: { - if (pckt->IpcEndianess == eIPCEPLittleEndian) - goto ipc_check_failed; - - break; - } - case Endian::kEndianLittle: { - if (pckt->IpcEndianess == eIPCEPBigEndian) - goto ipc_check_failed; - - break; - } - case Endian::kEndianMixed: { - if (pckt->IpcEndianess == eIPCEPMixedEndian) - goto ipc_check_failed; - - break; - } - default: - goto ipc_check_failed; - } - - if (pckt->IpcFrom == pckt->IpcTo || - pckt->IpcPacketSize > cXPCOMMsgSize) - { - goto ipc_check_failed; - } - - return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == cXPCOMHeaderMagic; - -ipc_check_failed: - ErrLocal() = kErrorIPC; - return false; -} - -namespace Kernel -{ - /// @brief Sanitize packet function - /// @retval true packet is correct. - /// @retval false packet is incorrect and process has crashed. - Bool ipc_sanitize_packet(IPC_MESSAGE_STRUCT* pckt) - { - if (!pckt || - !ipc_int_sanitize_packet(pckt)) - { - UserProcessScheduler::The().CurrentProcess().Leak().Crash(); - return false; - } - - return true; - } - - /// @brief Construct packet function - /// @retval true packet is correct. - /// @retval false packet is incorrect and process has crashed. - Bool ipc_construct_packet(_Output IPC_MESSAGE_STRUCT** pckt_in) - { - // don't do anything if it's valid already. - if (*pckt_in) - return true; - - // crash process if the packet pointer of pointer is NULL. - if (!pckt_in) - { - UserProcessScheduler::The().CurrentProcess().Leak().Crash(); - return false; - } - - *pckt_in = new IPC_MESSAGE_STRUCT(); - - MUST_PASS((*pckt_in)); - - if (*pckt_in) - { - auto endian = cDeduceEndian((*pckt_in), ((Char*)(*pckt_in))[0]); - - (*pckt_in)->IpcHeaderMagic = cXPCOMHeaderMagic; - - (*pckt_in)->IpcEndianess = static_cast(endian); - (*pckt_in)->IpcPacketSize = sizeof(IPC_MESSAGE_STRUCT); - - (*pckt_in)->IpcTo.UserProcessID = 0; - (*pckt_in)->IpcTo.UserProcessTeam = 0; - - (*pckt_in)->IpcFrom.UserProcessID = Kernel::UserProcessScheduler::The().CurrentProcess().Leak().ProcessId; - (*pckt_in)->IpcFrom.UserProcessTeam = Kernel::UserProcessScheduler::The().CurrentTeam().mTeamId; - - return true; - } - - UserProcessScheduler::The().CurrentProcess().Leak().Crash(); - return false; - } -} // namespace Kernel diff --git a/dev/zka/src/Network/NetworkDevice.cc b/dev/zka/src/Network/NetworkDevice.cc new file mode 100644 index 00000000..b2fba74d --- /dev/null +++ b/dev/zka/src/Network/NetworkDevice.cc @@ -0,0 +1,35 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + /// \brief Getter for fNetworkName. + const Char* NetworkDevice::Name() const + { + return this->fNetworkName; + } + + /// \brief Setter for fNetworkName. + Boolean NetworkDevice::Name(const Char* strView) + { + if (strView == nullptr) + return false; + + if (*strView == 0) + return false; + + if (rt_string_len(strView) > cNetworkNameLen) + return false; + + rt_copy_memory((VoidPtr)strView, + (VoidPtr)this->fNetworkName, rt_string_len(strView)); + + return true; + } +} // namespace Kernel diff --git a/dev/zka/src/Network/NetworkDevice.cxx b/dev/zka/src/Network/NetworkDevice.cxx deleted file mode 100644 index 8f968612..00000000 --- a/dev/zka/src/Network/NetworkDevice.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - /// \brief Getter for fNetworkName. - const Char* NetworkDevice::Name() const - { - return this->fNetworkName; - } - - /// \brief Setter for fNetworkName. - Boolean NetworkDevice::Name(const Char* strView) - { - if (strView == nullptr) - return false; - - if (*strView == 0) - return false; - - if (rt_string_len(strView) > cNetworkNameLen) - return false; - - rt_copy_memory((VoidPtr)strView, - (VoidPtr)this->fNetworkName, rt_string_len(strView)); - - return true; - } -} // namespace Kernel diff --git a/dev/zka/src/New+Delete.cc b/dev/zka/src/New+Delete.cc new file mode 100644 index 00000000..89696ed8 --- /dev/null +++ b/dev/zka/src/New+Delete.cc @@ -0,0 +1,50 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +void* operator new[](size_t sz) +{ + if (sz == 0) + ++sz; + + return Kernel::mm_new_heap(sz, true, false); +} + +void* operator new(size_t sz) +{ + if (sz == 0) + ++sz; + + return Kernel::mm_new_heap(sz, true, false); +} + +void operator delete[](void* ptr) +{ + if (ptr == nullptr) + return; + + Kernel::mm_delete_heap(ptr); +} + +void operator delete(void* ptr) +{ + if (ptr == nullptr) + return; + + Kernel::mm_delete_heap(ptr); +} + +void operator delete(void* ptr, size_t sz) +{ + if (ptr == nullptr) + return; + + ZKA_UNUSED(sz); + + Kernel::mm_delete_heap(ptr); +} diff --git a/dev/zka/src/New+Delete.cxx b/dev/zka/src/New+Delete.cxx deleted file mode 100644 index f63b79ed..00000000 --- a/dev/zka/src/New+Delete.cxx +++ /dev/null @@ -1,50 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -void* operator new[](size_t sz) -{ - if (sz == 0) - ++sz; - - return Kernel::mm_new_heap(sz, true, false); -} - -void* operator new(size_t sz) -{ - if (sz == 0) - ++sz; - - return Kernel::mm_new_heap(sz, true, false); -} - -void operator delete[](void* ptr) -{ - if (ptr == nullptr) - return; - - Kernel::mm_delete_heap(ptr); -} - -void operator delete(void* ptr) -{ - if (ptr == nullptr) - return; - - Kernel::mm_delete_heap(ptr); -} - -void operator delete(void* ptr, size_t sz) -{ - if (ptr == nullptr) - return; - - ZKA_UNUSED(sz); - - Kernel::mm_delete_heap(ptr); -} diff --git a/dev/zka/src/OwnPtr.cc b/dev/zka/src/OwnPtr.cc new file mode 100644 index 00000000..67a4235b --- /dev/null +++ b/dev/zka/src/OwnPtr.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/OwnPtr.cxx b/dev/zka/src/OwnPtr.cxx deleted file mode 100644 index 128f1b45..00000000 --- a/dev/zka/src/OwnPtr.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/PEFCodeMgr.cc b/dev/zka/src/PEFCodeMgr.cc new file mode 100644 index 00000000..593910be --- /dev/null +++ b/dev/zka/src/PEFCodeMgr.cc @@ -0,0 +1,262 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/// @brief PEF stack size symbol. +#define cPefStackSizeSymbol "SizeOfReserveStack" +#define cPefHeapSizeSymbol "SizeOfReserveHeap" +#define cPefNameSymbol "ProgramName" + +namespace Kernel +{ + namespace Detail + { + /// @brief Get the PEF platform signature according to the compiled backebnd + UInt32 ldr_get_platform(void) noexcept + { +#if defined(__ZKA_32X0__) + return kPefArch32x0; +#elif defined(__ZKA_64X0__) + return kPefArch64x0; +#elif defined(__ZKA_AMD64__) + return kPefArchAMD64; +#elif defined(__ZKA_PPC64__) + return kPefArchPowerPC; +#elif defined(__ZKA_ARM64__) + return kPefArchARM64; +#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) + { + fFile.New(const_cast(path), cRestrictRB); + fPath = StringBuilder::Construct(path).Leak(); + + auto cPefHeader = "PEF_CONTAINER"; + + fCachedBlob = fFile->Read(cPefHeader); + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + if (container->Cpu == Detail::ldr_get_platform() && + container->Magic[0] == kPefMagic[0] && + container->Magic[1] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && + container->Magic[3] == kPefMagic[3] && + container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi) + { + return; + } + else if (container->Magic[4] == kPefMagic[0] && + container->Magic[3] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && + container->Magic[1] == kPefMagic[3] && + container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) + { + /// This is a fat binary. + this->fFatBinary = true; + return; + } + + fBad = true; + + if (fCachedBlob) + mm_delete_heap(fCachedBlob); + + kcout << "PEFLoader: warn: Executable format error!\r"; + + fCachedBlob = nullptr; + } + + /// @brief PEF destructor. + PEFLoader::~PEFLoader() + { + if (fCachedBlob) + mm_delete_heap(fCachedBlob); + + fFile.Delete(); + } + + VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) + { + if (!fCachedBlob || fBad || !name) + return nullptr; + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + auto blob = fFile->Read(name); + + PEFCommandHeader* container_header = reinterpret_cast(blob); + + constexpr auto cMangleCharacter = '$'; + const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; + + ErrorOr error_or_symbol; + + switch (kind) + { + case kPefCode: { + error_or_symbol = StringBuilder::Construct(cContainerKinds[0]); // code symbol. + break; + } + case kPefData: { + error_or_symbol = StringBuilder::Construct(cContainerKinds[1]); // data symbol. + break; + } + case kPefZero: { + error_or_symbol = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol. + break; + } + default: + return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were + // a user process. + } + + Char* unconst_symbol = const_cast(name); + + for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) + { + if (unconst_symbol[i] == ' ') + { + unconst_symbol[i] = cMangleCharacter; + } + } + + error_or_symbol.Leak().Leak() += name; + + for (SizeT index = 0; index < container->Count; ++index) + { + if (StringBuilder::Equals(container_header->Name, + error_or_symbol.Leak().Leak().CData())) + { + if (container_header->Kind == kind) + { + if (container_header->Cpu != Detail::ldr_get_platform()) + { + if (!this->fFatBinary) + { + mm_delete_heap(blob); + return nullptr; + } + } + + Char* container_blob_value = new Char[container_header->Size]; + + rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); + mm_delete_heap(blob); + + kcout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; + + return container_blob_value; + } + } + } + + mm_delete_heap(blob); + return nullptr; + } + + /// @brief Finds the executable entrypoint. + /// @return + ErrorOr PEFLoader::FindStart() + { + if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) + return ErrorOr(sym); + + return ErrorOr(kErrorExecutable); + } + + /// @brief Tells if the executable is loaded or not. + /// @return + bool PEFLoader::IsLoaded() noexcept + { + return !fBad && fCachedBlob; + } + + namespace Utils + { + Bool execute_from_image(PEFLoader& exec, const Int32& procKind) noexcept + { + auto errOrStart = exec.FindStart(); + + if (errOrStart.Error() != kErrorSuccess) + return false; + + UserProcess proc; + + proc.SetImageStart(errOrStart.Leak().Leak()); + proc.Kind = procKind; + proc.StackSize = *(UIntPtr*)exec.FindSymbol(cPefStackSizeSymbol, kPefData); + proc.MemoryLimit = *(UIntPtr*)exec.FindSymbol(cPefHeapSizeSymbol, kPefData); + + rt_set_memory(proc.Name, 0, kProcessLen); + + if (exec.FindSymbol(cPefNameSymbol, kPefData)) + rt_copy_memory((VoidPtr)exec.FindSymbol(cPefNameSymbol, kPefData), proc.Name, rt_string_len((Char*)exec.FindSymbol(cPefNameSymbol, kPefData))); + else + rt_copy_memory((VoidPtr) "UNNAMED PROCESS.", proc.Name, rt_string_len("UNNAMED PROCESS.")); + + if (!proc.StackSize) + { + const auto cDefaultStackSizeMib = 8; + + proc.StackSize = mib_cast(cDefaultStackSizeMib); + } + + return UserProcessScheduler::The().Add(proc) > 0; + } + } // namespace Utils + + const Char* PEFLoader::Path() + { + return fPath.Leak().CData(); + } + + const Char* PEFLoader::AsString() + { +#ifdef __32x0__ + return "32x0 PEF executable."; +#elif defined(__64x0__) + return "64x0 PEF executable."; +#elif defined(__x86_64__) + return "x86_64 PEF executable."; +#elif defined(__aarch64__) + return "aarch64 PEF executable."; +#elif defined(__powerpc64__) + return "POWER64 PEF executable."; +#else + return "???? PEF executable."; +#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ + } + + const Char* PEFLoader::MIME() + { + return kPefApplicationMime; + } +} // namespace Kernel diff --git a/dev/zka/src/PEFCodeMgr.cxx b/dev/zka/src/PEFCodeMgr.cxx deleted file mode 100644 index edea684e..00000000 --- a/dev/zka/src/PEFCodeMgr.cxx +++ /dev/null @@ -1,262 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/// @brief PEF stack size symbol. -#define cPefStackSizeSymbol "SizeOfReserveStack" -#define cPefHeapSizeSymbol "SizeOfReserveHeap" -#define cPefNameSymbol "ProgramName" - -namespace Kernel -{ - namespace Detail - { - /// @brief Get the PEF platform signature according to the compiled backebnd - UInt32 ldr_get_platform(void) noexcept - { -#if defined(__ZKA_32X0__) - return kPefArch32x0; -#elif defined(__ZKA_64X0__) - return kPefArch64x0; -#elif defined(__ZKA_AMD64__) - return kPefArchAMD64; -#elif defined(__ZKA_PPC64__) - return kPefArchPowerPC; -#elif defined(__ZKA_ARM64__) - return kPefArchARM64; -#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) - { - fFile.New(const_cast(path), cRestrictRB); - fPath = StringBuilder::Construct(path).Leak(); - - auto cPefHeader = "PEF_CONTAINER"; - - fCachedBlob = fFile->Read(cPefHeader); - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - if (container->Cpu == Detail::ldr_get_platform() && - container->Magic[0] == kPefMagic[0] && - container->Magic[1] == kPefMagic[1] && - container->Magic[2] == kPefMagic[2] && - container->Magic[3] == kPefMagic[3] && - container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi) - { - return; - } - else if (container->Magic[4] == kPefMagic[0] && - container->Magic[3] == kPefMagic[1] && - container->Magic[2] == kPefMagic[2] && - container->Magic[1] == kPefMagic[3] && - container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi) - { - /// This is a fat binary. - this->fFatBinary = true; - return; - } - - fBad = true; - - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - kcout << "PEFLoader: warn: Executable format error!\r"; - - fCachedBlob = nullptr; - } - - /// @brief PEF destructor. - PEFLoader::~PEFLoader() - { - if (fCachedBlob) - mm_delete_heap(fCachedBlob); - - fFile.Delete(); - } - - VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind) - { - if (!fCachedBlob || fBad || !name) - return nullptr; - - PEFContainer* container = reinterpret_cast(fCachedBlob); - - auto blob = fFile->Read(name); - - PEFCommandHeader* container_header = reinterpret_cast(blob); - - constexpr auto cMangleCharacter = '$'; - const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr}; - - ErrorOr error_or_symbol; - - switch (kind) - { - case kPefCode: { - error_or_symbol = StringBuilder::Construct(cContainerKinds[0]); // code symbol. - break; - } - case kPefData: { - error_or_symbol = StringBuilder::Construct(cContainerKinds[1]); // data symbol. - break; - } - case kPefZero: { - error_or_symbol = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol. - break; - } - default: - return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were - // a user process. - } - - Char* unconst_symbol = const_cast(name); - - for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) - { - if (unconst_symbol[i] == ' ') - { - unconst_symbol[i] = cMangleCharacter; - } - } - - error_or_symbol.Leak().Leak() += name; - - for (SizeT index = 0; index < container->Count; ++index) - { - if (StringBuilder::Equals(container_header->Name, - error_or_symbol.Leak().Leak().CData())) - { - if (container_header->Kind == kind) - { - if (container_header->Cpu != Detail::ldr_get_platform()) - { - if (!this->fFatBinary) - { - mm_delete_heap(blob); - return nullptr; - } - } - - Char* container_blob_value = new Char[container_header->Size]; - - rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); - mm_delete_heap(blob); - - kcout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r"; - - return container_blob_value; - } - } - } - - mm_delete_heap(blob); - return nullptr; - } - - /// @brief Finds the executable entrypoint. - /// @return - ErrorOr PEFLoader::FindStart() - { - if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) - return ErrorOr(sym); - - return ErrorOr(kErrorExecutable); - } - - /// @brief Tells if the executable is loaded or not. - /// @return - bool PEFLoader::IsLoaded() noexcept - { - return !fBad && fCachedBlob; - } - - namespace Utils - { - Bool execute_from_image(PEFLoader& exec, const Int32& procKind) noexcept - { - auto errOrStart = exec.FindStart(); - - if (errOrStart.Error() != kErrorSuccess) - return false; - - UserProcess proc; - - proc.SetImageStart(errOrStart.Leak().Leak()); - proc.Kind = procKind; - proc.StackSize = *(UIntPtr*)exec.FindSymbol(cPefStackSizeSymbol, kPefData); - proc.MemoryLimit = *(UIntPtr*)exec.FindSymbol(cPefHeapSizeSymbol, kPefData); - - rt_set_memory(proc.Name, 0, kProcessLen); - - if (exec.FindSymbol(cPefNameSymbol, kPefData)) - rt_copy_memory((VoidPtr)exec.FindSymbol(cPefNameSymbol, kPefData), proc.Name, rt_string_len((Char*)exec.FindSymbol(cPefNameSymbol, kPefData))); - else - rt_copy_memory((VoidPtr) "UNNAMED PROCESS.", proc.Name, rt_string_len("UNNAMED PROCESS.")); - - if (!proc.StackSize) - { - const auto cDefaultStackSizeMib = 8; - - proc.StackSize = mib_cast(cDefaultStackSizeMib); - } - - return UserProcessScheduler::The().Add(proc) > 0; - } - } // namespace Utils - - const Char* PEFLoader::Path() - { - return fPath.Leak().CData(); - } - - const Char* PEFLoader::AsString() - { -#ifdef __32x0__ - return "32x0 PEF executable."; -#elif defined(__64x0__) - return "64x0 PEF executable."; -#elif defined(__x86_64__) - return "x86_64 PEF executable."; -#elif defined(__aarch64__) - return "aarch64 PEF executable."; -#elif defined(__powerpc64__) - return "POWER64 PEF executable."; -#else - return "???? PEF executable."; -#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__ - } - - const Char* PEFLoader::MIME() - { - return kPefApplicationMime; - } -} // namespace Kernel diff --git a/dev/zka/src/PRDT.cc b/dev/zka/src/PRDT.cc new file mode 100644 index 00000000..741e932b --- /dev/null +++ b/dev/zka/src/PRDT.cc @@ -0,0 +1,22 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include + +namespace Kernel +{ + /// @brief constructs a new PRD. + /// @param prd PRD reference. + /// @note This doesnt construct a valid, please fill it by yourself. + void construct_prdt(Ref& prd) + { + prd.Leak().fPhysAddress = 0x0; + prd.Leak().fSectorCount = 0x0; + prd.Leak().fEndBit = 0x0; + } +} // namespace Kernel diff --git a/dev/zka/src/PRDT.cxx b/dev/zka/src/PRDT.cxx deleted file mode 100644 index c12a4159..00000000 --- a/dev/zka/src/PRDT.cxx +++ /dev/null @@ -1,22 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include - -namespace Kernel -{ - /// @brief constructs a new PRD. - /// @param prd PRD reference. - /// @note This doesnt construct a valid, please fill it by yourself. - void construct_prdt(Ref& prd) - { - prd.Leak().fPhysAddress = 0x0; - prd.Leak().fSectorCount = 0x0; - prd.Leak().fEndBit = 0x0; - } -} // namespace Kernel diff --git a/dev/zka/src/PageMgr.cc b/dev/zka/src/PageMgr.cc new file mode 100644 index 00000000..18b65dc6 --- /dev/null +++ b/dev/zka/src/PageMgr.cc @@ -0,0 +1,110 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +#ifdef __ZKA_AMD64__ +#include +#elif defined(__ZKA_ARM64__) +#include +#endif // ifdef __ZKA_AMD64__ || defined(__ZKA_ARM64__) + +namespace Kernel +{ + PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) + : fRw(Rw), + fUser(User), + fExecDisable(ExecDisable), + fVirtAddr(VirtAddr), + fCache(false), + fShareable(false), + fWt(false), + fPresent(true), + fAccessed(false) + { + } + + PTEWrapper::~PTEWrapper() = default; + + /// @brief Flush virtual address. + /// @param VirtAddr + Void PageMgr::FlushTLB() + { +#ifndef __ZKA_MINIMAL_OS__ + hal_flush_tlb(); +#endif // !__ZKA_MINIMAL_OS__ + } + + /// @brief Reclaim freed page. + /// @return + Bool PTEWrapper::Reclaim() + { + if (!this->fPresent) + { + this->fPresent = true; + return true; + } + + return false; + } + + /// @brief Request a PTE. + /// @param Rw r/w? + /// @param User user mode? + /// @param ExecDisable disable execution on page? + /// @return + PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz) + { + // Store PTE wrapper right after PTE. + VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, false); + + return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast(ptr)}; + } + + /// @brief Disable BitMap. + /// @param wrapper the wrapper. + /// @return If the page bitmap was cleared or not. + Bool PageMgr::Free(Ref& wrapper) + { + if (!Kernel::HAL::mm_free_bitmap((VoidPtr)wrapper.Leak().VirtualAddress())) + return false; + + return true; + } + + /// @brief Virtual PTE address. + /// @return The virtual address of the page. + 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 Kernel diff --git a/dev/zka/src/PageMgr.cxx b/dev/zka/src/PageMgr.cxx deleted file mode 100644 index 6d9f4cc6..00000000 --- a/dev/zka/src/PageMgr.cxx +++ /dev/null @@ -1,110 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -#ifdef __ZKA_AMD64__ -#include -#elif defined(__ZKA_ARM64__) -#include -#endif // ifdef __ZKA_AMD64__ || defined(__ZKA_ARM64__) - -namespace Kernel -{ - PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) - : fRw(Rw), - fUser(User), - fExecDisable(ExecDisable), - fVirtAddr(VirtAddr), - fCache(false), - fShareable(false), - fWt(false), - fPresent(true), - fAccessed(false) - { - } - - PTEWrapper::~PTEWrapper() = default; - - /// @brief Flush virtual address. - /// @param VirtAddr - Void PageMgr::FlushTLB() - { -#ifndef __ZKA_MINIMAL_OS__ - hal_flush_tlb(); -#endif // !__ZKA_MINIMAL_OS__ - } - - /// @brief Reclaim freed page. - /// @return - Bool PTEWrapper::Reclaim() - { - if (!this->fPresent) - { - this->fPresent = true; - return true; - } - - return false; - } - - /// @brief Request a PTE. - /// @param Rw r/w? - /// @param User user mode? - /// @param ExecDisable disable execution on page? - /// @return - PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz) - { - // Store PTE wrapper right after PTE. - VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, false); - - return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast(ptr)}; - } - - /// @brief Disable BitMap. - /// @param wrapper the wrapper. - /// @return If the page bitmap was cleared or not. - Bool PageMgr::Free(Ref& wrapper) - { - if (!Kernel::HAL::mm_free_bitmap((VoidPtr)wrapper.Leak().VirtualAddress())) - return false; - - return true; - } - - /// @brief Virtual PTE address. - /// @return The virtual address of the page. - 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 Kernel diff --git a/dev/zka/src/Pmm.cc b/dev/zka/src/Pmm.cc new file mode 100644 index 00000000..4af7d909 --- /dev/null +++ b/dev/zka/src/Pmm.cc @@ -0,0 +1,94 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +#if defined(__ZKA_ARM64__) +#include +#endif // defined(__ZKA_ARM64__) + +#if defined(__ZKA_AMD64__) +#include +#endif // defined(__ZKA_AMD64__) + +namespace Kernel +{ + /// @brief Pmm constructor. + Pmm::Pmm() + : fPageMgr() + { + kcout << "[PMM] Allocate PageMemoryMgr"; + } + + 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 = fPageMgr.Leak().Request(user, readWrite, false, kPageSize); + + if (pt.fPresent) + { + kcout << "[PMM]: Allocation failed.\r"; + return {}; + } + + return Ref(pt); + } + + 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 Kernel diff --git a/dev/zka/src/Pmm.cxx b/dev/zka/src/Pmm.cxx deleted file mode 100644 index cf39714f..00000000 --- a/dev/zka/src/Pmm.cxx +++ /dev/null @@ -1,94 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -#if defined(__ZKA_ARM64__) -#include -#endif // defined(__ZKA_ARM64__) - -#if defined(__ZKA_AMD64__) -#include -#endif // defined(__ZKA_AMD64__) - -namespace Kernel -{ - /// @brief Pmm constructor. - Pmm::Pmm() - : fPageMgr() - { - kcout << "[PMM] Allocate PageMemoryMgr"; - } - - 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 = fPageMgr.Leak().Request(user, readWrite, false, kPageSize); - - if (pt.fPresent) - { - kcout << "[PMM]: Allocation failed.\r"; - return {}; - } - - return Ref(pt); - } - - 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 Kernel diff --git a/dev/zka/src/Property.cc b/dev/zka/src/Property.cc new file mode 100644 index 00000000..084616a4 --- /dev/null +++ b/dev/zka/src/Property.cc @@ -0,0 +1,27 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + Property::~Property() = default; + + Bool Property::StringEquals(StringView& name) + { + return this->fName && this->fName == name; + } + + StringView& Property::GetKey() + { + return this->fName; + } + + PropertyId& Property::GetValue() + { + return fAction; + } +} // namespace Kernel diff --git a/dev/zka/src/Property.cxx b/dev/zka/src/Property.cxx deleted file mode 100644 index 7cc78966..00000000 --- a/dev/zka/src/Property.cxx +++ /dev/null @@ -1,27 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - Property::~Property() = default; - - Bool Property::StringEquals(StringView& name) - { - return this->fName && this->fName == name; - } - - StringView& Property::GetKey() - { - return this->fName; - } - - PropertyId& Property::GetValue() - { - return fAction; - } -} // namespace Kernel diff --git a/dev/zka/src/Ref.cc b/dev/zka/src/Ref.cc new file mode 100644 index 00000000..2ac42395 --- /dev/null +++ b/dev/zka/src/Ref.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/Ref.cxx b/dev/zka/src/Ref.cxx deleted file mode 100644 index bdb60236..00000000 --- a/dev/zka/src/Ref.cxx +++ /dev/null @@ -1,7 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/Semaphore.cc b/dev/zka/src/Semaphore.cc new file mode 100644 index 00000000..08f33cf1 --- /dev/null +++ b/dev/zka/src/Semaphore.cc @@ -0,0 +1,62 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + Bool Semaphore::Unlock() noexcept + { + if (fLockingProcess) + fLockingProcess = nullptr; + + return fLockingProcess == nullptr; + } + + Bool Semaphore::Lock(UserProcess* process) + { + if (!process || fLockingProcess) + return false; + + fLockingProcess = process; + + return true; + } + + Bool Semaphore::IsLocked() const + { + return fLockingProcess; + } + + Bool Semaphore::LockOrWait(UserProcess* process, TimerInterface* timer) + { + if (process == nullptr) + return false; + + if (timer == nullptr) + return false; + + this->Lock(process); + + timer->Wait(); + + return this->Lock(process); + } + + /// @brief Wait with process, either wait for it to be being invalid, or not being run. + Void Semaphore::WaitForProcess() noexcept + { + while (fLockingProcess) + { + if (fLockingProcess->GetStatus() != ProcessStatusKind::kRunning) + { + this->Unlock(); + break; + } + } + } +} // namespace Kernel diff --git a/dev/zka/src/Semaphore.cxx b/dev/zka/src/Semaphore.cxx deleted file mode 100644 index 5a598001..00000000 --- a/dev/zka/src/Semaphore.cxx +++ /dev/null @@ -1,62 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - Bool Semaphore::Unlock() noexcept - { - if (fLockingProcess) - fLockingProcess = nullptr; - - return fLockingProcess == nullptr; - } - - Bool Semaphore::Lock(UserProcess* process) - { - if (!process || fLockingProcess) - return false; - - fLockingProcess = process; - - return true; - } - - Bool Semaphore::IsLocked() const - { - return fLockingProcess; - } - - Bool Semaphore::LockOrWait(UserProcess* process, TimerInterface* timer) - { - if (process == nullptr) - return false; - - if (timer == nullptr) - return false; - - this->Lock(process); - - timer->Wait(); - - return this->Lock(process); - } - - /// @brief Wait with process, either wait for it to be being invalid, or not being run. - Void Semaphore::WaitForProcess() noexcept - { - while (fLockingProcess) - { - if (fLockingProcess->GetStatus() != ProcessStatusKind::kRunning) - { - this->Unlock(); - break; - } - } - } -} // namespace Kernel diff --git a/dev/zka/src/Stop.cc b/dev/zka/src/Stop.cc new file mode 100644 index 00000000..3ec67249 --- /dev/null +++ b/dev/zka/src/Stop.cc @@ -0,0 +1,126 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define cWebsiteMacro "https://help.zws.com/" + +/* Each error code is attributed with an ID, which will prompt a string onto the + * screen. Wait for debugger... */ + +namespace Kernel +{ + void ke_stop(const Kernel::Int& id) + { + CGInit(); + + auto panic_text = RGB(0xff, 0xff, 0xff); + + auto start_y = 10; + auto x = 10; + + CGDrawString("minoskrnl.exe stopped working properly so it had to stop.", start_y, x, panic_text); + start_y += 10; + + // simply offset from previous string and then write the website. + CGDrawString("Please visit: ", start_y, x, panic_text); + CGDrawString(cWebsiteMacro, start_y, x + (FONT_SIZE_X * rt_string_len("Please visit: ")), panic_text); + + CGFini(); + + start_y += 10; + + // show text according to error id. + + switch (id) + { + case RUNTIME_CHECK_PROCESS: { + CGDrawString("0x00000008 Multi-Task error.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_ACPI: { + CGDrawString("0x00000006 ACPI configuration error.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_PAGE: { + CGDrawString("0x0000000B Write/Read in non paged area.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_FILESYSTEM: { + CGDrawString("0x0000000A Filesystem error.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_POINTER: { + CGDrawString("0x00000000 Heap is corrupted.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_BAD_BEHAVIOR: { + CGDrawString("0x00000009 Bad Behavior.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_BOOTSTRAP: { + CGDrawString("0x0000000A Boot code has finished executing, waiting for scheduler and other cores.", start_y, x, panic_text); + return; + } + case RUNTIME_CHECK_HANDSHAKE: { + CGDrawString("0x00000005 Handshake fault.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_IPC: { + CGDrawString("0x00000003 Bad IPC/XPCOM message.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_INVALID_PRIVILEGE: { + CGDrawString("0x00000007 Privilege access violation.", start_y, x, panic_text); + break; + case RUNTIME_CHECK_UNEXCPECTED: { + CGDrawString("0x0000000B Unexpected violation.", start_y, x, panic_text); + break; + } + case RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM: { + CGDrawString("0x10000001 Out of virtual memory.", start_y, x, panic_text); + + break; + } + case RUNTIME_CHECK_FAILED: { + CGDrawString("0x10000001 Kernel Bug check appears to have failed, a dump has been written to the storage.", start_y, x, panic_text); + break; + } + default: { + CGDrawString("0xFFFFFFFC Unknown Kernel Error.", start_y, x, panic_text); + break; + } + } + }; + + RecoveryFactory::Recover(); + } + + Void RecoveryFactory::Recover() noexcept + { + HAL::rt_halt(); + } + + void ke_runtime_check(bool expr, const Char* file, const Char* line) + { + if (!expr) + { + kcout << "FAILED: FILE: " << file << endl; + kcout << "FAILED: LINE: " << line << endl; + + ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed + } + } +} // namespace Kernel diff --git a/dev/zka/src/Stop.cxx b/dev/zka/src/Stop.cxx deleted file mode 100644 index 39e57070..00000000 --- a/dev/zka/src/Stop.cxx +++ /dev/null @@ -1,126 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define cWebsiteMacro "https://help.zws.com/" - -/* Each error code is attributed with an ID, which will prompt a string onto the - * screen. Wait for debugger... */ - -namespace Kernel -{ - void ke_stop(const Kernel::Int& id) - { - CGInit(); - - auto panic_text = RGB(0xff, 0xff, 0xff); - - auto start_y = 10; - auto x = 10; - - CGDrawString("minoskrnl.exe stopped working properly so it had to stop.", start_y, x, panic_text); - start_y += 10; - - // simply offset from previous string and then write the website. - CGDrawString("Please visit: ", start_y, x, panic_text); - CGDrawString(cWebsiteMacro, start_y, x + (FONT_SIZE_X * rt_string_len("Please visit: ")), panic_text); - - CGFini(); - - start_y += 10; - - // show text according to error id. - - switch (id) - { - case RUNTIME_CHECK_PROCESS: { - CGDrawString("0x00000008 Multi-Task error.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_ACPI: { - CGDrawString("0x00000006 ACPI configuration error.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_PAGE: { - CGDrawString("0x0000000B Write/Read in non paged area.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_FILESYSTEM: { - CGDrawString("0x0000000A Filesystem error.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_POINTER: { - CGDrawString("0x00000000 Heap is corrupted.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_BAD_BEHAVIOR: { - CGDrawString("0x00000009 Bad Behavior.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_BOOTSTRAP: { - CGDrawString("0x0000000A Boot code has finished executing, waiting for scheduler and other cores.", start_y, x, panic_text); - return; - } - case RUNTIME_CHECK_HANDSHAKE: { - CGDrawString("0x00000005 Handshake fault.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_IPC: { - CGDrawString("0x00000003 Bad IPC/XPCOM message.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_INVALID_PRIVILEGE: { - CGDrawString("0x00000007 Privilege access violation.", start_y, x, panic_text); - break; - case RUNTIME_CHECK_UNEXCPECTED: { - CGDrawString("0x0000000B Unexpected violation.", start_y, x, panic_text); - break; - } - case RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM: { - CGDrawString("0x10000001 Out of virtual memory.", start_y, x, panic_text); - - break; - } - case RUNTIME_CHECK_FAILED: { - CGDrawString("0x10000001 Kernel Bug check appears to have failed, a dump has been written to the storage.", start_y, x, panic_text); - break; - } - default: { - CGDrawString("0xFFFFFFFC Unknown Kernel Error.", start_y, x, panic_text); - break; - } - } - }; - - RecoveryFactory::Recover(); - } - - Void RecoveryFactory::Recover() noexcept - { - HAL::rt_halt(); - } - - void ke_runtime_check(bool expr, const Char* file, const Char* line) - { - if (!expr) - { - kcout << "FAILED: FILE: " << file << endl; - kcout << "FAILED: LINE: " << line << endl; - - ke_stop(RUNTIME_CHECK_FAILED); // Runtime Check failed - } - } -} // namespace Kernel diff --git a/dev/zka/src/Storage/AHCIDeviceInterface.cc b/dev/zka/src/Storage/AHCIDeviceInterface.cc new file mode 100644 index 00000000..a790236d --- /dev/null +++ b/dev/zka/src/Storage/AHCIDeviceInterface.cc @@ -0,0 +1,35 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +/// @brief Class constructor +/// @param Out Drive output +/// @param In Drive input +/// @param Cleanup Drive 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/dev/zka/src/Storage/AHCIDeviceInterface.cxx b/dev/zka/src/Storage/AHCIDeviceInterface.cxx deleted file mode 100644 index 9165ea32..00000000 --- a/dev/zka/src/Storage/AHCIDeviceInterface.cxx +++ /dev/null @@ -1,35 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive 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/dev/zka/src/Storage/ATADeviceInterface.cc b/dev/zka/src/Storage/ATADeviceInterface.cc new file mode 100644 index 00000000..2c027351 --- /dev/null +++ b/dev/zka/src/Storage/ATADeviceInterface.cc @@ -0,0 +1,88 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +/// @brief Class constructor +/// @param Out Drive output +/// @param In Drive input +/// @param Cleanup Drive 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 < kMaxDriveCountPerMountpoint; ++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 < kMaxDriveCountPerMountpoint; ++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/dev/zka/src/Storage/ATADeviceInterface.cxx b/dev/zka/src/Storage/ATADeviceInterface.cxx deleted file mode 100644 index 8eae0262..00000000 --- a/dev/zka/src/Storage/ATADeviceInterface.cxx +++ /dev/null @@ -1,88 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -using namespace Kernel; - -/// @brief Class constructor -/// @param Out Drive output -/// @param In Drive input -/// @param Cleanup Drive 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 < kMaxDriveCountPerMountpoint; ++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 < kMaxDriveCountPerMountpoint; ++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/dev/zka/src/Storage/NVMEDeviceInterface.cc b/dev/zka/src/Storage/NVMEDeviceInterface.cc new file mode 100644 index 00000000..c2bd701f --- /dev/null +++ b/dev/zka/src/Storage/NVMEDeviceInterface.cc @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + NVMEDeviceInterface::NVMEDeviceInterface(void (*Out)(MountpointInterface* outpacket), + void (*In)(MountpointInterface* inpacket), + void (*Cleanup)(void)) + : DeviceInterface(Out, In), fCleanup(Cleanup) + { + } + + NVMEDeviceInterface::~NVMEDeviceInterface() + { + if (fCleanup) + fCleanup(); + } + + const Char* NVMEDeviceInterface::Name() const + { + return ("NVMEDeviceInterface"); + } +} // namespace Kernel diff --git a/dev/zka/src/Storage/NVMEDeviceInterface.cxx b/dev/zka/src/Storage/NVMEDeviceInterface.cxx deleted file mode 100644 index c762affe..00000000 --- a/dev/zka/src/Storage/NVMEDeviceInterface.cxx +++ /dev/null @@ -1,28 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - NVMEDeviceInterface::NVMEDeviceInterface(void (*Out)(MountpointInterface* outpacket), - void (*In)(MountpointInterface* inpacket), - void (*Cleanup)(void)) - : DeviceInterface(Out, In), fCleanup(Cleanup) - { - } - - NVMEDeviceInterface::~NVMEDeviceInterface() - { - if (fCleanup) - fCleanup(); - } - - const Char* NVMEDeviceInterface::Name() const - { - return ("NVMEDeviceInterface"); - } -} // namespace Kernel diff --git a/dev/zka/src/Storage/SCSIDeviceInterface.cc b/dev/zka/src/Storage/SCSIDeviceInterface.cc new file mode 100644 index 00000000..2cb397e7 --- /dev/null +++ b/dev/zka/src/Storage/SCSIDeviceInterface.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +///! @brief ATAPI SCSI packet. +const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, + 0, 12, 0x40, 0, 0}; diff --git a/dev/zka/src/Storage/SCSIDeviceInterface.cxx b/dev/zka/src/Storage/SCSIDeviceInterface.cxx deleted file mode 100644 index bda16961..00000000 --- a/dev/zka/src/Storage/SCSIDeviceInterface.cxx +++ /dev/null @@ -1,11 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -///! @brief ATAPI SCSI packet. -const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; diff --git a/dev/zka/src/Stream.cc b/dev/zka/src/Stream.cc new file mode 100644 index 00000000..cf5cb4a4 --- /dev/null +++ b/dev/zka/src/Stream.cc @@ -0,0 +1,12 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + + File: Stream.cxx + Purpose: Stream object + + Revision History: + +------------------------------------------- */ + +#include diff --git a/dev/zka/src/Stream.cxx b/dev/zka/src/Stream.cxx deleted file mode 100644 index 6d975ca2..00000000 --- a/dev/zka/src/Stream.cxx +++ /dev/null @@ -1,12 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - - File: Stream.cxx - Purpose: Stream object - - Revision History: - -------------------------------------------- */ - -#include diff --git a/dev/zka/src/String.cc b/dev/zka/src/String.cc new file mode 100644 index 00000000..824e7b91 --- /dev/null +++ b/dev/zka/src/String.cc @@ -0,0 +1,215 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include +#include + +namespace Kernel +{ + Char* StringView::Data() + { + return fData; + } + + const Char* StringView::CData() const + { + return fData; + } + + Size StringView::Length() const + { + return fDataSz; + } + + 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 = new StringView(rt_string_len(data)); + (*view) += data; + + return ErrorOr(*view); + } + + const Char* StringBuilder::FromBool(const Char* fmt, bool i) + { + if (!fmt) + return ("?"); + + const Char* boolean_expr = i ? "True" : "False"; + char* ret = (char*)cAlloca((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; + } + + bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) + { + for (Size index = 0; rhs[index] != 0; ++index) + { + if (rhs[index] != lhs[index]) + return false; + } + + return true; + } + + const Char* StringBuilder::Format(const Char* fmt, const Char* fmt2) + { + if (!fmt || !fmt2) + return ("?"); + + char* ret = + (char*)cAlloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt)); + + 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 rt_string_append(Char* lhs, const Char* rhs, Int32 cur) + { + SizeT sz_rhs = rt_string_len(rhs); + SizeT rhs_i = 0; + + for (; rhs_i < sz_rhs; ++rhs_i) + { + lhs[rhs_i + cur] = rhs[rhs_i]; + } + } + + StringView& StringView::operator+=(const Char* rhs) + { + rt_string_append(this->fData, rhs, this->fCur); + this->fCur += rt_string_len(rhs); + + return *this; + } + + StringView& StringView::operator+=(const StringView& rhs) + { + if (rt_string_len(rhs.fData) > this->Length()) + return *this; + + rt_string_append(this->fData, const_cast(rhs.fData), this->fCur); + this->fCur += rt_string_len(const_cast(rhs.fData)); + + return *this; + } +} // namespace Kernel diff --git a/dev/zka/src/String.cxx b/dev/zka/src/String.cxx deleted file mode 100644 index c596db77..00000000 --- a/dev/zka/src/String.cxx +++ /dev/null @@ -1,215 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include -#include - -namespace Kernel -{ - Char* StringView::Data() - { - return fData; - } - - const Char* StringView::CData() const - { - return fData; - } - - Size StringView::Length() const - { - return fDataSz; - } - - 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 = new StringView(rt_string_len(data)); - (*view) += data; - - return ErrorOr(*view); - } - - const Char* StringBuilder::FromBool(const Char* fmt, bool i) - { - if (!fmt) - return ("?"); - - const Char* boolean_expr = i ? "True" : "False"; - char* ret = (char*)cAlloca((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; - } - - bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs) - { - for (Size index = 0; rhs[index] != 0; ++index) - { - if (rhs[index] != lhs[index]) - return false; - } - - return true; - } - - const Char* StringBuilder::Format(const Char* fmt, const Char* fmt2) - { - if (!fmt || !fmt2) - return ("?"); - - char* ret = - (char*)cAlloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt)); - - 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 rt_string_append(Char* lhs, const Char* rhs, Int32 cur) - { - SizeT sz_rhs = rt_string_len(rhs); - SizeT rhs_i = 0; - - for (; rhs_i < sz_rhs; ++rhs_i) - { - lhs[rhs_i + cur] = rhs[rhs_i]; - } - } - - StringView& StringView::operator+=(const Char* rhs) - { - rt_string_append(this->fData, rhs, this->fCur); - this->fCur += rt_string_len(rhs); - - return *this; - } - - StringView& StringView::operator+=(const StringView& rhs) - { - if (rt_string_len(rhs.fData) > this->Length()) - return *this; - - rt_string_append(this->fData, const_cast(rhs.fData), this->fCur); - this->fCur += rt_string_len(const_cast(rhs.fData)); - - return *this; - } -} // namespace Kernel diff --git a/dev/zka/src/ThreadLocalStorage.cc b/dev/zka/src/ThreadLocalStorage.cc new file mode 100644 index 00000000..ef8aba6c --- /dev/null +++ b/dev/zka/src/ThreadLocalStorage.cc @@ -0,0 +1,67 @@ +/* + * ======================================================== + * + * minoskrnl + * Copyright ZKA Web Services Co., all rights reserved. + * + * ======================================================== + */ + +#include +#include +#include +#include + +/***********************************************************************************/ +/// @bugs: 0 +/// @file ThreadLocalStorage.cxx +/// @brief Process Thread Local Storage. +/***********************************************************************************/ + +using namespace Kernel; + +/** + * @brief Checks for cookie inside the TIB. + * @param tib_ptr the TIB to check. + * @return if the cookie is enabled, true; false otherwise + */ + +Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) +{ + if (!tib_ptr || + !tib_ptr->f_ThreadRecord) + return false; + + IEncoderObject encoder; + const char* tib_as_bytes = encoder.AsBytes(tib_ptr); + + kcout << "Checking for a valid cookie inside the TIB...\r"; + + return tib_as_bytes[0] == kCookieMag0 && tib_as_bytes[1] == kCookieMag1 && + tib_as_bytes[2] == kCookieMag2; +} + +/** + * @brief System call implementation of the TLS check. + * @param tib_ptr The TIB record. + * @return + */ +EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept +{ + if (!tib_ptr) + { + kcout << "Failing because of an invalid TIB...\r"; + return false; + } + + THREAD_INFORMATION_BLOCK* tib = (THREAD_INFORMATION_BLOCK*)tib_ptr; + + if (!tls_check_tib(tib)) + { + kcout << "Crashing because of an invalid TIB...\r"; + return false; + } + + kcout << "Verification succeeded! staying alive...\r"; + return true; +} diff --git a/dev/zka/src/ThreadLocalStorage.cxx b/dev/zka/src/ThreadLocalStorage.cxx deleted file mode 100644 index 0468d628..00000000 --- a/dev/zka/src/ThreadLocalStorage.cxx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * ======================================================== - * - * minoskrnl - * Copyright ZKA Web Services Co., all rights reserved. - * - * ======================================================== - */ - -#include -#include -#include -#include - -/***********************************************************************************/ -/// @bugs: 0 -/// @file ThreadLocalStorage.cxx -/// @brief Process Thread Local Storage. -/***********************************************************************************/ - -using namespace Kernel; - -/** - * @brief Checks for cookie inside the TIB. - * @param tib_ptr the TIB to check. - * @return if the cookie is enabled, true; false otherwise - */ - -Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr) -{ - if (!tib_ptr || - !tib_ptr->f_ThreadRecord) - return false; - - IEncoderObject encoder; - const char* tib_as_bytes = encoder.AsBytes(tib_ptr); - - kcout << "Checking for a valid cookie inside the TIB...\r"; - - return tib_as_bytes[0] == kCookieMag0 && tib_as_bytes[1] == kCookieMag1 && - tib_as_bytes[2] == kCookieMag2; -} - -/** - * @brief System call implementation of the TLS check. - * @param tib_ptr The TIB record. - * @return - */ -EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept -{ - if (!tib_ptr) - { - kcout << "Failing because of an invalid TIB...\r"; - return false; - } - - THREAD_INFORMATION_BLOCK* tib = (THREAD_INFORMATION_BLOCK*)tib_ptr; - - if (!tls_check_tib(tib)) - { - kcout << "Crashing because of an invalid TIB...\r"; - return false; - } - - kcout << "Verification succeeded! staying alive...\r"; - return true; -} diff --git a/dev/zka/src/Timer.cc b/dev/zka/src/Timer.cc new file mode 100644 index 00000000..e7ad488a --- /dev/null +++ b/dev/zka/src/Timer.cc @@ -0,0 +1,47 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +///! BUGS: 0 +///! @file Timer.cxx +///! @brief Software Timer implementation + +using namespace Kernel; + +/// @brief Unimplemented as it is an interface. +Int32 TimerInterface::Wait() noexcept +{ + return kErrorUnimplemented; +} + +/// @brief SoftwareTimer class, meant to be generic. + +SoftwareTimer::SoftwareTimer(Int64 seconds) + : fWaitFor(seconds) +{ + fDigitalTimer = new IntPtr(); + MUST_PASS(fDigitalTimer); +} + +SoftwareTimer::~SoftwareTimer() +{ + delete fDigitalTimer; + fWaitFor = 0; +} + +Int32 SoftwareTimer::Wait() noexcept +{ + if (fWaitFor < 1) + return -1; + + while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) + { + ++(*fDigitalTimer); + } + + return 0; +} diff --git a/dev/zka/src/Timer.cxx b/dev/zka/src/Timer.cxx deleted file mode 100644 index f1d8c469..00000000 --- a/dev/zka/src/Timer.cxx +++ /dev/null @@ -1,47 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -///! BUGS: 0 -///! @file Timer.cxx -///! @brief Software Timer implementation - -using namespace Kernel; - -/// @brief Unimplemented as it is an interface. -Int32 TimerInterface::Wait() noexcept -{ - return kErrorUnimplemented; -} - -/// @brief SoftwareTimer class, meant to be generic. - -SoftwareTimer::SoftwareTimer(Int64 seconds) - : fWaitFor(seconds) -{ - fDigitalTimer = new IntPtr(); - MUST_PASS(fDigitalTimer); -} - -SoftwareTimer::~SoftwareTimer() -{ - delete fDigitalTimer; - fWaitFor = 0; -} - -Int32 SoftwareTimer::Wait() noexcept -{ - if (fWaitFor < 1) - return -1; - - while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) - { - ++(*fDigitalTimer); - } - - return 0; -} diff --git a/dev/zka/src/User.cc b/dev/zka/src/User.cc new file mode 100644 index 00000000..9037d729 --- /dev/null +++ b/dev/zka/src/User.cc @@ -0,0 +1,138 @@ +/* + * ======================================================== + * + * ZKA + * Copyright ZKA Web Services Co., all rights reserved. + * + * File: User.cxx + * Purpose: User class, used to provide authentication and security. + * + * ======================================================== + */ + +#include + +#include +#include +#include +#include +#include + +#define cStdUser (0xCEEF) +#define cSuperUser (0xECCF) + +/// BUGS: 0 + +namespace Kernel +{ + namespace Detail + { + /// \brief Constructs a password by hashing the password. + /// \param password password to hash. + /// \return the hashed password + const Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length) + { + if (!password || !user) + return -1; + + kcout << "Constructing password...\r"; + + for (Size i_pass = 0; i_pass < length; ++i_pass) + { + Char cur_chr = in_password[i_pass]; + + if (cur_chr == 0) + break; + + password[i_pass] = cur_chr + (user->IsStdUser() ? cStdUser : cSuperUser); + } + + kcout << "Done constructing password...\r"; + + return 0; + } + } // namespace Detail + + User::User(const Int32& sel, const Char* userName) + : fRing((RingKind)sel) + { + MUST_PASS(sel >= 0); + rt_copy_memory((VoidPtr)userName, this->fUserName, rt_string_len(userName)); + } + + User::User(const RingKind& ringKind, const Char* userName) + : fRing(ringKind) + { + rt_copy_memory((VoidPtr)userName, this->fUserName, rt_string_len(userName)); + } + + User::~User() = default; + + Bool User::TrySave(const Char* password_to_fill) noexcept + { + if (!password_to_fill || + *password_to_fill == 0) + return No; + + SizeT len = rt_string_len(password_to_fill); + + Char* password = new Char[len]; + MUST_PASS(password); + + // fill data first, generate hash. + // return false on error. + + rt_copy_memory((VoidPtr)password_to_fill, password, len); + + if (!Detail::cred_construct_token(password, password_to_fill, this, len)) + { + delete[] password; + password = nullptr; + + return No; + } + + // then store password. + + rt_copy_memory(password, this->fUserToken, rt_string_len(password_to_fill)); + + delete[] password; + password = nullptr; + + kcout << "Saved password successfully...\r"; + + return Yes; + } + + Bool User::operator==(const User& lhs) + { + return lhs.fRing == this->fRing; + } + + Bool User::operator!=(const User& lhs) + { + return lhs.fRing != this->fRing; + } + + Char* User::Name() noexcept + { + return this->fUserName; + } + + /// @brief Returns the user's ring. + /// @return The king of ring the user is attached to. + const RingKind& User::Ring() noexcept + { + return this->fRing; + } + + Bool User::IsStdUser() noexcept + { + return this->Ring() == RingKind::kRingStdUser; + } + + Bool User::IsSuperUser() noexcept + { + return this->Ring() == RingKind::kRingSuperUser; + } +} // namespace Kernel diff --git a/dev/zka/src/User.cxx b/dev/zka/src/User.cxx deleted file mode 100644 index f8800e9b..00000000 --- a/dev/zka/src/User.cxx +++ /dev/null @@ -1,138 +0,0 @@ -/* - * ======================================================== - * - * ZKA - * Copyright ZKA Web Services Co., all rights reserved. - * - * File: User.cxx - * Purpose: User class, used to provide authentication and security. - * - * ======================================================== - */ - -#include - -#include -#include -#include -#include -#include - -#define cStdUser (0xCEEF) -#define cSuperUser (0xECCF) - -/// BUGS: 0 - -namespace Kernel -{ - namespace Detail - { - /// \brief Constructs a password by hashing the password. - /// \param password password to hash. - /// \return the hashed password - const Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length) - { - if (!password || !user) - return -1; - - kcout << "Constructing password...\r"; - - for (Size i_pass = 0; i_pass < length; ++i_pass) - { - Char cur_chr = in_password[i_pass]; - - if (cur_chr == 0) - break; - - password[i_pass] = cur_chr + (user->IsStdUser() ? cStdUser : cSuperUser); - } - - kcout << "Done constructing password...\r"; - - return 0; - } - } // namespace Detail - - User::User(const Int32& sel, const Char* userName) - : fRing((RingKind)sel) - { - MUST_PASS(sel >= 0); - rt_copy_memory((VoidPtr)userName, this->fUserName, rt_string_len(userName)); - } - - User::User(const RingKind& ringKind, const Char* userName) - : fRing(ringKind) - { - rt_copy_memory((VoidPtr)userName, this->fUserName, rt_string_len(userName)); - } - - User::~User() = default; - - Bool User::TrySave(const Char* password_to_fill) noexcept - { - if (!password_to_fill || - *password_to_fill == 0) - return No; - - SizeT len = rt_string_len(password_to_fill); - - Char* password = new Char[len]; - MUST_PASS(password); - - // fill data first, generate hash. - // return false on error. - - rt_copy_memory((VoidPtr)password_to_fill, password, len); - - if (!Detail::cred_construct_token(password, password_to_fill, this, len)) - { - delete[] password; - password = nullptr; - - return No; - } - - // then store password. - - rt_copy_memory(password, this->fUserToken, rt_string_len(password_to_fill)); - - delete[] password; - password = nullptr; - - kcout << "Saved password successfully...\r"; - - return Yes; - } - - Bool User::operator==(const User& lhs) - { - return lhs.fRing == this->fRing; - } - - Bool User::operator!=(const User& lhs) - { - return lhs.fRing != this->fRing; - } - - Char* User::Name() noexcept - { - return this->fUserName; - } - - /// @brief Returns the user's ring. - /// @return The king of ring the user is attached to. - const RingKind& User::Ring() noexcept - { - return this->fRing; - } - - Bool User::IsStdUser() noexcept - { - return this->Ring() == RingKind::kRingStdUser; - } - - Bool User::IsSuperUser() noexcept - { - return this->Ring() == RingKind::kRingSuperUser; - } -} // namespace Kernel diff --git a/dev/zka/src/UserProcessScheduler.cc b/dev/zka/src/UserProcessScheduler.cc new file mode 100644 index 00000000..7dd213b5 --- /dev/null +++ b/dev/zka/src/UserProcessScheduler.cc @@ -0,0 +1,592 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + + FILE: UserProcessScheduler.cxx + PURPOSE: EL0/Ring-3 Process scheduler. + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file UserProcessScheduler.cxx +/// @brief User process scheduler. +/***********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +///! BUGS: 0 + +/***********************************************************************************/ +/** TODO: Document the Kernel, SDK and kits. */ +/***********************************************************************************/ + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief Exit Code global variable. + /***********************************************************************************/ + + STATIC UInt32 cLastExitCode = 0U; + + /***********************************************************************************/ + /// @brief User Process scheduler global and external reference of thread scheduler. + /***********************************************************************************/ + + UserProcessScheduler* kProcessScheduler = nullptr; + EXTERN HardwareThreadScheduler* kHardwareThreadScheduler; + + /// @brief Gets the last exit code. + /// @note Not thread-safe. + /// @return Int32 the last exit code. + const UInt32& sched_get_exit_code(void) noexcept + { + return cLastExitCode; + } + + /***********************************************************************************/ + /// @brief crash current process. + /***********************************************************************************/ + + Void UserProcess::Crash() + { + if (this->Status != ProcessStatusKind::kRunning) + return; + + if (*this->Name != 0) + { + kcout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << endl; + } + + this->Exit(kErrorProcessFault); + } + + /***********************************************************************************/ + //! @brief boolean operator, check status. + /***********************************************************************************/ + + UserProcess::operator bool() + { + return this->Status != ProcessStatusKind::kDead; + } + + /***********************************************************************************/ + /// @brief Gets the local last exit code. + /// @note Not thread-safe. + /// @return Int32 the last exit code. + /***********************************************************************************/ + + const UInt32& UserProcess::GetExitCode() noexcept + { + return this->fLastExitCode; + } + + /***********************************************************************************/ + /// @brief Error code variable getter. + /***********************************************************************************/ + + Int32& UserProcess::GetLocalCode() noexcept + { + return fLocalCode; + } + + /***********************************************************************************/ + /// @brief Wake process. + /***********************************************************************************/ + + void UserProcess::Wake(const bool should_wakeup) + { + this->Status = + should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; + } + + /***********************************************************************************/ + /** @brief Add pointer to entry. */ + /***********************************************************************************/ + + VoidPtr UserProcess::New(const SizeT& sz) + { +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(reinterpret_cast(this->MemoryPD)); + + auto ptr = mm_new_heap(sz, Yes, Yes); + + hal_write_cr3(reinterpret_cast(pd)); +#else + auto ptr = mm_new_heap(sz, Yes, Yes); +#endif + + if (!this->MemoryEntryList) + { + this->MemoryEntryList = new UserProcess::PROCESS_MEMORY_ENTRY(); + this->MemoryEntryList->MemoryEntry = ptr; + + this->MemoryEntryList->MemoryPrev = nullptr; + this->MemoryEntryList->MemoryNext = nullptr; + + return ptr; + } + else + { + PROCESS_MEMORY_ENTRY* entry = this->MemoryEntryList; + PROCESS_MEMORY_ENTRY* prev_entry = nullptr; + + while (!entry) + { + if (entry->MemoryEntry == nullptr) + break; // chose to break here, when we get an already allocated memory entry for our needs. + + prev_entry = entry; + entry = entry->MemoryNext; + } + + entry->MemoryNext = new PROCESS_MEMORY_ENTRY(); + entry->MemoryNext->MemoryEntry = ptr; + + entry->MemoryNext->MemoryPrev = entry; + entry->MemoryNext->MemoryNext = nullptr; + } + + return nullptr; + } + + /***********************************************************************************/ + /** @brief Free pointer from usage. */ + /***********************************************************************************/ + + Boolean UserProcess::Delete(VoidPtr ptr, const SizeT& sz) + { + if (!ptr || + sz == 0) + return No; + + PROCESS_MEMORY_ENTRY* entry = this->MemoryEntryList; + + while (entry != nullptr) + { + if (entry->MemoryEntry == ptr) + { +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(reinterpret_cast(this->MemoryPD)); + + auto ret = mm_delete_heap(entry->MemoryEntry); + + hal_write_cr3(pd); + + return ret; +#else + Bool ret = mm_delete_heap(ptr); + return ret; +#endif + } + + entry = entry->MemoryNext; + } + + return No; + } + + /***********************************************************************************/ + /// @brief Gets the name of the current process. + /***********************************************************************************/ + + const Char* UserProcess::GetProcessName() noexcept + { + return this->Name; + } + + /***********************************************************************************/ + /// @brief Gets the owner of the process. + /***********************************************************************************/ + + const User* UserProcess::GetOwner() noexcept + { + return this->Owner; + } + + /// @brief UserProcess status getter. + const ProcessStatusKind& UserProcess::GetStatus() noexcept + { + return this->Status; + } + + /***********************************************************************************/ + /** + @brief Affinity is the time slot allowed for the process. + */ + /***********************************************************************************/ + + const AffinityKind& UserProcess::GetAffinity() noexcept + { + return this->Affinity; + } + + /***********************************************************************************/ + /** + @brief Process exit method. + */ + /***********************************************************************************/ + + void UserProcess::Exit(const Int32& exit_code) + { + this->Status = ProcessStatusKind::kDead; + + fLastExitCode = exit_code; + cLastExitCode = exit_code; + + auto memory_list = this->MemoryEntryList; + + // Deleting memory lists. Make sure to free all of them. + while (memory_list) + { + if (memory_list->MemoryEntry) + { +#ifdef __ZKA_AMD64__ + auto pd = hal_read_cr3(); + hal_write_cr3(reinterpret_cast(this->MemoryPD)); +#endif + + MUST_PASS(mm_delete_heap(memory_list->MemoryEntry)); + +#ifdef __ZKA_AMD64__ + hal_write_cr3(pd); +#endif + } + + auto next = memory_list->MemoryNext; + + mm_delete_heap(memory_list); + memory_list = nullptr; + + memory_list = next; + } + + //! Free the memory's page directory. + HAL::mm_free_bitmap(reinterpret_cast(this->MemoryPD)); + + //! Delete image if not done already. + if (this->Image && mm_is_valid_heap(this->Image)) + mm_delete_heap(this->Image); + + if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) + mm_delete_heap((VoidPtr)this->StackFrame); + + this->Image = nullptr; + this->StackFrame = nullptr; + + if (this->Kind == kExectuableDLLKind) + { + Bool success = false; + rtl_fini_dll(this, this->PefDLLDelegate, &success); + + if (success) + { + this->PefDLLDelegate = nullptr; + } + } + + if (this->StackReserve) + delete[] this->StackReserve; + + this->ProcessId = 0; + + if (this->ProcessId > 0) + UserProcessScheduler::The().Remove(this->ProcessId); + } + + /***********************************************************************************/ + /// @brief Add process to list. + /// @param process the process *Ref* class. + /// @return the process index inside the team. + /***********************************************************************************/ + + SizeT UserProcessScheduler::Add(UserProcess process) + { + if (mTeam.mProcessAmount > kSchedProcessLimitPerTeam) + return 0; + +#ifdef __ZKA_AMD64__ + process.MemoryPD = reinterpret_cast(HAL::mm_alloc_bitmap(Yes, Yes, sizeof(PDE), Yes)); +#endif // __ZKA_AMD64__ + + process.Status = ProcessStatusKind::kStarting; + + process.StackFrame = (HAL::StackFramePtr)mm_new_heap(sizeof(HAL::StackFrame), Yes, Yes); + + if (!process.StackFrame) + { + process.Crash(); + return -kErrorProcessFault; + } + + // Create heap according to type of process. + if (process.Kind == UserProcess::kExectuableDLLKind) + { + process.PefDLLDelegate = rtl_init_dll(&process); + } + + if (!process.Image) + { + if (process.Kind != UserProcess::kExectuableDLLKind) + { + process.Crash(); + return -kErrorProcessFault; + } + } + + // get preferred stack size by app. + const auto cMaxStackSize = process.StackSize; + process.StackReserve = (UInt8*)mm_new_heap(sizeof(UInt8) * cMaxStackSize, Yes, Yes); + + if (!process.StackReserve) + { + mm_delete_heap(process.StackFrame); + process.StackFrame = nullptr; + return -kErrorProcessFault; + } + + ++mTeam.mProcessAmount; + + process.ProcessId = mTeam.mProcessAmount; + process.Status = ProcessStatusKind::kRunning; + + // avoid the pitfalls of moving process. + auto ret_pid = process.ProcessId; + + mTeam.AsArray()[process.ProcessId] = move(process); + + return ret_pid; + } + + /***********************************************************************************/ + /// @brief Retrieves the singleton of the process scheduler. + /***********************************************************************************/ + + UserProcessScheduler& UserProcessScheduler::The() + { + MUST_PASS(kProcessScheduler); + return *kProcessScheduler; + } + + /***********************************************************************************/ + + /// @brief Remove process from list. + /// @param process_id process slot inside team. + /// @retval true process was removed. + /// @retval false process doesn't exist in team. + + /***********************************************************************************/ + + Bool UserProcessScheduler::Remove(ProcessID process_id) + { + // check if process is within range. + if (process_id > mTeam.AsArray().Count()) + return No; + + mTeam.AsArray()[process_id].Status = ProcessStatusKind::kDead; + --mTeam.mProcessAmount; + + return Yes; + } + + const Bool UserProcessScheduler::IsUser() + { + return Yes; + } + + const Bool UserProcessScheduler::IsKernel() + { + return No; + } + + const Bool UserProcessScheduler::HasMP() + { + return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; + } + + /***********************************************************************************/ + + /// @brief Run User scheduler object. + /// @return Process executed within team. + + /***********************************************************************************/ + + SizeT UserProcessScheduler::Run() noexcept + { + SizeT process_index = 0; //! we store this guy to tell the scheduler how many + //! things we have scheduled. + + for (; process_index < mTeam.AsArray().Capacity(); ++process_index) + { + auto& process = mTeam.AsArray()[process_index]; + + //! check if process needs to be scheduled. + if (UserProcessHelper::CanBeScheduled(process)) + { + // Set current process header. + this->CurrentProcess() = process; + + process.PTime = static_cast(process.Affinity); + + UserProcessScheduler::The().CurrentProcess().Leak().Status = ProcessStatusKind::kFrozen; + UserProcessScheduler::The().CurrentProcess() = process; + + kcout << "Switch to '" << process.Name << "'.\r"; + + // tell helper to find a core to schedule on. + if (!UserProcessHelper::Switch(process.Image, &process.StackReserve[process.StackSize - 1], process.StackFrame, + process.ProcessId)) + { + process.Crash(); + continue; + } + } + else + { + if (process.Status == ProcessStatusKind::kRunning) + --process.PTime; + } + } + + kcout << "Scheduled Process Count: " << number(process_index) << endl; + + return process_index; + } + + /// @brief Gets the current scheduled team. + /// @return + UserProcessTeam& UserProcessScheduler::CurrentTeam() + { + return mTeam; + } + + /// @internal + + /// @brief Gets current running process. + /// @return + Ref& UserProcessScheduler::CurrentProcess() + { + return mTeam.AsRef(); + } + + /// @brief Current proccess id getter. + /// @return UserProcess ID integer. + PID& UserProcessHelper::TheCurrentPID() + { + kcout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; + return kProcessScheduler->CurrentProcess().Leak().ProcessId; + } + + /// @brief Check if process can be schedulded. + /// @param process the process reference. + /// @retval true can be schedulded. + /// @retval false cannot be schedulded. + Bool UserProcessHelper::CanBeScheduled(const UserProcess& process) + { + if (process.Status == ProcessStatusKind::kKilled || + process.Status == ProcessStatusKind::kDead) + return No; + + if (!process.Image && + process.Kind == UserProcess::kExectuableKind) + return No; + + return process.PTime < 1 && process.Status == ProcessStatusKind::kRunning; + } + + /***********************************************************************************/ + /** + * @brief Allocate a scheduler. + */ + /***********************************************************************************/ + + Bool UserProcessHelper::InitializeScheduler() + { + if (!kProcessScheduler) + { + kProcessScheduler = new UserProcessScheduler(); + } + + if (!kHardwareThreadScheduler) + { + kHardwareThreadScheduler = new HardwareThreadScheduler(); + } + + return Yes; + } + + /***********************************************************************************/ + /** + * @brief Start scheduling current AP/Hart/Core. + */ + /***********************************************************************************/ + SizeT UserProcessHelper::StartScheduling() + { + if (!kProcessScheduler) + return 0; + + return kProcessScheduler->Run(); + } + + /***********************************************************************************/ + /** + * \brief Does a context switch in a CPU. + * \param the_stack the stackframe of the running app. + * \param new_pid the process's PID. + */ + /***********************************************************************************/ + + Bool UserProcessHelper::Switch(VoidPtr image_ptr, UInt8* stack, HAL::StackFramePtr frame_ptr, const PID& new_pid) + { + if (!stack || !frame_ptr || !image_ptr || new_pid < 0) + return No; + + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Count(); ++index) + { + if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidHart) + continue; + + if (HardwareThreadScheduler::The()[index].Leak()->Kind() != + ThreadKind::kHartBoot && + HardwareThreadScheduler::The()[index].Leak()->Kind() != + ThreadKind::kHartSystemReserved) + { + PID prev_pid = UserProcessHelper::TheCurrentPID(); + UserProcessHelper::TheCurrentPID() = new_pid; + + auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime; + HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].ProcessId; + Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr); + + if (!ret) + { + HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime; + UserProcessHelper::TheCurrentPID() = prev_pid; + + continue; + } + } + } + + return false; + } + + /// @brief this checks if any process is on the team. + UserProcessScheduler::operator bool() + { + return mTeam.AsArray().Count() > 0; + } + + /// @brief this checks if no process is on the team. + bool UserProcessScheduler::operator!() + { + return mTeam.AsArray().Count() == 0; + } +} // namespace Kernel diff --git a/dev/zka/src/UserProcessScheduler.cxx b/dev/zka/src/UserProcessScheduler.cxx deleted file mode 100644 index 6802f59d..00000000 --- a/dev/zka/src/UserProcessScheduler.cxx +++ /dev/null @@ -1,592 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - - FILE: UserProcessScheduler.cxx - PURPOSE: EL0/Ring-3 Process scheduler. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file UserProcessScheduler.cxx -/// @brief User process scheduler. -/***********************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -///! BUGS: 0 - -/***********************************************************************************/ -/** TODO: Document the Kernel, SDK and kits. */ -/***********************************************************************************/ - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief Exit Code global variable. - /***********************************************************************************/ - - STATIC UInt32 cLastExitCode = 0U; - - /***********************************************************************************/ - /// @brief User Process scheduler global and external reference of thread scheduler. - /***********************************************************************************/ - - UserProcessScheduler* kProcessScheduler = nullptr; - EXTERN HardwareThreadScheduler* kHardwareThreadScheduler; - - /// @brief Gets the last exit code. - /// @note Not thread-safe. - /// @return Int32 the last exit code. - const UInt32& sched_get_exit_code(void) noexcept - { - return cLastExitCode; - } - - /***********************************************************************************/ - /// @brief crash current process. - /***********************************************************************************/ - - Void UserProcess::Crash() - { - if (this->Status != ProcessStatusKind::kRunning) - return; - - if (*this->Name != 0) - { - kcout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << endl; - } - - this->Exit(kErrorProcessFault); - } - - /***********************************************************************************/ - //! @brief boolean operator, check status. - /***********************************************************************************/ - - UserProcess::operator bool() - { - return this->Status != ProcessStatusKind::kDead; - } - - /***********************************************************************************/ - /// @brief Gets the local last exit code. - /// @note Not thread-safe. - /// @return Int32 the last exit code. - /***********************************************************************************/ - - const UInt32& UserProcess::GetExitCode() noexcept - { - return this->fLastExitCode; - } - - /***********************************************************************************/ - /// @brief Error code variable getter. - /***********************************************************************************/ - - Int32& UserProcess::GetLocalCode() noexcept - { - return fLocalCode; - } - - /***********************************************************************************/ - /// @brief Wake process. - /***********************************************************************************/ - - void UserProcess::Wake(const bool should_wakeup) - { - this->Status = - should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen; - } - - /***********************************************************************************/ - /** @brief Add pointer to entry. */ - /***********************************************************************************/ - - VoidPtr UserProcess::New(const SizeT& sz) - { -#ifdef __ZKA_AMD64__ - auto pd = hal_read_cr3(); - hal_write_cr3(reinterpret_cast(this->MemoryPD)); - - auto ptr = mm_new_heap(sz, Yes, Yes); - - hal_write_cr3(reinterpret_cast(pd)); -#else - auto ptr = mm_new_heap(sz, Yes, Yes); -#endif - - if (!this->MemoryEntryList) - { - this->MemoryEntryList = new UserProcess::PROCESS_MEMORY_ENTRY(); - this->MemoryEntryList->MemoryEntry = ptr; - - this->MemoryEntryList->MemoryPrev = nullptr; - this->MemoryEntryList->MemoryNext = nullptr; - - return ptr; - } - else - { - PROCESS_MEMORY_ENTRY* entry = this->MemoryEntryList; - PROCESS_MEMORY_ENTRY* prev_entry = nullptr; - - while (!entry) - { - if (entry->MemoryEntry == nullptr) - break; // chose to break here, when we get an already allocated memory entry for our needs. - - prev_entry = entry; - entry = entry->MemoryNext; - } - - entry->MemoryNext = new PROCESS_MEMORY_ENTRY(); - entry->MemoryNext->MemoryEntry = ptr; - - entry->MemoryNext->MemoryPrev = entry; - entry->MemoryNext->MemoryNext = nullptr; - } - - return nullptr; - } - - /***********************************************************************************/ - /** @brief Free pointer from usage. */ - /***********************************************************************************/ - - Boolean UserProcess::Delete(VoidPtr ptr, const SizeT& sz) - { - if (!ptr || - sz == 0) - return No; - - PROCESS_MEMORY_ENTRY* entry = this->MemoryEntryList; - - while (entry != nullptr) - { - if (entry->MemoryEntry == ptr) - { -#ifdef __ZKA_AMD64__ - auto pd = hal_read_cr3(); - hal_write_cr3(reinterpret_cast(this->MemoryPD)); - - auto ret = mm_delete_heap(entry->MemoryEntry); - - hal_write_cr3(pd); - - return ret; -#else - Bool ret = mm_delete_heap(ptr); - return ret; -#endif - } - - entry = entry->MemoryNext; - } - - return No; - } - - /***********************************************************************************/ - /// @brief Gets the name of the current process. - /***********************************************************************************/ - - const Char* UserProcess::GetProcessName() noexcept - { - return this->Name; - } - - /***********************************************************************************/ - /// @brief Gets the owner of the process. - /***********************************************************************************/ - - const User* UserProcess::GetOwner() noexcept - { - return this->Owner; - } - - /// @brief UserProcess status getter. - const ProcessStatusKind& UserProcess::GetStatus() noexcept - { - return this->Status; - } - - /***********************************************************************************/ - /** - @brief Affinity is the time slot allowed for the process. - */ - /***********************************************************************************/ - - const AffinityKind& UserProcess::GetAffinity() noexcept - { - return this->Affinity; - } - - /***********************************************************************************/ - /** - @brief Process exit method. - */ - /***********************************************************************************/ - - void UserProcess::Exit(const Int32& exit_code) - { - this->Status = ProcessStatusKind::kDead; - - fLastExitCode = exit_code; - cLastExitCode = exit_code; - - auto memory_list = this->MemoryEntryList; - - // Deleting memory lists. Make sure to free all of them. - while (memory_list) - { - if (memory_list->MemoryEntry) - { -#ifdef __ZKA_AMD64__ - auto pd = hal_read_cr3(); - hal_write_cr3(reinterpret_cast(this->MemoryPD)); -#endif - - MUST_PASS(mm_delete_heap(memory_list->MemoryEntry)); - -#ifdef __ZKA_AMD64__ - hal_write_cr3(pd); -#endif - } - - auto next = memory_list->MemoryNext; - - mm_delete_heap(memory_list); - memory_list = nullptr; - - memory_list = next; - } - - //! Free the memory's page directory. - HAL::mm_free_bitmap(reinterpret_cast(this->MemoryPD)); - - //! Delete image if not done already. - if (this->Image && mm_is_valid_heap(this->Image)) - mm_delete_heap(this->Image); - - if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) - mm_delete_heap((VoidPtr)this->StackFrame); - - this->Image = nullptr; - this->StackFrame = nullptr; - - if (this->Kind == kExectuableDLLKind) - { - Bool success = false; - rtl_fini_dll(this, this->PefDLLDelegate, &success); - - if (success) - { - this->PefDLLDelegate = nullptr; - } - } - - if (this->StackReserve) - delete[] this->StackReserve; - - this->ProcessId = 0; - - if (this->ProcessId > 0) - UserProcessScheduler::The().Remove(this->ProcessId); - } - - /***********************************************************************************/ - /// @brief Add process to list. - /// @param process the process *Ref* class. - /// @return the process index inside the team. - /***********************************************************************************/ - - SizeT UserProcessScheduler::Add(UserProcess process) - { - if (mTeam.mProcessAmount > kSchedProcessLimitPerTeam) - return 0; - -#ifdef __ZKA_AMD64__ - process.MemoryPD = reinterpret_cast(HAL::mm_alloc_bitmap(Yes, Yes, sizeof(PDE), Yes)); -#endif // __ZKA_AMD64__ - - process.Status = ProcessStatusKind::kStarting; - - process.StackFrame = (HAL::StackFramePtr)mm_new_heap(sizeof(HAL::StackFrame), Yes, Yes); - - if (!process.StackFrame) - { - process.Crash(); - return -kErrorProcessFault; - } - - // Create heap according to type of process. - if (process.Kind == UserProcess::kExectuableDLLKind) - { - process.PefDLLDelegate = rtl_init_dll(&process); - } - - if (!process.Image) - { - if (process.Kind != UserProcess::kExectuableDLLKind) - { - process.Crash(); - return -kErrorProcessFault; - } - } - - // get preferred stack size by app. - const auto cMaxStackSize = process.StackSize; - process.StackReserve = (UInt8*)mm_new_heap(sizeof(UInt8) * cMaxStackSize, Yes, Yes); - - if (!process.StackReserve) - { - mm_delete_heap(process.StackFrame); - process.StackFrame = nullptr; - return -kErrorProcessFault; - } - - ++mTeam.mProcessAmount; - - process.ProcessId = mTeam.mProcessAmount; - process.Status = ProcessStatusKind::kRunning; - - // avoid the pitfalls of moving process. - auto ret_pid = process.ProcessId; - - mTeam.AsArray()[process.ProcessId] = move(process); - - return ret_pid; - } - - /***********************************************************************************/ - /// @brief Retrieves the singleton of the process scheduler. - /***********************************************************************************/ - - UserProcessScheduler& UserProcessScheduler::The() - { - MUST_PASS(kProcessScheduler); - return *kProcessScheduler; - } - - /***********************************************************************************/ - - /// @brief Remove process from list. - /// @param process_id process slot inside team. - /// @retval true process was removed. - /// @retval false process doesn't exist in team. - - /***********************************************************************************/ - - Bool UserProcessScheduler::Remove(ProcessID process_id) - { - // check if process is within range. - if (process_id > mTeam.AsArray().Count()) - return No; - - mTeam.AsArray()[process_id].Status = ProcessStatusKind::kDead; - --mTeam.mProcessAmount; - - return Yes; - } - - const Bool UserProcessScheduler::IsUser() - { - return Yes; - } - - const Bool UserProcessScheduler::IsKernel() - { - return No; - } - - const Bool UserProcessScheduler::HasMP() - { - return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; - } - - /***********************************************************************************/ - - /// @brief Run User scheduler object. - /// @return Process executed within team. - - /***********************************************************************************/ - - SizeT UserProcessScheduler::Run() noexcept - { - SizeT process_index = 0; //! we store this guy to tell the scheduler how many - //! things we have scheduled. - - for (; process_index < mTeam.AsArray().Capacity(); ++process_index) - { - auto& process = mTeam.AsArray()[process_index]; - - //! check if process needs to be scheduled. - if (UserProcessHelper::CanBeScheduled(process)) - { - // Set current process header. - this->CurrentProcess() = process; - - process.PTime = static_cast(process.Affinity); - - UserProcessScheduler::The().CurrentProcess().Leak().Status = ProcessStatusKind::kFrozen; - UserProcessScheduler::The().CurrentProcess() = process; - - kcout << "Switch to '" << process.Name << "'.\r"; - - // tell helper to find a core to schedule on. - if (!UserProcessHelper::Switch(process.Image, &process.StackReserve[process.StackSize - 1], process.StackFrame, - process.ProcessId)) - { - process.Crash(); - continue; - } - } - else - { - if (process.Status == ProcessStatusKind::kRunning) - --process.PTime; - } - } - - kcout << "Scheduled Process Count: " << number(process_index) << endl; - - return process_index; - } - - /// @brief Gets the current scheduled team. - /// @return - UserProcessTeam& UserProcessScheduler::CurrentTeam() - { - return mTeam; - } - - /// @internal - - /// @brief Gets current running process. - /// @return - Ref& UserProcessScheduler::CurrentProcess() - { - return mTeam.AsRef(); - } - - /// @brief Current proccess id getter. - /// @return UserProcess ID integer. - PID& UserProcessHelper::TheCurrentPID() - { - kcout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return kProcessScheduler->CurrentProcess().Leak().ProcessId; - } - - /// @brief Check if process can be schedulded. - /// @param process the process reference. - /// @retval true can be schedulded. - /// @retval false cannot be schedulded. - Bool UserProcessHelper::CanBeScheduled(const UserProcess& process) - { - if (process.Status == ProcessStatusKind::kKilled || - process.Status == ProcessStatusKind::kDead) - return No; - - if (!process.Image && - process.Kind == UserProcess::kExectuableKind) - return No; - - return process.PTime < 1 && process.Status == ProcessStatusKind::kRunning; - } - - /***********************************************************************************/ - /** - * @brief Allocate a scheduler. - */ - /***********************************************************************************/ - - Bool UserProcessHelper::InitializeScheduler() - { - if (!kProcessScheduler) - { - kProcessScheduler = new UserProcessScheduler(); - } - - if (!kHardwareThreadScheduler) - { - kHardwareThreadScheduler = new HardwareThreadScheduler(); - } - - return Yes; - } - - /***********************************************************************************/ - /** - * @brief Start scheduling current AP/Hart/Core. - */ - /***********************************************************************************/ - SizeT UserProcessHelper::StartScheduling() - { - if (!kProcessScheduler) - return 0; - - return kProcessScheduler->Run(); - } - - /***********************************************************************************/ - /** - * \brief Does a context switch in a CPU. - * \param the_stack the stackframe of the running app. - * \param new_pid the process's PID. - */ - /***********************************************************************************/ - - Bool UserProcessHelper::Switch(VoidPtr image_ptr, UInt8* stack, HAL::StackFramePtr frame_ptr, const PID& new_pid) - { - if (!stack || !frame_ptr || !image_ptr || new_pid < 0) - return No; - - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Count(); ++index) - { - if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidHart) - continue; - - if (HardwareThreadScheduler::The()[index].Leak()->Kind() != - ThreadKind::kHartBoot && - HardwareThreadScheduler::The()[index].Leak()->Kind() != - ThreadKind::kHartSystemReserved) - { - PID prev_pid = UserProcessHelper::TheCurrentPID(); - UserProcessHelper::TheCurrentPID() = new_pid; - - auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime; - HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].ProcessId; - Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr); - - if (!ret) - { - HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime; - UserProcessHelper::TheCurrentPID() = prev_pid; - - continue; - } - } - } - - return false; - } - - /// @brief this checks if any process is on the team. - UserProcessScheduler::operator bool() - { - return mTeam.AsArray().Count() > 0; - } - - /// @brief this checks if no process is on the team. - bool UserProcessScheduler::operator!() - { - return mTeam.AsArray().Count() == 0; - } -} // namespace Kernel diff --git a/dev/zka/src/UserProcessTeam.cc b/dev/zka/src/UserProcessTeam.cc new file mode 100644 index 00000000..22b158b9 --- /dev/null +++ b/dev/zka/src/UserProcessTeam.cc @@ -0,0 +1,47 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +/***********************************************************************************/ +/// @file UserProcessTeam.cxx +/// @brief UserProcess teams implementation. +/***********************************************************************************/ + +#include + +namespace Kernel +{ + /***********************************************************************************/ + /// @brief UserProcess list array getter. + /// @return The list of process to schedule. + /***********************************************************************************/ + + Array& UserProcessTeam::AsArray() + { + return mProcessList; + } + + /***********************************************************************************/ + /// @brief Get team ID. + /// @return The team's ID. + /***********************************************************************************/ + + ProcessID& UserProcessTeam::Id() noexcept + { + return mTeamId; + } + + /***********************************************************************************/ + /// @brief Get current process getter as Ref. + /// @return The current process header. + /***********************************************************************************/ + + Ref& UserProcessTeam::AsRef() + { + return mCurrentProcess; + } +} // namespace Kernel + +// last rev 05-03-24 diff --git a/dev/zka/src/UserProcessTeam.cxx b/dev/zka/src/UserProcessTeam.cxx deleted file mode 100644 index 6d3fa2db..00000000 --- a/dev/zka/src/UserProcessTeam.cxx +++ /dev/null @@ -1,47 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -/***********************************************************************************/ -/// @file UserProcessTeam.cxx -/// @brief UserProcess teams implementation. -/***********************************************************************************/ - -#include - -namespace Kernel -{ - /***********************************************************************************/ - /// @brief UserProcess list array getter. - /// @return The list of process to schedule. - /***********************************************************************************/ - - Array& UserProcessTeam::AsArray() - { - return mProcessList; - } - - /***********************************************************************************/ - /// @brief Get team ID. - /// @return The team's ID. - /***********************************************************************************/ - - ProcessID& UserProcessTeam::Id() noexcept - { - return mTeamId; - } - - /***********************************************************************************/ - /// @brief Get current process getter as Ref. - /// @return The current process header. - /***********************************************************************************/ - - Ref& UserProcessTeam::AsRef() - { - return mCurrentProcess; - } -} // namespace Kernel - -// last rev 05-03-24 diff --git a/dev/zka/src/Utils.cc b/dev/zka/src/Utils.cc new file mode 100644 index 00000000..7427fe34 --- /dev/null +++ b/dev/zka/src/Utils.cc @@ -0,0 +1,212 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + Int rt_string_cmp(const Char* src, const Char* cmp, Size size) + { + if (!cmp || + !src) + return 1; + + 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) + { + Size len{0}; + while (str[len] != '\0') + { + if (len > _len) + { + return 0; + } + + len++; + } + + return len; + } + + Size rt_string_len(const Char* ptr) + { + if (*ptr == 0) + return 0; + + SizeT cnt = 0; + + while (ptr[cnt] != (Char)0) + { + cnt++; + } + + return cnt; + } + + voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) + { + if (!src || len < 1) + return nullptr; + + UInt32* start = reinterpret_cast(src); + + while (len) + { + *start = value; + ++start; + --len; + } + + return (voidPtr)start; + } + + Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) + { + 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 (SizeT i = 0; i < rt_string_len(in); ++i) + { + if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0) + return reinterpret_cast(const_cast(in + i)); + } + + return nullptr; + } + + // @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 Kernel diff --git a/dev/zka/src/Utils.cxx b/dev/zka/src/Utils.cxx deleted file mode 100644 index fe0d7ed4..00000000 --- a/dev/zka/src/Utils.cxx +++ /dev/null @@ -1,212 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include -#include - -namespace Kernel -{ - Int rt_string_cmp(const Char* src, const Char* cmp, Size size) - { - if (!cmp || - !src) - return 1; - - 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) - { - Size len{0}; - while (str[len] != '\0') - { - if (len > _len) - { - return 0; - } - - len++; - } - - return len; - } - - Size rt_string_len(const Char* ptr) - { - if (*ptr == 0) - return 0; - - SizeT cnt = 0; - - while (ptr[cnt] != (Char)0) - { - cnt++; - } - - return cnt; - } - - voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len) - { - if (!src || len < 1) - return nullptr; - - UInt32* start = reinterpret_cast(src); - - while (len) - { - *start = value; - ++start; - --len; - } - - return (voidPtr)start; - } - - Int rt_move_memory(const voidPtr src, voidPtr dst, Size len) - { - 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 (SizeT i = 0; i < rt_string_len(in); ++i) - { - if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0) - return reinterpret_cast(const_cast(in + i)); - } - - return nullptr; - } - - // @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 Kernel diff --git a/dev/zka/src/Variant.cc b/dev/zka/src/Variant.cc new file mode 100644 index 00000000..76ff2f04 --- /dev/null +++ b/dev/zka/src/Variant.cc @@ -0,0 +1,33 @@ +/* ------------------------------------------- + + Copyright ZKA Web Services Co. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + const Char* Variant::ToString() + { + switch (fKind) + { + case VariantKind::kXML: + return ("Class:{XML}"); + case VariantKind::kJson: + return ("Class:{Json}"); + case VariantKind::kString: + return ("Class:{String}"); + case VariantKind::kBlob: + return ("Class:{Blob}"); + default: + return ("Class:{Null}"); + } + } + + /// @brief Leak variant's instance. + VoidPtr Variant::Leak() + { + return fPtr; + } +} // namespace Kernel diff --git a/dev/zka/src/Variant.cxx b/dev/zka/src/Variant.cxx deleted file mode 100644 index 6314ed9e..00000000 --- a/dev/zka/src/Variant.cxx +++ /dev/null @@ -1,33 +0,0 @@ -/* ------------------------------------------- - - Copyright ZKA Web Services Co. - -------------------------------------------- */ - -#include - -namespace Kernel -{ - const Char* Variant::ToString() - { - switch (fKind) - { - case VariantKind::kXML: - return ("Class:{XML}"); - case VariantKind::kJson: - return ("Class:{Json}"); - case VariantKind::kString: - return ("Class:{String}"); - case VariantKind::kBlob: - return ("Class:{Blob}"); - default: - return ("Class:{Null}"); - } - } - - /// @brief Leak variant's instance. - VoidPtr Variant::Leak() - { - return fPtr; - } -} // namespace Kernel -- cgit v1.2.3