diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-06 09:14:11 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-06 09:14:11 +0100 |
| commit | 5339d016c07bf717ee388f4feb73544087324af0 (patch) | |
| tree | 94be6f67ed626091f24aee24ec3b3be03d01e4e7 /KernelKit | |
git: port from mercurial repo.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'KernelKit')
27 files changed, 1803 insertions, 0 deletions
diff --git a/KernelKit/CodeManager.hpp b/KernelKit/CodeManager.hpp new file mode 100644 index 00000000..61b609c6 --- /dev/null +++ b/KernelKit/CodeManager.hpp @@ -0,0 +1,74 @@ +/* +* ======================================================== +* +* hCore +* Copyright Mahrouss Logic, all rights reserved. +* +* ======================================================== +*/ + +#ifndef _INC_CODE_MANAGER_ +#define _INC_CODE_MANAGER_ + +#include <KernelKit/PEF.hpp> +#include <NewKit/ErrorOr.hpp> +#include <NewKit/String.hpp> + +namespace hCore +{ + /// + /// \name PEFLoader + /// PEF container format implementation. + /// + class PEFLoader : public Loader + { + PEFLoader() = delete; + + public: + explicit PEFLoader(const char* path); + ~PEFLoader() override; + + public: + HCORE_COPY_DEFAULT(PEFLoader); + + public: + typedef void(*MainKind)(void); + + public: + const char* Path() override; + const char* Format() override; + const char* MIME() override; + + public: + ErrorOr<VoidPtr> LoadStart() override; + VoidPtr FindSymbol(const char* name, Int32 kind) override; + + public: + bool IsLoaded() noexcept; + + private: + Ref<StringView> fPath; + VoidPtr fCachedBlob; + bool fBad; + + }; + + namespace Utils + { + /// \brief Much like Mac OS's UPP. + /// It cover other architecture code. + /// PowerPC <-> AMD64 for example. + typedef struct UniversalProcedureTable + { + public: + Char symbolName[kPefNameLen]; + VoidPtr symbolPtr; + SizeT symbolArchitecture; + + } UniversalProcedureTableType; + + bool execute_from_image(PEFLoader& exec); + } +} + +#endif // ifndef _INC_CODE_MANAGER_ diff --git a/KernelKit/DebugOutput.hpp b/KernelKit/DebugOutput.hpp new file mode 100644 index 00000000..9634c32b --- /dev/null +++ b/KernelKit/DebugOutput.hpp @@ -0,0 +1,40 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <KernelKit/Device.hpp> +#include <NewKit/OwnPtr.hpp> +#include <NewKit/Stream.hpp> + +namespace hCore +{ + // @brief Emulates a VT100 terminal. + class TerminalDevice final : public IDevice<const char*> + { + public: + TerminalDevice(void (*print)(const char *), void (*get)(const char *)) : IDevice<const char*>(print, get) {} + virtual ~TerminalDevice() {} + + /// @brief returns device name (terminal name) + /// @return string type (const char*) + virtual const char* Name() const override { return ("TerminalDevice"); } + + TerminalDevice &operator=(const TerminalDevice &) = default; + TerminalDevice(const TerminalDevice &) = default; + + }; + + namespace Detail + { + bool serial_init(); + } + + extern TerminalDevice kcout; +} // namespace hCore diff --git a/KernelKit/Defines.hpp b/KernelKit/Defines.hpp new file mode 100644 index 00000000..cc63918b --- /dev/null +++ b/KernelKit/Defines.hpp @@ -0,0 +1,15 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/Defines.hpp> + +#define KERNELKIT_VERSION "1.0.0" +#define KERNELKIT_RELEASE "Baldur"
\ No newline at end of file diff --git a/KernelKit/Device.hpp b/KernelKit/Device.hpp new file mode 100644 index 00000000..859a198b --- /dev/null +++ b/KernelKit/Device.hpp @@ -0,0 +1,97 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +/* hCore */ +/* File: KernelKit/Device.hpp */ +/* Device abstraction utilities. */ + +#include <NewKit/ErrorOr.hpp> +#include <NewKit/Ref.hpp> + +namespace hCore +{ + template<typename T> + class IDevice; + + template<typename T> + class IDevice + { + public: + IDevice(void (*Out)(T), void (*In)(T)) + : m_Out(Out), m_In(In) {} + + virtual ~IDevice() = default; + + public: + IDevice &operator=(const IDevice<T> &) = default; + IDevice(const IDevice<T> &) = default; + + public: + IDevice<T> &operator<<(T Data) + { + m_Out(Data); + return *this; + } + + IDevice<T> &operator>>(T Data) + { + m_In(Data); + return *this; + } + + virtual const char *Name() const + { + return ("IDevice"); + } + + operator bool() { return m_Out && m_In; } + bool operator!() { return !m_Out && !m_In; } + + private: + void (*m_Out)(T Data); + void (*m_In)(T Data); + + }; + + template<typename T> + class IOBuf final + { + public: + explicit IOBuf(T Dat) : m_Data(Dat) {} + + IOBuf &operator=(const IOBuf<T> &) = default; + IOBuf(const IOBuf<T> &) = default; + + ~IOBuf() = default; + + public: + T operator->() const { return m_Data; } + T &operator[](Size index) const { return m_Data[index]; } + + private: + T m_Data; + + }; + + ///! device types. + enum + { + kDeviceIde, + kDeviceNetwork, + kDevicePrinter, + kDeviceGSDB, + kDeviceScsi, + kDeviceSata, + kDeviceUsb, + kDeviceCD, + kDeviceSwap, + }; +} // namespace hCore diff --git a/KernelKit/DriveManager.hpp b/KernelKit/DriveManager.hpp new file mode 100644 index 00000000..77dbae61 --- /dev/null +++ b/KernelKit/DriveManager.hpp @@ -0,0 +1,87 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <CompilerKit/Compiler.hpp> +#include <NewKit/Defines.hpp> +#include <NewKit/String.hpp> + +#include <KernelKit/Device.hpp> + +#define kDriveInvalidID -1 +#define kDriveNameLen 32 + +namespace hCore +{ + enum + { + kInvalidDrive = -1, + kBlockDevice = 0xAD, + kMassStorage = 0xDA, + kFloppyDisc = 0xCD, + kOpticalDisc = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray + kReadOnly = 0x10, // Read only drive + kXPMDrive = 0x11, // eXplicit Partition Map. + kXPTDrive = 0x12, // GPT w/ XPM partition. + kMBRDrive = 0x13, // IBM PC classic partition scheme + }; + + typedef Int64 DriveID; + + // Mounted drive. + struct DriveTraits final + { + char fName[kDriveNameLen]; // /system, /boot... + Int32 fKind; // fMassStorage, fFloppy, fOpticalDisc. + DriveID fId; // Drive id. + Int32 fFlags; // fReadOnly, fXPMDrive, fXPTDrive + + //! disk mount, unmount operations + void(*fMount)(void); + void(*fUnmount)(void); + + bool(*fReady)(void); //! is drive ready? + + //! for StorageKit. + struct + { + voidPtr fPacketContent; // packet body. + Char fPacketMime[32]; //! identify what we're sending. + SizeT fPacketSize; // packet size + } fPacket; + }; + +#define kPacketBinary "file/x-binary" +#define kPacketSource "file/x-source" +#define kPacketASCII "file/x-ascii" +#define kPacketZip "file/x-zip" + + //! drive as a device. + typedef IDevice<DriveTraits> Drive; + typedef Drive* DrivePtr; + + class DriveSelector final + { + public: + explicit DriveSelector(); + ~DriveSelector(); + + public: + HCORE_COPY_DEFAULT(DriveSelector); + + DriveTraits& GetMounted(); + bool Mount(DriveTraits* drive); + DriveTraits* Unmount(); + + private: + DriveTraits* fDrive; + + }; +} diff --git a/KernelKit/FileManager.hpp b/KernelKit/FileManager.hpp new file mode 100644 index 00000000..2f8ad4a4 --- /dev/null +++ b/KernelKit/FileManager.hpp @@ -0,0 +1,206 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/Stream.hpp> +#include <NewKit/Ref.hpp> +#include <FSKit/NewFS.hxx> + +#include <NewKit/ErrorID.hpp> +#include <NewKit/Ref.hpp> + +/// Main filesystem abstraction manager. + +#define kBootFolder "/boot" +#define kBinFolder "/bin" +#define kShLibsFolder "/lib" + +#define kSectorSz 512 + +/// refer to first enum. +#define kFileOpsCount 4 + +namespace hCore +{ + enum + { + kFileWriteAll = 100, + kFileReadAll = 101, + kFileReadChunk = 102, + kFileWriteChunk = 103, + }; + + typedef VoidPtr NodePtr; + + class IFilesystemManager + { + public: + IFilesystemManager() = default; + virtual ~IFilesystemManager() = default; + + public: + HCORE_COPY_DEFAULT(IFilesystemManager); + + public: + static bool Mount(IFilesystemManager* pMount); + static IFilesystemManager* Unmount(); + static IFilesystemManager* GetMounted(); + + public: + virtual NodePtr Create(const char* path) = 0; + virtual NodePtr CreateAlias(const char* path) = 0; + virtual NodePtr CreateDirectory(const char* path) = 0; + + public: + virtual bool Remove(const char* path) = 0; + + public: + virtual NodePtr Open(const char* path, const char* r) = 0; + + public: + virtual void Write(NodePtr node, VoidPtr data, Int32 flags) = 0; + virtual VoidPtr Read(NodePtr node, Int32 flags, SizeT sz) = 0; + + public: + virtual bool Seek(NodePtr node, SizeT off) = 0; + + public: + virtual SizeT Tell(NodePtr node) = 0; + virtual bool Rewind(NodePtr node) = 0; + + }; + + class NewFilesystemManager final : public IFilesystemManager + { + public: + NewFilesystemManager(); + ~NewFilesystemManager() override; + + public: + HCORE_COPY_DEFAULT(NewFilesystemManager); + + public: + NodePtr Create(const char* path) override; + NodePtr CreateAlias(const char* path) override; + NodePtr CreateDirectory(const char* path) override; + + public: + bool Remove(const char* node) override; + + public: + NodePtr Open(const char* path, const char* r) override { return nullptr; } + + public: + void Write(NodePtr node, VoidPtr data, Int32 flags) override { } + VoidPtr Read(NodePtr node, Int32 flags, SizeT sz) override { return nullptr; } + + public: + bool Seek(NodePtr node, SizeT off) override { return true; } + + public: + SizeT Tell(NodePtr node) override { return 0; } + bool Rewind(NodePtr node) override { this->Seek(node, 0); return true; } + + public: + NewFSImpl* fIO{ nullptr }; + + }; + + template <typename Encoding = char, typename FSClass = NewFilesystemManager> + class FileStream final + { + public: + explicit FileStream(const Encoding* path); + ~FileStream(); + + public: + FileStream &operator=(const FileStream &); \ + FileStream(const FileStream &); + + public: + ErrorOr<Int64> WriteAll(const VoidPtr data) noexcept + { + if (data == nullptr) + return ErrorOr<Int64>(ME_INVALID_DATA); + + auto man = FSClass::GetMounted(); + + if (man) + { + man->Write(fFile, data, kFileWriteAll); + return ErrorOr<Int64>(0); + } + + return ErrorOr<Int64>(ME_INVALID_DATA); + } + + VoidPtr ReadAll() noexcept + { + auto man = FSClass::GetMounted(); + + if (man) + { + VoidPtr ret = man->Read(fFile, kFileReadAll, 0); + return ret; + } + + return nullptr; + } + + voidPtr Read(SizeT offset, SizeT sz) + { + auto man = FSClass::GetMounted(); + + if (man) + { + man->Seek(fFile, offset); + auto ret = man->Read(fFile, kFileReadChunk, sz); + + return ret; + } + + return nullptr; + } + + void Write(SizeT offset, voidPtr data, SizeT sz) + { + auto man = FSClass::GetMounted(); + + if (man) + { + man->Seek(fFile, offset); + man->Write(fFile, data, sz, kFileReadChunk); + } + } + + public: + const char* MIME() noexcept { return fMime; } + + private: + NodePtr fFile; + Char* fMime{ "application-type/*" }; + + }; + + using FileStreamUTF8 = FileStream<char>; + using FileStreamUTF16 = FileStream<wchar_t>; + + template <typename Encoding, typename Class> + FileStream<Encoding, Class>::FileStream(const Encoding* path) + : fFile(Class::GetMounted()->Open(path, "r+")) + {} + + template <typename Encoding, typename Class> + FileStream<Encoding, Class>::~FileStream() = default; +} + +#define node_cast(PTR) reinterpret_cast<hCore::NodePtr>(PTR) + + diff --git a/KernelKit/Framebuffer.hpp b/KernelKit/Framebuffer.hpp new file mode 100644 index 00000000..26a5739d --- /dev/null +++ b/KernelKit/Framebuffer.hpp @@ -0,0 +1,59 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#ifndef _INC_FB_HPP__ +#define _INC_FB_HPP__ + +#include <NewKit/Defines.hpp> +#include <NewKit/Ref.hpp> + +namespace hCore +{ + enum class FramebufferColorKind : UChar + { + RGB32, + RGB16, + RGB8, + INVALID, + }; + + class FramebufferContext final + { + public: + UIntPtr m_Base; + UIntPtr m_Bpp; + UInt m_Width; + UInt m_Height; + + }; + + class Framebuffer final + { + public: + Framebuffer(Ref<FramebufferContext*> &addr); + ~Framebuffer(); + + Framebuffer &operator=(const Framebuffer &) = delete; + Framebuffer(const Framebuffer &) = default; + + volatile UIntPtr* operator[](const UIntPtr &width_and_height); + operator bool(); + + const FramebufferColorKind& Color(const FramebufferColorKind &colour = FramebufferColorKind::INVALID); + + Ref<FramebufferContext*>& Leak(); + + private: + Ref<FramebufferContext*> m_FrameBufferAddr; + FramebufferColorKind m_Colour; + + }; +} // namespace hCore + +#endif /* ifndef _INC_FB_HPP__ */ diff --git a/KernelKit/Loader.hpp b/KernelKit/Loader.hpp new file mode 100644 index 00000000..80166189 --- /dev/null +++ b/KernelKit/Loader.hpp @@ -0,0 +1,34 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/ErrorOr.hpp> +#include <NewKit/Defines.hpp> +#include <CompilerKit/Compiler.hpp> + +namespace hCore +{ + class Loader + { + public: + Loader() = default; + virtual ~Loader() = default; + + HCORE_COPY_DEFAULT(Loader); + + public: + virtual const char* Format() = 0; + virtual const char* MIME() = 0; + virtual const char* Path() = 0; + virtual ErrorOr<VoidPtr> LoadStart() = 0; + virtual VoidPtr FindSymbol(const char* name, Int32 kind) = 0; + + }; +} diff --git a/KernelKit/OSErr.hpp b/KernelKit/OSErr.hpp new file mode 100644 index 00000000..26f91502 --- /dev/null +++ b/KernelKit/OSErr.hpp @@ -0,0 +1,29 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/Defines.hpp> + +namespace hCore +{ + typedef Int32 OSErr; + + inline constexpr OSErr kErrorExecutable = 33; + inline constexpr OSErr kErrorExecutableLib = 34; + inline constexpr OSErr kErrorFileNotFound = 35; + inline constexpr OSErr kErrorDirectoryNotFound = 36; + inline constexpr OSErr kErrorDiskReadOnly = 37; + inline constexpr OSErr kErrorDiskIsFull = 38; + inline constexpr OSErr kErrorProcessFault = 39; + inline constexpr OSErr kErrorSocketHangUp = 40; + inline constexpr OSErr kErrorThreadLocalStorage = 41; + inline constexpr OSErr kErrorMath = 42; + inline constexpr OSErr kErrorNoNetwork = 43; +}
\ No newline at end of file diff --git a/KernelKit/PCI/Database.hpp b/KernelKit/PCI/Database.hpp new file mode 100644 index 00000000..b709ac66 --- /dev/null +++ b/KernelKit/PCI/Database.hpp @@ -0,0 +1,38 @@ +/* + * ======================================================== + * + * hCore + * Copyright XPX Corp, all rights reserved. + * + * ======================================================== + */ +#pragma once + +#include <KernelKit/PCI/Device.hpp> +#include <NewKit/Defines.hpp> + +namespace hCore { + namespace Types { + // https://wiki.osdev.org/PCI + enum class PciDeviceKind : UChar { + MassStorageController = 0x1, + NetworkController = 0x2, + DisplayController = 0x3, + MultimediaController = 0x4, + MemoryController = 0x5, + Bridge = 0x6, + CommunicationController = 0x7, + GenericSystemPeripheral = 0x8, + InputDeviceController = 0x9, + DockingStation = 0xa, + Processor = 0xb, + SerialBusController = 0xc, + WirelessController = 0xd, + IntelligentController = 0xe, + SatelliteCommunicationsController = 0xf, + CoProcessor = 0x40, + Unassgined = 0xf, + Invalid = Unassgined, + }; + } // namespace Types +} // namespace hCore diff --git a/KernelKit/PCI/Device.hpp b/KernelKit/PCI/Device.hpp new file mode 100644 index 00000000..9c89e1b5 --- /dev/null +++ b/KernelKit/PCI/Device.hpp @@ -0,0 +1,84 @@ +/* + * ======================================================== + * + * hCore + * Copyright XPX Corp, all rights reserved. + * + * ======================================================== + */ +#pragma once + +#include <NewKit/Defines.hpp> + +namespace hCore::PCI +{ + enum class PciConfigKind : UShort + { + ConfigAddress = 0xCF8, + ConfigData = 0xCFC, + Invalid = 0xFFF + }; + + class Device final + { + public: + Device() = default; + + public: + explicit Device(UShort bus, UShort device, UShort function, UShort bar); + + Device &operator=(const Device &) = default; + + Device(const Device &) = default; + + ~Device(); + + public: + UInt Read(UInt bar, Size szData); + void Write(UInt bar, UIntPtr data, Size szData); + + public: + operator bool(); + + public: + template<typename T> + UInt Read(UInt bar) + { + static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported"); + return Read(bar, sizeof(T)); + } + + template<typename T> + void Write(UInt bar, UIntPtr data) + { + static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported"); + Write(bar, data, sizeof(T)); + } + + public: + UShort DeviceId(); + UShort VendorId(); + UShort InterfaceId(); + UChar Class(); + UChar Subclass(); + UChar ProgIf(); + UChar HeaderType(); + + public: + void EnableMmio(); + void BecomeBusMaster(); // for PCI-DMA, PC-DMA does not need that. + + UShort Vendor(); + + private: + UShort m_Bus; + UShort m_Device; + UShort m_Function; + UShort m_Bar; + + }; +} // namespace hCore::PCI + + +extern "C" void LumiaPCISetCfgTarget(hCore::UInt bar); +extern "C" hCore::UInt LumiaPCIReadRaw(hCore::UInt bar); diff --git a/KernelKit/PCI/Dma.hpp b/KernelKit/PCI/Dma.hpp new file mode 100644 index 00000000..518b6141 --- /dev/null +++ b/KernelKit/PCI/Dma.hpp @@ -0,0 +1,82 @@ +/* + * ======================================================== + * + * hCore + * Copyright XPX Corp, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <KernelKit/Device.hpp> +#include <KernelKit/PCI/Device.hpp> +#include <NewKit/Array.hpp> +#include <NewKit/OwnPtr.hpp> +#include <NewKit/Ref.hpp> + +namespace hCore +{ + enum class DmaKind + { + PCI, // Bus mastering is required to be turned on. Basiaclly a request + // control system. 64-Bit access depends on the PAE bit and the device + // (if Double Address Cycle is available) + ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM. + Invalid, + }; + + class DMAWrapper final + { + public: + DMAWrapper() = delete; + + public: + DMAWrapper(nullPtr) = delete; + DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) : m_Address(Ptr), m_Kind(Kind) {} + + public: + DMAWrapper &operator=(voidPtr Ptr); + + public: + DMAWrapper &operator=(const DMAWrapper &) = default; + DMAWrapper(const DMAWrapper &) = default; + + public: + ~DMAWrapper() = default; + + template<class T> + T *operator->(); + + template<class T> + T *Get(const UIntPtr off = 0); + + public: + operator bool(); + bool operator!(); + + public: + bool Write(const UIntPtr &bit, const UIntPtr &offset); + UIntPtr Read(const UIntPtr &offset); + Boolean Check(UIntPtr offset) const; + + public: + UIntPtr operator[](const UIntPtr &offset); + + private: + voidPtr m_Address{nullptr}; + DmaKind m_Kind{DmaKind::Invalid}; + + private: + friend class DMAFactory; + }; + + class DMAFactory final + { + public: + static OwnPtr<IOBuf<Char*>> Construct(OwnPtr <DMAWrapper> &dma); + + }; +} // namespace hCore + +#include <KernelKit/PCI/Dma.inl> diff --git a/KernelKit/PCI/Dma.inl b/KernelKit/PCI/Dma.inl new file mode 100644 index 00000000..c99d3ae3 --- /dev/null +++ b/KernelKit/PCI/Dma.inl @@ -0,0 +1,23 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +namespace hCore +{ + template<class T> + T* DMAWrapper::operator->() + { + return m_Address; + } + + template<class T> + T* DMAWrapper::Get(const UIntPtr offset) + { + return reinterpret_cast<T*>((UIntPtr) m_Address + offset); + } +} diff --git a/KernelKit/PCI/Express.hpp b/KernelKit/PCI/Express.hpp new file mode 100644 index 00000000..d53d636a --- /dev/null +++ b/KernelKit/PCI/Express.hpp @@ -0,0 +1,12 @@ +/* + * ======================================================== + * + * hCore + * Copyright XPX Corp, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/Defines.hpp>
\ No newline at end of file diff --git a/KernelKit/PCI/IO.hpp b/KernelKit/PCI/IO.hpp new file mode 100644 index 00000000..95f8f9db --- /dev/null +++ b/KernelKit/PCI/IO.hpp @@ -0,0 +1,77 @@ +/* + * ======================================================== + * + * hCore + * Copyright XPX Corp, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/Defines.hpp> + +#include <ArchKit/Arch.hpp> +#include <NewKit/Array.hpp> +#include <NewKit/Ref.hpp> + +namespace hCore +{ +template<SizeT Sz> +class IOArray final +{ + public: + IOArray() = delete; + + IOArray(nullPtr) = delete; + + explicit IOArray(Array <UShort, Sz> &ports) : m_Ports(ports) {} + ~IOArray() {} + + IOArray &operator=(const IOArray &) = default; + + IOArray(const IOArray &) = default; + + operator bool() { + return !m_Ports.Empty(); + } + + public: + template<typename T> + T In(SizeT index) { + switch (sizeof(T)) { +#ifdef __x86_64__ + case 4: + return HAL::in32(m_Ports[index].Leak()); + case 2: + return HAL::in16(m_Ports[index].Leak()); + case 1: + return HAL::in8(m_Ports[index].Leak()); +#endif + default: + return 0xFFFF; + } + } + + template<typename T> + void Out(SizeT index, T value) { + switch (sizeof(T)) { +#ifdef __x86_64__ + case 4: + HAL::out32(m_Ports[index].Leak(), value); + case 2: + HAL::out16(m_Ports[index].Leak(), value); + case 1: + HAL::out8(m_Ports[index].Leak(), value); +#endif + default: + break; + } + } + + private: + Array <UShort, Sz> m_Ports; +}; + +using IOArray16 = IOArray<16>; +} // namespace hCore diff --git a/KernelKit/PCI/Iterator.hpp b/KernelKit/PCI/Iterator.hpp new file mode 100644 index 00000000..70fbe59a --- /dev/null +++ b/KernelKit/PCI/Iterator.hpp @@ -0,0 +1,36 @@ +#ifndef __PCI_ITERATOR_HPP__ +#define __PCI_ITERATOR_HPP__ + +#include <KernelKit/PCI/Database.hpp> +#include <KernelKit/PCI/Device.hpp> +#include <NewKit/Array.hpp> +#include <NewKit/Defines.hpp> +#include <NewKit/Ref.hpp> + +#define ME_BUS_COUNT (256) +#define ME_DEVICE_COUNT (33) +#define ME_FUNCTION_COUNT (8) + +namespace hCore::PCI { + class Iterator final { + public: + Iterator() = delete; + + public: + explicit Iterator(const Types::PciDeviceKind &deviceType); + + Iterator &operator=(const Iterator &) = default; + + Iterator(const Iterator &) = default; + + ~Iterator(); + + public: + Ref<PCI::Device> operator[](const Size &sz); + + private: + Array<PCI::Device, ME_BUS_COUNT> m_Devices; + }; +} // namespace hCore::PCI + +#endif // __PCI_ITERATOR_HPP__ diff --git a/KernelKit/PCI/PCI.hpp b/KernelKit/PCI/PCI.hpp new file mode 100644 index 00000000..c5533684 --- /dev/null +++ b/KernelKit/PCI/PCI.hpp @@ -0,0 +1,56 @@ +/* + * ======================================================== + * + * hCore + * Copyright XPX Corp, all rights reserved. + * + * ======================================================== + */ +#pragma once + +#include <NewKit/Defines.hpp> + +#define PCI_CONFIG_ADDRESS (0xCF8) +#define PCI_CONFIG_DATA (0xCFC) + +#define PCI_DEVICE_COUNT (32) +#define PCI_FUNC_COUNT (8) +#define PCI_BUS_COUNT (255) + +namespace hCore::PCI { +// model + struct DeviceHeader { + UInt16 VendorId; + UInt16 DeviceId; + UInt8 Command; + UInt8 Status; + UInt8 RevisionId; + UInt8 ProgIf; + UInt8 SubClass; + UInt8 Class; + UInt8 CacheLineSz; + UInt8 LatencyTimer; + UInt8 HeaderType; + UInt8 Bist; + UInt8 Bus; + UInt8 Device; + UInt8 Function; + }; + + namespace Detail { + class BAR { + public: + UIntPtr BAR; + SizeT Size; + }; + } // namespace Detail + + class BAR { + public: + Detail::BAR BAR1; + Detail::BAR BAR2; + Detail::BAR BAR3; + Detail::BAR BAR4; + Detail::BAR BAR5; + }; +} // namespace hCore::PCI diff --git a/KernelKit/PEF.hpp b/KernelKit/PEF.hpp new file mode 100644 index 00000000..38418286 --- /dev/null +++ b/KernelKit/PEF.hpp @@ -0,0 +1,94 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#ifndef _INC_LOADER_PEF_HPP +#define _INC_LOADER_PEF_HPP + +#include <NewKit/Defines.hpp> +#include <KernelKit/Loader.hpp> +#include <CompilerKit/Compiler.hpp> + +#define kPefMagic "PEF" +#define kPefMagicFat "FEP" + +#define kPefMagicLen 3 + +#define kPefVersion 1 +#define kPefNameLen 64 + +// @brief Preferred Executable Format, a format designed for any computer. + +namespace hCore +{ + enum + { + kPefArchIntel86S, + kPefArchAMD64, + kPefArchRISCV, + kPefArchARC, /* Advanced RISC architecture. */ + kPefArchPower, + kPefArchInvalid = 0xFF, + }; + + enum + { + kPefKindExec = 1, /* .exe */ + kPefKindSharedObject = 2, /* .lib */ + kPefKindObject = 4, /* .obj */ + kPefKindDebug = 5, /* .debug */ + }; + + typedef struct PEFContainer final + { + Char Magic[kPefMagicLen]; + UInt32 Linker; + UInt32 Version; + UInt32 Kind; + UInt32 Abi; + UInt32 Cpu; + UInt32 SubCpu; /* Cpu specific information */ + UIntPtr Start; + SizeT HdrSz; /* Size of header */ + SizeT Count; /* container header count */ + } __attribute__((packed)) PEFContainer; + + /* First PEFCommandHeader starts after PEFContainer */ + /* Last container is __exec_end */ + + /* PEF executable section and commands. */ + + typedef struct PEFCommandHeader final + { + Char Name[kPefNameLen]; /* container name */ + UInt32 Flags; /* container flags */ + UInt16 Kind; /* container kind */ + UIntPtr Offset; /* content offset */ + SizeT Size; /* content Size */ + } __attribute__((packed)) PEFCommandHeader; + + enum + { + kPefCode = 0xC, + kPefData = 0xD, + kPefZero = 0xE, + kPefLinkerID = 0x1, + }; +} + +#define kPefExt ".o" +#define kPefDylibExt ".so" +#define kPefObjectExt ".o" +#define kPefDebugExt ".dbg" + +// hCore System Binary Interface. +#define kPefAbi (0xDEAD2) + +#define kPefStart "__start" + +#endif /* ifndef _INC_LOADER_PEF_HPP */ diff --git a/KernelKit/PermissionSelector.hxx b/KernelKit/PermissionSelector.hxx new file mode 100644 index 00000000..47ae8282 --- /dev/null +++ b/KernelKit/PermissionSelector.hxx @@ -0,0 +1,60 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#ifndef _INC_PERMISSION_SEL_HPP +#define _INC_PERMISSION_SEL_HPP + +#include <CompilerKit/Compiler.hpp> +#include <NewKit/Defines.hpp> + +// kernel mode user. +#define kMachineUser "machine" + +// user mode users. +#define kSuperUser "super" +#define kGuestUser "guest" + +// hash 'user@host:password' -> base64 encoded data +// use this data to then fetch specific data. + +namespace hCore +{ + enum class RingKind + { + kRingUser = 3, + kRingDriver = 2, + kRingKernel = 0, + kUnknown = -1, + }; + + class PermissionSelector final + { + private: + explicit PermissionSelector(const Int32& sel); + explicit PermissionSelector(const RingKind& kind); + + ~PermissionSelector(); + + public: + HCORE_COPY_DEFAULT(PermissionSelector) + + public: + bool operator==(const PermissionSelector& lhs); + bool operator!=(const PermissionSelector& lhs); + + public: + const RingKind& Ring() noexcept; + + private: + RingKind fRing; + + }; +} + +#endif /* ifndef _INC_PERMISSION_SEL_HPP */ diff --git a/KernelKit/ProcessManager.hpp b/KernelKit/ProcessManager.hpp new file mode 100644 index 00000000..3e1799d6 --- /dev/null +++ b/KernelKit/ProcessManager.hpp @@ -0,0 +1,223 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <KernelKit/PermissionSelector.hxx> +#include <KernelKit/FileManager.hpp> +#include <NewKit/MutableArray.hpp> +#include <NewKit/LockDelegate.hpp> +#include <ArchKit/Arch.hpp> +#include <NewKit/Heap.hpp> + +#define kMinMicroTime AffinityKind::kStandard + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace hCore +{ + //! @brief Process identifier. + typedef Int64 ProcessID; + + //! @brief Process name length. + inline constexpr SizeT kProcessLen = 256U; + + //! @brief Forward declaration. + class Process; + class ProcessManager; + class ProcessHelper; + + //! @brief Process status enum. + enum class ProcessStatus : Int32 + { + kStarting, + kRunning, + kKilled, + kFrozen, + kDead + }; + + //! @brief Affinity is the amount of nano-seconds this process is going + //! to run. + enum class AffinityKind : Int32 + { + kInvalid = 300, + kVeryHigh = 250, + kHigh = 200, + kStandard = 150, + kLowUsage = 100, + kVeryLowUsage = 50, + }; + + // operator overloading. + + inline bool operator<(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int < rhs_int; + } + + inline bool operator>(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int > rhs_int; + } + + inline bool operator<=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int <= rhs_int; + } + + inline bool operator>=(AffinityKind lhs, AffinityKind rhs) + { + Int32 lhs_int = static_cast<Int>(lhs); + Int32 rhs_int = static_cast<Int>(rhs); + + return lhs_int >= rhs_int; + } + + // end of operator overloading. + + using ProcessSubsystem = UInt32; + using ProcessTime = UInt64; + using PID = Int64; + + // for permission manager, tells where we run the code. + enum class ProcessSelector : Int + { + kRingUser, /* user ring (or ring 3 in x86) */ + kRingDriver, /* ring 2 in x86, hypervisor privileges in other archs */ + kRingKernel, /* machine privileges */ + }; + + // Helper types. + using ImagePtr = VoidPtr; + using HeapPtr = VoidPtr; + + // @brief Process header structure. + class Process final + { + public: + explicit Process(VoidPtr startImage = nullptr) : Image(startImage) { MUST_PASS(startImage); } + ~Process() = default; + + HCORE_COPY_DEFAULT(Process) + + private: + Char Name[kProcessLen] = { "hCore Process" }; + ProcessSubsystem SubSystem; + ProcessSelector Selector; + HAL::StackFrame* StackFrame{ nullptr }; + AffinityKind Affinity; + ProcessStatus Status; + + // Memory, images. + HeapPtr PoolCursor{ nullptr }; + ImagePtr Image{ nullptr }; + HeapPtr Pool{ nullptr }; + + // memory usage + SizeT UsedMemory{ 0 }; + SizeT FreeMemory{ 0 }; + + ProcessTime PTime; + PID ProcessId{ -1 }; + Int32 Ring{ 3 }; + + public: + //! @brief boolean operator, check status. + operator bool() { return Status != ProcessStatus::kDead; } + + //! @brief Crash program, exits with code ~0. + void Crash(); + + //! @brief Exits program. + void Exit(Int32 exit_code = 0); + + //! @brief TLS new + VoidPtr New(const SizeT& sz); + + //! @brief TLS delete. + Boolean Delete(VoidPtr ptr, const SizeT& sz); + + //! @brief Process name getter, example: "C RunTime" + const Char* GetName(); + + //! @brief Wakes up threads. + void Wake(const bool wakeup = false); + + public: + const ProcessSelector& GetSelector(); + const ProcessStatus& GetStatus(); + const AffinityKind& GetAffinity(); + + private: + friend ProcessManager; + friend ProcessHelper; + + }; + + using ProcessPtr = Process*; + + //! @brief Kernel scheduler.. + class ProcessManager final + { + private: + explicit ProcessManager() = default; + + public: + ~ProcessManager() = default; + + HCORE_COPY_DEFAULT(ProcessManager) + + operator bool() { return m_Headers.Count() > 0; } + bool operator!() { return m_Headers.Count() == 0; } + + bool Add(Ref<Process> &Header); + bool Remove(SizeT Header); + + Ref<Process>& GetCurrent(); + SizeT Run() noexcept; + + static Ref<ProcessManager> Shared(); + + private: + MutableArray<Ref<Process>> m_Headers; + Ref<Process> m_CurrentProcess; + + }; + + /* + * Just a helper class, which contains some utilities for the scheduler. + */ + + class ProcessHelper final + { + public: + static bool Switch(HAL::StackFrame* newStack, const PID& newPid); + static bool CanBeScheduled(Ref<Process>& process); + static PID& GetCurrentPID(); + static bool StartScheduling(); + + }; + + const Int32 &rt_get_exit_code() noexcept; +} // namespace hCore + +#include <KernelKit/ThreadLocalStorage.hxx> + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file diff --git a/KernelKit/SMPManager.hpp b/KernelKit/SMPManager.hpp new file mode 100644 index 00000000..4ebc944a --- /dev/null +++ b/KernelKit/SMPManager.hpp @@ -0,0 +1,113 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#ifndef _INC_SMP_MANAGER_HPP +#define _INC_SMP_MANAGER_HPP + +#include <CompilerKit/Compiler.hpp> +#include <ArchKit/Arch.hpp> +#include <NewKit/Ref.hpp> + +#define kMaxHarts 8 + +namespace hCore +{ + using ThreadID = UInt32; + + enum ThreadKind + { + kSystemReserved, // System reserved thread, well user can't use it + kStandard, // user thread, cannot be used by kernel + kFallback, // fallback thread, cannot be used by user if not clear or used by kernel. + kBoot, // The core we booted from, the mama. + }; + + /// + /// \name ProcessorCore + /// CPU core (PowerPC, Intel, or NewCPU) + /// + + class ProcessorCore final + { + public: + explicit ProcessorCore(); + ~ProcessorCore(); + + public: + HCORE_COPY_DEFAULT(ProcessorCore) + + public: + operator bool(); + + public: + void Wake(const bool wakeup = false) noexcept; + void Busy(const bool busy = false) noexcept; + + public: + bool Switch(HAL::StackFrame* stack); + bool IsWakeup() noexcept; + + public: + HAL::StackFrame* StackFrame() noexcept; + const ThreadKind& Kind() noexcept; + bool IsBusy() noexcept; + const ThreadID& ID() noexcept; + + private: + HAL::StackFrame* m_Stack; + ThreadKind m_Kind; + ThreadID m_ID; + bool m_Wakeup; + bool m_Busy; + Int64 m_PID; + + private: + friend class SMPManager; + + }; + + /// + /// \name ProcessorCore + /// + /// Multi processor manager to manage other cores and dispatch tasks. + /// + + class SMPManager final + { + private: + explicit SMPManager(); + + public: + ~SMPManager(); + + public: + HCORE_COPY_DEFAULT(SMPManager); + + public: + bool Switch(HAL::StackFrame* the); + HAL::StackFramePtr GetStack() noexcept; + + public: + Ref<ProcessorCore> operator[](const SizeT& idx); + bool operator!() noexcept; + operator bool() noexcept; + + public: + /// @brief Shared instance of the SMP Manager. + /// @return the reference to the smp manager. + static Ref<SMPManager> Shared(); + + private: + Array<ProcessorCore, kMaxHarts> m_ThreadList; + ThreadID m_CurrentThread; + + }; +} // namespace hCore + +#endif // !_INC_SMP_MANAGER_HPP diff --git a/KernelKit/Semaphore.hpp b/KernelKit/Semaphore.hpp new file mode 100644 index 00000000..03a724c8 --- /dev/null +++ b/KernelKit/Semaphore.hpp @@ -0,0 +1,46 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <NewKit/Defines.hpp> +#include <CompilerKit/Compiler.hpp> + +namespace hCore +{ + class Process; + + typedef Process* ProcessPtr; + + /// @brief Access control class, which locks a task until one is done. + class Semaphore final + { + public: + explicit Semaphore() = default; + ~Semaphore() = default; + + public: + bool IsLocked() const; + bool Unlock() noexcept; + + public: + void Sync() noexcept; + + public: + bool Lock(Process* process); + bool LockOrWait(Process* process, const Int64& seconds); + + public: + HCORE_COPY_DEFAULT(Semaphore); + + private: + ProcessPtr fLockingProcess{ nullptr }; + + }; +} diff --git a/KernelKit/SharedObjectCore.hxx b/KernelKit/SharedObjectCore.hxx new file mode 100644 index 00000000..51637192 --- /dev/null +++ b/KernelKit/SharedObjectCore.hxx @@ -0,0 +1,57 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#ifndef __SUPPORTKIT_SHARED_OBJECT_CORE_HXX__ +#define __SUPPORTKIT_SHARED_OBJECT_CORE_HXX__ + +#include <NewKit/Defines.hpp> +#include <KernelKit/Loader.hpp> + +namespace hCore +{ + class SharedObject final + { + public: + struct SharedObjectTraits final + { + VoidPtr fImageObject; + VoidPtr fImageEntrypointOffset; + }; + + public: + explicit SharedObject() = default; + ~SharedObject() = default; + + public: + HCORE_COPY_DEFAULT(SharedObject); + + private: + SharedObjectTraits* fMounted{ nullptr }; + + public: + SharedObjectTraits** GetAddressOf() { return &fMounted; } + SharedObjectTraits* Get() { return fMounted; } + + public: + void Mount(SharedObjectTraits* to_mount) { fMounted = to_mount; } + void Unmount() { if (fMounted) fMounted = nullptr; }; + + template <typename SymbolType> + SymbolType Load(const char* symbol_name); + + }; + + inline void hcore_pure_call(void) + { + // virtual placeholder. + return; + } +} + +#endif /* ifndef __SUPPORTKIT_SHARED_OBJECT_CORE_HXX__ */ diff --git a/KernelKit/ThreadLocalStorage.hxx b/KernelKit/ThreadLocalStorage.hxx new file mode 100644 index 00000000..c5030972 --- /dev/null +++ b/KernelKit/ThreadLocalStorage.hxx @@ -0,0 +1,37 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#ifndef _KERNELKIT_TLS_HPP +#define _KERNELKIT_TLS_HPP + +#include <NewKit/Defines.hpp> + +//! @brief TLS implementation in C++ + +#define kRTLMag0 'V' +#define kRTLMag1 'C' +#define kRTLMag2 'S' + +template <typename T> +T* hcore_tls_new_ptr(void); + +template <typename T> +bool hcore_tls_delete_ptr(T* ptr); + +template <typename T, typename... Args> +T* hcore_tls_new_class(Args&&... args); + +//! @brief Cookie Sanity check. +hCore::Boolean hcore_tls_check(hCore::VoidPtr ptr); + +typedef char rt_cookie_type[3]; + +#include "ThreadLocalStorage.inl" + +#endif /* ifndef _KERNELKIT_TLS_HPP */ diff --git a/KernelKit/ThreadLocalStorage.inl b/KernelKit/ThreadLocalStorage.inl new file mode 100644 index 00000000..c117dd4e --- /dev/null +++ b/KernelKit/ThreadLocalStorage.inl @@ -0,0 +1,50 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +//! @brief Allocates a pointer from the process's tls. + +template <typename T> +inline T* hcore_tls_new_ptr(void) +{ + using namespace hCore; + + auto ref_process = ProcessManager::Shared().Leak().GetCurrent(); + + T* pointer = (T*)ref_process.Leak().New(sizeof(T)); + return pointer; +} + +//! @brief TLS delete implementation. +template <typename T> +inline bool hcore_tls_delete_ptr(T* ptr) +{ + if (!ptr) + return false; + + using namespace hCore; + + auto ref_process = ProcessManager::Shared().Leak().GetCurrent(); + ptr->~T(); + + return ref_process.Leak().Delete(ptr, sizeof(T)); +} + +template <typename T, typename... Args> +T* hcore_tls_new_class(Args&&... args) +{ + T* ptr = hcore_tls_new_ptr<T>(); + + if (ptr) + { + *ptr = T(hCore::forward(args)...); + return ptr; + } + + return nullptr; +} diff --git a/KernelKit/Timer.hpp b/KernelKit/Timer.hpp new file mode 100644 index 00000000..81be74a0 --- /dev/null +++ b/KernelKit/Timer.hpp @@ -0,0 +1,69 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#pragma once + +#include <CompilerKit/Compiler.hpp> +#include <ArchKit/Arch.hpp> + +#include <NewKit/ErrorID.hpp> + +namespace hCore +{ + class ITimer; + class HardwareTimer; + + class ITimer + { + public: + ITimer() = default; + virtual ~ITimer() = default; + + public: + HCORE_COPY_DEFAULT(ITimer); + + public: + virtual Int32 Wait() { return ME_UNIMPLEMENTED; } + + }; + + class HardwareTimer final : public ITimer + { + public: + explicit HardwareTimer(Int64 seconds); + ~HardwareTimer() override; + + public: + HCORE_COPY_DEFAULT(HardwareTimer); + + public: + Int32 Wait() override; + + public: + IntPtr* fDigitalTimer{ nullptr }; + Int64 fWaitFor{ 0 }; + + }; + + inline Int64 Seconds(Int64 time) + { + if (time < 0) + return 0; + + return 1000 / time; + } + + inline Int64 Milliseconds(Int64 time) + { + if (time < 0) + return 0; + + return 1000 / Seconds(time); + } +} diff --git a/KernelKit/compile_flags.txt b/KernelKit/compile_flags.txt new file mode 100644 index 00000000..a37ae6bf --- /dev/null +++ b/KernelKit/compile_flags.txt @@ -0,0 +1,5 @@ +-nostdlib +-ffreestanding +-std=c++20 +-I./ +-I../ |
