ARMv7 data caches are "effectively" PIPT. This means there is in general
authorkettenis <kettenis@openbsd.org>
Mon, 8 Aug 2016 09:06:47 +0000 (09:06 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 8 Aug 2016 09:06:47 +0000 (09:06 +0000)
no need to clean and/or invalidate cached pages.  So remove most of the
cache cleaning and invalidation from the pmap.  We still need to synchronize
the instruction cache with the data cache in various places though.  And we
also need to make sure that we clean and invalidate when we make a page
non-cachable.

Tested by Daniel Bolgheroni, mglocker@ and jsg@. on Cortex-A8 and myself on
Cortex-A9.

ok visa@

sys/arch/arm/arm/pmap7.c

index fa0b232..e0631ef 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pmap7.c,v 1.33 2016/08/06 16:46:25 kettenis Exp $     */
+/*     $OpenBSD: pmap7.c,v 1.34 2016/08/08 09:06:47 kettenis Exp $     */
 /*     $NetBSD: pmap.c,v 1.147 2004/01/18 13:03:50 scw Exp $   */
 
 /*
@@ -917,9 +917,6 @@ pmap_l2ptp_ctor(void *v)
        ptep = &l2b->l2b_kva[l2pte_index(va)];
        pte = *ptep;
 
-       /* XXX redundant with PTE_SYNC_RANGE() ? */
-       cpu_idcache_wbinv_range(va, PAGE_SIZE);
-       cpu_sdcache_wbinv_range(va, pte & L2_S_FRAME, PAGE_SIZE);
        if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
                *ptep = (pte & ~L2_S_CACHE_MASK) | pte_l2_s_cache_mode_pt;
                PTE_SYNC(ptep);
@@ -952,6 +949,9 @@ pmap_uncache_page(paddr_t va, vaddr_t pa)
        PTE_SYNC(pte);
        cpu_tlb_flushD_SE(va);
        cpu_cpwait();
+
+       cpu_dcache_wbinv_range(va, PAGE_SIZE);
+       cpu_sdcache_wbinv_range(va, pa, PAGE_SIZE);
 }
 
 /*
@@ -1054,7 +1054,6 @@ pmap_clean_page(struct vm_page *pg, int isync)
 {
        pmap_t pm;
        struct pv_entry *pv;
-       boolean_t wb = FALSE;
 
        /*
         * To save time, we are only walking the pv list if an I$ invalidation
@@ -1080,34 +1079,8 @@ pmap_clean_page(struct vm_page *pg, int isync)
 
                        if (PV_BEEN_EXECD(pv->pv_flags))
                                cpu_icache_sync_range(pv->pv_va, PAGE_SIZE);
-
-                       /*
-                        * If we have not written back that page yet, do this
-                        * now while we still have a valid mapping for it.
-                        */
-                       if (!wb) {
-                               cpu_dcache_wb_range(pv->pv_va, PAGE_SIZE);
-                               cpu_sdcache_wb_range(pv->pv_va,
-                                   VM_PAGE_TO_PHYS(pg), PAGE_SIZE);
-                               wb = TRUE;
-                       }
                }
        }
-
-       /*
-        * If there is no active mapping left, or we did not bother checking
-        * for one, this does not mean the page doesn't have stale data. Map
-        * it in a working page and writeback.
-        */
-       if (!wb) {
-               *cwb_pte = L2_S_PROTO | VM_PAGE_TO_PHYS(pg) |
-                   L2_S_PROT(PTE_KERNEL, PROT_WRITE) | pte_l2_s_cache_mode;
-               PTE_SYNC(cwb_pte);
-               cpu_tlb_flushD_SE(cwbp);
-               cpu_cpwait();
-               cpu_dcache_wb_range(cwbp, PAGE_SIZE);
-               cpu_sdcache_wb_range(cwbp, VM_PAGE_TO_PHYS(pg), PAGE_SIZE);
-       }
 }
 
 /*
@@ -1152,15 +1125,6 @@ pmap_page_remove(struct vm_page *pg)
                            (pm == curpm || pm == pmap_kernel())) {
                                if (PV_BEEN_EXECD(pv->pv_flags))
                                        cpu_icache_sync_range(pv->pv_va, PAGE_SIZE);
-                               if (flush == FALSE) {
-                                       paddr_t pa;
-                                       cpu_dcache_wb_range(pv->pv_va,
-                                           PAGE_SIZE);
-                                       if (pmap_extract(pm, (vaddr_t)pv->pv_va,
-                                           &pa))
-                                               cpu_sdcache_wb_range(pv->pv_va,
-                                                   pa, PAGE_SIZE);
-                               }
                                flush = TRUE;
                        }
 
@@ -1338,18 +1302,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
                        oflags = pmap_modify_pv(pg, pm, va,
                            PVF_WRITE | PVF_EXEC | PVF_WIRED |
                            PVF_MOD | PVF_REF, nflags);
-
-                       /*
-                        * We may need to flush the cache if we're
-                        * doing rw-ro...
-                        */
-                       if ((oflags & PVF_NC) == 0 &&
-                           l2pte_is_writeable(opte, pm) &&
-                           (prot & PROT_WRITE) == 0) {
-                               cpu_dcache_wb_range(va, PAGE_SIZE);
-                               cpu_sdcache_wb_range(va, opte & L2_S_FRAME,
-                                   PAGE_SIZE);
-                       }
                } else {
                        /*
                         * New mapping, or changing the backing page
@@ -1573,10 +1525,6 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
        ptep = &l2b->l2b_kva[l2pte_index(va)];
        opte = *ptep;
 
-       if (l2pte_valid(opte)) {
-               cpu_dcache_wb_range(va, PAGE_SIZE);
-               cpu_sdcache_wb_range(va, opte & L2_S_FRAME, PAGE_SIZE);
-       } else
        if (opte == 0)
                l2b->l2b_occupancy++;
 
@@ -1624,11 +1572,6 @@ pmap_kremove(vaddr_t va, vsize_t len)
 
                while (va < next_bucket) {
                        opte = *ptep;
-                       if (l2pte_valid(opte)) {
-                               cpu_dcache_wb_range(va, PAGE_SIZE);
-                               cpu_sdcache_wb_range(va, opte & L2_S_FRAME,
-                                   PAGE_SIZE);
-                       }
                        if (opte != 0) {        /* !! not l2pte_valid */
                                *ptep = L2_TYPE_INV;
                                PTE_SYNC(ptep);
@@ -2554,11 +2497,8 @@ pmap_init_l1(struct l1_ttable *l1, pd_entry_t *l1pt)
        /*
         * Copy the kernel's L1 entries to each new L1.
         */
-       if (pmap_initialized) {
+       if (pmap_initialized)
                memcpy(l1pt, pmap_kernel()->pm_l1->l1_kva, L1_TABLE_SIZE);
-/* XXX overkill? */
-               cpu_dcache_wb_range((vaddr_t)l1pt, L1_TABLE_SIZE);
-       }
 
        if (pmap_extract(pmap_kernel(), (vaddr_t)l1pt,
            &l1->l1_physaddr) == FALSE)