aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/pmap.c32
-rw-r--r--sys/include/vm/pmap.h10
2 files changed, 42 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c
index e95471b..9443727 100644
--- a/sys/arch/amd64/amd64/pmap.c
+++ b/sys/arch/amd64/amd64/pmap.c
@@ -255,6 +255,38 @@ pmap_modify_tbl(struct vm_ctx *ctx, struct vas vas, vaddr_t va, size_t val)
}
int
+pmap_set_cache(struct vm_ctx *ctx, struct vas vas, vaddr_t va, int type)
+{
+ uintptr_t *tbl;
+ int status;
+ size_t idx;
+
+ if ((status = pmap_get_tbl(ctx, vas, va, false, &tbl)) != 0) {
+ return status;
+ }
+
+ idx = pmap_get_level_index(1, va);
+
+ /* Set the policy based on the type */
+ switch (type) {
+ case VM_CACHE_UC:
+ tbl[idx] |= PTE_PCD;
+ tbl[idx] &= ~(PTE_PWT);
+ break;
+ case VM_CACHE_WT:
+ tbl[idx] &= ~(PTE_PCD);
+ tbl[idx] |= PTE_PWT;
+ break;
+ default:
+ /* Invalid type */
+ return 1;
+ }
+
+ pmap_flush(va);
+ return 0;
+}
+
+int
pmap_map(struct vm_ctx *ctx, struct vas vas, vaddr_t va, paddr_t pa,
vm_prot_t prot)
{
diff --git a/sys/include/vm/pmap.h b/sys/include/vm/pmap.h
index 8c69372..cb18885 100644
--- a/sys/include/vm/pmap.h
+++ b/sys/include/vm/pmap.h
@@ -54,6 +54,10 @@
#define PROT_EXEC __BIT(1) /* Executable */
#define PROT_USER __BIT(2) /* User accessible */
+/* Caching types */
+#define VM_CACHE_UC 0x00000U /* Uncachable */
+#define VM_CACHE_WT 0x00001U /* Write-through */
+
#define is_vas_valid(vas) (vas.top_level != 0)
/*
@@ -67,6 +71,12 @@ struct vm_ctx {
};
/*
+ * Mark a virtual address with a specific caching
+ * type.
+ */
+int pmap_set_cache(struct vm_ctx *, struct vas, vaddr_t, int);
+
+/*
* Create a virtual address space
* and return the descriptor.
*/