Naze32 clone with Frysky receiver
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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