Merge pull request #399 from Smoothieware/edge
[clinton/Smoothieware.git] / build / mpu.h
CommitLineData
65eee97a
AG
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. */
73static __INLINE uint32_t getMPUDataRegionCount(void)
74{
75 return (MPU->TYPE & MPU_TYPE_DREGION_MASK) >> MPU_TYPE_DREGION_SHIFT;
76}
77
78static __INLINE uint32_t getHighestMPUDataRegionIndex(void)
79{
80 return getMPUDataRegionCount() - 1;
81}
82
83static __INLINE int isMPURegionNumberValid(uint32_t regionNumber)
84{
85 return regionNumber < getMPUDataRegionCount();
86}
87
88static __INLINE int isMPUNotPresent(void)
89{
90 return getMPUDataRegionCount() == 0;
91}
92
93static __INLINE uint32_t getMPUControlValue(void)
94{
95 if (isMPUNotPresent())
96 return ~0U;
97
98 return (MPU->CTRL);
99
100}
101
102static __INLINE void setMPUControlValue(uint32_t newControlValue)
103{
104 if (isMPUNotPresent())
105 return;
106
107 MPU->CTRL = newControlValue;
108 __DSB();
109 __ISB();
110}
111
112static __INLINE void disableMPU(void)
113{
114 if (isMPUNotPresent())
115 return;
116
117 MPU->CTRL &= ~MPU_CTRL_ENABLE;
118 __DSB();
119 __ISB();
120}
121
122static __INLINE void enableMPU(void)
123{
124 if (isMPUNotPresent())
125 return;
126
ddf5038e 127 MPU->CTRL = MPU_CTRL_ENABLE;
65eee97a
AG
128 __DSB();
129 __ISB();
130}
131
132static __INLINE void enableMPUWithHardAndNMIFaults(void)
133{
134 if (isMPUNotPresent())
135 return;
136
ddf5038e
AG
137 MPU->CTRL = MPU_CTRL_ENABLE | MPU_CTRL_HFNMIENA;
138 __DSB();
139 __ISB();
140}
141
142static __INLINE void enableMPUWithDefaultMemoryMap(void)
143{
144 if (isMPUNotPresent())
145 return;
146
147 MPU->CTRL = MPU_CTRL_ENABLE | MPU_CTRL_PRIVDEFENA;
65eee97a
AG
148 __DSB();
149 __ISB();
150}
151
152static __INLINE int prepareToAccessMPURegion(uint32_t regionNumber)
153{
154 if (!isMPURegionNumberValid(regionNumber))
155 return 0;
156
157 MPU->RNR = regionNumber;
158 return 1;
159}
160
161static __INLINE uint32_t getCurrentMPURegionNumber(void)
162{
163 return MPU->RNR;
164}
165
166static __INLINE void setMPURegionAddress(uint32_t address)
167{
168 if (isMPUNotPresent())
169 return;
170
ddf5038e 171 MPU->RBAR = address & MPU_RBAR_ADDR_MASK;
65eee97a
AG
172}
173
174static __INLINE uint32_t getMPURegionAddress(void)
175{
176 if (isMPUNotPresent())
177 return 0;
178
ddf5038e 179 return MPU->RBAR & MPU_RBAR_ADDR_MASK;
65eee97a
AG
180}
181
182static __INLINE void setMPURegionAttributeAndSize(uint32_t attributeAndSize)
183{
184 if (isMPUNotPresent())
185 return;
186
187 MPU->RASR = attributeAndSize;
188}
189
190static __INLINE uint32_t getMPURegionAttributeAndSize(void)
191{
192 if (isMPUNotPresent())
193 return 0;
194
195 return MPU->RASR;
196}
197
198#endif /* _MPU_H_ */