1 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
20 /* Memory Protection Unit Type Register Bits. */
21 /* Number of instruction regions supported by MPU. 0 for Cortex-M3 */
22 #define MPU_TYPE_IREGION_SHIFT 16
23 #define MPU_TYPE_IREGION_MASK (0xFF << MPU_TYPE_IREGION_SHIFT)
24 /* Number of data regions supported by MPU. */
25 #define MPU_TYPE_DREGION_SHIFT 8
26 #define MPU_TYPE_DREGION_MASK (0xFF << MPU_TYPE_DREGION_SHIFT)
27 /* Are instruction and data regions configured separately? 1 for yes and 0 otherwise. */
28 #define MPU_TYPE_SEPARATE 0x1
30 /* Memory Protection Unit Control Register Bits. */
31 /* Default memory map as background region for privileged access. 1 enables. */
32 #define MPU_CTRL_PRIVDEFENA (1 << 2)
33 /* Hard fault and NMI exceptions to use MPU. 0 disables MPU for these handlers. */
34 #define MPU_CTRL_HFNMIENA (1 << 1)
35 /* MPU Enable. 1 enables and disabled otherwise. */
36 #define MPU_CTRL_ENABLE 1
38 /* Memory Protection Unit Region Region Number Register Bits. */
39 #define MPU_RNR_REGION_MASK 0xFF
41 /* Memory Protection Unit Region Base Address Register Bits. */
42 /* Base address of this region. */
43 #define MPU_RBAR_ADDR_SHIFT 5
44 #define MPU_RBAR_ADDR_MASK (0x7FFFFFF << MPU_RBAR_ADDR_SHIFT)
45 /* Are the region bits in this register valid or should RNR be used instead. */
46 #define MPU_RBAR_VALID (1 << 4)
47 /* The region number. Only used when MPU_RBAR_VALID is one. */
48 #define MPU_RBAR_REGION_MASK 0xF
50 /* Memory Protection Unit Region Attribute and Size Register Bits. */
51 /* eXecute Never bit. 1 means code can't execute from this region. */
52 #define MPU_RASR_XN (1 << 28)
53 /* Access permission bits. */
54 #define MPU_RASR_AP_SHIFT 24
55 #define MPU_RASR_AP_MASK (0x7 << MPU_RASR_AP_SHIFT)
56 /* TEX, C, and B bits together determine memory type. */
57 #define MPU_RASR_TEX_SHIFT 19
58 #define MPU_RASR_TEX_MASK (0x7 << MPU_RASR_TEX_SHIFT)
59 #define MPU_RASR_S (1 << 18)
60 #define MPU_RASR_C (1 << 17)
61 #define MPU_RASR_B (1 << 16)
62 /* Sub-region disable bits. */
63 #define MPU_RASR_SRD_SHIFT 8
64 #define MPU_RASR_SRD_MASK (0xff << MPU_RASR_SRD_SHIFT)
65 /* Region size in 2^(value + 1) */
66 #define MPU_RASR_SIZE_SHIFT 1
67 #define MPU_RASR_SIZE_MASK (0x1F << MPU_RASR_SIZE_SHIFT)
68 /* Region enable. 1 enables. */
69 #define MPU_RASR_ENABLE 1
72 /* MPU - Memory Protection Unit Routines. */
73 static __INLINE
uint32_t getMPUDataRegionCount(void)
75 return (MPU
->TYPE
& MPU_TYPE_DREGION_MASK
) >> MPU_TYPE_DREGION_SHIFT
;
78 static __INLINE
uint32_t getHighestMPUDataRegionIndex(void)
80 return getMPUDataRegionCount() - 1;
83 static __INLINE
int isMPURegionNumberValid(uint32_t regionNumber
)
85 return regionNumber
< getMPUDataRegionCount();
88 static __INLINE
int isMPUNotPresent(void)
90 return getMPUDataRegionCount() == 0;
93 static __INLINE
uint32_t getMPUControlValue(void)
95 if (isMPUNotPresent())
102 static __INLINE
void setMPUControlValue(uint32_t newControlValue
)
104 if (isMPUNotPresent())
107 MPU
->CTRL
= newControlValue
;
112 static __INLINE
void disableMPU(void)
114 if (isMPUNotPresent())
117 MPU
->CTRL
&= ~MPU_CTRL_ENABLE
;
122 static __INLINE
void enableMPU(void)
124 if (isMPUNotPresent())
127 MPU
->CTRL
= MPU_CTRL_ENABLE
;
132 static __INLINE
void enableMPUWithHardAndNMIFaults(void)
134 if (isMPUNotPresent())
137 MPU
->CTRL
= MPU_CTRL_ENABLE
| MPU_CTRL_HFNMIENA
;
142 static __INLINE
void enableMPUWithDefaultMemoryMap(void)
144 if (isMPUNotPresent())
147 MPU
->CTRL
= MPU_CTRL_ENABLE
| MPU_CTRL_PRIVDEFENA
;
152 static __INLINE
int prepareToAccessMPURegion(uint32_t regionNumber
)
154 if (!isMPURegionNumberValid(regionNumber
))
157 MPU
->RNR
= regionNumber
;
161 static __INLINE
uint32_t getCurrentMPURegionNumber(void)
166 static __INLINE
void setMPURegionAddress(uint32_t address
)
168 if (isMPUNotPresent())
171 MPU
->RBAR
= address
& MPU_RBAR_ADDR_MASK
;
174 static __INLINE
uint32_t getMPURegionAddress(void)
176 if (isMPUNotPresent())
179 return MPU
->RBAR
& MPU_RBAR_ADDR_MASK
;
182 static __INLINE
void setMPURegionAttributeAndSize(uint32_t attributeAndSize
)
184 if (isMPUNotPresent())
187 MPU
->RASR
= attributeAndSize
;
190 static __INLINE
uint32_t getMPURegionAttributeAndSize(void)
192 if (isMPUNotPresent())