diff options
Diffstat (limited to 'Source')
53 files changed, 3193 insertions, 0 deletions
diff --git a/Source/Array.cxx b/Source/Array.cxx new file mode 100644 index 00000000..fade2249 --- /dev/null +++ b/Source/Array.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Array.hpp> diff --git a/Source/ArrayList.cxx b/Source/ArrayList.cxx new file mode 100644 index 00000000..72e17068 --- /dev/null +++ b/Source/ArrayList.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/ArrayList.hpp> diff --git a/Source/Atom.cxx b/Source/Atom.cxx new file mode 100644 index 00000000..dd83d7ce --- /dev/null +++ b/Source/Atom.cxx @@ -0,0 +1,13 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Atom.hpp> + +// @file Atom.cpp +// @brief Atomic primitives diff --git a/Source/CodeManager.cxx b/Source/CodeManager.cxx new file mode 100644 index 00000000..47c7bd1b --- /dev/null +++ b/Source/CodeManager.cxx @@ -0,0 +1,144 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/FileManager.hpp> +#include <KernelKit/CodeManager.hpp> +#include <KernelKit/DebugOutput.hpp> +#include <KernelKit/ProcessManager.hpp> +#include <NewKit/KHeap.hpp> +#include <NewKit/String.hpp> +#include <NewKit/OwnPtr.hpp> +#include <NewKit/ErrorID.hpp> + +namespace hCore +{ + namespace Detail + { + UInt32 rt_get_pef_platform(void) + { +#ifdef __powerpc + return kPefArchPower; +#elif defined(__arc__) + return kPefArchARC; +#elif defined(__x86_64__) + return kPefArchAMD64; +#else + return kPefArchInvalid; +#endif // __POWER || __x86_64__ + } + } + + PEFLoader::PEFLoader(const char* path) + : fCachedBlob(nullptr), fBad(false) + { + OwnPtr<FileStream<char>> file; + + file.New(const_cast<Char*>(path)); + + if (StringBuilder::Equals(file->MIME(), this->MIME())) + { + fPath = StringBuilder::Construct(path).Leak(); + + fCachedBlob = file->ReadAll(); + + PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); + + auto fFree = [&]() -> void { + kcout << "CodeManager: Warning: Bad executable, program will not be started!\n"; + fBad = true; + + kernel_delete_ptr(fCachedBlob); + + fCachedBlob = nullptr; + }; + + if (container->Cpu == Detail::rt_get_pef_platform() && + container->Magic[0] == kPefMagic[0] && + container->Magic[1] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && + container->Abi == kPefAbi) + { + if (container->Kind != kPefKindObject && + container->Kind != kPefKindDebug) + { + kcout << "CodeManager: Info: Good executable. can proceed.\n"; + return; + } + } + + fFree(); + } + } + + PEFLoader::~PEFLoader() + { + if (fCachedBlob) + kernel_delete_ptr(fCachedBlob); + } + + VoidPtr PEFLoader::FindSymbol(const char* name, Int32 kind) + { + if (!fCachedBlob || + fBad) + return nullptr; + + PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob); + + PEFCommandHeader* container_header = reinterpret_cast<PEFCommandHeader*>((UIntPtr)fCachedBlob + sizeof(PEFContainer)); + + for (SizeT index = 0; index < container->Count; ++index) + { + kcout << "Iterating over container at index: " << StringBuilder::FromInt("%", index) << ", name: " << container_header->Name << "\n"; + + if (StringBuilder::Equals(container_header->Name, name)) + { + kcout << "Found potential container, checking for validity.\n"; + + if (container_header->Kind == kind) + return static_cast<UIntPtr*>(fCachedBlob) + container_header->Offset; + + continue; + } + } + + return nullptr; + } + + ErrorOr<VoidPtr> PEFLoader::LoadStart() + { + if (auto sym = this->FindSymbol("__start", kPefCode); sym) + return ErrorOr<VoidPtr>(sym); + + return ErrorOr<VoidPtr>(ME_EXEC_ERROR); + } + + bool PEFLoader::IsLoaded() noexcept { return !fBad && fCachedBlob; } + + namespace Utils + { + bool execute_from_image(PEFLoader& exec) + { + auto errOrStart = exec.LoadStart(); + + if (errOrStart.Error() != 0) + return false; + + Process proc(errOrStart.Leak().Leak()); + Ref<Process> refProc = proc; + + return ProcessManager::Shared().Leak().Add(refProc); + } + } + + const char* PEFLoader::Path() { return fPath.Leak().CData(); } + + const char* PEFLoader::Format() { return "PEF"; } + + const char* PEFLoader::MIME() { return "application/x-exec"; } +} // namespace hCore diff --git a/Source/Crc32.cxx b/Source/Crc32.cxx new file mode 100644 index 00000000..db291d19 --- /dev/null +++ b/Source/Crc32.cxx @@ -0,0 +1,67 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/CRC32.hpp> + +// @file CRC32.cpp +// @brief Checksum implementation. + +namespace hCore +{ + UInt kCrcTbl[kCrcCnt] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, + 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, + 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, + 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, + 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, + 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, + 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, + 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, + 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, + 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + + static Int crc_byte(Int crc, UChar byte) + { + crc = (crc >> 8) ^ kCrcTbl[(byte) ^ (crc & 0x000000FF)]; // shift 8 bytes to the right + + // XOR polynomial XOR the crc + // without the 2 highest bytes + return crc; + } + + Int crc32(const Char *byte, Int len) + { + Int checksum = 0; + + for (UChar index = 1; index < len; ++index) + checksum = crc_byte(checksum, byte[index]); + + return checksum; + } +} // namespace hCore diff --git a/Source/CxxAbi.cxx b/Source/CxxAbi.cxx new file mode 100644 index 00000000..c9d2b98f --- /dev/null +++ b/Source/CxxAbi.cxx @@ -0,0 +1,92 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/DebugOutput.hpp> +#include <NewKit/CxxAbi.hpp> +#include <NewKit/Panic.hpp> + +#ifdef __GNUC__ + +void *__dso_handle; + +atexit_func_entry_t __atexit_funcs[DSO_MAX_OBJECTS]; +uarch_t __atexit_func_count; + +extern "C" void __cxa_pure_virtual() +{ + hCore::kcout << "[__cxa_pure_virtual] Placeholder\n"; +} + +extern "C" void __stack_chk_fail() +{ + hCore::kcout << "[__stack_chk_fail] Buffer overflow detected\n"; + hCore::panic(RUNTIME_CHECK_POINTER); +} + +extern "C" int __cxa_atexit(void (*f)(void *), void *arg, void *dso) { + if (__atexit_func_count >= DSO_MAX_OBJECTS) + 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 + +#else + +namespace cxxkit +{ + extern "C" void __unwind(void(**finis)(void), int cnt) + { + for (int i = 0; i < cnt; ++i) + (finis[i])(); + } +} + +#endif diff --git a/Source/CxxKitRT.cxx b/Source/CxxKitRT.cxx new file mode 100644 index 00000000..c2c1384b --- /dev/null +++ b/Source/CxxKitRT.cxx @@ -0,0 +1,48 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <HintKit/CompilerHint.hxx> +#include <KernelKit/OSErr.hpp> +#include <NewKit/Utils.hpp> + +using namespace hCore; + +// unimplemented _HintTell +void _HintTell(_HintMessage* ppMsg, _HintId* pId) +{ + switch (*pId) + { + case kErrorExecutable: + { + const char* msg = "CodeManager doesn't recognize this executable."; + rt_copy_memory((const voidPtr)msg, *ppMsg, string_length(msg)); + break; + } + case kErrorExecutableLib: + { + const char* msg = "CodeManager doesn't recognize this library."; + rt_copy_memory((const voidPtr)msg, *ppMsg, string_length(msg)); + break; + } + case kErrorFileNotFound: + { + const char* msg = "FileManager doesn't find this file."; + rt_copy_memory((const voidPtr)msg, *ppMsg, string_length(msg)); + break; + } + case kErrorNoNetwork: + { + const char* msg = "NetworkManager doesn't detect any WiFi/Ethernet connection."; + rt_copy_memory((const voidPtr)msg, *ppMsg, string_length(msg)); + break; + } + default: + break; + } +}
\ No newline at end of file diff --git a/Source/Defines.cxx b/Source/Defines.cxx new file mode 100644 index 00000000..f54e68ae --- /dev/null +++ b/Source/Defines.cxx @@ -0,0 +1,11 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Defines.hpp> + diff --git a/Source/Device.cxx b/Source/Device.cxx new file mode 100644 index 00000000..fbd1e19d --- /dev/null +++ b/Source/Device.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/Device.hpp> diff --git a/Source/DriveManager.cxx b/Source/DriveManager.cxx new file mode 100644 index 00000000..4c924b75 --- /dev/null +++ b/Source/DriveManager.cxx @@ -0,0 +1,61 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <FSKit/NewFS.hxx> +#include <NewKit/Utils.hpp> + +#include <KernelKit/DebugOutput.hpp> +#include <KernelKit/DriveManager.hpp> + +namespace hCore +{ + DriveSelector::DriveSelector() : fDrive(nullptr) {} + + DriveSelector::~DriveSelector() + { + if (fDrive) + { + this->Unmount(); + } + } + + DriveTraits& DriveSelector::GetMounted() { MUST_PASS(fDrive != nullptr); return *fDrive; } + + bool DriveSelector::Mount(DriveTraits* drive) + { + if (drive && + drive->fReady() && + fDrive == nullptr) + { + fDrive = drive; + fDrive->fMount(); + + kcout << "[Mount] Mount drive: " << fDrive->fName << "\n"; + + return true; + } + + return false; + } + + DriveTraits* DriveSelector::Unmount() + { + if (!fDrive) + return nullptr; + + auto drivePointer = fDrive; + + fDrive->fUnmount(); + fDrive = nullptr; + + kcout << "[Unmount] Mount drive: " << drivePointer->fName << "\n"; + + return drivePointer; + } +} // namespace hCore diff --git a/Source/ErrorOr.cxx b/Source/ErrorOr.cxx new file mode 100644 index 00000000..55711123 --- /dev/null +++ b/Source/ErrorOr.cxx @@ -0,0 +1,12 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/ErrorOr.hpp> + +/* BUILDME needs that file */
\ No newline at end of file diff --git a/Source/FileManager.cxx b/Source/FileManager.cxx new file mode 100644 index 00000000..c7e51811 --- /dev/null +++ b/Source/FileManager.cxx @@ -0,0 +1,48 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/FileManager.hpp> +#include <NewKit/ErrorID.hpp> +#include <NewKit/Utils.hpp> + +//! @brief File manager for hCore. + +namespace hCore +{ + static IFilesystemManager* kMounted = nullptr; + + /// @brief FilesystemManager getter. + /// @return The mounted filesystem. + IFilesystemManager* IFilesystemManager::GetMounted() { return kMounted; } + + IFilesystemManager* IFilesystemManager::Unmount() + { + if (kMounted) + { + auto mount = kMounted; + kMounted = nullptr; + + return mount; + } + + return nullptr; + } + + bool IFilesystemManager::Mount(IFilesystemManager* pMount) + { + if (pMount) + { + kMounted = pMount; + + return true; + } + + return false; + } +} diff --git a/Source/FilesystemIndexer.cxx b/Source/FilesystemIndexer.cxx new file mode 100644 index 00000000..84c52890 --- /dev/null +++ b/Source/FilesystemIndexer.cxx @@ -0,0 +1,28 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +//! @brief hCore NewFS Indexer. + +#include <FSKit/FilesystemIndexer.hxx> +#include <CompilerKit/Compiler.hpp> +#include <NewKit/MutableArray.hpp> +#include <NewKit/Utils.hpp> + +#define kMaxLenIndexer 256 + +namespace hCore +{ + namespace Indexer + { + IndexProperty& IndexableProperty::LeakProperty() noexcept { return fIndex; } + + void IndexableProperty::AddFlag(Int16 flag) { fFlags |= flag; } + void IndexableProperty::RemoveFlag(Int16 flag) { fFlags &= flag; } + } +} diff --git a/Source/Framebuffer.cxx b/Source/Framebuffer.cxx new file mode 100644 index 00000000..045e405a --- /dev/null +++ b/Source/Framebuffer.cxx @@ -0,0 +1,39 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/Framebuffer.hpp> + +namespace hCore +{ + Framebuffer::Framebuffer(hCore::Ref<FramebufferContext*> &addr) + : m_FrameBufferAddr(addr), m_Colour(FramebufferColorKind::RGB32) + {} + + Framebuffer::~Framebuffer() = default; + + volatile UIntPtr* Framebuffer::operator[](const UIntPtr& width_and_height) + { + if (m_FrameBufferAddr) + return reinterpret_cast<volatile hCore::UIntPtr*>(m_FrameBufferAddr->m_Base + width_and_height); + + return nullptr; + } + + Ref<FramebufferContext*>& Framebuffer::Leak() { return m_FrameBufferAddr; } + + Framebuffer::operator bool() { return m_FrameBufferAddr; } + + const FramebufferColorKind& Framebuffer::Color(const FramebufferColorKind& colour) + { + if (colour != FramebufferColorKind::INVALID) + m_Colour = colour; + + return m_Colour; + } +} // namespace hCore diff --git a/Source/GUIDWizard.cxx b/Source/GUIDWizard.cxx new file mode 100644 index 00000000..100b88d4 --- /dev/null +++ b/Source/GUIDWizard.cxx @@ -0,0 +1,66 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <CFKit/GUIDWizard.hpp> +#include <NewKit/Ref.hpp> + +// begin of ascii 'seeable' characters. (A, C, C, 1, 2) +#define kAsciiBegin 47 + +// @brief Size of UUID. +#define kUUIDSize 32 + +namespace hCore::XRN::Version1 +{ + auto make_sequence(const ArrayList<UShort>& uuidSeq) -> Ref<GUIDSequence*> + { + GUIDSequence *seq = new GUIDSequence(); + + if (!seq) + return {}; + + Ref<GUIDSequence*> sequenceReference{seq, true}; + + sequenceReference->m_Ms1 |= uuidSeq[0]; + sequenceReference->m_Ms2 |= uuidSeq[1]; + sequenceReference->m_Ms3 |= uuidSeq[2]; + sequenceReference->m_Ms3 |= uuidSeq[3]; + + return sequenceReference; + } + + // @brief Tries to make a guid out of a string. + // This function is not complete for now + auto try_guid_to_string(Ref<GUIDSequence*>& seq) -> ErrorOr <Ref<StringView>> + { + Char buf[kUUIDSize]; + + for (SizeT index = 0; index < 16; ++index) + { + buf[index] = seq->u8[index] + kAsciiBegin; + } + + for (SizeT index = 16; index < 24; ++index) + { + buf[index] = seq->u16[index] + kAsciiBegin; + } + + for (SizeT index = 24; index < 28; ++index) + { + buf[index] = seq->u32[index] + kAsciiBegin; + } + + auto view = StringBuilder::Construct(buf); + + if (view) + return ErrorOr<Ref<StringView>>{ view.Leak() }; + + return ErrorOr<Ref<StringView>>{-1}; + } +} // namespace hCore::XRN::Version1 diff --git a/Source/GUIDWrapper.cxx b/Source/GUIDWrapper.cxx new file mode 100644 index 00000000..d78779e0 --- /dev/null +++ b/Source/GUIDWrapper.cxx @@ -0,0 +1,15 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <CFKit/GUIDWrapper.hpp> + +namespace hCore::XRN +{ + +} diff --git a/Source/Heap.cxx b/Source/Heap.cxx new file mode 100644 index 00000000..a4bc72a8 --- /dev/null +++ b/Source/Heap.cxx @@ -0,0 +1,206 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Heap.hpp> +#include <NewKit/PageManager.hpp> +#include <NewKit/Panic.hpp> + +/// bugs: 0 + +namespace hCore +{ + class HeapManager final + { + public: + static Size& GetCount() { return s_NumPools; } + static Ref<Pmm>& GetPmm() { return s_Pmm; } + static Boolean& IsEnabled() { return s_PoolsAreEnabled; } + static Array<Ref<PTEWrapper*>, kPoolMaxSz>& The() { return s_Pool; } + + private: + static Size s_NumPools; + static Ref<Pmm> s_Pmm; + + private: + static Boolean s_PoolsAreEnabled; + static Array<Ref<PTEWrapper*>, kPoolMaxSz> s_Pool; + + }; + + //! declare fields + + SizeT HeapManager::s_NumPools = 0UL; + Ref<Pmm> HeapManager::s_Pmm; + Boolean HeapManager::s_PoolsAreEnabled = true; + Array<Ref<PTEWrapper*>, kPoolMaxSz> HeapManager::s_Pool; + + static voidPtr rt_find_unused_heap(Int flags); + static void rt_free_heap_internal(voidPtr vaddr); + static voidPtr rt_make_heap(voidPtr vaddr, Int flags); + static bool rt_check_and_free_heap(const SizeT &index, voidPtr ptr); + + static voidPtr rt_find_unused_heap(Int flags) + { + for (SizeT index = 0; index < kPoolMaxSz; ++index) + { + if (HeapManager::The()[index] && + !HeapManager::The()[index].Leak().Leak().Leak()->Present()) + { + HeapManager::GetPmm().Leak().TogglePresent(HeapManager::The()[index].Leak().Leak(), true); + kcout << "[rt_find_unused_heap] Done, trying now to make a pool\r\n"; + + return rt_make_heap((voidPtr)HeapManager::The()[index].Leak().Leak().Leak()->VirtualAddress(), flags); + } + } + + return nullptr; + } + + static voidPtr rt_make_heap(voidPtr virtualAddress, Int flags) + { + if (virtualAddress) + { + HeapHeader* pool_hdr = reinterpret_cast<HeapHeader*>(virtualAddress); + + if (!pool_hdr->Free) + { + kcout << "[rt_make_heap] pool_hdr->Free, Pool already exists\n"; + return nullptr; + } + + pool_hdr->Flags = flags; + pool_hdr->Magic = kPoolMag; + pool_hdr->Free = false; + + kcout << "[rt_make_heap] New allocation has been done.\n"; + return reinterpret_cast<voidPtr>((reinterpret_cast<UIntPtr>(virtualAddress) + sizeof(HeapHeader))); + } + + kcout << "[rt_make_heap] Address is invalid"; + return nullptr; + } + + static void rt_free_heap_internal(voidPtr virtualAddress) + { + HeapHeader* pool_hdr = reinterpret_cast<HeapHeader*>(reinterpret_cast<UIntPtr>(virtualAddress) - sizeof(HeapHeader)); + + if (pool_hdr->Magic == kPoolMag) + { + pool_hdr->Free = false; + pool_hdr->Flags = 0; + + kcout << "[rt_free_heap_internal] Successfully marked header as free!\r\n"; + } + } + + static bool rt_check_and_free_heap(const SizeT& index, voidPtr ptr) + { + if (HeapManager::The()[index]) + { + // ErrorOr<>::operator bool + if (!HeapManager::The()[index].Leak().Leak().IsStrong()) + { + // we want them to be weak + // because we allocated it. + if (HeapManager::The()[index].Leak().Leak().Leak()->VirtualAddress() == (UIntPtr) ptr) + { + HeapManager::GetPmm().Leak().FreePage(HeapManager::The()[index].Leak().Leak()); + --HeapManager::GetCount(); + + rt_free_heap_internal(ptr); + ptr = nullptr; + + return true; + } + } + } + + return false; + } + + /// @brief Creates a new pool pointer. + /// @param flags the flags attached to it. + /// @return a pool pointer with selected permissions. + voidPtr pool_new_ptr(Int32 flags) + { + if (!HeapManager::IsEnabled()) + return nullptr; + + if (HeapManager::GetCount() > kPoolMaxSz) + return nullptr; + + if (voidPtr ret = rt_find_unused_heap(flags)) + return ret; + + // this wasn't set to true + auto ref_page = HeapManager::GetPmm().Leak().RequestPage(((flags & kPoolUser)), + (flags & kPoolRw)); + if (ref_page) + { + ///! reserve page. + HeapManager::The()[HeapManager::GetCount()].Leak() = ref_page; + auto& ref = HeapManager::GetCount(); + ++ref; // increment the number of addresses we have now. + + kcout << "[pool_new_ptr] New Address found!\r\n"; + + // finally make the pool address. + return rt_make_heap(reinterpret_cast<voidPtr>(ref_page.Leak()->VirtualAddress()), flags); + } + + return nullptr; + } + + /// @brief free a pool pointer. + /// @param ptr The pool pointer to free. + /// @return + Int32 pool_free_ptr(voidPtr ptr) + { + if (!HeapManager::IsEnabled()) + return -1; + + if (ptr) + { + SizeT base = HeapManager::GetCount(); + + if (rt_check_and_free_heap(base, ptr)) + return 0; + + for (SizeT index = 0; index < kPoolMaxSz; ++index) + { + if (rt_check_and_free_heap(index, ptr)) + return 0; + + --base; + } + } + + return -1; + } + + /// @brief Checks if pointer is valid. + /// @param thePool the pool pointer. + /// @param thePtr the pointer. + /// @param theLimit the last address of the pool. + /// @return if it is valid. + Boolean pool_ptr_exists(UIntPtr thePool, UIntPtr thePtr, SizeT theLimit) + { + if (HeapManager::GetCount() < 1) + return false; + + if (thePool == 0 || + thePtr == 0 || + theLimit == 0) + { + return false; + } + + return thePool < thePtr < (theLimit); + } +} // namespace hCore diff --git a/Source/Json.cxx b/Source/Json.cxx new file mode 100644 index 00000000..dd106a4e --- /dev/null +++ b/Source/Json.cxx @@ -0,0 +1,5 @@ +#include <NewKit/Json.hpp> + +using namespace hCore; + +JsonType JsonType::kUndefined(1, 1);
\ No newline at end of file diff --git a/Source/KHeap.cxx b/Source/KHeap.cxx new file mode 100644 index 00000000..e626afb8 --- /dev/null +++ b/Source/KHeap.cxx @@ -0,0 +1,129 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/KHeap.hpp> + +//! @file KHeap.cpp +//! @brief this allocator is used by kernel to allocate pages. + +#define kMaxWrappers (4096 * 8) + +namespace hCore +{ + static Ref<PTEWrapper*> kWrapperList[kMaxWrappers]; + static SizeT kWrapperCount = 0UL; + static Ref<PTEWrapper*> kLastWrapper; + static Pmm kPmm; + + namespace Detail + { + static voidPtr try_find_ptr(const SizeT &sz, const bool rw, const bool user) + { + for (SizeT indexWrapper = 0; indexWrapper < kMaxWrappers; ++indexWrapper) + { + if (!kWrapperList[indexWrapper]->Present()) + { + kWrapperList[indexWrapper]->Reclaim(); /* very straight-forward as you can see. */ + return reinterpret_cast<voidPtr>(kWrapperList[indexWrapper]->VirtualAddress()); + } + } + + return nullptr; + } + } // namespace Detail + + /// @brief manual allocation + /// @param sz size of pointer + /// @param rw read write (true to enable it) + /// @param user is it accesible by user processes? + /// @return the pointer + VoidPtr kernel_new_ptr(const SizeT& sz, const bool rw, const bool user) + { + if (kWrapperCount < sz) + return nullptr; + + if (auto ptr = Detail::try_find_ptr(sz, rw, user); + ptr) + return ptr; + + Ref<PTEWrapper*> wrapper = kPmm.RequestPage(user, rw); + + if (wrapper) + { + kLastWrapper = wrapper; + + kWrapperList[kWrapperCount] = wrapper; + ++kWrapperCount; + + return reinterpret_cast<voidPtr>(wrapper->VirtualAddress()); + } + + return nullptr; + } + + /// @brief Declare pointer as free. + /// @param ptr the pointer. + /// @return + Int32 kernel_delete_ptr(voidPtr ptr) + { + if (ptr) + { + const UIntPtr virtualAddress = reinterpret_cast<UIntPtr>(ptr); + + if (kLastWrapper && + virtualAddress == kLastWrapper->VirtualAddress()) + { + return kPmm.FreePage(kLastWrapper); + } + + Ref<PTEWrapper*> wrapper; + + for (SizeT indexWrapper = 0; indexWrapper < kWrapperCount; ++indexWrapper) + { + if (kWrapperList[indexWrapper]->VirtualAddress() == virtualAddress) + { + wrapper = kWrapperList[indexWrapper]; + return kPmm.FreePage(wrapper); + } + } + } + + return -1; + } + + /// @brief find pointer in kernel heap + /// @param ptr the pointer + /// @return if it exists. + Boolean kernel_valid_ptr(voidPtr ptr) + { + if (ptr) + { + const UIntPtr virtualAddress = reinterpret_cast<UIntPtr>(ptr); + + if (kLastWrapper && + virtualAddress == kLastWrapper->VirtualAddress()) + { + return true; + } + + Ref<PTEWrapper*> wrapper; + + for (SizeT indexWrapper = 0; indexWrapper < kWrapperCount; ++indexWrapper) + { + if (kWrapperList[indexWrapper]->VirtualAddress() == virtualAddress) + { + wrapper = kWrapperList[indexWrapper]; + return true; + } + } + } + + return false; + } +} // namespace hCore diff --git a/Source/KMain.cxx b/Source/KMain.cxx new file mode 100644 index 00000000..cc847349 --- /dev/null +++ b/Source/KMain.cxx @@ -0,0 +1,26 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/FileManager.hpp> +#include <KernelKit/CodeManager.hpp> +#include <ArchKit/Arch.hpp> + +extern "C" void __KernelMain(hCore::VoidPtr this_image) +{ + hCore::Detail::serial_init(); + MUST_PASS(hCore::initialize_hardware_components()); + + hCore::IFilesystemManager::Mount(new hCore::NewFilesystemManager()); + hCore::PEFLoader img("/System/Seeker"); + + if (!hCore::Utils::execute_from_image(img)) + { + hCore::panic(RUNTIME_CHECK_BOOTSTRAP); + } +} diff --git a/Source/LockDelegate.cxx b/Source/LockDelegate.cxx new file mode 100644 index 00000000..786de18e --- /dev/null +++ b/Source/LockDelegate.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/LockDelegate.hpp>
\ No newline at end of file diff --git a/Source/MeBus/Database.cpp b/Source/MeBus/Database.cpp new file mode 100644 index 00000000..454c001e --- /dev/null +++ b/Source/MeBus/Database.cpp @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +//! Add this unit to compilation. diff --git a/Source/MutableArray.cxx b/Source/MutableArray.cxx new file mode 100644 index 00000000..be98f02e --- /dev/null +++ b/Source/MutableArray.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/MutableArray.hpp> diff --git a/Source/Network/IP.cpp b/Source/Network/IP.cpp new file mode 100644 index 00000000..482b5b7b --- /dev/null +++ b/Source/Network/IP.cpp @@ -0,0 +1,122 @@ +/* + * ======================================================== + * + * NewKit + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NetworkKit/IP.hpp> +#include <NewKit/Utils.hpp> + +namespace hCore +{ + RawIPAddress::RawIPAddress(char bytes[4]) + { + rt_copy_memory(bytes, m_Addr, 4); + } + + bool RawIPAddress::operator==(const RawIPAddress& ipv4) + { + for (Size index = 0; index < 4; ++index) + { + if (ipv4.m_Addr[index] != m_Addr[index]) + return false; + } + + return true; + } + + bool RawIPAddress::operator!=(const RawIPAddress& ipv4) + { + for (Size index = 0; index < 4; ++index) + { + if (ipv4.m_Addr[index] == m_Addr[index]) + return false; + } + + return true; + } + + char& RawIPAddress::operator[](const Size& index) + { + kcout << "[RawIPAddress::operator[]] Fetching Index...\r\n"; + + if (index > 4) + panic(RUNTIME_CHECK_EXPRESSION); + + return m_Addr[index]; + } + + RawIPAddress6::RawIPAddress6(char bytes[8]) + { + rt_copy_memory(bytes, m_Addr, 8); + } + + char &RawIPAddress6::operator[](const Size &index) + { + kcout << "[RawIPAddress6::operator[]] Fetching Index...\r\n"; + + if (index > 8) + panic(RUNTIME_CHECK_EXPRESSION); + + return m_Addr[index]; + } + + bool RawIPAddress6::operator==(const RawIPAddress6& ipv6) + { + for (SizeT index = 0; index < 8; ++index) + { + if (ipv6.m_Addr[index] != m_Addr[index]) + return false; + } + + return true; + } + + bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6) + { + for (SizeT index = 0; index < 8; ++index) + { + if (ipv6.m_Addr[index] == m_Addr[index]) + return false; + } + + return true; + } + + ErrorOr<StringView> IPHelper::ToStringView(Ref<RawIPAddress6> ipv6) + { + auto str = StringBuilder::Construct(ipv6.Leak().Address()); + return str; + } + + ErrorOr<StringView> IPHelper::ToStringView(Ref<RawIPAddress> ipv4) + { + auto str = StringBuilder::Construct(ipv4.Leak().Address()); + return str; + } + + bool IPHelper::IpCheckV4(const char *ip) + { + int cnter = 0; + + for (Size base = 0; base < string_length(ip); ++base) + { + if (ip[base] == '.') + { + cnter = 0; + } + else + { + if (cnter == 3) + return false; + + ++cnter; + } + } + + return true; + } +} // namespace NewKit diff --git a/Source/Network/NetworkDevice.cpp b/Source/Network/NetworkDevice.cpp new file mode 100644 index 00000000..8e9fc159 --- /dev/null +++ b/Source/Network/NetworkDevice.cpp @@ -0,0 +1,34 @@ +/* + * ======================================================== + * + * NewKit + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NetworkKit/NetworkDevice.hpp> + +// network devices implementation. +// PPPNetworkService, TCPNetworkDevice, UDPNetworkService + +namespace hCore +{ + NetworkDevice::NetworkDevice(void (*out)(NetworkDeviceCommand), void (*in)(NetworkDeviceCommand), void(*on_cleanup)(void)) + : IDevice<NetworkDeviceCommand>(out, in), fCleanup(on_cleanup) + { +#ifdef __DEBUG__ + kcout << "NetworkDevice init.\r\n"; +#endif + } + + NetworkDevice::~NetworkDevice() + { +#ifdef __DEBUG__ + kcout << "NetworkDevice cleanup.\r\n"; +#endif + + if (fCleanup) + fCleanup(); + } +} // namespace NewKit diff --git a/Source/New+Delete.cxx b/Source/New+Delete.cxx new file mode 100644 index 00000000..6f5e039e --- /dev/null +++ b/Source/New+Delete.cxx @@ -0,0 +1,54 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/KHeap.hpp> +#include <NewKit/New.hpp> + +void* operator new[](size_t sz) +{ + if (sz == 0) + ++sz; + + return hCore::kernel_new_ptr(sz, true, false); +} + +void* operator new(size_t sz) +{ + if (sz == 0) + ++sz; + + return hCore::kernel_new_ptr(sz, true, false); +} + +void operator delete[](void* ptr) +{ + if (ptr == nullptr) + return; + + hCore::kernel_delete_ptr(ptr); +} + +void operator delete(void* ptr) +{ + if (ptr == nullptr) + return; + + hCore::kernel_delete_ptr(ptr); +} + +void operator delete(void* ptr, size_t sz) +{ + if (ptr == nullptr) + return; + + (void)sz; + + hCore::kernel_delete_ptr(ptr); +} + diff --git a/Source/NewFS-Journal.cxx b/Source/NewFS-Journal.cxx new file mode 100644 index 00000000..244604c7 --- /dev/null +++ b/Source/NewFS-Journal.cxx @@ -0,0 +1,68 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + + +#include <FSKit/NewFS.hxx> +#include <KernelKit/DebugOutput.hpp> + +//! @brief Journaling for NewFS. + +#define kOpCache (4) + +namespace hCore +{ + typedef Boolean(*NewFSRunner)(VoidPtr delegate); + + class NewFSJournalRunner final + { + public: + NewFSRunner fLoadRoutine{ nullptr }; + NewFSRunner fCacheRoutine{ nullptr }; + NewFSRunner fUnloadRoutine{ nullptr }; + + explicit NewFSJournalRunner(NewFSRunner load_runner) + : fLoadRoutine(load_runner) + { + MUST_PASS(fLoadRoutine); + + fLoadRoutine(this); + } + + ~NewFSJournalRunner() noexcept + { + MUST_PASS(fUnloadRoutine); + + fUnloadRoutine(this); + } + + HCORE_COPY_DEFAULT(NewFSJournalRunner); + + public: + Boolean Run(const Int32& operation, VoidPtr class_ptr) + { + switch (operation) + { + case kOpCache: + { + if (!class_ptr) + { + kcout << "Miss for class_ptr at NewFSJournalManager::Run(class_ptr) " << __FILE__ << "\n"; + return false; + } + + MUST_PASS(fCacheRoutine); + return fCacheRoutine(class_ptr); + } + }; + + return false; + } + + }; +} // namespace hCore diff --git a/Source/NewFS.cxx b/Source/NewFS.cxx new file mode 100644 index 00000000..03a72398 --- /dev/null +++ b/Source/NewFS.cxx @@ -0,0 +1,46 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <FSKit/NewFS.hxx> +#include <KernelKit/FileManager.hpp> + +namespace hCore +{ + NewFilesystemManager::NewFilesystemManager() = default; + + NewFilesystemManager::~NewFilesystemManager() = default; + + bool NewFilesystemManager::Remove(const char* node) + { + if (node == nullptr || + *node == 0) + return false; + + if (auto catalog = fIO->GetCatalog(node); + catalog->Flags == kFlagCatalog) + return fIO->RemoveCatalog(*catalog); + + return false; + } + + NodePtr NewFilesystemManager::Create(const char* path) + { + return node_cast(fIO->CreateCatalog(path, 0, kCatalogKindFile)); + } + + NodePtr NewFilesystemManager::CreateDirectory(const char *path) + { + return node_cast(fIO->CreateCatalog(path, 0, kCatalogKindDir)); + } + + NodePtr NewFilesystemManager::CreateAlias(const char *path) + { + return node_cast(fIO->CreateCatalog(path, 0, kCatalogKindAlias)); + } +} // namespace hCore diff --git a/Source/OSErr.cxx b/Source/OSErr.cxx new file mode 100644 index 00000000..b454e079 --- /dev/null +++ b/Source/OSErr.cxx @@ -0,0 +1,11 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/OSErr.hpp> + diff --git a/Source/OwnPtr.cxx b/Source/OwnPtr.cxx new file mode 100644 index 00000000..1ea2ffeb --- /dev/null +++ b/Source/OwnPtr.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/OwnPtr.hpp>
\ No newline at end of file diff --git a/Source/PRDT.cxx b/Source/PRDT.cxx new file mode 100644 index 00000000..54556342 --- /dev/null +++ b/Source/PRDT.cxx @@ -0,0 +1,49 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/DebugOutput.hpp> +#include <StorageKit/PRDT.hpp> +#include <NewKit/String.hpp> + +namespace hCore +{ + PRDT::PRDT(const UIntPtr &physAddr) + : m_PrdtAddr(physAddr) + { + MUST_PASS(physAddr); + kcout << "PRDT::PRDT() {}\r\n"; + } + + PRDT::~PRDT() + { + kcout << "PRDT::~PRDT() {}\r\n"; + m_PrdtAddr = 0; + } + + const UInt& PRDT::Low() + { + return m_Low; + } + + const UShort& PRDT::High() + { + return m_High; + } + + const UIntPtr& PRDT::PhysicalAddress() + { + return m_PrdtAddr; + } + + PRDT& PRDT::operator=(const UIntPtr& prdtAddress) + { + m_PrdtAddr = prdtAddress; + return *this; + } +} // namespace hCore diff --git a/Source/PageAllocator.cxx b/Source/PageAllocator.cxx new file mode 100644 index 00000000..0768f4b1 --- /dev/null +++ b/Source/PageAllocator.cxx @@ -0,0 +1,56 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <ArchKit/Arch.hpp> +#include <KernelKit/DebugOutput.hpp> +#include <NewKit/PageAllocator.hpp> + +// empty for now. +namespace hCore::Detail +{ + UIntPtr create_page_wrapper(Boolean rw, Boolean user) + { + auto addr = HAL::hal_create_page(rw, user); + + if (addr == kBadAddress) + { + kcout << "[create_page_wrapper] kBadAddress returned\n"; + panic(RUNTIME_CHECK_POINTER); + } + + return addr; + } + + void exec_disable(UIntPtr VirtualAddr) + { + PTE *VirtualAddrTable = reinterpret_cast<PTE*>(VirtualAddr); + MUST_PASS(!VirtualAddrTable->Accessed); + VirtualAddrTable->ExecDisable = true; + + flush_tlb(VirtualAddr); + } + + bool page_disable(UIntPtr VirtualAddr) + { + if (VirtualAddr) { + auto VirtualAddrTable = (PTE * )(VirtualAddr); + MUST_PASS(!VirtualAddrTable->Accessed); + + if (VirtualAddrTable->Accessed) + return false; + VirtualAddrTable->Present = false; + + flush_tlb(VirtualAddr); + + return true; + } + + return false; + } +} // namespace hCore::Detail diff --git a/Source/PageManager.cxx b/Source/PageManager.cxx new file mode 100644 index 00000000..d9a8c98e --- /dev/null +++ b/Source/PageManager.cxx @@ -0,0 +1,146 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/DebugOutput.hpp> +#include <NewKit/PageManager.hpp> + +namespace hCore +{ + PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr) + : m_Rw(Rw), + m_User(User), + m_ExecDisable(ExecDisable), + m_VirtAddr(VirtAddr), + m_Cache(false), + m_Shareable(false), + m_Wt(false), + m_Present(true), + m_Accessed(false) + { + // special case for the null region. + if (VirtAddr == 0) + { + m_Wt = false; + m_Rw = false; + m_Cache = false; + m_Shareable = false; + } + } + + PTEWrapper::~PTEWrapper() + { + PTE* raw = reinterpret_cast<PTE*>(m_VirtAddr); + + MUST_PASS(raw); + MUST_PASS(!raw->Accessed); + + if (raw->Present) + raw->Present = false; + } + + void PTEWrapper::FlushTLB(Ref<PageManager> &pm) + { + pm.Leak().FlushTLB(this->m_VirtAddr); + } + + void PageManager::FlushTLB(UIntPtr VirtAddr) + { + if (VirtAddr == kBadAddress) + return; + + flush_tlb(VirtAddr); + } + + bool PTEWrapper::Reclaim() + { + if (!this->m_Present) + { + this->m_Present = true; + return true; + } + + return false; + } + + PTEWrapper *PageManager::Request(Boolean Rw, Boolean User, Boolean ExecDisable) + { + PTEWrapper *PageTableEntry = + reinterpret_cast<PTEWrapper*>(hCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User)); + + if (PageTableEntry == nullptr) { + kcout << "PTEWrapper : Page table is nullptr!, kernel_new_ptr failed!"; + return nullptr; + } + + *PageTableEntry = PTEWrapper{Rw, User, ExecDisable, Detail::create_page_wrapper(Rw, User)}; + return PageTableEntry; + } + + bool PageManager::Free(Ref<PTEWrapper*> &wrapper) + { + if (wrapper) { + if (!Detail::page_disable(wrapper->VirtualAddress())) + return false; + + this->FlushTLB(wrapper->VirtualAddress()); + return true; + } + + return false; + } + + const UIntPtr &PTEWrapper::VirtualAddress() + { + return m_VirtAddr; + } + + bool PTEWrapper::Shareable() + { + auto raw = reinterpret_cast<PTE*>(m_VirtAddr); + + if (raw->Present) + { + m_Shareable = raw->Shared; + return m_Shareable; + } + else + { + kcout << "[PTEWrapper::Shareable] page is not present!"; + return false; + } + } + + bool PTEWrapper::Present() + { + auto raw = reinterpret_cast<PTE*>(m_VirtAddr); + + if (raw->Present) + { + m_Present = raw->Present; + return m_Present; + } + else + { + kcout << "[PTEWrapper::Present] page is not present!"; + return false; + } + } + + bool PTEWrapper::Access() + { + auto raw = reinterpret_cast<PTE*>(m_VirtAddr); + + if (raw->Present) + { + m_Accessed = raw->Accessed; + } + + return m_Accessed; + } +} // namespace hCore diff --git a/Source/Panic.cxx b/Source/Panic.cxx new file mode 100644 index 00000000..a72005f1 --- /dev/null +++ b/Source/Panic.cxx @@ -0,0 +1,56 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Panic.hpp> +#include <ArchKit/Arch.hpp> +#include <NewKit/String.hpp> + +#include <KernelKit/DebugOutput.hpp> + +extern "C" [[noreturn]] void wait_for_debugger() +{ + while (true) + { + hCore::HAL::rt_cli(); + hCore::HAL::rt_halt(); + } +} + +/* Each error code is attributed with an ID, which will prompt a string onto the + * screen. Wait for debugger... */ + +namespace hCore +{ + void panic(const hCore::Int& id) + { +#ifdef __DEBUG__ + kcout << "hCore: Kernel Panic! \r\n"; + kcout << StringBuilder::FromInt("kError : %\n", id); + + DumpManager::Dump(); +#endif // __DEBUG__ + + wait_for_debugger(); + } + + void runtime_check(bool expr, const char *file, const char *line) + { + if (!expr) + { +#ifdef __DEBUG__ + kcout << "[KERNEL] Check Failed!\n"; + kcout << "[KERNEL] File: " << file << "\n"; + kcout << "[KERNEL] Where: " << line << "\n"; + +#endif // __DEBUG__ + + hCore::panic(RUNTIME_CHECK_FAILED); // Runtime Check failed + } + } +} // namespace hCore diff --git a/Source/PermissionSelector.cxx b/Source/PermissionSelector.cxx new file mode 100644 index 00000000..918de99e --- /dev/null +++ b/Source/PermissionSelector.cxx @@ -0,0 +1,33 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * File: PermissionSelector.cpp + * Purpose: Permission primitives and types. + * + * ======================================================== + */ + +#include <KernelKit/PermissionSelector.hxx> +#include <NewKit/Panic.hpp> + +namespace hCore +{ + PermissionSelector::PermissionSelector(const Int32& sel) + : fRing((RingKind)sel) + { MUST_PASS(sel > 0); } + + PermissionSelector::PermissionSelector(const RingKind& ringKind) + : fRing(ringKind) + {} + + PermissionSelector::~PermissionSelector() = default; + + bool PermissionSelector::operator==(const PermissionSelector& lhs) { return lhs.fRing == this->fRing; } + + bool PermissionSelector::operator!=(const PermissionSelector& lhs) { return lhs.fRing != this->fRing; } + + const RingKind& PermissionSelector::Ring() noexcept { return this->fRing; } +} diff --git a/Source/Pmm.cxx b/Source/Pmm.cxx new file mode 100644 index 00000000..a18b0c77 --- /dev/null +++ b/Source/Pmm.cxx @@ -0,0 +1,93 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/DebugOutput.hpp> +#include <NewKit/Pmm.hpp> + +namespace hCore +{ + Pmm::Pmm() = default; + + Pmm::Pmm(Ref<PageManager*> &pm) : m_PageManager(pm) + { + MUST_PASS(pm.Leak()); + kcout << "[PMM] New PhysicalMemoryManager\r\n"; + } + + Pmm::~Pmm() = default; + + /* If this returns Null pointer, enter emergency mode */ + Ref<PTEWrapper*> Pmm::RequestPage(Boolean user, Boolean readWrite) + { + if (m_PageManager) + { + PTEWrapper *pt = m_PageManager.Leak()->Request(user, readWrite, true); + + if (pt) + return Ref<PTEWrapper*>(pt); + + return {}; + } + + kcout << "[Pmm::RequestPage] Ref<PTEWrapper*> could not be created! " + "m_PageManager is nullptr!\r\n"; + + return {}; + } + + Boolean Pmm::FreePage(Ref<PTEWrapper*> PageRef) + { + if (!PageRef) + return false; + + PageRef->m_Present = false; + + return true; + } + + Boolean Pmm::TogglePresent(Ref<PTEWrapper*> PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef->m_Present = Enable; + + return true; + } + + Boolean Pmm::ToggleUser(Ref<PTEWrapper*> PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef->m_Rw = Enable; + + return true; + } + + Boolean Pmm::ToggleRw(Ref<PTEWrapper*> PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef->m_Rw = Enable; + + return true; + } + + Boolean Pmm::ToggleShare(Ref<PTEWrapper*> PageRef, Boolean Enable) + { + if (!PageRef) + return false; + + PageRef->m_Shareable = Enable; + + return true; + } +} // namespace hCore diff --git a/Source/ProcessManager.cxx b/Source/ProcessManager.cxx new file mode 100644 index 00000000..1a2cb73f --- /dev/null +++ b/Source/ProcessManager.cxx @@ -0,0 +1,298 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/ProcessManager.hpp> +#include <KernelKit/SMPManager.hpp> +#include <NewKit/KHeap.hpp> +#include <NewKit/String.hpp> + +#define kPoolAlign (4) + +///! bugs = 0 + +/***********************************************************************************/ +/* This file handles + * The preemptive multitasking of the OS. + * For MT see SMPManager. */ +/***********************************************************************************/ + +namespace hCore +{ + static Int32 kExitCode = 0; + + const Int32& rt_get_exit_code() noexcept { return kExitCode; } + + void Process::Crash() + { + kcout << this->Name << ": Crashed."; + this->Exit(-1); + } + + void Process::Wake(const bool should_wakeup) + { + this->Status = should_wakeup ? ProcessStatus::kRunning : ProcessStatus::kFrozen; + } + + VoidPtr Process::New(const SizeT& sz) + { + // RAM allocation + if (this->PoolCursor) + { + VoidPtr ptr = this->PoolCursor; + this->PoolCursor = (VoidPtr)((UIntPtr)this->PoolCursor + (sizeof(sz) + kPoolAlign)); + + return ptr; + } + + //! TODO: Disk to RAM allocation + + return nullptr; + } + + /* @brief checks if runtime pointer is in region. */ + bool rt_in_pool_region(VoidPtr pool_ptr, VoidPtr pool, const SizeT& sz) + { + Char* _pool_ptr = (Char*)pool_ptr; + Char* _pool = (Char*)pool; + + for (SizeT index = sz; _pool[sz] != 0x55; --index) + { + if (&_pool[index] > &_pool_ptr[sz]) + continue; + + if (_pool[index] != _pool_ptr[index]) + return false; + } + + return true; + } + + /* @brief free pointer from usage. */ + Boolean Process::Delete(VoidPtr ptr, const SizeT& sz) + { + if (sz < 1 || + this->PoolCursor == this->Pool) + return false; + + if (rt_in_pool_region(ptr, this->PoolCursor, this->UsedMemory)) + { + this->PoolCursor = (VoidPtr)((UIntPtr)this->PoolCursor - (sizeof(sz) - kPoolAlign)); + rt_zero_memory(ptr, sz); + + return true; + } + + return false; + } + + const Char* Process::GetName() { return this->Name; } + + const ProcessSelector& Process::GetSelector() { return this->Selector; } + + const ProcessStatus& Process::GetStatus() { return this->Status; } + + const AffinityKind& Process::GetAffinity() { return this->Affinity; } + + void Process::Exit(Int32 exit_code) + { + if (this->ProcessId != ProcessManager::Shared().Leak().GetCurrent().Leak().ProcessId) + return; + + if (this->Ring == (Int32)ProcessSelector::kRingKernel && + ProcessManager::Shared().Leak().GetCurrent().Leak().Ring > 0) + return; + + kExitCode = exit_code; + + if (this->Ring != (Int32)ProcessSelector::kRingDriver && + this->Ring != (Int32)ProcessSelector::kRingKernel) + { + pool_free_ptr(this->Pool); + + this->PoolCursor = nullptr; + + this->FreeMemory = kPoolMaxSz; + this->UsedMemory = 0UL; + } + + //! Delete image if not done already. + if (this->Image) + kernel_delete_ptr(this->Image); + + if (this->StackFrame) + kernel_delete_ptr((VoidPtr)this->StackFrame); + + ProcessManager::Shared().Leak().Remove(this->ProcessId); + } + + bool ProcessManager::Add(Ref<Process>& process) + { + if (!process) + return false; + + kcout << "ProcessManager::Add(Ref<Process>& process)\r\n"; + + process.Leak().Pool = pool_new_ptr(kPoolUser | kPoolRw); + process.Leak().ProcessId = this->m_Headers.Count(); + process.Leak().PoolCursor = process.Leak().Pool; + + process.Leak().StackFrame = reinterpret_cast<HAL::StackFrame*>( + kernel_new_ptr(sizeof(HAL::StackFrame), true, false) + ); + + MUST_PASS(process.Leak().StackFrame); + + UIntPtr imageStart = reinterpret_cast<UIntPtr>( + process.Leak().Image + ); + +#ifdef __x86_64__ + process.Leak().StackFrame->Rbp = imageStart; +#elif defined(__powerpc) + // link return register towards the __start symbol. + process.Leak().StackFrame->R3 = imageStart; +#endif + + this->m_Headers.Add(process); + + return true; + } + + bool ProcessManager::Remove(SizeT process) + { + if (process > this->m_Headers.Count()) + return false; + + kcout << "ProcessManager::Remove(SizeT process)\r\n"; + + return this->m_Headers.Remove(process); + } + + SizeT ProcessManager::Run() noexcept + { + SizeT processIndex = 0; //! we store this guy to tell the scheduler how many things we + //! have scheduled. + + for (; processIndex < this->m_Headers.Count(); ++processIndex) + { + auto process = this->m_Headers[processIndex]; + MUST_PASS(process); //! no need for a MUST_PASS(process.Leak());, it is recursive because of the nature of the class; + + //! run any process needed to be scheduled. + if (ProcessHelper::CanBeScheduled(process.Leak())) + { + auto unwrapped_process = *process.Leak(); + + unwrapped_process.PTime = 0; + + // set the current process. + m_CurrentProcess = unwrapped_process; + + ProcessHelper::Switch(m_CurrentProcess.Leak().StackFrame, + m_CurrentProcess.Leak().ProcessId); + } + else + { + // otherwise increment the micro-time. + ++m_CurrentProcess.Leak().PTime; + } + } + + return processIndex; + } + + Ref<ProcessManager> ProcessManager::Shared() + { + static ProcessManager ref; + return { ref }; + } + + Ref<Process>& ProcessManager::GetCurrent() + { + return m_CurrentProcess; + } + + PID& ProcessHelper::GetCurrentPID() + { + kcout << "ProcessHelper::GetCurrentPID\r\n"; + return ProcessManager::Shared().Leak().GetCurrent().Leak().ProcessId; + } + + bool ProcessHelper::CanBeScheduled(Ref<Process>& process) + { + if (process.Leak().Status == ProcessStatus::kFrozen || + process.Leak().Status == ProcessStatus::kDead) + return false; + + if (process.Leak().GetStatus() == ProcessStatus::kStarting) + { + if (process.Leak().PTime < static_cast<Int>(kMinMicroTime)) + { + process.Leak().Status = ProcessStatus::kRunning; + process.Leak().Affinity = AffinityKind::kStandard; + + return true; + } + + ++process.Leak().PTime; + } + + return process.Leak().PTime > static_cast<Int>(kMinMicroTime); + } + + bool ProcessHelper::StartScheduling() + { + if (ProcessHelper::CanBeScheduled(ProcessManager::Shared().Leak().GetCurrent())) + { + --ProcessManager::Shared().Leak().GetCurrent().Leak().PTime; + return false; + } + + auto process_ref = ProcessManager::Shared().Leak(); + + if (!process_ref) + return false; // we have nothing to schedule. simply return. + + SizeT ret = process_ref.Run(); + + kcout << StringBuilder::FromInt("ProcessHelper::Run() iterated over: % processes\r\n", ret); + + return true; + } + + bool ProcessHelper::Switch(HAL::StackFrame* the_stack, const PID& new_pid) + { + if (!the_stack || + new_pid < 0) + return false; + + for (SizeT index = 0UL; index < kMaxHarts; ++index) + { + if (SMPManager::Shared().Leak()[index].Leak().StackFrame() == the_stack) + { + SMPManager::Shared().Leak()[index].Leak().Busy(false); + continue; + } + + if (SMPManager::Shared().Leak()[index].Leak().IsBusy()) + continue; + + if (SMPManager::Shared().Leak()[index].Leak().Kind() != ThreadKind::kBoot || + SMPManager::Shared().Leak()[index].Leak().Kind() != ThreadKind::kSystemReserved) + { + SMPManager::Shared().Leak()[index].Leak().Busy(true); + ProcessHelper::GetCurrentPID() = new_pid; + + return SMPManager::Shared().Leak()[index].Leak().Switch(the_stack); + } + } + + return false; + } +} // namespace hCore diff --git a/Source/Property.cxx b/Source/Property.cxx new file mode 100644 index 00000000..2b364f24 --- /dev/null +++ b/Source/Property.cxx @@ -0,0 +1,23 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <CFKit/Property.hpp> + +namespace hCore +{ + bool Property::StringEquals(StringView &name) + { + return m_sName && this->m_sName == name; + } + + const PropertyId& Property::GetPropertyById() + { + return m_Action; + } +} // namespace hCore diff --git a/Source/Ref.cxx b/Source/Ref.cxx new file mode 100644 index 00000000..7ab92ba9 --- /dev/null +++ b/Source/Ref.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Ref.hpp> diff --git a/Source/SMPManager.cxx b/Source/SMPManager.cxx new file mode 100644 index 00000000..25dbc0cf --- /dev/null +++ b/Source/SMPManager.cxx @@ -0,0 +1,134 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/SMPManager.hpp> +#include <KernelKit/ProcessManager.hpp> +#include <ArchKit/Arch.hpp> + +//! This file handles multi processing in hCore. + +namespace hCore +{ + // @brief wakes up thread. + // wakes up thread from hang. + extern void rt_wakeup_thread(HAL::StackFrame* stack); + + // @brief makes thread sleep. + // hooks and hangs thread to prevent code from executing. + extern void rt_hang_thread(HAL::StackFrame* stack); + + // A ProcessorCore class takes care of it's owned hardware thread. + // It has a stack for it's core. + + // @brief constructor + ProcessorCore::ProcessorCore() = default; + + // @brief destructor + ProcessorCore::~ProcessorCore() = default; + + //! @brief returns the id + + const ThreadID& ProcessorCore::ID() noexcept { return m_ID; } + + //! @brief returns the kind + + const ThreadKind& ProcessorCore::Kind() noexcept { return m_Kind; } + + //! @brief is the core busy? + + bool ProcessorCore::IsBusy() noexcept { return m_Busy; } + + HAL::StackFrame* ProcessorCore::StackFrame() noexcept + { + MUST_PASS(m_Stack); + return m_Stack; + } + + void ProcessorCore::Busy(const bool busy) noexcept { m_Busy = busy; } + + ProcessorCore::operator bool() { return m_Stack; } + + void ProcessorCore::Wake(const bool wakeup) noexcept + { + m_Wakeup = wakeup; + + if (!m_Wakeup) + rt_hang_thread(m_Stack); + else + rt_wakeup_thread(m_Stack); + } + + bool ProcessorCore::Switch(HAL::StackFrame* stack) + { + if (stack == nullptr) + return false; + + return rt_do_context_switch(m_Stack, stack) == 0; + } + + ///! @brief Tells if processor is waked up. + bool ProcessorCore::IsWakeup() noexcept { return m_Wakeup; } + + //! @brief Constructor and destructor + + ///! @brief Default constructor. + SMPManager::SMPManager() = default; + + ///! @brief Default destructor. + SMPManager::~SMPManager() = default; + + Ref<SMPManager> SMPManager::Shared() + { + static SMPManager manager; + return { manager }; + } + + HAL::StackFramePtr SMPManager::GetStack() noexcept + { + if (m_ThreadList[m_CurrentThread].Leak() && + ProcessHelper::GetCurrentPID() == m_ThreadList[m_CurrentThread].Leak().Leak().m_PID) + return m_ThreadList[m_CurrentThread].Leak().Leak().m_Stack; + + return nullptr; + } + + // @brief Finds and switch to a free core. + bool SMPManager::Switch(HAL::StackFrame* stack) + { + if (stack == nullptr) + return false; + + for (SizeT idx = 0; idx < kMaxHarts; ++idx) + { + // stack != nullptr -> if core is used, then continue. + if (!m_ThreadList[idx].Leak() || + !m_ThreadList[idx].Leak().Leak().IsWakeup() || + !m_ThreadList[idx].Leak().Leak().IsBusy()) + continue; + + m_ThreadList[idx].Leak().Leak().m_ID = idx; + m_ThreadList[idx].Leak().Leak().m_Stack = stack; + m_ThreadList[idx].Leak().Leak().m_PID = ProcessHelper::GetCurrentPID(); + + m_ThreadList[idx].Leak().Leak().Busy(true); + + bool ret = rt_do_context_switch(rt_get_current_context(), stack) == 0; + + m_ThreadList[idx].Leak().Leak().Busy(false); + } + + return false; + } + + Ref<ProcessorCore> SMPManager::operator[](const SizeT& idx) { return m_ThreadList[idx].Leak(); } + + SMPManager::operator bool() noexcept { return !m_ThreadList.Empty(); } + + bool SMPManager::operator!() noexcept { return m_ThreadList.Empty(); } +} // namespace hCore diff --git a/Source/Semaphore.cxx b/Source/Semaphore.cxx new file mode 100644 index 00000000..1f4a04ef --- /dev/null +++ b/Source/Semaphore.cxx @@ -0,0 +1,53 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/Semaphore.hpp> + +#include <KernelKit/Timer.hpp> +#include <KernelKit/ProcessManager.hpp> + +namespace hCore +{ + bool Semaphore::Unlock() noexcept + { + if (fLockingProcess) + fLockingProcess = nullptr; + + return fLockingProcess == nullptr; + } + + bool Semaphore::Lock(Process* process) + { + if (!process || + fLockingProcess) + return false; + + fLockingProcess = process; + + return true; + } + + bool Semaphore::IsLocked() const { return fLockingProcess; } + + bool Semaphore::LockOrWait(Process* process, const Int64& seconds) + { + if (process == nullptr) + return false; + + HardwareTimer timer(Seconds(seconds)); + timer.Wait(); + + return this->Lock(process); + } + + void Semaphore::Sync() noexcept + { + while (fLockingProcess) {} + } +} diff --git a/Source/SharedObject.cxx b/Source/SharedObject.cxx new file mode 100644 index 00000000..4b226e69 --- /dev/null +++ b/Source/SharedObject.cxx @@ -0,0 +1,41 @@ +/* +* ======================================================== +* +* hCore +* Copyright Mahrouss Logic, all rights reserved. +* +* ======================================================== +*/ + +#include <KernelKit/DebugOutput.hpp> +#include <KernelKit/ProcessManager.hpp> +#include <KernelKit/ThreadLocalStorage.hxx> +#include <KernelKit/SharedObjectCore.hxx> + +using namespace hCore; + +/***********************************************************************************/ + +extern "C" SharedObject* __LibMain(VoidPtr image) +{ + /***********************************************************************************/ + /* Allocate new library to be added to the lookup table. */ + /***********************************************************************************/ + + SharedObject* library = hcore_tls_new_class<SharedObject>(); + + if (!library) + { + kcout << "__LibMain: out of memory!\n"; + ProcessManager::Shared().Leak().GetCurrent().Leak().Crash(); + return nullptr; + } + + library->Mount(hcore_tls_new_class<SharedObject::SharedObjectTraits>()); + + kcout << "__LibMain: Done allocate DSO.\n"; + + return library; +} + +/***********************************************************************************/
\ No newline at end of file diff --git a/Source/Storage/ATA.cxx b/Source/Storage/ATA.cxx new file mode 100644 index 00000000..5a53d78d --- /dev/null +++ b/Source/Storage/ATA.cxx @@ -0,0 +1,99 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <StorageKit/ATA.hpp> +#include <ArchKit/Arch.hpp> + +//! @brief Driver for ATA, listens to a specific address for data to come. +//! mapped by NewFirmware. + +#define kATAError 2 + +namespace hCore +{ + Ref<PRDT*> kPrdt = nullptr; + + bool set_prdt_struct(Ref<PRDT*>& refCtrl) + { + if (!kPrdt) + { + kPrdt = refCtrl; + kcout << "[set_prdt_struct] PRDT is set."; + + return true; + } + + kcout << "[set_prdt_struct] [WARNING] Tried to change PRDT.\n"; + return false; + } + + enum + { + k28BitRead = 0xC8, + k48BitRead = 0x25, + k28BitWrite = 0xCA, + k48BitWrite = 0x35, + }; + + const char* ata_read_28(ULong lba) + { + static char buffer[512]; + + UIntPtr* packet = (UIntPtr*)kPrdt.Leak()->PhysicalAddress(); + + packet[0] = k28BitRead; + packet[1] = (UIntPtr)&buffer; + packet[2] = lba; + + rt_wait_for_io(); + + return buffer; + } + + const char* ata_read_48(ULong lba) + { + static char buffer[512]; + + UIntPtr* packet = (UIntPtr*)kPrdt.Leak()->PhysicalAddress(); + + packet[0] = k48BitRead; + packet[1] = (UIntPtr)&buffer; + packet[4] = lba; + + rt_wait_for_io(); + + return buffer; + } + + Int32 ata_write_48(ULong lba, const char *text) + { + UIntPtr* packet = (UIntPtr*)kPrdt.Leak()->PhysicalAddress(); + + packet[0] = k48BitWrite; + packet[1] = (UIntPtr)&text; + packet[2] = lba; + + rt_wait_for_io(); + + return packet[1] == 2 ? kATAError : 0; + } + + Int32 ata_write_28(ULong lba, const char *text) + { + UIntPtr* packet = (UIntPtr*)kPrdt.Leak()->PhysicalAddress(); + + packet[0] = k28BitWrite; + packet[1] = (UIntPtr)&text; + packet[2] = lba; + + rt_wait_for_io(); + + return packet[1] == 2 ? kATAError : 0; + } +} // namespace hCore diff --git a/Source/Storage/NVME.cxx b/Source/Storage/NVME.cxx new file mode 100644 index 00000000..20fbd84d --- /dev/null +++ b/Source/Storage/NVME.cxx @@ -0,0 +1,18 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <StorageKit/NVME.hpp> + +namespace hCore +{ + const char *NVMEDevice::Name() const + { + return ("NVMEDevice"); + } +} // namespace hCore diff --git a/Source/Storage/Storage.cxx b/Source/Storage/Storage.cxx new file mode 100644 index 00000000..f6732599 --- /dev/null +++ b/Source/Storage/Storage.cxx @@ -0,0 +1,12 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <StorageKit/Storage.hpp> + +const OSScsiPacket kCDRomPacketTemplate = { 0x43, 0, 1, 0, 0, 0, 0, 12, 0x40, 0, 0 }; diff --git a/Source/Stream.cxx b/Source/Stream.cxx new file mode 100644 index 00000000..66125b5d --- /dev/null +++ b/Source/Stream.cxx @@ -0,0 +1,10 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Stream.hpp> diff --git a/Source/String.cxx b/Source/String.cxx new file mode 100644 index 00000000..1acbfc39 --- /dev/null +++ b/Source/String.cxx @@ -0,0 +1,242 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/KHeap.hpp> +#include <NewKit/String.hpp> +#include <NewKit/Utils.hpp> + +namespace hCore +{ + Char* StringView::Data() { return m_Data; } + + const Char* StringView::CData() { return m_Data; } + + Size StringView::Length() const { return string_length(m_Data); } + + bool StringView::operator==(const StringView &rhs) const + { + if (rhs.Length() != this->Length()) + return false; + + for (Size index = 0; index < this->Length(); ++index) + { + if (rhs.m_Data[index] != m_Data[index]) + return false; + } + + return true; + } + + bool StringView::operator==(const Char *rhs) const + { + if (string_length(rhs) != this->Length()) + return false; + + for (Size index = 0; index < string_length(rhs); ++index) + { + if (rhs[index] != m_Data[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.m_Data[index] == m_Data[index]) + return false; + } + + return true; + } + + bool StringView::operator!=(const Char *rhs) const + { + if (string_length(rhs) != this->Length()) + return false; + + for (Size index = 0; index < string_length(rhs); ++index) + { + if (rhs[index] == m_Data[index]) + return false; + } + + return true; + } + + ErrorOr<StringView> StringBuilder::Construct(const Char *data) + { + if (!data || + *data == 0) + return {}; + + StringView view(string_length(data)); + + rt_copy_memory(reinterpret_cast<voidPtr>(const_cast<Char*>(data)), reinterpret_cast<voidPtr>(view.Data()), + view.Length()); + + return ErrorOr<StringView>(view); + } + + const char* StringBuilder::FromInt(const char *fmt, int i) + { + if (!fmt) + return ("-1"); + + char* ret = (char*)__alloca(sizeof(char) * 8 + string_length(fmt)); + + if (!ret) + return ("-1"); + + Char result[8]; + + if (!to_str(result, sizeof(int), i)) + { + delete[] ret; + return ("-1"); + } + + const auto fmt_len = string_length(fmt); + const auto res_len = string_length(result); + + for (Size idx = 0; idx < fmt_len; ++idx) + { + if (fmt[idx] == '%') { + SizeT result_cnt = idx; + + for (auto y_idx = idx; y_idx < res_len; ++y_idx) { + ret[result_cnt] = result[y_idx]; + ++result_cnt; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; /* Copy that ret into a buffer, Alloca allocates to the stack */ + } + + const char *StringBuilder::FromBool(const char *fmt, bool i) + { + if (!fmt) + return ("?"); + + const char* boolean_expr = i ? "true" : "false"; + char* ret = (char*)__alloca((sizeof(char) * i) ? 4 : 5 + string_length(fmt)); + + if (!ret) + return ("?"); + + const auto fmt_len = string_length(fmt); + const auto res_len = string_length(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 (string_length(rhs) != string_length(lhs)) + return false; + + for (Size index = 0; index < string_length(rhs); ++index) + { + if (rhs[index] != lhs[index]) + return false; + } + + return true; + } + + const char *StringBuilder::Format(const char *fmt, const char *fmt2) + { + if (!fmt || !fmt2) + return ("?"); + + char* ret = (char*)alloca(sizeof(char) * string_length(fmt2) + string_length(fmt2)); + + if (!ret) + return ("?"); + + for (Size idx = 0; idx < string_length(fmt); ++idx) + { + if (fmt[idx] == '%') { + Size result_cnt = idx; + for (Size y_idx = 0; y_idx < string_length(fmt2); ++y_idx) + { + ret[result_cnt] = fmt2[y_idx]; + ++result_cnt; + } + + break; + } + + ret[idx] = fmt[idx]; + } + + return ret; + } + + static void string_append(char *lhs, char *rhs, int cur) + { + if (lhs && rhs && + cur < string_length(lhs)) + { + SizeT sz_lhs = string_length(lhs); + SizeT sz_rhs = string_length(rhs); + + rt_copy_memory(rhs, lhs + cur, sz_rhs); + } + } + + StringView& StringView::operator+=(const Char *rhs) + { + if (string_length(rhs) > string_length(this->m_Data)) + return *this; + + string_append(this->m_Data, const_cast<char*>(rhs), this->m_Cur); + this->m_Cur += string_length(rhs); + + return *this; + } + + StringView& StringView::operator+=(const StringView &rhs) + { + if (string_length(rhs.m_Data) > string_length(this->m_Data)) + return *this; + + string_append(this->m_Data, const_cast<char*>(rhs.m_Data), this->m_Cur); + this->m_Cur += string_length(const_cast<char*>(rhs.m_Data)); + + return *this; + } +} // namespace hCore diff --git a/Source/ThreadLocalStorage.cxx b/Source/ThreadLocalStorage.cxx new file mode 100644 index 00000000..36f59df5 --- /dev/null +++ b/Source/ThreadLocalStorage.cxx @@ -0,0 +1,33 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/ProcessManager.hpp> +#include <KernelKit/ThreadLocalStorage.hxx> + +#include <KernelKit/SharedObjectCore.hxx> + +using namespace hCore; + +Boolean hcore_tls_check(VoidPtr ptr) +{ + if (!ptr) + return false; + + const char *_ptr = (const char *)ptr; + return _ptr[0] == kRTLMag0 && _ptr[1] == kRTLMag1 && _ptr[2] == kRTLMag2; +} + +void hcore_tls_check_syscall_impl(VoidPtr ptr) noexcept +{ + if (!hcore_tls_check(ptr)) + { + kcout << "TLS: Thread check failure, crashing...\n"; + ProcessManager::Shared().Leak().GetCurrent().Leak().Crash(); + } +} diff --git a/Source/Timer.cxx b/Source/Timer.cxx new file mode 100644 index 00000000..13e66337 --- /dev/null +++ b/Source/Timer.cxx @@ -0,0 +1,28 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <KernelKit/Timer.hpp> + +// bugs = 0 + +using namespace hCore; + +HardwareTimer::HardwareTimer(Int64 seconds) : fWaitFor(seconds) {} +HardwareTimer::~HardwareTimer() { fWaitFor = 0; } + +Int32 HardwareTimer::Wait() +{ + if (fWaitFor < 1) + return -1; + + while (*fDigitalTimer < (*fDigitalTimer + fWaitFor)) + ; + + return 0; +}
\ No newline at end of file diff --git a/Source/URL.cxx b/Source/URL.cxx new file mode 100644 index 00000000..f382fb58 --- /dev/null +++ b/Source/URL.cxx @@ -0,0 +1,99 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <CFKit/URL.hpp> +#include <NewKit/Utils.hpp> + +#include <KernelKit/DebugOutput.hpp> + +// Bugs = 0 + +namespace hCore +{ + Url::Url(StringView &strUrl) : m_urlView(strUrl, false) {} + + Url::~Url() = default; + + constexpr const char *kProtos[] = { + "https", // http with the secure. + "http", // http without the secure + "file", // filesystem protocol + "ftp", // file transfer protocol + "params", // system settings + "rsh", // remote shell (gui) + }; + + constexpr const int kUrlOutSz = 3; //! :// + constexpr const int kProtosCount = 8; + constexpr const int kRangeSz = 4096; + + static ErrorOr<StringView> url_extract_location(const char *url) + { + if (!url || *url == 0 || string_length(url, kRangeSz) > kRangeSz) + return ErrorOr<StringView>{-1}; + + StringView view(string_length(url)); + + SizeT i = 0; + bool scheme_found = false; + + for (; i < string_length(url); ++i) + { + if (!scheme_found) + { + for (int y = 0; kProtosCount; ++y) + { + if (string_in_string(view.CData(), kProtos[y])) + { + i += string_length(kProtos[y]) + kUrlOutSz; + scheme_found = true; + + break; + } + } + } + + view.Data()[i] = url[i]; + } + + return ErrorOr<StringView>(view); + } + + static ErrorOr<StringView> url_extract_protocol(const char *url) + { + if (!url || *url == 0 || string_length(url, kRangeSz) > kRangeSz) + return ErrorOr<StringView>{-1}; + + ErrorOr<StringView> view{ -1 }; + + return view; + } + + Ref<ErrorOr<StringView>> Url::Location() noexcept + { + const char *src = m_urlView.Leak().CData(); + auto loc = url_extract_location(src); + + if (!loc) + return {}; + + return Ref<ErrorOr<StringView>>(loc); + } + + Ref<ErrorOr<StringView>> Url::Protocol() noexcept + { + const char *src = m_urlView.Leak().CData(); + auto loc = url_extract_protocol(src); + + if (!loc) + return {}; + + return Ref<ErrorOr<StringView>>(loc); + } +} // namespace hCore diff --git a/Source/Utils.cxx b/Source/Utils.cxx new file mode 100644 index 00000000..557632c3 --- /dev/null +++ b/Source/Utils.cxx @@ -0,0 +1,209 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Utils.hpp> + +namespace hCore +{ + Int string_compare(const Char *src, const Char *cmp, Size size) + { + Int32 counter = 0; + + for (Size index = 0; index < size; ++index) + { + if (src[index] != cmp[index]) + ++counter; + } + + return counter; + } + + void rt_zero_memory(voidPtr pointer, Size len) + { + rt_set_memory((voidPtr) pointer, 0, len); + } + + Size string_length(const Char *str, SizeT _len) + { + if (*str == '\0') + return 0; + + Size len{0}; + while (str[len] != '\0') + { + if (len > _len) + { + break; + } + + ++len; + } + + return len; + } + + Size string_length(const Char *str) + { + if (*str == '\0') + return 0; + + Size len{0}; + while (str[len] != '\0') + ++len; + + return len; + } + + voidPtr rt_set_memory(voidPtr src, char value, Size len) + { + if (!src || len < 1) + return nullptr; + char *start = reinterpret_cast<Char*>(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<Char*>(src); + char *dstChar = reinterpret_cast<Char*>(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; + if (!src || !dst) + return -1; + + char *srcChr = reinterpret_cast<char*>(src); + char *dstChar = reinterpret_cast<char*>(dst); + Size index = 0; + + while (index < len) + { + dstChar[index] = srcChr[index]; + index++; + } + + return 0; + } + + const Char *alloc_string(const Char *text) + { + if (!text) + return nullptr; + + const Char *string = new Char[string_length(text)]; + if (!string) + return nullptr; + + voidPtr vText = reinterpret_cast<voidPtr>(const_cast<char*>(text)); + voidPtr vStr = reinterpret_cast<voidPtr>(const_cast<char*>(string)); + rt_copy_memory(vText, vStr, string_length(text)); + return string; + } + + Int to_uppercase(Int character) + { + if (character >= 'a' && character <= 'z') + return character - 0x20; + + return character; + } + + Int to_lower(Int character) + { + if (character >= 'A' && character <= 'Z') + return character + 0x20; + + return character; + } + + bool to_str(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 string_in_string(const char *in, const char *needle) + { + for (size_t i = 0; i < string_length(in); ++i) + { + if (string_compare(in + i, needle, string_length(needle)) == 0) + return reinterpret_cast<voidPtr>(const_cast<char*>(in + i)); + } + + return nullptr; + } + + // @brief Checks for a string start at the character. + + char* string_from_char(char* str, const char chr) + { + while (*str != chr) + { + ++str; + + if (*str == 0) + return nullptr; + } + + return str; + } +} // namespace hCore diff --git a/Source/Variant.cxx b/Source/Variant.cxx new file mode 100644 index 00000000..b9621990 --- /dev/null +++ b/Source/Variant.cxx @@ -0,0 +1,32 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include <NewKit/Variant.hpp> + +namespace hCore +{ + const Char* Variant::ToString() + { + if (m_Ptr == nullptr) + { + return ("Memory:{Nullptr}"); + } + + switch (m_Kind) + { + case VariantKind::kString: + return ("Class:{String}"); + case VariantKind::kPointer: + return ("Memory:{Pointer}"); + default: + return ("Class:{Undefined}"); + } + } + +} // namespace hCore diff --git a/Source/compile_flags.txt b/Source/compile_flags.txt new file mode 100644 index 00000000..6b26618c --- /dev/null +++ b/Source/compile_flags.txt @@ -0,0 +1,4 @@ +-nostdlib +-ffreestanding +-std=c++20 +-I../
\ No newline at end of file |
