mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

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 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