summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
Diffstat (limited to 'dev')
-rw-r--r--dev/Boot/amd64-desktop.make5
-rw-r--r--dev/Boot/src/HEL/AMD64/EFIBootStartup.cc2
-rw-r--r--dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc2
-rw-r--r--dev/Kernel/HALKit/AMD64/Processor.h21
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc112
-rw-r--r--dev/Mod/AHCI/AHCI.h32
6 files changed, 109 insertions, 65 deletions
diff --git a/dev/Boot/amd64-desktop.make b/dev/Boot/amd64-desktop.make
index 1aa07a1e..4e817a43 100644
--- a/dev/Boot/amd64-desktop.make
+++ b/dev/Boot/amd64-desktop.make
@@ -82,7 +82,10 @@ compile-amd64:
.PHONY: run-efi-amd64-ahci
run-efi-amd64-ahci:
- $(EMU) $(EMU_FLAGS) -hda $(IMG) -s -S
+ $(EMU) $(EMU_FLAGS) -device ahci,id=ahci0 \
+ -drive id=disk,file=$(IMG),if=none,format=raw \
+ -device ide-hd,drive=disk \
+ -s -S
.PHONY: run-efi-amd64-ata
run-efi-amd64-ata:
diff --git a/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
index 462e59e4..d742b098 100644
--- a/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
+++ b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc
@@ -236,7 +236,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle,
const auto kFSName = "SSD";
- partition_factory.Format(kFSName, &root, 1);
+ // partition_factory.Format(kFSName, &root, 1);
fb_init();
diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
index 2c7e043c..c01a46fe 100644
--- a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
+++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
@@ -7,7 +7,7 @@
#include <ArchKit/ArchKit.h>
#include <KernelKit/UserProcessScheduler.h>
#include <NewKit/KString.h>
-#include <POSIXKit/signal.h>
+#include <POSIXKit/Signals.h>
STATIC BOOL kIsScheduling = NO;
diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h
index 0e6dcfff..acdf7e42 100644
--- a/dev/Kernel/HALKit/AMD64/Processor.h
+++ b/dev/Kernel/HALKit/AMD64/Processor.h
@@ -206,6 +206,27 @@ namespace Kernel::HAL
return edx & (1 << 5);
}
+ inline UInt64 hal_get_phys_address(void* virtual_address)
+ {
+ UInt64 addr = (UInt64)virtual_address;
+ UInt64 cr3 = (UInt64)hal_read_cr3();
+
+ // Extract indices for PML4, PDPT, PD, and PT
+ UInt64 pml4_idx = (addr >> 39) & 0x1FF;
+ UInt64 pdpt_idx = (addr >> 30) & 0x1FF;
+ UInt64 pd_idx = (addr >> 21) & 0x1FF;
+ UInt64 pt_idx = (addr >> 12) & 0x1FF;
+
+ // Get PML4 Table
+ UInt64* pml4 = (UInt64*)(cr3 & ~0xFFF);
+ UInt64* pdpt = (UInt64*)(pml4[pml4_idx] & ~0xFFF);
+ UInt64* pd = (UInt64*)(pdpt[pdpt_idx] & ~0xFFF);
+ UInt64* pt = (UInt64*)(pd[pd_idx] & ~0xFFF);
+
+ // Get Physical Address
+ return (pt[pt_idx] & ~0xFFF) + (addr & 0xFFF);
+ }
+
/***********************************************************************************/
/// @brief Get Model specific register inside core.
/// @param msr MSR
diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
index 74afcde3..a9f2decd 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
@@ -15,6 +15,10 @@
*
*/
+#include "HALKit/AMD64/Processor.h"
+#include "KernelKit/DebugOutput.h"
+#include "KernelKit/Heap.h"
+#include "NewKit/Defines.h"
#include <KernelKit/UserProcessScheduler.h>
#include <KernelKit/LPC.h>
@@ -62,12 +66,26 @@ static Kernel::Void drv_calculate_disk_geometry() noexcept
{
kCurrentDiskSectorCount = 0UL;
- Kernel::UInt8 identify_data[kib_cast(4)] = {};
+ Kernel::UInt8 __attribute__((aligned(4096))) 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];
+ Kernel::Char model[41];
+
+ for (int i = 0; i < 40; i += 2)
+ {
+ char temp = identify_data[54 + i];
+ identify_data[54 + i] = identify_data[54 + i + 1];
+ identify_data[54 + i + 1] = temp;
+ }
+
+ Kernel::rt_copy_memory((Kernel::Char*)(identify_data + 54), model, 40);
+ model[40] = '\0';
+
+ kcout << "SATA Model: " << model << "\r";
+
kcout << "Disk Size: " << Kernel::number(drv_get_size()) << endl;
kcout << "Highest LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl;
}
@@ -89,11 +107,11 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
if (kPCIDevice.Subclass() == kSATASubClass &&
kPCIDevice.ProgIf() == kSATAProgIfAHCI)
{
+ HbaMem* mem_ahci = (HbaMem*)(kPCIDevice.Bar(0x24) & 0xFFFFFFF0);
+
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.
- HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(0x24);
-
Kernel::UInt32 ports_implemented = mem_ahci->Pi;
Kernel::UInt16 ahci_index = 0;
@@ -113,7 +131,7 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
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)
+ if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1)
{
kcout << "Port is SATA.\r";
@@ -135,8 +153,7 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
const auto kAHCIBaseAddress = mib_cast(4);
- kSATAPort->Ports[kSATAPortIdx].Clb = kAHCIBaseAddress + (kSATAPortIdx << 10);
- kSATAPort->Ports[kSATAPortIdx].Clbu = 0;
+ kSATAPort->Ports[kSATAPortIdx].Clb = kAHCIBaseAddress + (kSATAPortIdx << 10);
rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb), 0, 1024);
@@ -151,8 +168,7 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
{
cmdheader[i].Prdtl = 8;
- cmdheader[i].Ctba = kAHCIBaseAddress + (40 << 10) + (kSATAPortIdx << 13) + (i << 8);
- cmdheader[i].Ctbau = 0;
+ cmdheader[i].Ctba = kAHCIBaseAddress + (40 << 10) + (kSATAPortIdx << 13) + (i << 8);
rt_set_memory((VoidPtr)(UIntPtr)cmdheader[i].Ctba, 0, 256);
}
@@ -164,23 +180,22 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre;
kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST;
- drv_calculate_disk_geometry();
+ // Enable AHCI Mode FIRST
+ kSATAPort->Ghc |= (1 >> 31);
- detected = YES;
+ drv_calculate_disk_geometry();
- break;
+ return YES;
}
}
ports_implemented >>= 1;
++ahci_index;
}
-
- return detected;
}
}
- return No;
+ return NO;
}
Kernel::Boolean drv_std_detected(Kernel::Void)
@@ -190,12 +205,12 @@ Kernel::Boolean drv_std_detected(Kernel::Void)
Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer)
{
- drv_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 / sector_sz);
}
Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer)
{
- drv_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 / sector_sz);
}
static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept
@@ -222,8 +237,6 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
if (!CommandOrCTRL)
return;
- kSATAPort->Ports[kSATAPortIdx].Is = -1;
-
auto slot = 0L;
slot = drv_find_cmd_slot(&kSATAPort->Ports[kSATAPortIdx]);
@@ -231,46 +244,51 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
if (slot == -1)
return;
- volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb + kSATAPort->Ports[kSATAPortIdx].Clbu));
+ kcout << "Reading AHCI disk...\r";
- command_header += slot;
+ volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb + slot * sizeof(HbaCmdHeader)));
+
+ Kernel::rt_set_memory((void*)command_header, 0, sizeof(HbaCmdTbl));
MUST_PASS(command_header);
command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32);
command_header->Write = Write;
- command_header->Prdtl = (Kernel::UInt16)((size_buffer - 1) >> 4) + 1;
+ command_header->Prdtl = 1;
+ command_header->Ctba = (Kernel::UIntPtr)Kernel::mm_new_heap(sizeof(HbaCmdTbl), YES, NO);
+
+ volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba);
- volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba + command_header->Ctbau);
+ Kernel::rt_set_memory((void*)command_table, 0, sizeof(HbaCmdTbl));
MUST_PASS(command_table);
- 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;
+ command_table->PrdtEntries->Dba = (Kernel::UInt64)Kernel::HAL::hal_get_phys_address(buffer);
+ command_table->PrdtEntries->Dbc = (size_buffer * sector_sz) - 1;
+ command_table->PrdtEntries->InterruptBit = YES;
+ kcout << "PRDT Entry 0 - Dba: " << Kernel::hex_number(command_table->PrdtEntries->Dba) << endl;
+ kcout << "PRDT Entry 0 - Dbc: " << Kernel::hex_number(command_table->PrdtEntries->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->CmdOrCtrl = YES;
+ h2d_fis->CmdOrCtrl = CommandOrCTRL;
h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx;
if (Identify)
h2d_fis->Command = kAHCICmdIdentify;
- h2d_fis->Lba0 = lba;
- h2d_fis->Lba1 = lba >> 8;
- h2d_fis->Lba2 = lba >> 16;
- h2d_fis->Lba3 = lba >> 24;
+ 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->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;
@@ -282,19 +300,23 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff
kcout << "waiting for slot to be ready\r\n";
}
- kSATAPort->Is = -1;
- kSATAPort->Ports[kSATAPortIdx].Ci |= 1 << slot;
+ kSATAPort->Ports[kSATAPortIdx].Ci = 1 << slot;
while (kSATAPort->Ports[kSATAPortIdx].Ci & (1 << slot))
{
- kcout << Kernel::number(slot) << endl;
+ Kernel::UInt32 tfd = kSATAPort->Ports[kSATAPortIdx].Tfd;
+ kcout << "AHCI TFD: " << Kernel::number(tfd) << endl;
+ }
- if (kSATAPort->Is & kHBAErrTaskFile) // check for task file error.
- {
- Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component.");
- return;
- }
+ kcout << "Last Command Sent: " << (int)Kernel::number(h2d_fis->Command) << endl;
+
+ kcout << "LBA 1 First 16 Bytes: ";
+ for (int i = 0; i < 16; i++)
+ {
+ kcout << Kernel::hex_number(buffer[i]);
}
+
+ Kernel::mm_delete_heap((Kernel::VoidPtr)command_header->Ctba);
}
/***
diff --git a/dev/Mod/AHCI/AHCI.h b/dev/Mod/AHCI/AHCI.h
index 08846e85..7b50d461 100644
--- a/dev/Mod/AHCI/AHCI.h
+++ b/dev/Mod/AHCI/AHCI.h
@@ -59,20 +59,21 @@ typedef struct FisRegH2D final
Kernel::UInt8 Reserved0 : 3; // Reserved
Kernel::UInt8 CmdOrCtrl : 1; // 1: Command, 0: Control
- Kernel::UInt8 Command; // Command register
- Kernel::UInt8 Featurel; // Feature register, 7:0
+ Kernel::UInt8 Command; // Command register
+ Kernel::UInt8 FeatureLow; // 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; // LBA high register, 23:16
+ Kernel::UInt8 Lba0; // LBA low register, 7:0
+ Kernel::UInt8 Lba1; // LBA mid register, 15:8
+ Kernel::UInt8 Lba2;
+
Kernel::UInt8 Device; // Device register
- // 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
+ Kernel::UInt8 Lba3; // Feature register, 15:8
+ Kernel::UInt8 Lba4;
+ Kernel::UInt8 Lba5;
+
+ Kernel::UInt8 FeatureHigh;
// DWORD 3
Kernel::UInt8 CountLow; // Count register, 7:0
@@ -191,7 +192,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
@@ -228,8 +229,7 @@ typedef struct FisDevBits final
typedef struct HbaPort final
{
- Kernel::UInt32 Clb; // 0x00, command list base address, 1K-byte aligned
- Kernel::UInt32 Clbu; // 0x04, command list base address upper 32 bits
+ Kernel::UInt64 Clb;
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
@@ -287,8 +287,7 @@ typedef struct HbaCmdHeader final
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 Ctbau; // Command table descriptor base address upper 32 bits
+ Kernel::UInt64 Ctba; // Command table descriptor base address
Kernel::UInt32 Reserved1[4]; // Reserved
} HbaCmdHeader;
@@ -314,8 +313,7 @@ typedef struct HbaFis final
typedef struct HbaPrdtEntry final
{
- Kernel::UInt32 Dba; // Data base address
- Kernel::UInt32 Dbau; // Data base address upper 32 bits
+ Kernel::UInt64 Dba; // Data base address
Kernel::UInt32 Reserved0; // Reserved
// DW3
Kernel::UInt32 Dbc : 22; // Byte count, 4M max