AnsweredAssumed Answered

Kinetis 20 MPU Trouble

Question asked by Leif Zars on Jan 26, 2016
Latest reply on Feb 14, 2016 by Hui_Ma

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


Outcomes