mmu_context.h 3.3 KB

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