Skip to content

Commit 1821d37

Browse files
c1728p90xc0170
authored andcommitted
Overhaul MPU for new requirements
Make the following changes: -Allow a vector specific ARM MPU driver by defining MBED_MPU_CUSTOM -Allow ROM address to be configured for ARMv7-M devices by setting the define MBED_MPU_ROM_END -Add ROM write protection -Add new functions and lock -enable at boot -disable during flash programming
1 parent d27566c commit 1821d37

File tree

11 files changed

+435
-163
lines changed

11 files changed

+435
-163
lines changed

TESTS/mbed_hal/flash/functional_tests/main.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,17 @@ Case cases[] = {
252252

253253
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
254254
{
255-
mbed_mpu_manager_lock_mem_xn();
255+
mbed_mpu_manager_lock_ram_xn();
256+
mbed_mpu_manager_lock_rom_wn();
256257

257258
GREENTEA_SETUP(20, "default_auto");
258259
return greentea_test_setup_handler(number_of_cases);
259260
}
260261

261262
void greentea_test_teardown(const size_t passed, const size_t failed, const failure_t failure)
262263
{
263-
mbed_mpu_manager_unlock_mem_xn();
264+
mbed_mpu_manager_unlock_ram_xn();
265+
mbed_mpu_manager_unlock_rom_wn();
264266

265267
greentea_test_teardown_handler(passed, failed, failure);
266268
}

drivers/FlashIAP.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "FlashIAP.h"
2727
#include "platform/mbed_assert.h"
2828
#include "platform/ScopedMpuXnLock.h"
29+
#include "platform/ScopedMpuWnLock.h"
2930

3031

3132
#ifdef DEVICE_FLASH
@@ -59,6 +60,7 @@ int FlashIAP::init()
5960
_mutex->lock();
6061
{
6162
ScopedMpuXnLock xn;
63+
ScopedMpuWnLock wn;
6264
if (flash_init(&_flash)) {
6365
ret = -1;
6466
}
@@ -76,6 +78,7 @@ int FlashIAP::deinit()
7678
_mutex->lock();
7779
{
7880
ScopedMpuXnLock xn;
81+
ScopedMpuWnLock wn;
7982
if (flash_free(&_flash)) {
8083
ret = -1;
8184
}
@@ -92,6 +95,7 @@ int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
9295
_mutex->lock();
9396
{
9497
ScopedMpuXnLock xn;
98+
ScopedMpuWnLock wn;
9599
ret = flash_read(&_flash, addr, (uint8_t *) buffer, size);
96100
}
97101
_mutex->unlock();
@@ -138,6 +142,7 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
138142
}
139143
{
140144
ScopedMpuXnLock xn;
145+
ScopedMpuWnLock wn;
141146
if (flash_program_page(&_flash, addr, prog_buf, prog_size)) {
142147
ret = -1;
143148
break;
@@ -185,6 +190,7 @@ int FlashIAP::erase(uint32_t addr, uint32_t size)
185190
while (size) {
186191
{
187192
ScopedMpuXnLock xn;
193+
ScopedMpuWnLock wn;
188194
ret = flash_erase_sector(&_flash, addr);
189195
}
190196
if (ret != 0) {

hal/mpu/mbed_mpu_v7m.c

Lines changed: 166 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,43 @@
1414
* limitations under the License.
1515
*/
1616
#include "hal/mpu_api.h"
17+
#include "platform/mbed_assert.h"
18+
#include "platform/mbed_error.h"
1719
#include "cmsis.h"
1820

1921
#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)
2124

2225
#if !DEVICE_MPU
2326
#error "Device has v7m MPU but it is not enabled. Add 'MPU' to device_has in targets.json"
2427
#endif
2528

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");
3544

36-
void mbed_mpu_enable_ram_xn(bool enable)
45+
void mbed_mpu_init()
3746
{
3847
// Flush memory writes before configuring the MPU.
3948
__DSB();
4049

4150
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+
}
4254

4355
// Disable the MCU
4456
MPU->CTRL = 0;
@@ -48,15 +60,11 @@ void mbed_mpu_enable_ram_xn(bool enable)
4860
ARM_MPU_ClrRegion(i);
4961
}
5062

51-
if (!enable) {
52-
return;
53-
}
54-
5563
/*
56-
* ARMv6m and ARMv7m memory map:
64+
* ARMv6m and ARMv7-M memory map:
5765
*
5866
* 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
6068
* 0x20000000 - 0x3FFFFFFF SRAM Yes Execute disabled
6169
* 0x40000000 - 0x5FFFFFFF Peripheral No
6270
* 0x60000000 - 0x7FFFFFFF RAM Yes Execute disabled
@@ -66,81 +74,102 @@ void mbed_mpu_enable_ram_xn(bool enable)
6674
* 0xE0000000 - 0xFFFFFFFF System No
6775
*/
6876

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+
);
144173

145174
// Enable the MPU
146175
MPU->CTRL =
@@ -153,4 +182,49 @@ void mbed_mpu_enable_ram_xn(bool enable)
153182
__DSB();
154183
}
155184

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+
156230
#endif

0 commit comments

Comments
 (0)