[11U68]fix P0_11 to use GPIO
Fork of mbed-src by
Embed:
(wiki syntax)
Show/hide line numbers
core_ca_mmu.h
Go to the documentation of this file.
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 21:24:11 by 1.7.2