summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-04 12:04:32 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-04 12:04:32 +0100
commit179b2fcaeb7d1ce1710c4957c2b9848f3f60bbb8 (patch)
tree27f7ff7e0a54e5b30c80458956f4612b9570d319
parent45f6db992d305c9937056e9f7e7205677143d94c (diff)
ADD: AHCI Metadata support, and working towards I/O support.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
-rw-r--r--dev/Boot/amd64-desktop.make4
-rw-r--r--dev/Boot/src/HEL/AMD64/EFIBootStartup.cc (renamed from dev/Boot/src/HEL/AMD64/BootMain.cc)2
-rw-r--r--dev/Boot/src/HEL/ARM64/CoreBootStartup.S36
-rw-r--r--dev/Boot/src/HEL/ARM64/EFIBootStartup.cc (renamed from dev/Boot/src/HEL/ARM64/BootMain.cc)0
-rw-r--r--dev/Kernel/FSKit/NeFS.h1
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc2
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc (renamed from dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc)153
-rw-r--r--dev/Kernel/src/DriveMgr.cc4
-rw-r--r--dev/Kernel/src/HardwareThreadScheduler.cc1
-rw-r--r--dev/Kernel/src/UserProcessScheduler.cc1
-rw-r--r--dev/Mod/AHCI/AHCI.h2
11 files changed, 99 insertions, 107 deletions
diff --git a/dev/Boot/amd64-desktop.make b/dev/Boot/amd64-desktop.make
index d56d5d78..e1d6b113 100644
--- a/dev/Boot/amd64-desktop.make
+++ b/dev/Boot/amd64-desktop.make
@@ -83,7 +83,7 @@ compile-amd64:
.PHONY: run-efi-amd64-ahci
run-efi-amd64-ahci:
- $(EMU) $(EMU_FLAGS) -hdd $(IMG)
+ $(EMU) $(EMU_FLAGS) -hda $(IMG)
.PHONY: run-efi-amd64-ata
run-efi-amd64-ata:
@@ -93,8 +93,6 @@ run-efi-amd64-ata:
.PHONY: epm-img
epm-img:
qemu-img create -f raw $(IMG) 4G
- qemu-img create -f raw $(IMG_2) 4G
- qemu-img create -f raw $(IMG_3) 4G
.PHONY: download-edk
download-edk:
diff --git a/dev/Boot/src/HEL/AMD64/BootMain.cc b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
index f2d6276b..5b05e1bb 100644
--- a/dev/Boot/src/HEL/AMD64/BootMain.cc
+++ b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
@@ -218,6 +218,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle,
syschk_thread->SetName("BootZ: System Recovery Check");
}
+#if 0
Boot::BDiskFormatFactory<BootDeviceATA> partition_factory;
if (syschk_thread->Start(handover_hdr, NO) != kEfiOk)
@@ -244,6 +245,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle,
fb_clear();
}
}
+#endif
// ------------------------------------------ //
// null these fields, to avoid being reused later.
diff --git a/dev/Boot/src/HEL/ARM64/CoreBootStartup.S b/dev/Boot/src/HEL/ARM64/CoreBootStartup.S
new file mode 100644
index 00000000..ee2dd3ec
--- /dev/null
+++ b/dev/Boot/src/HEL/ARM64/CoreBootStartup.S
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Theater Quality Corp, all rights reserved.
+
+------------------------------------------- */
+
+.section .boot_hdr
+.align 4
+
+/* BootZ boot header begin */
+
+boot_hdr_mag:
+ .ascii "CB"
+boot_hdr_name:
+ // it has to match ten bytes.
+ .asciz "zbaosldr\0\0"
+boot_hdr_ver:
+ .word 0x104
+boot_hdr_proc:
+ .long bootloader_start
+
+/* BootZ boot header end */
+
+.extern bootloader_main
+.extern bootloader_stack
+
+.globl bootloader_start
+bootloader_start:
+ adr x0, bootloader_stack
+ ldr x1, =bootloader_start
+ sub x0, x0, x1
+ ldr x0, [x0]
+ mov sp, x0
+
+ bl bootloader_main
+ ret \ No newline at end of file
diff --git a/dev/Boot/src/HEL/ARM64/BootMain.cc b/dev/Boot/src/HEL/ARM64/EFIBootStartup.cc
index 4d303c33..4d303c33 100644
--- a/dev/Boot/src/HEL/ARM64/BootMain.cc
+++ b/dev/Boot/src/HEL/ARM64/EFIBootStartup.cc
diff --git a/dev/Kernel/FSKit/NeFS.h b/dev/Kernel/FSKit/NeFS.h
index 78177e07..5431225c 100644
--- a/dev/Kernel/FSKit/NeFS.h
+++ b/dev/Kernel/FSKit/NeFS.h
@@ -112,6 +112,7 @@ default.
#define kNeFSForkNameLen (200)
#define kNeFSFrameworkExt ".fwrk"
+#define kNeFSStepsExt ".step"
#define kNeFSApplicationExt ".app"
#define kNeFSJournalExt ".jrnl"
diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc
index 1d02ca7b..b9da351a 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc
@@ -189,7 +189,7 @@ Kernel::SizeT drv_get_sector_count()
/// @brief Get the drive size.
Kernel::SizeT drv_get_size()
{
- return drv_get_sector_count() * kATASectorSize;
+ return (drv_get_sector_count()) * kATASectorSize;
}
#endif /* ifdef __ATA_PIO__ */
diff --git a/dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
index 2f8ea774..a3c1474d 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/AHCI-DMA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
@@ -55,10 +55,23 @@ STATIC Kernel::PCI::Device kAhciDevice;
STATIC HbaPort* kAhciPort = nullptr;
STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL;
-Kernel::Void drv_calculate_disk_geometry()
+template <BOOL ReadWrite, BOOL CommandOrCTRL, BOOL Identify>
+static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer);
+
+static Kernel::Void drv_calculate_disk_geometry() noexcept;
+
+static Kernel::Void drv_calculate_disk_geometry() noexcept
{
kCurrentDiskSectorCount = 0UL;
- kcout << "Highest AHCI LBA (48-bit): " << Kernel::number(kCurrentDiskSectorCount) << endl;
+
+ Kernel::UInt8 identify_data[kib_cast(4)] = {};
+
+ drv_std_input_output<NO, YES, YES>(0, identify_data, 0, kib_cast(8));
+
+ kCurrentDiskSectorCount = (identify_data[61] << 16) | identify_data[60];
+
+ kcout << "Disk Size: " << Kernel::number(drv_get_size()) << endl;
+ kcout << "Highest AHCI LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl;
}
/// @brief Initializes an AHCI disk.
@@ -126,46 +139,6 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
break;
}
- // when it's stopped.
-
- // do in-between
-
- kAhciPort->Clb = kAhciStartAddress + (ahci_index << 10);
- kAhciPort->Clbu = 0;
- rt_set_memory((Kernel::VoidPtr)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu), 0, 1024);
-
- // FIS offset: 32K+256*ahci_index
- // FIS entry size = 256 bytes per port
- kAhciPort->Fb = kAhciStartAddress + (32 << 10) + (ahci_index << 8);
- kAhciPort->Fbu = 0;
- rt_set_memory((Kernel::VoidPtr)((Kernel::UIntPtr)kAhciPort->Fb + kAhciPort->Fbu), 0, 256);
-
- // Command table offset: 40K + 8K*ahci_index
- // Command table size = 256*32 = 8K per port
- HbaCmdHeader* cmd_header = (HbaCmdHeader*)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu);
-
- for (SizeT i = 0; i < 32; i++)
- {
- cmd_header[i].Prdtl = 8; // 8 prdt entries per command table
- // 256 bytes per command table, 64+16+48+16*8
- // Command table offset: 40K + 8K*ahci_index + cmdheader_index*256
- cmd_header[i].Ctba = kAhciStartAddress + (40 << 10) + (ahci_index << 13) + (i << 8);
- cmd_header[i].Ctbau = 0;
-
- rt_set_memory((VoidPtr)((Kernel::UIntPtr)cmd_header[i].Ctba + cmd_header[i].Ctbau), 0, 256);
- }
-
- // when it's starting
-
- // check for bits again, to start it again.
- while (YES)
- {
- if (kAhciPort->Cmd & HBA_PxCMD_FR)
- continue;
-
- break;
- }
-
kAhciPort->Cmd |= HBA_PxCMD_FRE;
kAhciPort->Cmd |= HBA_PxCMD_ST;
@@ -193,12 +166,17 @@ Kernel::Boolean drv_std_detected(Kernel::Void)
Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer)
{
+ drv_std_input_output<YES, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_cnt, size_buffer);
}
Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer)
{
- kAhciPort->Is = -1;
+ drv_std_input_output<NO, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_cnt, size_buffer);
+}
+template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
+static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer)
+{
Kernel::SizeT port = 0;
Kernel::UInt32 slots = (kAhciPort->Sact | kAhciPort->Ci);
@@ -210,77 +188,52 @@ Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::Size
slots >>= 1;
}
- HbaCmdHeader* cmd_hdr = (HbaCmdHeader*)((Kernel::UIntPtr)kAhciPort->Clb + kAhciPort->Clbu);
+ if (slots == 0)
+ return;
- cmd_hdr += port;
- cmd_hdr->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32);
- cmd_hdr->Write = NO;
- cmd_hdr->Prdtl = (Kernel::UInt16)((sector_cnt - 1) >> 4) + 1;
+ Kernel::UInt32* command_list = new Kernel::UInt32[kib_cast(1)];
+ Kernel::UInt32* command_table = new Kernel::UInt32[kib_cast(4)];
- HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)((Kernel::UIntPtr)cmd_hdr->Ctba + cmd_hdr->Ctbau);
- Kernel::rt_set_memory(cmd_tbl, 0, (cmd_hdr->Prdtl - 1) * sizeof(HbaPrdtEntry));
+ Kernel::rt_set_memory(command_list, 0, kib_cast(1));
+ Kernel::rt_set_memory(command_table, 0, kib_cast(4));
- Kernel::SizeT i = 0;
+ auto command_table_deref = *(Kernel::UInt32*)&command_table;
- for (Kernel::SizeT i = 0; i < cmd_hdr->Prdtl - 1; i++)
- {
- cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer;
- cmd_tbl->PrdtEntries[i].Dbau = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32);
- cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value)
- cmd_tbl->PrdtEntries[i].InterruptBit = 1;
- }
+ command_table[0] = *(Kernel::UInt32*)&buffer;
- cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer;
- cmd_tbl->PrdtEntries[i].Dbau = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32);
- cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value)
- cmd_tbl->PrdtEntries[i].InterruptBit = 1;
+ command_list[0] = command_table_deref;
+ command_list[1] = size_buffer;
- FisRegH2D* cmd_fis = (FisRegH2D*)(&cmd_tbl->Cfis);
+ volatile Kernel::UInt32* command_header = (Kernel::UInt32*)kAhciPort + 0x10;
- cmd_fis->FisType = kFISTypeRegH2D;
- cmd_fis->CmdOrCtrl = YES; // Command
- cmd_fis->Command = kAHCICmdReadDmaEx;
+ auto command_list_deref = *(Kernel::UInt32*)&command_list;
- cmd_fis->Lba0 = (Kernel::UInt8)(Kernel::UInt32)lba & 0xFF;
- cmd_fis->Lba1 = (Kernel::UInt8)((Kernel::UInt32)lba >> 8);
- cmd_fis->Lba2 = (Kernel::UInt8)((Kernel::UInt32)lba >> 16);
- cmd_fis->Device = kAhciLBAMode; // LBA mode
+ command_header[0] = 5 | 0 | (Write ? kAHCICmdWriteDma : kAHCICmdReadDma) | 0 | 00000000 | 1 | 00000000000;
+ command_header[0] = command_header[0] | (lba & __UINT32_MAX__);
+
+ command_header[1] = command_list_deref;
- cmd_fis->Lba3 = (Kernel::UInt8)((Kernel::UInt32)lba >> 24);
- cmd_fis->Lba4 = (Kernel::UInt8)(lba >> 32);
- cmd_fis->Lba5 = (Kernel::UInt8)((lba >> 32) >> 8);
+ Kernel::UInt32* fis = command_list;
- cmd_fis->CountLow = sector_cnt & 0xFF;
- cmd_fis->CountHigh = (sector_cnt >> 8) & 0xFF;
+ fis[0] = kFISTypeRegH2D;
+ fis[1] = CommandOrCTRL;
- Kernel::UInt64 spin = 0UL;
+ fis[2] = Identify ? kAHCICmdIdentify : kAHCICmdReadDmaEx;
- // The below loop waits until the port is no longer busy before issuing a new command
- while ((kAhciPort->Tfd & (kAhciSRBsy | kAhciSRDrq)) && spin < kAhciMaxPoll)
- {
- spin++;
- }
- if (spin == 1000000)
- {
- kcout << "AHCI: Port is hung.\r";
- return;
- }
+ if (Write)
+ fis[2] = kAHCICmdWriteDmaEx;
- kAhciPort->Ci = 1 << port; // Issue command
+ // 5. Issue the command
+ // Write command issue bit
+ kAhciPort->Ci |= (1 << 0); // Command Issue
- // Wait for completion
- while (YES)
+ while (kAhciPort->Ci & (1 << 0))
{
- // In some longer duration reads, it may be helpful to spin on the DPS bit
- // in the PxIS port field as well (1 << 5)
- if ((kAhciPort->Ci & (1 << port)) == 0)
- break;
if (kAhciPort->Is & HBA_ERR_TFE) // Task file error
{
- using namespace Kernel;
- kcout << ("AHCI: Read disk error.\r");
+ kcout << "AHCI: Read disk error.\r";
- err_global_get() = kErrorUnrecoverableDisk;
+ err_global_get() = Kernel::kErrorUnrecoverableDisk;
return;
}
@@ -291,13 +244,17 @@ Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::Size
{
using namespace Kernel;
- kcout << ("AHCI: Read disk error.\r");
+ kcout << "AHCI: Read disk error.\r";
*buffer = 0;
err_global_get() = kErrorUnrecoverableDisk;
return;
}
+
+ delete[] command_table;
+
+ command_table = nullptr;
}
/***
@@ -313,7 +270,7 @@ Kernel::SizeT drv_get_sector_count()
/// @return Disk size in bytes.
Kernel::SizeT drv_get_size()
{
- return drv_get_sector_count() * kAHCISectorSize;
+ return (drv_get_sector_count()) * kAHCISectorSize;
}
#endif // ifdef __AHCI__
diff --git a/dev/Kernel/src/DriveMgr.cc b/dev/Kernel/src/DriveMgr.cc
index b588bb0a..4c279d0f 100644
--- a/dev/Kernel/src/DriveMgr.cc
+++ b/dev/Kernel/src/DriveMgr.cc
@@ -176,7 +176,7 @@ namespace Kernel
trait->fPacket.fPacketReadOnly = NO;
trait->fKind = kMassStorageDisc | kEPMDrive;
- kcout << "Formatted Disc is EPM (and Mass Storage too.)\r";
+ kcout << "Formatted Disk is EPM (and Mass Storage too.)\r";
}
else
{
@@ -186,7 +186,7 @@ namespace Kernel
kcout << "Scheme Found: " << block_struct.Name << endl;
if (block_struct.Name[0] == 0)
- kcout << "Disc partition is unknown (Was set to Read Only.)\r";
+ kcout << "Disk partition is unknown (Was set to Read Only.)\r";
}
rt_copy_memory((VoidPtr) "*/*", trait->fPacket.fPacketMime,
diff --git a/dev/Kernel/src/HardwareThreadScheduler.cc b/dev/Kernel/src/HardwareThreadScheduler.cc
index 91800ab7..a94ad64c 100644
--- a/dev/Kernel/src/HardwareThreadScheduler.cc
+++ b/dev/Kernel/src/HardwareThreadScheduler.cc
@@ -4,7 +4,6 @@
------------------------------------------- */
-#include "NewKit/Macros.h"
#include <ArchKit/ArchKit.h>
#include <KernelKit/UserProcessScheduler.h>
#include <KernelKit/HardwareThreadScheduler.h>
diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc
index 91001b05..85915e10 100644
--- a/dev/Kernel/src/UserProcessScheduler.cc
+++ b/dev/Kernel/src/UserProcessScheduler.cc
@@ -12,7 +12,6 @@
/// @brief Low level/Ring-3 process scheduler.
/***********************************************************************************/
-#include "NewKit/Macros.h"
#include <KernelKit/UserProcessScheduler.h>
#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/IPEFDLLObject.h>
diff --git a/dev/Mod/AHCI/AHCI.h b/dev/Mod/AHCI/AHCI.h
index 9b86dc81..f7211267 100644
--- a/dev/Mod/AHCI/AHCI.h
+++ b/dev/Mod/AHCI/AHCI.h
@@ -18,7 +18,7 @@
/// @note Forward declarations of structs.
-#define kAHCISectorSize (512U)
+#define kAHCISectorSize (512)
struct HbaPort;
struct FisData;