diff --git a/kernel/src/core/mm_store.cpp b/kernel/src/core/mm_store.cpp new file mode 100644 index 000000000..322455138 --- /dev/null +++ b/kernel/src/core/mm_store.cpp @@ -0,0 +1,169 @@ +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_mm_store.cpp + * + * @purpose + * Implementation of memory store management for UniversalisOS. + * Based on PikeOS mm.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + +#include "mm_store.h" + +/* ------------------------ STATIC VARIABLES ------------------------------- */ + +/** Global memory store */ +static uos_mem_store_t mm_global_store; + +/** Per-partition memory stores */ +static uos_mem_store_t* mm_part_stores[UOS_MAX_PARTITIONS]; + +/** Number of configured partitions */ +static uint32_t mm_num_partitions = 0; + +/* ----------------------- FUNCTION IMPLEMENTATIONS ------------------------ */ + +/** + * @purpose + * Initialize global and per-partition memory stores. + */ +void uos_mm_store_init(void) { + /* Initialize global memory store */ + uos_mm_list_init(&mm_global_store.free_list); + mm_global_store.id = 0; + mm_global_store.type = UOS_MEM_TYPE_PRIVILEGED; + mm_global_store.total = 0; + mm_global_store.free = 0; + mm_global_store.lock = 0; + + /* Initialize per-partition memory stores */ + for (int i = 0; i < UOS_MAX_PARTITIONS; i++) { + mm_part_stores[i] = NULL; + } + + /* TODO: Check if memory regions are configured */ + bool memregions_configured = false; + + if (memregions_configured) { + /* TODO: Allocate memory for per-partition memory stores */ + /* TODO: Initialize per-partition memory stores */ + } else { + /* Drain boot allocator to global store */ + uint64_t size; + void* block; + + while ((block = uos_mm_balloc_drain(&size)) != NULL) { + uos_mm_list_assign(&mm_global_store.free_list, (uint64_t)block, size); + mm_global_store.total += size; + mm_global_store.free += size; + } + } + + /* TODO: Update kinfo_ptr.allpages and kinfo_ptr.freepages */ +} + +/** + * @purpose + * Reclaim temporary memory to the global memory store + * during the late kernel initialization phase. + */ +void uos_mm_store_reclaim_tmp(void) { + uint64_t size; + void* block; + + /* Reclaim all temporary memory */ + while ((block = uos_mm_balloc_reclaim_tmp(&size)) != NULL) { + uos_mm_list_assign(&mm_global_store.free_list, (uint64_t)block, size); + mm_global_store.total += size; + mm_global_store.free += size; + } + + /* TODO: Update kinfo_ptr.allpages and kinfo_ptr.freepages */ +} + +/** + * @purpose + * Get the store corresponding to store_id, or NULL + */ +uos_mem_store_t* uos_mm_store_get_by_id(uint32_t store_id) { + /* Check if memory regions are configured */ + if (mm_num_partitions == 0) { + return NULL; + } + + /* Extract partition ID and memory region ID from store_id */ + uint32_t part_id = (store_id >> 16) & 0xFFFF; + uint32_t region_id = store_id & 0xFFFF; + + /* Validate partition ID */ + if (part_id >= mm_num_partitions) { + return NULL; + } + + /* Get partition store */ + uos_mem_store_t* store = mm_part_stores[part_id]; + if (store == NULL) { + return NULL; + } + + /* TODO: Validate region ID */ + (void)region_id; + + return store; +} + +/** + * @purpose + * Allocates memory according to user, kernel and architecture alignment + * requirements from the global memory store at early boot. + */ +void* uos_mm_ralloc_boot(uint64_t size, uint64_t align) { + /* Allocate from global store */ + void* result = uos_mm_list_alloc_aligned(&mm_global_store.free_list, + size, align, 0, 0); + + if (result != NULL) { + /* Update free count */ + mm_global_store.free -= size; + + /* TODO: Update kinfo_ptr.freepages */ + } + + return result; +} + +/** + * @purpose + * Allocates memory according to user, kernel and architecture alignment + * requirements. + */ +void* uos_mm_ralloc(uos_mem_store_t* store, + uint64_t size, + uint64_t align, + uint64_t destaddr, + uint64_t align_mask) { + /* Validate store */ + if (store == NULL) { + return NULL; + } + + /* TODO: Lock store */ + + /* Allocate from store */ + void* result = uos_mm_list_alloc_aligned(&store->free_list, + size, align, destaddr, align_mask); + + if (result != NULL) { + /* Update free count */ + store->free -= size; + + /* TODO: Update kinfo_ptr.freepages if global store */ + } + + /* TODO: Unlock store */ + + return result; +} diff --git a/kernel/src/core/mm_store.h b/kernel/src/core/mm_store.h new file mode 100644 index 000000000..0caded000 --- /dev/null +++ b/kernel/src/core/mm_store.h @@ -0,0 +1,125 @@ +#ifndef UOS_MM_STORE_H +#define UOS_MM_STORE_H + +/* -------------------------- FILE PROLOGUE -------------------------------- */ + +/** + * @file + * uos_mm_store.h + * + * @purpose + * The module manages the free memory of the kernel address space and + * provides allocation functions for initialization and runtime. + * + * Based on PikeOS mm.h architecture. + */ + +/* ------------------------- FILE INCLUSION -------------------------------- */ + +#include "mm_list.h" +#include "mm_balloc.h" + +/* ------------------- MACRO / CONSTANT DEFINITIONS ------------------------ */ + +/** Maximum number of partitions */ +#define UOS_MAX_PARTITIONS 16 + +/** Memory type definitions */ +#define UOS_MEM_TYPE_PRIVILEGED 0 +#define UOS_MEM_TYPE_UNPRIVILEGED 1 + +/* ------------------------ TYPE DECLARATIONS ------------------------------ */ + +/** + * @brief Memory store structure + * + * This structure is the data structure used for allocation built from the + * memory region configuration. + * + * It contains the main list of free kernel memory for allocation. + */ +typedef struct uos_mem_store_str { + uos_mm_list_t free_list; /**< Free memory blocks */ + uint32_t id; /**< Store ID (partition + index) */ + uint32_t type; /**< Privileged / non-privileged */ + uint64_t total; /**< Total bytes */ + uint64_t free; /**< Free bytes */ + uint32_t lock; /**< Lock for runtime allocation (TODO: spinlock) */ +} uos_mem_store_t; + +/* ----------------------- FUNCTION DECLARATIONS --------------------------- */ + +/** + * @purpose + * Initialize global and per-partition memory stores. + * Afterwards, allocate memory for the per-partition memory stores. + * If memory regions are not configured, + * move all free memory of the boot allocator to the global memory store. + * + * KDEV drivers can allocate memory from configured stores after this step. + */ +void uos_mm_store_init(void); + +/** + * @purpose + * Reclaim temporary memory to the global memory store + * during the late kernel initialization phase. + */ +void uos_mm_store_reclaim_tmp(void); + +/** + * @purpose + * Get the store corresponding to store_id, or NULL + * + * @param store_id + * IN: store ID of the to-be-retrieved store. + * + * @returns + * The store uos_mem_store_t corresponding to store_id + * NULL otherwise + */ +uos_mem_store_t* uos_mm_store_get_by_id(uint32_t store_id); + +/** + * @purpose + * Allocates memory according to user, kernel and architecture alignment + * requirements from the global memory store at early boot. + * + * @param size + * IN: Requested size + * @param align + * IN: Alignment requirement to the memory chunk + * + * @returns + * Pointer to the allocated block (virtual address) + * or NULL if no suitable chunk of memory is found + */ +void* uos_mm_ralloc_boot(uint64_t size, uint64_t align); + +/** + * @purpose + * Allocates memory according to user, kernel and architecture alignment + * requirements. + * + * @param store + * IN: Take memory from the free memory in this store + * @param size + * IN: Requested size + * @param align + * IN: Alignment requirement to the memory chunk + * @param destaddr + * IN: Destination address in user space + * @param align_mask + * IN: Alignment mask for cache aliasing effects + * + * @returns + * Pointer to the allocated block (virtual address) + * or NULL if no suitable chunk of memory is found + */ +void* uos_mm_ralloc(uos_mem_store_t* store, + uint64_t size, + uint64_t align, + uint64_t destaddr, + uint64_t align_mask); + +#endif /* UOS_MM_STORE_H */