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-m32r / mmu_context.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  4.1 KB  |  169 lines

  1. #ifndef _ASM_M32R_MMU_CONTEXT_H
  2. #define _ASM_M32R_MMU_CONTEXT_H
  3.  
  4. #ifdef __KERNEL__
  5.  
  6.  
  7. #include <asm/m32r.h>
  8.  
  9. #define MMU_CONTEXT_ASID_MASK      (0x000000FF)
  10. #define MMU_CONTEXT_VERSION_MASK   (0xFFFFFF00)
  11. #define MMU_CONTEXT_FIRST_VERSION  (0x00000100)
  12. #define NO_CONTEXT                 (0x00000000)
  13.  
  14.  
  15. #ifndef __ASSEMBLY__
  16.  
  17. #include <asm/atomic.h>
  18. #include <asm/pgalloc.h>
  19. #include <asm/mmu.h>
  20. #include <asm/tlbflush.h>
  21.  
  22. /*
  23.  * Cache of MMU context last used.
  24.  */
  25. #ifndef CONFIG_SMP
  26. extern unsigned long mmu_context_cache_dat;
  27. #define mmu_context_cache    mmu_context_cache_dat
  28. #define mm_context(mm)        mm->context
  29. #else /* not CONFIG_SMP */
  30. extern unsigned long mmu_context_cache_dat[];
  31. #define mmu_context_cache    mmu_context_cache_dat[smp_processor_id()]
  32. #define mm_context(mm)        mm->context[smp_processor_id()]
  33. #endif /* not CONFIG_SMP */
  34.  
  35. #define set_tlb_tag(entry, tag)        (*entry = (tag & PAGE_MASK)|get_asid())
  36. #define set_tlb_data(entry, data)    (*entry = (data | _PAGE_PRESENT))
  37.  
  38. #ifdef CONFIG_MMU
  39. #define enter_lazy_tlb(mm, tsk)    do { } while (0)
  40.  
  41. static inline void get_new_mmu_context(struct mm_struct *mm)
  42. {
  43.     unsigned long mc = ++mmu_context_cache;
  44.  
  45.     if (!(mc & MMU_CONTEXT_ASID_MASK)) {
  46.         /* We exhaust ASID of this version.
  47.            Flush all TLB and start new cycle. */
  48.         local_flush_tlb_all();
  49.         /* Fix version if needed.
  50.            Note that we avoid version #0 to distingush NO_CONTEXT. */
  51.         if (!mc)
  52.             mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
  53.     }
  54.     mm_context(mm) = mc;
  55. }
  56.  
  57. /*
  58.  * Get MMU context if needed.
  59.  */
  60. static inline void get_mmu_context(struct mm_struct *mm)
  61. {
  62.     if (mm) {
  63.         unsigned long mc = mmu_context_cache;
  64.  
  65.         /* Check if we have old version of context.
  66.            If it's old, we need to get new context with new version. */
  67.         if ((mm_context(mm) ^ mc) & MMU_CONTEXT_VERSION_MASK)
  68.             get_new_mmu_context(mm);
  69.     }
  70. }
  71.  
  72. /*
  73.  * Initialize the context related info for a new mm_struct
  74.  * instance.
  75.  */
  76. static inline int init_new_context(struct task_struct *tsk,
  77.     struct mm_struct *mm)
  78. {
  79. #ifndef CONFIG_SMP
  80.     mm->context = NO_CONTEXT;
  81. #else /* CONFIG_SMP */
  82.     int num_cpus = num_online_cpus();
  83.     int i;
  84.  
  85.     for (i = 0 ; i < num_cpus ; i++)
  86.         mm->context[i] = NO_CONTEXT;
  87. #endif /* CONFIG_SMP */
  88.  
  89.     return 0;
  90. }
  91.  
  92. /*
  93.  * Destroy context related info for an mm_struct that is about
  94.  * to be put to rest.
  95.  */
  96. #define destroy_context(mm)    do { } while (0)
  97.  
  98. static inline void set_asid(unsigned long asid)
  99. {
  100.     *(volatile unsigned long *)MASID = (asid & MMU_CONTEXT_ASID_MASK);
  101. }
  102.  
  103. static inline unsigned long get_asid(void)
  104. {
  105.     unsigned long asid;
  106.  
  107.     asid = *(volatile long *)MASID;
  108.     asid &= MMU_CONTEXT_ASID_MASK;
  109.  
  110.     return asid;
  111. }
  112.  
  113. /*
  114.  * After we have set current->mm to a new value, this activates
  115.  * the context for the new mm so we see the new mappings.
  116.  */
  117. static inline void activate_context(struct mm_struct *mm)
  118. {
  119.     get_mmu_context(mm);
  120.     set_asid(mm_context(mm) & MMU_CONTEXT_ASID_MASK);
  121. }
  122.  
  123. static inline void switch_mm(struct mm_struct *prev,
  124.     struct mm_struct *next, struct task_struct *tsk)
  125. {
  126. #ifdef CONFIG_SMP
  127.     int cpu = smp_processor_id();
  128. #endif    /* CONFIG_SMP */
  129.  
  130.     if (prev != next) {
  131. #ifdef CONFIG_SMP
  132.         cpu_set(cpu, next->cpu_vm_mask);
  133. #endif /* CONFIG_SMP */
  134.         /* Set MPTB = next->pgd */
  135.         *(volatile unsigned long *)MPTB = (unsigned long)next->pgd;
  136.         activate_context(next);
  137.     }
  138. #ifdef CONFIG_SMP
  139.     else
  140.         if (!cpu_test_and_set(cpu, next->cpu_vm_mask))
  141.             activate_context(next);
  142. #endif /* CONFIG_SMP */
  143. }
  144.  
  145. #define deactivate_mm(tsk, mm)    do { } while (0)
  146.  
  147. #define activate_mm(prev, next)    \
  148.     switch_mm((prev), (next), NULL)
  149.  
  150. #else
  151. #define get_mmu_context(mm)             do { } while (0)
  152. #define init_new_context(tsk,mm)        (0)
  153. #define destroy_context(mm)             do { } while (0)
  154. #define set_asid(asid)                  do { } while (0)
  155. #define get_asid()                      (0)
  156. #define activate_context(mm)            do { } while (0)
  157. #define switch_mm(prev,next,tsk)        do { } while (0)
  158. #define deactivate_mm(mm,tsk)           do { } while (0)
  159. #define activate_mm(prev,next)          do { } while (0)
  160. #define enter_lazy_tlb(mm,tsk)          do { } while (0)
  161. #endif /* CONFIG_MMU */
  162.  
  163.  
  164. #endif /* not __ASSEMBLY__ */
  165.  
  166. #endif /* __KERNEL__ */
  167.  
  168. #endif /* _ASM_M32R_MMU_CONTEXT_H */
  169.