From 739924cb5cb84e8f29c90b4accd0910daa58a579 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Sat, 20 Sep 2025 17:13:57 -0400 Subject: kern/amd64: mmu: Add page-level cacheability attrs This commit adds support for page-level cacheability attributes. We have added the pmap_set_cache() as well as some MMU_CACHE_* bits Signed-off-by: Ian Moffett --- src/sys/arch/amd64/cpu/mmu.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ src/sys/include/vm/mmu.h | 23 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/sys/arch/amd64/cpu/mmu.c b/src/sys/arch/amd64/cpu/mmu.c index 2b98d78..dad22dc 100644 --- a/src/sys/arch/amd64/cpu/mmu.c +++ b/src/sys/arch/amd64/cpu/mmu.c @@ -404,6 +404,51 @@ mmu_free_vas(struct vm_vas *vas) return 0; } +/* + * Set caching attributes + */ +int +pmap_set_cache(struct vm_vas *vas, vaddr_t va, cacheattr_t attr) +{ + uintptr_t *pte, pa; + uint32_t flags; + int error; + size_t idx; + + /* We'll modify page-level attributes */ + error = mmu_read_level( + vas, va, MMU_TBL, + &pte, true + ); + + if (error < 0) { + return -EINVAL; + } + + /* Uncachable? */ + if (ISSET(attr, MMU_CACHE_UC)) { + flags |= PTE_PCD; + flags &= ~PTE_PWT; + attr &= ~MMU_CACHE_WT; + } + + /* Write through? */ + if (ISSET(attr, MMU_CACHE_WT)) { + flags &= ~PTE_PCD; + flags |= PTE_PWT; + } + + /* Not global? */ + if (!ISSET(attr, MMU_CACHE_GL)) { + flags &= ~PTE_GLOBAL; + } + + /* Update attributes and flush the TLB */ + pte[idx] = pa | flags; + __invlpg((void *)va); + return 0; +} + /* * Verify that we are in a known state */ diff --git a/src/sys/include/vm/mmu.h b/src/sys/include/vm/mmu.h index be0678e..54a694b 100644 --- a/src/sys/include/vm/mmu.h +++ b/src/sys/include/vm/mmu.h @@ -41,6 +41,17 @@ #include /* standard */ #include +/* Caching types */ +#define MMU_CACHE_UC BIT(0) /* Uncachable */ +#define MMU_CACHE_WT BIT(1) /* Write-through */ +#define MMU_CACHE_GL BIT(2) /* Global (if supported) */ + +/* + * Represents caching attributes that can be applied + * to the address space (see VM_CACHE_* above). + */ +typedef uint16_t cacheattr_t; + /* * Standard memory protection flags */ @@ -127,4 +138,16 @@ int mmu_write_vas(struct vm_vas *vas); */ int mmu_free_vas(struct vm_vas *vas); +/* + * Update page-level caching attributes + * + * @vas: Virtual address space to target + * @va: Virtual page base to update + * @attr: Attributes to set + * + * Returns zero on success, otherwise a less than + * zero value to indicate error. + */ +int pmap_set_cache(struct vm_vas *vas, vaddr_t va, cacheattr_t attr); + #endif /* !_MACHINE_MMU_H_ */ -- cgit v1.2.3