I am trying to use the MPU on the k20 and am very confused. My goal is to have three regions two full access surrounding a region of supervisor access only.
Supervisor\User Access from 0 to 0x1fffc350-1
Supervisor Only Access from 0x1fffc350 to 0x1fffce54-1
Supervisor\User Access from 0x1fffce54 to 0xffffffff-1
So I set up this test below and am unable to prevent access to the middle region when in User Mode. In the example the 'xxx' variable is located in the middle region.
Can someone tell me what I am doing wrong?
Thanks
#define MPU_REGION_ALL MPU_WORD_M3SM(MPU_SM_RWX) | MPU_WORD_M3UM(MPU_UM_R | MPU_UM_W | MPU_UM_X) | \
MPU_WORD_M2SM(MPU_SM_RWX) | MPU_WORD_M2UM(MPU_UM_R | MPU_UM_W | MPU_UM_X) | \
MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(MPU_UM_R | MPU_UM_W | MPU_UM_X) | \
MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(MPU_UM_R | MPU_UM_W | MPU_UM_X)
__attribute__ ((section (".system_task_1_private_vars")))
static int xxx; //placed at middle of protected region 0x1fffcc34
void mpu_init() {
uint32_t i;
MPU_CESR &= ~MPU_CESR_VLD_MASK; //disable MPU
for (i = 0; i < CORTEX_MPU_REC; i++) {
MPU_WORD(i, 2) = 0;
}
uint32_t sectionStart = 0x1fffc350;
uint32_t sectionEnd = 0x1fffce54;
_set_region(1, 0, sectionStart - 1, MPU_REGION_ALL);
_set_region(2, sectionEnd, 0xFFFFFFFF, MPU_REGION_ALL);
_set_region(3, sectionStart, sectionEnd - 1,
MPU_WORD_M1SM(MPU_SM_RWX) | MPU_WORD_M1UM(0) |
MPU_WORD_M0SM(MPU_SM_RWX) | MPU_WORD_M0UM(0));
// Control == 0x02 before and after the call to sys_mpu_MakePrivileged()
sys_mpu_MakePrivileged();
MPU_CESR |= MPU_CESR_VLD_MASK; //enable MPU
xxx++;
sys_mpu_MakeUnPrivileged();
// Control now equals 0x03
xxx++; //*****Not sure why/how this works, expecting fault ********
}
void _set_region(uint32_t region, unsigned char *start, unsigned char *end, _mqx_uint flags) {
MPU_WORD(region, 0) = (_mem_size) start & MPU_WORD_SRTADDR_MASK;
MPU_WORD(region, 1) = ((_mem_size) end & MPU_WORD_ENDADDR_MASK) | 0x01f;
MPU_WORD(region, 2) = flags;
MPU_WORD(region, 3) = MPU_WORD_VLD_MASK;
}
void sys_mpu_MakePrivileged() {
__asm volatile (
"mrs r0, CONTROL \n"
"bic.w r0, r0, #1 \n"
"msr CONTROL, r0 \n"
"isb #15 \n"
::: "r0"
);
}
void sys_mpu_MakeUnPrivileged() {
__asm volatile (
"mrs r0, CONTROL \n"
"orr r0, r0, #1 \n"
"msr CONTROL, r0 \n"
"isb #15 \n"
::: "r0"
);
}