home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-xtensa / tlbflush.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  5.2 KB  |  201 lines

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