summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal <amlal.elmahrouss@icloud.com>2025-01-28 10:56:01 +0100
committerAmlal <amlal.elmahrouss@icloud.com>2025-01-28 10:56:01 +0100
commit0601399a597280f849ce6c07f73f8124eea35c8d (patch)
treecc8d9b781f9fa2615a42c3ad22df47415856161d /dev
parent97d9cac7420ee032e8a2c4ae5e55963003516116 (diff)
ADD: Improvements on the AHCI driver.
Signed-off-by: Amlal <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev')
-rw-r--r--dev/Boot/amd64-desktop.make2
-rw-r--r--dev/Boot/src/HEL/AMD64/EFIBootStartup.cc17
-rw-r--r--dev/Kernel/FirmwareKit/.gitkeep1
-rw-r--r--dev/Kernel/FirmwareKit/EFI/EFI.h4
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA.cc36
-rw-r--r--dev/Kernel/src/DriveMgr.cc4
-rw-r--r--dev/Mod/AHCI/AHCI.h39
7 files changed, 62 insertions, 41 deletions
diff --git a/dev/Boot/amd64-desktop.make b/dev/Boot/amd64-desktop.make
index 14ed07cd..c13a718f 100644
--- a/dev/Boot/amd64-desktop.make
+++ b/dev/Boot/amd64-desktop.make
@@ -95,7 +95,7 @@ run-efi-amd64-ata:
# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta specs.
.PHONY: epm-img
epm-img:
- qemu-img create -f raw $(IMG) 4G
+ qemu-img create -f qcow2 $(IMG) 4G
.PHONY: efi
efi:
diff --git a/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
index a1861178..3243e482 100644
--- a/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
+++ b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
@@ -74,6 +74,9 @@ STATIC Bool boot_init_fb() noexcept
EXTERN EfiBootServices* BS;
+EfiGUID kEfiGlobalNamespaceVarGUID = {
+ 0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C}};
+
/// @brief Main EFI entrypoint.
/// @param image_handle Handle of this image.
/// @param sys_table The system table of it.
@@ -222,6 +225,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)
@@ -248,6 +252,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle,
fb_clear();
}
}
+#endif
// ------------------------------------------ //
// null these fields, to avoid being reused later.
@@ -270,8 +275,16 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle,
// Assign to global 'kHandoverHeader'.
- const auto kernel_path = L"neoskrnl.exe";
- const auto kernel_path_sz = 15;
+ WideChar kernel_path[255] = {0};
+ UInt32 kernel_path_sz = 255;
+
+ if (ST->RuntimeServices->GetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, nullptr, &kernel_path_sz, kernel_path) != kEfiOk)
+ {
+ CopyMem(kernel_path, L"neoskrnl.exe", 15);
+
+ UInt32 attr = 0x00000001 | 0x00000002 | 0x00000004;
+ ST->RuntimeServices->SetVariable(L"/props/boot_path", kEfiGlobalNamespaceVarGUID, &attr, &kernel_path_sz, kernel_path);
+ }
Boot::BFileReader reader_kernel(kernel_path, image_handle);
diff --git a/dev/Kernel/FirmwareKit/.gitkeep b/dev/Kernel/FirmwareKit/.gitkeep
index e69de29b..8b137891 100644
--- a/dev/Kernel/FirmwareKit/.gitkeep
+++ b/dev/Kernel/FirmwareKit/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/dev/Kernel/FirmwareKit/EFI/EFI.h b/dev/Kernel/FirmwareKit/EFI/EFI.h
index bbf990ce..bef18e33 100644
--- a/dev/Kernel/FirmwareKit/EFI/EFI.h
+++ b/dev/Kernel/FirmwareKit/EFI/EFI.h
@@ -614,9 +614,9 @@ typedef struct EfiRuntimeServices
{
EfiTableHeader SystemTable;
VoidPtr GetTime, SetTime, GetWakeupTime, SetWakeupTime, SetVirtualAddressMap, ConvertPointer;
- UInt64(EFI_API* GetVariable)(const Char* Name, EfiGUID VendorGUID, UInt32* Attributes, UInt32* DataSize, VoidPtr Data);
+ UInt64(EFI_API* GetVariable)(const WideChar* Name, EfiGUID VendorGUID, UInt32* Attributes, UInt32* DataSize, VoidPtr Data);
VoidPtr GetNextVariable;
- UInt64(EFI_API* SetVariable)(const Char* Name, EfiGUID VendorGUID, UInt32* Attributes, UInt32* DataSize, VoidPtr Data);
+ UInt64(EFI_API* SetVariable)(const WideChar* Name, EfiGUID VendorGUID, UInt32* Attributes, UInt32* DataSize, VoidPtr Data);
VoidPtr GetNextHighMonotonicCount;
VoidPtr ResetSystem;
VoidPtr UpdateCapsule;
diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
index 74e1e8c1..dc95375d 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
@@ -64,18 +64,13 @@ static Kernel::Void drv_calculate_disk_geometry() noexcept
{
kCurrentDiskSectorCount = 0UL;
- Kernel::UInt8 __attribute__((aligned(4096))) identify_data[kib_cast(4)] = {};
+ Kernel::UInt8 identify_data[kib_cast(8)] = {};
- drv_std_input_output<NO, YES, YES>(0, identify_data, 0, kib_cast(4));
+ drv_std_input_output<NO, YES, YES>(0, identify_data, 0, kib_cast(8));
uint32_t lba28_sectors = (identify_data[61] << 16) | identify_data[60];
- uint64_t lba48_sectors = ((uint64_t)identify_data[103] << 48) |
- ((uint64_t)identify_data[102] << 32) |
- ((uint64_t)identify_data[101] << 16) |
- ((uint64_t)identify_data[100]);
-
- kCurrentDiskSectorCount = (lba48_sectors) ? lba48_sectors : lba28_sectors;
+ kCurrentDiskSectorCount = lba28_sectors;
for (Kernel::Int32 i = 0; i < 40; i += 2)
{
@@ -193,7 +188,7 @@ static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept
if (port == nullptr)
return -1;
- kcout << "Finding a slot...";
+ kcout << "Finding a slot...\r";
Kernel::UInt32 slots = (kSATAPort->Ports[kSATAPortIdx].Sact | kSATAPort->Ports[kSATAPortIdx].Ci);
@@ -219,7 +214,8 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
if (slot == -1)
return;
- kcout << "Reading AHCI disk...\r";
+ if (size_buffer > kib_cast(8))
+ return;
volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb));
command_header += slot;
@@ -237,12 +233,15 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
MUST_PASS(command_table);
- command_table->Prdt[0].Dba = (Kernel::UInt32)((Kernel::UInt64)buffer);
- command_table->Prdt[0].Dbau = (Kernel::UInt32)(((Kernel::UInt64)buffer >> 32));
- command_table->Prdt[0].Dbc = size_buffer;
+ Kernel::UInt8 ATTRIBUTE(aligned(kib_cast(4))) buffer_ahci[kib_cast(8)] = {0};
+
+ command_table->Prdt[0].Dba = (Kernel::UInt32)((Kernel::UInt64)buffer_ahci);
+ command_table->Prdt[0].Dbau = (Kernel::UInt32)((Kernel::UInt64)buffer_ahci << 32);
+
+ command_table->Prdt[0].Dbc = kib_cast(8) - 1;
command_table->Prdt[0].InterruptBit = YES; // Ensure Interrupt-On-Completion is set
- // Debug PRDT entry
+ 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;
@@ -280,7 +279,7 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
Kernel::UInt32 ahci_status = kSATAPort->Ports[kSATAPortIdx].Tfd;
kcout << "AHCI Status Before Write: " << Kernel::hex_number(ahci_status) << endl;
- kSATAPort->Ports[kSATAPortIdx].Ci = 1 << slot;
+ kSATAPort->Ports[kSATAPortIdx].Ci |= 1 << slot;
while (kSATAPort->Ports[kSATAPortIdx].Ci & (1 << slot))
{
@@ -291,7 +290,12 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
kcout << "Last Command Sent: " << (int)Kernel::number(h2d_fis->Command) << endl;
ahci_status = kSATAPort->Ports[kSATAPortIdx].Tfd;
- kcout << "AHCI Status Before Write: " << Kernel::hex_number(ahci_status) << endl;
+
+ 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);
}
/***
diff --git a/dev/Kernel/src/DriveMgr.cc b/dev/Kernel/src/DriveMgr.cc
index 4f6be802..e405cc96 100644
--- a/dev/Kernel/src/DriveMgr.cc
+++ b/dev/Kernel/src/DriveMgr.cc
@@ -191,7 +191,9 @@ namespace Kernel
kcout << "Scheme Found: " << block_struct.Name << endl;
- if (block_struct.Name[0] == 0)
+ if (block_struct.Name[0] == 0 ||
+ block_struct.Name[0] == 0xFF ||
+ block_struct.Name[0] == 0xAF)
kcout << "Disk partition is empty (Read Only)\r";
}
diff --git a/dev/Mod/AHCI/AHCI.h b/dev/Mod/AHCI/AHCI.h
index 937be6d2..87575e4e 100644
--- a/dev/Mod/AHCI/AHCI.h
+++ b/dev/Mod/AHCI/AHCI.h
@@ -59,21 +59,20 @@ typedef struct FisRegH2D final
Kernel::UInt8 Reserved0 : 3; // Reserved
Kernel::UInt8 CmdOrCtrl : 1; // 1: Command, 0: Control
- Kernel::UInt8 Command; // Command register
- Kernel::UInt8 FeatureLow; // Feature register, 7:0
+ Kernel::UInt8 Command; // Command register
+ Kernel::UInt8 Featurel; // Feature register, 7:0
// DWORD 1
- Kernel::UInt8 Lba0; // LBA low register, 7:0
- Kernel::UInt8 Lba1; // LBA mid register, 15:8
- Kernel::UInt8 Lba2;
-
+ Kernel::UInt8 Lba0; // LBA low register, 7:0
+ Kernel::UInt8 Lba1; // LBA mid register, 15:8
+ Kernel::UInt8 Lba2; // LBA high register, 23:16
Kernel::UInt8 Device; // Device register
- Kernel::UInt8 Lba3; // Feature register, 15:8
- Kernel::UInt8 Lba4;
- Kernel::UInt8 Lba5;
-
- Kernel::UInt8 FeatureHigh;
+ // DWORD 2
+ Kernel::UInt8 Lba3; // LBA register, 31:24
+ Kernel::UInt8 Lba4; // LBA register, 39:32
+ Kernel::UInt8 Lba5; // LBA register, 47:40
+ Kernel::UInt8 FeatureHigh; // Feature register, 15:8
// DWORD 3
Kernel::UInt8 CountLow; // Count register, 7:0
@@ -192,7 +191,7 @@ typedef struct FisDmaSetup final
Kernel::UInt32 Rsvd; // More reserved
// DWORD 4
- Kernel::UInt32 DmaBufOffset; // Byte offset into buffer. First 2 bits must be 0
+ Kernel::UInt32 DmabufOffset; // Byte offset into buffer. First 2 bits must be 0
// DWORD 5
Kernel::UInt32 TransferCount; // Number of bytes to transfer. Bit 0 must be 0
@@ -229,7 +228,8 @@ typedef struct FisDevBits final
typedef struct HbaPort final
{
- Kernel::UInt64 Clb;
+ Kernel::UInt32 Clb; // 0x00, command list base address, 1K-byte aligned
+ Kernel::UInt32 Clbu; // 0x04, command list base address upper 32 bits
Kernel::UInt32 Fb; // 0x08, FIS base address, 256-byte aligned
Kernel::UInt32 Fbu; // 0x0C, FIS base address upper 32 bits
Kernel::UInt32 Is; // 0x10, interrupt status
@@ -267,7 +267,7 @@ typedef struct HbaMem final
Kernel::UInt8 Resv0[0xA0 - 0x2C];
Kernel::UInt8 Vendor[0x100 - 0xA0];
- HbaPort Ports[32]; // 1 ~ 32, 32 is the max ahci devices per controller.
+ HbaPort Ports[1]; // 1 ~ 32, 32 is the max ahci devices per controller.
} HbaMem;
typedef struct HbaCmdHeader final
@@ -284,10 +284,11 @@ typedef struct HbaCmdHeader final
Kernel::UInt8 Reserved0 : 1; // Reserved
Kernel::UInt8 Pmp : 4; // Port multiplier port
- Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries
- Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred
+ Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries
+ volatile Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred
- Kernel::UInt32 Ctba; // Command table descriptor base address
+ Kernel::UInt32 Ctba; // Command table descriptor base address
+ Kernel::UInt32 Ctbau; // Command table descriptor base address upper 32 bits
Kernel::UInt32 Reserved1[4]; // Reserved
} HbaCmdHeader;
@@ -313,8 +314,8 @@ typedef struct HbaFis final
typedef struct HbaPrdtEntry final
{
- Kernel::UInt32 Dba; // Data base address
- Kernel::UInt32 Dbau;
+ Kernel::UInt32 Dba; // Data base address
+ Kernel::UInt32 Dbau; // Data base address upper 32 bits
Kernel::UInt32 Reserved0; // Reserved
// DW3
Kernel::UInt32 Dbc : 22; // Byte count, 4M max