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