summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/amd64/pmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/amd64/pmap.c')
-rw-r--r--sys/arch/amd64/amd64/pmap.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c
index d7dfac863d5..4f8f1999906 100644
--- a/sys/arch/amd64/amd64/pmap.c
+++ b/sys/arch/amd64/amd64/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.50 2009/08/06 15:28:14 oga Exp $ */
+/* $OpenBSD: pmap.c,v 1.51 2009/08/11 17:15:54 oga Exp $ */
/* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */
/*
@@ -447,7 +447,8 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
pte = kvtopte(va);
- npte = pa | ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) | PG_V;
+ npte = (pa & PMAP_PA_MASK) | ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) |
+ ((pa & PMAP_NOCACHE) ? PG_N : 0) | PG_V;
/* special 1:1 mappings in the first 2MB must not be global */
if (va >= (vaddr_t)NBPD_L2)
@@ -462,6 +463,8 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
panic("pmap_kenter_pa: PG_PS");
#endif
if (pmap_valid_entry(opte)) {
+ if (pa & PMAP_NOCACHE && (opte & PG_N) == 0)
+ wbinvd();
/* This shouldn't happen */
pmap_tlb_shootpage(pmap_kernel(), va);
pmap_tlb_shootwait();
@@ -1963,8 +1966,11 @@ pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
struct pv_entry *pve = NULL;
int ptpdelta, wireddelta, resdelta;
boolean_t wired = (flags & PMAP_WIRED) != 0;
+ boolean_t nocache = (pa & PMAP_NOCACHE) != 0;
int error;
+ pa &= PMAP_PA_MASK;
+
#ifdef DIAGNOSTIC
if (va == (vaddr_t) PDP_BASE || va == (vaddr_t) APDP_BASE)
panic("pmap_enter: trying to map over PDP/APDP!");
@@ -2127,7 +2133,7 @@ enter_now:
npte |= PG_PVLIST;
if (wired)
npte |= PG_W;
- if (flags & PMAP_NOCACHE)
+ if (nocache)
npte |= PG_N;
if (va < VM_MAXUSER_ADDRESS)
npte |= PG_u;
@@ -2143,6 +2149,8 @@ enter_now:
* flush the TLB. (is this overkill?)
*/
if (opte & PG_V) {
+ if (nocache && (opte & PG_N) == 0)
+ wbinvd();
pmap_tlb_shootpage(pmap, va);
pmap_tlb_shootwait();
}