110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao/* 210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * linux/arch/unicore32/include/asm/tlbflush.h 310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Code specific to PKUnity SoC and UniCore ISA 510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Copyright (C) 2001-2010 GUAN Xue-tao 710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * This program is free software; you can redistribute it and/or modify 910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * it under the terms of the GNU General Public License version 2 as 1010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * published by the Free Software Foundation. 1110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao */ 1210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#ifndef __UNICORE_TLBFLUSH_H__ 1310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define __UNICORE_TLBFLUSH_H__ 1410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 1510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#ifndef __ASSEMBLY__ 1610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 1710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#include <linux/sched.h> 1810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 1910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaoextern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, 2010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao struct vm_area_struct *); 2110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaoextern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); 2210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 2310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao/* 2410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * TLB Management 2510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * ============== 2610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 2710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * The arch/unicore/mm/tlb-*.S files implement these methods. 2810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 2910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * The TLB specific code is expected to perform whatever tests it 3010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * needs to determine if it should invalidate the TLB for each 3110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * call. Start addresses are inclusive and end addresses are 3210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * exclusive; it is safe to round these addresses down. 3310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 3410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * flush_tlb_all() 3510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 3610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Invalidate the entire TLB. 3710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 3810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * flush_tlb_mm(mm) 3910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 4010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Invalidate all TLB entries in a particular address 4110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * space. 4210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - mm - mm_struct describing address space 4310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 4410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * flush_tlb_range(mm,start,end) 4510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 4610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Invalidate a range of TLB entries in the specified 4710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * address space. 4810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - mm - mm_struct describing address space 4910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - start - start address (may not be aligned) 5010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - end - end address (exclusive, may not be aligned) 5110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 5210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * flush_tlb_page(vaddr,vma) 5310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 5410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Invalidate the specified page in the specified address range. 5510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - vaddr - virtual address (may not be aligned) 5610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - vma - vma_struct describing address range 5710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 5810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * flush_kern_tlb_page(kaddr) 5910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 6010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Invalidate the TLB entry for the specified page. The address 6110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * will be in the kernels virtual memory space. Current uses 6210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * only require the D-TLB to be invalidated. 6310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * - kaddr - Kernel virtual memory address 6410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao */ 6510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 6610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaostatic inline void local_flush_tlb_all(void) 6710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao{ 6810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao const int zero = 0; 6910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 7010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* TLB invalidate all */ 7110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop" 7210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (zero) : "cc"); 7310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao} 7410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 7510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaostatic inline void local_flush_tlb_mm(struct mm_struct *mm) 7610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao{ 7710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao const int zero = 0; 7810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 7910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { 8010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* TLB invalidate all */ 8110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop" 8210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (zero) : "cc"); 8310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao } 8410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao put_cpu(); 8510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao} 8610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 8710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaostatic inline void 8810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaolocal_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 8910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao{ 9010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { 9110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE 9210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* iTLB invalidate page */ 9310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop" 9410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (uaddr & PAGE_MASK) : "cc"); 9510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* dTLB invalidate page */ 9610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop" 9710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (uaddr & PAGE_MASK) : "cc"); 9810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#else 9910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* TLB invalidate all */ 10010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop" 10110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (uaddr & PAGE_MASK) : "cc"); 10210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#endif 10310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao } 10410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao} 10510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 10610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaostatic inline void local_flush_tlb_kernel_page(unsigned long kaddr) 10710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao{ 10810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#ifndef CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE 10910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* iTLB invalidate page */ 11010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #5; nop; nop; nop; nop; nop; nop; nop; nop" 11110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (kaddr & PAGE_MASK) : "cc"); 11210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* dTLB invalidate page */ 11310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #3; nop; nop; nop; nop; nop; nop; nop; nop" 11410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (kaddr & PAGE_MASK) : "cc"); 11510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#else 11610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* TLB invalidate all */ 11710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c6, %0, #6; nop; nop; nop; nop; nop; nop; nop; nop" 11810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (kaddr & PAGE_MASK) : "cc"); 11910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#endif 12010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao} 12110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 12210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao/* 12310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * flush_pmd_entry 12410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 12510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Flush a PMD entry (word aligned, or double-word aligned) to 12610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * RAM if the TLB for the CPU we are running on requires this. 12710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * This is typically used when we are creating PMD entries. 12810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 12910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * clean_pmd_entry 13010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * 13110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Clean (but don't drain the write buffer) if the CPU requires 13210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * these operations. This is typically used when we are removing 13310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * PMD entries. 13410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao */ 13510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaostatic inline void flush_pmd_entry(pmd_t *pmd) 13610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao{ 13710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE 13810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* flush dcache line, see dcacheline_flush in proc-macros.S */ 13910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("mov r1, %0 << #20\n" 14010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao "ldw r2, =_stext\n" 14110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao "add r2, r2, r1 >> #20\n" 14210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao "ldw r1, [r2+], #0x0000\n" 14310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao "ldw r1, [r2+], #0x1000\n" 14410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao "ldw r1, [r2+], #0x2000\n" 14510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao "ldw r1, [r2+], #0x3000\n" 14610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (pmd) : "r1", "r2"); 14710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#else 14810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* flush dcache all */ 14910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c5, %0, #14; nop; nop; nop; nop; nop; nop; nop; nop" 15010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (pmd) : "cc"); 15110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#endif 15210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao} 15310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 15410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaostatic inline void clean_pmd_entry(pmd_t *pmd) 15510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao{ 15610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE 15710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* clean dcache line */ 15810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c5, %0, #11; nop; nop; nop; nop; nop; nop; nop; nop" 15910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (__pa(pmd) & ~(L1_CACHE_BYTES - 1)) : "cc"); 16010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#else 16110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao /* clean dcache all */ 16210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao asm("movc p0.c5, %0, #10; nop; nop; nop; nop; nop; nop; nop; nop" 16310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao : : "r" (pmd) : "cc"); 16410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#endif 16510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao} 16610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 16710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao/* 16810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * Convert calls to our calling convention. 16910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao */ 17010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define local_flush_tlb_range(vma, start, end) \ 17110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao __cpu_flush_user_tlb_range(start, end, vma) 17210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define local_flush_tlb_kernel_range(s, e) \ 17310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao __cpu_flush_kern_tlb_range(s, e) 17410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 17510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define flush_tlb_all local_flush_tlb_all 17610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define flush_tlb_mm local_flush_tlb_mm 17710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define flush_tlb_page local_flush_tlb_page 17810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define flush_tlb_kernel_page local_flush_tlb_kernel_page 17910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define flush_tlb_range local_flush_tlb_range 18010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#define flush_tlb_kernel_range local_flush_tlb_kernel_range 18110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 18210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao/* 18310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * if PG_dcache_clean is not set for the page, we need to ensure that any 18410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * cache entries for the kernels virtual memory range are written 18510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao * back to the page. 18610c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao */ 18710c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaoextern void update_mmu_cache(struct vm_area_struct *vma, 18810c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao unsigned long addr, pte_t *ptep); 18910c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 19010c9c10c31514564b09c153432a42ffaea3ce831GuanXuetaoextern void do_bad_area(unsigned long addr, unsigned int fsr, 19110c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao struct pt_regs *regs); 19210c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 19310c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#endif 19410c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao 19510c9c10c31514564b09c153432a42ffaea3ce831GuanXuetao#endif 196