summaryrefslogtreecommitdiff
path: root/mm/memblock.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
committerRichard Qin <richard.qin.x@gmail.com>2026-10-16 02:39:56 +0800
commit8cace3f05003c6cb4d38c36890055f03151c2ad4 (patch)
treeaa739deaac0266f17c4e91b333957501cb1ea2e9 /mm/memblock.cc
parent3ad39e9878310e5317ee73c9b353c1e2c1c5c4ee (diff)
downloadlume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.gz
lume-8cace3f05003c6cb4d38c36890055f03151c2ad4.tar.xz
Remove old code
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
Diffstat (limited to 'mm/memblock.cc')
-rw-r--r--mm/memblock.cc257
1 files changed, 0 insertions, 257 deletions
diff --git a/mm/memblock.cc b/mm/memblock.cc
deleted file mode 100644
index aee0245..0000000
--- a/mm/memblock.cc
+++ /dev/null
@@ -1,257 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* Copyright (C) 2026 Richard Qin */
-
-/*
- * memblock.cc — Boot-time physical memory allocator
- *
- * Simple region tracker: one memory region (from FDT) plus an array
- * of reserved regions. Allocation searches for gaps between reserved
- * regions. All operations are O(n_reserved), which is fine for the
- * ~20 allocations that happen during early boot.
- *
- * Reference: inspired by Linux kernel's mm/memblock.c
- */
-
-#include <lume/memblock.h>
-#include <lume/fdt.h>
-#include <lume/klog.h>
-#include <lume/kprintf.h>
-#include <lume/config.h>
-#include <lume/addr.h>
-
-extern "C" char _stext[], _kernel_end[];
-
-/* ------------------------------------------------------------------ */
-/* Module state */
-/* ------------------------------------------------------------------ */
-
-namespace {
-
-constexpr uint64 kMB = 1024ULL * 1024ULL;
-
-struct {
- uint64 mem_base;
- uint64 mem_size;
-
- struct {
- uint64 base;
- uint64 size;
- } reserved[kMemblockMaxRegions];
- int reserved_count;
- bool active;
-} g_mb;
-
-/* ------------------------------------------------------------------ */
-/* Internal helpers */
-/* ------------------------------------------------------------------ */
-
-/* Insert a reserved region, keeping the array sorted by base. */
-void insert_reserved(uint64 base, uint64 size)
-{
- if (g_mb.reserved_count >= kMemblockMaxRegions) {
- kernel_panic("memblock: too many reserved regions");
- }
-
- int i = g_mb.reserved_count;
- while (i > 0 && g_mb.reserved[i - 1].base > base) {
- g_mb.reserved[i] = g_mb.reserved[i - 1];
- i--;
- }
- g_mb.reserved[i] = {base, size};
- g_mb.reserved_count++;
-}
-
-/* Check if [base, base+size) overlaps any reserved region. */
-bool overlaps_reserved(uint64 base, uint64 size)
-{
- uint64 end = base + size;
- for (int i = 0; i < g_mb.reserved_count; i++) {
- uint64 rb = g_mb.reserved[i].base;
- uint64 re = rb + g_mb.reserved[i].size;
- if (base < re && end > rb) {
- return true;
- }
- }
- return false;
-}
-
-/* Find the end of the first reserved region that covers `addr`. */
-uint64 reserved_end_covering(uint64 addr)
-{
- for (int i = 0; i < g_mb.reserved_count; i++) {
- uint64 rb = g_mb.reserved[i].base;
- uint64 re = rb + g_mb.reserved[i].size;
- if (addr >= rb && addr < re) {
- return re;
- }
- }
- return addr;
-}
-
-} // namespace
-
-/* ------------------------------------------------------------------ */
-/* Public API */
-/* ------------------------------------------------------------------ */
-
-void memblock_init(uint64 fdt_paddr)
-{
-
- /* 1. Get memory layout from FDT */
- uint64 mem_base = 0;
- uint64 mem_size = 0;
- fdt_early_get_mem_info(&mem_base, &mem_size);
- if (mem_size == 0) {
- kernel_panic("memblock_init: FDT reports zero memory");
- }
-
- g_mb.mem_base = mem_base;
- g_mb.mem_size = mem_size;
- g_mb.reserved_count = 0;
- g_mb.active = true;
-
- /* 2. Reserve firmware region [mem_base, kPhysStart).
- *
- * Everything below the kernel's linked load address is firmware
- * territory (OpenSBI), which is PMP-protected. */
- {
- uint64 fw_end = kPhysStart;
- if (fw_end > mem_base) {
- memblock_reserve(mem_base, fw_end - mem_base);
- }
- }
-
- /* 2b. Reserve stale pre-relocation kernel image.
- *
- * After physical KASLR, the kernel is relocated from its original
- * load address (kPhysStart) to a new PA. The old copy at
- * [kPhysStart, kPhysStart + kernel_size) must not be allocated —
- * it contains stale code/data that would corrupt page tables or
- * other structures if reused. */
- {
- uint64 ks_pa = boot_va_to_pa(virt_addr(
- reinterpret_cast<uint64>(_stext))).raw;
- if (ks_pa != kPhysStart) {
- /* Kernel was relocated — reserve the original location */
- uint64 kernel_size = boot_va_to_pa(virt_addr(
- reinterpret_cast<uint64>(_kernel_end))).raw - ks_pa;
- memblock_reserve(kPhysStart, kernel_size);
- }
- }
-
- /* 3. Reserve kernel image [_stext, _kernel_end) */
- uint64 ks_pa = boot_va_to_pa(virt_addr(
- reinterpret_cast<uint64>(_stext))).raw;
- uint64 ke_pa = boot_va_to_pa(virt_addr(
- reinterpret_cast<uint64>(_kernel_end))).raw;
- memblock_reserve(ks_pa, ke_pa - ks_pa);
-
- /* 4. Reserve FDT blob — it lives in RAM and must not be overwritten
- * by vmemmap/page_map or buddy before fdt_unflatten() copies it. */
- {
- struct fdt_hdr { uint32 magic; uint32 totalsize; };
- const auto* fh = reinterpret_cast<const fdt_hdr*>(fdt_paddr);
- uint32 fdt_size = ((fh->totalsize & 0xFF) << 24) |
- (((fh->totalsize >> 8) & 0xFF) << 16) |
- (((fh->totalsize >> 16) & 0xFF) << 8) |
- ((fh->totalsize >> 24) & 0xFF);
- memblock_reserve(fdt_paddr, fdt_size);
- kprintf("[memblock] FDT reserved [0x%llx, 0x%llx)\n",
- fdt_paddr, fdt_paddr + fdt_size);
- }
-
- kprintf("[memblock] RAM [0x%llx, 0x%llx) = %llu MB\n",
- mem_base, mem_base + mem_size, mem_size / kMB);
- kprintf("[memblock] kernel reserved [0x%llx, 0x%llx)\n", ks_pa, ke_pa);
-}
-
-void memblock_reserve(uint64 base, uint64 size)
-{
- uint64 aligned_base = page_align_down(base);
- uint64 aligned_end = page_align_up(base + size);
- insert_reserved(aligned_base, aligned_end - aligned_base);
-}
-
-uint64 memblock_alloc_top(uint64 size, uint64 align)
-{
- uint64 mem_end = g_mb.mem_base + g_mb.mem_size;
-
- /* Search from top of RAM downward */
- uint64 end = page_align_down(mem_end);
- uint64 start = (end - size) & ~(align - 1);
-
- while (start >= g_mb.mem_base && start + size <= mem_end) {
- if (!overlaps_reserved(start, size)) {
- memblock_reserve(start, size);
- return start;
- }
- if (start < align) {
- break;
- }
- start -= align;
- }
-
- kernel_panic("memblock_alloc_top: out of memory");
- return 0;
-}
-
-uint64 memblock_alloc(uint64 size, uint64 align)
-{
- uint64 mem_end = g_mb.mem_base + g_mb.mem_size;
- uint64 start = page_align_up(g_mb.mem_base);
-
- while (start + size <= mem_end) {
- start = (start + align - 1) & ~(align - 1);
- if (start + size > mem_end) {
- break;
- }
-
- if (!overlaps_reserved(start, size)) {
- memblock_reserve(start, size);
- return start;
- }
-
- /* Skip past the overlapping reserved region */
- uint64 skip = reserved_end_covering(start);
- if (skip <= start) {
- start += align;
- } else {
- start = skip;
- }
- }
-
- kernel_panic("memblock_alloc: out of memory");
- return 0;
-}
-
-uint64 memblock_get_mem_base() { return g_mb.mem_base; }
-uint64 memblock_get_mem_size() { return g_mb.mem_size; }
-
-bool memblock_is_active() { return g_mb.active; }
-void memblock_retire() { g_mb.active = false; }
-
-void memblock_for_each_free(void (*cb)(uint64 base, uint64 size, void* ctx),
- void* ctx)
-{
- uint64 pos = g_mb.mem_base;
- uint64 mem_end = g_mb.mem_base + g_mb.mem_size;
-
- for (int i = 0; i < g_mb.reserved_count && pos < mem_end; i++) {
- uint64 rb = g_mb.reserved[i].base;
- if (rb < pos) {
- uint64 re = g_mb.reserved[i].base + g_mb.reserved[i].size;
- if (re > pos) {
- pos = re;
- }
- continue;
- }
- if (rb > pos) {
- cb(pos, rb - pos, ctx);
- }
- pos = g_mb.reserved[i].base + g_mb.reserved[i].size;
- }
-
- if (pos < mem_end) {
- cb(pos, mem_end - pos, ctx);
- }
-}