Skip to content

Commit bacbea6

Browse files
MaureenHelmgalak
authored andcommitted
arm: nxp: mpu: Rework handling of region descriptor 0
The NXP MPU requires special handling of region descriptor 0 to guarantee that the debugger has access to the entire address space. It does not allow writes from the core to affect the start or end addresses, or the permissions associated with the debugger. The original implementation of this driver attempted to work around region descriptor 0, resulting in an off-by-1 error caught by Coverity. Instead, define region descriptor 0 explicitly in the mpu_regions array, and add some asserts to ensure that one doesn't try to change its start or end addresses. This has an added benefit such that more permissions can be enabled in region 0 if desired, whereas the previous implementation always forced all writable permissions to be cleared. Coverity-CID: 170473 Jira: ZEP-2258 Signed-off-by: Maureen Helm <[email protected]>
1 parent d2e38de commit bacbea6

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

arch/arm/core/cortex_m/mpu/nxp_mpu.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,33 @@ static inline u8_t _get_num_regions(void)
4444
static void _region_init(u32_t index, u32_t region_base,
4545
u32_t region_end, u32_t region_attr)
4646
{
47-
SYSMPU->WORD[index][0] = region_base;
48-
SYSMPU->WORD[index][1] = region_end;
49-
SYSMPU->WORD[index][2] = region_attr;
50-
SYSMPU->WORD[index][3] = SYSMPU_WORD_VLD_MASK;
47+
if (index == 0) {
48+
/* The MPU does not allow writes from the core to affect the
49+
* RGD0 start or end addresses nor the permissions associated
50+
* with the debugger; it can only write the permission fields
51+
* associated with the other masters. These protections
52+
* guarantee that the debugger always has access to the entire
53+
* address space.
54+
*/
55+
__ASSERT(region_base == SYSMPU->WORD[index][0],
56+
"Region %d base address got 0x%08x expected 0x%08x",
57+
index, region_base, SYSMPU->WORD[index][0]);
58+
59+
__ASSERT(region_end == SYSMPU->WORD[index][1],
60+
"Region %d end address got 0x%08x expected 0x%08x",
61+
index, region_end, SYSMPU->WORD[index][1]);
62+
63+
/* Changes to the RGD0_WORD2 alterable fields should be done
64+
* via a write to RGDAAC0.
65+
*/
66+
SYSMPU->RGDAAC[index] = region_attr;
67+
68+
} else {
69+
SYSMPU->WORD[index][0] = region_base;
70+
SYSMPU->WORD[index][1] = region_end;
71+
SYSMPU->WORD[index][2] = region_attr;
72+
SYSMPU->WORD[index][3] = SYSMPU_WORD_VLD_MASK;
73+
}
5174

5275
SYS_LOG_DBG("[%d] 0x%08x 0x%08x 0x%08x 0x%08x", index,
5376
SYSMPU->WORD[index][0],
@@ -130,7 +153,7 @@ void arm_core_mpu_configure(u8_t type, u32_t base, u32_t size)
130153
* structure is mapped on the mpu_config.sram_region + 1 region of
131154
* the MPU.
132155
*/
133-
_region_init(mpu_config.sram_region + 1,
156+
_region_init(mpu_config.sram_region,
134157
mpu_config.mpu_regions[mpu_config.sram_region].base,
135158
ENDADDR_ROUND(base),
136159
mpu_config.mpu_regions[mpu_config.sram_region].attr);
@@ -182,22 +205,9 @@ static void _nxp_mpu_config(void)
182205

183206
/* MPU Configuration */
184207

185-
/* Disable Region 0 */
186-
SYSMPU->WORD[0][2] = 0;
187-
188-
SYS_LOG_DBG("[0] 0x%08x 0x%08x 0x%08x 0x%08x",
189-
SYSMPU->WORD[0][0],
190-
SYSMPU->WORD[0][1],
191-
SYSMPU->WORD[0][2],
192-
SYSMPU->WORD[0][3]);
193-
194-
/*
195-
* Configure regions:
196-
* r_index starts from 0 but is passed to region_init as r_index + 1,
197-
* region 0 is not configurable
198-
*/
208+
/* Configure regions */
199209
for (r_index = 0; r_index < mpu_config.num_regions; r_index++) {
200-
_region_init(r_index + 1,
210+
_region_init(r_index,
201211
mpu_config.mpu_regions[r_index].base,
202212
mpu_config.mpu_regions[r_index].end,
203213
mpu_config.mpu_regions[r_index].attr);

arch/arm/soc/nxp_kinetis/k6x/nxp_mpu_regions.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@
1212

1313
static struct nxp_mpu_region mpu_regions[] = {
1414
/* Region 0 */
15+
MPU_REGION_ENTRY("DEBUGGER_0",
16+
0,
17+
0xFFFFFFFF,
18+
0),
19+
/* Region 1 */
1520
MPU_REGION_ENTRY("FLASH_0",
1621
CONFIG_FLASH_BASE_ADDRESS,
1722
0x07FFFFFF,
1823
REGION_FLASH_ATTR),
19-
/* Region 1 */
24+
/* Region 2 */
2025
/*
2126
* This region (Flexbus + FlexNVM) is bigger than the FLEXBUS one in
2227
* order to save 1 region allocation in the MPU.
@@ -25,18 +30,18 @@ static struct nxp_mpu_region mpu_regions[] = {
2530
FLEXBUS_BASE_ADDRESS,
2631
0x1BFFFFFF,
2732
REGION_IO_ATTR),
28-
/* Region 2 */
33+
/* Region 3 */
2934
MPU_REGION_ENTRY("RAM_L_0",
3035
SRAM_L_BASE_ADDRESS,
3136
0x1FFFFFFF,
3237
REGION_RAM_ATTR),
33-
/* Region 3 */
38+
/* Region 4 */
3439
MPU_REGION_ENTRY("RAM_U_0",
3540
CONFIG_SRAM_BASE_ADDRESS,
3641
(CONFIG_SRAM_BASE_ADDRESS +
3742
(CONFIG_SRAM_SIZE * 1024) - 1),
3843
REGION_RAM_ATTR),
39-
/* Region 4 */
44+
/* Region 5 */
4045
MPU_REGION_ENTRY("DEVICE_0",
4146
DEVICE_S_BASE_ADDRESS,
4247
0xFFFFFFFF,
@@ -46,5 +51,5 @@ static struct nxp_mpu_region mpu_regions[] = {
4651
struct nxp_mpu_config mpu_config = {
4752
.num_regions = ARRAY_SIZE(mpu_regions),
4853
.mpu_regions = mpu_regions,
49-
.sram_region = 3,
54+
.sram_region = 4,
5055
};

0 commit comments

Comments
 (0)