Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
mpu_armv8.h
00001 /****************************************************************************** 00002 * @file mpu_armv8.h 00003 * @brief CMSIS MPU API for Armv8-M MPU 00004 * @version V5.0.4 00005 * @date 10. January 2018 00006 ******************************************************************************/ 00007 /* 00008 * Copyright (c) 2017-2018 Arm Limited. All rights reserved. 00009 * 00010 * SPDX-License-Identifier: Apache-2.0 00011 * 00012 * Licensed under the Apache License, Version 2.0 (the License); you may 00013 * not use this file except in compliance with the License. 00014 * You may obtain a copy of the License at 00015 * 00016 * www.apache.org/licenses/LICENSE-2.0 00017 * 00018 * Unless required by applicable law or agreed to in writing, software 00019 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00020 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 * See the License for the specific language governing permissions and 00022 * limitations under the License. 00023 */ 00024 00025 #if defined ( __ICCARM__ ) 00026 #pragma system_include /* treat file as system include file for MISRA check */ 00027 #elif defined (__clang__) 00028 #pragma clang system_header /* treat file as system include file */ 00029 #endif 00030 00031 #ifndef ARM_MPU_ARMV8_H 00032 #define ARM_MPU_ARMV8_H 00033 00034 /** \brief Attribute for device memory (outer only) */ 00035 #define ARM_MPU_ATTR_DEVICE ( 0U ) 00036 00037 /** \brief Attribute for non-cacheable, normal memory */ 00038 #define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) 00039 00040 /** \brief Attribute for normal memory (outer and inner) 00041 * \param NT Non-Transient: Set to 1 for non-transient data. 00042 * \param WB Write-Back: Set to 1 to use write-back update policy. 00043 * \param RA Read Allocation: Set to 1 to use cache allocation on read miss. 00044 * \param WA Write Allocation: Set to 1 to use cache allocation on write miss. 00045 */ 00046 #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ 00047 (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) 00048 00049 /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ 00050 #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) 00051 00052 /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ 00053 #define ARM_MPU_ATTR_DEVICE_nGnRE (1U) 00054 00055 /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ 00056 #define ARM_MPU_ATTR_DEVICE_nGRE (2U) 00057 00058 /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ 00059 #define ARM_MPU_ATTR_DEVICE_GRE (3U) 00060 00061 /** \brief Memory Attribute 00062 * \param O Outer memory attributes 00063 * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes 00064 */ 00065 #define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) 00066 00067 /** \brief Normal memory non-shareable */ 00068 #define ARM_MPU_SH_NON (0U) 00069 00070 /** \brief Normal memory outer shareable */ 00071 #define ARM_MPU_SH_OUTER (2U) 00072 00073 /** \brief Normal memory inner shareable */ 00074 #define ARM_MPU_SH_INNER (3U) 00075 00076 /** \brief Memory access permissions 00077 * \param RO Read-Only: Set to 1 for read-only memory. 00078 * \param NP Non-Privileged: Set to 1 for non-privileged memory. 00079 */ 00080 #define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) 00081 00082 /** \brief Region Base Address Register value 00083 * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. 00084 * \param SH Defines the Shareability domain for this memory region. 00085 * \param RO Read-Only: Set to 1 for a read-only memory region. 00086 * \param NP Non-Privileged: Set to 1 for a non-privileged memory region. 00087 * \oaram XN eXecute Never: Set to 1 for a non-executable memory region. 00088 */ 00089 #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ 00090 ((BASE & MPU_RBAR_BASE_Pos) | \ 00091 ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ 00092 ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ 00093 ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) 00094 00095 /** \brief Region Limit Address Register value 00096 * \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. 00097 * \param IDX The attribute index to be associated with this memory region. 00098 */ 00099 #define ARM_MPU_RLAR(LIMIT, IDX) \ 00100 ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ 00101 ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ 00102 (MPU_RLAR_EN_Msk)) 00103 00104 /** 00105 * Struct for a single MPU Region 00106 */ 00107 typedef struct { 00108 uint32_t RBAR; /*!< Region Base Address Register value */ 00109 uint32_t RLAR ; /*!< Region Limit Address Register value */ 00110 } ARM_MPU_Region_t; 00111 00112 /** Enable the MPU. 00113 * \param MPU_Control Default access permissions for unconfigured regions. 00114 */ 00115 __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) 00116 { 00117 __DSB(); 00118 __ISB(); 00119 MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; 00120 #ifdef SCB_SHCSR_MEMFAULTENA_Msk 00121 SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; 00122 #endif 00123 } 00124 00125 /** Disable the MPU. 00126 */ 00127 __STATIC_INLINE void ARM_MPU_Disable(void) 00128 { 00129 __DSB(); 00130 __ISB(); 00131 #ifdef SCB_SHCSR_MEMFAULTENA_Msk 00132 SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; 00133 #endif 00134 MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; 00135 } 00136 00137 #ifdef MPU_NS 00138 /** Enable the Non-secure MPU. 00139 * \param MPU_Control Default access permissions for unconfigured regions. 00140 */ 00141 __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) 00142 { 00143 __DSB(); 00144 __ISB(); 00145 MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; 00146 #ifdef SCB_SHCSR_MEMFAULTENA_Msk 00147 SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; 00148 #endif 00149 } 00150 00151 /** Disable the Non-secure MPU. 00152 */ 00153 __STATIC_INLINE void ARM_MPU_Disable_NS(void) 00154 { 00155 __DSB(); 00156 __ISB(); 00157 #ifdef SCB_SHCSR_MEMFAULTENA_Msk 00158 SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; 00159 #endif 00160 MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; 00161 } 00162 #endif 00163 00164 /** Set the memory attribute encoding to the given MPU. 00165 * \param mpu Pointer to the MPU to be configured. 00166 * \param idx The attribute index to be set [0-7] 00167 * \param attr The attribute value to be set. 00168 */ 00169 __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) 00170 { 00171 const uint8_t reg = idx / 4U; 00172 const uint32_t pos = ((idx % 4U) * 8U); 00173 const uint32_t mask = 0xFFU << pos; 00174 00175 if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { 00176 return; // invalid index 00177 } 00178 00179 mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); 00180 } 00181 00182 /** Set the memory attribute encoding. 00183 * \param idx The attribute index to be set [0-7] 00184 * \param attr The attribute value to be set. 00185 */ 00186 __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) 00187 { 00188 ARM_MPU_SetMemAttrEx(MPU, idx, attr); 00189 } 00190 00191 #ifdef MPU_NS 00192 /** Set the memory attribute encoding to the Non-secure MPU. 00193 * \param idx The attribute index to be set [0-7] 00194 * \param attr The attribute value to be set. 00195 */ 00196 __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) 00197 { 00198 ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); 00199 } 00200 #endif 00201 00202 /** Clear and disable the given MPU region of the given MPU. 00203 * \param mpu Pointer to MPU to be used. 00204 * \param rnr Region number to be cleared. 00205 */ 00206 __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) 00207 { 00208 mpu->RNR = rnr; 00209 mpu->RLAR = 0U; 00210 } 00211 00212 /** Clear and disable the given MPU region. 00213 * \param rnr Region number to be cleared. 00214 */ 00215 __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) 00216 { 00217 ARM_MPU_ClrRegionEx(MPU, rnr); 00218 } 00219 00220 #ifdef MPU_NS 00221 /** Clear and disable the given Non-secure MPU region. 00222 * \param rnr Region number to be cleared. 00223 */ 00224 __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) 00225 { 00226 ARM_MPU_ClrRegionEx(MPU_NS, rnr); 00227 } 00228 #endif 00229 00230 /** Configure the given MPU region of the given MPU. 00231 * \param mpu Pointer to MPU to be used. 00232 * \param rnr Region number to be configured. 00233 * \param rbar Value for RBAR register. 00234 * \param rlar Value for RLAR register. 00235 */ 00236 __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) 00237 { 00238 mpu->RNR = rnr; 00239 mpu->RBAR = rbar; 00240 mpu->RLAR = rlar; 00241 } 00242 00243 /** Configure the given MPU region. 00244 * \param rnr Region number to be configured. 00245 * \param rbar Value for RBAR register. 00246 * \param rlar Value for RLAR register. 00247 */ 00248 __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) 00249 { 00250 ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); 00251 } 00252 00253 #ifdef MPU_NS 00254 /** Configure the given Non-secure MPU region. 00255 * \param rnr Region number to be configured. 00256 * \param rbar Value for RBAR register. 00257 * \param rlar Value for RLAR register. 00258 */ 00259 __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) 00260 { 00261 ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); 00262 } 00263 #endif 00264 00265 /** Memcopy with strictly ordered memory access, e.g. for register targets. 00266 * \param dst Destination data is copied to. 00267 * \param src Source data is copied from. 00268 * \param len Amount of data words to be copied. 00269 */ 00270 __STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) 00271 { 00272 uint32_t i; 00273 for (i = 0U; i < len; ++i) 00274 { 00275 dst[i] = src[i]; 00276 } 00277 } 00278 00279 /** Load the given number of MPU regions from a table to the given MPU. 00280 * \param mpu Pointer to the MPU registers to be used. 00281 * \param rnr First region number to be configured. 00282 * \param table Pointer to the MPU configuration table. 00283 * \param cnt Amount of regions to be configured. 00284 */ 00285 __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 00286 { 00287 const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; 00288 if (cnt == 1U) { 00289 mpu->RNR = rnr; 00290 orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); 00291 } else { 00292 uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); 00293 uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; 00294 00295 mpu->RNR = rnrBase; 00296 while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { 00297 uint32_t c = MPU_TYPE_RALIASES - rnrOffset; 00298 orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); 00299 table += c; 00300 cnt -= c; 00301 rnrOffset = 0U; 00302 rnrBase += MPU_TYPE_RALIASES; 00303 mpu->RNR = rnrBase; 00304 } 00305 00306 orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); 00307 } 00308 } 00309 00310 /** Load the given number of MPU regions from a table. 00311 * \param rnr First region number to be configured. 00312 * \param table Pointer to the MPU configuration table. 00313 * \param cnt Amount of regions to be configured. 00314 */ 00315 __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 00316 { 00317 ARM_MPU_LoadEx(MPU, rnr, table, cnt); 00318 } 00319 00320 #ifdef MPU_NS 00321 /** Load the given number of MPU regions from a table to the Non-secure MPU. 00322 * \param rnr First region number to be configured. 00323 * \param table Pointer to the MPU configuration table. 00324 * \param cnt Amount of regions to be configured. 00325 */ 00326 __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 00327 { 00328 ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); 00329 } 00330 #endif 00331 00332 #endif 00333 00334
Generated on Tue Jul 12 2022 16:47:29 by
