diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
| commit | 83d870e58457a1d335a1d9b9966a6a1887cc297b (patch) | |
| tree | 72888f88c7728c82f3f6df1f4f70591de15eab36 /src/kernel/DmaKit | |
| parent | ab37adbacf0f33845804c788b39680cd754752a8 (diff) | |
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'src/kernel/DmaKit')
| -rw-r--r-- | src/kernel/DmaKit/DmaPool.h | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/kernel/DmaKit/DmaPool.h b/src/kernel/DmaKit/DmaPool.h new file mode 100644 index 00000000..e20f8c69 --- /dev/null +++ b/src/kernel/DmaKit/DmaPool.h @@ -0,0 +1,101 @@ +/* ======================================== + + Copyright (C) 2025, Amlal El Mahrouss , licensed under the Apache 2.0 license. + + File: DmaPool.h + Purpose: Dma Pool Manager. + +======================================== */ + +#pragma once + +#include <KernelKit/DebugOutput.h> + +#ifdef __NE_AMD64__ +#include <HALKit/AMD64/Processor.h> +#define kNeDMAPoolStart (0x1000000) +#define kNeDMAPoolSize (0x1000000) +#elif defined(__NE_ARM64__) +#include <HALKit/ARM64/Processor.h> + +/// @todo what reference offset shall we use? +#define kNeDMAPoolStart (0x1000000) +#define kNeDMAPoolSize (0x1000000) +#endif + +#define kNeDMABestAlign (8) + +namespace Kernel { +/// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it. +inline UInt8* kDmaPoolPtr = (UInt8*) kNeDMAPoolStart; +inline const UInt8* kDmaPoolEnd = (UInt8*) (kNeDMAPoolStart + kNeDMAPoolSize); + +/***********************************************************************************/ +/// @brief allocate from the rtl_dma_alloc system. +/// @param size the size of the chunk to allocate. +/// @param align alignement of pointer. +/***********************************************************************************/ +inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { + if (!size) { + return nullptr; + } + + /// Check alignement according to architecture. + if ((align % kNeDMABestAlign) != 0) { + return nullptr; + } + + UIntPtr addr = (UIntPtr) kDmaPoolPtr; + + /// here we just align the address according to a `align` variable, i'd rather be a power of two + /// really. + addr = (addr + (align - 1)) & ~(align - 1); + + if ((addr + size) > reinterpret_cast<UIntPtr>(kDmaPoolEnd)) { + err_global_get() = kErrorDmaExhausted; + return nullptr; + } + + kDmaPoolPtr = (UInt8*) (addr + size); + + HAL::mm_memory_fence((VoidPtr) addr); + + return (VoidPtr) addr; +} + +/***********************************************************************************/ +/// @brief Free DMA pointer. +/***********************************************************************************/ +inline Void rtl_dma_free(SizeT size) { + if (!size) return; + + auto ptr = (kDmaPoolPtr - size); + + if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) { + err_global_get() = kErrorDmaExhausted; + return; + } + + kDmaPoolPtr = ptr; + + HAL::mm_memory_fence(ptr); +} + +/***********************************************************************************/ +/// @brief Flush DMA pointer. +/***********************************************************************************/ +inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) { + if (ptr > kDmaPoolEnd) { + return; + } + + if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) { + err_global_get() = kErrorDmaExhausted; + return; + } + + for (SizeT buf_idx = 0UL; buf_idx < size_buffer; ++buf_idx) { + HAL::mm_memory_fence((VoidPtr) ((UInt8*) ptr + buf_idx)); + } +} +} // namespace Kernel |
