diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-03-25 15:35:28 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-03-25 15:35:28 +0100 |
| commit | 0ead895f52d24dad009f738037a7795d4e3d840a (patch) | |
| tree | 863fd1c881fc7bf26ab78b932421e6416bbef288 /dev/kernel/HALKit/AMD64 | |
| parent | 59dbe4cffc7c633709ef8b45f49c46daf7f74e92 (diff) | |
kernel: Refactor AHCI I/O path, enhance memory allocators, and cleanup obsolete script
- Removed unused `build_gcc.sh` script.
- Namespaced CPU feature flags under `NeOS` and transitioned from enum to unnamed enum for scoping.
- Renamed `drv_std_input_output` to `drv_std_input_output_ahci` for clarity.
- Improved AHCI driver documentation and added zeroing for read buffers.
- Added optional `pad` parameter to memory allocators: `mm_alloc_bitmap`, `mm_new_heap`, `PageMgr::Request`, etc.
- Updated bitmap allocator to correctly handle and align with padded sizes.
- Added `fPad` field to memory header block.
- Fixed `ATA-DMA` mode comment, corrected PRD usage and logic.
- Improved code documentation and formatting in `UserProcessScheduler`, `PageMgr`, and related components.
- Enhanced safety in process memory cleanup (e.g., `StackReserve` cleanup).
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64')
| -rw-r--r-- | dev/kernel/HALKit/AMD64/CPUID.h | 131 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Paging.h | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 48 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc | 36 |
4 files changed, 129 insertions, 88 deletions
diff --git a/dev/kernel/HALKit/AMD64/CPUID.h b/dev/kernel/HALKit/AMD64/CPUID.h index 7f04ac27..6ea84106 100644 --- a/dev/kernel/HALKit/AMD64/CPUID.h +++ b/dev/kernel/HALKit/AMD64/CPUID.h @@ -15,72 +15,73 @@ #include <NewKit/Defines.h> -enum CPUFeatureEnum -{ - kCPUFeatureSSE3 = 1 << 0, - kCPUFeaturePCLMUL = 1 << 1, - kCPUFeatureDTES64 = 1 << 2, - kCPUFeatureMONITOR = 1 << 3, - kCPUFeatureDS_CPL = 1 << 4, - kCPUFeatureVMX = 1 << 5, - kCPUFeatureSMX = 1 << 6, - kCPUFeatureEST = 1 << 7, - kCPUFeatureTM2 = 1 << 8, - kCPUFeatureSSSE3 = 1 << 9, - kCPUFeatureCID = 1 << 10, - kCPUFeatureSDBG = 1 << 11, - kCPUFeatureFMA = 1 << 12, - kCPUFeatureCX16 = 1 << 13, - kCPUFeatureXTPR = 1 << 14, - kCPUFeaturePDCM = 1 << 15, - kCPUFeaturePCID = 1 << 17, - kCPUFeatureDCA = 1 << 18, - kCPUFeatureSSE4_1 = 1 << 19, - kCPUFeatureSSE4_2 = 1 << 20, - kCPUFeatureX2APIC = 1 << 21, - kCPUFeatureMOVBE = 1 << 22, - kCPUFeaturePOP3C = 1 << 23, - kCPUFeatureECXTSC = 1 << 24, - kCPUFeatureAES = 1 << 25, - kCPUFeatureXSAVE = 1 << 26, - kCPUFeatureOSXSAVE = 1 << 27, - kCPUFeatureAVX = 1 << 28, - kCPUFeatureF16C = 1 << 29, - kCPUFeatureRDRAND = 1 << 30, - kCPUFeatureHYPERVISOR = 1 << 31, - kCPUFeatureFPU = 1 << 0, - kCPUFeatureVME = 1 << 1, - kCPUFeatureDE = 1 << 2, - kCPUFeaturePSE = 1 << 3, - kCPUFeatureEDXTSC = 1 << 4, - kCPUFeatureMSR = 1 << 5, - kCPUFeaturePAE = 1 << 6, - kCPUFeatureMCE = 1 << 7, - kCPUFeatureCX8 = 1 << 8, - kCPUFeatureAPIC = 1 << 9, - kCPUFeatureSEP = 1 << 11, - kCPUFeatureMTRR = 1 << 12, - kCPUFeaturePGE = 1 << 13, - kCPUFeatureMCA = 1 << 14, - kCPUFeatureCMOV = 1 << 15, - kCPUFeaturePAT = 1 << 16, - kCPUFeaturePSE36 = 1 << 17, - kCPUFeaturePSN = 1 << 18, - kCPUFeatureCLFLUSH = 1 << 19, - kCPUFeatureDS = 1 << 21, - kCPUFeatureACPI = 1 << 22, - kCPUFeatureMMX = 1 << 23, - kCPUFeatureFXSR = 1 << 24, - kCPUFeatureSSE = 1 << 25, - kCPUFeatureSSE2 = 1 << 26, - kCPUFeatureSS = 1 << 27, - kCPUFeatureHTT = 1 << 28, - kCPUFeatureTM = 1 << 29, - kCPUFeatureIA64 = 1 << 30, - kCPUFeaturePBE = 1 << 31 -}; - namespace NeOS { + + enum + { + kCPUFeatureSSE3 = 1 << 0, + kCPUFeaturePCLMUL = 1 << 1, + kCPUFeatureDTES64 = 1 << 2, + kCPUFeatureMONITOR = 1 << 3, + kCPUFeatureDS_CPL = 1 << 4, + kCPUFeatureVMX = 1 << 5, + kCPUFeatureSMX = 1 << 6, + kCPUFeatureEST = 1 << 7, + kCPUFeatureTM2 = 1 << 8, + kCPUFeatureSSSE3 = 1 << 9, + kCPUFeatureCID = 1 << 10, + kCPUFeatureSDBG = 1 << 11, + kCPUFeatureFMA = 1 << 12, + kCPUFeatureCX16 = 1 << 13, + kCPUFeatureXTPR = 1 << 14, + kCPUFeaturePDCM = 1 << 15, + kCPUFeaturePCID = 1 << 17, + kCPUFeatureDCA = 1 << 18, + kCPUFeatureSSE4_1 = 1 << 19, + kCPUFeatureSSE4_2 = 1 << 20, + kCPUFeatureX2APIC = 1 << 21, + kCPUFeatureMOVBE = 1 << 22, + kCPUFeaturePOP3C = 1 << 23, + kCPUFeatureECXTSC = 1 << 24, + kCPUFeatureAES = 1 << 25, + kCPUFeatureXSAVE = 1 << 26, + kCPUFeatureOSXSAVE = 1 << 27, + kCPUFeatureAVX = 1 << 28, + kCPUFeatureF16C = 1 << 29, + kCPUFeatureRDRAND = 1 << 30, + kCPUFeatureHYPERVISOR = 1 << 31, + kCPUFeatureFPU = 1 << 0, + kCPUFeatureVME = 1 << 1, + kCPUFeatureDE = 1 << 2, + kCPUFeaturePSE = 1 << 3, + kCPUFeatureEDXTSC = 1 << 4, + kCPUFeatureMSR = 1 << 5, + kCPUFeaturePAE = 1 << 6, + kCPUFeatureMCE = 1 << 7, + kCPUFeatureCX8 = 1 << 8, + kCPUFeatureAPIC = 1 << 9, + kCPUFeatureSEP = 1 << 11, + kCPUFeatureMTRR = 1 << 12, + kCPUFeaturePGE = 1 << 13, + kCPUFeatureMCA = 1 << 14, + kCPUFeatureCMOV = 1 << 15, + kCPUFeaturePAT = 1 << 16, + kCPUFeaturePSE36 = 1 << 17, + kCPUFeaturePSN = 1 << 18, + kCPUFeatureCLFLUSH = 1 << 19, + kCPUFeatureDS = 1 << 21, + kCPUFeatureACPI = 1 << 22, + kCPUFeatureMMX = 1 << 23, + kCPUFeatureFXSR = 1 << 24, + kCPUFeatureSSE = 1 << 25, + kCPUFeatureSSE2 = 1 << 26, + kCPUFeatureSS = 1 << 27, + kCPUFeatureHTT = 1 << 28, + kCPUFeatureTM = 1 << 29, + kCPUFeatureIA64 = 1 << 30, + kCPUFeaturePBE = 1 << 31 + }; + typedef Int64 CPUID; } // namespace NeOS diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h index 4e2ac1b1..09b6ade3 100644 --- a/dev/kernel/HALKit/AMD64/Paging.h +++ b/dev/kernel/HALKit/AMD64/Paging.h @@ -88,7 +88,7 @@ namespace NeOS::HAL NE_PTE* ALIGN(kPageAlign) fEntries[kPageMax]; }; - auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; + auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, const SizeT pad = 0) -> VoidPtr; auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; } // namespace NeOS::HAL diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc index bd5c86f4..b1584c80 100644 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc @@ -63,7 +63,7 @@ STATIC Char kCurrentDiskModel[50] = {"UNKNOWN AHCI DRIVE"}; STATIC UInt16 kSATAPortsImplemented = 0U; template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept; +STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept; STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept; @@ -73,21 +73,29 @@ STATIC Void drv_compute_disk_ahci() noexcept { kSATASectorCount = 0UL; + /// Normally 512 bytes, but add an additional 512 bytes to make 1 KIB. const UInt16 kSzIdent = kib_cast(1); + /// Push it to the stack UInt8 identify_data[kSzIdent] = {0}; rt_set_memory(identify_data, 0, kSzIdent); - drv_std_input_output<NO, YES, YES>(0, identify_data, kAHCISectorSize, kSzIdent); + /// Send AHCI command. + drv_std_input_output_ahci<NO, YES, YES>(0, identify_data, kAHCISectorSize, kSzIdent); + /// Extract 28-bit LBA. kSATASectorCount = (identify_data[61] << 16) | identify_data[60]; + /// Show what we got. kout << "Disk Model: " << kCurrentDiskModel << kendl; kout << "Disk Size: " << number(drv_get_size()) << kendl; kout << "Disk Sector Count: " << number(kSATASectorCount) << kendl; } +/// @brief Finds a command slot for a HBA port. +/// @param port The port to search on. +/// @return The slot, or ~0. STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept { UInt32 slots = (port->Sact | port->Ci); @@ -103,8 +111,13 @@ STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept return ~0; } +/// @brief Send an AHCI command, according to the template parameters. +/// @param lba Logical Block Address to look for. +/// @param buffer The data buffer to transfer. +/// @param sector_sz The disk's sector size (unused) +/// @param size_buffer The size of the **buffer** parameter. template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept +STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept { UIntPtr slot = 0UL; @@ -113,6 +126,12 @@ STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, Siz if (slot == ~0) return; + if (!Write) + { + // Zero-memory the buffer field. + rt_set_memory(buffer, 0, size_buffer); + } + volatile HbaCmdHeader* command_header = ((HbaCmdHeader*)(((UInt64)kSATAHba->Ports[kSATAIndex].Clb))); command_header += slot; @@ -310,6 +329,8 @@ STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi) return NO; } +/// @brief Checks if an AHCI device is detected. +/// @return Either if detected, or not found. Bool drv_std_detected_ahci() { return kSATADev.DeviceId() != (UShort)PCI::PciConfigKind::Invalid && kSATADev.Bar(kSATABar5) != 0; @@ -317,6 +338,7 @@ Bool drv_std_detected_ahci() namespace NeOS { + /// @brief Initialize an AHCI device (StorageKit) UInt16 sk_init_ahci_device(BOOL atapi) { UInt16 pi = 0; @@ -327,6 +349,7 @@ namespace NeOS return pi; } + /// @brief Implementation details namespace. namespace Detail { /// @brief Read AHCI device. @@ -344,7 +367,7 @@ namespace NeOS if (!disk) return; - drv_std_input_output<NO, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize); + drv_std_input_output_ahci<NO, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize); } /// @brief Write AHCI device. @@ -362,10 +385,13 @@ namespace NeOS if (!disk) return; - drv_std_input_output<YES, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize); + drv_std_input_output_ahci<YES, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize); } } // namespace Detail + /// @brief Acquires a new AHCI device with drv_index in mind. + /// @param drv_index The drive index to assign. + /// @return A wrapped device interface if successful, or error code. ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(Int32 drv_index) { if (!drv_std_detected_ahci()) @@ -382,16 +408,24 @@ namespace NeOS } } // namespace NeOS +// ================================================================================================ + +// +// This applies only if we compile with AHCI as a default disk driver. +// + +// ================================================================================================ + #ifdef __AHCI__ Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { - drv_std_input_output<YES, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer); + drv_std_input_output_ahci<YES, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer); } Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { - drv_std_input_output<NO, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer); + drv_std_input_output_ahci<NO, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer); } Bool drv_std_init(UInt16& pi) diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc index 0a03dafc..9624ea5b 100644 --- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc @@ -7,7 +7,7 @@ /** * @file ATA-PIO.cc * @author Amlal EL Mahrouss (amlal@nekernel.org) - * @brief ATA driver (PIO mode). + * @brief ATA driver (DMA mode). * @version 0.1 * @date 2024-02-02 * @@ -131,17 +131,15 @@ Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) return NO; } -namespace Detail +namespace NeOS::Detail { - using namespace NeOS; - struct PRDEntry { UInt32 mAddress; UInt16 mByteCount; UInt16 mFlags; }; -} // namespace Detail +} // namespace NeOS::Detail static UIntPtr kReadAddr = mib_cast(2); static UIntPtr kWriteAddr = mib_cast(4); @@ -151,7 +149,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz Lba /= SectorSz; if (Size > kib_cast(64)) - ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + return; UInt8 Command = ((!Master) ? 0xE0 : 0xF0); @@ -168,7 +166,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - Detail::PRDEntry* prd = (Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct. + NeOS::Detail::PRDEntry* prd = (NeOS::Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct. prd->mAddress = (UInt32)(UIntPtr)kReadAddr; prd->mByteCount = Size - 1; @@ -196,7 +194,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS Lba /= SectorSz; if (Size > kib_cast(64)) - ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + return; UInt8 Command = ((!Master) ? 0xE0 : 0xF0); @@ -211,10 +209,11 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - Detail::PRDEntry* prd = (Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4); - prd->mAddress = (UInt32)(UIntPtr)kWriteAddr; - prd->mByteCount = Size - 1; - prd->mFlags = 0x8000; + NeOS::Detail::PRDEntry* prd = (NeOS::Detail::PRDEntry*)(kATADevice.Bar(0x20) + 4); + + prd->mAddress = (UInt32)(UIntPtr)kWriteAddr; + prd->mByteCount = Size - 1; + prd->mFlags = 0x8000; rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32)(UIntPtr)prd); rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA); @@ -230,21 +229,28 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS prd = nullptr; } -/// @brief is ATA detected? +/***********************************************************************************/ +/// @brief Is ATA detected? +/***********************************************************************************/ Boolean drv_std_detected(Void) { return kATADetected; } +/***********************************************************************************/ /*** - @brief Getter, gets the number of sectors inside the drive. + @brief Gets the number of sectors inside the drive. + @return Number of sectors, or zero. */ +/***********************************************************************************/ NeOS::SizeT drv_get_sector_count() { return (kATAData[61] << 16) | kATAData[60]; } -/// @brief Get the drive size. +/***********************************************************************************/ +/// @brief Get the size of the current drive. +/***********************************************************************************/ NeOS::SizeT drv_get_size() { return (drv_get_sector_count()) * kATASectorSize; |
