Skip to content

Commit 6f57600

Browse files
author
Cruz Monrreal
authored
Merge pull request #9061 from kjbracey-arm/more_mpu_work
More MPU work
2 parents 995725b + adf253e commit 6f57600

File tree

5 files changed

+194
-146
lines changed

5 files changed

+194
-146
lines changed

hal/mpu/mbed_mpu_v7m.c

Lines changed: 68 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
#include "hal/mpu_api.h"
1717
#include "platform/mbed_assert.h"
18-
#include "platform/mbed_error.h"
1918
#include "cmsis.h"
2019

2120
#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_6M__ == 1U)) && \
@@ -26,7 +25,9 @@
2625
#error "Device has v7m MPU but it is not enabled. Add 'MPU' to device_has in targets.json"
2726
#endif
2827

29-
#if !defined(MBED_MPU_ROM_END)
28+
#ifdef MBED_CONF_TARGET_MPU_ROM_END
29+
#define MBED_MPU_ROM_END MBED_CONF_TARGET_MPU_ROM_END
30+
#else
3031
#define MBED_MPU_ROM_END (0x10000000 - 1)
3132
#endif
3233
#define MBED_MPU_RAM_START (MBED_MPU_ROM_END + 1)
@@ -45,12 +46,17 @@ MBED_STATIC_ASSERT(
4546
void mbed_mpu_init()
4647
{
4748
// Flush memory writes before configuring the MPU.
48-
__DSB();
49+
__DMB();
4950

5051
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-
}
52+
53+
// Our MPU setup requires 3 or 4 regions - if this assert is hit, remove
54+
// a region by setting MPU_ROM_END to 0x1fffffff, or remove MPU from device_has
55+
#if MBED_MPU_RAM_START == 0x20000000
56+
MBED_ASSERT(regions >= 3);
57+
#else
58+
MBED_ASSERT(regions >= 4);
59+
#endif
5460

5561
// Disable the MCU
5662
MPU->CTRL = 0;
@@ -74,13 +80,12 @@ void mbed_mpu_init()
7480
* 0xE0000000 - 0xFFFFFFFF System No
7581
*/
7682

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 =
83+
// Select region 0 and use it for the WT read-only rom region
84+
// - Code 0x00000000 to MBED_MPU_ROM_END
85+
ARM_MPU_SetRegion(
86+
ARM_MPU_RBAR(
87+
0, // Region
88+
0x00000000), // Base
8489
ARM_MPU_RASR(
8590
0, // DisableExec
8691
ARM_MPU_AP_RO, // AccessPermission
@@ -97,16 +102,16 @@ void mbed_mpu_init()
97102
((MBED_MPU_ROM_END >= 0x14000000) ? 0 : (1 << 5)) |
98103
((MBED_MPU_ROM_END >= 0x18000000) ? 0 : (1 << 6)) |
99104
((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 =
105+
ARM_MPU_REGION_SIZE_512MB) // Size
106+
);
107+
108+
#if MBED_MPU_RAM_START < 0x20000000
109+
// Select region 3 and use it for a WT ram region in the Code area
110+
// - Code MBED_MPU_ROM_END + 1 to 0x1FFFFFFF
111+
ARM_MPU_SetRegion(
112+
ARM_MPU_RBAR(
113+
3, // Region
114+
0x00000000), // Base
110115
ARM_MPU_RASR(
111116
1, // DisableExec
112117
ARM_MPU_AP_FULL, // AccessPermission
@@ -123,17 +128,20 @@ void mbed_mpu_init()
123128
((MBED_MPU_RAM_START <= 0x18000000) ? 0 : (1 << 5)) |
124129
((MBED_MPU_RAM_START <= 0x1C000000) ? 0 : (1 << 6)) |
125130
((MBED_MPU_RAM_START <= 0x20000000) ? 0 : (1 << 7)),
126-
ARM_MPU_REGION_SIZE_512MB // Size
127-
);
131+
ARM_MPU_REGION_SIZE_512MB) // Size
132+
);
133+
#define LAST_RAM_REGION 3
134+
#else
135+
#define LAST_RAM_REGION 2
136+
#endif
128137

129-
// Select region 2 and used it for WBWA ram regions
138+
// Select region 1 and use it for WBWA ram regions
130139
// - SRAM 0x20000000 to 0x3FFFFFFF
131140
// - 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 =
141+
ARM_MPU_SetRegion(
142+
ARM_MPU_RBAR(
143+
1, // Region
144+
0x00000000), // Base
137145
ARM_MPU_RASR(
138146
1, // DisableExec
139147
ARM_MPU_AP_FULL, // AccessPermission
@@ -150,26 +158,25 @@ void mbed_mpu_init()
150158
(1 << 5) | // Disable Sub-region
151159
(1 << 6) | // Disable Sub-region
152160
(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 =
161+
ARM_MPU_REGION_SIZE_4GB) // Size
162+
);
163+
164+
// Select region 2 and use it for the WT ram region
165+
// - RAM 0x80000000 to 0x9FFFFFFF
166+
ARM_MPU_SetRegion(
167+
ARM_MPU_RBAR(
168+
2, // Region
169+
0x80000000), // Base
163170
ARM_MPU_RASR(
164171
1, // DisableExec
165172
ARM_MPU_AP_FULL, // AccessPermission
166173
0, // TypeExtField
167174
0, // IsShareable
168175
1, // IsCacheable
169176
0, // IsBufferable
170-
~0U, // SubRegionDisable
171-
ARM_MPU_REGION_SIZE_512MB // Size
172-
);
177+
0U, // SubRegionDisable
178+
ARM_MPU_REGION_SIZE_512MB) // Size
179+
);
173180

174181
// Enable the MPU
175182
MPU->CTRL =
@@ -178,53 +185,53 @@ void mbed_mpu_init()
178185
(1 << MPU_CTRL_ENABLE_Pos); // Enable MPU
179186

180187
// Ensure changes take effect
181-
__ISB();
182188
__DSB();
189+
__ISB();
183190
}
184191

185192
void mbed_mpu_free()
186193
{
187194
// Flush memory writes before configuring the MPU.
188-
__DSB();
195+
__DMB();
189196

190197
// Disable the MPU
191198
MPU->CTRL = 0;
192199

193200
// Ensure changes take effect
194-
__ISB();
195201
__DSB();
202+
__ISB();
203+
}
204+
205+
static void enable_region(bool enable, uint32_t region)
206+
{
207+
MPU->RNR = region;
208+
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable << MPU_RASR_ENABLE_Pos);
196209
}
197210

198211
void mbed_mpu_enable_rom_wn(bool enable)
199212
{
200213
// Flush memory writes before configuring the MPU.
201-
__DSB();
214+
__DMB();
202215

203-
MPU->RNR = 0;
204-
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);
216+
enable_region(enable, 0);
205217

206218
// Ensure changes take effect
207-
__ISB();
208219
__DSB();
220+
__ISB();
209221
}
210222

211223
void mbed_mpu_enable_ram_xn(bool enable)
212224
{
213225
// Flush memory writes before configuring the MPU.
214-
__DSB();
226+
__DMB();
215227

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);
228+
for (uint32_t region = 1; region <= LAST_RAM_REGION; region++) {
229+
enable_region(enable, region);
230+
}
224231

225232
// Ensure changes take effect
226-
__ISB();
227233
__DSB();
234+
__ISB();
228235
}
229236

230237
#endif

0 commit comments

Comments
 (0)