diff options
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/arch/amd64/cpu/mmu.c | 45 | ||||
-rw-r--r-- | src/sys/include/vm/mmu.h | 23 |
2 files changed, 68 insertions, 0 deletions
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 @@ -405,6 +405,51 @@ mmu_free_vas(struct vm_vas *vas) } /* + * 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 */ int 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 <machine/vas.h> /* standard */ #include <vm/vm.h> +/* 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_ */ |