mmu.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
  3. This file is part of ChibiOS.
  4. ChibiOS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. ChibiOS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. /**
  16. * @file mmu.c
  17. * @brief MMU code.
  18. *
  19. * @addtogroup MMU
  20. * @{
  21. */
  22. #include <stddef.h>
  23. #include <stdint.h>
  24. #include <stdbool.h>
  25. #include "mmu.h"
  26. #include "armparams.h"
  27. #include "mcuconf.h"
  28. #include "ARMCA5.h"
  29. #if defined(__GNUC__) || defined(__DOXYGEN__)
  30. #include "cmsis_gcc.h"
  31. #else
  32. #include "cmsis_armcc.h"
  33. #endif
  34. #include "ccportab.h"
  35. #if !defined(SAMA_L2CC_ASSUME_ENABLED)
  36. #define SAMA_L2CC_ASSUME_ENABLED 0
  37. #endif
  38. #if !defined(SAMA_L2CC_ENABLE)
  39. #define SAMA_L2CC_ENABLE 0
  40. #endif
  41. #if (SAMA_L2CC_ASSUME_ENABLED && SAMA_L2CC_ENABLE)
  42. #error "These macros are mutually exclusive"
  43. #endif
  44. /*===========================================================================*/
  45. /* Module local definitions. */
  46. /*===========================================================================*/
  47. /*
  48. * @brief No cacheable memory start address.
  49. */
  50. #define NO_CACHE_MEMORY_START_ADDR ((uint8_t *) 0x26F00000)
  51. /*===========================================================================*/
  52. /* Module exported variables. */
  53. /*===========================================================================*/
  54. /*===========================================================================*/
  55. /* Module local types. */
  56. /*===========================================================================*/
  57. /*===========================================================================*/
  58. /* Module local variables. */
  59. /*===========================================================================*/
  60. /*
  61. * Use 1MB granularity. It best fits the SAMA5D2 memory layout.
  62. *
  63. * The MMU table contains 4096 entries.
  64. * Each entry in the mmu table (short descriptor, type 1MB section) is 32 bit wide (total 16kB),
  65. * and is structured in this way (with examples):
  66. *
  67. * +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
  68. * |3 2|1 |1|1 |1|1 |1 1|1 1| | | | | | | |
  69. * |1 0|9 |8|7 |6|5 |4 2|1 0|9|8 5|4 |3|2|1|0 |
  70. * +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
  71. * | section |NS|0|nG|S|AP[2]|TEX[2:0]|AP[1:0]| |domain|XN|C|B|1|PXN|
  72. * +---------+--+-+--+-+-----+--------+-------+-+------+--+-+-+-+---+
  73. * | |X |0|0 |0|0 |111 |11 |0|0000 |0 |1|1|1|0 | == normal, cacheable, write back, no write allocate
  74. * | |0 |0|0 |1|0 |100 |11 |0|0000 |0 |0|0|1|0 | == normal, no-cacheable
  75. * | |0 |0|0 |1|0 |000 |11 |0|0000 |0 |0|1|1|0 | == device
  76. * | |0 |0|0 |1|0 |000 |11 |0|0000 |0 |0|0|1|0 | == strongly-ordered
  77. * | |0 |0|0 |0|0 |000 |00 |0|0000 |0 |0|0|0|0 | == undefined
  78. *
  79. * Domains are 'client'. Accesses are checked against the permission bits in tlb.
  80. */
  81. static uint32_t mmuTable[4096] CC_ALIGN(16384);
  82. /*===========================================================================*/
  83. /* Module local functions. */
  84. /*===========================================================================*/
  85. /*===========================================================================*/
  86. /* Module exported functions. */
  87. /*===========================================================================*/
  88. /**
  89. * @brief Core/MMU Module initialization.
  90. * @note This function is implicitly invoked on system initialization,
  91. * there is no need to explicitly initialize the module.
  92. *
  93. * @notapi
  94. */
  95. void __core_init(void) {
  96. uint32_t pm;
  97. #if ARM_SUPPORTS_L2CC
  98. #if !SAMA_L2CC_ASSUME_ENABLED
  99. /* Flush and disable an enabled L2 Cache
  100. invalidate a disabled L2 Cache.*/
  101. if ((L2C_310->CONTROL & L2CC_CR_L2CEN) != 0) {
  102. L2C_Disable();
  103. L2C_CleanInvAllByWay();
  104. }
  105. #endif
  106. #endif
  107. /* Flush and disable an enabled L1 D Cache
  108. Invalidate a disabled L1 D Cache.*/
  109. pm = __get_SCTLR();
  110. if ((pm & SCTLR_C_Msk)) {
  111. L1C_DisableCaches();
  112. L1C_CleanInvalidateCache(DCISW_CLEAN);
  113. }
  114. /* Disable the MMU and invalidate TLB.*/
  115. MMU_Disable();
  116. L1C_InvalidateBTAC();
  117. MMU_InvalidateTLB();
  118. /*
  119. * Default, undefined regions
  120. */
  121. for (pm = 0; pm < 4096; ++pm)
  122. mmuTable[pm] = TTE_SECT_UNDEF;
  123. /*
  124. * ROM region
  125. *
  126. * 0x00000000
  127. */
  128. mmuTable[0] = TTE_SECT_SECTION(0x00000000) |
  129. TTE_SECT_MEM_NO_CACHEABLE |
  130. TTE_SECT_RO_ACCESS |
  131. TTE_SECT_DOM(0x00) |
  132. TTE_SECT_S | TTE_TYPE_SECT;
  133. /*
  134. * NFC SRAM region
  135. *
  136. * 0x00100000
  137. */
  138. mmuTable[1] = TTE_SECT_SECTION(0x00100000) |
  139. TTE_SECT_DEVICE |
  140. TTE_SECT_RW_ACCESS |
  141. TTE_SECT_DOM(0x00) |
  142. TTE_SECT_S | TTE_TYPE_SECT;
  143. /*
  144. * SRAM region
  145. *
  146. * 0x00200000
  147. */
  148. mmuTable[2] = TTE_SECT_SECTION(0x00200000) |
  149. TTE_SECT_MEM_CACHEABLE |
  150. TTE_SECT_RW_ACCESS |
  151. TTE_SECT_DOM(0x00) |
  152. TTE_TYPE_SECT;
  153. /*
  154. * UDPHS RAM region
  155. *
  156. * 0x00300000
  157. */
  158. mmuTable[3] = TTE_SECT_SECTION(0x00300000) |
  159. TTE_SECT_DEVICE |
  160. TTE_SECT_RW_ACCESS |
  161. TTE_SECT_DOM(0x00) |
  162. TTE_SECT_EXE_NEVER |
  163. TTE_SECT_S | TTE_TYPE_SECT;
  164. /*
  165. * UHPHS region
  166. *
  167. * 0x00400000
  168. */
  169. mmuTable[4] = TTE_SECT_SECTION(0x00400000) |
  170. TTE_SECT_DEVICE |
  171. TTE_SECT_RW_ACCESS |
  172. TTE_SECT_DOM(0x00) |
  173. TTE_SECT_EXE_NEVER |
  174. TTE_SECT_S | TTE_TYPE_SECT;
  175. /*
  176. * UDPHS region
  177. *
  178. * 0x00500000
  179. */
  180. mmuTable[5] = TTE_SECT_SECTION(0x00500000) |
  181. TTE_SECT_DEVICE |
  182. TTE_SECT_RW_ACCESS |
  183. TTE_SECT_DOM(0x00) |
  184. TTE_SECT_EXE_NEVER |
  185. TTE_SECT_S | TTE_TYPE_SECT;
  186. /*
  187. * AXIMX region
  188. *
  189. * 0x00600000
  190. */
  191. mmuTable[6] = TTE_SECT_SECTION(0x00600000) |
  192. TTE_SECT_DEVICE |
  193. TTE_SECT_RW_ACCESS |
  194. TTE_SECT_DOM(0x00) |
  195. TTE_SECT_EXE_NEVER |
  196. TTE_SECT_S | TTE_TYPE_SECT;
  197. /*
  198. * DAP region
  199. *
  200. * 0x00700000
  201. */
  202. mmuTable[7] = TTE_SECT_SECTION(0x00700000) |
  203. TTE_SECT_DEVICE |
  204. TTE_SECT_RW_ACCESS |
  205. TTE_SECT_DOM(0x00) |
  206. TTE_SECT_EXE_NEVER |
  207. TTE_SECT_S | TTE_TYPE_SECT;
  208. /*
  209. * L2CC region, low
  210. *
  211. * 0x00a00000
  212. */
  213. mmuTable[0xa] = TTE_SECT_SECTION(0x00a00000) |
  214. TTE_SECT_DEVICE |
  215. TTE_SECT_RW_ACCESS |
  216. TTE_SECT_DOM(0x00) |
  217. TTE_SECT_EXE_NEVER |
  218. TTE_SECT_S | TTE_TYPE_SECT;
  219. /*
  220. * L2CC region, hi
  221. *
  222. * 0x00b00000
  223. */
  224. mmuTable[0xb] = TTE_SECT_SECTION(0x00b00000) |
  225. TTE_SECT_DEVICE |
  226. TTE_SECT_RW_ACCESS |
  227. TTE_SECT_DOM(0x00) |
  228. TTE_SECT_EXE_NEVER |
  229. TTE_SECT_S | TTE_TYPE_SECT;
  230. /*
  231. * EBI regions
  232. *
  233. * 0x10000000 - 0x1fffffff
  234. */
  235. for (pm = 0x100; pm < 0x200; pm++)
  236. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  237. TTE_SECT_MEM_STRONGLY_ORD |
  238. TTE_SECT_RW_ACCESS |
  239. TTE_SECT_DOM(0x00) |
  240. TTE_SECT_EXE_NEVER |
  241. TTE_SECT_S | TTE_TYPE_SECT;
  242. /*
  243. * DDR regions
  244. *
  245. * 0x20000000 - 0x3fffffff
  246. */
  247. for (pm = 0x200; pm < 0x400; pm++)
  248. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  249. TTE_SECT_MEM_CACHEABLE |
  250. TTE_SECT_RW_ACCESS |
  251. TTE_SECT_DOM(0x00) |
  252. TTE_TYPE_SECT;
  253. /*
  254. * DDR AESB regions
  255. *
  256. * 0x40000000 - 0x5fffffff
  257. */
  258. for (pm = 0x400; pm < 0x600; pm++)
  259. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  260. TTE_SECT_MEM_CACHEABLE |
  261. TTE_SECT_RW_ACCESS |
  262. TTE_SECT_DOM(0x00) |
  263. TTE_TYPE_SECT;
  264. /*
  265. * EBI 1, 2 and 3 regions
  266. *
  267. * 0x60000000 - 0x8fffffff
  268. */
  269. for (pm = 0x600; pm < 0x900; pm++)
  270. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  271. TTE_SECT_MEM_STRONGLY_ORD |
  272. TTE_SECT_RW_ACCESS |
  273. TTE_SECT_DOM(0x00) |
  274. TTE_SECT_S | TTE_TYPE_SECT;
  275. /*
  276. * QSPI0/1 AESB MEM regions
  277. *
  278. * 0x90000000 - 0x9fffffff
  279. */
  280. for (pm = 0x900; pm < 0xa00; pm++)
  281. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  282. TTE_SECT_MEM_STRONGLY_ORD |
  283. TTE_SECT_RW_ACCESS |
  284. TTE_SECT_DOM(0x00) |
  285. TTE_SECT_S | TTE_TYPE_SECT;
  286. /*
  287. * SDMMC0/1 regions
  288. *
  289. * 0xa0000000 - 0xbfffffff
  290. */
  291. for (pm = 0xa00; pm < 0xc00; pm++)
  292. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  293. TTE_SECT_MEM_STRONGLY_ORD |
  294. TTE_SECT_RW_ACCESS |
  295. TTE_SECT_DOM(0x00) |
  296. TTE_SECT_EXE_NEVER |
  297. TTE_TYPE_SECT;
  298. /*
  299. * NFC regions
  300. *
  301. * 0xc0000000 - 0xcfffffff
  302. */
  303. for (pm = 0xc00; pm < 0xd00; pm++)
  304. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  305. TTE_SECT_MEM_STRONGLY_ORD |
  306. TTE_SECT_RW_ACCESS |
  307. TTE_SECT_DOM(0x00) |
  308. TTE_SECT_EXE_NEVER |
  309. TTE_SECT_S | TTE_TYPE_SECT;
  310. /*
  311. * QSPI0/1 MEM regions
  312. *
  313. * 0xd0000000 - 0xdfffffff
  314. */
  315. for (pm = 0xd00; pm < 0xe00; pm++)
  316. mmuTable[pm] = TTE_SECT_SECTION(pm << 20) |
  317. TTE_SECT_MEM_STRONGLY_ORD |
  318. TTE_SECT_RW_ACCESS |
  319. TTE_SECT_DOM(0x00) |
  320. TTE_SECT_S | TTE_TYPE_SECT;
  321. /*
  322. * Internal peripherals regions
  323. *
  324. * 0xf0000000
  325. * 0xf8000000
  326. * 0xfc000000
  327. */
  328. mmuTable[0xf00] = TTE_SECT_SECTION(0xf0000000) |
  329. TTE_SECT_DEVICE |
  330. TTE_SECT_RW_ACCESS |
  331. TTE_SECT_DOM(0x00) |
  332. TTE_SECT_EXE_NEVER |
  333. TTE_SECT_S | TTE_TYPE_SECT;
  334. mmuTable[0xf80] = TTE_SECT_SECTION(0xf8000000) |
  335. TTE_SECT_DEVICE |
  336. TTE_SECT_RW_ACCESS |
  337. TTE_SECT_DOM(0x00) |
  338. TTE_SECT_EXE_NEVER |
  339. TTE_SECT_S | TTE_TYPE_SECT;
  340. mmuTable[0xfc0] = TTE_SECT_SECTION(0xfc000000) |
  341. TTE_SECT_DEVICE |
  342. TTE_SECT_RW_ACCESS |
  343. TTE_SECT_DOM(0x00) |
  344. TTE_SECT_EXE_NEVER |
  345. TTE_SECT_S | TTE_TYPE_SECT;
  346. /* Make a NO CACHE AREA */
  347. MMU_MemorySection((mmuTable + ((uint32_t)NO_CACHE_MEMORY_START_ADDR >> 20)), NORMAL, NON_CACHEABLE, NON_CACHEABLE);
  348. /* Invalidate TLB and L1 I cache
  349. Enable caches and MMU.*/
  350. MMU_InvalidateTLB();
  351. __set_TTBR0((uint32_t)mmuTable|0x5B);
  352. __set_DACR(0x00000001);
  353. __DSB();
  354. __ISB();
  355. /* L1 I cache invalidate and enable.*/
  356. pm = __get_SCTLR();
  357. if ((pm & SCTLR_I_Msk) == 0) {
  358. __set_ICIALLU(0);
  359. __set_SCTLR(pm | SCTLR_I_Msk);
  360. }
  361. /* MMU enable.*/
  362. pm = __get_SCTLR();
  363. if ((pm & SCTLR_M_Msk) == 0)
  364. __set_SCTLR(pm | SCTLR_M_Msk);
  365. /* L1 D cache enable.*/
  366. pm = __get_SCTLR();
  367. if ((pm & SCTLR_C_Msk) == 0) {
  368. L1C_CleanInvalidateCache(DCISW_INVALIDATE);
  369. __set_SCTLR(pm | SCTLR_C_Msk);
  370. }
  371. #if ARM_SUPPORTS_L2CC
  372. #if !(SAMA_L2CC_ASSUME_ENABLED) && (SAMA_L2CC_ENABLE)
  373. if (!(L2C_310->CONTROL & L2CC_CR_L2CEN)) {
  374. /* High SRAM to L2CC.*/
  375. SFR->SFR_L2CC_HRAMC = 0x1;
  376. /* Invalidate and enable L2 cache.*/
  377. L2C_InvAllByWay();
  378. L2C_310->AUX_CNT = L2CC_ACR_DPEN | L2CC_ACR_IPEN;
  379. /* Prefetch control register. Double linefeed, instr and data enabled.*/
  380. *((uint32_t *)((char *)L2C_310+0x0F60)) = 0x75800001;
  381. L2C_Enable();
  382. __DSB();
  383. __ISB();
  384. }
  385. #endif
  386. #endif
  387. }
  388. /** @} */