Loading arch/mips/mm/c-r4k.c +28 −46 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include <linux/init.h> #include <linux/highmem.h> #include <linux/kernel.h> #include <linux/linkage.h> #include <linux/sched.h> Loading Loading @@ -318,23 +319,6 @@ static void __init r4k_blast_scache_setup(void) r4k_blast_scache = blast_scache128; } /* * This is former mm's flush_cache_all() which really should be * flush_cache_vunmap these days ... */ static inline void local_r4k_flush_cache_all(void * args) { r4k_blast_dcache(); } static void r4k_flush_cache_all(void) { if (!cpu_has_dc_aliases) return; r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1); } static inline void local_r4k___flush_cache_all(void * args) { #if defined(CONFIG_CPU_LOONGSON2) Loading Loading @@ -423,13 +407,14 @@ static inline void local_r4k_flush_cache_page(void *args) struct flush_cache_page_args *fcp_args = args; struct vm_area_struct *vma = fcp_args->vma; unsigned long addr = fcp_args->addr; unsigned long paddr = fcp_args->pfn << PAGE_SHIFT; struct page *page = pfn_to_page(fcp_args->pfn); int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; pte_t *ptep; void *vaddr; /* * If ownes no valid ASID yet, cannot possibly have gotten Loading @@ -451,43 +436,40 @@ static inline void local_r4k_flush_cache_page(void *args) if (!(pte_val(*ptep) & _PAGE_PRESENT)) return; if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) vaddr = NULL; else { /* * Doing flushes for another ASID than the current one is * too difficult since stupid R4k caches do a TLB translation * for every cache flush operation. So we do indexed flushes * in that case, which doesn't overly flush the cache too much. * Use kmap_coherent or kmap_atomic to do flushes for * another ASID than the current one. */ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { if (cpu_has_dc_aliases) vaddr = kmap_coherent(page, addr); else vaddr = kmap_atomic(page, KM_USER0); addr = (unsigned long)vaddr; } if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page(addr); if (exec && !cpu_icache_snoops_remote_store) r4k_blast_scache_page(addr); } if (exec) r4k_blast_icache_page(addr); return; } /* * Do indexed flush, too much work to get the (possible) TLB refills * to work correctly. */ if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ? paddr : addr); if (exec && !cpu_icache_snoops_remote_store) { r4k_blast_scache_page_indexed(paddr); } } if (exec) { if (cpu_has_vtag_icache && mm == current->active_mm) { if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { int cpu = smp_processor_id(); if (cpu_context(cpu, mm) != 0) drop_mmu_context(mm, cpu); } else r4k_blast_icache_page_indexed(addr); r4k_blast_icache_page(addr); } if (vaddr) { if (cpu_has_dc_aliases) kunmap_coherent(); else kunmap_atomic(vaddr, KM_USER0); } } Loading Loading @@ -1279,7 +1261,7 @@ void __init r4k_cache_init(void) PAGE_SIZE - 1); else shm_align_mask = PAGE_SIZE-1; flush_cache_all = r4k_flush_cache_all; flush_cache_all = cache_noop; __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; flush_cache_page = r4k_flush_cache_page; Loading Loading
arch/mips/mm/c-r4k.c +28 −46 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include <linux/init.h> #include <linux/highmem.h> #include <linux/kernel.h> #include <linux/linkage.h> #include <linux/sched.h> Loading Loading @@ -318,23 +319,6 @@ static void __init r4k_blast_scache_setup(void) r4k_blast_scache = blast_scache128; } /* * This is former mm's flush_cache_all() which really should be * flush_cache_vunmap these days ... */ static inline void local_r4k_flush_cache_all(void * args) { r4k_blast_dcache(); } static void r4k_flush_cache_all(void) { if (!cpu_has_dc_aliases) return; r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1); } static inline void local_r4k___flush_cache_all(void * args) { #if defined(CONFIG_CPU_LOONGSON2) Loading Loading @@ -423,13 +407,14 @@ static inline void local_r4k_flush_cache_page(void *args) struct flush_cache_page_args *fcp_args = args; struct vm_area_struct *vma = fcp_args->vma; unsigned long addr = fcp_args->addr; unsigned long paddr = fcp_args->pfn << PAGE_SHIFT; struct page *page = pfn_to_page(fcp_args->pfn); int exec = vma->vm_flags & VM_EXEC; struct mm_struct *mm = vma->vm_mm; pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; pte_t *ptep; void *vaddr; /* * If ownes no valid ASID yet, cannot possibly have gotten Loading @@ -451,43 +436,40 @@ static inline void local_r4k_flush_cache_page(void *args) if (!(pte_val(*ptep) & _PAGE_PRESENT)) return; if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) vaddr = NULL; else { /* * Doing flushes for another ASID than the current one is * too difficult since stupid R4k caches do a TLB translation * for every cache flush operation. So we do indexed flushes * in that case, which doesn't overly flush the cache too much. * Use kmap_coherent or kmap_atomic to do flushes for * another ASID than the current one. */ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { if (cpu_has_dc_aliases) vaddr = kmap_coherent(page, addr); else vaddr = kmap_atomic(page, KM_USER0); addr = (unsigned long)vaddr; } if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page(addr); if (exec && !cpu_icache_snoops_remote_store) r4k_blast_scache_page(addr); } if (exec) r4k_blast_icache_page(addr); return; } /* * Do indexed flush, too much work to get the (possible) TLB refills * to work correctly. */ if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { r4k_blast_dcache_page_indexed(cpu_has_pindexed_dcache ? paddr : addr); if (exec && !cpu_icache_snoops_remote_store) { r4k_blast_scache_page_indexed(paddr); } } if (exec) { if (cpu_has_vtag_icache && mm == current->active_mm) { if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { int cpu = smp_processor_id(); if (cpu_context(cpu, mm) != 0) drop_mmu_context(mm, cpu); } else r4k_blast_icache_page_indexed(addr); r4k_blast_icache_page(addr); } if (vaddr) { if (cpu_has_dc_aliases) kunmap_coherent(); else kunmap_atomic(vaddr, KM_USER0); } } Loading Loading @@ -1279,7 +1261,7 @@ void __init r4k_cache_init(void) PAGE_SIZE - 1); else shm_align_mask = PAGE_SIZE-1; flush_cache_all = r4k_flush_cache_all; flush_cache_all = cache_noop; __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; flush_cache_page = r4k_flush_cache_page; Loading