^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2001 - 2013 Tensilica Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #ifndef _XTENSA_TLBFLUSH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define _XTENSA_TLBFLUSH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/stringify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define DTLB_WAY_PGD 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define ITLB_ARF_WAYS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define DTLB_ARF_WAYS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define ITLB_HIT_BIT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DTLB_HIT_BIT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #ifndef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* TLB flushing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * - flush_tlb_all() flushes all processes TLB entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * - flush_tlb_mm(mm) flushes the specified mm context TLB entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * - flush_tlb_page(mm, vmaddr) flushes a single page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * - flush_tlb_range(mm, start, end) flushes a range of pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) void local_flush_tlb_all(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) void local_flush_tlb_mm(struct mm_struct *mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) void local_flush_tlb_page(struct vm_area_struct *vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) void local_flush_tlb_range(struct vm_area_struct *vma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) unsigned long start, unsigned long end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) void local_flush_tlb_kernel_range(unsigned long start, unsigned long end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void flush_tlb_all(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void flush_tlb_mm(struct mm_struct *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void flush_tlb_page(struct vm_area_struct *, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void flush_tlb_range(struct vm_area_struct *, unsigned long,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void flush_tlb_kernel_range(unsigned long start, unsigned long end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #else /* !CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define flush_tlb_all() local_flush_tlb_all()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define flush_tlb_kernel_range(start, end) local_flush_tlb_kernel_range(start, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif /* CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* TLB operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static inline unsigned long itlb_probe(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __asm__ __volatile__("pitlb %0, %1\n\t" : "=a" (tmp) : "a" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static inline unsigned long dtlb_probe(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __asm__ __volatile__("pdtlb %0, %1\n\t" : "=a" (tmp) : "a" (addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static inline void invalidate_itlb_entry (unsigned long probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __asm__ __volatile__("iitlb %0; isync\n\t" : : "a" (probe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static inline void invalidate_dtlb_entry (unsigned long probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __asm__ __volatile__("idtlb %0; dsync\n\t" : : "a" (probe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Use the .._no_isync functions with caution. Generally, these are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * handy for bulk invalidates followed by a single 'isync'. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * caller must follow up with an 'isync', which can be relatively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * expensive on some Xtensa implementations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static inline void invalidate_itlb_entry_no_isync (unsigned entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Caller must follow up with 'isync'. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) __asm__ __volatile__ ("iitlb %0\n" : : "a" (entry) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static inline void invalidate_dtlb_entry_no_isync (unsigned entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Caller must follow up with 'isync'. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) __asm__ __volatile__ ("idtlb %0\n" : : "a" (entry) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static inline void set_itlbcfg_register (unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __asm__ __volatile__("wsr %0, itlbcfg\n\t" "isync\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) : : "a" (val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline void set_dtlbcfg_register (unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __asm__ __volatile__("wsr %0, dtlbcfg; dsync\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) : : "a" (val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline void set_ptevaddr_register (unsigned long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) __asm__ __volatile__(" wsr %0, ptevaddr; isync\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) : : "a" (val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static inline unsigned long read_ptevaddr_register (void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) __asm__ __volatile__("rsr %0, ptevaddr\n\t" : "=a" (tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static inline void write_dtlb_entry (pte_t entry, int way)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __asm__ __volatile__("wdtlb %1, %0; dsync\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) : : "r" (way), "r" (entry) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static inline void write_itlb_entry (pte_t entry, int way)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) __asm__ __volatile__("witlb %1, %0; isync\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) : : "r" (way), "r" (entry) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static inline void invalidate_page_directory (void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) invalidate_dtlb_entry (DTLB_WAY_PGD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) invalidate_dtlb_entry (DTLB_WAY_PGD+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) invalidate_dtlb_entry (DTLB_WAY_PGD+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static inline void invalidate_itlb_mapping (unsigned address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned long tlb_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (((tlb_entry = itlb_probe(address)) & (1 << ITLB_HIT_BIT)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) invalidate_itlb_entry(tlb_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static inline void invalidate_dtlb_mapping (unsigned address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned long tlb_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (((tlb_entry = dtlb_probe(address)) & (1 << DTLB_HIT_BIT)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) invalidate_dtlb_entry(tlb_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * DO NOT USE THESE FUNCTIONS. These instructions aren't part of the Xtensa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * ISA and exist only for test purposes..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * You may find it helpful for MMU debugging, however.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * 'at' is the unmodified input register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * 'as' is the output register, as follows (specific to the Linux config):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * as[31..12] contain the virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * as[11..08] are meaningless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * as[07..00] contain the asid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static inline unsigned long read_dtlb_virtual (int way)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) __asm__ __volatile__("rdtlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static inline unsigned long read_dtlb_translation (int way)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) __asm__ __volatile__("rdtlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static inline unsigned long read_itlb_virtual (int way)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) __asm__ __volatile__("ritlb0 %0, %1\n\t" : "=a" (tmp), "+a" (way));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static inline unsigned long read_itlb_translation (int way)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) __asm__ __volatile__("ritlb1 %0, %1\n\t" : "=a" (tmp), "+a" (way));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #endif /* __ASSEMBLY__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #endif /* _XTENSA_TLBFLUSH_H */