From c95dad2a6be6bd6a78a2b22b01daa5e542a297a3 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 18 Apr 2026 19:20:54 -0400 Subject: [PATCH] sp1: mm: Add physical memory management groundwork Signed-off-by: Ian Moffett --- usr/src/sp1/common/Makefile | 1 + usr/src/sp1/common/mm/vm_physseg.c | 117 +++++++++++++++++++++++++++++ usr/src/sp1/common/os/main.c | 4 + usr/src/sp1/head/mm/physmem.h | 20 +++++ 4 files changed, 142 insertions(+) create mode 100644 usr/src/sp1/common/mm/vm_physseg.c create mode 100644 usr/src/sp1/head/mm/physmem.h diff --git a/usr/src/sp1/common/Makefile b/usr/src/sp1/common/Makefile index 39eadbc..737dbb4 100644 --- a/usr/src/sp1/common/Makefile +++ b/usr/src/sp1/common/Makefile @@ -12,6 +12,7 @@ CFILES = $(shell find os/ -name "*.c") CFILES += $(shell find io/ -name "*.c") CFILES += $(shell find bpt/ -name "*.c") +CFILES += $(shell find mm/ -name "*.c") CFILES += $(shell find ../ext -name "*.c") CFILES += $(shell find ../lib -name "*.c") diff --git a/usr/src/sp1/common/mm/vm_physseg.c b/usr/src/sp1/common/mm/vm_physseg.c new file mode 100644 index 0000000..7a6fd53 --- /dev/null +++ b/usr/src/sp1/common/mm/vm_physseg.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2026, Mirocom Laboratories + * All rights reserved. + * + * The following sources are CONFIDENTIAL and PROPRIETARY + * property of Mirocom Laboratories. Unauthorized copying, + * use, distribution or modification of this file, in whole + * and in part, is strictly prohibited without the prior written + * consent from Mirocom Laboratories. + */ + +#include +#include +#include +#include +#include +#include + +#define pr_trace(fmt, ...) \ + printf("physseg: " fmt, ##__VA_ARGS__) + +/* Use to convert type constants to strings */ +#define MEM_TYPE(TYPE) \ + ((TYPE) < NELEM(typetab)) \ + ? typetab[(TYPE)] \ + : "invalid" + +/* + * Memory type constant to human readable + * string table. + */ +static const char *typetab[] = { + [MEMORY_USABLE] = "usable", + [MEMORY_RESERVED] = "reserved", + [MEMORY_ACPI_RECLAIM] = "acpi reclaimable", + [MEMORY_ACPI_NVS] = "acpi nvs", + [MEMORY_BAD] = "bad*", + [MEMORY_BOOTLOADER] = "bootloader", + [MEMORY_KERNEL] = "syspaw", + [MEMORY_FRAMEBUFFER] = "framebuffer", + [MEMORY_ACPI_TABLES] = "acpi tables" +}; + +/* Memory stats */ +static uintptr_t highest_usable; +static size_t mem_total = 0; +static size_t mem_usable = 0; + +static inline void +physmem_print_size(const char *title, size_t len) +{ + if (title == NULL) { + return; + } + + if (len >= UNIT_GIB) { + pr_trace("... %d GiB %s\n", len / UNIT_GIB, title); + } else if (len >= UNIT_MIB) { + pr_trace("... %d MiB %s\n", len / UNIT_MIB, title); + } else { + pr_trace("... %d bytes %s\n", len, title); + } +} + +/* + * Begin scanning physical memory for usable entries + * and other information + */ +static void +physmem_probe(void) +{ + struct mem_entry entry; + status_t status; + + for (size_t i = 0;; ++i) { + status = bpt_mem_entry_i(i, &entry); + + /* Are there no more entries? */ + if (status != STATUS_SUCCESS) { + break; + } + + /* Print this entry */ + pr_trace( + "%p ... %p : %s\n", + entry.base, + entry.base + entry.length, + MEM_TYPE(entry.type) + ); + + mem_total += entry.length; + + /* Skip non-usable memory from here on out */ + if (entry.type != MEMORY_USABLE) { + continue; + } + + if ((entry.base + entry.length) > highest_usable) { + highest_usable = ALIGN_UP(entry.base + entry.length, PAGESIZE); + } + + mem_usable += entry.length; + } + + /* Print memory stats */ + pr_trace("begin stats\n"); + physmem_print_size("usable", mem_usable); + physmem_print_size("total", mem_total); +} + +void +mm_physmem_init(void) +{ + /* Probe the physical memory */ + pr_trace("sniffing out physical memory...\n"); + physmem_probe(); +} diff --git a/usr/src/sp1/common/os/main.c b/usr/src/sp1/common/os/main.c index 607d56a..1fc7e56 100644 --- a/usr/src/sp1/common/os/main.c +++ b/usr/src/sp1/common/os/main.c @@ -13,6 +13,7 @@ #include #include #include +#include #define KERNEL_VERSION "0.0.1" @@ -46,4 +47,7 @@ main(void) /* Initialize boot protocol translation layer */ bpt_init(); + + /* Initialize physical memory management */ + mm_physmem_init(); } diff --git a/usr/src/sp1/head/mm/physmem.h b/usr/src/sp1/head/mm/physmem.h new file mode 100644 index 0000000..88e167b --- /dev/null +++ b/usr/src/sp1/head/mm/physmem.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2026, Mirocom Laboratories + * All rights reserved. + * + * The following sources are CONFIDENTIAL and PROPRIETARY + * property of Mirocom Laboratories. Unauthorized copying, + * use, distribution or modification of this file, in whole + * and in part, is strictly prohibited without the prior written + * consent from Mirocom Laboratories. + */ + +#ifndef _MM_PHYSMEM_H_ +#define _MM_PHYSMEM_H_ 1 + +/* + * Initialize the physical memory management + */ +void mm_physmem_init(void); + +#endif /* !_MM_PHYSMEM_H_ */