From d445096b8403ad0bdbf0095c50f66ba01fde9f33 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 1 Apr 2024 23:57:19 +0200 Subject: Kernel: Bringing support 48-bit ATA PIO. Kernel: Adding support for IPCEP. Kernel: Improve scheduler, create heap according to process kind. Kernel: PRD transfer enum for upcoming ATA DMA driver. Kernel: Add kErrorNoEntrypoint. NewBoot: Add 48-bit support for ATA PIO. Signed-off-by: Amlal El Mahrouss --- Private/CFKit/IPCEndpoint.hxx | 27 ---- Private/HALKit/AMD64/Storage/ATA-DMA.cxx | 0 Private/HALKit/AMD64/Storage/ATA-PIO.cxx | 177 +++++++++++++++++++++++++++ Private/HALKit/AMD64/Storage/ATA.cxx | 175 -------------------------- Private/KernelKit/HError.hpp | 1 + Private/KernelKit/UserHeap.hpp | 6 +- Private/NetworkKit/IPCEP.hxx | 45 +++++++ Private/NewBoot/Source/HEL/AMD64/BootATA.cxx | 2 + Private/Source/ProcessScheduler.cxx | 33 +++-- Private/Source/URL.cxx | 8 +- Private/StorageKit/PRDT.hpp | 6 + 11 files changed, 256 insertions(+), 224 deletions(-) delete mode 100644 Private/CFKit/IPCEndpoint.hxx create mode 100644 Private/HALKit/AMD64/Storage/ATA-DMA.cxx create mode 100644 Private/HALKit/AMD64/Storage/ATA-PIO.cxx delete mode 100644 Private/HALKit/AMD64/Storage/ATA.cxx create mode 100644 Private/NetworkKit/IPCEP.hxx diff --git a/Private/CFKit/IPCEndpoint.hxx b/Private/CFKit/IPCEndpoint.hxx deleted file mode 100644 index bc697dc7..00000000 --- a/Private/CFKit/IPCEndpoint.hxx +++ /dev/null @@ -1,27 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#ifndef _INC_IPC_ENDPOINT_HXX_ -#define _INC_IPC_ENDPOINT_HXX_ - -#include -#include - -/// @brief Includes macros and utilities to make an IPC connection. - -/// IA separator. -#define kRemoteSeparator "." - -/// Interchange address, consists of domain+namespace. -#define kRemoteInvalid "00.00.00.00:00000000" -#define kRemoteMaxLen 21 - -namespace NewOS { -typedef UIntPtr ipc_method_type; -typedef Char ipc_remote_type[kRemoteMaxLen]; -} // namespace NewOS - -#endif // _INC_IPC_ENDPOINT_HXX_ \ No newline at end of file diff --git a/Private/HALKit/AMD64/Storage/ATA-DMA.cxx b/Private/HALKit/AMD64/Storage/ATA-DMA.cxx new file mode 100644 index 00000000..e69de29b diff --git a/Private/HALKit/AMD64/Storage/ATA-PIO.cxx b/Private/HALKit/AMD64/Storage/ATA-PIO.cxx new file mode 100644 index 00000000..0f8a0d75 --- /dev/null +++ b/Private/HALKit/AMD64/Storage/ATA-PIO.cxx @@ -0,0 +1,177 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +/** + * @file ATA-PIO.cxx + * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) + * @brief ATA driver (PIO mode). + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) Mahrouss Logic + * + */ + +#include +#include + +using namespace NewOS; +using namespace NewOS::HAL; + +/// bugs: 0 + +#define kATADataLen 256 + +static Boolean kATADetected = false; +static Int32 kATADeviceType = kATADeviceCount; +static Char kATAData[kATADataLen] = {0}; + +Boolean drv_ata_wait_io(UInt16 IO) { + for (int i = 0; i < 4; i++) In8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto statRdy = In8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = In8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) return false; + + if (!(statRdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_ata_select(UInt16 Bus) { + if (Bus == ATA_PRIMARY_IO) + Out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); + else + Out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); +} + +Boolean drv_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, + UInt8& OutMaster) { + if (drv_ata_detected()) return false; + + UInt16 IO = Bus; + + drv_ata_select(IO); + + // Bus init, NEIN bit. + Out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good. +ATAInit_Retry: + auto statRdy = In8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) { + kcout << "NewOS: ATA: Select error, not an IDE based hard-drive.\r\n"; + + return false; + } + + if ((statRdy & ATA_SR_BSY)) goto ATAInit_Retry; + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + rt_set_memory(kATAData, 0, kATADataLen); + + /// fetch serial info + /// model, speed, number of sectors... + + drv_ata_wait_io(IO); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { + kATAData[indexData] = In16(IO + ATA_REG_DATA); + } + + OutBus = Bus; + OutMaster = (OutBus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + Out8(Bus + ATA_REG_HDDEVSEL, 0xA0 | ATA_MASTER << 4); + + In8(Bus + ATA_REG_CONTROL); + In8(Bus + ATA_REG_CONTROL); + In8(Bus + ATA_REG_CONTROL); + In8(Bus + ATA_REG_CONTROL); + + unsigned cl = In8(Bus + ATA_CYL_LOW); /* get the "signature bytes" */ + unsigned ch = In8(Bus + ATA_CYL_HIGH); + + /* differentiate ATA, ATAPI, SATA and SATAPI */ + if (cl == 0x14 && ch == 0xEB) { + kcout << "NewOS: PATAPI drive detected.\r\n"; + kATADeviceType = kATADevicePATA_PI; + } + if (cl == 0x69 && ch == 0x96) { + kcout << "NewOS: SATAPI drive detected.\r\n"; + kATADeviceType = kATADeviceSATA_PI; + } + + if (cl == 0x0 && ch == 0x0) { + kcout << "NewOS: PATA drive detected.\r\n"; + kATADeviceType = kATADevicePATA; + } + + if (cl == 0x3c && ch == 0xc3) { + kcout << "NewOS: SATA drive detected.\r\n"; + kATADeviceType = kATADeviceSATA; + } + + Out8(IO + ATA_REG_CONTROL, 0x02); + + return true; +} + +Void drv_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, + SizeT SectorSz, SizeT Size) { + UInt8 Command = (!Master ? 0xE0 : 0xF0); + + Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0xF)); + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz); + + Out8(IO + ATA_REG_LBA0, (Lba)); + Out8(IO + ATA_REG_LBA1, (Lba) >> 8); + Out8(IO + ATA_REG_LBA2, (Lba) >> 16); + Out8(IO + ATA_REG_LBA3, (Lba) >> 24); + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); + + drv_ata_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + WideChar chr = In16(IO + ATA_REG_DATA); + + Buf[IndexOff] = chr; + } +} + +Void drv_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, + SizeT SectorSz, SizeT Size) { + UInt8 Command = (!Master ? 0xE0 : 0xF0); + + Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0xF)); + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz); + + Out8(IO + ATA_REG_LBA0, (Lba)); + Out8(IO + ATA_REG_LBA1, (Lba) >> 8); + Out8(IO + ATA_REG_LBA2, (Lba) >> 16); + Out8(IO + ATA_REG_LBA3, (Lba) >> 24); + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + + drv_ata_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + Out16(IO + ATA_REG_DATA, Buf[IndexOff]); + + } +} + +/// @check is ATA detected? +Boolean drv_ata_detected(Void) { return kATADetected; } diff --git a/Private/HALKit/AMD64/Storage/ATA.cxx b/Private/HALKit/AMD64/Storage/ATA.cxx deleted file mode 100644 index b2191250..00000000 --- a/Private/HALKit/AMD64/Storage/ATA.cxx +++ /dev/null @@ -1,175 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -/** - * @file ATA.cxx - * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) - * @brief ATA driver. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Mahrouss Logic - * - */ - -#include -#include - -using namespace NewOS; -using namespace NewOS::HAL; - -/// bugs: 0 - -#define kATADataLen 256 - -static Boolean kATADetected = false; -static Int32 kATADeviceType = kATADeviceCount; -static Char kATAData[kATADataLen] = {0}; - -Boolean drv_ata_wait_io(UInt16 IO) { - for (int i = 0; i < 4; i++) In8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto statRdy = In8(IO + ATA_REG_STATUS); - - if ((statRdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - statRdy = In8(IO + ATA_REG_STATUS); - - if (statRdy & ATA_SR_ERR) return false; - - if (!(statRdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -Void drv_ata_select(UInt16 Bus) { - if (Bus == ATA_PRIMARY_IO) - Out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - Out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, - UInt8& OutMaster) { - if (drv_ata_detected()) return false; - - UInt16 IO = Bus; - - drv_ata_select(IO); - - // Bus init, NEIN bit. - Out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto statRdy = In8(IO + ATA_REG_STATUS); - - if (statRdy & ATA_SR_ERR) { - kcout << "NewOS: ATA: Select error, not an IDE based hard-drive.\r\n"; - - return false; - } - - if ((statRdy & ATA_SR_BSY)) goto ATAInit_Retry; - - Out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - rt_set_memory(kATAData, 0, kATADataLen); - - /// fetch serial info - /// model, speed, number of sectors... - - drv_ata_wait_io(IO); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { - kATAData[indexData] = In16(IO + ATA_REG_DATA); - } - - OutBus = Bus; - OutMaster = (OutBus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - Out8(Bus + ATA_REG_HDDEVSEL, 0xA0 | ATA_MASTER << 4); - - In8(Bus + ATA_REG_CONTROL); - In8(Bus + ATA_REG_CONTROL); - In8(Bus + ATA_REG_CONTROL); - In8(Bus + ATA_REG_CONTROL); - - unsigned cl = In8(Bus + ATA_CYL_LOW); /* get the "signature bytes" */ - unsigned ch = In8(Bus + ATA_CYL_HIGH); - - /* differentiate ATA, ATAPI, SATA and SATAPI */ - if (cl == 0x14 && ch == 0xEB) { - kcout << "NewOS: PATAPI drive detected.\r\n"; - kATADeviceType = kATADevicePATA_PI; - } - if (cl == 0x69 && ch == 0x96) { - kcout << "NewOS: SATAPI drive detected.\r\n"; - kATADeviceType = kATADeviceSATA_PI; - } - - if (cl == 0x0 && ch == 0x0) { - kcout << "NewOS: PATA drive detected.\r\n"; - kATADeviceType = kATADevicePATA; - } - - if (cl == 0x3c && ch == 0xc3) { - kcout << "NewOS: SATA drive detected.\r\n"; - kATADeviceType = kATADeviceSATA; - } - - Out8(IO + ATA_REG_CONTROL, 0x02); - - return true; -} - -Void drv_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, - SizeT SectorSz, SizeT Size) { - UInt8 Command = (!Master ? 0xE0 : 0xF0); - - Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0xF)); - Out8(IO + ATA_REG_SEC_COUNT0, SectorSz); - - Out8(IO + ATA_REG_LBA0, (Lba)); - Out8(IO + ATA_REG_LBA1, (Lba) >> 8); - Out8(IO + ATA_REG_LBA2, (Lba) >> 16); - - Out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - drv_ata_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { - WideChar chr = In16(IO + ATA_REG_DATA); - - Buf[IndexOff] = chr; - } -} - -Void drv_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, - SizeT SectorSz, SizeT Size) { - UInt8 Command = (!Master ? 0xE0 : 0xF0); - - Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0xF)); - Out8(IO + ATA_REG_SEC_COUNT0, SectorSz); - - Out8(IO + ATA_REG_LBA0, (Lba)); - Out8(IO + ATA_REG_LBA1, (Lba) >> 8); - Out8(IO + ATA_REG_LBA2, (Lba) >> 16); - - Out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - drv_ata_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { - Out16(IO + ATA_REG_DATA, Buf[IndexOff]); - - } -} - -/// @check is ATA detected? -Boolean drv_ata_detected(Void) { return kATADetected; } diff --git a/Private/KernelKit/HError.hpp b/Private/KernelKit/HError.hpp index d5a16fd6..a0105d64 100644 --- a/Private/KernelKit/HError.hpp +++ b/Private/KernelKit/HError.hpp @@ -33,6 +33,7 @@ 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 kErrorUnimplemented = 0; Boolean ke_bug_check(void) noexcept; diff --git a/Private/KernelKit/UserHeap.hpp b/Private/KernelKit/UserHeap.hpp index c919db53..e1455b49 100644 --- a/Private/KernelKit/UserHeap.hpp +++ b/Private/KernelKit/UserHeap.hpp @@ -22,9 +22,13 @@ namespace NewOS { typedef enum { - kUserHeapHypervisor = 0x2, + /// @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; diff --git a/Private/NetworkKit/IPCEP.hxx b/Private/NetworkKit/IPCEP.hxx new file mode 100644 index 00000000..b3b8a759 --- /dev/null +++ b/Private/NetworkKit/IPCEP.hxx @@ -0,0 +1,45 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#ifndef _INC_IPC_ENDPOINT_HXX_ +#define _INC_IPC_ENDPOINT_HXX_ + +#include +#include + +/// @brief IPC Endpoint Protocol (IPCEP) definition. + +/// IA separator. +#define kRemoteSeparator "." + +/// Interchange address, consists of domain+namespace. +#define kRemoteInvalid "00.00.00.00:0" +#define kRemoteMaxLen 21 + +#define kRemoteHeaderMagic 0xFFEEAACCEE + +namespace NewOS { +/// @brief 96-bit number to represent the domain and namespace +struct PACKED IPCEPNumber final { + UInt32 RemoteAddress; + UInt64 RemoteNamespace; +}; + +typedef struct IPCEPNumber IPCEPNumberType; + +/// @brief IPCEP connection header +typedef struct IPCEPConnectionHeader final { + UInt64 IpcHeader; // 0xFFEEAACCEE + UInt8 IpcEndianess; // 0 : LE, 1 : BE + SizeT IpcPacketSize; + IPCEPNumberType IpcFrom; + IPCEPNumberType IpcTo; + UInt32 IpcCRC32; + Char IpcPad[8]; +} PACKED IPCEPConnectionHeader; +} // namespace NewOS + +#endif // _INC_IPC_ENDPOINT_HXX_ \ No newline at end of file diff --git a/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx b/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx index ed591412..3f309f31 100644 --- a/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/BootATA.cxx @@ -143,6 +143,7 @@ Void boot_ata_read(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, Out8(IO + ATA_REG_LBA0, (Lba)); Out8(IO + ATA_REG_LBA1, (Lba) >> 8); Out8(IO + ATA_REG_LBA2, (Lba) >> 16); + Out8(IO + ATA_REG_LBA3, (Lba) >> 24); Out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); @@ -176,6 +177,7 @@ Void boot_ata_write(UInt64 Lba, UInt16 IO, UInt8 Master, CharacterTypeUTF8* Buf, Out8(IO + ATA_REG_LBA0, (Lba)); Out8(IO + ATA_REG_LBA1, (Lba) >> 8); Out8(IO + ATA_REG_LBA2, (Lba) >> 16); + Out8(IO + ATA_REG_LBA3, (Lba) >> 24); Out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); diff --git a/Private/Source/ProcessScheduler.cxx b/Private/Source/ProcessScheduler.cxx index 5d8a7f56..59b9bcea 100644 --- a/Private/Source/ProcessScheduler.cxx +++ b/Private/Source/ProcessScheduler.cxx @@ -146,37 +146,36 @@ void ProcessHeader::Exit(Int32 exit_code) { SizeT ProcessScheduler::Add(Ref &process) { if (!process) return -1; + + if (!process.Leak().Image) { + if (process.Leak().Kind != ProcessHeader::kLibKind) { + return -kErrorNoEntrypoint; + } + } + if (!mTeam.AsArray().Count() > kSchedProcessLimitPerTeam) return -kErrorOutOfTeamSlot; if (process.Leak().Ring != (Int32)ProcessSelector::kRingKernel) return -1; kcout << "ProcessScheduler::Add(Ref& process)\r\n"; - process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw); - process.Leak().ProcessId = mTeam.AsArray().Count(); - process.Leak().HeapCursor = process.Leak().HeapPtr; + /// Create heap according to type of process. + if (process.Leak().Kind == ProcessHeader::kUserKind) + process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw); + else if (process.Leak().Kind == ProcessHeader::kLibKind) + process.Leak().HeapPtr = rt_new_heap(kUserHeapUser | kUserHeapRw || kUserHeapShared); + else + process.Leak().HeapPtr = rt_new_heap(kUserHeapDriver | kUserHeapRw); process.Leak().StackFrame = reinterpret_cast( ke_new_ke_heap(sizeof(HAL::StackFrame), true, false)); MUST_PASS(process.Leak().StackFrame); - UIntPtr imageStart = reinterpret_cast(process.Leak().Image); - - process.Leak().SetEntrypoint(imageStart); - mTeam.AsArray().Add(process); - if (!imageStart && process.Leak().Kind == ProcessHeader::kUserKind) { - process.Leak().Crash(); - } - - if (!imageStart && process.Leak().Kind == ProcessHeader::kDriverKind) { - if (process.Leak().Ring == 3) - process.Leak().Crash(); - else - ke_stop(RUNTIME_CHECK_PROCESS); - } + process.Leak().ProcessId = mTeam.AsArray().Count() - 1; + process.Leak().HeapCursor = process.Leak().HeapPtr; return mTeam.AsArray().Count() - 1; } diff --git a/Private/Source/URL.cxx b/Private/Source/URL.cxx index fba6bca9..c384c378 100644 --- a/Private/Source/URL.cxx +++ b/Private/Source/URL.cxx @@ -16,10 +16,10 @@ Url::Url(StringView &strUrl) : m_urlView(strUrl, false) {} Url::~Url() = default; constexpr const char *kURLProtocols[] = { - "https", // http with tls. - "http", // http - "file", // filesystem protocol - "ftp", // file transfer protocol + "file", // Filesystem protocol + "ping", // Ping protocol. + "telnet", // Telnet protocol + "ssh", // SSH protocol }; constexpr const int kUrlOutSz = 3; //! such as: :// diff --git a/Private/StorageKit/PRDT.hpp b/Private/StorageKit/PRDT.hpp index f3f4aa67..48886db6 100644 --- a/Private/StorageKit/PRDT.hpp +++ b/Private/StorageKit/PRDT.hpp @@ -12,6 +12,12 @@ #define kPrdtTransferSize (sizeof(NewOS::UShort)) namespace NewOS { +enum { + kPRDTTransferInProgress, + kPRDTTransferIsDone, + kPRDTTransferCount, +}; + class PRDT final { public: explicit PRDT() = delete; -- cgit v1.2.3