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