mbed library sources

Fork of mbed-src by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers core_ca_mmu.h Source File

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