summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel/HALKit/AMD64/Storage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-31 12:10:05 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-31 12:10:05 +0100
commit44a080365293be62538b056dcd135ca673ebc5db (patch)
treeb10a9c93d52a7302bc5067f4b9c5388c8fbe2a2d /dev/Kernel/HALKit/AMD64/Storage
parentaf68a93fe0b049e19fd260423873b72b70ac75cf (diff)
ADD: Disk Driver has been reverted, working on that version now.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/Kernel/HALKit/AMD64/Storage')
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/ATA.cc4
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA.cc174
2 files changed, 90 insertions, 88 deletions
diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA.cc
index 0e1120a2..9b16d866 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/ATA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/ATA.cc
@@ -157,7 +157,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz
rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz - 1) / SectorSz));
- rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
+ rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF);
rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
@@ -209,7 +209,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz - 1)) / SectorSz));
- rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
+ rt_out8(IO + ATA_REG_LBA0, (Lba)&0xFF);
rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
index 66793b3e..71161ed4 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
@@ -1,6 +1,6 @@
/* -------------------------------------------
- Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.
------------------------------------------- */
@@ -15,7 +15,6 @@
*
*/
-#include <stdint.h>
#include <KernelKit/UserProcessScheduler.h>
#include <KernelKit/LPC.h>
@@ -48,10 +47,9 @@ enum
};
STATIC Kernel::PCI::Device kPCIDevice;
-STATIC HbaMem* kSATAPort = nullptr;
+STATIC HbaMem* kSATAPort = nullptr;
STATIC Kernel::SizeT kSATAPortIdx = 0UL;
STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL;
-STATIC Kernel::Char kModel[41] = {0};
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept;
@@ -64,28 +62,14 @@ static Kernel::Void drv_calculate_disk_geometry() noexcept
{
kCurrentDiskSectorCount = 0UL;
- Kernel::UInt8 identify_data[256] = {0};
+ Kernel::UInt8 identify_data[kib_cast(4)] = {};
- drv_std_input_output<NO, YES, YES>(0, identify_data, 0, 256);
+ drv_std_input_output<NO, YES, YES>(0, identify_data, 0, kib_cast(8));
- Kernel::UInt32 lba28_sectors = (identify_data[61] << 16) | identify_data[60];
+ kCurrentDiskSectorCount = (identify_data[61] << 16) | identify_data[60];
- kCurrentDiskSectorCount = lba28_sectors;
-
- Kernel::UInt32 i = 0;
-
- for (i = 0; i < 20; i++)
- {
- // 20 words = 40 bytes
- kModel[i * 2] = identify_data[27 + i] >> 8; // High byte first
- kModel[i * 2 + 1] = identify_data[27 + i] & 0xFF; // Low byte
- }
-
- kModel[40] = '\0'; // Null-terminate
-
- kcout << "Disk Model: " << kModel << endl;
kcout << "Disk Size: " << Kernel::number(drv_get_size()) << endl;
- kcout << "Disk Highest LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl;
+ kcout << "Highest Disk LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl;
}
/// @brief Initializes an AHCI disk.
@@ -105,11 +89,11 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
if (kPCIDevice.Subclass() == kSATASubClass &&
kPCIDevice.ProgIf() == kSATAProgIfAHCI)
{
- HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(kSATABar5);
-
kPCIDevice.EnableMmio(kSATABar5); // Enable the memory index_byte/o for this ahci device.
kPCIDevice.BecomeBusMaster(kSATABar5); // Become bus master for this ahci device, so that we can control it.
+ HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(kSATABar5);
+
Kernel::UInt32 ports_implemented = mem_ahci->Pi;
Kernel::UInt16 ahci_index = 0;
@@ -131,42 +115,72 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1)
{
- kcout << "Port is SATA.\r";
+ kcout << "Port is implemented as SATA.\r";
kSATAPortIdx = ahci_index;
kSATAPort = mem_ahci;
- // Enable AHCI Mode FIRST
- kSATAPort->Ghc |= (1 << 31);
+ kSATAPort->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdST;
+ kSATAPort->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdFre;
- const int timeout = 1000000;
- int attempts = 0;
- while ((kSATAPort->Ports[kSATAPortIdx].Tfd & 0x80) && (attempts < timeout))
+ while (YES)
{
- attempts++;
+ if (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdFR)
+ continue;
+
+ if (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR)
+ continue;
+
+ break;
}
- if (attempts == timeout)
+
+ const auto kAHCIBaseAddress = mib_cast(4);
+
+ kSATAPort->Ports[kSATAPortIdx].Clb = kAHCIBaseAddress + (kSATAPortIdx << 10);
+ kSATAPort->Ports[kSATAPortIdx].Clbu = 0;
+
+ rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb), 0, 1024);
+
+ kSATAPort->Ports[kSATAPortIdx].Fb = kAHCIBaseAddress + (32 << 10) + (kSATAPortIdx << 8);
+ kSATAPort->Ports[kSATAPortIdx].Fbu = 0;
+
+ rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Fb), 0, 256);
+
+ HbaCmdHeader* cmd_header = (HbaCmdHeader*)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb);
+
+ for (Int32 i = 0; i < 32; i++)
{
- kcout << "Error: Drive is still busy after waiting.\r";
- return NO;
+ cmd_header[i].Prdtl = 8;
+
+ cmd_header[i].Ctba = kAHCIBaseAddress + (40 << 10) + (kSATAPortIdx << 13) + (i << 8);
+ cmd_header[i].Ctbau = 0;
+
+ rt_set_memory((VoidPtr)(UIntPtr)cmd_header[i].Ctba, 0, 256);
}
- kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST;
+ while (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR)
+ ;
+
kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre;
+ kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST;
drv_calculate_disk_geometry();
- return YES;
+ detected = YES;
+
+ break;
}
}
ports_implemented >>= 1;
++ahci_index;
}
+
+ return detected;
}
}
- return NO;
+ return No;
}
Kernel::Boolean drv_std_detected(Kernel::Void)
@@ -189,14 +203,14 @@ static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept
if (port == nullptr)
return -1;
- kcout << "Finding a slot...\r";
-
Kernel::UInt32 slots = (kSATAPort->Ports[kSATAPortIdx].Sact | kSATAPort->Ports[kSATAPortIdx].Ci);
for (Kernel::Int32 i = 0; i < ((kSATAPort->Cap & 0x1F) + 1); i++)
{
- if ((slots & (1 << i)) == 0)
+ if ((slots & 1) == 0)
return i;
+
+ slots >>= 1;
}
return -1;
@@ -205,6 +219,11 @@ static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept
{
+ if (!CommandOrCTRL)
+ return;
+
+ kSATAPort->Ports[kSATAPortIdx].Is = -1;
+
auto slot = 0L;
slot = drv_find_cmd_slot(&kSATAPort->Ports[kSATAPortIdx]);
@@ -212,43 +231,35 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
if (slot == -1)
return;
- if (size_buffer > kib_cast(8))
- return;
+ volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb + kSATAPort->Ports[kSATAPortIdx].Clbu));
- volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb));
command_header += slot;
MUST_PASS(command_header);
command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32);
command_header->Write = Write;
- command_header->Prdtl = (Kernel::UInt16)(kib_cast(8) - 1) >> 4 + 1;
-
- volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba);
+ command_header->Prdtl = (Kernel::UInt16)((size_buffer - 1) >> 4) + 1;
- Kernel::rt_set_memory((void*)command_table, 0, sizeof(HbaCmdTbl));
+ volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba + command_header->Ctbau);
MUST_PASS(command_table);
- Kernel::UInt8* buffer_ahci = new Kernel::UInt8[kib_cast(8)];
-
- Kernel::Int32 i = 0;
-
- command_table->Prdt[0].Dba = (uint32_t)(uint64_t)buffer_ahci & 0xFFFFFFFF;
- command_table->Prdt[0].Dbau = (uint32_t)(uint64_t)buffer_ahci >> 32;
- command_table->Prdt[0].Dbc = (size_buffer << 9) - 1; // 512 bytes per sector
- command_table->Prdt[0].InterruptBit = 1;
+ for (Kernel::SizeT i = 0; i < (command_header->Prdtl - 1); i++)
+ {
+ command_table->PrdtEntries[i].Dba = ((Kernel::UInt32)(Kernel::UInt64)buffer & 0xFFFFFFFF);
+ command_table->PrdtEntries[i].Dbau = (((Kernel::UInt64)buffer >> 32) & 0xFFFFFFFF);
+ command_table->PrdtEntries[i].Dbc = (size_buffer - 1);
+ command_table->PrdtEntries[i].InterruptBit = YES;
- kcout << "LBA: " << Kernel::hex_number(lba) << endl;
- kcout << "PRDT Entry - Dba (Low): " << Kernel::hex_number(command_table->Prdt[0].Dba) << endl;
- kcout << "PRDT Entry - DbaU (High): " << Kernel::hex_number(command_table->Prdt[0].Dbau) << endl;
- kcout << "PRDT Entry - Dbc: " << Kernel::hex_number(command_table->Prdt[0].Dbc) << endl;
+ size_buffer -= 16;
+ buffer += kib_cast(4);
+ }
- volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)(&command_table->Cfis);
+ volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)((Kernel::UInt64)command_table->Cfis);
- Kernel::rt_set_memory((void*)h2d_fis, 0, sizeof(FisRegH2D));
+ h2d_fis->FisType = kFISTypeRegH2D;
- h2d_fis->FisType = 0x27; // H2D
h2d_fis->CmdOrCtrl = CommandOrCTRL;
h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx;
@@ -256,45 +267,36 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
if (Identify)
h2d_fis->Command = kAHCICmdIdentify;
- h2d_fis->Lba0 = (Kernel::UInt32)(lba) & 0xFF;
- h2d_fis->Lba1 = (Kernel::UInt8)(lba >> 8) & 0xFF;
- h2d_fis->Lba2 = (Kernel::UInt8)(lba >> 16) & 0xFF;
+ h2d_fis->Lba0 = lba;
+ h2d_fis->Lba1 = lba >> 8;
+ h2d_fis->Lba2 = lba >> 16;
+ h2d_fis->Lba3 = lba >> 24;
- h2d_fis->Lba3 = (Kernel::UInt8)(lba >> 24) & 0xFF;
- h2d_fis->Lba4 = (Kernel::UInt8)(lba >> 32) & 0xFF;
- h2d_fis->Lba5 = (Kernel::UInt8)(lba >> 40) & 0xFF;
+ h2d_fis->Device = kSataLBAMode;
- h2d_fis->Device = 0; // master device.
+ // 28-bit LBA mode, fis is done being configured.
h2d_fis->CountLow = sector_sz & 0xFF;
h2d_fis->CountHigh = (sector_sz >> 8) & 0xFF;
while ((kSATAPort->Ports[kSATAPortIdx].Tfd & (kAhciSRBsy | kAhciSRDrq)))
{
- kcout << "waiting for slot to be ready\r\n";
+ kcout << "Waiting for slot to be ready...\r\n";
}
- Kernel::UInt32 ahci_status = kSATAPort->Ports[kSATAPortIdx].Tfd;
- kcout << "AHCI Status Before Write: " << Kernel::hex_number(ahci_status) << endl;
+ if (kSATAPort->Is & kHBAErrTaskFile)
+ Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component.");
- kSATAPort->Ports[kSATAPortIdx].Ci = 1 << slot;
+ // send fis/cmdtbl/cmdhdr.
+ kSATAPort->Ports[kSATAPortIdx].Ci |= 1 << slot;
while (kSATAPort->Ports[kSATAPortIdx].Ci & (1 << slot))
+ ;
+
+ while ((kSATAPort->Ports[kSATAPortIdx].Tfd & (kAhciSRBsy | kAhciSRDrq)))
{
- Kernel::UInt32 tfd = kSATAPort->Ports[kSATAPortIdx].Tfd;
- kcout << "AHCI TFD: " << Kernel::number(tfd) << endl;
+ kcout << "Waiting for slot to be ready...\r\n";
}
-
- kcout << "Last Command Sent: " << (int)Kernel::number(h2d_fis->Command) << endl;
-
- ahci_status = kSATAPort->Ports[kSATAPortIdx].Tfd;
-
- kcout << "AHCI Status After Write: " << Kernel::hex_number(ahci_status) << endl;
- kcout << "AHCI STSS: " << Kernel::hex_number(kSATAPort->Ports[kSATAPortIdx].Ssts) << endl;
- kcout << "AHCI SERR: " << Kernel::hex_number(kSATAPort->Ports[kSATAPortIdx].Serr) << endl;
-
- Kernel::rt_copy_memory(buffer_ahci, buffer, size_buffer);
- delete[] buffer_ahci;
}
/***