mmu.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * File : mmu.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2012-01-10 bernard porting to AM1808
  13. */
  14. #include <rtthread.h>
  15. #include "am33xx.h"
  16. #include <mmu.h>
  17. extern void rt_cpu_dcache_disable(void);
  18. extern void rt_hw_cpu_dcache_enable(void);
  19. extern void rt_cpu_icache_disable(void);
  20. extern void rt_hw_cpu_icache_enable(void);
  21. extern void rt_cpu_mmu_disable(void);
  22. extern void rt_cpu_mmu_enable(void);
  23. extern void rt_cpu_tlb_set(register rt_uint32_t i);
  24. void mmu_disable_dcache()
  25. {
  26. rt_cpu_dcache_disable();
  27. }
  28. void mmu_enable_dcache()
  29. {
  30. rt_hw_cpu_dcache_enable();
  31. }
  32. void mmu_disable_icache()
  33. {
  34. rt_cpu_icache_disable();
  35. }
  36. void mmu_enable_icache()
  37. {
  38. rt_hw_cpu_icache_enable();
  39. }
  40. void mmu_disable()
  41. {
  42. rt_cpu_mmu_disable();
  43. }
  44. void mmu_enable()
  45. {
  46. rt_cpu_mmu_enable();
  47. }
  48. void mmu_setttbase(register rt_uint32_t i)
  49. {
  50. register rt_uint32_t value;
  51. /* Invalidates all TLBs.Domain access is selected as
  52. * client by configuring domain access register,
  53. * in that case access controlled by permission value
  54. * set by page table entry
  55. */
  56. value = 0;
  57. asm volatile ("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
  58. value = 0x55555555;
  59. asm volatile ("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
  60. rt_cpu_tlb_set(i);
  61. }
  62. void mmu_set_domain(register rt_uint32_t i)
  63. {
  64. asm volatile ("mcr p15,0, %0, c3, c0, 0": :"r" (i));
  65. }
  66. void mmu_enable_alignfault()
  67. {
  68. register rt_uint32_t i;
  69. /* read control register */
  70. asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  71. i |= (1 << 1);
  72. /* write back to control register */
  73. asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  74. }
  75. void mmu_disable_alignfault()
  76. {
  77. register rt_uint32_t i;
  78. /* read control register */
  79. asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  80. i &= ~(1 << 1);
  81. /* write back to control register */
  82. asm volatile ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  83. }
  84. void mmu_clean_invalidated_cache_index(int index)
  85. {
  86. asm volatile ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
  87. }
  88. void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
  89. {
  90. unsigned int ptr;
  91. ptr = buffer & ~0x1f;
  92. while (ptr < buffer + size)
  93. {
  94. asm volatile ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr));
  95. ptr += 32;
  96. }
  97. }
  98. void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
  99. {
  100. unsigned int ptr;
  101. ptr = buffer & ~0x1f;
  102. while (ptr < buffer + size)
  103. {
  104. asm volatile ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr));
  105. ptr += 32;
  106. }
  107. }
  108. void mmu_invalidate_tlb()
  109. {
  110. asm volatile ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
  111. }
  112. void mmu_invalidate_icache()
  113. {
  114. asm volatile ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
  115. }
  116. /* level1 page table */
  117. static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024)));
  118. void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr)
  119. {
  120. volatile rt_uint32_t *pTT;
  121. volatile int i,nSec;
  122. pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20);
  123. nSec=(vaddrEnd>>20)-(vaddrStart>>20);
  124. for(i=0;i<=nSec;i++)
  125. {
  126. *pTT = attr |(((paddrStart>>20)+i)<<20);
  127. pTT++;
  128. }
  129. }
  130. /* set page table */
  131. RT_WEAK void mmu_setmtts(void)
  132. {
  133. mmu_setmtt(0x00000000, 0xFFFFFFFF, 0x00000000, RW_NCNB); /* None cached for 4G memory */
  134. mmu_setmtt(0x80200000, 0x80800000 - 1, 0x80200000, RW_CB); /* 126M cached DDR memory */
  135. mmu_setmtt(0x80000000, 0x80200000 - 1, 0x80000000, RW_NCNB); /* 2M none-cached DDR memory */
  136. mmu_setmtt(0x402F0000, 0x40300000 - 1, 0x402F0000, RW_CB); /* 63K OnChip memory */
  137. }
  138. void rt_hw_mmu_init(void)
  139. {
  140. /* disable I/D cache */
  141. mmu_disable_dcache();
  142. mmu_disable_icache();
  143. mmu_disable();
  144. mmu_invalidate_tlb();
  145. mmu_setmtts();
  146. /* set MMU table address */
  147. mmu_setttbase((rt_uint32_t)_page_table);
  148. /* enables MMU */
  149. mmu_enable();
  150. /* enable Instruction Cache */
  151. mmu_enable_icache();
  152. /* enable Data Cache */
  153. mmu_enable_dcache();
  154. }