Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
core_ca_mmu.h
00001 ;/**************************************************************************//** 00002 ; * @file core_ca_mmu.h 00003 ; * @brief MMU Startup File for A9_MP Device Series 00004 ; * @version V1.01 00005 ; * @date 10 Sept 2014 00006 ; * 00007 ; * @note 00008 ; * 00009 ; ******************************************************************************/ 00010 ;/* Copyright (c) 2012-2014 ARM LIMITED 00011 ; 00012 ; All rights reserved. 00013 ; Redistribution and use in source and binary forms, with or without 00014 ; modification, are permitted provided that the following conditions are met: 00015 ; - Redistributions of source code must retain the above copyright 00016 ; notice, this list of conditions and the following disclaimer. 00017 ; - Redistributions in binary form must reproduce the above copyright 00018 ; notice, this list of conditions and the following disclaimer in the 00019 ; documentation and/or other materials provided with the distribution. 00020 ; - Neither the name of ARM nor the names of its contributors may be used 00021 ; to endorse or promote products derived from this software without 00022 ; specific prior written permission. 00023 ; * 00024 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 ; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00027 ; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00028 ; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00029 ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00030 ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00031 ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00032 ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00033 ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 ; POSSIBILITY OF SUCH DAMAGE. 00035 ; ---------------------------------------------------------------------------*/ 00036 00037 #ifdef __cplusplus 00038 extern "C" { 00039 #endif 00040 00041 #ifndef _MMU_FUNC_H 00042 #define _MMU_FUNC_H 00043 00044 #define SECTION_DESCRIPTOR (0x2) 00045 #define SECTION_MASK (0xFFFFFFFC) 00046 00047 #define SECTION_TEXCB_MASK (0xFFFF8FF3) 00048 #define SECTION_B_SHIFT (2) 00049 #define SECTION_C_SHIFT (3) 00050 #define SECTION_TEX0_SHIFT (12) 00051 #define SECTION_TEX1_SHIFT (13) 00052 #define SECTION_TEX2_SHIFT (14) 00053 00054 #define SECTION_XN_MASK (0xFFFFFFEF) 00055 #define SECTION_XN_SHIFT (4) 00056 00057 #define SECTION_DOMAIN_MASK (0xFFFFFE1F) 00058 #define SECTION_DOMAIN_SHIFT (5) 00059 00060 #define SECTION_P_MASK (0xFFFFFDFF) 00061 #define SECTION_P_SHIFT (9) 00062 00063 #define SECTION_AP_MASK (0xFFFF73FF) 00064 #define SECTION_AP_SHIFT (10) 00065 #define SECTION_AP2_SHIFT (15) 00066 00067 #define SECTION_S_MASK (0xFFFEFFFF) 00068 #define SECTION_S_SHIFT (16) 00069 00070 #define SECTION_NG_MASK (0xFFFDFFFF) 00071 #define SECTION_NG_SHIFT (17) 00072 00073 #define SECTION_NS_MASK (0xFFF7FFFF) 00074 #define SECTION_NS_SHIFT (19) 00075 00076 00077 #define PAGE_L1_DESCRIPTOR (0x1) 00078 #define PAGE_L1_MASK (0xFFFFFFFC) 00079 00080 #define PAGE_L2_4K_DESC (0x2) 00081 #define PAGE_L2_4K_MASK (0xFFFFFFFD) 00082 00083 #define PAGE_L2_64K_DESC (0x1) 00084 #define PAGE_L2_64K_MASK (0xFFFFFFFC) 00085 00086 #define PAGE_4K_TEXCB_MASK (0xFFFFFE33) 00087 #define PAGE_4K_B_SHIFT (2) 00088 #define PAGE_4K_C_SHIFT (3) 00089 #define PAGE_4K_TEX0_SHIFT (6) 00090 #define PAGE_4K_TEX1_SHIFT (7) 00091 #define PAGE_4K_TEX2_SHIFT (8) 00092 00093 #define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) 00094 #define PAGE_64K_B_SHIFT (2) 00095 #define PAGE_64K_C_SHIFT (3) 00096 #define PAGE_64K_TEX0_SHIFT (12) 00097 #define PAGE_64K_TEX1_SHIFT (13) 00098 #define PAGE_64K_TEX2_SHIFT (14) 00099 00100 #define PAGE_TEXCB_MASK (0xFFFF8FF3) 00101 #define PAGE_B_SHIFT (2) 00102 #define PAGE_C_SHIFT (3) 00103 #define PAGE_TEX_SHIFT (12) 00104 00105 #define PAGE_XN_4K_MASK (0xFFFFFFFE) 00106 #define PAGE_XN_4K_SHIFT (0) 00107 #define PAGE_XN_64K_MASK (0xFFFF7FFF) 00108 #define PAGE_XN_64K_SHIFT (15) 00109 00110 00111 #define PAGE_DOMAIN_MASK (0xFFFFFE1F) 00112 #define PAGE_DOMAIN_SHIFT (5) 00113 00114 #define PAGE_P_MASK (0xFFFFFDFF) 00115 #define PAGE_P_SHIFT (9) 00116 00117 #define PAGE_AP_MASK (0xFFFFFDCF) 00118 #define PAGE_AP_SHIFT (4) 00119 #define PAGE_AP2_SHIFT (9) 00120 00121 #define PAGE_S_MASK (0xFFFFFBFF) 00122 #define PAGE_S_SHIFT (10) 00123 00124 #define PAGE_NG_MASK (0xFFFFF7FF) 00125 #define PAGE_NG_SHIFT (11) 00126 00127 #define PAGE_NS_MASK (0xFFFFFFF7) 00128 #define PAGE_NS_SHIFT (3) 00129 00130 #define OFFSET_1M (0x00100000) 00131 #define OFFSET_64K (0x00010000) 00132 #define OFFSET_4K (0x00001000) 00133 00134 #define DESCRIPTOR_FAULT (0x00000000) 00135 00136 /* ########################### MMU Function Access ########################### */ 00137 /** \ingroup MMU_FunctionInterface 00138 \defgroup MMU_Functions MMU Functions Interface 00139 @{ 00140 */ 00141 00142 /* Attributes enumerations */ 00143 00144 /* Region size attributes */ 00145 typedef enum 00146 { 00147 SECTION, 00148 PAGE_4k, 00149 PAGE_64k, 00150 } mmu_region_size_Type; 00151 00152 /* Region type attributes */ 00153 typedef enum 00154 { 00155 NORMAL, 00156 DEVICE, 00157 SHARED_DEVICE, 00158 NON_SHARED_DEVICE, 00159 STRONGLY_ORDERED 00160 } mmu_memory_Type; 00161 00162 /* Region cacheability attributes */ 00163 typedef enum 00164 { 00165 NON_CACHEABLE, 00166 WB_WA, 00167 WT, 00168 WB_NO_WA, 00169 } mmu_cacheability_Type; 00170 00171 /* Region parity check attributes */ 00172 typedef enum 00173 { 00174 ECC_DISABLED, 00175 ECC_ENABLED, 00176 } mmu_ecc_check_Type; 00177 00178 /* Region execution attributes */ 00179 typedef enum 00180 { 00181 EXECUTE, 00182 NON_EXECUTE, 00183 } mmu_execute_Type; 00184 00185 /* Region global attributes */ 00186 typedef enum 00187 { 00188 GLOBAL, 00189 NON_GLOBAL, 00190 } mmu_global_Type; 00191 00192 /* Region shareability attributes */ 00193 typedef enum 00194 { 00195 NON_SHARED, 00196 SHARED, 00197 } mmu_shared_Type; 00198 00199 /* Region security attributes */ 00200 typedef enum 00201 { 00202 SECURE, 00203 NON_SECURE, 00204 } mmu_secure_Type; 00205 00206 /* Region access attributes */ 00207 typedef enum 00208 { 00209 NO_ACCESS, 00210 RW, 00211 READ, 00212 } mmu_access_Type; 00213 00214 /* Memory Region definition */ 00215 typedef struct RegionStruct { 00216 mmu_region_size_Type rg_t; 00217 mmu_memory_Type mem_t; 00218 uint8_t domain; 00219 mmu_cacheability_Type inner_norm_t; 00220 mmu_cacheability_Type outer_norm_t; 00221 mmu_ecc_check_Type e_t; 00222 mmu_execute_Type xn_t; 00223 mmu_global_Type g_t; 00224 mmu_secure_Type sec_t; 00225 mmu_access_Type priv_t; 00226 mmu_access_Type user_t; 00227 mmu_shared_Type sh_t; 00228 00229 } mmu_region_attributes_Type; 00230 00231 /** \brief Set section execution-never attribute 00232 00233 The function sets section execution-never attribute 00234 00235 \param [out] descriptor_l1 L1 descriptor. 00236 \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. 00237 00238 \return 0 00239 */ 00240 __STATIC_INLINE int __xn_section(uint32_t *descriptor_l1, mmu_execute_Type xn) 00241 { 00242 *descriptor_l1 &= SECTION_XN_MASK; 00243 *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); 00244 return 0; 00245 } 00246 00247 /** \brief Set section domain 00248 00249 The function sets section domain 00250 00251 \param [out] descriptor_l1 L1 descriptor. 00252 \param [in] domain Section domain 00253 00254 \return 0 00255 */ 00256 __STATIC_INLINE int __domain_section(uint32_t *descriptor_l1, uint8_t domain) 00257 { 00258 *descriptor_l1 &= SECTION_DOMAIN_MASK; 00259 *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); 00260 return 0; 00261 } 00262 00263 /** \brief Set section parity check 00264 00265 The function sets section parity check 00266 00267 \param [out] descriptor_l1 L1 descriptor. 00268 \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED 00269 00270 \return 0 00271 */ 00272 __STATIC_INLINE int __p_section(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) 00273 { 00274 *descriptor_l1 &= SECTION_P_MASK; 00275 *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); 00276 return 0; 00277 } 00278 00279 /** \brief Set section access privileges 00280 00281 The function sets section access privileges 00282 00283 \param [out] descriptor_l1 L1 descriptor. 00284 \param [in] user User Level Access: NO_ACCESS, RW, READ 00285 \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ 00286 \param [in] afe Access flag enable 00287 00288 \return 0 00289 */ 00290 __STATIC_INLINE int __ap_section(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) 00291 { 00292 uint32_t ap = 0; 00293 00294 if (afe == 0) { //full access 00295 if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } 00296 else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 00297 else if ((priv == RW) && (user == READ)) { ap = 0x2; } 00298 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 00299 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 00300 else if ((priv == READ) && (user == READ)) { ap = 0x7; } 00301 } 00302 00303 else { //Simplified access 00304 if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 00305 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 00306 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 00307 else if ((priv == READ) && (user == READ)) { ap = 0x7; } 00308 } 00309 00310 *descriptor_l1 &= SECTION_AP_MASK; 00311 *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; 00312 *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; 00313 00314 return 0; 00315 } 00316 00317 /** \brief Set section shareability 00318 00319 The function sets section shareability 00320 00321 \param [out] descriptor_l1 L1 descriptor. 00322 \param [in] s_bit Section shareability: NON_SHARED, SHARED 00323 00324 \return 0 00325 */ 00326 __STATIC_INLINE int __shared_section(uint32_t *descriptor_l1, mmu_shared_Type s_bit) 00327 { 00328 *descriptor_l1 &= SECTION_S_MASK; 00329 *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); 00330 return 0; 00331 } 00332 00333 /** \brief Set section Global attribute 00334 00335 The function sets section Global attribute 00336 00337 \param [out] descriptor_l1 L1 descriptor. 00338 \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL 00339 00340 \return 0 00341 */ 00342 __STATIC_INLINE int __global_section(uint32_t *descriptor_l1, mmu_global_Type g_bit) 00343 { 00344 *descriptor_l1 &= SECTION_NG_MASK; 00345 *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); 00346 return 0; 00347 } 00348 00349 /** \brief Set section Security attribute 00350 00351 The function sets section Global attribute 00352 00353 \param [out] descriptor_l1 L1 descriptor. 00354 \param [in] s_bit Section Security attribute: SECURE, NON_SECURE 00355 00356 \return 0 00357 */ 00358 __STATIC_INLINE int __secure_section(uint32_t *descriptor_l1, mmu_secure_Type s_bit) 00359 { 00360 *descriptor_l1 &= SECTION_NS_MASK; 00361 *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); 00362 return 0; 00363 } 00364 00365 /* Page 4k or 64k */ 00366 /** \brief Set 4k/64k page execution-never attribute 00367 00368 The function sets 4k/64k page execution-never attribute 00369 00370 \param [out] descriptor_l2 L2 descriptor. 00371 \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. 00372 \param [in] page Page size: PAGE_4k, PAGE_64k, 00373 00374 \return 0 00375 */ 00376 __STATIC_INLINE int __xn_page(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) 00377 { 00378 if (page == PAGE_4k) 00379 { 00380 *descriptor_l2 &= PAGE_XN_4K_MASK; 00381 *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); 00382 } 00383 else 00384 { 00385 *descriptor_l2 &= PAGE_XN_64K_MASK; 00386 *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); 00387 } 00388 return 0; 00389 } 00390 00391 /** \brief Set 4k/64k page domain 00392 00393 The function sets 4k/64k page domain 00394 00395 \param [out] descriptor_l1 L1 descriptor. 00396 \param [in] domain Page domain 00397 00398 \return 0 00399 */ 00400 __STATIC_INLINE int __domain_page(uint32_t *descriptor_l1, uint8_t domain) 00401 { 00402 *descriptor_l1 &= PAGE_DOMAIN_MASK; 00403 *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); 00404 return 0; 00405 } 00406 00407 /** \brief Set 4k/64k page parity check 00408 00409 The function sets 4k/64k page parity check 00410 00411 \param [out] descriptor_l1 L1 descriptor. 00412 \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED 00413 00414 \return 0 00415 */ 00416 __STATIC_INLINE int __p_page(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) 00417 { 00418 *descriptor_l1 &= SECTION_P_MASK; 00419 *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); 00420 return 0; 00421 } 00422 00423 /** \brief Set 4k/64k page access privileges 00424 00425 The function sets 4k/64k page access privileges 00426 00427 \param [out] descriptor_l2 L2 descriptor. 00428 \param [in] user User Level Access: NO_ACCESS, RW, READ 00429 \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ 00430 \param [in] afe Access flag enable 00431 00432 \return 0 00433 */ 00434 __STATIC_INLINE int __ap_page(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) 00435 { 00436 uint32_t ap = 0; 00437 00438 if (afe == 0) { //full access 00439 if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } 00440 else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 00441 else if ((priv == RW) && (user == READ)) { ap = 0x2; } 00442 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 00443 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 00444 else if ((priv == READ) && (user == READ)) { ap = 0x6; } 00445 } 00446 00447 else { //Simplified access 00448 if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } 00449 else if ((priv == RW) && (user == RW)) { ap = 0x3; } 00450 else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } 00451 else if ((priv == READ) && (user == READ)) { ap = 0x7; } 00452 } 00453 00454 *descriptor_l2 &= PAGE_AP_MASK; 00455 *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; 00456 *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; 00457 00458 return 0; 00459 } 00460 00461 /** \brief Set 4k/64k page shareability 00462 00463 The function sets 4k/64k page shareability 00464 00465 \param [out] descriptor_l2 L2 descriptor. 00466 \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED 00467 00468 \return 0 00469 */ 00470 __STATIC_INLINE int __shared_page(uint32_t *descriptor_l2, mmu_shared_Type s_bit) 00471 { 00472 *descriptor_l2 &= PAGE_S_MASK; 00473 *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); 00474 return 0; 00475 } 00476 00477 /** \brief Set 4k/64k page Global attribute 00478 00479 The function sets 4k/64k page Global attribute 00480 00481 \param [out] descriptor_l2 L2 descriptor. 00482 \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL 00483 00484 \return 0 00485 */ 00486 __STATIC_INLINE int __global_page(uint32_t *descriptor_l2, mmu_global_Type g_bit) 00487 { 00488 *descriptor_l2 &= PAGE_NG_MASK; 00489 *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); 00490 return 0; 00491 } 00492 00493 /** \brief Set 4k/64k page Security attribute 00494 00495 The function sets 4k/64k page Global attribute 00496 00497 \param [out] descriptor_l1 L1 descriptor. 00498 \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE 00499 00500 \return 0 00501 */ 00502 __STATIC_INLINE int __secure_page(uint32_t *descriptor_l1, mmu_secure_Type s_bit) 00503 { 00504 *descriptor_l1 &= PAGE_NS_MASK; 00505 *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); 00506 return 0; 00507 } 00508 00509 00510 /** \brief Set Section memory attributes 00511 00512 The function sets section memory attributes 00513 00514 \param [out] descriptor_l1 L1 descriptor. 00515 \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED 00516 \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 00517 \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 00518 00519 \return 0 00520 */ 00521 __STATIC_INLINE int __memory_section(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) 00522 { 00523 *descriptor_l1 &= SECTION_TEXCB_MASK; 00524 00525 if (STRONGLY_ORDERED == mem) 00526 { 00527 return 0; 00528 } 00529 else if (SHARED_DEVICE == mem) 00530 { 00531 *descriptor_l1 |= (1 << SECTION_B_SHIFT); 00532 } 00533 else if (NON_SHARED_DEVICE == mem) 00534 { 00535 *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); 00536 } 00537 else if (NORMAL == mem) 00538 { 00539 *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; 00540 switch(inner) 00541 { 00542 case NON_CACHEABLE: 00543 break; 00544 case WB_WA: 00545 *descriptor_l1 |= (1 << SECTION_B_SHIFT); 00546 break; 00547 case WT: 00548 *descriptor_l1 |= 1 << SECTION_C_SHIFT; 00549 break; 00550 case WB_NO_WA: 00551 *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); 00552 break; 00553 } 00554 switch(outer) 00555 { 00556 case NON_CACHEABLE: 00557 break; 00558 case WB_WA: 00559 *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); 00560 break; 00561 case WT: 00562 *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; 00563 break; 00564 case WB_NO_WA: 00565 *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); 00566 break; 00567 } 00568 } 00569 00570 return 0; 00571 } 00572 00573 /** \brief Set 4k/64k page memory attributes 00574 00575 The function sets 4k/64k page memory attributes 00576 00577 \param [out] descriptor_l2 L2 descriptor. 00578 \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED 00579 \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 00580 \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, 00581 00582 \return 0 00583 */ 00584 __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) 00585 { 00586 *descriptor_l2 &= PAGE_4K_TEXCB_MASK; 00587 00588 if (page == PAGE_64k) 00589 { 00590 //same as section 00591 __memory_section(descriptor_l2, mem, outer, inner); 00592 } 00593 else 00594 { 00595 if (STRONGLY_ORDERED == mem) 00596 { 00597 return 0; 00598 } 00599 else if (SHARED_DEVICE == mem) 00600 { 00601 *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); 00602 } 00603 else if (NON_SHARED_DEVICE == mem) 00604 { 00605 *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); 00606 } 00607 else if (NORMAL == mem) 00608 { 00609 *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; 00610 switch(inner) 00611 { 00612 case NON_CACHEABLE: 00613 break; 00614 case WB_WA: 00615 *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); 00616 break; 00617 case WT: 00618 *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; 00619 break; 00620 case WB_NO_WA: 00621 *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); 00622 break; 00623 } 00624 switch(outer) 00625 { 00626 case NON_CACHEABLE: 00627 break; 00628 case WB_WA: 00629 *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); 00630 break; 00631 case WT: 00632 *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; 00633 break; 00634 case WB_NO_WA: 00635 *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT); 00636 break; 00637 } 00638 } 00639 } 00640 00641 return 0; 00642 } 00643 00644 /** \brief Create a L1 section descriptor 00645 00646 The function creates a section descriptor. 00647 00648 Assumptions: 00649 - 16MB super sections not supported 00650 - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor 00651 - Functions always return 0 00652 00653 \param [out] descriptor L1 descriptor 00654 \param [out] descriptor2 L2 descriptor 00655 \param [in] reg Section attributes 00656 00657 \return 0 00658 */ 00659 __STATIC_INLINE int __get_section_descriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) 00660 { 00661 *descriptor = 0; 00662 00663 __memory_section(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); 00664 __xn_section(descriptor,reg.xn_t); 00665 __domain_section(descriptor, reg.domain); 00666 __p_section(descriptor, reg.e_t); 00667 __ap_section(descriptor, reg.priv_t, reg.user_t, 1); 00668 __shared_section(descriptor,reg.sh_t); 00669 __global_section(descriptor,reg.g_t); 00670 __secure_section(descriptor,reg.sec_t); 00671 *descriptor &= SECTION_MASK; 00672 *descriptor |= SECTION_DESCRIPTOR; 00673 00674 return 0; 00675 00676 } 00677 00678 00679 /** \brief Create a L1 and L2 4k/64k page descriptor 00680 00681 The function creates a 4k/64k page descriptor. 00682 Assumptions: 00683 - TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor 00684 - Functions always return 0 00685 00686 \param [out] descriptor L1 descriptor 00687 \param [out] descriptor2 L2 descriptor 00688 \param [in] reg 4k/64k page attributes 00689 00690 \return 0 00691 */ 00692 __STATIC_INLINE int __get_page_descriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) 00693 { 00694 *descriptor = 0; 00695 *descriptor2 = 0; 00696 00697 switch (reg.rg_t) 00698 { 00699 case PAGE_4k: 00700 __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); 00701 __xn_page(descriptor2, reg.xn_t, PAGE_4k); 00702 __domain_page(descriptor, reg.domain); 00703 __p_page(descriptor, reg.e_t); 00704 __ap_page(descriptor2, reg.priv_t, reg.user_t, 1); 00705 __shared_page(descriptor2,reg.sh_t); 00706 __global_page(descriptor2,reg.g_t); 00707 __secure_page(descriptor,reg.sec_t); 00708 *descriptor &= PAGE_L1_MASK; 00709 *descriptor |= PAGE_L1_DESCRIPTOR; 00710 *descriptor2 &= PAGE_L2_4K_MASK; 00711 *descriptor2 |= PAGE_L2_4K_DESC; 00712 break; 00713 00714 case PAGE_64k: 00715 __memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); 00716 __xn_page(descriptor2, reg.xn_t, PAGE_64k); 00717 __domain_page(descriptor, reg.domain); 00718 __p_page(descriptor, reg.e_t); 00719 __ap_page(descriptor2, reg.priv_t, reg.user_t, 1); 00720 __shared_page(descriptor2,reg.sh_t); 00721 __global_page(descriptor2,reg.g_t); 00722 __secure_page(descriptor,reg.sec_t); 00723 *descriptor &= PAGE_L1_MASK; 00724 *descriptor |= PAGE_L1_DESCRIPTOR; 00725 *descriptor2 &= PAGE_L2_64K_MASK; 00726 *descriptor2 |= PAGE_L2_64K_DESC; 00727 break; 00728 00729 case SECTION: 00730 //error 00731 break; 00732 00733 } 00734 00735 return 0; 00736 00737 } 00738 00739 /** \brief Create a 1MB Section 00740 00741 \param [in] ttb Translation table base address 00742 \param [in] base_address Section base address 00743 \param [in] count Number of sections to create 00744 \param [in] descriptor_l1 L1 descriptor (region attributes) 00745 00746 */ 00747 __STATIC_INLINE void __TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) 00748 { 00749 uint32_t offset; 00750 uint32_t entry; 00751 uint32_t i; 00752 00753 offset = base_address >> 20; 00754 entry = (base_address & 0xFFF00000) | descriptor_l1; 00755 00756 //4 bytes aligned 00757 ttb = ttb + offset; 00758 00759 for (i = 0; i < count; i++ ) 00760 { 00761 //4 bytes aligned 00762 *ttb++ = entry; 00763 entry += OFFSET_1M; 00764 } 00765 } 00766 00767 /** \brief Create a 4k page entry 00768 00769 \param [in] ttb L1 table base address 00770 \param [in] base_address 4k base address 00771 \param [in] count Number of 4k pages to create 00772 \param [in] descriptor_l1 L1 descriptor (region attributes) 00773 \param [in] ttb_l2 L2 table base address 00774 \param [in] descriptor_l2 L2 descriptor (region attributes) 00775 00776 */ 00777 __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 ) 00778 { 00779 00780 uint32_t offset, offset2; 00781 uint32_t entry, entry2; 00782 uint32_t i; 00783 00784 00785 offset = base_address >> 20; 00786 entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; 00787 00788 //4 bytes aligned 00789 ttb += offset; 00790 //create l1_entry 00791 *ttb = entry; 00792 00793 offset2 = (base_address & 0xff000) >> 12; 00794 ttb_l2 += offset2; 00795 entry2 = (base_address & 0xFFFFF000) | descriptor_l2; 00796 for (i = 0; i < count; i++ ) 00797 { 00798 //4 bytes aligned 00799 *ttb_l2++ = entry2; 00800 entry2 += OFFSET_4K; 00801 } 00802 } 00803 00804 /** \brief Create a 64k page entry 00805 00806 \param [in] ttb L1 table base address 00807 \param [in] base_address 64k base address 00808 \param [in] count Number of 64k pages to create 00809 \param [in] descriptor_l1 L1 descriptor (region attributes) 00810 \param [in] ttb_l2 L2 table base address 00811 \param [in] descriptor_l2 L2 descriptor (region attributes) 00812 00813 */ 00814 __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 ) 00815 { 00816 uint32_t offset, offset2; 00817 uint32_t entry, entry2; 00818 uint32_t i,j; 00819 00820 00821 offset = base_address >> 20; 00822 entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; 00823 00824 //4 bytes aligned 00825 ttb += offset; 00826 //create l1_entry 00827 *ttb = entry; 00828 00829 offset2 = (base_address & 0xff000) >> 12; 00830 ttb_l2 += offset2; 00831 entry2 = (base_address & 0xFFFF0000) | descriptor_l2; 00832 for (i = 0; i < count; i++ ) 00833 { 00834 //create 16 entries 00835 for (j = 0; j < 16; j++) 00836 //4 bytes aligned 00837 *ttb_l2++ = entry2; 00838 entry2 += OFFSET_64K; 00839 } 00840 } 00841 00842 /*@} end of MMU_Functions */ 00843 #endif 00844 00845 #ifdef __cplusplus 00846 } 00847 #endif
Generated on Tue Jul 12 2022 23:05:49 by
