Files
PluralTechnology/service/ptos/mm/vm.c
T
2026-07-11 20:27:07 -04:00

142 lines
3.1 KiB
C

/*
* Copyright (c) 2026, Chloe M.
* Provided under the BSD-3 clause.
*
* Description: Virtual memory management
* Author: Chloe M.
*/
#include <mm/vm.h>
#include <mm/pm.h>
#include <ex/trace.h>
#include <hal/page.h>
#include <hal/mmu.h>
#include <ke/bugcheck.h>
#include <ptdef.h>
#define DTRACE(Fmt, ...) \
TRACE("[ VM ]: " Fmt, ##__VA_ARGS__)
/*
* Number of pages we start with that can be valloc'd
* total.
*/
#define INITIAL_VALLOC_PAGES 128
/* Use to safely convert page size */
#define PAGE_SIZE(PS) \
((PS) >= NELEM(PageSizeTable)) \
? PageSizeTable[PAGESIZE_4K] \
: PageSizeTable[(PS)]
/* Page size table */
static USIZE PageSizeTable[] = {
[PAGESIZE_4K] = 0x1000
};
/* Bump pointer */
static UPTR VallocBump = VALLOC_BASE;
PT_STATUS MmUnmapRange(MMU_VAS *Vas, const MM_RANGE *Range, MMU_PAGESIZE PageSize)
{
PT_STATUS Status;
UPTR Off = 0;
UPTR VirtualBase;
USIZE Gran;
if (Vas == NULL || Range == NULL) {
return STATUS_INVALID_PARAM;
}
/* Align down the base addresses */
VirtualBase = ALIGN_DOWN(Range->VirtualBase, PAGESIZE);
Gran = PAGE_SIZE(PageSize);
for (Off = 0; Off < Range->Length; Off += Gran) {
Status = HalMmuUnmapPage(
Vas,
VirtualBase + Off,
PageSize
);
if (PT_ERROR(Status)) {
return Status;
}
}
return STATUS_SUCCESS;
}
PT_STATUS
MmMapRange(MMU_VAS *Vas, const MM_RANGE *Range, MM_PROT Prot, MMU_PAGESIZE PageSize)
{
PT_STATUS Status;
UPTR Off = 0;
UPTR VirtualBase;
UPTR PhysicalBase;
USIZE Gran;
if (Vas == NULL || Range == NULL) {
return STATUS_INVALID_PARAM;
}
/* Align down the base addresses */
VirtualBase = ALIGN_DOWN(Range->VirtualBase, PAGESIZE);
PhysicalBase = ALIGN_DOWN(Range->PhysicalBase, PAGESIZE);
Gran = PAGE_SIZE(PageSize);
for (Off = 0; Off < Range->Length; Off += Gran) {
Status = HalMmuMapPage(
Vas,
VirtualBase + Off,
PhysicalBase + Off,
Prot,
PageSize
);
if (PT_ERROR(Status)) {
MmUnmapRange(Vas, Range, PageSize);
return Status;
}
}
return STATUS_SUCCESS;
}
VOID
MmVmInit(VOID)
{
PT_STATUS Status;
MMU_VAS VasCurrent;
UPTR VirtualStart;
UPTR VirtualEnd, Off;
UPTR PhysicalBase;
USIZE NumPages;
MM_PFN Pfn;
HalMmuReadVas(&VasCurrent);
VirtualStart = VallocBump;
VallocBump += INITIAL_VALLOC_PAGES * PAGESIZE;
VirtualEnd = VallocBump;
NumPages = (VirtualEnd - VirtualStart) / PAGESIZE;
for (Off = 0; Off < NumPages * PAGESIZE; Off += PAGESIZE) {
Pfn = MmRequestFrame();
PhysicalBase = PFN_TO_ADDRESS(Pfn);
Status = HalMmuMapPage(
&VasCurrent,
VirtualStart + Off,
PhysicalBase + Off,
PAGE_READ | PAGE_WRITE,
PAGESIZE_4K
);
if (PT_ERROR(Status)) {
KeBugCheck(BUGCHECK_OOM, "failed to map valloc pages\n");
}
}
DTRACE("initialized %d valloc pages\n", NumPages);
}