Lancaster University's (short term!) clone of mbed-src for micro:bit. This is a copy of the github branch https://github.com/lancaster-university/mbed-classic
Fork of mbed-src 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 21:24:11 by 1.7.2