mmu.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  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. * 2008-04-25 Yi.qiu first version
  13. * 2009-12-18 Bernard port to armcc
  14. */
  15. #include <rtthread.h>
  16. #include "s3c24x0.h"
  17. #define _MMUTT_STARTADDRESS 0x33FF0000
  18. #define DESC_SEC (0x2|(1<<4))
  19. #define CB (3<<2) //cache_on, write_back
  20. #define CNB (2<<2) //cache_on, write_through
  21. #define NCB (1<<2) //cache_off,WR_BUF on
  22. #define NCNB (0<<2) //cache_off,WR_BUF off
  23. #define AP_RW (3<<10) //supervisor=RW, user=RW
  24. #define AP_RO (2<<10) //supervisor=RW, user=RO
  25. #define DOMAIN_FAULT (0x0)
  26. #define DOMAIN_CHK (0x1)
  27. #define DOMAIN_NOTCHK (0x3)
  28. #define DOMAIN0 (0x0<<5)
  29. #define DOMAIN1 (0x1<<5)
  30. #define DOMAIN0_ATTR (DOMAIN_CHK<<0)
  31. #define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
  32. #define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC)
  33. #define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC)
  34. #define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC)
  35. #define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC)
  36. #ifdef __GNUC__
  37. void mmu_setttbase(register rt_uint32_t i)
  38. {
  39. asm ("mcr p15, 0, %0, c2, c0, 0": :"r" (i));
  40. }
  41. void mmu_set_domain(register rt_uint32_t i)
  42. {
  43. asm ("mcr p15,0, %0, c3, c0, 0": :"r" (i));
  44. }
  45. void mmu_enable()
  46. {
  47. register rt_uint32_t i;
  48. /* read control register */
  49. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  50. i |= 0x1;
  51. /* write back to control register */
  52. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  53. }
  54. void mmu_disable()
  55. {
  56. register rt_uint32_t i;
  57. /* read control register */
  58. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  59. i &= ~0x1;
  60. /* write back to control register */
  61. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  62. }
  63. void mmu_enable_icache()
  64. {
  65. register rt_uint32_t i;
  66. /* read control register */
  67. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  68. i |= (1 << 12);
  69. /* write back to control register */
  70. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  71. }
  72. void mmu_enable_dcache()
  73. {
  74. register rt_uint32_t i;
  75. /* read control register */
  76. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  77. i |= (1 << 2);
  78. /* write back to control register */
  79. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  80. }
  81. void mmu_disable_icache()
  82. {
  83. register rt_uint32_t i;
  84. /* read control register */
  85. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  86. i &= ~(1 << 12);
  87. /* write back to control register */
  88. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  89. }
  90. void mmu_disable_dcache()
  91. {
  92. register rt_uint32_t i;
  93. /* read control register */
  94. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  95. i &= ~(1 << 2);
  96. /* write back to control register */
  97. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  98. }
  99. void mmu_enable_alignfault()
  100. {
  101. register rt_uint32_t i;
  102. /* read control register */
  103. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  104. i |= (1 << 1);
  105. /* write back to control register */
  106. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  107. }
  108. void mmu_disable_alignfault()
  109. {
  110. register rt_uint32_t i;
  111. /* read control register */
  112. asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
  113. i &= ~(1 << 1);
  114. /* write back to control register */
  115. asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
  116. }
  117. void mmu_clean_invalidated_cache_index(int index)
  118. {
  119. asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
  120. }
  121. void mmu_invalidate_tlb()
  122. {
  123. asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
  124. }
  125. void mmu_invalidate_icache()
  126. {
  127. asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
  128. }
  129. #endif
  130. #ifdef __CC_ARM
  131. void mmu_setttbase(rt_uint32_t i)
  132. {
  133. __asm
  134. {
  135. mcr p15, 0, i, c2, c0, 0
  136. }
  137. }
  138. void mmu_set_domain(rt_uint32_t i)
  139. {
  140. __asm
  141. {
  142. mcr p15,0, i, c3, c0, 0
  143. }
  144. }
  145. void mmu_enable()
  146. {
  147. register rt_uint32_t value;
  148. __asm
  149. {
  150. mrc p15, 0, value, c1, c0, 0
  151. orr value, value, #0x01
  152. mcr p15, 0, value, c1, c0, 0
  153. }
  154. }
  155. void mmu_disable()
  156. {
  157. register rt_uint32_t value;
  158. __asm
  159. {
  160. mrc p15, 0, value, c1, c0, 0
  161. bic value, value, #0x01
  162. mcr p15, 0, value, c1, c0, 0
  163. }
  164. }
  165. void mmu_enable_icache()
  166. {
  167. register rt_uint32_t value;
  168. __asm
  169. {
  170. mrc p15, 0, value, c1, c0, 0
  171. orr value, value, #0x1000
  172. mcr p15, 0, value, c1, c0, 0
  173. }
  174. }
  175. void mmu_enable_dcache()
  176. {
  177. register rt_uint32_t value;
  178. __asm
  179. {
  180. mrc p15, 0, value, c1, c0, 0
  181. orr value, value, #0x04
  182. mcr p15, 0, value, c1, c0, 0
  183. }
  184. }
  185. void mmu_disable_icache()
  186. {
  187. register rt_uint32_t value;
  188. __asm
  189. {
  190. mrc p15, 0, value, c1, c0, 0
  191. bic value, value, #0x1000
  192. mcr p15, 0, value, c1, c0, 0
  193. }
  194. }
  195. void mmu_disable_dcache()
  196. {
  197. register rt_uint32_t value;
  198. __asm
  199. {
  200. mrc p15, 0, value, c1, c0, 0
  201. bic value, value, #0x04
  202. mcr p15, 0, value, c1, c0, 0
  203. }
  204. }
  205. void mmu_enable_alignfault()
  206. {
  207. register rt_uint32_t value;
  208. __asm
  209. {
  210. mrc p15, 0, value, c1, c0, 0
  211. orr value, value, #0x02
  212. mcr p15, 0, value, c1, c0, 0
  213. }
  214. }
  215. void mmu_disable_alignfault()
  216. {
  217. register rt_uint32_t value;
  218. __asm
  219. {
  220. mrc p15, 0, value, c1, c0, 0
  221. bic value, value, #0x02
  222. mcr p15, 0, value, c1, c0, 0
  223. }
  224. }
  225. void mmu_clean_invalidated_cache_index(int index)
  226. {
  227. __asm
  228. {
  229. mcr p15, 0, index, c7, c14, 2
  230. }
  231. }
  232. void mmu_invalidate_tlb()
  233. {
  234. register rt_uint32_t value;
  235. value = 0;
  236. __asm
  237. {
  238. mcr p15, 0, value, c8, c7, 0
  239. }
  240. }
  241. void mmu_invalidate_icache()
  242. {
  243. register rt_uint32_t value;
  244. value = 0;
  245. __asm
  246. {
  247. mcr p15, 0, value, c7, c5, 0
  248. }
  249. }
  250. #endif
  251. void mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr)
  252. {
  253. volatile rt_uint32_t *pTT;
  254. volatile int i,nSec;
  255. pTT=(rt_uint32_t *)_MMUTT_STARTADDRESS+(vaddrStart>>20);
  256. nSec=(vaddrEnd>>20)-(vaddrStart>>20);
  257. for(i=0;i<=nSec;i++)
  258. {
  259. *pTT = attr |(((paddrStart>>20)+i)<<20);
  260. pTT++;
  261. }
  262. }
  263. void rt_hw_mmu_init(void)
  264. {
  265. int i,j;
  266. //========================== IMPORTANT NOTE =========================
  267. //The current stack and code area can't be re-mapped in this routine.
  268. //If you want memory map mapped freely, your own sophiscated mmu
  269. //initialization code is needed.
  270. //===================================================================
  271. mmu_disable_dcache();
  272. mmu_disable_icache();
  273. //If write-back is used,the DCache should be cleared.
  274. for(i=0;i<64;i++)
  275. for(j=0;j<8;j++)
  276. mmu_clean_invalidated_cache_index((i<<26)|(j<<5));
  277. mmu_invalidate_icache();
  278. //To complete mmu_Init() fast, Icache may be turned on here.
  279. mmu_enable_icache();
  280. mmu_disable();
  281. mmu_invalidate_tlb();
  282. //mmu_setmtt(int vaddrStart,int vaddrEnd,int paddrStart,int attr);
  283. mmu_setmtt(0x00000000,0x07f00000,0x00000000,RW_CNB); //bank0
  284. mmu_setmtt(0x00000000,0x03f00000,(int)0x30000000,RW_CB); //bank0
  285. mmu_setmtt(0x04000000,0x07f00000,0,RW_NCNB); //bank0
  286. mmu_setmtt(0x08000000,0x0ff00000,0x08000000,RW_CNB); //bank1
  287. mmu_setmtt(0x10000000,0x17f00000,0x10000000,RW_NCNB); //bank2
  288. mmu_setmtt(0x18000000,0x1ff00000,0x18000000,RW_NCNB); //bank3
  289. //mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_CB); //bank4
  290. mmu_setmtt(0x20000000,0x27f00000,0x20000000,RW_NCNB); //bank4 for DM9000
  291. mmu_setmtt(0x28000000,0x2ff00000,0x28000000,RW_NCNB); //bank5
  292. //30f00000->30100000, 31000000->30200000
  293. mmu_setmtt(0x30000000,0x30100000,0x30000000,RW_CB); //bank6-1
  294. mmu_setmtt(0x30200000,0x33e00000,0x30200000,RW_CB); //bank6-2
  295. mmu_setmtt(0x33f00000,0x34000000,0x33f00000,RW_NCNB); //bank6-3
  296. mmu_setmtt(0x38000000,0x3ff00000,0x38000000,RW_NCNB); //bank7
  297. mmu_setmtt(0x40000000,0x47f00000,0x40000000,RW_NCNB); //SFR
  298. mmu_setmtt(0x48000000,0x5af00000,0x48000000,RW_NCNB); //SFR
  299. mmu_setmtt(0x5b000000,0x5b000000,0x5b000000,RW_NCNB); //SFR
  300. mmu_setmtt(0x5b100000,0xfff00000,0x5b100000,RW_FAULT);//not used
  301. mmu_setmtt(0x60000000,0x67f00000,0x60000000,RW_NCNB); //SFR
  302. mmu_setttbase(_MMUTT_STARTADDRESS);
  303. /* DOMAIN1: no_access, DOMAIN0,2~15=client(AP is checked) */
  304. mmu_set_domain(0x55555550|DOMAIN1_ATTR|DOMAIN0_ATTR);
  305. mmu_enable_alignfault();
  306. mmu_enable();
  307. /* ICache enable */
  308. mmu_enable_icache();
  309. /* DCache should be turned on after mmu is turned on. */
  310. mmu_enable_dcache();
  311. }