1367b8112SChris Zankel /* 2367b8112SChris Zankel * include/asm-xtensa/tlbflush.h 3367b8112SChris Zankel * 4367b8112SChris Zankel * This file is subject to the terms and conditions of the GNU General Public 5367b8112SChris Zankel * License. See the file "COPYING" in the main directory of this archive 6367b8112SChris Zankel * for more details. 7367b8112SChris Zankel * 8367b8112SChris Zankel * Copyright (C) 2001 - 2005 Tensilica Inc. 9367b8112SChris Zankel */ 10367b8112SChris Zankel 11367b8112SChris Zankel #ifndef _XTENSA_TLBFLUSH_H 12367b8112SChris Zankel #define _XTENSA_TLBFLUSH_H 13367b8112SChris Zankel 14367b8112SChris Zankel #ifdef __KERNEL__ 15367b8112SChris Zankel 16367b8112SChris Zankel #include <linux/stringify.h> 17367b8112SChris Zankel #include <asm/processor.h> 18367b8112SChris Zankel 19367b8112SChris Zankel #define DTLB_WAY_PGD 7 20367b8112SChris Zankel 21367b8112SChris Zankel #define ITLB_ARF_WAYS 4 22367b8112SChris Zankel #define DTLB_ARF_WAYS 4 23367b8112SChris Zankel 24367b8112SChris Zankel #define ITLB_HIT_BIT 3 25367b8112SChris Zankel #define DTLB_HIT_BIT 4 26367b8112SChris Zankel 27367b8112SChris Zankel #ifndef __ASSEMBLY__ 28367b8112SChris Zankel 29367b8112SChris Zankel /* TLB flushing: 30367b8112SChris Zankel * 31367b8112SChris Zankel * - flush_tlb_all() flushes all processes TLB entries 32367b8112SChris Zankel * - flush_tlb_mm(mm) flushes the specified mm context TLB entries 33367b8112SChris Zankel * - flush_tlb_page(mm, vmaddr) flushes a single page 34367b8112SChris Zankel * - flush_tlb_range(mm, start, end) flushes a range of pages 35367b8112SChris Zankel */ 36367b8112SChris Zankel 37367b8112SChris Zankel extern void flush_tlb_all(void); 38367b8112SChris Zankel extern void flush_tlb_mm(struct mm_struct*); 39367b8112SChris Zankel extern void flush_tlb_page(struct vm_area_struct*,unsigned long); 40367b8112SChris Zankel extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long); 41367b8112SChris Zankel 42367b8112SChris Zankel #define flush_tlb_kernel_range(start,end) flush_tlb_all() 43367b8112SChris Zankel 44367b8112SChris Zankel /* TLB operations. */ 45367b8112SChris Zankel 46367b8112SChris Zankel static inline unsigned long itlb_probe(unsigned long addr) 47367b8112SChris Zankel { 48367b8112SChris Zankel unsigned long tmp; 49367b8112SChris Zankel __asm__ __volatile__("pitlb %0, %1\n\t" : "=a" (tmp) : "a" (addr)); 50367b8112SChris Zankel return tmp; 51367b8112SChris Zankel } 52367b8112SChris Zankel 53367b8112SChris Zankel static inline unsigned long dtlb_probe(unsigned long addr) 54367b8112SChris Zankel { 55367b8112SChris Zankel unsigned long tmp; 56367b8112SChris Zankel __asm__ __volatile__("pdtlb %0, %1\n\t" : "=a" (tmp) : "a" (addr)); 57367b8112SChris Zankel return tmp; 58367b8112SChris Zankel } 59367b8112SChris Zankel 60367b8112SChris Zankel static inline void invalidate_itlb_entry (unsigned long probe) 61367b8112SChris Zankel { 62367b8112SChris Zankel __asm__ __volatile__("iitlb %0; isync\n\t" : : "a" (probe)); 63367b8112SChris Zankel } 64367b8112SChris Zankel 65367b8112SChris Zankel static inline void invalidate_dtlb_entry (unsigned long probe) 66367b8112SChris Zankel { 67367b8112SChris Zankel __asm__ __volatile__("idtlb %0; dsync\n\t" : : "a" (probe)); 68367b8112SChris Zankel } 69367b8112SChris Zankel 70367b8112SChris Zankel /* Use the .._no_isync functions with caution. Generally, these are 71367b8112SChris Zankel * handy for bulk invalidates followed by a single 'isync'. The 72367b8112SChris Zankel * caller must follow up with an 'isync', which can be relatively 73367b8112SChris Zankel * expensive on some Xtensa implementations. 74367b8112SChris Zankel */ 75367b8112SChris Zankel static inline void invalidate_itlb_entry_no_isync (unsigned entry) 76367b8112SChris Zankel { 77367b8112SChris Zankel /* Caller must follow up with 'isync'. */ 78367b8112SChris Zankel __asm__ __volatile__ ("iitlb %0\n" : : "a" (entry) ); 79367b8112SChris Zankel } 80367b8112SChris Zankel 81367b8112SChris Zankel static inline void invalidate_dtlb_entry_no_isync (unsigned entry) 82367b8112SChris Zankel { 83367b8112SChris Zankel /* Caller must follow up with 'isync'. */ 84367b8112SChris Zankel __asm__ __volatile__ ("idtlb %0\n" : : "a" (entry) ); 85367b8112SChris Zankel } 86367b8112SChris Zankel 87367b8112SChris Zankel static inline void set_itlbcfg_register (unsigned long val) 88367b8112SChris Zankel { 89*bc5378fcSMax Filippov __asm__ __volatile__("wsr %0, itlbcfg\n\t" "isync\n\t" 90367b8112SChris Zankel : : "a" (val)); 91367b8112SChris Zankel } 92367b8112SChris Zankel 93367b8112SChris Zankel static inline void set_dtlbcfg_register (unsigned long val) 94367b8112SChris Zankel { 95*bc5378fcSMax Filippov __asm__ __volatile__("wsr %0, dtlbcfg; dsync\n\t" 96367b8112SChris Zankel : : "a" (val)); 97367b8112SChris Zankel } 98367b8112SChris Zankel 99367b8112SChris Zankel static inline void set_ptevaddr_register (unsigned long val) 100367b8112SChris Zankel { 101*bc5378fcSMax Filippov __asm__ __volatile__(" wsr %0, ptevaddr; isync\n" 102367b8112SChris Zankel : : "a" (val)); 103367b8112SChris Zankel } 104367b8112SChris Zankel 105367b8112SChris Zankel static inline unsigned long read_ptevaddr_register (void) 106367b8112SChris Zankel { 107367b8112SChris Zankel unsigned long tmp; 108*bc5378fcSMax Filippov __asm__ __volatile__("rsr %0, ptevaddr\n\t" : "=a" (tmp)); 109367b8112SChris Zankel return tmp; 110367b8112SChris Zankel } 111367b8112SChris Zankel 112367b8112SChris Zankel static inline void write_dtlb_entry (pte_t entry, int way) 113367b8112SChris Zankel { 114367b8112SChris Zankel __asm__ __volatile__("wdtlb %1, %0; dsync\n\t" 115367b8112SChris Zankel : : "r" (way), "r" (entry) ); 116367b8112SChris Zankel } 117367b8112SChris Zankel 118367b8112SChris Zankel static inline void write_itlb_entry (pte_t entry, int way) 119367b8112SChris Zankel { 120367b8112SChris Zankel __asm__ __volatile__("witlb %1, %0; isync\n\t" 121367b8112SChris Zankel : : "r" (way), "r" (entry) ); 122367b8112SChris Zankel } 123367b8112SChris Zankel 124367b8112SChris Zankel static inline void invalidate_page_directory (void) 125367b8112SChris Zankel { 126367b8112SChris Zankel invalidate_dtlb_entry (DTLB_WAY_PGD); 127367b8112SChris Zankel invalidate_dtlb_entry (DTLB_WAY_PGD+1); 128367b8112SChris Zankel invalidate_dtlb_entry (DTLB_WAY_PGD+2); 129367b8112SChris Zankel } 130367b8112SChris Zankel 131367b8112SChris Zankel static inline void invalidate_itlb_mapping (unsigned address) 132367b8112SChris Zankel { 133367b8112SChris Zankel unsigned long tlb_entry; 134367b8112SChris Zankel if (((tlb_entry = itlb_probe(address)) & (1 << ITLB_HIT_BIT)) != 0) 135367b8112SChris Zankel invalidate_itlb_entry(tlb_entry); 136367b8112SChris Zankel } 137367b8112SChris Zankel 138367b8112SChris Zankel static inline void invalidate_dtlb_mapping (unsigned address) 139367b8112SChris Zankel { 140367b8112SChris Zankel unsigned long tlb_entry; 141367b8112SChris Zankel if (((tlb_entry = dtlb_probe(address)) & (1 << DTLB_HIT_BIT)) != 0) 142367b8112SChris Zankel invalidate_dtlb_entry(tlb_entry); 143367b8112SChris Zankel } 144367b8112SChris Zankel 145367b8112SChris Zankel #define check_pgt_cache() do { } while (0) 146367b8112SChris Zankel 147367b8112SChris Zankel 148367b8112SChris Zankel /* 149367b8112SChris Zankel * DO NOT USE THESE FUNCTIONS. These instructions aren't part of the Xtensa 150367b8112SChris Zankel * ISA and exist only for test purposes.. 151367b8112SChris Zankel * You may find it helpful for MMU debugging, however. 152367b8112SChris Zankel * 153367b8112SChris Zankel * 'at' is the unmodified input register 154367b8112SChris Zankel * 'as' is the output register, as follows (specific to the Linux config): 155367b8112SChris Zankel * 156367b8112SChris Zankel * as[31..12] contain the virtual address 157367b8112SChris Zankel * as[11..08] are meaningless 158367b8112SChris Zankel * as[07..00] contain the asid 159367b8112SChris Zankel */ 160367b8112SChris Zankel 161367b8112SChris Zankel static inline unsigned long read_dtlb_virtual (int way) 162367b8112SChris Zankel { 163367b8112SChris Zankel unsigned long tmp; 164367b8112SChris Zankel __asm__ __volatile__("rdtlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way)); 165367b8112SChris Zankel return tmp; 166367b8112SChris Zankel } 167367b8112SChris Zankel 168367b8112SChris Zankel static inline unsigned long read_dtlb_translation (int way) 169367b8112SChris Zankel { 170367b8112SChris Zankel unsigned long tmp; 171367b8112SChris Zankel __asm__ __volatile__("rdtlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way)); 172367b8112SChris Zankel return tmp; 173367b8112SChris Zankel } 174367b8112SChris Zankel 175367b8112SChris Zankel static inline unsigned long read_itlb_virtual (int way) 176367b8112SChris Zankel { 177367b8112SChris Zankel unsigned long tmp; 178367b8112SChris Zankel __asm__ __volatile__("ritlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way)); 179367b8112SChris Zankel return tmp; 180367b8112SChris Zankel } 181367b8112SChris Zankel 182367b8112SChris Zankel static inline unsigned long read_itlb_translation (int way) 183367b8112SChris Zankel { 184367b8112SChris Zankel unsigned long tmp; 185367b8112SChris Zankel __asm__ __volatile__("ritlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way)); 186367b8112SChris Zankel return tmp; 187367b8112SChris Zankel } 188367b8112SChris Zankel 189367b8112SChris Zankel #endif /* __ASSEMBLY__ */ 190367b8112SChris Zankel #endif /* __KERNEL__ */ 191367b8112SChris Zankel #endif /* _XTENSA_TLBFLUSH_H */ 192