tdse-tp0_03-hw_sw_test

FIUBA - Electrónica - Taller de Sistemas Embebidos - Trabajo Práctico N°: 0 - Proyecto N°: 03
Index Commits Files Refs README
Drivers/CMSIS/Include/mpu_armv8.h (11196B)
   1 /******************************************************************************
   2  * @file     mpu_armv8.h
   3  * @brief    CMSIS MPU API for Armv8-M MPU
   4  * @version  V5.0.4
   5  * @date     10. January 2018
   6  ******************************************************************************/
   7 /*
   8  * Copyright (c) 2017-2018 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 /**
 105  * Struct for a single MPU Region
 106  */
 107 typedef struct {
 108     uint32_t RBAR; /*!< Region Base Address Register value */
 109     uint32_t RLAR; /*!< Region Limit Address Register value */
 110 } ARM_MPU_Region_t;
 111 
 112 /** Enable the MPU.
 113  * \param MPU_Control Default access permissions for unconfigured regions.
 114  */
 115 __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
 116 {
 117     __DSB();
 118     __ISB();
 119     MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
 120 #ifdef SCB_SHCSR_MEMFAULTENA_Msk
 121   SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
 122 #endif
 123 }
 124 
 125 /** Disable the MPU.
 126  */
 127 __STATIC_INLINE void ARM_MPU_Disable(void)
 128 {
 129     __DSB();
 130     __ISB();
 131 #ifdef SCB_SHCSR_MEMFAULTENA_Msk
 132   SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
 133 #endif
 134     MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
 135 }
 136 
 137 #ifdef MPU_NS
 138 /** Enable the Non-secure MPU.
 139 * \param MPU_Control Default access permissions for unconfigured regions.
 140 */
 141 __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
 142 {
 143   __DSB();
 144   __ISB();
 145   MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
 146 #ifdef SCB_SHCSR_MEMFAULTENA_Msk
 147   SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
 148 #endif
 149 }
 150 
 151 /** Disable the Non-secure MPU.
 152 */
 153 __STATIC_INLINE void ARM_MPU_Disable_NS(void)
 154 {
 155   __DSB();
 156   __ISB();
 157 #ifdef SCB_SHCSR_MEMFAULTENA_Msk
 158   SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
 159 #endif
 160   MPU_NS->CTRL  &= ~MPU_CTRL_ENABLE_Msk;
 161 }
 162 #endif
 163 
 164 /** Set the memory attribute encoding to the given MPU.
 165  * \param mpu Pointer to the MPU to be configured.
 166  * \param idx The attribute index to be set [0-7]
 167  * \param attr The attribute value to be set.
 168  */
 169 __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type *mpu, uint8_t idx,
 170         uint8_t attr)
 171 {
 172     const uint8_t reg = idx / 4U;
 173     const uint32_t pos = ((idx % 4U) * 8U);
 174     const uint32_t mask = 0xFFU << pos;
 175 
 176     if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
 177         return; // invalid index
 178     }
 179 
 180     mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
 181 }
 182 
 183 /** Set the memory attribute encoding.
 184  * \param idx The attribute index to be set [0-7]
 185  * \param attr The attribute value to be set.
 186  */
 187 __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
 188 {
 189     ARM_MPU_SetMemAttrEx(MPU, idx, attr);
 190 }
 191 
 192 #ifdef MPU_NS
 193 /** Set the memory attribute encoding to the Non-secure MPU.
 194 * \param idx The attribute index to be set [0-7]
 195 * \param attr The attribute value to be set.
 196 */
 197 __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
 198 {
 199   ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
 200 }
 201 #endif
 202 
 203 /** Clear and disable the given MPU region of the given MPU.
 204  * \param mpu Pointer to MPU to be used.
 205  * \param rnr Region number to be cleared.
 206  */
 207 __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type *mpu, uint32_t rnr)
 208 {
 209     mpu->RNR = rnr;
 210     mpu->RLAR = 0U;
 211 }
 212 
 213 /** Clear and disable the given MPU region.
 214  * \param rnr Region number to be cleared.
 215  */
 216 __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
 217 {
 218     ARM_MPU_ClrRegionEx(MPU, rnr);
 219 }
 220 
 221 #ifdef MPU_NS
 222 /** Clear and disable the given Non-secure MPU region.
 223 * \param rnr Region number to be cleared.
 224 */
 225 __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
 226 {  
 227   ARM_MPU_ClrRegionEx(MPU_NS, rnr);
 228 }
 229 #endif
 230 
 231 /** Configure the given MPU region of the given MPU.
 232  * \param mpu Pointer to MPU to be used.
 233  * \param rnr Region number to be configured.
 234  * \param rbar Value for RBAR register.
 235  * \param rlar Value for RLAR register.
 236  */
 237 __STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type *mpu, uint32_t rnr,
 238         uint32_t rbar, uint32_t rlar)
 239 {
 240     mpu->RNR = rnr;
 241     mpu->RBAR = rbar;
 242     mpu->RLAR = rlar;
 243 }
 244 
 245 /** Configure the given MPU region.
 246  * \param rnr Region number to be configured.
 247  * \param rbar Value for RBAR register.
 248  * \param rlar Value for RLAR register.
 249  */
 250 __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar,
 251         uint32_t rlar)
 252 {
 253     ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
 254 }
 255 
 256 #ifdef MPU_NS
 257 /** Configure the given Non-secure MPU region.
 258 * \param rnr Region number to be configured.
 259 * \param rbar Value for RBAR register.
 260 * \param rlar Value for RLAR register.
 261 */   
 262 __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
 263 {
 264   ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);  
 265 }
 266 #endif
 267 
 268 /** Memcopy with strictly ordered memory access, e.g. for register targets.
 269  * \param dst Destination data is copied to.
 270  * \param src Source data is copied from.
 271  * \param len Amount of data words to be copied.
 272  */
 273 __STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
 274 {
 275     uint32_t i;
 276     for (i = 0U; i < len; ++i)
 277     {
 278         dst[i] = src[i];
 279     }
 280 }
 281 
 282 /** Load the given number of MPU regions from a table to the given MPU.
 283  * \param mpu Pointer to the MPU registers to be used.
 284  * \param rnr First region number to be configured.
 285  * \param table Pointer to the MPU configuration table.
 286  * \param cnt Amount of regions to be configured.
 287  */
 288 __STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type *mpu, uint32_t rnr,
 289         ARM_MPU_Region_t const *table, uint32_t cnt)
 290 {
 291     const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t) / 4U;
 292     if (cnt == 1U) {
 293         mpu->RNR = rnr;
 294         orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
 295     } else {
 296         uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES - 1U);
 297         uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
 298 
 299         mpu->RNR = rnrBase;
 300         while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
 301             uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
 302             orderedCpy(&(mpu->RBAR) + (rnrOffset * 2U), &(table->RBAR),
 303                     c * rowWordSize);
 304             table += c;
 305             cnt -= c;
 306             rnrOffset = 0U;
 307             rnrBase += MPU_TYPE_RALIASES;
 308             mpu->RNR = rnrBase;
 309         }
 310 
 311         orderedCpy(&(mpu->RBAR) + (rnrOffset * 2U), &(table->RBAR),
 312                 cnt * rowWordSize);
 313     }
 314 }
 315 
 316 /** Load the given number of MPU regions from a table.
 317  * \param rnr First region number to be configured.
 318  * \param table Pointer to the MPU configuration table.
 319  * \param cnt Amount of regions to be configured.
 320  */
 321 __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const *table,
 322         uint32_t cnt)
 323 {
 324     ARM_MPU_LoadEx(MPU, rnr, table, cnt);
 325 }
 326 
 327 #ifdef MPU_NS
 328 /** Load the given number of MPU regions from a table to the Non-secure MPU.
 329 * \param rnr First region number to be configured.
 330 * \param table Pointer to the MPU configuration table.
 331 * \param cnt Amount of regions to be configured.
 332 */
 333 __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 
 334 {
 335   ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
 336 }
 337 #endif
 338 
 339 #endif
 340