diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-05-05 21:10:18 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-05-05 21:10:18 +0200 |
| commit | f95d8bf159d10b5a9521dcaa0bc37aa0e9dfc02b (patch) | |
| tree | bf8186f1a0521a64983bb0bca4f7b54883542195 /Private/KernelKit | |
| parent | 5a903c1d8f80ca8d7bc5fbea0aea710ce0133f9d (diff) | |
MHR-23: Add run_format.sh, kernel patches.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Private/KernelKit')
30 files changed, 1903 insertions, 1696 deletions
diff --git a/Private/KernelKit/CodeManager.hpp b/Private/KernelKit/CodeManager.hpp index a6984cfc..8864130a 100644 --- a/Private/KernelKit/CodeManager.hpp +++ b/Private/KernelKit/CodeManager.hpp @@ -20,13 +20,14 @@ #define kUPPNameLen 64 -namespace NewOS { -/// @brief Main process entrypoint. -typedef void (*MainKind)(void); - -/// @brief Executes a new process from a function. kernel code only. -/// @note This sets up a new stack, anything on the main function that calls the kernel will not be accessible. -/// @param main the start of the process. -/// @return if the process was started or not. -bool execute_from_image(MainKind main, const char* processName); +namespace NewOS +{ + /// @brief Main process entrypoint. + typedef void (*MainKind)(void); + + /// @brief Executes a new process from a function. kernel code only. + /// @note This sets up a new stack, anything on the main function that calls the kernel will not be accessible. + /// @param main the start of the process. + /// @return if the process was started or not. + bool execute_from_image(MainKind main, const char* processName); } // namespace NewOS
\ No newline at end of file diff --git a/Private/KernelKit/DebugOutput.hpp b/Private/KernelKit/DebugOutput.hpp index 69455fc2..52677d59 100644 --- a/Private/KernelKit/DebugOutput.hpp +++ b/Private/KernelKit/DebugOutput.hpp @@ -21,138 +21,164 @@ #define kDebugMag3 'G' #define kDebugSourceFile 0 -#define kDebugLine 33 -#define kDebugTeam 43 -#define kDebugEOP 49 - -namespace NewOS { -// @brief Emulates a VT100 terminal. -class TerminalDevice final : public DeviceInterface<const Char *> { - public: - TerminalDevice(void (*print)(const Char *), void (*get)(const Char *)) - : DeviceInterface<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"); } - - NEWOS_COPY_DEFAULT(TerminalDevice); - - static TerminalDevice& Shared() noexcept; -}; - -inline TerminalDevice& end_line() { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - selfTerm << "\r"; - return selfTerm; -} - -inline TerminalDevice& carriage_return() { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - selfTerm << "\r"; - return selfTerm; -} - -inline TerminalDevice& tabulate() { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - selfTerm << "\t"; - return selfTerm; -} - -/// @brief emulate a terminal bell, like the VT100 does. -inline TerminalDevice& bell() { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - selfTerm << "\a"; - return selfTerm; -} - -namespace Detail { -inline TerminalDevice _write_number(const Long &x, TerminalDevice& term) { - UInt64 y = (x > 0 ? x : -x) / 10; - UInt64 h = (x > 0 ? x : -x) % 10; - - if (y) _write_number(y, term); - - /* fail if the number is not base-10 */ - if (h > 9) { - _write_number('?', term); - return term; - } - - if (y < 0) y = -y; - - const char NUMBERS[11] = "0123456789"; - - Char buf[2]; - buf[0] = NUMBERS[h]; - buf[1] = 0; - - term << buf; - return term; -} - -inline TerminalDevice _write_number_hex(const Long &x, TerminalDevice& term) { - UInt64 y = (x > 0 ? x : -x) / 16; - UInt64 h = (x > 0 ? x : -x) % 16; - - if (y) _write_number_hex(y, term); - - /* fail if the hex number is not base-16 */ - if (h > 15) { - _write_number_hex('?', term); - return term; - } - - if (y < 0) y = -y; - - const char NUMBERS[17] = "0123456789ABCDEF"; - - Char buf[2]; - buf[0] = NUMBERS[h]; - buf[1] = 0; - - term << buf; - return term; -} -} // namespace Detail - -inline TerminalDevice& hex_number(const Long &x) { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - - selfTerm << "0x"; - Detail::_write_number_hex(x, selfTerm); - - return selfTerm; -} - -inline TerminalDevice& number(const Long &x) { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - - Detail::_write_number(x, selfTerm); - - return selfTerm; -} - -inline TerminalDevice& get_console_in(Char* buf) { - TerminalDevice& selfTerm = TerminalDevice::Shared(); - selfTerm >> buf; - return selfTerm; -} - -typedef Char rt_debug_type[255]; - -class DebuggerPortHeader final { - public: - Int16 fPort[kDebugMaxPorts]; - Int16 fBoundCnt; -}; -} // namespace NewOS +#define kDebugLine 33 +#define kDebugTeam 43 +#define kDebugEOP 49 + +namespace NewOS +{ + // @brief Emulates a VT100 terminal. + class TerminalDevice final : public DeviceInterface<const Char*> + { + public: + TerminalDevice(void (*print)(const Char*), void (*get)(const Char*)) + : DeviceInterface<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"); + } + + NEWOS_COPY_DEFAULT(TerminalDevice); + + static TerminalDevice& Shared() noexcept; + }; + + inline TerminalDevice& end_line() + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + selfTerm << "\r"; + return selfTerm; + } + + inline TerminalDevice& carriage_return() + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + selfTerm << "\r"; + return selfTerm; + } + + inline TerminalDevice& tabulate() + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + selfTerm << "\t"; + return selfTerm; + } + + /// @brief emulate a terminal bell, like the VT100 does. + inline TerminalDevice& bell() + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + selfTerm << "\a"; + return selfTerm; + } + + namespace Detail + { + inline TerminalDevice _write_number(const Long& x, TerminalDevice& term) + { + UInt64 y = (x > 0 ? x : -x) / 10; + UInt64 h = (x > 0 ? x : -x) % 10; + + if (y) + _write_number(y, term); + + /* fail if the number is not base-10 */ + if (h > 9) + { + _write_number('?', term); + return term; + } + + if (y < 0) + y = -y; + + const char NUMBERS[11] = "0123456789"; + + Char buf[2]; + buf[0] = NUMBERS[h]; + buf[1] = 0; + + term << buf; + return term; + } + + inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term) + { + UInt64 y = (x > 0 ? x : -x) / 16; + UInt64 h = (x > 0 ? x : -x) % 16; + + if (y) + _write_number_hex(y, term); + + /* fail if the hex number is not base-16 */ + if (h > 15) + { + _write_number_hex('?', term); + return term; + } + + if (y < 0) + y = -y; + + const char NUMBERS[17] = "0123456789ABCDEF"; + + Char buf[2]; + buf[0] = NUMBERS[h]; + buf[1] = 0; + + term << buf; + return term; + } + } // namespace Detail + + inline TerminalDevice& hex_number(const Long& x) + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + + selfTerm << "0x"; + Detail::_write_number_hex(x, selfTerm); + + return selfTerm; + } + + inline TerminalDevice& number(const Long& x) + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + + Detail::_write_number(x, selfTerm); + + return selfTerm; + } + + inline TerminalDevice& get_console_in(Char* buf) + { + TerminalDevice& selfTerm = TerminalDevice::Shared(); + selfTerm >> buf; + return selfTerm; + } + + typedef Char rt_debug_type[255]; + + class DebuggerPortHeader final + { + public: + Int16 fPort[kDebugMaxPorts]; + Int16 fBoundCnt; + }; +} // namespace NewOS #ifdef kcout #undef kcout -#endif // ifdef kcout +#endif // ifdef kcout #define kcout TerminalDevice::Shared() -#define endl end_line() +#define endl end_line() diff --git a/Private/KernelKit/DeviceManager.hpp b/Private/KernelKit/DeviceManager.hpp index 490ebc71..e9baa194 100644 --- a/Private/KernelKit/DeviceManager.hpp +++ b/Private/KernelKit/DeviceManager.hpp @@ -26,85 +26,106 @@ // Last Rev // Wed, Apr 3, 2024 9:09:41 AM -namespace NewOS { -template <typename T> -class DeviceInterface; - -template <typename T> -class DeviceInterface { - public: - explicit DeviceInterface(void (*Out)(T), void (*In)(T)) - : fOut(Out), fIn(In) {} - - virtual ~DeviceInterface() = default; - - public: - DeviceInterface &operator=(const DeviceInterface<T> &) = default; - DeviceInterface(const DeviceInterface<T> &) = default; - - public: - virtual DeviceInterface<T> &operator<<(T Data) { - fOut(Data); - return *this; - } - - virtual DeviceInterface<T> &operator>>(T Data) { - fIn(Data); - return *this; - } - - virtual const char *Name() const { return "DeviceInterface"; } - - operator bool() { return fOut && fIn; } - bool operator!() { return !fOut && !fIn; } - - private: - void (*fOut)(T Data); - void (*fIn)(T Data); -}; - -/// -/// @brief Input Output Buffer -/// Used mainly to communicate between hardware. -/// -template <typename T> -class IOBuf final { - public: - explicit IOBuf(T Dat) : fData(Dat) { - // at least pass something valid when instancating this struct. - MUST_PASS(Dat); - } - - IOBuf &operator=(const IOBuf<T> &) = default; - IOBuf(const IOBuf<T> &) = default; - - ~IOBuf() = default; - - public: - template <typename R> - R operator->() const { - return fData; - } - - template <typename R> - R &operator[](Size index) const { - return fData[index]; - } - - private: - T fData; -}; - -///! @brief Device enum types. -enum { - kDeviceTypeIDE, - kDeviceTypeEthernet, - kDeviceTypeWiFi, - kDeviceTypeRS232, - kDeviceTypeSCSI, - kDeviceTypeSHCI, - kDeviceTypeUSB, - kDeviceTypeMedia, - kDeviceTypeCount, -}; -} // namespace NewOS +namespace NewOS +{ + template <typename T> + class DeviceInterface; + + template <typename T> + class DeviceInterface + { + public: + explicit DeviceInterface(void (*Out)(T), void (*In)(T)) + : fOut(Out), fIn(In) + { + } + + virtual ~DeviceInterface() = default; + + public: + DeviceInterface& operator=(const DeviceInterface<T>&) = default; + DeviceInterface(const DeviceInterface<T>&) = default; + + public: + virtual DeviceInterface<T>& operator<<(T Data) + { + fOut(Data); + return *this; + } + + virtual DeviceInterface<T>& operator>>(T Data) + { + fIn(Data); + return *this; + } + + virtual const char* Name() const + { + return "DeviceInterface"; + } + + operator bool() + { + return fOut && fIn; + } + bool operator!() + { + return !fOut && !fIn; + } + + private: + void (*fOut)(T Data); + void (*fIn)(T Data); + }; + + /// + /// @brief Input Output Buffer + /// Used mainly to communicate between hardware. + /// + template <typename T> + class IOBuf final + { + public: + explicit IOBuf(T Dat) + : fData(Dat) + { + // at least pass something valid when instancating this struct. + MUST_PASS(Dat); + } + + IOBuf& operator=(const IOBuf<T>&) = default; + IOBuf(const IOBuf<T>&) = default; + + ~IOBuf() = default; + + public: + template <typename R> + R operator->() const + { + return fData; + } + + template <typename R> + R& operator[](Size index) const + { + return fData[index]; + } + + private: + T fData; + }; + + ///! @brief Device enum types. + enum + { + kDeviceTypeIDE, + kDeviceTypeEthernet, + kDeviceTypeWiFi, + kDeviceTypeRS232, + kDeviceTypeSCSI, + kDeviceTypeSHCI, + kDeviceTypeUSB, + kDeviceTypeMedia, + kDeviceTypeCount, + }; +} // namespace NewOS diff --git a/Private/KernelKit/DriveManager.hxx b/Private/KernelKit/DriveManager.hxx index 0fd8a0d4..4f8bdd1d 100644 --- a/Private/KernelKit/DriveManager.hxx +++ b/Private/KernelKit/DriveManager.hxx @@ -15,113 +15,132 @@ #include <NewKit/String.hpp> #define kDriveInvalidID -1 -#define kDriveNameLen 32 - -namespace NewOS { -enum { - kInvalidDrive = -1, - kBlockDevice = 0xAD, - kMassStorage = 0xDA, - kFloppyDisc = 0xCD, - kOpticalDisc = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray - /// combine with below. - kReadOnly = 0x10, // Read only drive - kEPMDrive = 0x11, // Explicit Partition Map. - kEPTDrive = 0x12, // ESP w/ EPM partition. - kMBRDrive = 0x13, // IBM PC classic partition scheme - kDriveCnt = 9, -}; - -typedef Int64 rt_drive_id_type; - -/// @brief Media drive trait type. -struct DriveTrait final { - Char fName[kDriveNameLen]; // /System, /Boot, //./Devices/USB... - Int32 fKind; // fMassStorage, fFloppy, fOpticalDisc. - rt_drive_id_type fId; // Drive id. - Int32 fFlags; // fReadOnly, fXPMDrive, fXPTDrive - - /// @brief Packet drive (StorageKit compilant.) - struct DrivePacket final { - VoidPtr fPacketContent; //! packet body. - Char fPacketMime[kDriveNameLen]; //! identify what we're sending. - SizeT fPacketSize; //! packet size - UInt32 fPacketCRC32; //! sanity crc, in case if good is set to false - Boolean fPacketGood; - Lba fLba; - } fPacket; - - Void (*fInput)(DrivePacket* packetPtr); - Void (*fOutput)(DrivePacket* packetPtr); - Void (*fVerify)(DrivePacket* packetPtr); - const Char* (*fDriveKind)(Void); -}; - -///! drive as a device. -typedef DriveTrait* DriveTraitPtr; - -/** +#define kDriveNameLen 32 + +namespace NewOS +{ + enum + { + kInvalidDrive = -1, + kBlockDevice = 0xAD, + kMassStorage = 0xDA, + kFloppyDisc = 0xCD, + kOpticalDisc = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray + /// combine with below. + kReadOnly = 0x10, // Read only drive + kEPMDrive = 0x11, // Explicit Partition Map. + kEPTDrive = 0x12, // ESP w/ EPM partition. + kMBRDrive = 0x13, // IBM PC classic partition scheme + kDriveCnt = 9, + }; + + typedef Int64 rt_drive_id_type; + + /// @brief Media drive trait type. + struct DriveTrait final + { + Char fName[kDriveNameLen]; // /System, /Boot, //./Devices/USB... + Int32 fKind; // fMassStorage, fFloppy, fOpticalDisc. + rt_drive_id_type fId; // Drive id. + Int32 fFlags; // fReadOnly, fXPMDrive, fXPTDrive + + /// @brief Packet drive (StorageKit compilant.) + struct DrivePacket final + { + VoidPtr fPacketContent; //! packet body. + Char fPacketMime[kDriveNameLen]; //! identify what we're sending. + SizeT fPacketSize; //! packet size + UInt32 fPacketCRC32; //! sanity crc, in case if good is set to false + Boolean fPacketGood; + Lba fLba; + } fPacket; + + Void (*fInput)(DrivePacket* packetPtr); + Void (*fOutput)(DrivePacket* packetPtr); + Void (*fVerify)(DrivePacket* packetPtr); + const Char* (*fDriveKind)(Void); + }; + + ///! drive as a device. + typedef DriveTrait* DriveTraitPtr; + + /** * @brief Mounted drives interface. * @note This class has all of it's drive set to nullptr, allocate them using * GetAddressOf(index). */ -class MountpointInterface final { - public: - explicit MountpointInterface() = default; - ~MountpointInterface() = default; - - NEWOS_COPY_DEFAULT(MountpointInterface); - - public: - DriveTrait& A() { return mA; } - DriveTrait& B() { return mB; } - DriveTrait& C() { return mC; } - DriveTrait& D() { return mD; } - - DriveTraitPtr GetAddressOf(Int32 index) { - DbgLastError() = kErrorSuccess; - - switch (index) { - case 0: - return &mA; - case 1: - return &mB; - case 2: - return &mC; - case 3: - return &mD; - default: { - DbgLastError() = kErrorNoSuchDisk; - kcout << "New OS: No such disk.\n"; - - break; - } - } - - return nullptr; - } - - private: - DriveTrait mA, mB, mC, mD; -}; - -/// @brief Unimplemented drive. -/// @param pckt -/// @return -Void ke_drv_unimplemented(DriveTrait::DrivePacket* pckt); - -/// @brief Gets the drive kind (ATA, SCSI, AHCI...) -/// @param -/// @return -const Char* ke_drive_kind(Void); - -/// @brief Makes a new drive. -/// @return the new drive. -DriveTrait construct_drive(void) noexcept; - -/// @brief Fetches the main drive. -/// @return the new drive. -DriveTrait construct_main_drive(void) noexcept; -} // namespace NewOS + class MountpointInterface final + { + public: + explicit MountpointInterface() = default; + ~MountpointInterface() = default; + + NEWOS_COPY_DEFAULT(MountpointInterface); + + public: + DriveTrait& A() + { + return mA; + } + DriveTrait& B() + { + return mB; + } + DriveTrait& C() + { + return mC; + } + DriveTrait& D() + { + return mD; + } + + DriveTraitPtr GetAddressOf(Int32 index) + { + DbgLastError() = kErrorSuccess; + + switch (index) + { + case 0: + return &mA; + case 1: + return &mB; + case 2: + return &mC; + case 3: + return &mD; + default: { + DbgLastError() = kErrorNoSuchDisk; + kcout << "New OS: No such disk.\n"; + + break; + } + } + + return nullptr; + } + + private: + DriveTrait mA, mB, mC, mD; + }; + + /// @brief Unimplemented drive. + /// @param pckt + /// @return + Void ke_drv_unimplemented(DriveTrait::DrivePacket* pckt); + + /// @brief Gets the drive kind (ATA, SCSI, AHCI...) + /// @param + /// @return + const Char* ke_drive_kind(Void); + + /// @brief Makes a new drive. + /// @return the new drive. + DriveTrait construct_drive(void) noexcept; + + /// @brief Fetches the main drive. + /// @return the new drive. + DriveTrait construct_main_drive(void) noexcept; +} // namespace NewOS #endif /* ifndef __DRIVE_MANAGER__ */ diff --git a/Private/KernelKit/FileManager.hpp b/Private/KernelKit/FileManager.hpp index 51bfb13c..142e1afd 100644 --- a/Private/KernelKit/FileManager.hpp +++ b/Private/KernelKit/FileManager.hpp @@ -16,7 +16,7 @@ #ifdef __FSKIT_NEWFS__ #include <FSKit/NewFS.hxx> -#endif // __FSKIT_NEWFS__ +#endif // __FSKIT_NEWFS__ #include <CompilerKit/CompilerKit.hxx> #include <HintKit/CompilerHint.hxx> @@ -27,207 +27,227 @@ /// @brief Filesystem abstraction manager. /// Works like the VFS or IFS. -#define kBootFolder "/Boot" -#define kBinFolder "/Applications" +#define kBootFolder "/Boot" +#define kBinFolder "/Applications" #define kShLibsFolder "/Library" -#define kMountFolder "/Mount" +#define kMountFolder "/Mount" /// refer to first enum. -#define kFileOpsCount 4 +#define kFileOpsCount 4 #define kFileMimeGeneric "application-type/*" -namespace NewOS { -enum { - kFileWriteAll = 100, - kFileReadAll = 101, - kFileReadChunk = 102, - kFileWriteChunk = 103, - kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, -}; +namespace NewOS +{ + enum + { + kFileWriteAll = 100, + kFileReadAll = 101, + kFileReadChunk = 102, + kFileWriteChunk = 103, + kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1, + }; -typedef VoidPtr NodePtr; + typedef VoidPtr NodePtr; -/** + /** @brief Filesystem Manager Interface class @brief Used to provide common I/O for a specific filesystem. */ -class FilesystemManagerInterface { - public: - FilesystemManagerInterface() = default; - virtual ~FilesystemManagerInterface() = default; + class FilesystemManagerInterface + { + public: + FilesystemManagerInterface() = default; + virtual ~FilesystemManagerInterface() = default; - public: - NEWOS_COPY_DEFAULT(FilesystemManagerInterface); + public: + NEWOS_COPY_DEFAULT(FilesystemManagerInterface); - public: - /// @brief Mounts a new filesystem into an active state. - /// @param interface the filesystem interface - /// @return - static bool Mount(FilesystemManagerInterface *interface); + public: + /// @brief Mounts a new filesystem into an active state. + /// @param interface the filesystem interface + /// @return + static bool Mount(FilesystemManagerInterface* interface); - /// @brief Unmounts the active filesystem - /// @return - static FilesystemManagerInterface *Unmount(); + /// @brief Unmounts the active filesystem + /// @return + static FilesystemManagerInterface* Unmount(); - /// @brief Getter, gets the active filesystem. - /// @return - static FilesystemManagerInterface *GetMounted(); + /// @brief Getter, gets the active filesystem. + /// @return + static FilesystemManagerInterface* GetMounted(); - public: - virtual NodePtr Create(_Input const char *path) = 0; - virtual NodePtr CreateAlias(_Input const char *path) = 0; - virtual NodePtr CreateDirectory(_Input const char *path) = 0; + public: + virtual NodePtr Create(_Input const char* path) = 0; + virtual NodePtr CreateAlias(_Input const char* path) = 0; + virtual NodePtr CreateDirectory(_Input const char* path) = 0; - public: - virtual bool Remove(_Input const char *path) = 0; + public: + virtual bool Remove(_Input const char* path) = 0; - public: - virtual NodePtr Open(_Input const char *path, _Input const char *r) = 0; + public: + virtual NodePtr Open(_Input const char* path, _Input const char* r) = 0; - public: - virtual Void Write(_Input NodePtr node, _Input VoidPtr data, - _Input Int32 flags, _Input SizeT size) = 0; - virtual _Output VoidPtr Read(_Input NodePtr node, _Input Int32 flags, - _Input SizeT sz) = 0; + public: + virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) = 0; + virtual _Output VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) = 0; - public: - virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0; + public: + virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0; - public: - virtual SizeT Tell(_Input NodePtr node) = 0; - virtual bool Rewind(_Input NodePtr node) = 0; -}; + public: + virtual SizeT Tell(_Input NodePtr node) = 0; + virtual bool Rewind(_Input NodePtr node) = 0; + }; /** @brief invalid position. (n-pos) */ #define kNPos (SizeT)(-1); #ifdef __FSKIT_NEWFS__ -/** + /** * @brief Based of FilesystemManagerInterface, takes care of managing NewFS * disks. */ -class NewFilesystemManager final : public FilesystemManagerInterface { - public: - explicit NewFilesystemManager(); - ~NewFilesystemManager() override; - - public: - NEWOS_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 *path) override; - NodePtr Open(const char *path, const char *r) override; - Void Write(NodePtr node, VoidPtr data, Int32 flags, SizeT sz) override; - VoidPtr Read(NodePtr node, Int32 flags, SizeT sz) override; - bool Seek(NodePtr node, SizeT off); - SizeT Tell(NodePtr node) override; - bool Rewind(NodePtr node) override; - - NewFSParser* GetImpl() noexcept; - - private: - NewFSParser *fImpl{nullptr}; -}; - -#endif // ifdef __FSKIT_NEWFS__ - -/** + class NewFilesystemManager final : public FilesystemManagerInterface + { + public: + explicit NewFilesystemManager(); + ~NewFilesystemManager() override; + + public: + NEWOS_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* path) override; + NodePtr Open(const char* path, const char* r) override; + Void Write(NodePtr node, VoidPtr data, Int32 flags, SizeT sz) override; + VoidPtr Read(NodePtr node, Int32 flags, SizeT sz) override; + bool Seek(NodePtr node, SizeT off); + SizeT Tell(NodePtr node) override; + bool Rewind(NodePtr node) override; + + NewFSParser* GetImpl() noexcept; + + private: + NewFSParser* fImpl{nullptr}; + }; + +#endif // ifdef __FSKIT_NEWFS__ + + /** * Usable FileStream * @tparam Encoding file encoding (char, wchar_t...) * @tparam FSClass Filesystem contract who takes care of it. */ -template <typename Encoding = char, - typename FSClass = FilesystemManagerInterface> -class FileStream final { - public: - explicit FileStream(const Encoding *path, const Encoding *restrict_type); - ~FileStream(); - - public: - FileStream &operator=(const FileStream &); - FileStream(const FileStream &); - - public: - ErrorOr<Int64> WriteAll(const VoidPtr data) noexcept { - if (data == nullptr) return ErrorOr<Int64>(H_INVALID_DATA); - - auto man = FSClass::GetMounted(); - - if (man) { - man->Write(fFile, data, kFileWriteAll); - return ErrorOr<Int64>(0); - } - - return ErrorOr<Int64>(H_INVALID_DATA); - } - - VoidPtr Read() 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); - } - } - - /// @brief Leak node pointer. - /// @return The node pointer. - NodePtr Leak() { return fFile; } - - public: - char *MIME() noexcept { return const_cast<char *>(fMime); } - - private: - NodePtr fFile; - const Char *fMime{kFileMimeGeneric}; -}; - -#define kRestrictR "r" + template <typename Encoding = char, + typename FSClass = FilesystemManagerInterface> + class FileStream final + { + public: + explicit FileStream(const Encoding* path, const Encoding* restrict_type); + ~FileStream(); + + public: + FileStream& operator=(const FileStream&); + FileStream(const FileStream&); + + public: + ErrorOr<Int64> WriteAll(const VoidPtr data) noexcept + { + if (data == nullptr) + return ErrorOr<Int64>(H_INVALID_DATA); + + auto man = FSClass::GetMounted(); + + if (man) + { + man->Write(fFile, data, kFileWriteAll); + return ErrorOr<Int64>(0); + } + + return ErrorOr<Int64>(H_INVALID_DATA); + } + + VoidPtr Read() 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); + } + } + + /// @brief Leak node pointer. + /// @return The node pointer. + NodePtr Leak() + { + return fFile; + } + + public: + char* MIME() noexcept + { + return const_cast<char*>(fMime); + } + + private: + NodePtr fFile; + const Char* fMime{kFileMimeGeneric}; + }; + +#define kRestrictR "r" #define kRestrictRB "rb" -#define kRestrictW "w" +#define kRestrictW "w" #define kRestrictRW "rw" -using FileStreamUTF8 = FileStream<Char>; -using FileStreamUTF16 = FileStream<WideChar>; + using FileStreamUTF8 = FileStream<Char>; + using FileStreamUTF16 = FileStream<WideChar>; -typedef UInt64 CursorType; + typedef UInt64 CursorType; -template <typename Encoding, typename Class> -FileStream<Encoding, Class>::FileStream(const Encoding *path, - const Encoding *restrict_type) - : fFile(Class::GetMounted()->Open(path, restrict_type)) {} + template <typename Encoding, typename Class> + FileStream<Encoding, Class>::FileStream(const Encoding* path, + const Encoding* restrict_type) + : fFile(Class::GetMounted()->Open(path, restrict_type)) + { + } -template <typename Encoding, typename Class> -FileStream<Encoding, Class>::~FileStream() = default; -} // namespace NewOS + template <typename Encoding, typename Class> + FileStream<Encoding, Class>::~FileStream() = default; +} // namespace NewOS #define node_cast(PTR) reinterpret_cast<NewOS::NodePtr>(PTR) diff --git a/Private/KernelKit/Framebuffer.hpp b/Private/KernelKit/Framebuffer.hpp index ada00447..7d8257cb 100644 --- a/Private/KernelKit/Framebuffer.hpp +++ b/Private/KernelKit/Framebuffer.hpp @@ -13,71 +13,78 @@ #include <NewKit/Defines.hpp> #include <NewKit/Ref.hpp> -namespace NewOS { -enum class FramebufferColorKind : UChar { - RGB32, - RGB16, - RGB8, - INVALID, -}; - -class FramebufferContext final { - public: - UIntPtr fBase; - UIntPtr fBpp; - UInt fWidth; - UInt fHeight; -}; - -class Framebuffer final { - public: - explicit Framebuffer(Ref<FramebufferContext *> &addr) - : fFrameBufferAddr(addr) {} - ~Framebuffer() {} - - Framebuffer &operator=(const Framebuffer &) = delete; - Framebuffer(const Framebuffer &) = default; - - volatile UIntPtr *operator[](const UIntPtr &pos); - - operator bool(); - - const FramebufferColorKind &Color( - const FramebufferColorKind &colour = FramebufferColorKind::INVALID); - - Ref<FramebufferContext *> &Leak(); - - /// @brief Draws a rectangle inside the fb. - /// @param width the width of it - /// @param height the height of it - /// @param x its x coord. - /// @param y its y coord. - /// @param color the color of it. - /// @return the framebuffer object. - Framebuffer &DrawRect(SizeT width, SizeT height, SizeT x, SizeT y, - UInt32 color); - - /// @brief Puts a pixel on the screen. - /// @param x where in X - /// @param y where in Y - /// @param color the color of it. - /// @return the framebuffer object. - Framebuffer &PutPixel(SizeT x, SizeT y, UInt32 color); - - private: - Ref<FramebufferContext *> fFrameBufferAddr; - FramebufferColorKind fColour; -}; - -/***********************************************************************************/ -/// Some common colors. -/***********************************************************************************/ - -extern const UInt32 kRgbRed; -extern const UInt32 kRgbGreen; -extern const UInt32 kRgbBlue; -extern const UInt32 kRgbBlack; -extern const UInt32 kRgbWhite; -} // namespace NewOS +namespace NewOS +{ + enum class FramebufferColorKind : UChar + { + RGB32, + RGB16, + RGB8, + INVALID, + }; + + class FramebufferContext final + { + public: + UIntPtr fBase; + UIntPtr fBpp; + UInt fWidth; + UInt fHeight; + }; + + class Framebuffer final + { + public: + explicit Framebuffer(Ref<FramebufferContext*>& addr) + : fFrameBufferAddr(addr) + { + } + ~Framebuffer() + { + } + + Framebuffer& operator=(const Framebuffer&) = delete; + Framebuffer(const Framebuffer&) = default; + + volatile UIntPtr* operator[](const UIntPtr& pos); + + operator bool(); + + const FramebufferColorKind& Color( + const FramebufferColorKind& colour = FramebufferColorKind::INVALID); + + Ref<FramebufferContext*>& Leak(); + + /// @brief Draws a rectangle inside the fb. + /// @param width the width of it + /// @param height the height of it + /// @param x its x coord. + /// @param y its y coord. + /// @param color the color of it. + /// @return the framebuffer object. + Framebuffer& DrawRect(SizeT width, SizeT height, SizeT x, SizeT y, UInt32 color); + + /// @brief Puts a pixel on the screen. + /// @param x where in X + /// @param y where in Y + /// @param color the color of it. + /// @return the framebuffer object. + Framebuffer& PutPixel(SizeT x, SizeT y, UInt32 color); + + private: + Ref<FramebufferContext*> fFrameBufferAddr; + FramebufferColorKind fColour; + }; + + /***********************************************************************************/ + /// Some common colors. + /***********************************************************************************/ + + extern const UInt32 kRgbRed; + extern const UInt32 kRgbGreen; + extern const UInt32 kRgbBlue; + extern const UInt32 kRgbBlack; + extern const UInt32 kRgbWhite; +} // namespace NewOS #endif /* ifndef __INC_FB_HPP__ */ diff --git a/Private/KernelKit/HError.hpp b/Private/KernelKit/HError.hpp index b82f7c6b..5a4f49fb 100644 --- a/Private/KernelKit/HError.hpp +++ b/Private/KernelKit/HError.hpp @@ -9,40 +9,41 @@ #include <NewKit/Defines.hpp> #include <NewKit/ErrorID.hpp> -namespace NewOS { -typedef Int32 HError; - -inline constexpr HError kErrorSuccess = 0; -inline constexpr HError kErrorExecutable = 33; -inline constexpr HError kErrorExecutableLib = 34; // no such library!!! -inline constexpr HError kErrorFileNotFound = 35; -inline constexpr HError kErrorDirectoryNotFound = 36; -inline constexpr HError kErrorDiskReadOnly = 37; -inline constexpr HError kErrorDiskIsFull = 38; -inline constexpr HError kErrorProcessFault = 39; -inline constexpr HError kErrorSocketHangUp = 40; -inline constexpr HError kErrorThreadLocalStorage = 41; -inline constexpr HError kErrorMath = 42; -inline constexpr HError kErrorNoNetwork = 43; -inline constexpr HError kErrorHeapOutOfMemory = 44; -inline constexpr HError kErrorNoSuchDisk = 45; -inline constexpr HError kErrorFileExists = 46; -inline constexpr HError kErrorFormatFailed = 47; -inline constexpr HError kErrorNetworkTimeout = 48; -inline constexpr HError kErrorInternal = 49; -inline constexpr HError kErrorForkAlreadyExists = 50; -inline constexpr HError kErrorOutOfTeamSlot = 51; -inline constexpr HError kErrorHeapNotPresent = 52; -inline constexpr HError kErrorNoEntrypoint = 53; -inline constexpr HError kErrorDiskIsCorrupted = 54; -inline constexpr HError kErrorDisk = 55; -inline constexpr HError kErrorUnimplemented = 0; - -Boolean ke_bug_check(void) noexcept; -} // namespace NewOS - -#define DbgOk() (kLastError == NewOS::kErrorSuccess) -#define DbgFailed() (kLastError != NewOS::kErrorSuccess) +namespace NewOS +{ + typedef Int32 HError; + + inline constexpr HError kErrorSuccess = 0; + inline constexpr HError kErrorExecutable = 33; + inline constexpr HError kErrorExecutableLib = 34; // no such library!!! + inline constexpr HError kErrorFileNotFound = 35; + inline constexpr HError kErrorDirectoryNotFound = 36; + inline constexpr HError kErrorDiskReadOnly = 37; + inline constexpr HError kErrorDiskIsFull = 38; + inline constexpr HError kErrorProcessFault = 39; + inline constexpr HError kErrorSocketHangUp = 40; + inline constexpr HError kErrorThreadLocalStorage = 41; + inline constexpr HError kErrorMath = 42; + inline constexpr HError kErrorNoNetwork = 43; + inline constexpr HError kErrorHeapOutOfMemory = 44; + inline constexpr HError kErrorNoSuchDisk = 45; + inline constexpr HError kErrorFileExists = 46; + inline constexpr HError kErrorFormatFailed = 47; + inline constexpr HError kErrorNetworkTimeout = 48; + inline constexpr HError kErrorInternal = 49; + inline constexpr HError kErrorForkAlreadyExists = 50; + inline constexpr HError kErrorOutOfTeamSlot = 51; + inline constexpr HError kErrorHeapNotPresent = 52; + inline constexpr HError kErrorNoEntrypoint = 53; + inline constexpr HError kErrorDiskIsCorrupted = 54; + inline constexpr HError kErrorDisk = 55; + inline constexpr HError kErrorUnimplemented = 0; + + Boolean ke_bug_check(void) noexcept; +} // namespace NewOS + +#define DbgOk() (kLastError == NewOS::kErrorSuccess) +#define DbgFailed() (kLastError != NewOS::kErrorSuccess) #define DbgLastError() kLastError inline NewOS::HError kLastError = 0; diff --git a/Private/KernelKit/KernelHeap.hpp b/Private/KernelKit/KernelHeap.hpp index 471dcb54..f14c2e35 100644 --- a/Private/KernelKit/KernelHeap.hpp +++ b/Private/KernelKit/KernelHeap.hpp @@ -12,27 +12,28 @@ #include <NewKit/Defines.hpp> -namespace NewOS { - -/// @brief Declare pointer as free. -/// @param heapPtr the pointer. -/// @return -Int32 ke_delete_ke_heap(voidPtr allocatedPtr); - -/// @brief Check if pointer is a valid kernel pointer. -/// @param heapPtr the pointer -/// @return if it exists. -Boolean ke_is_valid_heap(VoidPtr ptr); - -/// @brief allocate chunk of memory. -/// @param sz size of pointer -/// @param rw read write (true to enable it) -/// @param user is it accesible by user processes? -/// @return the pointer -voidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user); - -/// @brief Protect the heap with a CRC value. -/// @param heapPtr HIB pointer. -/// @return if it valid: point has crc now., otherwise fail. -Boolean ke_protect_ke_heap(VoidPtr heapPtr); -} // namespace NewOS +namespace NewOS +{ + + /// @brief Declare pointer as free. + /// @param heapPtr the pointer. + /// @return + Int32 ke_delete_ke_heap(voidPtr allocatedPtr); + + /// @brief Check if pointer is a valid kernel pointer. + /// @param heapPtr the pointer + /// @return if it exists. + Boolean ke_is_valid_heap(VoidPtr ptr); + + /// @brief allocate chunk of memory. + /// @param sz size of pointer + /// @param rw read write (true to enable it) + /// @param user is it accesible by user processes? + /// @return the pointer + voidPtr ke_new_ke_heap(SizeT sz, const bool rw, const bool user); + + /// @brief Protect the heap with a CRC value. + /// @param heapPtr HIB pointer. + /// @return if it valid: point has crc now., otherwise fail. + Boolean ke_protect_ke_heap(VoidPtr heapPtr); +} // namespace NewOS diff --git a/Private/KernelKit/LoaderInterface.hpp b/Private/KernelKit/LoaderInterface.hpp index 97a12938..6d51a09c 100644 --- a/Private/KernelKit/LoaderInterface.hpp +++ b/Private/KernelKit/LoaderInterface.hpp @@ -11,21 +11,23 @@ #include <NewKit/Defines.hpp> #include <NewKit/ErrorOr.hpp> -namespace NewOS { -/// @brief This interface is used to make loader contracts (MSCOFF, PEF). -/// @author @Amlal-El-Mahrouss -class LoaderInterface { - public: - explicit LoaderInterface() = default; - virtual ~LoaderInterface() = default; +namespace NewOS +{ + /// @brief This interface is used to make loader contracts (MSCOFF, PEF). + /// @author @Amlal-El-Mahrouss + class LoaderInterface + { + public: + explicit LoaderInterface() = default; + virtual ~LoaderInterface() = default; - NEWOS_COPY_DEFAULT(LoaderInterface); + NEWOS_COPY_DEFAULT(LoaderInterface); - public: - virtual _Output const char* FormatAsString() = 0; - virtual _Output const char* MIME() = 0; - virtual _Output const char* Path() = 0; - virtual _Output ErrorOr<VoidPtr> FindStart() = 0; - virtual _Output VoidPtr FindSymbol(_Input const char* name, _Input Int32 kind) = 0; -}; -} // namespace NewOS + public: + virtual _Output const char* FormatAsString() = 0; + virtual _Output const char* MIME() = 0; + virtual _Output const char* Path() = 0; + virtual _Output ErrorOr<VoidPtr> FindStart() = 0; + virtual _Output VoidPtr FindSymbol(_Input const char* name, _Input Int32 kind) = 0; + }; +} // namespace NewOS diff --git a/Private/KernelKit/LockDelegate.hpp b/Private/KernelKit/LockDelegate.hpp index 3b4889c9..5b135625 100644 --- a/Private/KernelKit/LockDelegate.hpp +++ b/Private/KernelKit/LockDelegate.hpp @@ -9,56 +9,56 @@ #include <NewKit/Atom.hpp> #include <NewKit/Defines.hpp> -#define kLockDone (200U) /* job is done */ +#define kLockDone (200U) /* job is done */ #define kLockTimedOut (100U) /* job has timed out */ namespace NewOS { -/// @brief Lock condition pointer. -typedef Boolean* LockPtr; + /// @brief Lock condition pointer. + typedef Boolean* LockPtr; -/// @brief Locking delegate class, hangs until limit. -/// @tparam N the amount of cycles to wait. -template <SizeT N> -class LockDelegate final -{ - public: - LockDelegate() = delete; + /// @brief Locking delegate class, hangs until limit. + /// @tparam N the amount of cycles to wait. + template <SizeT N> + class LockDelegate final + { + public: + LockDelegate() = delete; + + public: + explicit LockDelegate(LockPtr expr) + { + auto spin = 0U; - public: - explicit LockDelegate(LockPtr expr) - { - auto spin = 0U; - - while (spin != N) - { - if (*expr) - { - fLockStatus | kLockDone; - break; - } - } + while (spin != N) + { + if (*expr) + { + fLockStatus | kLockDone; + break; + } + } - if (spin == N) - fLockStatus | kLockTimedOut; - } + if (spin == N) + fLockStatus | kLockTimedOut; + } - ~LockDelegate() = default; + ~LockDelegate() = default; - LockDelegate &operator=(const LockDelegate &) = delete; - LockDelegate(const LockDelegate &) = delete; + LockDelegate& operator=(const LockDelegate&) = delete; + LockDelegate(const LockDelegate&) = delete; - bool Done() - { - return fLockStatus[kLockDone] == kLockDone; - } + bool Done() + { + return fLockStatus[kLockDone] == kLockDone; + } - bool HasTimedOut() - { - return fLockStatus[kLockTimedOut] != kLockTimedOut; - } + bool HasTimedOut() + { + return fLockStatus[kLockTimedOut] != kLockTimedOut; + } - private: - Atom<UInt> fLockStatus; -}; + private: + Atom<UInt> fLockStatus; + }; } // namespace NewOS diff --git a/Private/KernelKit/MSDOS.hpp b/Private/KernelKit/MSDOS.hpp index 8826c2c7..41e8340f 100644 --- a/Private/KernelKit/MSDOS.hpp +++ b/Private/KernelKit/MSDOS.hpp @@ -24,39 +24,45 @@ #define kMagMz1 'Z' typedef NewOS::UInt32 DosWord; -typedef NewOS::Long DosLong; - -typedef struct _DosHeader { - NewOS::UInt8 eMagic[2]; - DosWord eMagLen; - DosWord ePagesCount; - DosWord eCrlc; - DosWord eCParHdr; - DosWord eMinAlloc; - DosWord eMaxAlloc; - DosWord eStackSeg; - DosWord eStackPtr; - DosWord eChksum; - DosWord eIp; - DosWord eCs; - DosWord eLfarlc; - DosWord eOvno; - DosWord eRes[4]; - DosWord eOemid; - DosWord eOeminfo; - DosWord eRes2[10]; - DosLong eLfanew; +typedef NewOS::Long DosLong; + +typedef struct _DosHeader +{ + NewOS::UInt8 eMagic[2]; + DosWord eMagLen; + DosWord ePagesCount; + DosWord eCrlc; + DosWord eCParHdr; + DosWord eMinAlloc; + DosWord eMaxAlloc; + DosWord eStackSeg; + DosWord eStackPtr; + DosWord eChksum; + DosWord eIp; + DosWord eCs; + DosWord eLfarlc; + DosWord eOvno; + DosWord eRes[4]; + DosWord eOemid; + DosWord eOeminfo; + DosWord eRes2[10]; + DosLong eLfanew; } DosHeader, *DosHeaderPtr; -namespace NewOS { -/// @brief Find the PE header inside the the blob. -inline auto rt_find_exec_header(DosHeaderPtr ptrDos) -> VoidPtr { - if (!ptrDos) return nullptr; - if (ptrDos->eMagic[0] != kMagMz0) return nullptr; - if (ptrDos->eMagic[1] != kMagMz1) return nullptr; +namespace NewOS +{ + /// @brief Find the PE header inside the the blob. + inline auto rt_find_exec_header(DosHeaderPtr ptrDos) -> VoidPtr + { + if (!ptrDos) + return nullptr; + if (ptrDos->eMagic[0] != kMagMz0) + return nullptr; + if (ptrDos->eMagic[1] != kMagMz1) + return nullptr; - return (VoidPtr)(&ptrDos->eLfanew + 1); -} -} // namespace NewOS + return (VoidPtr)(&ptrDos->eLfanew + 1); + } +} // namespace NewOS #endif /* ifndef __MSDOS_EXEC__ */ diff --git a/Private/KernelKit/PCI/Database.hpp b/Private/KernelKit/PCI/Database.hpp index b79f7b57..cf8b737f 100644 --- a/Private/KernelKit/PCI/Database.hpp +++ b/Private/KernelKit/PCI/Database.hpp @@ -8,28 +8,31 @@ #include <KernelKit/PCI/Device.hpp> #include <NewKit/Defines.hpp> -namespace NewOS { - 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 NewOS +{ + 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 NewOS diff --git a/Private/KernelKit/PCI/Device.hpp b/Private/KernelKit/PCI/Device.hpp index ea11e327..e34a12b0 100644 --- a/Private/KernelKit/PCI/Device.hpp +++ b/Private/KernelKit/PCI/Device.hpp @@ -9,73 +9,71 @@ namespace NewOS::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 fBus; - UShort fDevice; - UShort fFunction; - UShort fBar; - - }; + 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 fBus; + UShort fDevice; + UShort fFunction; + UShort fBar; + }; } // namespace NewOS::PCI - EXTERN_C void NewOSPCISetCfgTarget(NewOS::UInt bar); EXTERN_C NewOS::UInt NewOSPCIReadRaw(NewOS::UInt bar); diff --git a/Private/KernelKit/PCI/Dma.hpp b/Private/KernelKit/PCI/Dma.hpp index 392aeee3..bdfc52cf 100644 --- a/Private/KernelKit/PCI/Dma.hpp +++ b/Private/KernelKit/PCI/Dma.hpp @@ -12,64 +12,70 @@ #include <NewKit/OwnPtr.hpp> #include <NewKit/Ref.hpp> -namespace NewOS { -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: - explicit DMAWrapper() = delete; - - public: - explicit DMAWrapper(nullPtr) = delete; - explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) - : fAddress(Ptr), fKind(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 fAddress{nullptr}; - DmaKind fKind{DmaKind::Invalid}; - - private: - friend class DMAFactory; -}; - -class DMAFactory final { - public: - static OwnPtr<IOBuf<Char *>> Construct(OwnPtr<DMAWrapper> &dma); -}; -} // namespace NewOS +namespace NewOS +{ + 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: + explicit DMAWrapper() = delete; + + public: + explicit DMAWrapper(nullPtr) = delete; + explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI) + : fAddress(Ptr), fKind(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 fAddress{nullptr}; + DmaKind fKind{DmaKind::Invalid}; + + private: + friend class DMAFactory; + }; + + class DMAFactory final + { + public: + static OwnPtr<IOBuf<Char*>> Construct(OwnPtr<DMAWrapper>& dma); + }; +} // namespace NewOS #include <KernelKit/PCI/Dma.inl> diff --git a/Private/KernelKit/PCI/IO.hpp b/Private/KernelKit/PCI/IO.hpp index a0ee51dc..b76214bf 100644 --- a/Private/KernelKit/PCI/IO.hpp +++ b/Private/KernelKit/PCI/IO.hpp @@ -11,39 +11,49 @@ #include <NewKit/Defines.hpp> #include <NewKit/Ref.hpp> -namespace NewOS { -template <SizeT Sz> -class IOArray final { - public: - IOArray() = delete; +namespace NewOS +{ + template <SizeT Sz> + class IOArray final + { + public: + IOArray() = delete; - IOArray(nullPtr) = delete; + IOArray(nullPtr) = delete; - explicit IOArray(Array<UShort, Sz> &ports) : fPorts(ports) {} - ~IOArray() {} + explicit IOArray(Array<UShort, Sz>& ports) + : fPorts(ports) + { + } + ~IOArray() + { + } - IOArray &operator=(const IOArray &) = default; + IOArray& operator=(const IOArray&) = default; - IOArray(const IOArray &) = default; + IOArray(const IOArray&) = default; - operator bool() { return !fPorts.Empty(); } + operator bool() + { + return !fPorts.Empty(); + } - public: - template <typename T> - T In(SizeT index); + public: + template <typename T> + T In(SizeT index); - template <typename T> - void Out(SizeT index, T value); + template <typename T> + void Out(SizeT index, T value); - private: - Array<UShort, Sz> fPorts; -}; + private: + Array<UShort, Sz> fPorts; + }; -using IOArray16 = IOArray<16>; -} // namespace NewOS + using IOArray16 = IOArray<16>; +} // namespace NewOS #ifdef __x86_64__ #include <KernelKit/PCI/IO-Impl-AMD64.inl> #else #error Please provide platform specific code for the I/O -#endif // ifdef __x86_64__ +#endif // ifdef __x86_64__ diff --git a/Private/KernelKit/PCI/Iterator.hpp b/Private/KernelKit/PCI/Iterator.hpp index b81aae74..278711a7 100644 --- a/Private/KernelKit/PCI/Iterator.hpp +++ b/Private/KernelKit/PCI/Iterator.hpp @@ -7,30 +7,32 @@ #include <NewKit/Defines.hpp> #include <NewKit/Ref.hpp> -#define NEWOS_BUS_COUNT (256) -#define NEWOS_DEVICE_COUNT (33) +#define NEWOS_BUS_COUNT (256) +#define NEWOS_DEVICE_COUNT (33) #define NEWOS_FUNCTION_COUNT (8) -namespace NewOS::PCI { - class Iterator final { - public: - Iterator() = delete; +namespace NewOS::PCI +{ + class Iterator final + { + public: + Iterator() = delete; - public: - explicit Iterator(const Types::PciDeviceKind &deviceType); + public: + explicit Iterator(const Types::PciDeviceKind& deviceType); - Iterator &operator=(const Iterator &) = default; + Iterator& operator=(const Iterator&) = default; - Iterator(const Iterator &) = default; + Iterator(const Iterator&) = default; - ~Iterator(); + ~Iterator(); - public: - Ref<PCI::Device> operator[](const Size &sz); + public: + Ref<PCI::Device> operator[](const Size& sz); - private: - Array<PCI::Device, NEWOS_BUS_COUNT> fDevices; - }; + private: + Array<PCI::Device, NEWOS_BUS_COUNT> fDevices; + }; } // namespace NewOS::PCI #endif // __PCI_ITERATOR_HPP__ diff --git a/Private/KernelKit/PCI/PCI.hpp b/Private/KernelKit/PCI/PCI.hpp index 65e199ad..53f9392f 100644 --- a/Private/KernelKit/PCI/PCI.hpp +++ b/Private/KernelKit/PCI/PCI.hpp @@ -8,46 +8,51 @@ #include <NewKit/Defines.hpp> #define PCI_CONFIG_ADDRESS (0xCF8) -#define PCI_CONFIG_DATA (0xCFC) +#define PCI_CONFIG_DATA (0xCFC) #define PCI_DEVICE_COUNT (32) -#define PCI_FUNC_COUNT (8) -#define PCI_BUS_COUNT (255) - -namespace NewOS::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; - }; +#define PCI_FUNC_COUNT (8) +#define PCI_BUS_COUNT (255) + +namespace NewOS::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 NewOS::PCI diff --git a/Private/KernelKit/PE.hxx b/Private/KernelKit/PE.hxx index 57e224ca..d7c959da 100644 --- a/Private/KernelKit/PE.hxx +++ b/Private/KernelKit/PE.hxx @@ -18,15 +18,16 @@ #define kPeMagic 0x00004550 -typedef struct ExecHeader final { - NewOS::UInt32 mMagic; // PE\0\0 or 0x00004550 - NewOS::UInt16 mMachine; - NewOS::UInt16 mNumberOfSections; - NewOS::UInt32 mTimeDateStamp; - NewOS::UInt32 mPointerToSymbolTable; - NewOS::UInt32 mNumberOfSymbols; - NewOS::UInt16 mSizeOfOptionalHeader; - NewOS::UInt16 mCharacteristics; +typedef struct ExecHeader final +{ + NewOS::UInt32 mMagic; // PE\0\0 or 0x00004550 + NewOS::UInt16 mMachine; + NewOS::UInt16 mNumberOfSections; + NewOS::UInt32 mTimeDateStamp; + NewOS::UInt32 mPointerToSymbolTable; + NewOS::UInt32 mNumberOfSymbols; + NewOS::UInt16 mSizeOfOptionalHeader; + NewOS::UInt16 mCharacteristics; } ALIGN(8) ExecHeader, *ExecHeaderPtr; #define kMagPE32 0x010b @@ -35,81 +36,86 @@ typedef struct ExecHeader final { #define kPEMachineAMD64 0x8664 #define kPEMachineARM64 0xaa64 -typedef struct ExecOptionalHeader final { - NewOS::UInt16 mMagic; // 0x010b - PE32, 0x020b - PE32+ (64 bit) - NewOS::UChar mMajorLinkerVersion; - NewOS::UChar mMinorLinkerVersion; - NewOS::UIntPtr mSizeOfCode; - NewOS::UIntPtr mSizeOfInitializedData; - NewOS::UIntPtr mSizeOfUninitializedData; - NewOS::UInt32 mAddressOfEntryPoint; - NewOS::UInt32 mBaseOfCode; - NewOS::UIntPtr mImageBase; - NewOS::UInt32 mSectionAlignment; - NewOS::UInt32 mFileAlignment; - NewOS::UInt16 mMajorOperatingSystemVersion; - NewOS::UInt16 mMinorOperatingSystemVersion; - NewOS::UInt16 mMajorImageVersion; - NewOS::UInt16 mMinorImageVersion; - NewOS::UInt16 mMajorSubsystemVersion; - NewOS::UInt16 mMinorSubsystemVersion; - NewOS::UInt32 mWin32VersionValue; - NewOS::UIntPtr mSizeOfImage; - NewOS::UIntPtr mSizeOfHeaders; - NewOS::UInt32 mCheckSum; - NewOS::UInt16 mSubsystem; - NewOS::UInt16 mDllCharacteristics; - NewOS::UIntPtr mSizeOfStackReserve; - NewOS::UIntPtr mSizeOfStackCommit; - NewOS::UIntPtr mSizeOfHeapReserve; - NewOS::UIntPtr mSizeOfHeapCommit; - NewOS::UInt32 mLoaderFlags; - NewOS::UInt32 mNumberOfRvaAndSizes; +typedef struct ExecOptionalHeader final +{ + NewOS::UInt16 mMagic; // 0x010b - PE32, 0x020b - PE32+ (64 bit) + NewOS::UChar mMajorLinkerVersion; + NewOS::UChar mMinorLinkerVersion; + NewOS::UIntPtr mSizeOfCode; + NewOS::UIntPtr mSizeOfInitializedData; + NewOS::UIntPtr mSizeOfUninitializedData; + NewOS::UInt32 mAddressOfEntryPoint; + NewOS::UInt32 mBaseOfCode; + NewOS::UIntPtr mImageBase; + NewOS::UInt32 mSectionAlignment; + NewOS::UInt32 mFileAlignment; + NewOS::UInt16 mMajorOperatingSystemVersion; + NewOS::UInt16 mMinorOperatingSystemVersion; + NewOS::UInt16 mMajorImageVersion; + NewOS::UInt16 mMinorImageVersion; + NewOS::UInt16 mMajorSubsystemVersion; + NewOS::UInt16 mMinorSubsystemVersion; + NewOS::UInt32 mWin32VersionValue; + NewOS::UIntPtr mSizeOfImage; + NewOS::UIntPtr mSizeOfHeaders; + NewOS::UInt32 mCheckSum; + NewOS::UInt16 mSubsystem; + NewOS::UInt16 mDllCharacteristics; + NewOS::UIntPtr mSizeOfStackReserve; + NewOS::UIntPtr mSizeOfStackCommit; + NewOS::UIntPtr mSizeOfHeapReserve; + NewOS::UIntPtr mSizeOfHeapCommit; + NewOS::UInt32 mLoaderFlags; + NewOS::UInt32 mNumberOfRvaAndSizes; } ExecOptionalHeader, *ExecOptionalHeaderPtr; -typedef struct ExecSectionHeader final { - CONST NewOS::UChar mName[8]; - NewOS::UInt32 mVirtualSize; - NewOS::UInt32 mVirtualAddress; - NewOS::UInt32 mSizeOfRawData; - NewOS::UInt32 mPointerToRawData; - NewOS::UInt32 mPointerToRelocations; - NewOS::UInt32 mPointerToLinenumbers; - NewOS::UInt16 mNumberOfRelocations; - NewOS::UInt16 mNumberOfLinenumbers; - NewOS::UInt32 mCharacteristics; +typedef struct ExecSectionHeader final +{ + CONST NewOS::UChar mName[8]; + NewOS::UInt32 mVirtualSize; + NewOS::UInt32 mVirtualAddress; + NewOS::UInt32 mSizeOfRawData; + NewOS::UInt32 mPointerToRawData; + NewOS::UInt32 mPointerToRelocations; + NewOS::UInt32 mPointerToLinenumbers; + NewOS::UInt16 mNumberOfRelocations; + NewOS::UInt16 mNumberOfLinenumbers; + NewOS::UInt32 mCharacteristics; } ExecSectionHeader, *ExecSectionHeaderPtr; -enum kExecDataDirParams { - kExecExport, - kExecImport, - kExecInvalid, - kExecCount, +enum kExecDataDirParams +{ + kExecExport, + kExecImport, + kExecInvalid, + kExecCount, }; -typedef struct ExecExportDirectory { - NewOS::UInt32 mCharacteristics; - NewOS::UInt32 mTimeDateStamp; - NewOS::UInt16 mMajorVersion; - NewOS::UInt16 mMinorVersion; - NewOS::UInt32 mName; - NewOS::UInt32 mBase; - NewOS::UInt32 mNumberOfFunctions; - NewOS::UInt32 mNumberOfNames; - NewOS::UInt32 mAddressOfFunctions; // export table rva - NewOS::UInt32 mAddressOfNames; - NewOS::UInt32 mAddressOfNameOrdinal; // ordinal table rva +typedef struct ExecExportDirectory +{ + NewOS::UInt32 mCharacteristics; + NewOS::UInt32 mTimeDateStamp; + NewOS::UInt16 mMajorVersion; + NewOS::UInt16 mMinorVersion; + NewOS::UInt32 mName; + NewOS::UInt32 mBase; + NewOS::UInt32 mNumberOfFunctions; + NewOS::UInt32 mNumberOfNames; + NewOS::UInt32 mAddressOfFunctions; // export table rva + NewOS::UInt32 mAddressOfNames; + NewOS::UInt32 mAddressOfNameOrdinal; // ordinal table rva } ExecExportDirectory, *ExecExportDirectoryPtr; -typedef struct ExecImportDirectory { - union { - NewOS::UInt32 mCharacteristics; - NewOS::UInt32 mOriginalFirstThunk; - }; - NewOS::UInt32 mTimeDateStamp; - NewOS::UInt32 mForwarderChain; - NewOS::UInt32 mNameRva; - NewOS::UInt32 mThunkTableRva; +typedef struct ExecImportDirectory +{ + union { + NewOS::UInt32 mCharacteristics; + NewOS::UInt32 mOriginalFirstThunk; + }; + NewOS::UInt32 mTimeDateStamp; + NewOS::UInt32 mForwarderChain; + NewOS::UInt32 mNameRva; + NewOS::UInt32 mThunkTableRva; } ExecImportDirectory, *ExecImportDirectoryPtr; #define kPeStart "__hcore_subsys_start" diff --git a/Private/KernelKit/PEF.hpp b/Private/KernelKit/PEF.hpp index 2b85196e..6c3cc5fe 100644 --- a/Private/KernelKit/PEF.hpp +++ b/Private/KernelKit/PEF.hpp @@ -18,7 +18,7 @@ #include <KernelKit/LoaderInterface.hpp> #include <NewKit/Defines.hpp> -#define kPefMagic "Joy!" +#define kPefMagic "Joy!" #define kPefMagicFat "yoJ!" #define kPefMagicLen 5 @@ -28,82 +28,89 @@ /// @brief Preferred Executable Format. -namespace NewOS { -enum { - kPefArchIntel86S, - kPefArchAMD64, - kPefArchRISCV, - kPefArch64x0, /* 64x0. ISA */ - kPefArch32x0, /* 32x0. ISA */ - kPefArchPowerPC, - kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, - kPefArchInvalid = 0xFF, -}; - -enum { - kPefSubArchAMD, - kPefSubArchIntel, - kPefSubArchARM, - kPefSubArchIBM, -}; - -enum { - kPefKindExec = 1, /* .exe */ - kPefKindSharedObject = 2, /* .lib */ - kPefKindObject = 4, /* .obj */ - kPefKindDebug = 5, /* .dbg */ - kPefKindDriver = 6, - kPefKindCount, -}; - -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 */ -} 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 Cpu; /* container cpu */ - UInt32 SubCpu; /* container sub-cpu */ - UInt32 Flags; /* container flags */ - UInt16 Kind; /* container kind */ - UIntPtr Offset; /* content offset */ - SizeT Size; /* content Size */ -} PACKED PEFCommandHeader; - -enum { - kPefCode = 0xC, - kPefData = 0xD, - kPefZero = 0xE, - kPefLinkerID = 0x1, -}; -} // namespace NewOS - -#define kPefExt ".exec" -#define kPefDylibExt ".lib" -#define kPefLibExt ".slib" +namespace NewOS +{ + enum + { + kPefArchIntel86S, + kPefArchAMD64, + kPefArchRISCV, + kPefArch64x0, /* 64x0. ISA */ + kPefArch32x0, /* 32x0. ISA */ + kPefArchPowerPC, + kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1, + kPefArchInvalid = 0xFF, + }; + + enum + { + kPefSubArchAMD, + kPefSubArchIntel, + kPefSubArchARM, + kPefSubArchIBM, + }; + + enum + { + kPefKindExec = 1, /* .exe */ + kPefKindSharedObject = 2, /* .lib */ + kPefKindObject = 4, /* .obj */ + kPefKindDebug = 5, /* .dbg */ + kPefKindDriver = 6, + kPefKindCount, + }; + + 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 */ + } 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 Cpu; /* container cpu */ + UInt32 SubCpu; /* container sub-cpu */ + UInt32 Flags; /* container flags */ + UInt16 Kind; /* container kind */ + UIntPtr Offset; /* content offset */ + SizeT Size; /* content Size */ + } PACKED PEFCommandHeader; + + enum + { + kPefCode = 0xC, + kPefData = 0xD, + kPefZero = 0xE, + kPefLinkerID = 0x1, + }; +} // namespace NewOS + +#define kPefExt ".exec" +#define kPefDylibExt ".lib" +#define kPefLibExt ".slib" #define kPefObjectExt ".obj" -#define kPefDebugExt ".dbg" +#define kPefDebugExt ".dbg" // NewOS System Binary Interface. #define kPefAbi (0x5046) #define kPefStart "__ImageStart" -#define kPefForkKind kPefMagic +#define kPefForkKind kPefMagic #define kPefForkKindFAT kPefMagicFat #endif /* ifndef __PEF__ */ diff --git a/Private/KernelKit/PEFCodeManager.hxx b/Private/KernelKit/PEFCodeManager.hxx index 2d8517cb..1b8b7847 100644 --- a/Private/KernelKit/PEFCodeManager.hxx +++ b/Private/KernelKit/PEFCodeManager.hxx @@ -13,45 +13,48 @@ #define kPefApplicationMime "application/x-newos-exec" -namespace NewOS { -/// -/// \name PEFLoader -/// \brief PEF loader class. -/// -class PEFLoader : public LoaderInterface { - private: - explicit PEFLoader() = delete; - - public: - explicit PEFLoader(const VoidPtr blob); - explicit PEFLoader(const Char* path); - ~PEFLoader() override; - - public: - NEWOS_COPY_DEFAULT(PEFLoader); - - public: - const char *Path() override; - const char *FormatAsString() override; - const char *MIME() override; - - public: - ErrorOr<VoidPtr> FindStart() override; - VoidPtr FindSymbol(const char *name, Int32 kind) override; - - public: - bool IsLoaded() noexcept; - - private: - Ref<StringView> fPath; - VoidPtr fCachedBlob; - bool fFatBinary; - bool fBad; -}; - -namespace Utils { -bool execute_from_image(PEFLoader &exec, const Int32& procKind) noexcept; -} // namespace Utils -} // namespace NewOS - -#endif // ifndef _INC_CODE_MANAGER_PEF_ +namespace NewOS +{ + /// + /// \name PEFLoader + /// \brief PEF loader class. + /// + class PEFLoader : public LoaderInterface + { + private: + explicit PEFLoader() = delete; + + public: + explicit PEFLoader(const VoidPtr blob); + explicit PEFLoader(const Char* path); + ~PEFLoader() override; + + public: + NEWOS_COPY_DEFAULT(PEFLoader); + + public: + const char* Path() override; + const char* FormatAsString() override; + const char* MIME() override; + + public: + ErrorOr<VoidPtr> FindStart() override; + VoidPtr FindSymbol(const char* name, Int32 kind) override; + + public: + bool IsLoaded() noexcept; + + private: + Ref<StringView> fPath; + VoidPtr fCachedBlob; + bool fFatBinary; + bool fBad; + }; + + namespace Utils + { + bool execute_from_image(PEFLoader& exec, const Int32& procKind) noexcept; + } // namespace Utils +} // namespace NewOS + +#endif // ifndef _INC_CODE_MANAGER_PEF_ diff --git a/Private/KernelKit/PEFSharedObject.hxx b/Private/KernelKit/PEFSharedObject.hxx index 185310ee..6176c31d 100644 --- a/Private/KernelKit/PEFSharedObject.hxx +++ b/Private/KernelKit/PEFSharedObject.hxx @@ -15,78 +15,98 @@ #include <KernelKit/PEFCodeManager.hxx> #include <NewKit/Defines.hpp> -namespace NewOS { -/// @brief Pure implementation, missing method/function handler. -extern "C" void __mh_purecall(void); +namespace NewOS +{ + /// @brief Pure implementation, missing method/function handler. + extern "C" void __mh_purecall(void); -/** + /** * @brief Shared Library class * Load library from this class */ -class SharedObject final { - public: - struct SharedObjectTrait final { - VoidPtr fImageObject; - VoidPtr fImageEntrypointOffset; - }; - - public: - explicit SharedObject() = default; - ~SharedObject() = default; - - public: - NEWOS_COPY_DEFAULT(SharedObject); - - private: - SharedObjectTrait *fMounted{nullptr}; - - public: - SharedObjectTrait **GetAddressOf() { return &fMounted; } - - SharedObjectTrait *Get() { return fMounted; } - - public: - void Mount(SharedObjectTrait *to_mount) { - if (!to_mount || !to_mount->fImageObject) return; - - fMounted = to_mount; - - if (fLoader && to_mount) { - delete fLoader; - fLoader = nullptr; - } - - if (!fLoader) { - fLoader = new PEFLoader(fMounted->fImageObject); - } - } - - void Unmount() { - if (fMounted) fMounted = nullptr; - }; - - template <typename SymbolType> - SymbolType Load(const char *symbol_name, SizeT len, Int32 kind) { - if (symbol_name == nullptr || *symbol_name == 0) return nullptr; - if (len > kPathLen || len < 1) return nullptr; - - auto ret = - reinterpret_cast<SymbolType>(fLoader->FindSymbol(symbol_name, kind)); - - if (!ret) { - if (kind == kPefCode) return (VoidPtr)__mh_purecall; - - return nullptr; - } - - return ret; - } - - private: - PEFLoader *fLoader{nullptr}; -}; - -typedef SharedObject *SharedObjectPtr; -} // namespace NewOS + class SharedObject final + { + public: + struct SharedObjectTrait final + { + VoidPtr fImageObject; + VoidPtr fImageEntrypointOffset; + }; + + public: + explicit SharedObject() = default; + ~SharedObject() = default; + + public: + NEWOS_COPY_DEFAULT(SharedObject); + + private: + SharedObjectTrait* fMounted{nullptr}; + + public: + SharedObjectTrait** GetAddressOf() + { + return &fMounted; + } + + SharedObjectTrait* Get() + { + return fMounted; + } + + public: + void Mount(SharedObjectTrait* to_mount) + { + if (!to_mount || !to_mount->fImageObject) + return; + + fMounted = to_mount; + + if (fLoader && to_mount) + { + delete fLoader; + fLoader = nullptr; + } + + if (!fLoader) + { + fLoader = new PEFLoader(fMounted->fImageObject); + } + } + + void Unmount() + { + if (fMounted) + fMounted = nullptr; + }; + + template <typename SymbolType> + SymbolType Load(const char* symbol_name, SizeT len, Int32 kind) + { + if (symbol_name == nullptr || *symbol_name == 0) + return nullptr; + if (len > kPathLen || len < 1) + return nullptr; + + auto ret = + reinterpret_cast<SymbolType>(fLoader->FindSymbol(symbol_name, kind)); + + if (!ret) + { + if (kind == kPefCode) + return (VoidPtr)__mh_purecall; + + return nullptr; + } + + return ret; + } + + private: + PEFLoader* fLoader{nullptr}; + }; + + typedef SharedObject* SharedObjectPtr; +} // namespace NewOS #endif /* ifndef __KERNELKIT_SHARED_OBJECT_HXX__ */ diff --git a/Private/KernelKit/PermissionSelector.hxx b/Private/KernelKit/PermissionSelector.hxx index d398ccb9..d5325a85 100644 --- a/Private/KernelKit/PermissionSelector.hxx +++ b/Private/KernelKit/PermissionSelector.hxx @@ -20,35 +20,38 @@ // hash 'user@host:password' -> base64 encoded data // use this data to then fetch specific data. -namespace NewOS { -enum class RingKind { - kRingUser = 3, - kRingDriver = 2, - kRingKernel = 0, - kRingUnknown = -1, - kRingCount = 4, -}; - -class PermissionSelector final { - private: - explicit PermissionSelector(const Int32& sel); - explicit PermissionSelector(const RingKind& kind); - - ~PermissionSelector(); - - public: - NEWOS_COPY_DEFAULT(PermissionSelector) - - public: - bool operator==(const PermissionSelector& lhs); - bool operator!=(const PermissionSelector& lhs); - - public: - const RingKind& Ring() noexcept; - - private: - RingKind fRing; -}; -} // namespace NewOS +namespace NewOS +{ + enum class RingKind + { + kRingUser = 3, + kRingDriver = 2, + kRingKernel = 0, + kRingUnknown = -1, + kRingCount = 4, + }; + + class PermissionSelector final + { + private: + explicit PermissionSelector(const Int32& sel); + explicit PermissionSelector(const RingKind& kind); + + ~PermissionSelector(); + + public: + NEWOS_COPY_DEFAULT(PermissionSelector) + + public: + bool operator==(const PermissionSelector& lhs); + bool operator!=(const PermissionSelector& lhs); + + public: + const RingKind& Ring() noexcept; + + private: + RingKind fRing; + }; +} // namespace NewOS #endif /* ifndef _INC_PERMISSION_SEL_HPP */ diff --git a/Private/KernelKit/ProcessScheduler.hpp b/Private/KernelKit/ProcessScheduler.hpp index 3c080b15..882aa7f0 100644 --- a/Private/KernelKit/ProcessScheduler.hpp +++ b/Private/KernelKit/ProcessScheduler.hpp @@ -15,7 +15,7 @@ #include <NewKit/MutableArray.hpp> #define kSchedMinMicroTime AffinityKind::kHartStandard -#define kSchedInvalidPID (-1) +#define kSchedInvalidPID (-1) #define kSchedProcessLimitPerTeam (100U) @@ -25,241 +25,270 @@ //////////////////////////////////////////////////// -namespace NewOS { -class ProcessHeader; -class ProcessTeam; -class ProcessScheduler; - -//! @brief Process identifier. -typedef Int64 ProcessID; - -//! @brief Process name length. -inline constexpr SizeT kProcessLen = 256U; - -//! @brief Forward declaration. -class ProcessHeader; -class ProcessScheduler; -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, - kHartStandard = 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. - -enum ProcessSubsystemEnum { - eProcessSubsystemLogin, - eProcessSubsystemNative, - eProcessSubsystemInvalid, - eProcessSubsystemCount, -}; - -using ProcessSubsystem = ProcessSubsystemEnum; -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; - -// @name ProcessHeader -// @brief Process Header (PH) -// Holds information about the running process. -// Thread execution is being abstracted away. -class ProcessHeader final { - public: - explicit ProcessHeader(VoidPtr startImage = nullptr) : Image(startImage) { - MUST_PASS(startImage); - } - - ~ProcessHeader() = default; - - NEWOS_COPY_DEFAULT(ProcessHeader) - - public: - void SetEntrypoint(UIntPtr &imageStart) noexcept; - - public: - Char Name[kProcessLen] = {"NewOS Process"}; - ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; - ProcessSelector Selector{ProcessSelector::kRingUser}; - HAL::StackFramePtr StackFrame{nullptr}; - AffinityKind Affinity; - ProcessStatus Status; - - // Memory, images. - HeapPtr HeapCursor{nullptr}; - ImagePtr Image{nullptr}; - HeapPtr HeapPtr{nullptr}; - - // memory usage - SizeT UsedMemory{0}; - SizeT FreeMemory{0}; +namespace NewOS +{ + class ProcessHeader; + class ProcessTeam; + class ProcessScheduler; + + //! @brief Process identifier. + typedef Int64 ProcessID; + + //! @brief Process name length. + inline constexpr SizeT kProcessLen = 256U; + + //! @brief Forward declaration. + class ProcessHeader; + class ProcessScheduler; + 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, + kHartStandard = 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. + + enum ProcessSubsystemEnum + { + eProcessSubsystemLogin, + eProcessSubsystemNative, + eProcessSubsystemInvalid, + eProcessSubsystemCount, + }; + + using ProcessSubsystem = ProcessSubsystemEnum; + 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; + + // @name ProcessHeader + // @brief Process Header (PH) + // Holds information about the running process. + // Thread execution is being abstracted away. + class ProcessHeader final + { + public: + explicit ProcessHeader(VoidPtr startImage = nullptr) + : Image(startImage) + { + MUST_PASS(startImage); + } + + ~ProcessHeader() = default; + + NEWOS_COPY_DEFAULT(ProcessHeader) + + public: + void SetEntrypoint(UIntPtr& imageStart) noexcept; + + public: + Char Name[kProcessLen] = {"NewOS Process"}; + ProcessSubsystem SubSystem{ProcessSubsystem::eProcessSubsystemInvalid}; + ProcessSelector Selector{ProcessSelector::kRingUser}; + HAL::StackFramePtr StackFrame{nullptr}; + AffinityKind Affinity; + ProcessStatus Status; + + // Memory, images. + HeapPtr HeapCursor{nullptr}; + ImagePtr Image{nullptr}; + HeapPtr HeapPtr{nullptr}; + + // memory usage + SizeT UsedMemory{0}; + SizeT FreeMemory{0}; + + enum + { + kUserKind = 3, + kLibKind = 3, + kDriverKind = 0, + kKindCount, + }; + + enum + { + kRingUserKind = 3, + kRingDriverKind = 0, + }; + + ProcessTime PTime; + PID ProcessId{kSchedInvalidPID}; + Int32 Ring{kRingDriverKind}; + Int32 Kind{kUserKind}; + + public: + //! @brief boolean operator, check status. + operator bool() + { + return Status != ProcessStatus::kDead; + } + + //! @brief Crash the app, exits with code ~0. + void Crash(); + + //! @brief Exits app. + void Exit(Int32 exitCode = 0); + + //! @brief TLS Allocate + VoidPtr New(const SizeT& sz); + + //! @brief TLS Free. + Boolean Delete(VoidPtr ptr, const SizeT& sz); + + //! @brief Wakes up threads. + void Wake(const bool wakeup = false); + + // ProcessHeader getters. + public: + //! @brief ProcessHeader name getter, example: "C RunTime" + const Char* GetName(); + + const ProcessSelector& GetSelector(); + const ProcessStatus& GetStatus(); + const AffinityKind& GetAffinity(); + + private: + friend ProcessScheduler; + friend ProcessHelper; + }; + + /// \brief Processs Team (contains multiple processes inside it.) + /// Equivalent to a process batch + class ProcessTeam final + { + public: + explicit ProcessTeam() = default; + ~ProcessTeam() = default; + + NEWOS_COPY_DEFAULT(ProcessTeam); + + MutableArray<Ref<ProcessHeader>>& AsArray(); + Ref<ProcessHeader>& AsRef(); + + public: + MutableArray<Ref<ProcessHeader>> mProcessList; + Ref<ProcessHeader> mCurrentProcess; + }; + + using ProcessHeaderRef = ProcessHeader*; + + /// @brief ProcessHeader manager class. + /// The main class which you call to schedule an app. + class ProcessScheduler final + { + private: + explicit ProcessScheduler() = default; + + public: + ~ProcessScheduler() = default; + + NEWOS_COPY_DEFAULT(ProcessScheduler) + + operator bool() + { + return mTeam.AsArray().Count() > 0; + } + bool operator!() + { + return mTeam.AsArray().Count() == 0; + } + + ProcessTeam& CurrentTeam() + { + return mTeam; + } + + SizeT Add(Ref<ProcessHeader>& headerRef); + bool Remove(SizeT headerIndex); + + Ref<ProcessHeader>& GetCurrent(); + SizeT Run() noexcept; + + static Ref<ProcessScheduler> Shared(); + + private: + ProcessTeam mTeam; + }; - enum { - kUserKind = 3, - kLibKind = 3, - kDriverKind = 0, - kKindCount, - }; - - enum { - kRingUserKind = 3, - kRingDriverKind = 0, - }; - - ProcessTime PTime; - PID ProcessId{kSchedInvalidPID}; - Int32 Ring{kRingDriverKind}; - Int32 Kind{kUserKind}; - - public: - //! @brief boolean operator, check status. - operator bool() { return Status != ProcessStatus::kDead; } - - //! @brief Crash the app, exits with code ~0. - void Crash(); - - //! @brief Exits app. - void Exit(Int32 exitCode = 0); - - //! @brief TLS Allocate - VoidPtr New(const SizeT &sz); - - //! @brief TLS Free. - Boolean Delete(VoidPtr ptr, const SizeT &sz); - - //! @brief Wakes up threads. - void Wake(const bool wakeup = false); - - // ProcessHeader getters. - public: - //! @brief ProcessHeader name getter, example: "C RunTime" - const Char *GetName(); - - const ProcessSelector &GetSelector(); - const ProcessStatus &GetStatus(); - const AffinityKind &GetAffinity(); - - private: - friend ProcessScheduler; - friend ProcessHelper; -}; - -/// \brief Processs Team (contains multiple processes inside it.) -/// Equivalent to a process batch -class ProcessTeam final { - public: - explicit ProcessTeam() = default; - ~ProcessTeam() = default; - - NEWOS_COPY_DEFAULT(ProcessTeam); - - MutableArray<Ref<ProcessHeader>> &AsArray(); - Ref<ProcessHeader> &AsRef(); - - public: - MutableArray<Ref<ProcessHeader>> mProcessList; - Ref<ProcessHeader> mCurrentProcess; -}; - -using ProcessHeaderRef = ProcessHeader *; - -/// @brief ProcessHeader manager class. -/// The main class which you call to schedule an app. -class ProcessScheduler final { - private: - explicit ProcessScheduler() = default; - - public: - ~ProcessScheduler() = default; - - NEWOS_COPY_DEFAULT(ProcessScheduler) - - operator bool() { return mTeam.AsArray().Count() > 0; } - bool operator!() { return mTeam.AsArray().Count() == 0; } - - ProcessTeam &CurrentTeam() { return mTeam; } - - SizeT Add(Ref<ProcessHeader> &headerRef); - bool Remove(SizeT headerIndex); - - Ref<ProcessHeader> &GetCurrent(); - SizeT Run() noexcept; - - static Ref<ProcessScheduler> Shared(); - - private: - ProcessTeam mTeam; -}; - -/* + /* * 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<ProcessHeader> &process); - static PID &GetCurrentPID(); - static bool StartScheduling(); -}; - -const Int32 &rt_get_exit_code() noexcept; -} // namespace NewOS + class ProcessHelper final + { + public: + static bool Switch(HAL::StackFrame* newStack, const PID& newPid); + static bool CanBeScheduled(Ref<ProcessHeader>& process); + static PID& GetCurrentPID(); + static bool StartScheduling(); + }; + + const Int32& rt_get_exit_code() noexcept; +} // namespace NewOS #include <KernelKit/ThreadLocalStorage.hxx> diff --git a/Private/KernelKit/SMPManager.hpp b/Private/KernelKit/SMPManager.hpp index b7f78ebd..191cad88 100644 --- a/Private/KernelKit/SMPManager.hpp +++ b/Private/KernelKit/SMPManager.hpp @@ -16,110 +16,114 @@ #define kMaxHarts 8 -namespace NewOS { -using ThreadID = UInt32; - -enum ThreadKind { - kHartSystemReserved, // System reserved thread, well user can't use it - kHartStandard, // user thread, cannot be used by kernel - kHartFallback, // fallback thread, cannot be used by user if not clear or - // used by kernel. - kHartBoot, // The core we booted from, the mama. - kInvalidHart, - kHartCount, -}; - -typedef enum ThreadKind SmThreadKind; -typedef ThreadID SmThreadID; - -/// -/// \name HardwareThread -/// @brief CPU Hardware Thread (POWER, x64, or 64x0) -/// - -class HardwareThread final { - public: - explicit HardwareThread(); - ~HardwareThread(); - - public: - NEWOS_COPY_DEFAULT(HardwareThread) - - 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* fStack; - ThreadKind fKind; - ThreadID fID; - bool fWakeup; - bool fBusy; - Int64 fPID; - - private: - friend class SMPManager; -}; - -/// -/// \name SMPManager -/// @brief Multi processor manager to manage other cores and dispatch tasks. -/// - -class SMPManager final { - private: - explicit SMPManager(); - - public: - ~SMPManager(); - - public: - NEWOS_COPY_DEFAULT(SMPManager); - - public: - bool Switch(HAL::StackFrame* the); - HAL::StackFramePtr GetStackFrame() noexcept; - - public: - Ref<HardwareThread> 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(); - - public: - /// @brief Returns the amount of threads present in the system. - /// @returns SizeT the amount of cores present. - SizeT Count() noexcept; - - private: - Array<HardwareThread, kMaxHarts> fThreadList; - ThreadID fCurrentThread{0}; -}; - -/// @brief wakes up thread. -/// wakes up thread from hang. -Void rt_wakeup_thread(HAL::StackFramePtr stack); - -/// @brief makes thread sleep. -/// hooks and hangs thread to prevent code from executing. -Void rt_hang_thread(HAL::StackFramePtr stack); -} // namespace NewOS - -#endif // !__SMP_MANAGER__ +namespace NewOS +{ + using ThreadID = UInt32; + + enum ThreadKind + { + kHartSystemReserved, // System reserved thread, well user can't use it + kHartStandard, // user thread, cannot be used by kernel + kHartFallback, // fallback thread, cannot be used by user if not clear or + // used by kernel. + kHartBoot, // The core we booted from, the mama. + kInvalidHart, + kHartCount, + }; + + typedef enum ThreadKind SmThreadKind; + typedef ThreadID SmThreadID; + + /// + /// \name HardwareThread + /// @brief CPU Hardware Thread (POWER, x64, or 64x0) + /// + + class HardwareThread final + { + public: + explicit HardwareThread(); + ~HardwareThread(); + + public: + NEWOS_COPY_DEFAULT(HardwareThread) + + 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* fStack; + ThreadKind fKind; + ThreadID fID; + bool fWakeup; + bool fBusy; + Int64 fPID; + + private: + friend class SMPManager; + }; + + /// + /// \name SMPManager + /// @brief Multi processor manager to manage other cores and dispatch tasks. + /// + + class SMPManager final + { + private: + explicit SMPManager(); + + public: + ~SMPManager(); + + public: + NEWOS_COPY_DEFAULT(SMPManager); + + public: + bool Switch(HAL::StackFrame* the); + HAL::StackFramePtr GetStackFrame() noexcept; + + public: + Ref<HardwareThread> 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(); + + public: + /// @brief Returns the amount of threads present in the system. + /// @returns SizeT the amount of cores present. + SizeT Count() noexcept; + + private: + Array<HardwareThread, kMaxHarts> fThreadList; + ThreadID fCurrentThread{0}; + }; + + /// @brief wakes up thread. + /// wakes up thread from hang. + Void rt_wakeup_thread(HAL::StackFramePtr stack); + + /// @brief makes thread sleep. + /// hooks and hangs thread to prevent code from executing. + Void rt_hang_thread(HAL::StackFramePtr stack); +} // namespace NewOS + +#endif // !__SMP_MANAGER__ diff --git a/Private/KernelKit/Semaphore.hpp b/Private/KernelKit/Semaphore.hpp index ede1b921..523fecb5 100644 --- a/Private/KernelKit/Semaphore.hpp +++ b/Private/KernelKit/Semaphore.hpp @@ -13,31 +13,30 @@ namespace NewOS { class ProcessHeader; - typedef ProcessHeader* ProcessHeaderRef; - - /// @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(ProcessHeader* process); - bool LockOrWait(ProcessHeader* process, const Int64& seconds); - - public: - NEWOS_COPY_DEFAULT(Semaphore); - - private: - ProcessHeaderRef fLockingProcess{ nullptr }; - - }; -} + typedef ProcessHeader* ProcessHeaderRef; + + /// @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(ProcessHeader* process); + bool LockOrWait(ProcessHeader* process, const Int64& seconds); + + public: + NEWOS_COPY_DEFAULT(Semaphore); + + private: + ProcessHeaderRef fLockingProcess{nullptr}; + }; +} // namespace NewOS diff --git a/Private/KernelKit/ThreadLocalStorage.hxx b/Private/KernelKit/ThreadLocalStorage.hxx index bdf00a8a..8072b867 100644 --- a/Private/KernelKit/ThreadLocalStorage.hxx +++ b/Private/KernelKit/ThreadLocalStorage.hxx @@ -16,28 +16,29 @@ #define kCookieMag2 'R' template <typename T> -T *tls_new_ptr(void); +T* tls_new_ptr(void); template <typename T> -bool tls_delete_ptr(T *ptr); +bool tls_delete_ptr(T* ptr); template <typename T, typename... Args> -T *tls_new_class(Args &&...args); +T* tls_new_class(Args&&... args); #define kTLSCookieLen 3 /// @brief Thread Information Block for Local Storage. /// Located in GS on AMD64, Virtual Address 0x10000 (64x0, 32x0, ARM64) -struct PACKED ThreadInformationBlock final { - NewOS::Char Cookie[kTLSCookieLen]; - NewOS::UIntPtr StartCode; // Start Address - NewOS::UIntPtr StartData; // Allocation Heap - NewOS::UIntPtr StartStack; // Stack Pointer. - NewOS::Int32 ThreadID; // Thread execution ID. +struct PACKED ThreadInformationBlock final +{ + NewOS::Char Cookie[kTLSCookieLen]; + NewOS::UIntPtr StartCode; // Start Address + NewOS::UIntPtr StartData; // Allocation Heap + NewOS::UIntPtr StartStack; // Stack Pointer. + NewOS::Int32 ThreadID; // Thread execution ID. }; /// @brief TLS install TIB and PIB. -EXTERN_C void rt_install_tib(ThreadInformationBlock *TIB, NewOS::VoidPtr PIB); +EXTERN_C void rt_install_tib(ThreadInformationBlock* TIB, NewOS::VoidPtr PIB); ///! @brief Cookie Sanity check. NewOS::Boolean tls_check_tib(ThreadInformationBlock* Ptr); diff --git a/Private/KernelKit/ThreadLocalStorage.inl b/Private/KernelKit/ThreadLocalStorage.inl index 2b920d0f..9c80d9b8 100644 --- a/Private/KernelKit/ThreadLocalStorage.inl +++ b/Private/KernelKit/ThreadLocalStorage.inl @@ -11,40 +11,45 @@ #endif template <typename T> -inline T* tls_new_ptr(void) { - using namespace NewOS; +inline T* tls_new_ptr(void) +{ + using namespace NewOS; - MUST_PASS(ProcessScheduler::Shared().Leak().GetCurrent()); + MUST_PASS(ProcessScheduler::Shared().Leak().GetCurrent()); - auto ref_process = ProcessScheduler::Shared().Leak().GetCurrent(); + auto ref_process = ProcessScheduler::Shared().Leak().GetCurrent(); - T* pointer = (T*)ref_process.Leak().New(sizeof(T)); - return pointer; + T* pointer = (T*)ref_process.Leak().New(sizeof(T)); + return pointer; } //! @brief TLS delete implementation. template <typename T> -inline bool tls_delete_ptr(T* ptr) { - if (!ptr) return false; +inline bool tls_delete_ptr(T* ptr) +{ + if (!ptr) + return false; - using namespace NewOS; + using namespace NewOS; - MUST_PASS(ProcessScheduler::Shared().Leak().GetCurrent()); + MUST_PASS(ProcessScheduler::Shared().Leak().GetCurrent()); - ptr->~T(); + ptr->~T(); - auto ref_process = ProcessScheduler::Shared().Leak().GetCurrent(); - return ref_process.Leak().Delete(ptr, sizeof(T)); + auto ref_process = ProcessScheduler::Shared().Leak().GetCurrent(); + return ref_process.Leak().Delete(ptr, sizeof(T)); } template <typename T, typename... Args> -T* tls_new_class(Args&&... args) { - T* ptr = tls_new_ptr<T>(); +T* tls_new_class(Args&&... args) +{ + T* ptr = tls_new_ptr<T>(); - if (ptr) { - *ptr = T(NewOS::forward(args)...); - return ptr; - } + if (ptr) + { + *ptr = T(NewOS::forward(args)...); + return ptr; + } - return nullptr; + return nullptr; } diff --git a/Private/KernelKit/Timer.hpp b/Private/KernelKit/Timer.hpp index dbd29af1..fac1b11f 100644 --- a/Private/KernelKit/Timer.hpp +++ b/Private/KernelKit/Timer.hpp @@ -13,53 +13,53 @@ namespace NewOS { -class HardwareTimer; -class HardwareTimerInterface; - -class HardwareTimerInterface -{ - public: - /// @brief Default constructor - explicit HardwareTimerInterface() = default; - virtual ~HardwareTimerInterface() = default; - - public: - NEWOS_COPY_DEFAULT(HardwareTimerInterface); - - public: - virtual Int32 Wait() noexcept; -}; - -class HardwareTimer final : public HardwareTimerInterface -{ - public: - explicit HardwareTimer(Int64 seconds); - ~HardwareTimer() override; - - public: - NEWOS_COPY_DEFAULT(HardwareTimer); - - public: - Int32 Wait() noexcept 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); -} + class HardwareTimer; + class HardwareTimerInterface; + + class HardwareTimerInterface + { + public: + /// @brief Default constructor + explicit HardwareTimerInterface() = default; + virtual ~HardwareTimerInterface() = default; + + public: + NEWOS_COPY_DEFAULT(HardwareTimerInterface); + + public: + virtual Int32 Wait() noexcept; + }; + + class HardwareTimer final : public HardwareTimerInterface + { + public: + explicit HardwareTimer(Int64 seconds); + ~HardwareTimer() override; + + public: + NEWOS_COPY_DEFAULT(HardwareTimer); + + public: + Int32 Wait() noexcept 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); + } } // namespace NewOS diff --git a/Private/KernelKit/UserHeap.hpp b/Private/KernelKit/UserHeap.hpp index e1455b49..7bdd4d1d 100644 --- a/Private/KernelKit/UserHeap.hpp +++ b/Private/KernelKit/UserHeap.hpp @@ -18,27 +18,29 @@ /// @brief memory heap for user programs. #define kUserHeapMaxSz (4096) -#define kUserHeapMag (0xFAF0FEF0) - -namespace NewOS { -typedef enum { - /// @brief Driver only heap. - kUserHeapDriver = 0x2, - /// @brief Shared heap. - kUserHeapShared = 0x4, - /// @brief User and private heap. - kUserHeapUser = 0x6, - /// @brief Read and Write heap. - kUserHeapRw = 0x8, -} kUserHeapFlags; - -/// @brief Allocate a process heap, no zero out is done here. -/// @param flags -/// @return The process's heap. -VoidPtr rt_new_heap(Int32 flags); - -/// @brief Frees the process heap. -/// @param pointer The process heap pointer. -/// @return -Int32 rt_free_heap(voidPtr pointer); -} // namespace NewOS +#define kUserHeapMag (0xFAF0FEF0) + +namespace NewOS +{ + typedef enum + { + /// @brief Driver only heap. + kUserHeapDriver = 0x2, + /// @brief Shared heap. + kUserHeapShared = 0x4, + /// @brief User and private heap. + kUserHeapUser = 0x6, + /// @brief Read and Write heap. + kUserHeapRw = 0x8, + } kUserHeapFlags; + + /// @brief Allocate a process heap, no zero out is done here. + /// @param flags + /// @return The process's heap. + VoidPtr rt_new_heap(Int32 flags); + + /// @brief Frees the process heap. + /// @param pointer The process heap pointer. + /// @return + Int32 rt_free_heap(voidPtr pointer); +} // namespace NewOS diff --git a/Private/KernelKit/XCOFF.hxx b/Private/KernelKit/XCOFF.hxx index 631efdf3..36c70e96 100644 --- a/Private/KernelKit/XCOFF.hxx +++ b/Private/KernelKit/XCOFF.hxx @@ -16,23 +16,23 @@ #include <NewKit/Defines.hpp> -#define kXCOFF64Magic 0x01F7 +#define kXCOFF64Magic 0x01F7 -#define kXCOFFRelFlg 0x0001 +#define kXCOFFRelFlg 0x0001 #define kXCOFFExecutable 0x0002 -#define kXCOFFLnno 0x0004 -#define kXCOFFLSyms 0x0008 +#define kXCOFFLnno 0x0004 +#define kXCOFFLSyms 0x0008 /// @brief XCoff file header, meant for POWER apps. typedef struct XCoffFileHeader { - NewOS::UInt16 fMagic; - NewOS::UInt16 fTarget; - NewOS::UInt16 fNumSecs; - NewOS::UInt32 fTimeDat; - NewOS::UIntPtr fSymPtr; - NewOS::UInt32 fNumSyms; - NewOS::UInt16 fOptHdr; // ?: Number of bytes in optional header + NewOS::UInt16 fMagic; + NewOS::UInt16 fTarget; + NewOS::UInt16 fNumSecs; + NewOS::UInt32 fTimeDat; + NewOS::UIntPtr fSymPtr; + NewOS::UInt32 fNumSyms; + NewOS::UInt16 fOptHdr; // ?: Number of bytes in optional header } XCoffFileHeader; #endif // ifndef __XCOFF__ |
