mmu_context.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright (C) 2004-2006 Atmel Corporation
  3. *
  4. * ASID handling taken from SH implementation.
  5. * Copyright (C) 1999 Niibe Yutaka
  6. * Copyright (C) 2003 Paul Mundt
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #ifndef __ASM_AVR32_MMU_CONTEXT_H
  13. #define __ASM_AVR32_MMU_CONTEXT_H
  14. #include <asm/tlbflush.h>
  15. #include <asm/sysreg.h>
  16. #include <asm-generic/mm_hooks.h>
  17. /*
  18. * The MMU "context" consists of two things:
  19. * (a) TLB cache version
  20. * (b) ASID (Address Space IDentifier)
  21. */
  22. #define MMU_CONTEXT_ASID_MASK 0x000000ff
  23. #define MMU_CONTEXT_VERSION_MASK 0xffffff00
  24. #define MMU_CONTEXT_FIRST_VERSION 0x00000100
  25. #define NO_CONTEXT 0
  26. #define MMU_NO_ASID 0x100
  27. /* Virtual Page Number mask */
  28. #define MMU_VPN_MASK 0xfffff000
  29. /* Cache of MMU context last used */
  30. extern unsigned long mmu_context_cache;
  31. /*
  32. * Get MMU context if needed
  33. */
  34. static inline void
  35. get_mmu_context(struct mm_struct *mm)
  36. {
  37. unsigned long mc = mmu_context_cache;
  38. if (((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) == 0)
  39. /* It's up to date, do nothing */
  40. return;
  41. /* It's old, we need to get new context with new version */
  42. mc = ++mmu_context_cache;
  43. if (!(mc & MMU_CONTEXT_ASID_MASK)) {
  44. /*
  45. * We have exhausted all ASIDs of this version.
  46. * Flush the TLB and start new cycle.
  47. */
  48. flush_tlb_all();
  49. /*
  50. * Fix version. Note that we avoid version #0
  51. * to distinguish NO_CONTEXT.
  52. */
  53. if (!mc)
  54. mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
  55. }
  56. mm->context = mc;
  57. }
  58. /*
  59. * Initialize the context related info for a new mm_struct
  60. * instance.
  61. */
  62. static inline int init_new_context(struct task_struct *tsk,
  63. struct mm_struct *mm)
  64. {
  65. mm->context = NO_CONTEXT;
  66. return 0;
  67. }
  68. /*
  69. * Destroy context related info for an mm_struct that is about
  70. * to be put to rest.
  71. */
  72. static inline void destroy_context(struct mm_struct *mm)
  73. {
  74. /* Do nothing */
  75. }
  76. static inline void set_asid(unsigned long asid)
  77. {
  78. /* XXX: We're destroying TLBEHI[8:31] */
  79. sysreg_write(TLBEHI, asid & MMU_CONTEXT_ASID_MASK);
  80. cpu_sync_pipeline();
  81. }
  82. static inline unsigned long get_asid(void)
  83. {
  84. unsigned long asid;
  85. asid = sysreg_read(TLBEHI);
  86. return asid & MMU_CONTEXT_ASID_MASK;
  87. }
  88. static inline void activate_context(struct mm_struct *mm)
  89. {
  90. get_mmu_context(mm);
  91. set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
  92. }
  93. static inline void switch_mm(struct mm_struct *prev,
  94. struct mm_struct *next,
  95. struct task_struct *tsk)
  96. {
  97. if (likely(prev != next)) {
  98. unsigned long __pgdir = (unsigned long)next->pgd;
  99. sysreg_write(PTBR, __pgdir);
  100. activate_context(next);
  101. }
  102. }
  103. #define deactivate_mm(tsk,mm) do { } while(0)
  104. #define activate_mm(prev, next) switch_mm((prev), (next), NULL)
  105. static inline void
  106. enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  107. {
  108. }
  109. static inline void enable_mmu(void)
  110. {
  111. sysreg_write(MMUCR, (SYSREG_BIT(MMUCR_S)
  112. | SYSREG_BIT(E)
  113. | SYSREG_BIT(MMUCR_I)));
  114. nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
  115. if (mmu_context_cache == NO_CONTEXT)
  116. mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
  117. set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK);
  118. }
  119. static inline void disable_mmu(void)
  120. {
  121. sysreg_write(MMUCR, SYSREG_BIT(MMUCR_S));
  122. }
  123. #endif /* __ASM_AVR32_MMU_CONTEXT_H */