1/** 2\defgroup mpu_functions MPU Functions for Armv6-M/v7-M 3\brief Functions that relate to the Memory Protection Unit. 4\details 5The following functions support the optional Memory Protection Unit (MPU) that is available on the Cortex-M0+, M3, M4 and M7 processor. 6 7The MPU is used to prevent from illegal memory accesses that are typically caused by errors in an application software. 8 9<b>Example:</b> 10\code 11int main() 12{ 13 // Set Region 0 14 ARM_MPU_SetRegionEx(0UL, 0x08000000UL, ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB)); 15 16 ARM_MPU_Enable(0); 17 18 // Execute application code that is access protected by the MPU 19 20 ARM_MPU_Disable(); 21} 22\endcode 23 24@{ 25*/ 26 27/** 28*/ 29typedef struct {} MPU_Type; 30 31 32/** \def ARM_MPU_RBAR 33* \brief MPU Region Base Address Register Value 34* 35* This preprocessor function can be used to construct a valid \ref MPU_Type::RBAR "RBAR" value. 36* The VALID bit is implicitly set to 1. 37* 38* \param Region The region to be configured, number 0 to 15. 39* \param BaseAddress The base address for the region. 40*/ 41#define ARM_MPU_RBAR(Region, BaseAddress) 42 43/** 44* \def ARM_MPU_RASR 45* \brief MPU Region Attribute and Size Register Value 46* 47* This macro is used to construct a valid \ref MPU_Type::RASR "RASR" value. 48* The ENABLE bit of the RASR value is implicitly set to 1. 49* 50* \param DisableExec Instruction access disable bit. 1 = disable instruction fetches. 51* \param AccessPermission Data access permission configures read/write access for User and Privileged mode. Possible values see \ref ARM_MPU_AP_xxx. 52* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. 53* \param IsShareable 1 = region is shareable between multiple bus masters. 54* \param IsCacheable 1 = region is cacheable (values may be kept in cache). 55* \param IsBufferable 1 = region is bufferable (when using write-back caching). Cacheable but non-bufferable regions use write-through policy. 56* \param SubRegionDisable Sub-region disable field (8 bits). 57* \param Size Region size with values defined under \ref ARM_MPU_REGION_SIZE_xxx. 58*/ 59#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) 60 61 62/** 63* \def ARM_MPU_RASR_EX 64* \brief MPU Region Attribute and Size Register Value 65* 66* This macro is used to construct a valid \ref MPU_Type::RASR "RASR" value. 67* The ENABLE bit of the RASR value is implicitly set to 1. 68* 69* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. 70* \param AccessPermission Data access permission configures read/write access for User and Privileged mode. Possible values see \ref ARM_MPU_AP_xxx. 71* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_xxx. 72* \param SubRegionDisable Sub-region disable field (8 bits). 73* \param Size Region size with values defined under \ref ARM_MPU_REGION_SIZE_xxx. 74*/ 75#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) 76 77/** 78* \brief Setup information of a single MPU Region 79* \details The typedef \ref ARM_MPU_Region_t allows to define a MPU table (array of MPU regions) with pre-compiled register values. 80* Such tables enable efficient MPU setup using the function \ref ARM_MPU_Load. 81* 82* <b>Example:</b> See \ref ARM_MPU_Load 83*/ 84typedef struct { 85 uint32_t RBAR; //!< The region base address register value (\ref MPU_Type::RBAR "RBAR") 86 uint32_t RASR; //!< The region attribute and size register value (\ref MPU_Type::RASR "RASR"), see \ref ARM_MPU_RASR. 87} ARM_MPU_Region_t; 88 89/** 90\brief Enable the memory protection unit (MPU) and 91\param MPU_CTRL Additional control settings that configure MPU behaviour 92\details 93The function \ref ARM_MPU_Enable writes to the register \ref MPU_Type::CTRL "MPU->CTRL" and sets bit ENABLE. The parameter \em MPU_CTRL provides additional bit values 94(see table below) that configure the MPU behaviour. For processors that implement an <b>MPU Fault Handler</b> the \ref NVIC_gr "MemoryManagement_IRQn" exception is enabled by setting the bit MEMFAULTACT in register SBC->SHCSR. 95 96The following table contains possible values for the parameter \em MPU_CTRL that set specific bits in register MPU->CTRL. 97| Bit | MPU_CTRL value | When applied | When not applied 98|:----|:-------------------------|:------------------------------------------------------------------------|:--------------------------------------- 99| 1 | MPU_CTRL_HFNMIENA_Msk | Enable MPU during hard fault, NMI, and FAULTMASK handlers execution | Disable MPU during hard fault, NMI, and FAULTMASK handler execution 100| 2 | MPU_CTRL_PRIVDEFENA_Msk | Enable default memory map as a background region for privileged access | Use only MPU region settings 101 102<b>Example:</b> 103 104\code 105// enable MPU with all region definitions. Exceptions are not protected by MPU. 106 MPU_Enable (0); 107 108// enable MPU with all region definitions and background regions for privileged access. Exceptions are protected by MPU. 109 MPU_Enable (MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk); 110\endcode 111 112 113*/ 114__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_CTRL); 115 116/** Disable the MPU. 117*/ 118__STATIC_INLINE void ARM_MPU_Disable(); 119 120/** Clear and disable the given MPU region. 121* \param rnr Region number to be cleared. 122*/ 123__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr); 124 125/** Configure an MPU region. 126* 127* The region number should be contained in the rbar value. 128* 129* \param rbar Value for \ref MPU_Type::RBAR "RBAR" register. 130* \param rasr Value for \ref MPU_Type::RASR "RASR" register. 131*/ 132__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr); 133 134/** Configure the given MPU region. 135* \param rnr Region number to be configured. 136* \param rbar Value for \ref MPU_Type::RBAR "RBAR" register. 137* \param rasr Value for \ref MPU_Type::RASR "RASR" register. 138*/ 139__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr); 140 141/** Memcpy with strictly ordered memory access, e.g. used by code in \ref ARM_MPU_Load. 142* \param dst Destination data is copied to. 143* \param src Source data is copied from. 144* \param len Amount of data words to be copied. 145*/ 146__STATIC_INLINE void ARM_MPU_OrderedMemcpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len); 147 148/** Load the given number of MPU regions from a table. 149* \param table Pointer to the MPU configuration table. 150* \param cnt Number of regions to be configured. 151* 152* \note only up to 16 regions can be handled as the function \ref ARM_MPU_Load uses the REGION field in \ref MPU_Type::RBAR "MPU->RBAR". 153* 154* <b>Example:</b> 155* \code 156* const ARM_MPU_Region_t mpuTable[3][4] = { 157* { 158* { .RBAR = ARM_MPU_RBAR(0UL, 0x08000000UL), .RASR = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB) }, 159* { .RBAR = ARM_MPU_RBAR(1UL, 0x20000000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_32KB) }, 160* { .RBAR = ARM_MPU_RBAR(2UL, 0x40020000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, ARM_MPU_REGION_SIZE_8KB) }, 161* { .RBAR = ARM_MPU_RBAR(3UL, 0x40022000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, ARM_MPU_REGION_SIZE_4KB) } 162* }, 163* { 164* { .RBAR = ARM_MPU_RBAR(4UL, 0x08000000UL), .RASR = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB) }, 165* { .RBAR = ARM_MPU_RBAR(5UL, 0x20000000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_32KB) }, 166* { .RBAR = ARM_MPU_RBAR(6UL, 0x40020000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, ARM_MPU_REGION_SIZE_8KB) }, 167* { .RBAR = ARM_MPU_RBAR(7UL, 0x40022000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, ARM_MPU_REGION_SIZE_4KB) } 168* }, 169* { 170* { .RBAR = ARM_MPU_RBAR(4UL, 0x18000000UL), .RASR = ARM_MPU_RASR(0UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_1MB) }, 171* { .RBAR = ARM_MPU_RBAR(5UL, 0x30000000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 0UL, 0UL, 1UL, 1UL, 0x00UL, ARM_MPU_REGION_SIZE_32KB) }, 172* { .RBAR = ARM_MPU_RBAR(6UL, 0x50020000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0x00UL, ARM_MPU_REGION_SIZE_8KB) }, 173* { .RBAR = ARM_MPU_RBAR(7UL, 0x50022000UL), .RASR = ARM_MPU_RASR(1UL, ARM_MPU_AP_FULL, 2UL, 0UL, 0UL, 0UL, 0xC0UL, ARM_MPU_REGION_SIZE_4KB) } 174* } 175* }; 176* 177* void UpdateMpu(uint32_t idx) 178* { 179* ARM_MPU_Load(mpuTable[idx], 4); 180* } 181* \endcode 182* 183*/ 184__STATIC_INLINE void ARM_MPU_Load(MPU_Region_t const* table, uint32_t cnt); 185 186 187/** 188 @} 189 190\defgroup mpu_defines Define values 191\ingroup mpu_functions 192\brief Define values for MPU region setup. 193\details 194The following define values are used with \ref ARM_MPU_RASR to setup the \ref MPU_Type::RASR "RASR" value field in the MPU region. 195 196\see 197ARM_MPU_Region_t, ARM_MPU_SetRegion, ARM_MPU_SetRegionEx. 198@{ 199*/ 200 201/** \def ARM_MPU_REGION_SIZE_xxx 202\brief Size values of a MPU region (in RASR field) 203\details 204The following define values are used to compose the size information for an MPU region: 205 206|\#define | Value | Description | 207|:-------------------------|:-----------------|:---------------------------------------------------------| 208|ARM_MPU_REGION_SIZE_32B | 0x04U | Region size 32 Bytes 209|ARM_MPU_REGION_SIZE_64B | 0x05U | Region size 64 Bytes 210|ARM_MPU_REGION_SIZE_128B | 0x06U | Region size 128 Bytes 211|ARM_MPU_REGION_SIZE_256B | 0x07U | Region size 256 Bytes 212|ARM_MPU_REGION_SIZE_512B | 0x08U | Region size 512 Bytes 213|ARM_MPU_REGION_SIZE_1KB | 0x09U | Region size 1 KByte 214|ARM_MPU_REGION_SIZE_2KB | 0x0AU | Region size 2 KBytes 215|ARM_MPU_REGION_SIZE_4KB | 0x0BU | Region size 4 KBytes 216|ARM_MPU_REGION_SIZE_8KB | 0x0CU | Region size 8 KBytes 217|ARM_MPU_REGION_SIZE_16KB | 0x0DU | Region size 16 KBytes 218|ARM_MPU_REGION_SIZE_32KB | 0x0EU | Region size 32 KBytes 219|ARM_MPU_REGION_SIZE_64KB | 0x0FU | Region size 64 KBytes 220|ARM_MPU_REGION_SIZE_128KB | 0x10U | Region size 128 KBytes 221|ARM_MPU_REGION_SIZE_256KB | 0x11U | Region size 256 KBytes 222|ARM_MPU_REGION_SIZE_512KB | 0x12U | Region size 512 KBytes 223|ARM_MPU_REGION_SIZE_1MB | 0x13U | Region size 1 MByte 224|ARM_MPU_REGION_SIZE_2MB | 0x14U | Region size 2 MBytes 225|ARM_MPU_REGION_SIZE_4MB | 0x15U | Region size 4 MBytes 226|ARM_MPU_REGION_SIZE_8MB | 0x16U | Region size 8 MBytes 227|ARM_MPU_REGION_SIZE_16MB | 0x17U | Region size 16 MBytes 228|ARM_MPU_REGION_SIZE_32MB | 0x18U | Region size 32 MBytes 229|ARM_MPU_REGION_SIZE_64MB | 0x19U | Region size 64 MBytes 230|ARM_MPU_REGION_SIZE_128MB | 0x1AU | Region size 128 MBytes 231|ARM_MPU_REGION_SIZE_256MB | 0x1BU | Region size 256 MBytes 232|ARM_MPU_REGION_SIZE_512MB | 0x1CU | Region size 512 MBytes 233|ARM_MPU_REGION_SIZE_1GB | 0x1DU | Region size 1 GByte 234|ARM_MPU_REGION_SIZE_2GB | 0x1EU | Region size 2 GBytes 235|ARM_MPU_REGION_SIZE_4GB | 0x1FU | Region size 4 GBytes 236*/ 237#define ARM_MPU_REGION_SIZE_xxx 238 239/** \def ARM_MPU_AP_xxx 240\brief Values for MPU region access permissions (in RASR field) 241\details 242The following define values are used to compose the access permission for an MPU region: 243|\#define | Value | Access permissions | 244|:-------------------------|:-----------------|:---------------------------------------------------------| 245|ARM_MPU_AP_NONE | 0x0U | None: any access generates a permission fault. 246|ARM_MPU_AP_PRIV | 0x1U | Privileged Read/Write: privileged access only; any unprivileged access generates a permission fault. 247|ARM_MPU_AP_URO | 0x2U | Privileged Read/Write; Unprivileged Read-only: any unprivileged write generates a permission fault. 248|ARM_MPU_AP_FULL | 0x3U | Privileged Read/Write. Unprivileged Read/Write: full access, permission faults are never generated. 249|ARM_MPU_AP_PRO | 0x5U | Privileged Read-only: any unprivileged access or privileged write generates a permission fault. 250|ARM_MPU_AP_RO | 0x6U | Privileged and Unprivileged Read-only: any write generates a permission fault. 251*/ 252#define ARM_MPU_AP_xxx 253 254/** \def ARM_MPU_ACCESS_xxx 255\brief Values for MPU region access attributes (in RASR field) 256\details 257The following define values are used to compose the access attributes for an MPU region: 258|\#define | TEX | Shareable | Cacheable | Bufferable | Description | 259|:-----------------------------|:-----|:----------|:----------|:-----------|:------------------------| 260| ARM_MPU_ACCESS_ORDERED | 000b | 1 | 0 | 0 | Strongly ordered memory | 261| ARM_MPU_ACCESS_DEVICE(S) | 0s0b | S | 0 | S | Memory mapped peripheral device, shared (S=1) or non-shared (S=0) | 262| ARM_MPU_ACCESS_NORMAL(O,I,S) | 1BBb | S | A | A | Normal memory, with outer/inner cache policy (O/I=\ref ARM_MPU_CACHEP_xxx, shared (S=1) or non-share (S=0) | 263*/ 264#define ARM_MPU_ACCESS_xxx 265 266/** \def ARM_MPU_CACHEP_xxx 267\brief Cache policy values for MPU region access attributes (in RASR field) 268\details 269The following define values are used to compose the cacheability flags within the 270access attributes for an MPU region: 271|\#define | Value | Cacheability policy | 272|:-----------------------------|:------|:------------------------| 273| ARM_MPU_CACHEP_NOCACHE | 00b | Non-cacheable | 274| ARM_MPU_CACHEP_WB_WRA | 01b | Write-back, write and read allocate | 275| ARM_MPU_CACHEP_WT_NWA | 10b | Write-through, no write allocate | 276| ARM_MPU_CACHEP_WB_NWA | 11b | Write-back, no write allocate | 277*/ 278#define ARM_MPU_CACHEP_xxx 279 280/** @} */ 281 282/** 283 284\var ARM_MPU_Region_t::RBAR 285This value specifies the start address of the MPU protected memory region. The address must be a multiple of the region size (size aligned). 286 287See \ref MPU_Type::RBAR for details about field bit format. 288 289\var ARM_MPU_Region_t::RASR 290This value specifies region attributes and size. Use the \ref ARM_MPU_RASR macro to compose this value. 291 292\var MPU_Type::TYPE 293The MPU Type Register indicates how many regions the MPU support. Software can use it 294to determine if the processor implements an MPU. 295 296| Bits | Name | Function | 297| :------ | :------------ | :------------------------------------------------------------ | 298| [31:24] | - | Reserved. | 299| [23:16] | IREGION | Instruction region. RAZ. Armv7-M only supports a unified MPU. | 300| [15:8] | DREGION | Number of regions supported by the MPU. If this field reads-as-zero the processor does not implement an MPU. | 301| [7:1] | - | Reserved. | 302| [0] | SEPARATE | Indicates support for separate instruction and data address maps. RAZ. Armv7-M only supports a unified MPU. | 303 304\var MPU_Type::CTRL 305Enables the MPU, and when the MPU is enabled, controls whether the default memory map 306is enabled as a background region for privileged accesses, and whether the MPU is enabled 307for HardFaults, NMIs, and exception handlers when FAULTMASK is set to 1. 308 309| Bits | Name | Function | 310| :------ | :------------ | :------------------------------------------------------------ | 311| [31:3] | - | Reserved. | 312| [2] | PRIVDEFENA | 0 - Disables the default memory map. 1 - Enables the default memory map as a background region for privileged access. | 313| [1] | HFNMIENA | 0 - Disables the MPU for exception handlers. 1 - Use the MPU for memory accesses by exception handlers. | 314| [0] | ENABLE | 0 - The MPU is disabled. 1 - The MPU is enabled. | 315 316\var MPU_Type::RNR 317Selects the region currently accessed by \ref MPU_Type::RBAR and \ref MPU_Type::RASR. 318 319| Bits | Name | Function | 320| :------ | :------------ | :------------------------------------------------------------ | 321| [31:8] | - | Reserved. | 322| [7:0] | REGION | Indicates the memory region accessed. | 323 324\var MPU_Type::RBAR 325Holds the base address of the region identified by MPU_RNR. On a write, can also be used 326to update the base address of a specified region, in the range 0 to 15, updating MPU_RNR 327with the new region number. 328 329| Bits | Name | Function | 330| :------ | :------------ | :------------------------------------------------------------ | 331| [31:5] | ADDR | Base address of the region. | 332| [4] | VALID | 1 - Update \ref MPU_Type::RNR to the value obtained by zero extending the REGION value specified in this write, and apply the base address update to this region. | 333| [3:0] | REGION | On writes, can specify the number of the region to update, see VALID field description. | 334 335\var MPU_Type::RASR 336Defines the size and access behavior of the region identified by MPU_RNR, and enables 337that region. 338 339| Bits | Name | Function | 340| :------ | :------------ | :------------------------------------------------------------ | 341| [31:29] | - | Reserved. | 342| [28] | XN | Execute Never. | 343| [27] | - | Reserved. | 344| [26:24] | AP | Access Permissions, see \ref ARM_MPU_AP_xxx. | 345| [23:22] | - | Reserved. | 346| [21:19] | TEX | Type Extension. | 347| [18] | S | Shareable. | 348| [17] | C | Cacheable. | 349| [16] | B | Bufferable. | 350| [15:8] | SRD | Subregion Disable. For regions of 256 bytes or larger, each bit of this field controls whether one of the eight equal subregions is enabled (0) or disabled (1). 351| [7:6] | - | Reserved. | 352| [5:1] | SIZE | Indicates the region size. The region size, in bytes, is 2(SIZE+1). SIZE field values less than 4 are reserved, because the smallest supported region size is 32 bytes. | 353| [0] | ENABLE | 0 - This region is disabled. 1 - This region is enabled. | 354 355\var MPU_Type::RBAR_A1 356Alias for \ref MPU_Type::RBAR. 357 358\var MPU_Type::RASR_A1 359Alias for \ref MPU_Type::RASR. 360 361\var MPU_Type::RBAR_A2 362Alias for \ref MPU_Type::RBAR. 363 364\var MPU_Type::RASR_A2 365Alias for \ref MPU_Type::RASR. 366 367\var MPU_Type::RBAR_A3 368Alias for \ref MPU_Type::RBAR. 369 370\var MPU_Type::RASR_A3 371Alias for \ref MPU_Type::RASR. 372 373*/ 374