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