diff --git a/paw/stos/arch/amd64/cpu/init.c b/paw/stos/arch/amd64/cpu/init.c index 02ec45e..61586cc 100644 --- a/paw/stos/arch/amd64/cpu/init.c +++ b/paw/stos/arch/amd64/cpu/init.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -131,3 +133,22 @@ HalKpcrP1Init(KPCR *Kpcr) : "memory" ); } + +VOID +HalKpcrP2Init(KPCR *Kpcr) +{ + ST_STATUS Status; + + if (Kpcr == NULL) { + return; + } + + Status = ExPoolInit(&Kpcr->AllocPool); + if (Status != STATUS_SUCCESS) { + KeKnot( + KNOT_MISC, + "failed to initialize pool for cpu%d\n", + Kpcr->CoreId + ); + } +} diff --git a/paw/stos/ex/pool.c b/paw/stos/ex/pool.c new file mode 100644 index 0000000..2486ce9 --- /dev/null +++ b/paw/stos/ex/pool.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: Pool allocator + * Author: Chloe M. + */ + +#include +#include +#include +#include + +#define DTRACE(Fmt, ...) \ + TRACE("[ POOL ]: " Fmt, ##__VA_ARGS__) + +/* Globals */ +static USIZE PoolCount = 0; + +static ST_STATUS +PoolInitBlock(MEMORY_BLOCK *Block) +{ + if (Block == NULL) { + return STATUS_INVALID_PARAM; + } + + Block->FirstPage = MmAllocPages(1); + if (Block->FirstPage == NULL) { + return STATUS_NO_MEMORY; + } + + Block->LastPage = Block->FirstPage; + Block->PageCount = 1; + RtlMemSet(Block->FirstPage, 0, PAGESIZE); + return STATUS_SUCCESS; +} + +ST_STATUS +ExPoolInit(MEMORY_POOL *Pool) +{ + UCHAR LevelIdx; + MEMORY_BLOCK *Block; + ST_STATUS Status; + + if (Pool == NULL) { + return STATUS_INVALID_PARAM; + } + + /* Initialize the pools */ + DTRACE("bringing up pool #%d\n", PoolCount); + for (LevelIdx = 0; LevelIdx < LEVEL_COUNT; ++LevelIdx) { + Block = &Pool->BlockLevels[LevelIdx]; + Status = PoolInitBlock(Block); + + /* XXX: We may wanna clean up our mess we made */ + if (Status != STATUS_SUCCESS) { + DTRACE("critical: failed to initialize pool\n"); + return STATUS_NO_MEMORY; + } + } + + DTRACE("brought up %d levels for pool #%d : ok\n", LEVEL_COUNT, PoolCount); + ++PoolCount; + return STATUS_SUCCESS; +} diff --git a/paw/stos/head/ex/pool.h b/paw/stos/head/ex/pool.h new file mode 100644 index 0000000..57db775 --- /dev/null +++ b/paw/stos/head/ex/pool.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: Pool allocator + * Author: Chloe M. + */ + +#ifndef _EX_POOL_H_ +#define _EX_POOL_H_ 1 + +#include +#include +#include + +/* Compute the granularity of a specific level */ +#define LEVEL_GRAN(LEVEL) \ + (1 << (3 + (LEVEL))) + +/* Maximum levels per pool */ +#define LEVEL_COUNT 8 + +/* + * When allocating pages, we sacrifice a little bit of its + * first bytes to store some metadata. This is the true size + * of unreserved / usable data. + */ +#define POOL_REAL_PAGESZ \ + (PAGESIZE - sizeof(MEMORY_PAGE)) + +/* + * Page data structure used internally to link together page + * lists + * + * @Bitmap: Bitmap to data [0 : free, 1 : allocated] + * @Next: Next page in list + */ +typedef struct _MEMORY_PAGE { + UQUAD Bitmap; + struct _MEMORY_PAGE *Next; +} MEMORY_PAGE; + +/* + * A memory block holds a list of memory chunks of a specific + * granularity. + * + * @FirstPage: First page in list + * @LastPage: Last page in list + * @PageCount: Number of pages total + */ +typedef struct { + MEMORY_PAGE *FirstPage; + MEMORY_PAGE *LastPage; + USIZE PageCount; +} MEMORY_BLOCK; + +/* + * A memory pool holds blocks of varying granularities + * + * @BlockLevels: Block levels [granularity : GRAN(level)] + */ +typedef struct { + MEMORY_BLOCK BlockLevels[LEVEL_COUNT]; +} MEMORY_POOL; + +/* + * Initialize a memory pool + * + * @Pool: Memory pool to initialize + */ +ST_STATUS ExPoolInit(MEMORY_POOL *Pool); + +#endif /* !_EX_POOL_H_ */ diff --git a/paw/stos/head/hal/kpcr.h b/paw/stos/head/hal/kpcr.h index eda957b..9e8aece 100644 --- a/paw/stos/head/hal/kpcr.h +++ b/paw/stos/head/hal/kpcr.h @@ -11,17 +11,20 @@ #include #include +#include /* * The kernel processor control region contains MI * information about the processor. * - * @CoreId: Processor core ID assigned by us - * @Mcb: Machine-core block + * @CoreId: Processor core ID assigned by us + * @Mcb: Machine-core block + * @AllocPool: Memory-allocation pool */ typedef struct { USHORT CoreId; MCB Mcb; + MEMORY_POOL AllocPool; } KPCR; /* @@ -31,4 +34,11 @@ typedef struct { */ VOID HalKpcrP1Init(KPCR *Kpcr); +/* + * Phase 2 initialization of processor + * + * @Kpcr: KPCR to initialize + */ +VOID HalKpcrP2Init(KPCR *Kpcr); + #endif /* !_HAL_KPCR_H_ */ diff --git a/paw/stos/init/init.c b/paw/stos/init/init.c index 87f41ad..1c04ea2 100644 --- a/paw/stos/init/init.c +++ b/paw/stos/init/init.c @@ -75,4 +75,7 @@ KiKernelEntry(VOID) /* Initialize ACPI */ AcpiInit(); + + /* Phase 2 initialization of the bootstrap core */ + HalKpcrP2Init(&BootstrapCore); }