summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-03-25 15:35:28 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-03-25 15:35:28 +0100
commit0ead895f52d24dad009f738037a7795d4e3d840a (patch)
tree863fd1c881fc7bf26ab78b932421e6416bbef288 /dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
parent59dbe4cffc7c633709ef8b45f49c46daf7f74e92 (diff)
kernel: Refactor AHCI I/O path, enhance memory allocators, and cleanup obsolete script
- Removed unused `build_gcc.sh` script. - Namespaced CPU feature flags under `NeOS` and transitioned from enum to unnamed enum for scoping. - Renamed `drv_std_input_output` to `drv_std_input_output_ahci` for clarity. - Improved AHCI driver documentation and added zeroing for read buffers. - Added optional `pad` parameter to memory allocators: `mm_alloc_bitmap`, `mm_new_heap`, `PageMgr::Request`, etc. - Updated bitmap allocator to correctly handle and align with padded sizes. - Added `fPad` field to memory header block. - Fixed `ATA-DMA` mode comment, corrected PRD usage and logic. - Improved code documentation and formatting in `UserProcessScheduler`, `PageMgr`, and related components. - Enhanced safety in process memory cleanup (e.g., `StackReserve` cleanup). Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc')
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc48
1 files changed, 41 insertions, 7 deletions
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
index bd5c86f4..b1584c80 100644
--- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -63,7 +63,7 @@ STATIC Char kCurrentDiskModel[50] = {"UNKNOWN AHCI DRIVE"};
STATIC UInt16 kSATAPortsImplemented = 0U;
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
-STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept;
+STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept;
STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept;
@@ -73,21 +73,29 @@ STATIC Void drv_compute_disk_ahci() noexcept
{
kSATASectorCount = 0UL;
+ /// Normally 512 bytes, but add an additional 512 bytes to make 1 KIB.
const UInt16 kSzIdent = kib_cast(1);
+ /// Push it to the stack
UInt8 identify_data[kSzIdent] = {0};
rt_set_memory(identify_data, 0, kSzIdent);
- drv_std_input_output<NO, YES, YES>(0, identify_data, kAHCISectorSize, kSzIdent);
+ /// Send AHCI command.
+ drv_std_input_output_ahci<NO, YES, YES>(0, identify_data, kAHCISectorSize, kSzIdent);
+ /// Extract 28-bit LBA.
kSATASectorCount = (identify_data[61] << 16) | identify_data[60];
+ /// Show what we got.
kout << "Disk Model: " << kCurrentDiskModel << kendl;
kout << "Disk Size: " << number(drv_get_size()) << kendl;
kout << "Disk Sector Count: " << number(kSATASectorCount) << kendl;
}
+/// @brief Finds a command slot for a HBA port.
+/// @param port The port to search on.
+/// @return The slot, or ~0.
STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept
{
UInt32 slots = (port->Sact | port->Ci);
@@ -103,8 +111,13 @@ STATIC Int32 drv_find_cmd_slot(HbaPort* port) noexcept
return ~0;
}
+/// @brief Send an AHCI command, according to the template parameters.
+/// @param lba Logical Block Address to look for.
+/// @param buffer The data buffer to transfer.
+/// @param sector_sz The disk's sector size (unused)
+/// @param size_buffer The size of the **buffer** parameter.
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
-STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept
+STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, SizeT size_buffer) noexcept
{
UIntPtr slot = 0UL;
@@ -113,6 +126,12 @@ STATIC Void drv_std_input_output(UInt64 lba, UInt8* buffer, SizeT sector_sz, Siz
if (slot == ~0)
return;
+ if (!Write)
+ {
+ // Zero-memory the buffer field.
+ rt_set_memory(buffer, 0, size_buffer);
+ }
+
volatile HbaCmdHeader* command_header = ((HbaCmdHeader*)(((UInt64)kSATAHba->Ports[kSATAIndex].Clb)));
command_header += slot;
@@ -310,6 +329,8 @@ STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi)
return NO;
}
+/// @brief Checks if an AHCI device is detected.
+/// @return Either if detected, or not found.
Bool drv_std_detected_ahci()
{
return kSATADev.DeviceId() != (UShort)PCI::PciConfigKind::Invalid && kSATADev.Bar(kSATABar5) != 0;
@@ -317,6 +338,7 @@ Bool drv_std_detected_ahci()
namespace NeOS
{
+ /// @brief Initialize an AHCI device (StorageKit)
UInt16 sk_init_ahci_device(BOOL atapi)
{
UInt16 pi = 0;
@@ -327,6 +349,7 @@ namespace NeOS
return pi;
}
+ /// @brief Implementation details namespace.
namespace Detail
{
/// @brief Read AHCI device.
@@ -344,7 +367,7 @@ namespace NeOS
if (!disk)
return;
- drv_std_input_output<NO, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
+ drv_std_input_output_ahci<NO, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
}
/// @brief Write AHCI device.
@@ -362,10 +385,13 @@ namespace NeOS
if (!disk)
return;
- drv_std_input_output<YES, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
+ drv_std_input_output_ahci<YES, YES, NO>(disk->fPacket.fPacketLba, (UInt8*)disk->fPacket.fPacketContent, kAHCISectorSize, disk->fPacket.fPacketSize);
}
} // namespace Detail
+ /// @brief Acquires a new AHCI device with drv_index in mind.
+ /// @param drv_index The drive index to assign.
+ /// @return A wrapped device interface if successful, or error code.
ErrorOr<AHCIDeviceInterface> sk_acquire_ahci_device(Int32 drv_index)
{
if (!drv_std_detected_ahci())
@@ -382,16 +408,24 @@ namespace NeOS
}
} // namespace NeOS
+// ================================================================================================
+
+//
+// This applies only if we compile with AHCI as a default disk driver.
+//
+
+// ================================================================================================
+
#ifdef __AHCI__
Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer)
{
- drv_std_input_output<YES, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
+ drv_std_input_output_ahci<YES, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
}
Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer)
{
- drv_std_input_output<NO, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
+ drv_std_input_output_ahci<NO, YES, NO>(lba, (UInt8*)buffer, sector_sz, size_buffer);
}
Bool drv_std_init(UInt16& pi)