From af8a516fc22865abd80d6e26f1541fa3d6bebfdc Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 9 May 2024 00:42:44 +0200 Subject: MHR-23: :boom:, refactors. - Move NewBoot to /Boot, thus making Kernel directory only containing the kernel. Signed-off-by: Amlal El Mahrouss --- Kernel/NewKit/Application.hxx | 31 ++++++ Kernel/NewKit/Array.hpp | 69 ++++++++++++ Kernel/NewKit/ArrayList.hpp | 58 ++++++++++ Kernel/NewKit/Atom.hpp | 46 ++++++++ Kernel/NewKit/Crc32.hpp | 22 ++++ Kernel/NewKit/CxxAbi.hpp | 28 +++++ Kernel/NewKit/Defines.hpp | 150 ++++++++++++++++++++++++++ Kernel/NewKit/ErrorOr.hpp | 72 +++++++++++++ Kernel/NewKit/Function.hpp | 53 +++++++++ Kernel/NewKit/Json.hpp | 118 ++++++++++++++++++++ Kernel/NewKit/KernelCheck.hpp | 63 +++++++++++ Kernel/NewKit/Macros.hpp | 98 +++++++++++++++++ Kernel/NewKit/MutableArray.hpp | 232 ++++++++++++++++++++++++++++++++++++++++ Kernel/NewKit/New.hpp | 18 ++++ Kernel/NewKit/NewKit.hpp | 22 ++++ Kernel/NewKit/OwnPtr.hpp | 94 ++++++++++++++++ Kernel/NewKit/PageAllocator.hpp | 21 ++++ Kernel/NewKit/PageManager.hpp | 81 ++++++++++++++ Kernel/NewKit/Pair.hpp | 14 +++ Kernel/NewKit/Pmm.hpp | 44 ++++++++ Kernel/NewKit/Ref.hpp | 89 +++++++++++++++ Kernel/NewKit/Stream.hpp | 58 ++++++++++ Kernel/NewKit/String.hpp | 76 +++++++++++++ Kernel/NewKit/Utils.hpp | 29 +++++ Kernel/NewKit/Variant.hpp | 54 ++++++++++ Kernel/NewKit/compile_flags.txt | 6 ++ 26 files changed, 1646 insertions(+) create mode 100644 Kernel/NewKit/Application.hxx create mode 100644 Kernel/NewKit/Array.hpp create mode 100644 Kernel/NewKit/ArrayList.hpp create mode 100644 Kernel/NewKit/Atom.hpp create mode 100644 Kernel/NewKit/Crc32.hpp create mode 100644 Kernel/NewKit/CxxAbi.hpp create mode 100644 Kernel/NewKit/Defines.hpp create mode 100644 Kernel/NewKit/ErrorOr.hpp create mode 100644 Kernel/NewKit/Function.hpp create mode 100644 Kernel/NewKit/Json.hpp create mode 100644 Kernel/NewKit/KernelCheck.hpp create mode 100644 Kernel/NewKit/Macros.hpp create mode 100644 Kernel/NewKit/MutableArray.hpp create mode 100644 Kernel/NewKit/New.hpp create mode 100644 Kernel/NewKit/NewKit.hpp create mode 100644 Kernel/NewKit/OwnPtr.hpp create mode 100644 Kernel/NewKit/PageAllocator.hpp create mode 100644 Kernel/NewKit/PageManager.hpp create mode 100644 Kernel/NewKit/Pair.hpp create mode 100644 Kernel/NewKit/Pmm.hpp create mode 100644 Kernel/NewKit/Ref.hpp create mode 100644 Kernel/NewKit/Stream.hpp create mode 100644 Kernel/NewKit/String.hpp create mode 100644 Kernel/NewKit/Utils.hpp create mode 100644 Kernel/NewKit/Variant.hpp create mode 100644 Kernel/NewKit/compile_flags.txt (limited to 'Kernel/NewKit') diff --git a/Kernel/NewKit/Application.hxx b/Kernel/NewKit/Application.hxx new file mode 100644 index 00000000..19a892d6 --- /dev/null +++ b/Kernel/NewKit/Application.hxx @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +/// +/// @brief Application object, given by the OS to the process. interact with the OS. +/// @file Application.hxx +/// @author Amlal EL Mahrouss +/// + +#include +#include + +/// \brief Application Interface. +/// \author Amlal El Mahrouss +typedef struct _ApplicationInterface final +{ + /// @brief Releases the object exit the process on main object. + NewOS::Void (*Release)(struct _Application* Self, NewOS::Int32 ExitCode); + /// @brief Invoke a function from the application object. + NewOS::IntPtr (*Invoke)(struct _Application* Self, NewOS::Int32 Sel, ...); + /// @brief Query a new application object from a GUID. + /// @note this doesn't query a process, it query a registered object withtin that app. + NewOS::Void (*Query)(struct _Application* Self, NewOS::VoidPtr* Dst, NewOS::SizeT SzDst, NewOS::XRN::GUIDSequence GuidOf); +} ApplicationInterface, *ApplicationInterfaceRef; + +#define app_cast reinterpret_cast diff --git a/Kernel/NewKit/Array.hpp b/Kernel/NewKit/Array.hpp new file mode 100644 index 00000000..623d9860 --- /dev/null +++ b/Kernel/NewKit/Array.hpp @@ -0,0 +1,69 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ +#pragma once + +#include +#include +#include + +namespace NewOS +{ + template + class Array final + { + public: + explicit Array() = default; + ~Array() = default; + + Array& operator=(const Array&) = default; + Array(const Array&) = default; + + ErrorOr operator[](Size At) + { + if (At > N) + return {}; + + kcout << "Returning element\r"; + return ErrorOr(fArray[At]); + } + + Boolean Empty() const + { + for (auto Val : fArray) + { + if (Val) + return false; + } + + return true; + } + + SizeT Count() const + { + SizeT cntElems = 0UL; + for (auto Val : fArray) + { + if (Val) + ++cntElems; + } + + return cntElems; + } + + const T* CData() + { + return fArray; + } + + operator bool() + { + return !Empty(); + } + + private: + T fArray[N]; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/ArrayList.hpp b/Kernel/NewKit/ArrayList.hpp new file mode 100644 index 00000000..7ac47f40 --- /dev/null +++ b/Kernel/NewKit/ArrayList.hpp @@ -0,0 +1,58 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include + +namespace NewOS +{ + template + class ArrayList final + { + public: + explicit ArrayList(T* list) + : fList(reinterpret_cast(list)) + { + } + + ~ArrayList() = default; + + ArrayList& operator=(const ArrayList&) = default; + ArrayList(const ArrayList&) = default; + + T* Data() + { + return fList; + } + + const T* CData() + { + return fList; + } + + T& operator[](int index) const + { + return fList[index]; + } + + operator bool() + { + return fList; + } + + private: + T* fList; + + friend class InitHelpers; + }; + + template + ArrayList make_list(ValueType val) + { + return ArrayList{val}; + } +} // namespace NewOS diff --git a/Kernel/NewKit/Atom.hpp b/Kernel/NewKit/Atom.hpp new file mode 100644 index 00000000..df7d3dda --- /dev/null +++ b/Kernel/NewKit/Atom.hpp @@ -0,0 +1,46 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ +#pragma once + +#include + +namespace NewOS +{ + template + class Atom final + { + public: + explicit Atom() = default; + ~Atom() = default; + + public: + Atom& operator=(const Atom&) = delete; + Atom(const Atom&) = delete; + + public: + T operator[](Size sz) + { + return (fArrayOfAtoms & sz); + } + void operator|(Size sz) + { + fArrayOfAtoms |= sz; + } + + friend Boolean operator==(Atom& atomic, const T& idx) + { + return atomic[idx] == idx; + } + + friend Boolean operator!=(Atom& atomic, const T& idx) + { + return atomic[idx] == idx; + } + + private: + T fArrayOfAtoms; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/Crc32.hpp b/Kernel/NewKit/Crc32.hpp new file mode 100644 index 00000000..e13aaad5 --- /dev/null +++ b/Kernel/NewKit/Crc32.hpp @@ -0,0 +1,22 @@ +/* + * ======================================================== + * + * NewOS Date Added: 13/02/2023 + * Copyright SoftwareLabs, all rights reserved. + * + * ======================================================== + */ + +#ifndef __CRC32_H__ +#define __CRC32_H__ + +#include + +#define kCrcCnt (256) + +namespace NewOS +{ + UInt ke_calculate_crc32(const Char* crc, UInt len) noexcept; +} // namespace NewOS + +#endif // !__CRC32_H__ diff --git a/Kernel/NewKit/CxxAbi.hpp b/Kernel/NewKit/CxxAbi.hpp new file mode 100644 index 00000000..92dcbdee --- /dev/null +++ b/Kernel/NewKit/CxxAbi.hpp @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ +#pragma once + +#include + +#ifdef __GNUC__ + +#define kDSOMaxObjects (128) + +struct atexit_func_entry_t +{ + void (*destructor_func)(void*); + void* obj_ptr; + void* dso_handle; +}; + +typedef unsigned uarch_t; + +namespace cxxabiv1 +{ + typedef void* __guard; +} + +#endif // __GNUC__ \ No newline at end of file diff --git a/Kernel/NewKit/Defines.hpp b/Kernel/NewKit/Defines.hpp new file mode 100644 index 00000000..f32e873a --- /dev/null +++ b/Kernel/NewKit/Defines.hpp @@ -0,0 +1,150 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include + +#define NEWKIT_VERSION "1.01" + +#if !defined(_INC_NO_STDC_HEADERS) && defined(__GNUC__) +#include +#endif + +#ifdef __has_feature +#if !__has_feature(cxx_nullptr) +#if !__has_nullptr +#error You must at least have nullptr featured on your C++ compiler. +#endif +#endif +#endif + +/// @brief NewOS namespace. +namespace NewOS +{ + using voidPtr = void*; + using VoidPtr = void*; + using nullPtr = decltype(nullptr); + using NullPtr = decltype(nullptr); + + using Int = int; + using Int32 = int; + using UShort = unsigned short; + using UInt16 = unsigned short; + using Short = short; + using Int16 = short; + using UInt = unsigned int; + using UInt32 = unsigned int; + using Long = __INT64_TYPE__; + using Int64 = __INT64_TYPE__; + using ULong = __UINT64_TYPE__; + using UInt64 = __UINT64_TYPE__; + using Boolean = bool; + using Bool = bool; + using Char = char; + using UChar = unsigned char; + using UInt8 = unsigned char; + + using SSize = Int64; + using SSizeT = Int64; + using Size = __SIZE_TYPE__; + using SizeT = __SIZE_TYPE__; + using IntPtr = __INTPTR_TYPE__; + using UIntPtr = __UINTPTR_TYPE__; + using IntFast = __INT_FAST32_TYPE__; + using IntFast64 = __INT_FAST64_TYPE__; + using PtrDiff = __PTRDIFF_TYPE__; + + typedef UIntPtr* Ptr64; + typedef UInt32* Ptr32; + + using Utf8Char = char8_t; + using Utf16Char = char16_t; + using WideChar = wchar_t; + using Utf32Char = char32_t; + + using Void = void; + + using Lba = UInt64; + + enum class Endian : UChar + { + kEndianLittle, + kEndianBig, + kEndianMixed, + kCount + }; + + /// @brief Forward object. + /// @tparam Args the object type. + /// @param arg the object. + /// @return object's rvalue + template + inline Args&& forward(Args& arg) + { + return static_cast(arg); + } + + /// @brief Move object. + /// @tparam Args the object type. + /// @param arg the object. + /// @return object's rvalue + template + inline Args&& move(Args&& arg) + { + return static_cast(arg); + } + + /// @brief Encoder class + /// Used to cast A to B or B to A. + class Encoder final + { + public: + explicit Encoder() = default; + ~Encoder() = default; + + Encoder& operator=(const Encoder&) = default; + Encoder(const Encoder&) = default; + + public: + /// @brief Convert type to bytes. + /// @tparam T the type. + /// @param type (a1) the data. + /// @return a1 as Char* + template + Char* AsBytes(T type) noexcept + { + return reinterpret_cast(type); + } + + /// @brief Convert T class to Y class. + /// @tparam T the class type of type. + /// @tparam Y the result class. + /// @param type the class to cast. + /// @return the class as Y. + template + Y As(T type) noexcept + { + return type.template As(); + } + }; +} // namespace NewOS + +#define DEDUCE_ENDIAN(address, value) \ + (((reinterpret_cast(address)[0]) == (value)) \ + ? (NewOS::Endian::kEndianBig) \ + : (NewOS::Endian::kEndianLittle)) + +#define Yes (true) +#define No (false) + +#define VoidStar NewOS::voidPtr + +#ifdef INIT +#undef INIT +#endif // ifdef INIT + +#define INIT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__) diff --git a/Kernel/NewKit/ErrorOr.hpp b/Kernel/NewKit/ErrorOr.hpp new file mode 100644 index 00000000..236a2d1c --- /dev/null +++ b/Kernel/NewKit/ErrorOr.hpp @@ -0,0 +1,72 @@ +/* +* ======================================================== +* +* NewOS +* Copyright SoftwareLabs, all rights reserved. +* +* ======================================================== +*/ + +#pragma once + +#include +#include + +namespace NewOS +{ + using ErrorT = UInt; + + template + class ErrorOr final + { + public: + ErrorOr() = default; + ~ErrorOr() = default; + + public: + explicit ErrorOr(Int32 err) + : mId(err) + { + } + + explicit ErrorOr(nullPtr Null) + { + } + + explicit ErrorOr(T Class) + : mRef(Class) + { + } + + ErrorOr& operator=(const ErrorOr&) = default; + ErrorOr(const ErrorOr&) = default; + + ErrorOr& operator=(const Ref& refErr) + { + mRef = refErr; + return *this; + } + + Ref Leak() + { + return mRef; + } + + Int32 Error() + { + return mId; + } + + operator bool() + { + return mRef; + } + + private: + Ref mRef; + Int32 mId{0}; + }; + + using ErrorOrAny = ErrorOr; + +} // namespace NewOS diff --git a/Kernel/NewKit/Function.hpp b/Kernel/NewKit/Function.hpp new file mode 100644 index 00000000..12ae03f3 --- /dev/null +++ b/Kernel/NewKit/Function.hpp @@ -0,0 +1,53 @@ +#ifndef _INC_FUNCTION_HPP__ +#define _INC_FUNCTION_HPP__ + +#include + +namespace NewOS +{ + template + class Function final + { + public: + Function() = default; + + public: + explicit Function(T (*Fn)(Args... args)) + : fFn(Fn) + { + } + + ~Function() = default; + + Function& operator=(const Function&) = default; + Function(const Function&) = default; + + template + T operator()(Args... args) + { + return fFn(args...); + } + + template + T Call(Args... args) + { + return fFn(args...); + } + + operator bool() + { + return fFn; + } + + bool operator!() + { + return !fFn; + } + + private: + T(*fFn) + (Args... args); + }; +} // namespace NewOS + +#endif // !_INC_FUNCTION_HPP__ diff --git a/Kernel/NewKit/Json.hpp b/Kernel/NewKit/Json.hpp new file mode 100644 index 00000000..ebdcc848 --- /dev/null +++ b/Kernel/NewKit/Json.hpp @@ -0,0 +1,118 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +// last-rev: 30/01/24 + +#include +#include +#include +#include +#include + +namespace NewOS +{ + /// @brief Json value class + class JsonType final + { + public: + explicit JsonType() + : NewOS::JsonType(1, 1) + { + } + + explicit JsonType(SizeT lhsLen, SizeT rhsLen) + : fKey(lhsLen), fValue(rhsLen) + { + } + + ~JsonType() = default; + + NEWOS_COPY_DEFAULT(JsonType); + + private: + StringView fKey; + StringView fValue; + + public: + /// @brief returns the key of the json + /// @return the key as string view. + StringView& AsKey() + { + return fKey; + } + + /// @brief returns the value of the json. + /// @return the key as string view. + StringView& AsValue() + { + return fValue; + } + + static JsonType kUndefined; + }; + + /// @brief Json stream helper class. + struct JsonStreamTrait final + { + JsonType In(const char* full_array) + { + SizeT len = rt_string_len(full_array); + + if (full_array[0] == '\"' && full_array[len - 1] == ',' || + full_array[len - 1] == '\"') + { + Boolean probe_key = true; + + SizeT key_len = 0; + SizeT value_len = 0; + + for (SizeT i = 1; i < len; i++) + { + if (full_array[i] == ' ') + continue; + + JsonType type(kPathLen, kPathLen); + + if (probe_key) + { + type.AsKey().Data()[key_len] = full_array[i]; + ++key_len; + + if (full_array[i] == '\"') + { + probe_key = false; + type.AsKey().Data()[key_len] = 0; + + ++i; + } + } + else + { + type.AsValue().Data()[value_len] = full_array[i]; + ++value_len; + + if (full_array[i] == '\"') + { + type.AsValue().Data()[value_len] = 0; + } + } + } + } + + return JsonType::kUndefined; + } + + JsonType Out(JsonType& out) + { + return out; + } + }; + + using JsonStream = Stream; +} // namespace NewOS diff --git a/Kernel/NewKit/KernelCheck.hpp b/Kernel/NewKit/KernelCheck.hpp new file mode 100644 index 00000000..e6a27834 --- /dev/null +++ b/Kernel/NewKit/KernelCheck.hpp @@ -0,0 +1,63 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include + +namespace NewOS +{ + void ke_runtime_check(bool bExpression, const char* file, const char* line); +} + +#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG) +#define __MUST_PASS(EXPR, FILE, LINE) \ + NewOS::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE)) +#define MUST_PASS(EXPR) __MUST_PASS(EXPR, __FILE__, __LINE__) +#define assert(EXPR) MUST_PASS(EXPR, RUNTIME_CHECK_EXPRESSION) + +enum RUNTIME_CHECK +{ + RUNTIME_CHECK_FAILED = -1, + RUNTIME_CHECK_POINTER = 0, + RUNTIME_CHECK_EXPRESSION, + RUNTIME_CHECK_FILE, + RUNTIME_CHECK_IPC, + RUNTIME_CHECK_TLS, + RUNTIME_CHECK_HANDSHAKE, + RUNTIME_CHECK_ACPI, + RUNTIME_CHECK_INVALID_PRIVILEGE, + RUNTIME_CHECK_PROCESS, + RUNTIME_CHECK_BAD_BEHAVIOR, + RUNTIME_CHECK_BOOTSTRAP, + RUNTIME_CHECK_UNEXCPECTED, + RUNTIME_CHECK_COUNT, +}; + +namespace NewOS +{ + class DumpManager final + { + public: + static void Dump(void) + { + // TODO: + } + }; + + void ke_stop(const Int& id); +} // namespace NewOS + +#ifdef TRY +#undef TRY +#endif + +#define TRY(FN) \ + if (!FN()) \ + { \ + MUST_PASS(false); \ + } diff --git a/Kernel/NewKit/Macros.hpp b/Kernel/NewKit/Macros.hpp new file mode 100644 index 00000000..7e9dc759 --- /dev/null +++ b/Kernel/NewKit/Macros.hpp @@ -0,0 +1,98 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#ifndef KIB +#define KIB(X) ((X) / 1024) +#endif + +#ifndef MIB +#define MIB(X) ((UInt64)KIB(X) / 1024) +#endif + +#ifndef GIB +#define GIB(X) ((UInt64)MIB(X) / 1024) +#endif + +#ifndef TIB +#define TIB(X) ((UInt64)GIB(X) / 1024) +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) \ + (((sizeof(a) / sizeof(*(a))) / \ + (static_cast(!(sizeof(a) % sizeof(*(a))))))) +#endif + +#ifndef ALIGN +#define ALIGN(X) __attribute__((aligned(X))) +#endif // #ifndef ALIGN + +#ifndef ATTRIBUTE +#define ATTRIBUTE(X) __attribute__((X)) +#endif // #ifndef ATTRIBUTE + +#ifndef __MAHROUSS__ +#define __MAHROUSS__ (202401) +#endif // !__MAHROUSS__ + +#ifndef EXTERN_C +#define EXTERN_C extern "C" +#endif + +#ifndef MAKE_ENUM +#define MAKE_ENUM(NAME) \ + enum NAME \ + { +#endif + +#ifndef END_ENUM +#define END_ENUM() \ + } \ + ; +#endif + +#ifndef MAKE_STRING_ENUM +#define MAKE_STRING_ENUM(NAME) \ + namespace NAME \ + { +#endif + +#ifndef ENUM_STRING +#define ENUM_STRING(NAME, VAL) inline constexpr const char* NAME = VAL +#endif + +#ifndef END_STRING_ENUM +#define END_STRING_ENUM() } +#endif + +#ifndef Alloca +#define Alloca(Sz) __builtin_alloca(Sz) +#endif // #ifndef Alloca + +#ifndef CANT_REACH +#define CANT_REACH() __builtin_unreachable() +#endif + +#define kBadPtr 0xFBFBFBFBFBFBFBFB +#define kMaxAddr 0xFFFFFFFFFFFFFFFF +#define kPathLen 255 + +#define PACKED ATTRIBUTE(packed) +#define NO_EXEC ATTRIBUTE(noexec) + +#define EXTERN extern +#define STATIC static + +#define CONST const + +#define STRINGIFY(X) #X +#define NEWOS_UNUSED(X) ((void)X) + +#ifndef RGB +#define RGB(R, G, B) (UInt32)(0x##R##G##B) +#endif // !RGB diff --git a/Kernel/NewKit/MutableArray.hpp b/Kernel/NewKit/MutableArray.hpp new file mode 100644 index 00000000..0dfed60c --- /dev/null +++ b/Kernel/NewKit/MutableArray.hpp @@ -0,0 +1,232 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ +#pragma once + +#include +#include +#include + +#define TRY_FIND_NODE(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) \ + { \ + if (NAME->fIndex == Index) \ + return NAME->fVal; \ + NAME = NAME->fNext; \ + } + +#define TRY_FIND_NODE2(NAME, NODE) \ + auto* NAME = NODE; \ + while (NAME) \ + { \ + if (NAME->fIndex == Index) \ + return Ref{NAME->fVal}; \ + NAME = NAME->fNext; \ + } + +#define TRY_REMOVE_NODE(NODE) \ + if (NODE && NODE->fIndex == Index) \ + { \ + NODE->fUsed = false; \ + NODE->fIndex = 0; \ + \ + return true; \ + } + +// FIXME: this is a shitty algorithm, which is consumer hungry. +// Remove and occurences of that, and remove that class. +namespace NewOS +{ + template + class MutableArray; + + template + class NullableMutableArray; + + template + class MutableLinkedList + { + public: + T fVal; + SizeT fIndex{0}; + Boolean fUsed{false}; + + MutableLinkedList* fPrev{nullptr}; + MutableLinkedList* fNext{nullptr}; + }; + + template + class NullableMutableArray + { + public: + // explicit this. + explicit NullableMutableArray() + : fFirstNode(new MutableLinkedList()) + { + } + + /* + * We free all the nodes allocated by the array + * and store the next one inside "NextIt" + */ + + virtual ~NullableMutableArray() + { + auto* It = fFirstNode; + MutableLinkedList* NextIt = nullptr; + + while (It) + { + NextIt = It->fNext; + delete It; + + It = NextIt; + } + } + + NullableMutableArray& operator=(const NullableMutableArray&) = default; + NullableMutableArray(const NullableMutableArray&) = default; + + operator bool() + { + return Count() > 1; + } + + public: + T operator[](const SizeT& Index) const + { + TRY_FIND_NODE(first, fFirstNode); + TRY_FIND_NODE(last, fLastNode); + + return _PlaceHolderValue; + } + + SizeT Count() const + { + return fNodeCount; + } + + public: + Boolean Remove(const SizeT& Index) + { + TRY_REMOVE_NODE(fFirstNode); + TRY_REMOVE_NODE(fLastNode); + + return false; + } + + Boolean Add(const T val) + { + auto* iterationNode = fFirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) + { + if (!iterationNode->fUsed) + { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList* fLastNode{nullptr}; + MutableLinkedList* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + NewOS::SizeT fNodeCount{0}; + + private: + // don't remove that + friend MutableArray; + }; + + template + class MutableArray : public NullableMutableArray + { + public: + // explicit this. + explicit MutableArray() = default; + virtual ~MutableArray() = default; + + NEWOS_COPY_DEFAULT(MutableArray) + + public: + Boolean Add(const T val) + { + auto* iterationNode = fFirstNode; + MUST_PASS(iterationNode); + + while (iterationNode) + { + if (!iterationNode->fUsed) + { + iterationNode->fVal = val; + iterationNode->fIndex = 0; + + iterationNode->fUsed = true; + + ++fNodeCount; + + return true; + } + + iterationNode = iterationNode->fNext; + } + + return false; + } + + public: + Ref operator[](const SizeT& Index) const + { + TRY_FIND_NODE2(first, fFirstNode); + TRY_FIND_NODE2(last, fLastNode); + + return {}; + } + + SizeT Count() const + { + return fNodeCount; + } + + bool Contains(T& value) noexcept + { + MutableLinkedList* first = fFirstNode; + + while (first) + { + if (first->fVal == value && first->fUsed) + return true; + + first = first->fNext; + } + + return false; + } + + private: + /* Avoid useless lookups */ + MutableLinkedList* fLastNode{nullptr}; + MutableLinkedList* fFirstNode{nullptr}; + + /* Number of nodes inside of this dynamic array. */ + NewOS::SizeT fNodeCount{0}; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/New.hpp b/Kernel/NewKit/New.hpp new file mode 100644 index 00000000..1e80f641 --- /dev/null +++ b/Kernel/NewKit/New.hpp @@ -0,0 +1,18 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ +#pragma once + +#include + +typedef __SIZE_TYPE__ size_t; // gcc will complain about that + +void* operator new(size_t ptr); +void* operator new[](size_t ptr); + +void operator delete(void* ptr); +void operator delete(void* ptr, unsigned long); +void operator delete[](void* ptr); diff --git a/Kernel/NewKit/NewKit.hpp b/Kernel/NewKit/NewKit.hpp new file mode 100644 index 00000000..273efde2 --- /dev/null +++ b/Kernel/NewKit/NewKit.hpp @@ -0,0 +1,22 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/Kernel/NewKit/OwnPtr.hpp b/Kernel/NewKit/OwnPtr.hpp new file mode 100644 index 00000000..ca89787a --- /dev/null +++ b/Kernel/NewKit/OwnPtr.hpp @@ -0,0 +1,94 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace NewOS +{ + template + class OwnPtr; + + template + class NonNullRefPtr; + + template + class OwnPtr final + { + public: + OwnPtr() + { + } + ~OwnPtr() + { + this->Delete(); + } + + OwnPtr& operator=(const OwnPtr&) = default; + OwnPtr(const OwnPtr&) = default; + + public: + template + bool New(Args&&... arg) + { + if (fCls) + { + return false; + } + + fCls = new T(arg...); + return fCls; + } + + void Delete() + { + if (fCls) + delete fCls; + + fCls = nullptr; + } + + T* operator->() const + { + return fCls; + }; + T* Raw() + { + return fCls; + } + + Ref AsRef() + { + return Ref(fCls); + } + + operator bool() + { + return fCls; + } + bool operator!() + { + return !fCls; + } + + private: + T* fCls; + }; + + template + OwnPtr make_ptr(Args... args) + { + OwnPtr ret; + ret.template New(forward(args)...); + MUST_PASS(ret); + + return ret; + } +} // namespace NewOS diff --git a/Kernel/NewKit/PageAllocator.hpp b/Kernel/NewKit/PageAllocator.hpp new file mode 100644 index 00000000..fa92f635 --- /dev/null +++ b/Kernel/NewKit/PageAllocator.hpp @@ -0,0 +1,21 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace NewOS +{ + namespace Detail + { + VoidPtr create_page_wrapper(Boolean rw, Boolean user, SizeT pageSz); + void exec_disable(UIntPtr addr); + bool page_disable(UIntPtr addr); + } // namespace Detail +} // namespace NewOS diff --git a/Kernel/NewKit/PageManager.hpp b/Kernel/NewKit/PageManager.hpp new file mode 100644 index 00000000..7706c9f4 --- /dev/null +++ b/Kernel/NewKit/PageManager.hpp @@ -0,0 +1,81 @@ +// a way to create and find our pages. +// I'm thinking about a separate way of getting a paged area. + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +#ifndef kBadAddress +#define kBadAddress (0) +#endif // #ifndef kBadAddress + +namespace NewOS +{ + class PageManager; + + class PTEWrapper final + { + public: + explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false, UIntPtr Address = 0); + + ~PTEWrapper(); + + PTEWrapper& operator=(const PTEWrapper&) = default; + PTEWrapper(const PTEWrapper&) = default; + + public: + const UIntPtr VirtualAddress(); + + void NoExecute(const bool enable = false); + const bool& NoExecute(); + + bool Reclaim(); + bool Shareable(); + bool Present(); + bool Access(); + + private: + Boolean fRw; + Boolean fUser; + Boolean fExecDisable; + UIntPtr fVirtAddr; + Boolean fCache; + Boolean fShareable; + Boolean fWt; + Boolean fPresent; + Boolean fAccessed; + + private: + friend class PageManager; + friend class Pmm; + }; + + struct PageManager final + { + public: + PageManager() = default; + ~PageManager() = default; + + PageManager& operator=(const PageManager&) = default; + PageManager(const PageManager&) = default; + + public: + PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz); + bool Free(Ref& wrapper); + + private: + void FlushTLB(UIntPtr VirtAddr); + + private: + friend PTEWrapper; + friend class Pmm; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/Pair.hpp b/Kernel/NewKit/Pair.hpp new file mode 100644 index 00000000..e5de607d --- /dev/null +++ b/Kernel/NewKit/Pair.hpp @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include + +namespace NewOS +{ + +} // namespace NewOS diff --git a/Kernel/NewKit/Pmm.hpp b/Kernel/NewKit/Pmm.hpp new file mode 100644 index 00000000..10fd148b --- /dev/null +++ b/Kernel/NewKit/Pmm.hpp @@ -0,0 +1,44 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace NewOS +{ + class Pmm; + class PTEWrapper; + + class Pmm final + { + public: + explicit Pmm(); + ~Pmm(); + + Pmm& operator=(const Pmm&) = delete; + Pmm(const Pmm&) = default; + + Ref RequestPage(Boolean user = false, Boolean readWrite = false); + Boolean FreePage(Ref refPage); + + Boolean ToggleRw(Ref refPage, Boolean enable = true); + Boolean TogglePresent(Ref refPage, Boolean enable = true); + Boolean ToggleUser(Ref refPage, Boolean enable = true); + Boolean ToggleShare(Ref refPage, Boolean enable = true); + + /// @brief Get the page manager of this. + Ref& Leak() + { + return fPageManager; + } + + private: + Ref fPageManager; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/Ref.hpp b/Kernel/NewKit/Ref.hpp new file mode 100644 index 00000000..356fcad0 --- /dev/null +++ b/Kernel/NewKit/Ref.hpp @@ -0,0 +1,89 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace NewOS +{ + template + class Ref final + { + public: + Ref() = default; + ~Ref() = default; + + public: + Ref(T cls, const bool& strong = false) + : fClass(cls), fStrong(strong) + { + } + + Ref& operator=(T ref) + { + fClass = ref; + return *this; + } + + public: + T operator->() const + { + return fClass; + } + + T& Leak() + { + return fClass; + } + + T operator*() + { + return fClass; + } + + bool IsStrong() const + { + return fStrong; + } + + operator bool() + { + return fStrong; + } + + private: + T fClass; + bool fStrong{false}; + }; + + template + class NonNullRef final + { + public: + NonNullRef() = delete; + NonNullRef(nullPtr) = delete; + + NonNullRef(T* ref) + : fRef(ref, true) + { + } + + Ref& operator->() + { + MUST_PASS(fRef); + return fRef; + } + + NonNullRef& operator=(const NonNullRef& ref) = delete; + NonNullRef(const NonNullRef& ref) = default; + + private: + Ref fRef{nullptr}; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/Stream.hpp b/Kernel/NewKit/Stream.hpp new file mode 100644 index 00000000..a1074a79 --- /dev/null +++ b/Kernel/NewKit/Stream.hpp @@ -0,0 +1,58 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace NewOS +{ + template + class Stream final + { + public: + explicit Stream(Ref ref) + : fStream(ref) + { + } + + ~Stream() = default; + + Stream& operator=(const Stream&) = default; + Stream(const Stream&) = default; + + template + friend Stream& operator>>(Stream& Ks, Ref& Buf) + { + Ks.fKind = Ks.fStream->In(Buf); + return *Ks; + } + + template + friend Stream& operator<<(Stream& Ks, Ref& Buf) + { + Ks.fKind = Buf; + Ks.fStream->Out(Buf.Leak()); + return *Ks; + } + + Ref& AsStreamTrait() + { + return fStream; + } + + Ref& AsType() + { + return fKind; + } + + private: + Ref fStream; + Ref fKind; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/String.hpp b/Kernel/NewKit/String.hpp new file mode 100644 index 00000000..6bf5edfd --- /dev/null +++ b/Kernel/NewKit/String.hpp @@ -0,0 +1,76 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include +#include + +namespace NewOS +{ + class StringView final + { + public: + explicit StringView() = default; + + explicit StringView(Size Sz) + : fSz(Sz) + { + MUST_PASS(Sz > 1); + fData = new Char[Sz]; + MUST_PASS(fData); + } + + ~StringView() + { + if (fData) + delete[] fData; + } + + StringView& operator=(const StringView&) = default; + StringView(const StringView&) = default; + + Char* Data(); + const Char* CData(); + Size Length() const; + + bool operator==(const Char* rhs) const; + bool operator!=(const Char* rhs) const; + + bool operator==(const StringView& rhs) const; + bool operator!=(const StringView& rhs) const; + + StringView& operator+=(const Char* rhs); + StringView& operator+=(const StringView& rhs); + + operator bool() + { + return fData; + } + + bool operator!() + { + return fData; + } + + private: + Char* fData{nullptr}; + Size fSz{0}; + Size fCur{0}; + + friend class StringBuilder; + }; + + struct StringBuilder final + { + static ErrorOr Construct(const Char* data); + static const char* FromInt(const char* fmt, int n); + static const char* FromBool(const char* fmt, bool n); + static const char* Format(const char* fmt, const char* from); + static bool Equals(const char* lhs, const char* rhs); + }; +} // namespace NewOS diff --git a/Kernel/NewKit/Utils.hpp b/Kernel/NewKit/Utils.hpp new file mode 100644 index 00000000..977f5ea7 --- /dev/null +++ b/Kernel/NewKit/Utils.hpp @@ -0,0 +1,29 @@ + +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include + +namespace NewOS +{ + Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len); + Int rt_move_memory(const voidPtr src, voidPtr dst, Size len); + voidPtr rt_set_memory(voidPtr dst, Char val, Size len); + void rt_zero_memory(voidPtr pointer, Size len); + Int rt_string_cmp(const Char* src, const Char* cmp, Size len); + const Char* alloc_string(const Char* text); + Size rt_string_len(const Char* str); + Size rt_string_len(const Char* str, SizeT _len); + Boolean rt_to_string(Char* buf, Int limit, Int base); + Boolean is_newln(Char chr); + Boolean is_space(Char chr); + Int rt_to_uppercase(Int c); + Int rt_to_lower(Int c); + voidPtr rt_string_in_string(const char* in, const char* needle); + char* rt_string_has_char(char* str, const char chr); +} // namespace NewOS diff --git a/Kernel/NewKit/Variant.hpp b/Kernel/NewKit/Variant.hpp new file mode 100644 index 00000000..a8f6759f --- /dev/null +++ b/Kernel/NewKit/Variant.hpp @@ -0,0 +1,54 @@ +/* ------------------------------------------- + + Copyright SoftwareLabs + +------------------------------------------- */ + +#pragma once + +#include +#include + +namespace NewOS +{ + class Variant final + { + public: + enum class VariantKind + { + kString, + kPointer, + kUndefined + }; + + public: + explicit Variant() = delete; + + public: + Variant& operator=(const Variant&) = default; + Variant(const Variant&) = default; + + ~Variant() = default; + + public: + explicit Variant(StringView* stringView) + : fPtr((voidPtr)stringView), fKind(VariantKind::kString) + { + } + explicit Variant(nullPtr) + : fPtr(nullptr), fKind(VariantKind::kUndefined) + { + } + explicit Variant(voidPtr ptr) + : fPtr(ptr), fKind(VariantKind::kPointer) + { + } + + public: + const Char* ToString(); + + private: + voidPtr fPtr{nullptr}; + VariantKind fKind{VariantKind::kUndefined}; + }; +} // namespace NewOS diff --git a/Kernel/NewKit/compile_flags.txt b/Kernel/NewKit/compile_flags.txt new file mode 100644 index 00000000..14c5bc51 --- /dev/null +++ b/Kernel/NewKit/compile_flags.txt @@ -0,0 +1,6 @@ +-nostdlib +-ffreestanding +-std=c++20 +-I./ +-I../ +-I../../../ -- cgit v1.2.3