/* * Copyright (c) 2026, Chloe M. * Provided under the BSD-3 clause. * * Description: Physical memory management * Author: Chloe M. */ #include #include #include #include #define DTRACE(Fmt, ...) \ TRACE("[ PMM ]: " 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] = "stoskrnl.sys", [MEMORY_FRAMEBUFFER] = "framebuffer", [MEMORY_ACPI_TABLES] = "acpi tables" }; /* Globals */ static USIZE UsableMemory = 0; /* * Print the units of a size in a pretty format * * @Length: Number of bytes * @Title: Title of units */ static inline VOID MmPrintUnits(USIZE Length, const CHAR *Title) { if (Title == NULL) { return; } if (Length >= UNIT_GIB) { DTRACE("%d gib %s\n", Length / UNIT_GIB, Title); } else if (Length >= UNIT_MIB) { DTRACE("%d mib %s\n", Length / UNIT_MIB, Title); } else { DTRACE("%010d b %s\n", Length, Title); } } static VOID MmProbeMemory(VOID) { BPAL_HANDLE BpalHandle; MEMMAP_ENTRY Entry; UPTR EntryEnd; USIZE Idx; ST_STATUS Status; KeBpalGetHandle(&BpalHandle); for (Idx = 0;; ++Idx) { Status = BpalHandle.MemEntryIdx(Idx, &Entry); if (Status != STATUS_SUCCESS) { break; } EntryEnd = Entry.Base + Entry.Length; DTRACE("[%p - %p) ~ %s\n", Entry.Base, EntryEnd, MEM_TYPE(Entry.Type)); /* Only usable entries from this point on */ if (Entry.Type != MEMORY_USABLE) { continue; } UsableMemory += Entry.Length; } MmPrintUnits(UsableMemory, "avl"); } VOID MmInitPmm(VOID) { DTRACE("sniffing out installed ram...\n"); MmProbeMemory(); }