Skip to content

Commit

Permalink
Documentation: Add MPU document
Browse files Browse the repository at this point in the history
Adding MPU document, also update comment in mpu related file.
  • Loading branch information
Louie Lu committed Oct 18, 2016
1 parent 194e5c1 commit e0c94b3
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 5 deletions.
113 changes: 113 additions & 0 deletions Documentation/mpu.txt
Original file line number Diff line number Diff line change
@@ -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
8 changes: 4 additions & 4 deletions include/platform/mpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

#include <memory.h>

#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
Expand Down
2 changes: 1 addition & 1 deletion platform/stm32-common/mpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit e0c94b3

Please sign in to comment.