diff --git a/service/ptos/head/mm/vm.h b/service/ptos/head/mm/vm.h index 4365cad..0751e57 100644 --- a/service/ptos/head/mm/vm.h +++ b/service/ptos/head/mm/vm.h @@ -10,6 +10,10 @@ #define _MM_VM_H_ 1 #include +#include +#include +#include +#include /* * Virtual memory allocation region. This is outside the @@ -28,4 +32,39 @@ #define VMA_TO_PMA(VMA) \ (UPTR)PTR_NOFFSET(VMA, KeBpalLoadBase()) +/* + * Represents a virtual memory range + * + * @VirtualBase: Virtual address base + * @PhysicalBase: Physical address base + * @Length: Length of memory range + */ +typedef struct { + UPTR VirtualBase; + UPTR PhysicalBase; + USIZE Length; +} MM_RANGE; + +/* + * Unmap a virtual memory range + * + * @Vas: Virtual address space to unmap + * @Range: Range to unmap + * @PageSize: Page size to unmap + */ +PT_STATUS MmUnmapRange(MMU_VAS *Vas, const MM_RANGE *Range, MMU_PAGESIZE PageSize); + +/* + * Map a virtual memory range + * + * @Vas: Virtual address space to map within + * @Range: Range to map + * @Prot: Protection flags to map with + * @PageSize: Page size to map + */ +PT_STATUS MmMapRange( + MMU_VAS *Vas, const MM_RANGE *Range, + MM_PROT Prot, MMU_PAGESIZE PageSize +); + #endif /* !_MM_VM_H_ */ diff --git a/service/ptos/mm/vm.c b/service/ptos/mm/vm.c new file mode 100644 index 0000000..34caf69 --- /dev/null +++ b/service/ptos/mm/vm.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2026, Chloe M. + * Provided under the BSD-3 clause. + * + * Description: Virtual memory management + * Author: Chloe M. + */ + +#include +#include +#include + +/* 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 +}; + +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; +}