Naze32 clone with Frysky receiver
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

core_ca_mmu.h 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. ;/**************************************************************************//**
  2. ; * @file core_ca_mmu.h
  3. ; * @brief MMU Startup File for A9_MP Device Series
  4. ; * @version V1.01
  5. ; * @date 10 Sept 2014
  6. ; *
  7. ; * @note
  8. ; *
  9. ; ******************************************************************************/
  10. ;/* Copyright (c) 2012-2014 ARM LIMITED
  11. ;
  12. ; All rights reserved.
  13. ; Redistribution and use in source and binary forms, with or without
  14. ; modification, are permitted provided that the following conditions are met:
  15. ; - Redistributions of source code must retain the above copyright
  16. ; notice, this list of conditions and the following disclaimer.
  17. ; - Redistributions in binary form must reproduce the above copyright
  18. ; notice, this list of conditions and the following disclaimer in the
  19. ; documentation and/or other materials provided with the distribution.
  20. ; - Neither the name of ARM nor the names of its contributors may be used
  21. ; to endorse or promote products derived from this software without
  22. ; specific prior written permission.
  23. ; *
  24. ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  25. ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. ; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. ; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  28. ; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31. ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  32. ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  33. ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. ; POSSIBILITY OF SUCH DAMAGE.
  35. ; ---------------------------------------------------------------------------*/
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. #ifndef _MMU_FUNC_H
  40. #define _MMU_FUNC_H
  41. #define SECTION_DESCRIPTOR (0x2)
  42. #define SECTION_MASK (0xFFFFFFFC)
  43. #define SECTION_TEXCB_MASK (0xFFFF8FF3)
  44. #define SECTION_B_SHIFT (2)
  45. #define SECTION_C_SHIFT (3)
  46. #define SECTION_TEX0_SHIFT (12)
  47. #define SECTION_TEX1_SHIFT (13)
  48. #define SECTION_TEX2_SHIFT (14)
  49. #define SECTION_XN_MASK (0xFFFFFFEF)
  50. #define SECTION_XN_SHIFT (4)
  51. #define SECTION_DOMAIN_MASK (0xFFFFFE1F)
  52. #define SECTION_DOMAIN_SHIFT (5)
  53. #define SECTION_P_MASK (0xFFFFFDFF)
  54. #define SECTION_P_SHIFT (9)
  55. #define SECTION_AP_MASK (0xFFFF73FF)
  56. #define SECTION_AP_SHIFT (10)
  57. #define SECTION_AP2_SHIFT (15)
  58. #define SECTION_S_MASK (0xFFFEFFFF)
  59. #define SECTION_S_SHIFT (16)
  60. #define SECTION_NG_MASK (0xFFFDFFFF)
  61. #define SECTION_NG_SHIFT (17)
  62. #define SECTION_NS_MASK (0xFFF7FFFF)
  63. #define SECTION_NS_SHIFT (19)
  64. #define PAGE_L1_DESCRIPTOR (0x1)
  65. #define PAGE_L1_MASK (0xFFFFFFFC)
  66. #define PAGE_L2_4K_DESC (0x2)
  67. #define PAGE_L2_4K_MASK (0xFFFFFFFD)
  68. #define PAGE_L2_64K_DESC (0x1)
  69. #define PAGE_L2_64K_MASK (0xFFFFFFFC)
  70. #define PAGE_4K_TEXCB_MASK (0xFFFFFE33)
  71. #define PAGE_4K_B_SHIFT (2)
  72. #define PAGE_4K_C_SHIFT (3)
  73. #define PAGE_4K_TEX0_SHIFT (6)
  74. #define PAGE_4K_TEX1_SHIFT (7)
  75. #define PAGE_4K_TEX2_SHIFT (8)
  76. #define PAGE_64K_TEXCB_MASK (0xFFFF8FF3)
  77. #define PAGE_64K_B_SHIFT (2)
  78. #define PAGE_64K_C_SHIFT (3)
  79. #define PAGE_64K_TEX0_SHIFT (12)
  80. #define PAGE_64K_TEX1_SHIFT (13)
  81. #define PAGE_64K_TEX2_SHIFT (14)
  82. #define PAGE_TEXCB_MASK (0xFFFF8FF3)
  83. #define PAGE_B_SHIFT (2)
  84. #define PAGE_C_SHIFT (3)
  85. #define PAGE_TEX_SHIFT (12)
  86. #define PAGE_XN_4K_MASK (0xFFFFFFFE)
  87. #define PAGE_XN_4K_SHIFT (0)
  88. #define PAGE_XN_64K_MASK (0xFFFF7FFF)
  89. #define PAGE_XN_64K_SHIFT (15)
  90. #define PAGE_DOMAIN_MASK (0xFFFFFE1F)
  91. #define PAGE_DOMAIN_SHIFT (5)
  92. #define PAGE_P_MASK (0xFFFFFDFF)
  93. #define PAGE_P_SHIFT (9)
  94. #define PAGE_AP_MASK (0xFFFFFDCF)
  95. #define PAGE_AP_SHIFT (4)
  96. #define PAGE_AP2_SHIFT (9)
  97. #define PAGE_S_MASK (0xFFFFFBFF)
  98. #define PAGE_S_SHIFT (10)
  99. #define PAGE_NG_MASK (0xFFFFF7FF)
  100. #define PAGE_NG_SHIFT (11)
  101. #define PAGE_NS_MASK (0xFFFFFFF7)
  102. #define PAGE_NS_SHIFT (3)
  103. #define OFFSET_1M (0x00100000)
  104. #define OFFSET_64K (0x00010000)
  105. #define OFFSET_4K (0x00001000)
  106. #define DESCRIPTOR_FAULT (0x00000000)
  107. /* ########################### MMU Function Access ########################### */
  108. /** \ingroup MMU_FunctionInterface
  109. \defgroup MMU_Functions MMU Functions Interface
  110. @{
  111. */
  112. /* Attributes enumerations */
  113. /* Region size attributes */
  114. typedef enum
  115. {
  116. SECTION,
  117. PAGE_4k,
  118. PAGE_64k,
  119. } mmu_region_size_Type;
  120. /* Region type attributes */
  121. typedef enum
  122. {
  123. NORMAL,
  124. DEVICE,
  125. SHARED_DEVICE,
  126. NON_SHARED_DEVICE,
  127. STRONGLY_ORDERED
  128. } mmu_memory_Type;
  129. /* Region cacheability attributes */
  130. typedef enum
  131. {
  132. NON_CACHEABLE,
  133. WB_WA,
  134. WT,
  135. WB_NO_WA,
  136. } mmu_cacheability_Type;
  137. /* Region parity check attributes */
  138. typedef enum
  139. {
  140. ECC_DISABLED,
  141. ECC_ENABLED,
  142. } mmu_ecc_check_Type;
  143. /* Region execution attributes */
  144. typedef enum
  145. {
  146. EXECUTE,
  147. NON_EXECUTE,
  148. } mmu_execute_Type;
  149. /* Region global attributes */
  150. typedef enum
  151. {
  152. GLOBAL,
  153. NON_GLOBAL,
  154. } mmu_global_Type;
  155. /* Region shareability attributes */
  156. typedef enum
  157. {
  158. NON_SHARED,
  159. SHARED,
  160. } mmu_shared_Type;
  161. /* Region security attributes */
  162. typedef enum
  163. {
  164. SECURE,
  165. NON_SECURE,
  166. } mmu_secure_Type;
  167. /* Region access attributes */
  168. typedef enum
  169. {
  170. NO_ACCESS,
  171. RW,
  172. READ,
  173. } mmu_access_Type;
  174. /* Memory Region definition */
  175. typedef struct RegionStruct {
  176. mmu_region_size_Type rg_t;
  177. mmu_memory_Type mem_t;
  178. uint8_t domain;
  179. mmu_cacheability_Type inner_norm_t;
  180. mmu_cacheability_Type outer_norm_t;
  181. mmu_ecc_check_Type e_t;
  182. mmu_execute_Type xn_t;
  183. mmu_global_Type g_t;
  184. mmu_secure_Type sec_t;
  185. mmu_access_Type priv_t;
  186. mmu_access_Type user_t;
  187. mmu_shared_Type sh_t;
  188. } mmu_region_attributes_Type;
  189. /** \brief Set section execution-never attribute
  190. The function sets section execution-never attribute
  191. \param [out] descriptor_l1 L1 descriptor.
  192. \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE.
  193. \return 0
  194. */
  195. __STATIC_INLINE int __xn_section(uint32_t *descriptor_l1, mmu_execute_Type xn)
  196. {
  197. *descriptor_l1 &= SECTION_XN_MASK;
  198. *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT);
  199. return 0;
  200. }
  201. /** \brief Set section domain
  202. The function sets section domain
  203. \param [out] descriptor_l1 L1 descriptor.
  204. \param [in] domain Section domain
  205. \return 0
  206. */
  207. __STATIC_INLINE int __domain_section(uint32_t *descriptor_l1, uint8_t domain)
  208. {
  209. *descriptor_l1 &= SECTION_DOMAIN_MASK;
  210. *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT);
  211. return 0;
  212. }
  213. /** \brief Set section parity check
  214. The function sets section parity check
  215. \param [out] descriptor_l1 L1 descriptor.
  216. \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED
  217. \return 0
  218. */
  219. __STATIC_INLINE int __p_section(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
  220. {
  221. *descriptor_l1 &= SECTION_P_MASK;
  222. *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
  223. return 0;
  224. }
  225. /** \brief Set section access privileges
  226. The function sets section access privileges
  227. \param [out] descriptor_l1 L1 descriptor.
  228. \param [in] user User Level Access: NO_ACCESS, RW, READ
  229. \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ
  230. \param [in] afe Access flag enable
  231. \return 0
  232. */
  233. __STATIC_INLINE int __ap_section(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe)
  234. {
  235. uint32_t ap = 0;
  236. if (afe == 0) { //full access
  237. if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
  238. else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
  239. else if ((priv == RW) && (user == READ)) { ap = 0x2; }
  240. else if ((priv == RW) && (user == RW)) { ap = 0x3; }
  241. else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
  242. else if ((priv == READ) && (user == READ)) { ap = 0x7; }
  243. }
  244. else { //Simplified access
  245. if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
  246. else if ((priv == RW) && (user == RW)) { ap = 0x3; }
  247. else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
  248. else if ((priv == READ) && (user == READ)) { ap = 0x7; }
  249. }
  250. *descriptor_l1 &= SECTION_AP_MASK;
  251. *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT;
  252. *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT;
  253. return 0;
  254. }
  255. /** \brief Set section shareability
  256. The function sets section shareability
  257. \param [out] descriptor_l1 L1 descriptor.
  258. \param [in] s_bit Section shareability: NON_SHARED, SHARED
  259. \return 0
  260. */
  261. __STATIC_INLINE int __shared_section(uint32_t *descriptor_l1, mmu_shared_Type s_bit)
  262. {
  263. *descriptor_l1 &= SECTION_S_MASK;
  264. *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT);
  265. return 0;
  266. }
  267. /** \brief Set section Global attribute
  268. The function sets section Global attribute
  269. \param [out] descriptor_l1 L1 descriptor.
  270. \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL
  271. \return 0
  272. */
  273. __STATIC_INLINE int __global_section(uint32_t *descriptor_l1, mmu_global_Type g_bit)
  274. {
  275. *descriptor_l1 &= SECTION_NG_MASK;
  276. *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT);
  277. return 0;
  278. }
  279. /** \brief Set section Security attribute
  280. The function sets section Global attribute
  281. \param [out] descriptor_l1 L1 descriptor.
  282. \param [in] s_bit Section Security attribute: SECURE, NON_SECURE
  283. \return 0
  284. */
  285. __STATIC_INLINE int __secure_section(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
  286. {
  287. *descriptor_l1 &= SECTION_NS_MASK;
  288. *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT);
  289. return 0;
  290. }
  291. /* Page 4k or 64k */
  292. /** \brief Set 4k/64k page execution-never attribute
  293. The function sets 4k/64k page execution-never attribute
  294. \param [out] descriptor_l2 L2 descriptor.
  295. \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE.
  296. \param [in] page Page size: PAGE_4k, PAGE_64k,
  297. \return 0
  298. */
  299. __STATIC_INLINE int __xn_page(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page)
  300. {
  301. if (page == PAGE_4k)
  302. {
  303. *descriptor_l2 &= PAGE_XN_4K_MASK;
  304. *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT);
  305. }
  306. else
  307. {
  308. *descriptor_l2 &= PAGE_XN_64K_MASK;
  309. *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT);
  310. }
  311. return 0;
  312. }
  313. /** \brief Set 4k/64k page domain
  314. The function sets 4k/64k page domain
  315. \param [out] descriptor_l1 L1 descriptor.
  316. \param [in] domain Page domain
  317. \return 0
  318. */
  319. __STATIC_INLINE int __domain_page(uint32_t *descriptor_l1, uint8_t domain)
  320. {
  321. *descriptor_l1 &= PAGE_DOMAIN_MASK;
  322. *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT);
  323. return 0;
  324. }
  325. /** \brief Set 4k/64k page parity check
  326. The function sets 4k/64k page parity check
  327. \param [out] descriptor_l1 L1 descriptor.
  328. \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED
  329. \return 0
  330. */
  331. __STATIC_INLINE int __p_page(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
  332. {
  333. *descriptor_l1 &= SECTION_P_MASK;
  334. *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
  335. return 0;
  336. }
  337. /** \brief Set 4k/64k page access privileges
  338. The function sets 4k/64k page access privileges
  339. \param [out] descriptor_l2 L2 descriptor.
  340. \param [in] user User Level Access: NO_ACCESS, RW, READ
  341. \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ
  342. \param [in] afe Access flag enable
  343. \return 0
  344. */
  345. __STATIC_INLINE int __ap_page(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe)
  346. {
  347. uint32_t ap = 0;
  348. if (afe == 0) { //full access
  349. if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
  350. else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
  351. else if ((priv == RW) && (user == READ)) { ap = 0x2; }
  352. else if ((priv == RW) && (user == RW)) { ap = 0x3; }
  353. else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
  354. else if ((priv == READ) && (user == READ)) { ap = 0x6; }
  355. }
  356. else { //Simplified access
  357. if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
  358. else if ((priv == RW) && (user == RW)) { ap = 0x3; }
  359. else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
  360. else if ((priv == READ) && (user == READ)) { ap = 0x7; }
  361. }
  362. *descriptor_l2 &= PAGE_AP_MASK;
  363. *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT;
  364. *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT;
  365. return 0;
  366. }
  367. /** \brief Set 4k/64k page shareability
  368. The function sets 4k/64k page shareability
  369. \param [out] descriptor_l2 L2 descriptor.
  370. \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED
  371. \return 0
  372. */
  373. __STATIC_INLINE int __shared_page(uint32_t *descriptor_l2, mmu_shared_Type s_bit)
  374. {
  375. *descriptor_l2 &= PAGE_S_MASK;
  376. *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT);
  377. return 0;
  378. }
  379. /** \brief Set 4k/64k page Global attribute
  380. The function sets 4k/64k page Global attribute
  381. \param [out] descriptor_l2 L2 descriptor.
  382. \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL
  383. \return 0
  384. */
  385. __STATIC_INLINE int __global_page(uint32_t *descriptor_l2, mmu_global_Type g_bit)
  386. {
  387. *descriptor_l2 &= PAGE_NG_MASK;
  388. *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT);
  389. return 0;
  390. }
  391. /** \brief Set 4k/64k page Security attribute
  392. The function sets 4k/64k page Global attribute
  393. \param [out] descriptor_l1 L1 descriptor.
  394. \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE
  395. \return 0
  396. */
  397. __STATIC_INLINE int __secure_page(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
  398. {
  399. *descriptor_l1 &= PAGE_NS_MASK;
  400. *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT);
  401. return 0;
  402. }
  403. /** \brief Set Section memory attributes
  404. The function sets section memory attributes
  405. \param [out] descriptor_l1 L1 descriptor.
  406. \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
  407. \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
  408. \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
  409. \return 0
  410. */
  411. __STATIC_INLINE int __memory_section(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner)
  412. {
  413. *descriptor_l1 &= SECTION_TEXCB_MASK;
  414. if (STRONGLY_ORDERED == mem)
  415. {
  416. return 0;
  417. }
  418. else if (SHARED_DEVICE == mem)
  419. {
  420. *descriptor_l1 |= (1 << SECTION_B_SHIFT);
  421. }
  422. else if (NON_SHARED_DEVICE == mem)
  423. {
  424. *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT);
  425. }
  426. else if (NORMAL == mem)
  427. {
  428. *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT;
  429. switch(inner)
  430. {
  431. case NON_CACHEABLE:
  432. break;
  433. case WB_WA:
  434. *descriptor_l1 |= (1 << SECTION_B_SHIFT);
  435. break;
  436. case WT:
  437. *descriptor_l1 |= 1 << SECTION_C_SHIFT;
  438. break;
  439. case WB_NO_WA:
  440. *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT);
  441. break;
  442. }
  443. switch(outer)
  444. {
  445. case NON_CACHEABLE:
  446. break;
  447. case WB_WA:
  448. *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT);
  449. break;
  450. case WT:
  451. *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT;
  452. break;
  453. case WB_NO_WA:
  454. *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT);
  455. break;
  456. }
  457. }
  458. return 0;
  459. }
  460. /** \brief Set 4k/64k page memory attributes
  461. The function sets 4k/64k page memory attributes
  462. \param [out] descriptor_l2 L2 descriptor.
  463. \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
  464. \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
  465. \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
  466. \return 0
  467. */
  468. __STATIC_INLINE int __memory_page(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page)
  469. {
  470. *descriptor_l2 &= PAGE_4K_TEXCB_MASK;
  471. if (page == PAGE_64k)
  472. {
  473. //same as section
  474. __memory_section(descriptor_l2, mem, outer, inner);
  475. }
  476. else
  477. {
  478. if (STRONGLY_ORDERED == mem)
  479. {
  480. return 0;
  481. }
  482. else if (SHARED_DEVICE == mem)
  483. {
  484. *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
  485. }
  486. else if (NON_SHARED_DEVICE == mem)
  487. {
  488. *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT);
  489. }
  490. else if (NORMAL == mem)
  491. {
  492. *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT;
  493. switch(inner)
  494. {
  495. case NON_CACHEABLE:
  496. break;
  497. case WB_WA:
  498. *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
  499. break;
  500. case WT:
  501. *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT;
  502. break;
  503. case WB_NO_WA:
  504. *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT);
  505. break;
  506. }
  507. switch(outer)
  508. {
  509. case NON_CACHEABLE:
  510. break;
  511. case WB_WA:
  512. *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT);
  513. break;
  514. case WT:
  515. *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT;
  516. break;
  517. case WB_NO_WA:
  518. *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT);
  519. break;
  520. }
  521. }
  522. }
  523. return 0;
  524. }
  525. /** \brief Create a L1 section descriptor
  526. The function creates a section descriptor.
  527. Assumptions:
  528. - 16MB super sections not supported
  529. - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
  530. - Functions always return 0
  531. \param [out] descriptor L1 descriptor
  532. \param [out] descriptor2 L2 descriptor
  533. \param [in] reg Section attributes
  534. \return 0
  535. */
  536. __STATIC_INLINE int __get_section_descriptor(uint32_t *descriptor, mmu_region_attributes_Type reg)
  537. {
  538. *descriptor = 0;
  539. __memory_section(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t);
  540. __xn_section(descriptor,reg.xn_t);
  541. __domain_section(descriptor, reg.domain);
  542. __p_section(descriptor, reg.e_t);
  543. __ap_section(descriptor, reg.priv_t, reg.user_t, 1);
  544. __shared_section(descriptor,reg.sh_t);
  545. __global_section(descriptor,reg.g_t);
  546. __secure_section(descriptor,reg.sec_t);
  547. *descriptor &= SECTION_MASK;
  548. *descriptor |= SECTION_DESCRIPTOR;
  549. return 0;
  550. }
  551. /** \brief Create a L1 and L2 4k/64k page descriptor
  552. The function creates a 4k/64k page descriptor.
  553. Assumptions:
  554. - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
  555. - Functions always return 0
  556. \param [out] descriptor L1 descriptor
  557. \param [out] descriptor2 L2 descriptor
  558. \param [in] reg 4k/64k page attributes
  559. \return 0
  560. */
  561. __STATIC_INLINE int __get_page_descriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg)
  562. {
  563. *descriptor = 0;
  564. *descriptor2 = 0;
  565. switch (reg.rg_t)
  566. {
  567. case PAGE_4k:
  568. __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k);
  569. __xn_page(descriptor2, reg.xn_t, PAGE_4k);
  570. __domain_page(descriptor, reg.domain);
  571. __p_page(descriptor, reg.e_t);
  572. __ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
  573. __shared_page(descriptor2,reg.sh_t);
  574. __global_page(descriptor2,reg.g_t);
  575. __secure_page(descriptor,reg.sec_t);
  576. *descriptor &= PAGE_L1_MASK;
  577. *descriptor |= PAGE_L1_DESCRIPTOR;
  578. *descriptor2 &= PAGE_L2_4K_MASK;
  579. *descriptor2 |= PAGE_L2_4K_DESC;
  580. break;
  581. case PAGE_64k:
  582. __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k);
  583. __xn_page(descriptor2, reg.xn_t, PAGE_64k);
  584. __domain_page(descriptor, reg.domain);
  585. __p_page(descriptor, reg.e_t);
  586. __ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
  587. __shared_page(descriptor2,reg.sh_t);
  588. __global_page(descriptor2,reg.g_t);
  589. __secure_page(descriptor,reg.sec_t);
  590. *descriptor &= PAGE_L1_MASK;
  591. *descriptor |= PAGE_L1_DESCRIPTOR;
  592. *descriptor2 &= PAGE_L2_64K_MASK;
  593. *descriptor2 |= PAGE_L2_64K_DESC;
  594. break;
  595. case SECTION:
  596. //error
  597. break;
  598. }
  599. return 0;
  600. }
  601. /** \brief Create a 1MB Section
  602. \param [in] ttb Translation table base address
  603. \param [in] base_address Section base address
  604. \param [in] count Number of sections to create
  605. \param [in] descriptor_l1 L1 descriptor (region attributes)
  606. */
  607. __STATIC_INLINE void __TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1)
  608. {
  609. uint32_t offset;
  610. uint32_t entry;
  611. uint32_t i;
  612. offset = base_address >> 20;
  613. entry = (base_address & 0xFFF00000) | descriptor_l1;
  614. //4 bytes aligned
  615. ttb = ttb + offset;
  616. for (i = 0; i < count; i++ )
  617. {
  618. //4 bytes aligned
  619. *ttb++ = entry;
  620. entry += OFFSET_1M;
  621. }
  622. }
  623. /** \brief Create a 4k page entry
  624. \param [in] ttb L1 table base address
  625. \param [in] base_address 4k base address
  626. \param [in] count Number of 4k pages to create
  627. \param [in] descriptor_l1 L1 descriptor (region attributes)
  628. \param [in] ttb_l2 L2 table base address
  629. \param [in] descriptor_l2 L2 descriptor (region attributes)
  630. */
  631. __STATIC_INLINE void __TTPage_4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
  632. {
  633. uint32_t offset, offset2;
  634. uint32_t entry, entry2;
  635. uint32_t i;
  636. offset = base_address >> 20;
  637. entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
  638. //4 bytes aligned
  639. ttb += offset;
  640. //create l1_entry
  641. *ttb = entry;
  642. offset2 = (base_address & 0xff000) >> 12;
  643. ttb_l2 += offset2;
  644. entry2 = (base_address & 0xFFFFF000) | descriptor_l2;
  645. for (i = 0; i < count; i++ )
  646. {
  647. //4 bytes aligned
  648. *ttb_l2++ = entry2;
  649. entry2 += OFFSET_4K;
  650. }
  651. }
  652. /** \brief Create a 64k page entry
  653. \param [in] ttb L1 table base address
  654. \param [in] base_address 64k base address
  655. \param [in] count Number of 64k pages to create
  656. \param [in] descriptor_l1 L1 descriptor (region attributes)
  657. \param [in] ttb_l2 L2 table base address
  658. \param [in] descriptor_l2 L2 descriptor (region attributes)
  659. */
  660. __STATIC_INLINE void __TTPage_64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
  661. {
  662. uint32_t offset, offset2;
  663. uint32_t entry, entry2;
  664. uint32_t i,j;
  665. offset = base_address >> 20;
  666. entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
  667. //4 bytes aligned
  668. ttb += offset;
  669. //create l1_entry
  670. *ttb = entry;
  671. offset2 = (base_address & 0xff000) >> 12;
  672. ttb_l2 += offset2;
  673. entry2 = (base_address & 0xFFFF0000) | descriptor_l2;
  674. for (i = 0; i < count; i++ )
  675. {
  676. //create 16 entries
  677. for (j = 0; j < 16; j++)
  678. //4 bytes aligned
  679. *ttb_l2++ = entry2;
  680. entry2 += OFFSET_64K;
  681. }
  682. }
  683. /*@} end of MMU_Functions */
  684. #endif
  685. #ifdef __cplusplus
  686. }
  687. #endif