Merge branch 'upstreamedge' into test/encoder-direct-step
[clinton/Smoothieware.git] / build / mpu.h
1 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
2
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
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
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.
14 */
15 #ifndef _MPU_H_
16 #define _MPU_H_
17
18 #include <cmsis.h>
19
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
29
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
37
38 /* Memory Protection Unit Region Region Number Register Bits. */
39 #define MPU_RNR_REGION_MASK 0xFF
40
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
49
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
70
71
72 /* MPU - Memory Protection Unit Routines. */
73 static __INLINE uint32_t getMPUDataRegionCount(void)
74 {
75 return (MPU->TYPE & MPU_TYPE_DREGION_MASK) >> MPU_TYPE_DREGION_SHIFT;
76 }
77
78 static __INLINE uint32_t getHighestMPUDataRegionIndex(void)
79 {
80 return getMPUDataRegionCount() - 1;
81 }
82
83 static __INLINE int isMPURegionNumberValid(uint32_t regionNumber)
84 {
85 return regionNumber < getMPUDataRegionCount();
86 }
87
88 static __INLINE int isMPUNotPresent(void)
89 {
90 return getMPUDataRegionCount() == 0;
91 }
92
93 static __INLINE uint32_t getMPUControlValue(void)
94 {
95 if (isMPUNotPresent())
96 return ~0U;
97
98 return (MPU->CTRL);
99
100 }
101
102 static __INLINE void setMPUControlValue(uint32_t newControlValue)
103 {
104 if (isMPUNotPresent())
105 return;
106
107 MPU->CTRL = newControlValue;
108 __DSB();
109 __ISB();
110 }
111
112 static __INLINE void disableMPU(void)
113 {
114 if (isMPUNotPresent())
115 return;
116
117 MPU->CTRL &= ~MPU_CTRL_ENABLE;
118 __DSB();
119 __ISB();
120 }
121
122 static __INLINE void enableMPU(void)
123 {
124 if (isMPUNotPresent())
125 return;
126
127 MPU->CTRL = MPU_CTRL_ENABLE;
128 __DSB();
129 __ISB();
130 }
131
132 static __INLINE void enableMPUWithHardAndNMIFaults(void)
133 {
134 if (isMPUNotPresent())
135 return;
136
137 MPU->CTRL = MPU_CTRL_ENABLE | MPU_CTRL_HFNMIENA;
138 __DSB();
139 __ISB();
140 }
141
142 static __INLINE void enableMPUWithDefaultMemoryMap(void)
143 {
144 if (isMPUNotPresent())
145 return;
146
147 MPU->CTRL = MPU_CTRL_ENABLE | MPU_CTRL_PRIVDEFENA;
148 __DSB();
149 __ISB();
150 }
151
152 static __INLINE int prepareToAccessMPURegion(uint32_t regionNumber)
153 {
154 if (!isMPURegionNumberValid(regionNumber))
155 return 0;
156
157 MPU->RNR = regionNumber;
158 return 1;
159 }
160
161 static __INLINE uint32_t getCurrentMPURegionNumber(void)
162 {
163 return MPU->RNR;
164 }
165
166 static __INLINE void setMPURegionAddress(uint32_t address)
167 {
168 if (isMPUNotPresent())
169 return;
170
171 MPU->RBAR = address & MPU_RBAR_ADDR_MASK;
172 }
173
174 static __INLINE uint32_t getMPURegionAddress(void)
175 {
176 if (isMPUNotPresent())
177 return 0;
178
179 return MPU->RBAR & MPU_RBAR_ADDR_MASK;
180 }
181
182 static __INLINE void setMPURegionAttributeAndSize(uint32_t attributeAndSize)
183 {
184 if (isMPUNotPresent())
185 return;
186
187 MPU->RASR = attributeAndSize;
188 }
189
190 static __INLINE uint32_t getMPURegionAttributeAndSize(void)
191 {
192 if (isMPUNotPresent())
193 return 0;
194
195 return MPU->RASR;
196 }
197
198 #endif /* _MPU_H_ */