summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel/HALKit
diff options
context:
space:
mode:
Diffstat (limited to 'dev/Kernel/HALKit')
-rw-r--r--dev/Kernel/HALKit/AMD64/HalAPICController.cc5
-rw-r--r--dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc5
-rw-r--r--dev/Kernel/HALKit/AMD64/HalKernelPanic.cc4
-rw-r--r--dev/Kernel/HALKit/AMD64/Processor.h40
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/DMA.cc152
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/PIO.cc26
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA.cc26
7 files changed, 140 insertions, 118 deletions
diff --git a/dev/Kernel/HALKit/AMD64/HalAPICController.cc b/dev/Kernel/HALKit/AMD64/HalAPICController.cc
index 3e2e267a..c3ce5c1a 100644
--- a/dev/Kernel/HALKit/AMD64/HalAPICController.cc
+++ b/dev/Kernel/HALKit/AMD64/HalAPICController.cc
@@ -12,6 +12,11 @@
namespace Kernel::HAL
{
+ APICController::APICController(VoidPtr base)
+ : fApic(base)
+ {
+ }
+
/// @brief Read from APIC controller.
/// @param reg register.
UInt32 APICController::Read(UInt32 reg) noexcept
diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
index c64a3e41..63ed2a21 100644
--- a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
+++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
@@ -133,7 +133,10 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip)
auto process = Kernel::UserProcessScheduler::The().CurrentProcess();
if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
- return;
+ {
+ while (YES)
+ ;
+ }
kIsScheduling = NO;
diff --git a/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc
index 6a4284ec..11ed4c04 100644
--- a/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc
+++ b/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc
@@ -40,9 +40,9 @@ namespace Kernel
auto y = 10;
auto x = 10;
- kout << "Kernel_Panic: " << message << endl;
+ kout << "Kernel_Panic_MSG: " << message << endl;
kout << "Kernel_Panic_ID: " << hex_number(id) << endl;
- kout << "Kernel_Panic_CR2:" << hex_number((UIntPtr)hal_read_cr2()) << endl;
+ kout << "Kernel_Panic_CR2: " << hex_number((UIntPtr)hal_read_cr2()) << endl;
RecoveryFactory::Recover();
}
diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h
index b95fff74..24e84b79 100644
--- a/dev/Kernel/HALKit/AMD64/Processor.h
+++ b/dev/Kernel/HALKit/AMD64/Processor.h
@@ -19,14 +19,14 @@
#include <FirmwareKit/Handover.h>
#include <HALKit/AMD64/Paging.h>
-#define kPITControlPort 0x43
-#define kPITChannel0Port 0x40
-#define kPITFrequency 1193180
+#define kPITControlPort (0x43)
+#define kPITChannel0Port (0x40)
+#define kPITFrequency (1193180)
-#define kPICCommand 0x20
-#define kPICData 0x21
-#define kPIC2Command 0xA0
-#define kPIC2Data 0xA1
+#define kPICCommand (0x20)
+#define kPICData (0x21)
+#define kPIC2Command (0xA0)
+#define kPIC2Data (0xA1)
EXTERN_C
{
@@ -294,14 +294,10 @@ namespace Kernel::HAL
};
} // namespace Detail
- class APICController
+ class APICController final
{
public:
- explicit APICController(VoidPtr base)
- : fApic(base)
- {
- }
-
+ explicit APICController(VoidPtr base);
~APICController() = default;
NE_COPY_DEFAULT(APICController);
@@ -325,16 +321,16 @@ namespace Kernel::HAL
EXTERN_C UInt16 rt_in16(UInt16 port);
EXTERN_C UInt32 rt_in32(UInt16 port);
- EXTERN_C void rt_out16(UShort port, UShort byte);
- EXTERN_C void rt_out8(UShort port, UChar byte);
- EXTERN_C void rt_out32(UShort port, UInt byte);
+ EXTERN_C Void rt_out16(UShort port, UShort byte);
+ EXTERN_C Void rt_out8(UShort port, UChar byte);
+ EXTERN_C Void rt_out32(UShort port, UInt byte);
- EXTERN_C void rt_wait_400ns();
- EXTERN_C void rt_halt();
- EXTERN_C void rt_cli();
- EXTERN_C void rt_sti();
- EXTERN_C void rt_cld();
- EXTERN_C void rt_std();
+ EXTERN_C Void rt_wait_400ns();
+ EXTERN_C Void rt_halt();
+ EXTERN_C Void rt_cli();
+ EXTERN_C Void rt_sti();
+ EXTERN_C Void rt_cld();
+ EXTERN_C Void rt_std();
} // namespace Kernel::HAL
EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp);
diff --git a/dev/Kernel/HALKit/AMD64/Storage/DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/DMA.cc
index 6fa98a24..c592277d 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/DMA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/DMA.cc
@@ -15,8 +15,11 @@
*
*/
+#include "KernelKit/DebugOutput.h"
+#include "NewKit/KernelPanic.h"
#include <Mod/ATA/ATA.h>
#include <ArchKit/ArchKit.h>
+#include <KernelKit/PCI/Iterator.h>
#if defined(__ATA_DMA__)
@@ -30,6 +33,8 @@ using namespace Kernel::HAL;
STATIC Boolean kATADetected = false;
STATIC Int32 kATADeviceType = kATADeviceCount;
STATIC Char kATAData[kATADataLen] = {0};
+STATIC Kernel::PCI::Device kATADevice;
+STATIC Char kCurrentDiskModel[50] = {"UNKNOWN ATA DRIVE"};
Boolean drv_std_wait_io(UInt16 IO)
{
@@ -64,79 +69,75 @@ Void drv_std_select(UInt16 Bus)
Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster)
{
- if (drv_std_detected())
- return true;
+ PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController);
- UInt16 IO = Bus;
+ for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index)
+ {
+ kATADevice = iterator[device_index].Leak(); // And then leak the reference.
- drv_std_select(IO);
+ // if SATA and then interface is AHCI...
+ if (kATADevice.Subclass() == 0x01)
+ {
+ UInt16 IO = Bus;
- // Bus init, NEIN bit.
- rt_out8(IO + ATA_REG_NEIN, 1);
+ drv_std_select(IO);
- // identify until it's good.
-ATAInit_Retry:
- auto statRdy = rt_in8(IO + ATA_REG_STATUS);
+ // Bus init, NEIN bit.
+ rt_out8(IO + ATA_REG_NEIN, 1);
- if (statRdy & ATA_SR_ERR)
- {
- return false;
- }
+ // identify until it's good.
+ ATAInit_Retry:
+ auto statRdy = rt_in8(IO + ATA_REG_STATUS);
- if ((statRdy & ATA_SR_BSY))
- goto ATAInit_Retry;
+ if (statRdy & ATA_SR_ERR)
+ {
+ return false;
+ }
- rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
+ if ((statRdy & ATA_SR_BSY))
+ goto ATAInit_Retry;
- /// fetch serial info
- /// model, speed, number of sectors...
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
- drv_std_wait_io(IO);
+ /// fetch serial info
+ /// model, speed, number of sectors...
- for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData)
- {
- kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA);
- }
+ drv_std_wait_io(IO);
- OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
- OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
+ for (SizeT i = 0ul; i < kATADataLen; ++i)
+ {
+ drv_std_wait_io(IO);
+ kATAData[i] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA);
+ drv_std_wait_io(IO);
+ }
- return true;
-#ifdef __ATA_DMA__
- // Step 7: Check if the drive supports DMA
- if (!(kATAData[63] & (1 << 8)) || !(kATAData[88] & 0xFF))
- {
- kout << "No DMA support...\r";
- ke_panic(RUNTIME_CHECK_BOOTSTRAP, "No DMA support on necessary disk driver.");
+ for (SizeT i = 0; i < 40; i += 2)
+ {
+ kCurrentDiskModel[i] = kATAData[54 + i] >> 8;
+ kCurrentDiskModel[i + 1] = kATAData[54 + i] & 0xFF;
+ }
- return false;
- }
+ kCurrentDiskModel[40] = '\0';
- // Step 8: Enable DMA Mode
- rt_out8(IO + ATA_REG_FEATURES, 0x03); // Enable DMA mode
- rt_out8(IO + ATA_REG_COMMAND, ATA_REG_SET_FEATURES); // Send set features command
+ kout << "Drive Model: " << kCurrentDiskModel << endl;
- // Step 9: Wait for drive to acknowledge DMA setting
- timeout = 100000;
- while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRDY) && --timeout)
- ;
- if (!timeout)
- {
- kout << "DMA Initialization Timeout...\r";
- return false;
+ OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
+ OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
+
+ return YES;
+ }
}
-#endif // __ATA_DMA__
- kout << "ATA is enabled now.\r";
+ ke_panic(RUNTIME_CHECK_BOOTSTRAP, "Invalid ATA DMA driver, not detected");
- return YES;
+ return NO;
}
namespace Details
{
using namespace Kernel;
- struct __attribute__((packed, aligned(4))) PRD final
+ struct PRD final
{
UInt32 mAddress;
UInt16 mByteCount;
@@ -144,12 +145,20 @@ namespace Details
};
} // namespace Details
+static UIntPtr kReadAddr = mib_cast(2);
+static UIntPtr kWriteAddr = mib_cast(4);
+
Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size)
{
Lba /= SectorSz;
+ if (Size > kib_cast(64))
+ ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers.");
+
UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+ rt_copy_memory((VoidPtr)Buf, (VoidPtr)kReadAddr, Size);
+
drv_std_select(IO);
rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
@@ -161,22 +170,23 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
- if (Size > kib_cast(64))
- ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers.");
-
- Details::PRD* prd = new Details::PRD();
- prd->mAddress = (UInt32)(UIntPtr)Buf;
- prd->mByteCount = Size;
+ Details::PRD* prd = (Details::PRD*)(kATADevice.Bar(0x20) + 4);
+ prd->mAddress = (UInt32)(UIntPtr)kReadAddr;
+ prd->mByteCount = Size - 1;
prd->mFlags = 0x8000;
- rt_out32(IO + 0x04, (UInt32)(UIntPtr)prd);
+ rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32)(UIntPtr)prd);
- rt_out8(IO + 0x00, 0x09); // Start DMA engine
- rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_DMA);
+ rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_READ_DMA);
+
+ rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine
- while (rt_in8(ATA_REG_STATUS) & 0x01)
+ while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01)
;
- rt_out8(IO + 0x00, 0x00); // Stop DMA engine
+
+ rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine
+
+ rt_copy_memory((VoidPtr)kReadAddr, (VoidPtr)Buf, Size);
delete prd;
prd = nullptr;
@@ -186,9 +196,12 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
{
Lba /= SectorSz;
+ if (Size > kib_cast(64))
+ ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers.");
+
UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
- drv_std_select(IO);
+ rt_copy_memory((VoidPtr)Buf, (VoidPtr)kWriteAddr, Size);
rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
@@ -199,23 +212,20 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
- if (Size > kib_cast(64))
- ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers.");
-
- Details::PRD* prd = new Details::PRD();
- prd->mAddress = (UInt32)(UIntPtr)Buf;
- prd->mByteCount = Size;
+ Details::PRD* prd = (Details::PRD*)(kATADevice.Bar(0x20) + 4);
+ prd->mAddress = (UInt32)(UIntPtr)kWriteAddr;
+ prd->mByteCount = Size - 1;
prd->mFlags = 0x8000;
- rt_out32(IO + 0x04, (UInt32)(UIntPtr)prd);
+ rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32)(UIntPtr)prd);
+ rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA);
rt_out8(IO + 0x00, 0x09); // Start DMA engine
- rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA);
- while (rt_in8(ATA_REG_STATUS) & 0x01)
+ while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01)
;
- rt_out8(IO + 0x00, 0x00); // Stop DMA engine
+ rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine
delete prd;
prd = nullptr;
diff --git a/dev/Kernel/HALKit/AMD64/Storage/PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/PIO.cc
index 3f1286b6..3ca1e403 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/PIO.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/PIO.cc
@@ -5,7 +5,7 @@
------------------------------------------- */
/**
- * @file ATA-PIO.cc
+ * @file PIO.cc
* @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com)
* @brief ATA driver (PIO mode).
* @version 0.1
@@ -30,6 +30,7 @@ using namespace Kernel::HAL;
STATIC Boolean kATADetected = false;
STATIC Int32 kATADeviceType = kATADeviceCount;
STATIC Char kATAData[kATADataLen] = {0};
+STATIC Char kCurrentDiskModel[50] = {"UNKNOWN ATA DRIVE"};
Boolean drv_std_wait_io(UInt16 IO)
{
@@ -64,9 +65,6 @@ Void drv_std_select(UInt16 Bus)
Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster)
{
- if (drv_std_detected())
- return true;
-
UInt16 IO = Bus;
drv_std_select(IO);
@@ -93,11 +91,23 @@ ATAInit_Retry:
drv_std_wait_io(IO);
- for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData)
+ for (SizeT i = 0ul; i < kATADataLen; ++i)
+ {
+ drv_std_wait_io(IO);
+ kATAData[i] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA);
+ drv_std_wait_io(IO);
+ }
+
+ for (SizeT i = 0; i < 40; i += 2)
{
- kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA);
+ kCurrentDiskModel[i] = kATAData[54 + i] >> 8;
+ kCurrentDiskModel[i + 1] = kATAData[54 + i] & 0xFF;
}
+ kCurrentDiskModel[40] = '\0';
+
+ kout << "Drive Model: " << kCurrentDiskModel << endl;
+
OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
@@ -173,7 +183,7 @@ Boolean drv_std_detected(Void)
}
/***
- @brief Getter, gets the number of sectors inside the drive.
+ @brief Getter, gets the number of sectors inside the drive.
*/
Kernel::SizeT drv_get_sector_count()
{
@@ -186,4 +196,4 @@ Kernel::SizeT drv_get_size()
return (drv_get_sector_count()) * kATASectorSize;
}
-#endif /* ifdef __ATA_PIO__ */
+#endif /* ifdef __ATA_PIO__ */ \ No newline at end of file
diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
index b37de7e5..8f68b734 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
@@ -15,7 +15,6 @@
*
*/
-#include "KernelKit/DebugOutput.h"
#include <KernelKit/UserProcessScheduler.h>
#include <KernelKit/LPC.h>
@@ -46,7 +45,7 @@
#define kSATASubClass (0x06)
#define kSATABar5 (0x24)
-STATIC Kernel::PCI::Device kPCIDevice;
+STATIC Kernel::PCI::Device kDevice;
STATIC HbaMem* kSATA = nullptr;
STATIC Kernel::SizeT kSATAPortIdx = 0UL;
STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL;
@@ -94,16 +93,16 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index)
{
- kPCIDevice = iterator[device_index].Leak(); // And then leak the reference.
+ kDevice = iterator[device_index].Leak(); // And then leak the reference.
// if SATA and then interface is AHCI...
- if (kPCIDevice.Subclass() == kSATASubClass &&
- kPCIDevice.ProgIf() == kSATAProgIfAHCI)
+ if (kDevice.Subclass() == kSATASubClass &&
+ kDevice.ProgIf() == kSATAProgIfAHCI)
{
- 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.
+ kDevice.EnableMmio(kSATABar5); // Enable the memory index_byte/o for this ahci device.
+ kDevice.BecomeBusMaster(kSATABar5); // Become bus master for this ahci device, so that we can control it.
- HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(kSATABar5);
+ HbaMem* mem_ahci = (HbaMem*)kDevice.Bar(kSATABar5);
kout << hex_number((UIntPtr)mem_ahci) << endl;
@@ -124,9 +123,6 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
HAL::mm_map_page(mem_ahci, mem_ahci, HAL::kMMFlagsWr);
- kout << "Virtddr: " << hex_number((UIntPtr)mem_ahci) << endl;
- kout << "PhysAddr: " << hex_number((UIntPtr)HAL::hal_get_phys_address(mem_ahci)) << endl;
-
if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1 &&
(mem_ahci->Ports[ahci_index].Ssts & 0xF))
{
@@ -135,6 +131,8 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
kSATAPortIdx = ahci_index;
kSATA = mem_ahci;
+ // Restart the HBA.
+
kSATA->Ports[kSATAPortIdx].Cmd &= ~(kHBAPxCmdST | kHBAPxCmdFre); // Disable command and FIS reception
while (kSATA->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR)
@@ -145,8 +143,8 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre; // Re-enable FIS reception
kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST; // Start command engine
-
- kSATA->Ghc |= kHBACmdAE; // Enable AHCI mode
+
+ kSATA->Ghc |= kHBACmdAE; // Enable AHCI mode
HAL::rt_wait_400ns();
@@ -167,7 +165,7 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
Kernel::Boolean drv_std_detected(Kernel::Void)
{
- return kPCIDevice.DeviceId() != 0xFFFF && kCurrentDiskSectorCount > 0;
+ return kDevice.DeviceId() != 0xFFFF && kCurrentDiskSectorCount > 0;
}
Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer)