void flush_icache_pte(pte_t pte) { struct page *page = pte_page(pte); if (!test_and_set_bit(PG_dcache_clean, &page->flags)) flush_icache_all(); }
/* sys_cacheflush -- flush (part of) the processor cache. */ asmlinkage int sys_cacheflush (unsigned long addr, unsigned long len, int op) { struct vm_area_struct *vma; if ((op < 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I))) return -EINVAL; /* * Verify that the specified address region actually belongs * to this process. */ if (addr + len < addr) return -EFAULT; vma = find_vma (current->mm, addr); if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) return -EFAULT; switch (op & CACHEFLUSH_D_PURGE) { case CACHEFLUSH_D_INVAL: __flush_invalidate_region(addr, len); break; case CACHEFLUSH_D_WB: __flush_wback_region(addr, len); break; case CACHEFLUSH_D_PURGE: __flush_purge_region(addr, len); break; } if (op & CACHEFLUSH_I) { flush_icache_all(); } return 0; }
static inline void __flush_cache_range( unsigned long start, unsigned long end, unsigned long value) { unsigned long i,flags; if ((end - start) > 0x1000) { if (value | INS_CACHE) { flush_icache_all(); } if (value | DATA_CACHE) { flush_dcache_all(); } return; } flags = irqsave(); if (value & INS_CACHE) { dis_icache(); } for (i = start; i < end; i += L1_CACHE_BYTES) { set_cr22(i); set_cr17(CACHE_OMS | value); } if (end & (L1_CACHE_BYTES - 1)) { set_cr22(end); set_cr17(CACHE_OMS | value); } if (value & INS_CACHE) { en_icache(); } irqrestore(flags); }