diff --git a/Documentation/mpu.txt b/Documentation/mpu.txt new file mode 100644 index 00000000..fe9669c4 --- /dev/null +++ b/Documentation/mpu.txt @@ -0,0 +1,113 @@ +MPU: Memory Protection Unit for F9 Microkernel + +CONTENTS: + +1. MPU Introduction +2. Description of the MPU registers +3. Using MPU in F9 microkernel +4. Reference + +1. MPU Introduction + +F9 microkernel is focus on IoT device with ARM Cortex-M series CPU, especially +optimized for Crotex M3/M4, ARMv7-M processor supports the ARMv7 Protected Memory +System Architecture (PMSAv7) model. The system address space of a PMSAv7 compliant +system is protected by a Memory Protection Unit(MPU)[1]. + +The protected memory is divided up into a set of regions, with the number of +regions supported IMPLEMENTATION DEFINED, for example, in stm32f429, it provides +eight separate memory regions. In PMSAv7, the minimum protect region size is 32 +bytes, and maximum up to 4 GB. + +The MPU provides full support for[2]: + +* Protection regions +* Overlapping protection regions +* Access permissions +* Exporting memory attributes to the system. + +MPU mismatches and permission violations invoke the programmable-priority +MemManage fault handler. + +2. Description of the MPU registers + +There are three general MPU register: + + * MPU Type Register (0xE000ED90): + This regiseter can be used to determine if an MPU exists, and the number of + regions supported. + + * MPU Control Register (0xE000ED94): + The MPU Control register includes a global enable bit which must be set to + enable the MPU feature. + + * MPU Region Number Register (0xE000ED98) + +The MPU Region Number Register selects the associated region registers: + + * MPU Region Base Address Register (0xE000ED9C): + MPU Region Base Address Register to write the base address of a region. + The Region Base Address Register also contains a REGION field that you can + use to override the REGION field in the MPU Region Number Register,if the + VALID bit is set. + + The Region Base Address register sets the base for the region. It is aligned + by the size. So, a 64-KB sized region must be aligned on a multiple of 64KB, + for example, 0x00010000 or 0x00020000. + + * MPU Region Attribute and Size Register (0xE000EDA0): + MPU Region Attribute and Size Register defines the size and access behavior + of the associated memory region. + + + MPU Region Attribute and Size Register bit assignments + ------------------------------------------------------ + 31 29|28|27|26 24 |23 22 |21 19 |18 17 16 |15 8 |7 6 |5 1|0 + Reserve|X |R |Access |Res |Type |S C B |Sub |Res |Region|Enable + N |e |Permission | |Extension | |Region | |Size | + s |Field |Disable + + + RASR fields used in F9 microkernel: + + XN: eXecute Never, instruction must have read access as defined by the AP + bits and XN clear for correct execution, otherwise a MemManage fault is + generate when instrction is issued. + + AP: Access Permission, setting for privileged R/W permissions and + user R/W permissions. + + Region size: region size can be setting from 32B to 4GB, starting from + b00100: 32B, b00101: 64B, b00110: 128B to b11111: 4GB. + + Enable: When set, the associated region is enabled within the MPU. The global + MPU enable bit must also be set for it to take effect. + +3. Using MPU in F9 microkernel + +F9 microkernel provides 4 function to manipulate with MPU: + +* void mpu_setup_region(int n, fpage_t *fp); + +Call from `thread_switch` -> `as_setup_mpu` -> `mpu_setup_region`, when F9 +microkernel perform thread switch, it will reset MPU for current thread (the +thread which we want to switch in) + +* void mpu_enable(mpu_state_t i); + +Used in kernel/start.c, F9 microkernel will enable MPU before switch to kernel + +* void __memmanage_handler(void); + +The handler for MemManage fault interrupt, the NVIC vector table in kernel/init.c +will setting for this. + +* int mpu_select_lru(as_t *as, uint32_t addr); + +Select least recently used MPU region. + +4. Reference + +[1] ARM v7-M ArchitectureApplication LevelReference Manual +[2] Cortex™-M3 Technical Reference Manual 9.1 About the MPU +[3] ARM®v7-M Architecture Reference Manual \ No newline at end of file diff --git a/include/platform/mpu.h b/include/platform/mpu.h index 7ea5a33d..319385be 100644 --- a/include/platform/mpu.h +++ b/include/platform/mpu.h @@ -8,10 +8,10 @@ #include -#define MPU_BASE_ADDR 0xE000ED9C -#define MPU_ATTR_ADDR 0xE000EDA0 -#define MPU_CTRL_ADDR 0xE000ED94 -#define MPU_RNR_ADDR 0xE000ED98 +#define MPU_BASE_ADDR 0xE000ED9C /* Region Base Address Register (RBAR) */ +#define MPU_ATTR_ADDR 0xE000EDA0 /* Region Attribute and Size Register (RASR) */ +#define MPU_CTRL_ADDR 0xE000ED94 /* MPU Control Register (CTRL) */ +#define MPU_RNR_ADDR 0xE000ED98 /* Region Number Register (RNR) */ #define MPU_FAULT_STATUS_ADDR 0xE000ED28 #define MPU_FAULT_ADDRESS_ADDR 0xE000ED34 diff --git a/platform/stm32-common/mpu.c b/platform/stm32-common/mpu.c index 43939f6b..8faab340 100644 --- a/platform/stm32-common/mpu.c +++ b/platform/stm32-common/mpu.c @@ -23,7 +23,7 @@ void mpu_setup_region(int n, fpage_t *fp) 0 : (1 << 28)) | /* XN bit */ (0x3 << 24) /* Full access */ | - ((fp->fpage.shift - 1) << 1) /* Region */ | + ((fp->fpage.shift - 1) << 1) /* Region size*/ | 1 /* Enable */; } else { /* Clean MPU region */