summaryrefslogtreecommitdiff
path: root/na/include
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-04-21 23:22:09 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-04-21 23:22:09 +0800
commit04f27cb82d29c980660e485d3358ead9a820d281 (patch)
tree282448c1720b43a1d72630d22e6d4481a6a40248 /na/include
parent510f295124f7c8e51ec66f59be61a9e9aa8f9d25 (diff)
downloadlume-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.h75
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();