diff --git a/paw/stos/head/mm/pmm.h b/paw/stos/head/mm/pmm.h new file mode 100644 index 0000000..a6c2d0e --- /dev/null +++ b/paw/stos/head/mm/pmm.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: Physical memory management + * Author: Chloe M. + */ + +#ifndef _MM_PMM_H_ +#define _MM_PMM_H_ 1 + +#include + +/* + * Initialize the physical memory management + */ +VOID MmInitPmm(VOID); + +#endif /* !_MM_PMM_H_ */ diff --git a/paw/stos/init/init.c b/paw/stos/init/init.c index 23c50fb..fe650dd 100644 --- a/paw/stos/init/init.c +++ b/paw/stos/init/init.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #define DTRACE(Fmt, ...) \ @@ -43,4 +44,7 @@ KiKernelEntry(VOID) /* Init bootcons */ BootVidInitCons(NULL); + + /* Initialize physical memory */ + MmInitPmm(); } diff --git a/paw/stos/ke/Makefile b/paw/stos/ke/Makefile index 778091b..1ddab20 100644 --- a/paw/stos/ke/Makefile +++ b/paw/stos/ke/Makefile @@ -13,6 +13,7 @@ CFILES = $(shell find ../init -name "*.c") CFILES += $(shell find ../xt -name "*.c") CFILES += $(shell find ../lib -name "*.c") CFILES += $(shell find ../drivers -name "*.c") +CFILES += $(shell find ../mm -name "*.c") CFILES += $(shell find bpal -name "*.c") DFILES = $(CFILES:.c=.d) OFILES = $(CFILES:.c=.o) diff --git a/paw/stos/mm/pmm.c b/paw/stos/mm/pmm.c new file mode 100644 index 0000000..394db67 --- /dev/null +++ b/paw/stos/mm/pmm.c @@ -0,0 +1,99 @@ +/* + * 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(); +}