MPU for ARMv7 (ARM R5)

Features Supported

  • APIs to setup MPU regions, including region address, size, attributes like access permissions, cache properties

  • APIs to enable, disable MPU

  • API to check if MPU is enabled

Features NOT Supported

NA

Important Usage Guidelines

  • Refer to ARMv7-R or ARMv7-M architecture manual for more details

  • The number of MPU entries varies based on the ARM R5, ARM M4 instantiated in a given DEVICE, refer DEVICE datasheet for more details.

  • In R5 for this DEVICE, there are 16 MPU regions

  • In M4 for this DEVICE, there are 16 MPU regions

  • MPU regions can overlap each other, with higher numbered regions taking more precedence in case of address overlaps.

Example Usage

Include the below file to access the APIs,


//! [include]
#include <kernel/dpl/CacheP.h>
#include <kernel/dpl/MpuP_armv7.h>
//! [include]

void samples()
{
//! [mpu]
    #define MAX_REGIONS (16u) /* Max regions on a R5F */

Example usage to setup MPU regions and enable MPU:

    MpuP_RegionAttrs regionParams;
    uint32_t regionId = 0;

    /* recommend to disable Cache and MPU before setting up MPU regions */
    CacheP_disable(CacheP_TYPE_ALL);
    MpuP_disable();

    /* make all 4G as strongly ordered, non-cacheable */
    MpuP_RegionAttrs_init(&regionParams);
    regionParams.isEnable = 1;
    regionParams.isCacheable = 0;
    regionParams.isBufferable = 0;
    regionParams.isSharable = 1;
    regionParams.isExecuteNever = 1; /* dont allow code execution */
    regionParams.tex = 0;
    regionParams.accessPerm = MpuP_AP_S_RW;
    MpuP_setRegion(regionId, (void*)0x00000000, MpuP_RegionSize_4G, &regionParams);
    regionId++;

    /* make ATCM as cacheable */
    MpuP_RegionAttrs_init(&regionParams);
    regionParams.isEnable = 1;
    regionParams.isCacheable = 1;
    regionParams.isBufferable = 1;
    regionParams.isSharable = 0;
    regionParams.isExecuteNever = 0; /* allow code execution */
    regionParams.tex = 1;
    regionParams.accessPerm = MpuP_AP_S_RW;
    MpuP_setRegion(regionId, (void*)0x00000000, MpuP_RegionSize_32K, &regionParams);
    regionId++;

    /* make memory region as strongly ordered, non-cacheable */
    MpuP_RegionAttrs_init(&regionParams);
    regionParams.isEnable = 1;
    regionParams.isCacheable = 0;
    regionParams.isBufferable = 0;
    regionParams.isSharable = 1;
    regionParams.isExecuteNever = 1; /* dont allow code execution */
    regionParams.tex = 0;

Example to setup MPU regions and enable MPU is shown below,

API Reference

Enums

enum MpuP_AccessPerm

Enum’s to represent different types of access permissions that are possible for a given MPU region.

Values:

enumerator MpuP_AP_ALL_BLOCK

All accesses are blocked

enumerator MpuP_AP_S_RW

Only RD+WR supervisor mode accesses are allowed

enumerator MpuP_AP_S_RW_U_R

RD+WR supervisor and RD only user mode accesses are allowed

enumerator MpuP_AP_ALL_RW

All RD+WR accesses are allowed

enumerator MpuP_AP_S_R

Only RD supervisor mode accesses are allowed

enumerator MpuP_AP_ALL_R

All RD accesses are allowed

enum MpuP_RegionSize

Enum’s to represent different possible MPU region size.

Values:

enumerator MpuP_RegionSize_32
enumerator MpuP_RegionSize_64
enumerator MpuP_RegionSize_128
enumerator MpuP_RegionSize_256
enumerator MpuP_RegionSize_512
enumerator MpuP_RegionSize_1K
enumerator MpuP_RegionSize_2K
enumerator MpuP_RegionSize_4K
enumerator MpuP_RegionSize_8K
enumerator MpuP_RegionSize_16K
enumerator MpuP_RegionSize_32K
enumerator MpuP_RegionSize_64K
enumerator MpuP_RegionSize_128K
enumerator MpuP_RegionSize_256K
enumerator MpuP_RegionSize_512K
enumerator MpuP_RegionSize_1M
enumerator MpuP_RegionSize_2M
enumerator MpuP_RegionSize_4M
enumerator MpuP_RegionSize_8M
enumerator MpuP_RegionSize_16M
enumerator MpuP_RegionSize_32M
enumerator MpuP_RegionSize_64M
enumerator MpuP_RegionSize_128M
enumerator MpuP_RegionSize_256M
enumerator MpuP_RegionSize_512M
enumerator MpuP_RegionSize_1G
enumerator MpuP_RegionSize_2G
enumerator MpuP_RegionSize_4G

Functions

void MpuP_RegionAttrs_init(MpuP_RegionAttrs *region)

Set default values to MpuP_RegionAttrs.

Strongly recommended to be called before seting values in MpuP_RegionAttrs

Parameters:

region – [out] parameter structure to set to default

void MpuP_setRegion(uint32_t regionNum, void *addr, uint32_t size, MpuP_RegionAttrs *attrs)

Setup a region in the MPU.

Note

Refer to ARMv7-R or ARMv7-M architecture manual for more details

Note

Recommended to disable MPU and disable cache before setting up MPU regions

Parameters:
  • regionNum – [in] region to setup

  • addr – [in] region start address, MUST aligned to region size

  • size – [in] region size, see MpuP_RegionSize

  • attrs – [in] region attrs, see MpuP_RegionAttrs

void MpuP_resetRegion(uint32_t regionNum)

Reset a region in the MPU.

Note

Refer to ARMv7-R or ARMv7-M architecture manual for more details

Parameters:

regionNum – [in] region to reset

void MpuP_enable(void)

Enable MPU sub-system using the region that are setup using MpuP_setRegion.

void MpuP_disable(void)

Disable MPU sub-system.

uint32_t MpuP_isEnable(void)

Check if MPU sub-system is enabled.

Returns:

0: MPU sub-system is disabled, 1: MPU sub-system is enabled

void MpuP_init(void)

Initialize MPU sub-system, called by SysConfig, not to be called by end users.

struct MpuP_RegionAttrs
#include <MpuP_armv7.h>

Attribute’s to apply for a MPU region.

Note

Refer to ARMv7-R or ARMv7-M architecture manual for more details

Note

C, B, S, TEX[0:2] bits together control if a region should be fully cached or non-cached or marked as device memory

Public Members

uint8_t isEnable

1: enable this region, 0: disable this region

uint8_t isCacheable

1: set C bit, 0: clear C bit

uint8_t isBufferable

1: set B bit, 0: clear B bit

uint8_t isSharable

1: set S bit, 0: clear S bit

uint8_t isExecuteNever

1: set XN bit, 0: clear XN bit

uint8_t tex

set TEX[0:2] bits

uint8_t accessPerm

set AP[0:2] bits, see MpuP_AccessPerm

uint8_t subregionDisableMask

subregion disable mask, bitN = 1 means disable that subregion

struct MpuP_RegionConfig
#include <MpuP_armv7.h>

Region config structure, this used by SysConfig and not to be used by end-users directly.

Public Members

uint32_t baseAddr

region start address, MUST aligned to region size

uint32_t size

region size, see MpuP_RegionSize

MpuP_RegionAttrs attrs
struct MpuP_Config
#include <MpuP_armv7.h>

MPU config structure, this used by SysConfig and not to be used by end-users directly.

Public Members

uint32_t numRegions
uint32_t enableBackgroundRegion

Number of regions to configure 0: disable backgroun region, 1: enable background region

uint32_t enableMpu

0: keep MPU disabled, 1: enable MPU