diff options
Diffstat (limited to 'dev')
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 9 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/Storage/SATA.cc | 247 | ||||
| -rw-r--r-- | dev/Kernel/src/KString.cc | 6 |
3 files changed, 161 insertions, 101 deletions
diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 75219dc6..ef1ce21f 100644 --- a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -104,6 +104,8 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) process.Leak().Crash(); } +EXTERN BOOL kAHCICommandIssued; + /// @brief Handle any generic fault. /// @param rsp EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) @@ -111,7 +113,10 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) + { + kout << "Getting here.\r"; return; + } kIsScheduling = NO; @@ -134,6 +139,8 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) { + kout << "Kernel: SIGTRAP\r"; + while (YES) ; } @@ -148,7 +155,7 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status; - kout << "Kernel: SIGKILL status.\r"; + kout << "Kernel: SIGTRAP status.\r"; process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; } diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc index 7f8f8a5d..784033dd 100644 --- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc +++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc @@ -1,21 +1,21 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + Copyright (C) 2024-2025, DeVrije-Aker Corporation, all rights reserved. ------------------------------------------- */ /** * @file AHCI.cc - * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) + * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) * @brief AHCI driver. * @version 0.1 * @date 2024-02-02 * - * @Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + * @Copyright (C) 2024, DeVrije-Aker, all rights reserved. * */ -#include "NewKit/Defines.h" +#include "HALKit/AMD64/Processor.h" #include <KernelKit/UserProcessScheduler.h> #include <KernelKit/LPC.h> @@ -28,61 +28,49 @@ #ifdef __AHCI__ #define kHBAErrTaskFile (1 << 30) -#define kHBACmdGhc (1 << 31) -#define kHBACmdAE (0x80000000) -#define kHBAPxCmdST (0x0001) -#define kHBAPxCmdFre (0x0010) -#define kHBAPxCmdFR (0x4000) -#define kHBAPxCmdCR (0x8000) +#define kHBAPxCmdST 0x0001 +#define kHBAPxCmdFre 0x0010 +#define kHBAPxCmdFR 0x4000 +#define kHBAPxCmdCR 0x8000 -#define kSATALBAMode (1 << 6) +#define kSataLBAMode (1 << 6) -#define kSATASRBsy (0x80) -#define kSATASRDrq (0x08) +#define kAhciSRBsy (0x80) +#define kAhciSRDrq (0x08) -#define kSATAPortCnt (0x20) +#define kAhciPortCnt 32 -#define kSATAProgIfAHCI (0x01) -#define kSATASubClass (0x06) -#define kSATABar5 (0x24) +enum +{ + kSATAProgIfAHCI = 0x01, + kSATASubClass = 0x06, + kSATABar5 = 0x24, +}; -STATIC Kernel::PCI::Device kDevice; +STATIC Kernel::PCI::Device kPCIDevice; STATIC HbaMem* kSATA = nullptr; STATIC Kernel::SizeT kSATAPortIdx = 0UL; STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; -STATIC Kernel::Char kCurrentDiskModel[50] = {"UNKNOWN SATA DRIVE"}; template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept; +static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept; -static Kernel::Int32 drvi_find_cmd_slot(HbaPort* port) noexcept; +static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept; -static Kernel::Void drvi_calculate_disk_geometry() noexcept; +static Kernel::Void drv_calculate_disk_geometry() noexcept; -static Kernel::Void drvi_calculate_disk_geometry() noexcept +static Kernel::Void drv_calculate_disk_geometry() noexcept { kCurrentDiskSectorCount = 0UL; - Kernel::UInt8* identify_data = new Kernel::UInt8[512]; + Kernel::UInt8 identify_data[kib_cast(4)] = {0}; - drvi_std_input_output<NO, NO, YES>(0, identify_data, 0, 512); + drv_std_input_output<NO, YES, YES>(0, identify_data, 0, kib_cast(8)); kCurrentDiskSectorCount = (identify_data[61] << 16) | identify_data[60]; - for (Kernel::Int32 i = 0; i < 20; i++) - { - kCurrentDiskModel[i * 2] = identify_data[27 + i] >> 8; - kCurrentDiskModel[i * 2 + 1] = identify_data[27 + i + 1] & 0xFF; - } - - kCurrentDiskModel[40] = '\0'; - - kout << "Drive Model: " << kCurrentDiskModel << endl; - kout << "Disk Size: " << Kernel::number(drv_get_size()) << endl; - kout << "Highest Disk LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl; - - delete[] identify_data; + kout << "Highest LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl; } /// @brief Initializes an AHCI disk. @@ -96,49 +84,100 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { - kDevice = iterator[device_index].Leak(); // And then leak the reference. + kPCIDevice = iterator[device_index].Leak(); // And then leak the reference. // if SATA and then interface is AHCI... - if (kDevice.Subclass() == kSATASubClass && - kDevice.ProgIf() == kSATAProgIfAHCI) + if (kPCIDevice.Subclass() == kSATASubClass && + kPCIDevice.ProgIf() == kSATAProgIfAHCI) { - HbaMem* mem_ahci = (HbaMem*)kDevice.Bar(kSATABar5); + kPCIDevice.EnableMmio(0x24); // Enable the memory index_byte/o for this ahci device. + kPCIDevice.BecomeBusMaster(0x24); // Become bus master for this ahci device, so that we can control it. - kDevice.EnableMmio(kDevice.Bar(kSATABar5)); // Enable the memory index_byte/o for this ahci device. - kDevice.BecomeBusMaster(kDevice.Bar(kSATABar5)); // Become bus master for this ahci device, so that we can control it. + HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(0x24); Kernel::UInt32 ports_implemented = mem_ahci->Pi; Kernel::UInt16 ahci_index = 0; - const Kernel::UInt16 kMaxPortsImplemented = kSATAPortCnt; + const Kernel::UInt16 kMaxPortsImplemented = kAhciPortCnt; const Kernel::UInt32 kSATASignature = 0x00000101; - const Kernel::UInt8 kSATAPresent = 0x03; - const Kernel::UInt8 kSATAIPMActive = 0x01; + const Kernel::UInt8 kAhciPresent = 0x03; + const Kernel::UInt8 kAhciIPMActive = 0x01; + + Kernel::Boolean detected = false; while (ahci_index < kMaxPortsImplemented) { if (ports_implemented) { + kout << "Port is implemented.\r"; + Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; - if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == kSATAPresent && ipm == kSATAIPMActive && - (mem_ahci->Ports[ahci_index].Ssts & 0xF)) + if (mem_ahci->Ports[ahci_index].Sig == kSATASignature) { - kout << "Port is implemented as SATA.\r"; + kout << "Port is SATA.\r"; kSATAPortIdx = ahci_index; kSATA = mem_ahci; - drvi_calculate_disk_geometry(); + kSATA->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdST; + kSATA->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdFre; + + while (YES) + { + if (kSATA->Ports[kSATAPortIdx].Cmd & kHBAPxCmdFR) + continue; + if (kSATA->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR) + continue; + + break; + } + + const auto kAHCIBaseAddress = mib_cast(4); + + kSATA->Ports[kSATAPortIdx].Clb = kAHCIBaseAddress + (kSATAPortIdx << 10); + kSATA->Ports[kSATAPortIdx].Clbu = 0; + + rt_set_memory((VoidPtr)((UIntPtr)kSATA->Ports[kSATAPortIdx].Clb), 0, 1024); + + kSATA->Ports[kSATAPortIdx].Fb = kAHCIBaseAddress + (32 << 10) + (kSATAPortIdx << 8); + kSATA->Ports[kSATAPortIdx].Fbu = 0; + + rt_set_memory((VoidPtr)((UIntPtr)kSATA->Ports[kSATAPortIdx].Fb), 0, 256); + + HbaCmdHeader* cmdheader = (HbaCmdHeader*)((UIntPtr)kSATA->Ports[kSATAPortIdx].Clb); + + for (int i = 0; i < 32; i++) + { + cmdheader[i].Prdtl = 8; + + cmdheader[i].Ctba = kAHCIBaseAddress + (40 << 10) + (kSATAPortIdx << 13) + (i << 8); + cmdheader[i].Ctbau = 0; + + rt_set_memory((VoidPtr)(UIntPtr)cmdheader[i].Ctba, 0, 256); + } + + while (kSATA->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR) + { + } + + kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre; + kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST; - return YES; + drv_calculate_disk_geometry(); + + detected = YES; + + break; } } ports_implemented >>= 1; ++ahci_index; } + + return detected; } } @@ -147,24 +186,27 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) Kernel::Boolean drv_std_detected(Kernel::Void) { - return kDevice.DeviceId() != 0xFFFF && kCurrentDiskSectorCount > 0; + return kPCIDevice.DeviceId() != 0xFFFF; } Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) { - drvi_std_input_output<YES, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer); + drv_std_input_output<YES, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer); } Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) { - drvi_std_input_output<NO, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer); + drv_std_input_output<NO, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer); } -static Kernel::Int32 drvi_find_cmd_slot(HbaPort* port) noexcept +static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept { - Kernel::UInt32 slots = port->Ci; + if (port == nullptr) + return -1; - for (Kernel::Int32 i = 0; i < kSATAPortCnt; i++) + Kernel::UInt32 slots = (kSATA->Ports[kSATAPortIdx].Sact | kSATA->Ports[kSATAPortIdx].Ci); + + for (Kernel::Int32 i = 0; i < ((kSATA->Cap & 0x1F) + 1); i++) { if ((slots & 1) == 0) return i; @@ -175,46 +217,55 @@ static Kernel::Int32 drvi_find_cmd_slot(HbaPort* port) noexcept return -1; } +BOOL kAHCICommandIssued = NO; + template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept +static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept { - const Kernel::SizeT slot = drvi_find_cmd_slot(&kSATA->Ports[kSATAPortIdx]); + kSATA->Ports[kSATAPortIdx].Is = -1; + kSATA->Is = -1; + + auto slot = 0L; + + slot = drv_find_cmd_slot(&kSATA->Ports[kSATAPortIdx]); if (slot == -1) return; - if (size_buffer > mib_cast(4)) - Kernel::ke_panic(RUNTIME_CHECK_FAILED, "AHCI only supports < 4mib DMA transfers per PRD."); - - if (!Write) - Kernel::rt_set_memory(buffer, 0, size_buffer); + volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATA->Ports[kSATAPortIdx].Clb + kSATA->Ports[kSATAPortIdx].Clbu)); - HbaCmdHeader* ATTRIBUTE(aligned(1024)) command_header = ((HbaCmdHeader*)((Kernel::UInt64)(kSATA->Ports[kSATAPortIdx].Clb))); + command_header += slot; - command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); - command_header->Write = Write; - command_header->Prdtl = 1; - command_header->Atapi = 0; - command_header->Prefetchable = 0; + MUST_PASS(command_header); - HbaCmdTbl* command_table = ((HbaCmdTbl*)((Kernel::UInt64)(command_header->Ctba))); + command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); + command_header->Write = Write; + command_header->Prdtl = (size_buffer / kib_cast(8)) / sizeof(HbaPrdtEntry) + 1; - Kernel::rt_set_memory(command_table, 0, sizeof(HbaCmdTbl)); + volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba + command_header->Ctbau); MUST_PASS(command_table); - auto phys_dma_buf = (Kernel::UIntPtr)Kernel::HAL::hal_get_phys_address(buffer); + auto buffer_phys = Kernel::HAL::hal_get_phys_address(buffer); + + for (Kernel::SizeT i = 0; i < (command_header->Prdtl - 1); i++) + { + command_table->Prdt[i].Dba = ((Kernel::UInt32)(Kernel::UInt64)buffer_phys & 0xFFFFFFFF); + command_table->Prdt[i].Dbau = (((Kernel::UInt64)buffer_phys >> 32) & 0xFFFFFFFF); + command_table->Prdt[i].Dbc = (16 - 1); + command_table->Prdt[i].Ie = YES; + + size_buffer -= 16; + buffer += 16; + } + + volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)((Kernel::UInt64)&command_table->Cfis); - command_table->Prdt[0].Dbau = (((Kernel::UInt64)phys_dma_buf >> 32)); - command_table->Prdt[0].Dba = ((Kernel::UInt32)(Kernel::UInt64)phys_dma_buf); - command_table->Prdt[0].Dbc = ((size_buffer)-1); - command_table->Prdt[0].Ie = 1; + h2d_fis->FisType = kFISTypeRegH2D; - FisRegH2D* h2d_fis = (FisRegH2D*)((Kernel::UInt64)&command_table->Cfis); + h2d_fis->CmdOrCtrl = YES; - h2d_fis->FisType = kFISTypeRegH2D; - h2d_fis->CmdOrCtrl = CommandOrCTRL; - h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx; + h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx; if (Identify) h2d_fis->Command = kAHCICmdIdentify; @@ -226,28 +277,30 @@ static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buf h2d_fis->Lba4 = (lba >> 32) & 0xFF; h2d_fis->Lba5 = (lba >> 40) & 0xFF; - h2d_fis->Device = kSATALBAMode; - - // 28-bit LBA mode, fis is done being configured. + h2d_fis->Device = kSataLBAMode; h2d_fis->CountLow = sector_sz & 0xFF; h2d_fis->CountHigh = (sector_sz >> 8) & 0xFF; - if (kSATA->Is & kHBAErrTaskFile) - Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component."); + while ((kSATA->Ports[kSATAPortIdx].Tfd & (kAhciSRBsy | kAhciSRDrq))) + { + kout << "Waiting for slot to be ready\r"; + } - kSATA->Ports[kSATAPortIdx].Ie = 1; + kSATA->Ports[kSATAPortIdx].Ci = 1 << slot; + kAHCICommandIssued = YES; - kSATA->Ports[kSATAPortIdx].Cmd = kHBAPxCmdFR | kHBAPxCmdST; - kSATA->Ports[kSATAPortIdx].Ci = (1 << slot); + while (kSATA->Ports[kSATAPortIdx].Ci & (1 << slot)) + { - while (!drv_is_ready()) - ; -} + kout << Kernel::number(slot) << endl; -BOOL drv_is_ready(void) -{ - return kSATA->Ports[kSATAPortIdx].Ci == 0; + if (kSATA->Is & kHBAErrTaskFile) // check for task file error. + { + Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component."); + return; + } + } } /*** @@ -266,4 +319,4 @@ Kernel::SizeT drv_get_size() return (drv_get_sector_count()) * kAHCISectorSize; } -#endif // ifdef __AHCI__ +#endif // ifdef __AHCI__
\ No newline at end of file diff --git a/dev/Kernel/src/KString.cc b/dev/Kernel/src/KString.cc index ca6a2009..f37a16ad 100644 --- a/dev/Kernel/src/KString.cc +++ b/dev/Kernel/src/KString.cc @@ -14,17 +14,17 @@ namespace Kernel { Char* KString::Data() { - return fData; + return this->fData; } const Char* KString::CData() const { - return fData; + return const_cast<const Char*>(this->fData); } Size KString::Length() const { - return fDataSz; + return this->fDataSz; } bool KString::operator==(const KString& rhs) const |
