LCOV - code coverage report
Current view: top level - home/jason/ncs-2.0.0/modules/hal/cmsis/CMSIS/Core/Include - mpu_armv8.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 15 53.3 %
Date: 2022-08-18 11:36:24 Functions: 2 4 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * @file     mpu_armv8.h
       3                 :            :  * @brief    CMSIS MPU API for Armv8-M and Armv8.1-M MPU
       4                 :            :  * @version  V5.1.3
       5                 :            :  * @date     03. February 2021
       6                 :            :  ******************************************************************************/
       7                 :            : /*
       8                 :            :  * Copyright (c) 2017-2021 Arm Limited. All rights reserved.
       9                 :            :  *
      10                 :            :  * SPDX-License-Identifier: Apache-2.0
      11                 :            :  *
      12                 :            :  * Licensed under the Apache License, Version 2.0 (the License); you may
      13                 :            :  * not use this file except in compliance with the License.
      14                 :            :  * You may obtain a copy of the License at
      15                 :            :  *
      16                 :            :  * www.apache.org/licenses/LICENSE-2.0
      17                 :            :  *
      18                 :            :  * Unless required by applicable law or agreed to in writing, software
      19                 :            :  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
      20                 :            :  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      21                 :            :  * See the License for the specific language governing permissions and
      22                 :            :  * limitations under the License.
      23                 :            :  */
      24                 :            : 
      25                 :            : #if   defined ( __ICCARM__ )
      26                 :            :   #pragma system_include         /* treat file as system include file for MISRA check */
      27                 :            : #elif defined (__clang__)
      28                 :            :   #pragma clang system_header    /* treat file as system include file */
      29                 :            : #endif
      30                 :            : 
      31                 :            : #ifndef ARM_MPU_ARMV8_H
      32                 :            : #define ARM_MPU_ARMV8_H
      33                 :            : 
      34                 :            : /** \brief Attribute for device memory (outer only) */
      35                 :            : #define ARM_MPU_ATTR_DEVICE                           ( 0U )
      36                 :            : 
      37                 :            : /** \brief Attribute for non-cacheable, normal memory */
      38                 :            : #define ARM_MPU_ATTR_NON_CACHEABLE                    ( 4U )
      39                 :            : 
      40                 :            : /** \brief Attribute for normal memory (outer and inner)
      41                 :            : * \param NT Non-Transient: Set to 1 for non-transient data.
      42                 :            : * \param WB Write-Back: Set to 1 to use write-back update policy.
      43                 :            : * \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
      44                 :            : * \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
      45                 :            : */
      46                 :            : #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
      47                 :            :   ((((NT) & 1U) << 3U) | (((WB) & 1U) << 2U) | (((RA) & 1U) << 1U) | ((WA) & 1U))
      48                 :            : 
      49                 :            : /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
      50                 :            : #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
      51                 :            : 
      52                 :            : /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
      53                 :            : #define ARM_MPU_ATTR_DEVICE_nGnRE  (1U)
      54                 :            : 
      55                 :            : /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
      56                 :            : #define ARM_MPU_ATTR_DEVICE_nGRE   (2U)
      57                 :            : 
      58                 :            : /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
      59                 :            : #define ARM_MPU_ATTR_DEVICE_GRE    (3U)
      60                 :            : 
      61                 :            : /** \brief Memory Attribute
      62                 :            : * \param O Outer memory attributes
      63                 :            : * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
      64                 :            : */
      65                 :            : #define ARM_MPU_ATTR(O, I) ((((O) & 0xFU) << 4U) | ((((O) & 0xFU) != 0U) ? ((I) & 0xFU) : (((I) & 0x3U) << 2U)))
      66                 :            : 
      67                 :            : /** \brief Normal memory non-shareable  */
      68                 :            : #define ARM_MPU_SH_NON   (0U)
      69                 :            : 
      70                 :            : /** \brief Normal memory outer shareable  */
      71                 :            : #define ARM_MPU_SH_OUTER (2U)
      72                 :            : 
      73                 :            : /** \brief Normal memory inner shareable  */
      74                 :            : #define ARM_MPU_SH_INNER (3U)
      75                 :            : 
      76                 :            : /** \brief Memory access permissions
      77                 :            : * \param RO Read-Only: Set to 1 for read-only memory.
      78                 :            : * \param NP Non-Privileged: Set to 1 for non-privileged memory.
      79                 :            : */
      80                 :            : #define ARM_MPU_AP_(RO, NP) ((((RO) & 1U) << 1U) | ((NP) & 1U))
      81                 :            : 
      82                 :            : /** \brief Region Base Address Register value
      83                 :            : * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
      84                 :            : * \param SH Defines the Shareability domain for this memory region.
      85                 :            : * \param RO Read-Only: Set to 1 for a read-only memory region.
      86                 :            : * \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
      87                 :            : * \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
      88                 :            : */
      89                 :            : #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
      90                 :            :   (((BASE) & MPU_RBAR_BASE_Msk) | \
      91                 :            :   (((SH) << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
      92                 :            :   ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
      93                 :            :   (((XN) << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
      94                 :            : 
      95                 :            : /** \brief Region Limit Address Register value
      96                 :            : * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
      97                 :            : * \param IDX The attribute index to be associated with this memory region.
      98                 :            : */
      99                 :            : #define ARM_MPU_RLAR(LIMIT, IDX) \
     100                 :            :   (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
     101                 :            :   (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
     102                 :            :   (MPU_RLAR_EN_Msk))
     103                 :            : 
     104                 :            : #if defined(MPU_RLAR_PXN_Pos)
     105                 :            :   
     106                 :            : /** \brief Region Limit Address Register with PXN value
     107                 :            : * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
     108                 :            : * \param PXN Privileged execute never. Defines whether code can be executed from this privileged region.
     109                 :            : * \param IDX The attribute index to be associated with this memory region.
     110                 :            : */
     111                 :            : #define ARM_MPU_RLAR_PXN(LIMIT, PXN, IDX) \
     112                 :            :   (((LIMIT) & MPU_RLAR_LIMIT_Msk) | \
     113                 :            :   (((PXN) << MPU_RLAR_PXN_Pos) & MPU_RLAR_PXN_Msk) | \
     114                 :            :   (((IDX) << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
     115                 :            :   (MPU_RLAR_EN_Msk))
     116                 :            :   
     117                 :            : #endif
     118                 :            : 
     119                 :            : /**
     120                 :            : * Struct for a single MPU Region
     121                 :            : */
     122                 :            : typedef struct {
     123                 :            :   uint32_t RBAR;                   /*!< Region Base Address Register value */
     124                 :            :   uint32_t RLAR;                   /*!< Region Limit Address Register value */
     125                 :            : } ARM_MPU_Region_t;
     126                 :            :     
     127                 :            : /** Enable the MPU.
     128                 :            : * \param MPU_Control Default access permissions for unconfigured regions.
     129                 :            : */
     130                 :            : __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
     131                 :            : {
     132                 :            :   __DMB();
     133                 :            :   MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
     134                 :            : #ifdef SCB_SHCSR_MEMFAULTENA_Msk
     135                 :            :   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
     136                 :            : #endif
     137                 :            :   __DSB();
     138                 :            :   __ISB();
     139                 :            : }
     140                 :            : 
     141                 :            : /** Disable the MPU.
     142                 :            : */
     143                 :            : __STATIC_INLINE void ARM_MPU_Disable(void)
     144                 :            : {
     145                 :            :   __DMB();
     146                 :            : #ifdef SCB_SHCSR_MEMFAULTENA_Msk
     147                 :            :   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
     148                 :            : #endif
     149                 :            :   MPU->CTRL  &= ~MPU_CTRL_ENABLE_Msk;
     150                 :            :   __DSB();
     151                 :            :   __ISB();
     152                 :            : }
     153                 :            : 
     154                 :            : #ifdef MPU_NS
     155                 :            : /** Enable the Non-secure MPU.
     156                 :            : * \param MPU_Control Default access permissions for unconfigured regions.
     157                 :            : */
     158                 :            : __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
     159                 :            : {
     160                 :            :   __DMB();
     161                 :            :   MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
     162                 :            : #ifdef SCB_SHCSR_MEMFAULTENA_Msk
     163                 :            :   SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
     164                 :            : #endif
     165                 :            :   __DSB();
     166                 :            :   __ISB();
     167                 :            : }
     168                 :            : 
     169                 :            : /** Disable the Non-secure MPU.
     170                 :            : */
     171                 :            : __STATIC_INLINE void ARM_MPU_Disable_NS(void)
     172                 :            : {
     173                 :            :   __DMB();
     174                 :            : #ifdef SCB_SHCSR_MEMFAULTENA_Msk
     175                 :            :   SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
     176                 :            : #endif
     177                 :            :   MPU_NS->CTRL  &= ~MPU_CTRL_ENABLE_Msk;
     178                 :            :   __DSB();
     179                 :            :   __ISB();
     180                 :            : }
     181                 :            : #endif
     182                 :            : 
     183                 :            : /** Set the memory attribute encoding to the given MPU.
     184                 :            : * \param mpu Pointer to the MPU to be configured.
     185                 :            : * \param idx The attribute index to be set [0-7]
     186                 :            : * \param attr The attribute value to be set.
     187                 :            : */
     188                 :            : __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
     189                 :            : {
     190                 :            :   const uint8_t reg = idx / 4U;
     191                 :            :   const uint32_t pos = ((idx % 4U) * 8U);
     192                 :            :   const uint32_t mask = 0xFFU << pos;
     193                 :            :   
     194                 :            :   if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
     195                 :            :     return; // invalid index
     196                 :            :   }
     197                 :            :   
     198                 :            :   mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
     199                 :            : }
     200                 :            : 
     201                 :            : /** Set the memory attribute encoding.
     202                 :            : * \param idx The attribute index to be set [0-7]
     203                 :            : * \param attr The attribute value to be set.
     204                 :            : */
     205                 :            : __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
     206                 :            : {
     207                 :            :   ARM_MPU_SetMemAttrEx(MPU, idx, attr);
     208                 :            : }
     209                 :            : 
     210                 :            : #ifdef MPU_NS
     211                 :            : /** Set the memory attribute encoding to the Non-secure MPU.
     212                 :            : * \param idx The attribute index to be set [0-7]
     213                 :            : * \param attr The attribute value to be set.
     214                 :            : */
     215                 :            : __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
     216                 :            : {
     217                 :            :   ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
     218                 :            : }
     219                 :            : #endif
     220                 :            : 
     221                 :            : /** Clear and disable the given MPU region of the given MPU.
     222                 :            : * \param mpu Pointer to MPU to be used.
     223                 :            : * \param rnr Region number to be cleared.
     224                 :            : */
     225                 :          0 : __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
     226                 :            : {
     227                 :          0 :   mpu->RNR = rnr;
     228                 :          0 :   mpu->RLAR = 0U;
     229                 :          0 : }
     230                 :            : 
     231                 :            : /** Clear and disable the given MPU region.
     232                 :            : * \param rnr Region number to be cleared.
     233                 :            : */
     234                 :          0 : __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
     235                 :            : {
     236                 :          0 :   ARM_MPU_ClrRegionEx(MPU, rnr);
     237                 :          0 : }
     238                 :            : 
     239                 :            : #ifdef MPU_NS
     240                 :            : /** Clear and disable the given Non-secure MPU region.
     241                 :            : * \param rnr Region number to be cleared.
     242                 :            : */
     243                 :            : __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
     244                 :            : {  
     245                 :            :   ARM_MPU_ClrRegionEx(MPU_NS, rnr);
     246                 :            : }
     247                 :            : #endif
     248                 :            : 
     249                 :            : /** Configure the given MPU region of the given MPU.
     250                 :            : * \param mpu Pointer to MPU to be used.
     251                 :            : * \param rnr Region number to be configured.
     252                 :            : * \param rbar Value for RBAR register.
     253                 :            : * \param rlar Value for RLAR register.
     254                 :            : */   
     255                 :          2 : __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
     256                 :            : {
     257                 :          2 :   mpu->RNR = rnr;
     258                 :          2 :   mpu->RBAR = rbar;
     259                 :          2 :   mpu->RLAR = rlar;
     260                 :          2 : }
     261                 :            : 
     262                 :            : /** Configure the given MPU region.
     263                 :            : * \param rnr Region number to be configured.
     264                 :            : * \param rbar Value for RBAR register.
     265                 :            : * \param rlar Value for RLAR register.
     266                 :            : */   
     267                 :          2 : __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
     268                 :            : {
     269                 :          2 :   ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
     270                 :          2 : }
     271                 :            : 
     272                 :            : #ifdef MPU_NS
     273                 :            : /** Configure the given Non-secure MPU region.
     274                 :            : * \param rnr Region number to be configured.
     275                 :            : * \param rbar Value for RBAR register.
     276                 :            : * \param rlar Value for RLAR register.
     277                 :            : */   
     278                 :            : __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
     279                 :            : {
     280                 :            :   ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);  
     281                 :            : }
     282                 :            : #endif
     283                 :            : 
     284                 :            : /** Memcpy with strictly ordered memory access, e.g. used by code in ARM_MPU_LoadEx()
     285                 :            : * \param dst Destination data is copied to.
     286                 :            : * \param src Source data is copied from.
     287                 :            : * \param len Amount of data words to be copied.
     288                 :            : */
     289                 :            : __STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
     290                 :            : {
     291                 :            :   uint32_t i;
     292                 :            :   for (i = 0U; i < len; ++i) 
     293                 :            :   {
     294                 :            :     dst[i] = src[i];
     295                 :            :   }
     296                 :            : }
     297                 :            : 
     298                 :            : /** Load the given number of MPU regions from a table to the given MPU.
     299                 :            : * \param mpu Pointer to the MPU registers to be used.
     300                 :            : * \param rnr First region number to be configured.
     301                 :            : * \param table Pointer to the MPU configuration table.
     302                 :            : * \param cnt Amount of regions to be configured.
     303                 :            : */
     304                 :            : __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 
     305                 :            : {
     306                 :            :   const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
     307                 :            :   if (cnt == 1U) {
     308                 :            :     mpu->RNR = rnr;
     309                 :            :     ARM_MPU_OrderedMemcpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
     310                 :            :   } else {
     311                 :            :     uint32_t rnrBase   = rnr & ~(MPU_TYPE_RALIASES-1U);
     312                 :            :     uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
     313                 :            :     
     314                 :            :     mpu->RNR = rnrBase;
     315                 :            :     while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
     316                 :            :       uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
     317                 :            :       ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
     318                 :            :       table += c;
     319                 :            :       cnt -= c;
     320                 :            :       rnrOffset = 0U;
     321                 :            :       rnrBase += MPU_TYPE_RALIASES;
     322                 :            :       mpu->RNR = rnrBase;
     323                 :            :     }
     324                 :            :     
     325                 :            :     ARM_MPU_OrderedMemcpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
     326                 :            :   }
     327                 :            : }
     328                 :            : 
     329                 :            : /** Load the given number of MPU regions from a table.
     330                 :            : * \param rnr First region number to be configured.
     331                 :            : * \param table Pointer to the MPU configuration table.
     332                 :            : * \param cnt Amount of regions to be configured.
     333                 :            : */
     334                 :            : __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 
     335                 :            : {
     336                 :            :   ARM_MPU_LoadEx(MPU, rnr, table, cnt);
     337                 :            : }
     338                 :            : 
     339                 :            : #ifdef MPU_NS
     340                 :            : /** Load the given number of MPU regions from a table to the Non-secure MPU.
     341                 :            : * \param rnr First region number to be configured.
     342                 :            : * \param table Pointer to the MPU configuration table.
     343                 :            : * \param cnt Amount of regions to be configured.
     344                 :            : */
     345                 :            : __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 
     346                 :            : {
     347                 :            :   ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
     348                 :            : }
     349                 :            : #endif
     350                 :            : 
     351                 :            : #endif
     352                 :            : 

Generated by: LCOV version 1.14