diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-04-21 23:22:09 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-04-21 23:22:09 +0800 |
| commit | 04f27cb82d29c980660e485d3358ead9a820d281 (patch) | |
| tree | 282448c1720b43a1d72630d22e6d4481a6a40248 /na/include | |
| parent | 510f295124f7c8e51ec66f59be61a9e9aa8f9d25 (diff) | |
| download | lume-04f27cb82d29c980660e485d3358ead9a820d281.tar.gz lume-04f27cb82d29c980660e485d3358ead9a820d281.tar.xz | |
feat: implement Physical Memory Manager (PMM) with Buddy System and Per-CPU Cache
Diffstat (limited to 'na/include')
| -rw-r--r-- | na/include/lume/pmm.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/na/include/lume/pmm.h b/na/include/lume/pmm.h new file mode 100644 index 0000000..1ac1e17 --- /dev/null +++ b/na/include/lume/pmm.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2026 Richard Qin */ + +#pragma once + +/* + * Physical Memory Manager (PMM) — Buddy System + Per-CPU Cache + * + * Manages all physical page frames discovered via FDT. Built on a + * power-of-two buddy allocator for multi-page requests, with a + * Per-CPU single-page cache (PCP) to reduce lock contention on the + * hot single-frame alloc/free path. + * + * Concurrency model: + * - PCP operations run with interrupts disabled (same-CPU safety). + * - Global buddy operations are protected by a single Spinlock. + * - Reference counts use __atomic builtins (lock-free). + * + * Reference: docs/specs/pmm.md + */ + +#include <lume/types.h> +#include <lume/frame.h> + +/* Buddy system constants */ +inline constexpr int kMaxOrder = 11; // Orders 0..10 → 4KB..4MB +inline constexpr int kPcpHighWatermark = 64; // Max frames cached per CPU +inline constexpr int kPcpBatchSize = 32; // Frames moved per refill/drain + +/* ================================================================== */ +/* Public free-function API */ +/* ================================================================== */ + +/* + * Initialize the PMM. Called by BSP after fdt_init(). + * Discovers memory via FDT, places frame_map, and populates buddy lists. + * Panics on failure (no memory, bad FDT, etc.). + */ +void pmm_init(); + +/* --- Single-frame fast path (uses PCP) --- */ + +// Allocate one 4KB frame. Returns nullptr on OOM. +Frame* pmm_alloc_frame(); + +// Free one 4KB frame. +void pmm_free_frame(Frame* frame); + +/* --- Multi-frame slow path (direct buddy) --- */ + +// Allocate 2^order contiguous frames. Returns nullptr on OOM. +Frame* pmm_alloc_frames(uint8 order); + +// Free 2^order contiguous frames. +void pmm_free_frames(Frame* frame, uint8 order); + +/* --- Reference counting (atomic, lock-free) --- */ + +void frame_incref(Frame* frame); +void frame_decref(Frame* frame); + +/* --- Address conversion --- */ + +// Convert a Frame* to its physical address. +uint64 frame_to_pa(const Frame* frame); + +// Convert a physical address to its Frame*. +Frame* pa_to_frame(uint64 pa); + +// Convert a Frame* to a kernel virtual address. +uint64 frame_to_va(const Frame* frame); + +// Query PMM memory range (for VMM kernel mapping) +uint64 pmm_get_mem_base(); +uint64 pmm_get_mem_size(); |
