feat(kernel/mm): page store backing layer
This commit is contained in:
parent
b7ec8e2c7b
commit
e8e2f06b0a
2 changed files with 294 additions and 0 deletions
169
kernel/src/core/mm_store.cpp
Normal file
169
kernel/src/core/mm_store.cpp
Normal file
|
|
@ -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;
|
||||
}
|
||||
125
kernel/src/core/mm_store.h
Normal file
125
kernel/src/core/mm_store.h
Normal file
|
|
@ -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 */
|
||||
Loading…
Reference in a new issue