From 003c50d1d55b1792705ac44b048c0fd72c7a9b3c Mon Sep 17 00:00:00 2001 From: thorpej Date: Wed, 18 Mar 1998 23:55:25 +0000 Subject: [PATCH] Add a macro to invalidate the TLB for a given pmap/va pair. TLB invalidation algorithm: if (old mapping had PG_ASM set || pmap is active) { TIBS(va); if (also sync I-stream) imb(); } The check for "old mapping had PG_ASM" will get all kernel mappings (since kernel mappings always have PG_ASM set). This allows us to remove the bogus check for the kernel pmap in active_pmap() - do so. Use the new TLB invalidation macro whenever such action is needed. --- sys/arch/alpha/alpha/pmap.old.c | 70 ++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/sys/arch/alpha/alpha/pmap.old.c b/sys/arch/alpha/alpha/pmap.old.c index abb6f43696b7..15a649c19574 100644 --- a/sys/arch/alpha/alpha/pmap.old.c +++ b/sys/arch/alpha/alpha/pmap.old.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.old.c,v 1.63 1998/03/18 23:11:44 thorpej Exp $ */ +/* $NetBSD: pmap.old.c,v 1.64 1998/03/18 23:55:25 thorpej Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -155,7 +155,7 @@ #include /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: pmap.old.c,v 1.63 1998/03/18 23:11:44 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.old.c,v 1.64 1998/03/18 23:55:25 thorpej Exp $"); #include #include @@ -375,8 +375,7 @@ void pmap_pvdump __P((vm_offset_t)); * Check to see if a pmap is active on the current processor. */ #define active_pmap(pm) \ - ((pm) == pmap_kernel() || /* XXX */ \ - ((pm)->pm_cpus & (1UL << alpha_pal_whami())) != 0) + (((pm)->pm_cpus & (1UL << alpha_pal_whami())) != 0) /* * PMAP_ACTIVATE: @@ -403,6 +402,24 @@ do { \ } \ } while (0) +/* + * PMAP_INVALIDATE_TLB: + * + * Invalidate the TLB entry for the pmap/va pair. + */ +#define PMAP_INVALIDATE_TLB(pmap, va, hadasm, isactive, doimb) \ +do { \ + if ((hadasm) || (isactive)) { \ + /* \ + * Simply invalidating the TLB entry and I-stream \ + * works in this case. \ + */ \ + ALPHA_TBIS((va)); \ + if ((doimb)) \ + alpha_pal_imb(); \ + } \ +} while (0) + /* * pmap_bootstrap: * @@ -1056,7 +1073,8 @@ pmap_protect(pmap, sva, eva, prot) vm_prot_t prot; { register pt_entry_t *pte, bits; - boolean_t needtflush; + boolean_t isactive; + boolean_t hadasm; #ifdef DEBUG if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) @@ -1080,7 +1098,7 @@ pmap_protect(pmap, sva, eva, prot) return; bits = pte_prot(pmap, prot); - needtflush = active_pmap(pmap); + isactive = active_pmap(pmap); while (sva < eva) { /* @@ -1105,12 +1123,10 @@ pmap_protect(pmap, sva, eva, prot) */ pte = pmap_l3pte(pmap, sva); if (pmap_pte_v(pte) && pmap_pte_prot_chg(pte, bits)) { + hadasm = (pmap_pte_asm(pte) != 0); pmap_pte_set_prot(pte, bits); - if (needtflush) { - ALPHA_TBIS(sva); - if (prot & VM_PROT_EXECUTE) - alpha_pal_imb(); - } + PMAP_INVALIDATE_TLB(pmap, sva, hadasm, isactive, + (prot & VM_PROT_EXECUTE) != 0); #ifdef PMAPSTATS protect_stats.changed++; #endif @@ -1152,6 +1168,7 @@ pmap_enter(pmap, va, pa, prot, wired) pt_entry_t *pte, npte; vm_offset_t opa; boolean_t tflush = TRUE; + boolean_t hadasm = FALSE; /* XXX gcc -Wuninitialized */ #ifdef DEBUG if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) @@ -1271,6 +1288,8 @@ pmap_enter(pmap, va, pa, prot, wired) } opa = pmap_pte_pa(pte); + hadasm = (pmap_pte_asm(pte) != 0); + if (opa == pa) { /* * Mapping has not changed; must be a protection or @@ -1394,14 +1413,11 @@ pmap_enter(pmap, va, pa, prot, wired) /* * Invalidate the TLB entry for this VA and any appropriate - * caches. Note that this is not necessary for wiring-only - * changes. + * caches. */ - if (tflush && active_pmap(pmap)) { - ALPHA_TBIS(va); - if (prot & VM_PROT_EXECUTE) - alpha_pal_imb(); - } + if (tflush) + PMAP_INVALIDATE_TLB(pmap, va, hadasm, active_pmap(pmap), + (prot & VM_PROT_EXECUTE) != 0); } #if defined(PMAP_NEW) @@ -1463,9 +1479,8 @@ pmap_kenter_pa(va, pa, prot) * Invalidate the TLB entry for this VA and any appropriate * caches. */ - ALPHA_TBIS(va); - if (prot & VM_PROT_EXECUTE) - alpha_pal_imb(); + PMAP_INVALIDATE_TLB(pmap_kernel(), va, TRUE, TRUE, + (prot & VM_PROT_EXECUTE) != 0); } /* @@ -2101,6 +2116,7 @@ pmap_remove_mapping(pmap, va, pte) vm_offset_t pa; int s; boolean_t onpv; + boolean_t hadasm; #ifdef DEBUG if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) @@ -2119,6 +2135,7 @@ pmap_remove_mapping(pmap, va, pte) pa = pmap_pte_pa(pte); onpv = (pmap_pte_pv(pte) != 0); + hadasm = (pmap_pte_asm(pte) != 0); #ifdef PMAPSTATS remove_stats.removes++; @@ -2139,10 +2156,7 @@ pmap_remove_mapping(pmap, va, pte) #endif *pte = PG_NV; - if (active_pmap(pmap)) { - ALPHA_TBIS(va); - alpha_pal_imb(); - } + PMAP_INVALIDATE_TLB(pmap, va, hadasm, active_pmap(pmap), TRUE); /* * If we're removing a user mapping, check to see if we @@ -2244,6 +2258,7 @@ pmap_changebit(pa, bit, setem) pv_entry_t pv; pt_entry_t *pte, npte; vm_offset_t va; + boolean_t hadasm; int s; #ifdef PMAPSTATS struct chgstats *chgp; @@ -2294,9 +2309,10 @@ pmap_changebit(pa, bit, setem) else npte = *pte & ~bit; if (*pte != npte) { + hadasm = (pmap_pte_asm(pte) != 0); *pte = npte; - if (active_pmap(pv->pv_pmap)) - ALPHA_TBIS(va); + PMAP_INVALIDATE_TLB(pv->pv_pmap, va, hadasm, + active_pmap(pv->pv_pmap), TRUE); #ifdef PMAPSTATS if (setem) chgp->sethits++;