14
14
* limitations under the License.
15
15
*/
16
16
#include "hal/mpu_api.h"
17
+ #include "platform/mbed_assert.h"
18
+ #include "platform/mbed_error.h"
17
19
#include "cmsis.h"
18
20
19
21
#if ((__ARM_ARCH_7M__ == 1U ) || (__ARM_ARCH_7EM__ == 1U ) || (__ARM_ARCH_6M__ == 1U )) && \
20
- defined (__MPU_PRESENT ) && (__MPU_PRESENT == 1U )
22
+ defined (__MPU_PRESENT ) && (__MPU_PRESENT == 1U ) && \
23
+ !defined(MBED_MPU_CUSTOM )
21
24
22
25
#if !DEVICE_MPU
23
26
#error "Device has v7m MPU but it is not enabled. Add 'MPU' to device_has in targets.json"
24
27
#endif
25
28
26
- void mbed_mpu_init ()
27
- {
28
- mbed_mpu_enable_ram_xn (false);
29
- }
30
-
31
- void mbed_mpu_free ()
32
- {
33
- mbed_mpu_enable_ram_xn (false);
34
- }
29
+ #if !defined(MBED_MPU_ROM_END )
30
+ #define MBED_MPU_ROM_END (0x10000000 - 1)
31
+ #endif
32
+ #define MBED_MPU_RAM_START (MBED_MPU_ROM_END + 1)
33
+
34
+ MBED_STATIC_ASSERT (
35
+ MBED_MPU_ROM_END == 0x04000000 - 1 ||
36
+ MBED_MPU_ROM_END == 0x08000000 - 1 ||
37
+ MBED_MPU_ROM_END == 0x0C000000 - 1 ||
38
+ MBED_MPU_ROM_END == 0x10000000 - 1 ||
39
+ MBED_MPU_ROM_END == 0x14000000 - 1 ||
40
+ MBED_MPU_ROM_END == 0x18000000 - 1 ||
41
+ MBED_MPU_ROM_END == 0x1C000000 - 1 ||
42
+ MBED_MPU_ROM_END == 0x20000000 - 1 ,
43
+ "Unsupported value for MBED_MPU_ROM_END" );
35
44
36
- void mbed_mpu_enable_ram_xn ( bool enable )
45
+ void mbed_mpu_init ( )
37
46
{
38
47
// Flush memory writes before configuring the MPU.
39
48
__DSB ();
40
49
41
50
const uint32_t regions = (MPU -> TYPE & MPU_TYPE_DREGION_Msk ) >> MPU_TYPE_DREGION_Pos ;
51
+ if (regions < 4 ) {
52
+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_HAL , MBED_ERROR_CODE_EINVAL ), "Device is not capable of supporting an MPU - remove DEVICE_MPU for device_has." );
53
+ }
42
54
43
55
// Disable the MCU
44
56
MPU -> CTRL = 0 ;
@@ -48,15 +60,11 @@ void mbed_mpu_enable_ram_xn(bool enable)
48
60
ARM_MPU_ClrRegion (i );
49
61
}
50
62
51
- if (!enable ) {
52
- return ;
53
- }
54
-
55
63
/*
56
- * ARMv6m and ARMv7m memory map:
64
+ * ARMv6m and ARMv7-M memory map:
57
65
*
58
66
* Start End Name Executable by default Mbed MPU protection
59
- * 0x00000000 - 0x1FFFFFFF Code Yes Execute disabled for second half
67
+ * 0x00000000 - 0x1FFFFFFF Code Yes Write disabled for first portion and execute disabled for the rest
60
68
* 0x20000000 - 0x3FFFFFFF SRAM Yes Execute disabled
61
69
* 0x40000000 - 0x5FFFFFFF Peripheral No
62
70
* 0x60000000 - 0x7FFFFFFF RAM Yes Execute disabled
@@ -66,81 +74,102 @@ void mbed_mpu_enable_ram_xn(bool enable)
66
74
* 0xE0000000 - 0xFFFFFFFF System No
67
75
*/
68
76
69
- if (regions >= 3 ) {
70
- // Select region 0 and used it for the WT rom region
71
- // - RAM 0x10000000 - 0x1FFFFFFF
72
- MPU -> RNR = 0 ;
73
- // Set address to 0
74
- MPU -> RBAR = 0 ;
75
- // Configure and enable region
76
- MPU -> RASR =
77
- MPU_RASR_ENABLE_Msk |
78
- ARM_MPU_RASR (
79
- 1 , // DisableExec
80
- ARM_MPU_AP_FULL , // AccessPermission
81
- 0 , // TypeExtField
82
- 0 , // IsShareable
83
- 1 , // IsCacheable
84
- 0 , // IsBufferable
85
- // SubRegionDisable
86
- (1 << 0 ) | // Disable Sub-region
87
- (1 << 1 ) | // Disable Sub-region
88
- (1 << 2 ) | // Disable Sub-region
89
- (1 << 3 ) | // Disable Sub-region
90
- (0 << 4 ) | // Enable Sub-region RAM 0x10000000 - 0x1FFFFFFF
91
- (0 << 5 ) |
92
- (0 << 6 ) |
93
- (0 << 7 ),
94
- ARM_MPU_REGION_SIZE_512MB // Size
95
- );
96
-
97
- // Select region 1 and used it for WBWA ram regions
98
- // - SRAM 0x20000000 - 0x3FFFFFFF
99
- // - RAM 0x60000000 - 0x7FFFFFFF
100
- MPU -> RNR = 1 ;
101
- // Set address to 0
102
- MPU -> RBAR = 0 ;
103
- // Configure and enable region
104
- MPU -> RASR =
105
- MPU_RASR_ENABLE_Msk |
106
- ARM_MPU_RASR (
107
- 1 , // DisableExec
108
- ARM_MPU_AP_FULL , // AccessPermission
109
- 1 , // TypeExtField
110
- 0 , // IsShareable
111
- 1 , // IsCacheable
112
- 1 , // IsBufferable
113
- // SubRegionDisable
114
- (1 << 0 ) | // Disable Sub-region
115
- (0 << 1 ) | // Enable Sub-region SRAM 0x20000000 - 0x3FFFFFFF
116
- (1 << 2 ) | // Disable Sub-region
117
- (0 << 3 ) | // Enable Sub-region RAM 0x60000000 - 0x7FFFFFFF
118
- (1 << 4 ) | // Disable Sub-region
119
- (1 << 5 ) | // Disable Sub-region
120
- (1 << 6 ) | // Disable Sub-region
121
- (1 << 7 ), // Disable Sub-region
122
- ARM_MPU_REGION_SIZE_4GB // Size
123
- );
124
-
125
- // Select region 2 and used it for the WT ram region
126
- // - RAM RAM 0x80000000 - 0x9FFFFFFF
127
- MPU -> RNR = 2 ;
128
- // Set address
129
- MPU -> RBAR = 0x80000000 ;
130
- // Configure and enable region
131
- MPU -> RASR =
132
- MPU_RASR_ENABLE_Msk |
133
- ARM_MPU_RASR (
134
- 1 , // DisableExec
135
- ARM_MPU_AP_FULL , // AccessPermission
136
- 0 , // TypeExtField
137
- 0 , // IsShareable
138
- 1 , // IsCacheable
139
- 0 , // IsBufferable
140
- ~0U , // SubRegionDisable
141
- ARM_MPU_REGION_SIZE_512MB // Size
142
- );
143
- }
77
+ // Select region 1 and used it for the WT rom region
78
+ // - RAM 0x00000000 to MBED_MPU_ROM_END
79
+ MPU -> RNR = 0 ;
80
+ // Set address to 0
81
+ MPU -> RBAR = 0 ;
82
+ // Configure and enable region
83
+ MPU -> RASR =
84
+ ARM_MPU_RASR (
85
+ 0 , // DisableExec
86
+ ARM_MPU_AP_RO , // AccessPermission
87
+ 0 , // TypeExtField
88
+ 0 , // IsShareable
89
+ 1 , // IsCacheable
90
+ 0 , // IsBufferable
91
+ // SubRegionDisable - based on where ROM ends
92
+ ((MBED_MPU_ROM_END >= 0x00000000 ) ? 0 : (1 << 0 )) | // 0 to enable, 1 << n to disable
93
+ ((MBED_MPU_ROM_END >= 0x04000000 ) ? 0 : (1 << 1 )) |
94
+ ((MBED_MPU_ROM_END >= 0x08000000 ) ? 0 : (1 << 2 )) |
95
+ ((MBED_MPU_ROM_END >= 0x0C000000 ) ? 0 : (1 << 3 )) |
96
+ ((MBED_MPU_ROM_END >= 0x10000000 ) ? 0 : (1 << 4 )) |
97
+ ((MBED_MPU_ROM_END >= 0x14000000 ) ? 0 : (1 << 5 )) |
98
+ ((MBED_MPU_ROM_END >= 0x18000000 ) ? 0 : (1 << 6 )) |
99
+ ((MBED_MPU_ROM_END >= 0x1C000000 ) ? 0 : (1 << 7 )),
100
+ ARM_MPU_REGION_SIZE_512MB // Size
101
+ );
102
+
103
+ // Select region 1 and used it for the WT rom region
104
+ // - RAM MBED_MPU_ROM_END + 1 to 0x1FFFFFFF
105
+ MPU -> RNR = 1 ;
106
+ // Set address to 0
107
+ MPU -> RBAR = 0 ;
108
+ // Configure and enable region
109
+ MPU -> RASR =
110
+ ARM_MPU_RASR (
111
+ 1 , // DisableExec
112
+ ARM_MPU_AP_FULL , // AccessPermission
113
+ 0 , // TypeExtField
114
+ 0 , // IsShareable
115
+ 1 , // IsCacheable
116
+ 0 , // IsBufferable
117
+ // SubRegionDisable - based on where RAM starts
118
+ ((MBED_MPU_RAM_START <= 0x04000000 ) ? 0 : (1 << 0 )) | // 0 to enable, 1 << n to disable
119
+ ((MBED_MPU_RAM_START <= 0x08000000 ) ? 0 : (1 << 1 )) |
120
+ ((MBED_MPU_RAM_START <= 0x0C000000 ) ? 0 : (1 << 2 )) |
121
+ ((MBED_MPU_RAM_START <= 0x10000000 ) ? 0 : (1 << 3 )) |
122
+ ((MBED_MPU_RAM_START <= 0x14000000 ) ? 0 : (1 << 4 )) |
123
+ ((MBED_MPU_RAM_START <= 0x18000000 ) ? 0 : (1 << 5 )) |
124
+ ((MBED_MPU_RAM_START <= 0x1C000000 ) ? 0 : (1 << 6 )) |
125
+ ((MBED_MPU_RAM_START <= 0x20000000 ) ? 0 : (1 << 7 )),
126
+ ARM_MPU_REGION_SIZE_512MB // Size
127
+ );
128
+
129
+ // Select region 2 and used it for WBWA ram regions
130
+ // - SRAM 0x20000000 to 0x3FFFFFFF
131
+ // - RAM 0x60000000 to 0x7FFFFFFF
132
+ MPU -> RNR = 2 ;
133
+ // Set address to 0
134
+ MPU -> RBAR = 0 ;
135
+ // Configure and enable region
136
+ MPU -> RASR =
137
+ ARM_MPU_RASR (
138
+ 1 , // DisableExec
139
+ ARM_MPU_AP_FULL , // AccessPermission
140
+ 1 , // TypeExtField
141
+ 0 , // IsShareable
142
+ 1 , // IsCacheable
143
+ 1 , // IsBufferable
144
+ // SubRegionDisable
145
+ (1 << 0 ) | // Disable Sub-region
146
+ (0 << 1 ) | // Enable Sub-region SRAM 0x20000000 - 0x3FFFFFFF
147
+ (1 << 2 ) | // Disable Sub-region
148
+ (0 << 3 ) | // Enable Sub-region RAM 0x60000000 - 0x7FFFFFFF
149
+ (1 << 4 ) | // Disable Sub-region
150
+ (1 << 5 ) | // Disable Sub-region
151
+ (1 << 6 ) | // Disable Sub-region
152
+ (1 << 7 ), // Disable Sub-region
153
+ ARM_MPU_REGION_SIZE_4GB // Size
154
+ );
155
+
156
+ // Select region 3 and used it for the WT ram region
157
+ // - RAM RAM 0x80000000 to 0x9FFFFFFF
158
+ MPU -> RNR = 3 ;
159
+ // Set address
160
+ MPU -> RBAR = 0x80000000 ;
161
+ // Configure and enable region
162
+ MPU -> RASR =
163
+ ARM_MPU_RASR (
164
+ 1 , // DisableExec
165
+ ARM_MPU_AP_FULL , // AccessPermission
166
+ 0 , // TypeExtField
167
+ 0 , // IsShareable
168
+ 1 , // IsCacheable
169
+ 0 , // IsBufferable
170
+ ~0U , // SubRegionDisable
171
+ ARM_MPU_REGION_SIZE_512MB // Size
172
+ );
144
173
145
174
// Enable the MPU
146
175
MPU -> CTRL =
@@ -153,4 +182,49 @@ void mbed_mpu_enable_ram_xn(bool enable)
153
182
__DSB ();
154
183
}
155
184
185
+ void mbed_mpu_free ()
186
+ {
187
+ // Flush memory writes before configuring the MPU.
188
+ __DSB ();
189
+
190
+ // Disable the MPU
191
+ MPU -> CTRL = 0 ;
192
+
193
+ // Ensure changes take effect
194
+ __ISB ();
195
+ __DSB ();
196
+ }
197
+
198
+ void mbed_mpu_enable_rom_wn (bool enable )
199
+ {
200
+ // Flush memory writes before configuring the MPU.
201
+ __DSB ();
202
+
203
+ MPU -> RNR = 0 ;
204
+ MPU -> RASR = (MPU -> RASR & ~MPU_RASR_ENABLE_Msk ) | (enable ? MPU_RASR_ENABLE_Msk : 0 );
205
+
206
+ // Ensure changes take effect
207
+ __ISB ();
208
+ __DSB ();
209
+ }
210
+
211
+ void mbed_mpu_enable_ram_xn (bool enable )
212
+ {
213
+ // Flush memory writes before configuring the MPU.
214
+ __DSB ();
215
+
216
+ MPU -> RNR = 1 ;
217
+ MPU -> RASR = (MPU -> RASR & ~MPU_RASR_ENABLE_Msk ) | (enable ? MPU_RASR_ENABLE_Msk : 0 );
218
+
219
+ MPU -> RNR = 2 ;
220
+ MPU -> RASR = (MPU -> RASR & ~MPU_RASR_ENABLE_Msk ) | (enable ? MPU_RASR_ENABLE_Msk : 0 );
221
+
222
+ MPU -> RNR = 3 ;
223
+ MPU -> RASR = (MPU -> RASR & ~MPU_RASR_ENABLE_Msk ) | (enable ? MPU_RASR_ENABLE_Msk : 0 );
224
+
225
+ // Ensure changes take effect
226
+ __ISB ();
227
+ __DSB ();
228
+ }
229
+
156
230
#endif
0 commit comments