arm: core: mpu: Add core support to ARM MPU
This patch add arm core MPU support to ARM MPU driver. Change-Id: I5a61da4615ae687bf42f1c9947e291ebfd2d2c1d Signed-off-by: Vincenzo Frascino <vincenzo.frascino@linaro.org>
This commit is contained in:
parent
acc9fb29a3
commit
b94c5b16fe
2 changed files with 102 additions and 1 deletions
|
@ -10,9 +10,45 @@
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
#include <arch/arm/cortex_m/cmsis.h>
|
#include <arch/arm/cortex_m/cmsis.h>
|
||||||
#include <arch/arm/cortex_m/mpu/arm_mpu.h>
|
#include <arch/arm/cortex_m/mpu/arm_mpu.h>
|
||||||
|
#include <arch/arm/cortex_m/mpu/arm_core_mpu.h>
|
||||||
|
#include <logging/sys_log.h>
|
||||||
|
|
||||||
#define ARM_MPU_DEV ((volatile struct arm_mpu *) ARM_MPU_BASE)
|
#define ARM_MPU_DEV ((volatile struct arm_mpu *) ARM_MPU_BASE)
|
||||||
|
|
||||||
|
/* ARM MPU Enabled state */
|
||||||
|
static u8_t arm_mpu_enabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes referenced in this function are described at:
|
||||||
|
* https://goo.gl/hMry3r
|
||||||
|
* This function is private to the driver.
|
||||||
|
*/
|
||||||
|
static inline u32_t _get_region_attr(u32_t xn, u32_t ap, u32_t tex,
|
||||||
|
u32_t c, u32_t b, u32_t s,
|
||||||
|
u32_t srd, u32_t size)
|
||||||
|
{
|
||||||
|
return ((xn << 28) | (ap) | (tex << 19) | (s << 18)
|
||||||
|
| (c << 17) | (b << 16) | (srd << 5) | (size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This internal function is utilized by the MPU driver to parse the intent
|
||||||
|
* type (i.e. THREAD_STACK_REGION) and return the correct parameter set.
|
||||||
|
*/
|
||||||
|
static inline u32_t _get_region_attr_by_type(u32_t type, u32_t size)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case THREAD_STACK_REGION:
|
||||||
|
return 0;
|
||||||
|
case THREAD_STACK_GUARD_REGION:
|
||||||
|
return _get_region_attr(1, P_RO_U_RO, 0, 1, 0,
|
||||||
|
1, 0, REGION_32B);
|
||||||
|
default:
|
||||||
|
/* Size 0 region */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline u8_t _get_num_regions(void)
|
static inline u8_t _get_num_regions(void)
|
||||||
{
|
{
|
||||||
u32_t type = ARM_MPU_DEV->type;
|
u32_t type = ARM_MPU_DEV->type;
|
||||||
|
@ -32,6 +68,61 @@ static void _region_init(u32_t index, u32_t region_addr,
|
||||||
ARM_MPU_DEV->rasr = region_attr | REGION_ENABLE;
|
ARM_MPU_DEV->rasr = region_attr | REGION_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ARM Core MPU Driver API Implementation for ARM MPU */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief enable the MPU
|
||||||
|
*/
|
||||||
|
void arm_core_mpu_enable(void)
|
||||||
|
{
|
||||||
|
if (arm_mpu_enabled == 0) {
|
||||||
|
/* Enable MPU */
|
||||||
|
ARM_MPU_DEV->ctrl = ARM_MPU_ENABLE | ARM_MPU_PRIVDEFENA;
|
||||||
|
|
||||||
|
arm_mpu_enabled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief disable the MPU
|
||||||
|
*/
|
||||||
|
void arm_core_mpu_disable(void)
|
||||||
|
{
|
||||||
|
if (arm_mpu_enabled == 1) {
|
||||||
|
/* Disable MPU */
|
||||||
|
ARM_MPU_DEV->ctrl = 0;
|
||||||
|
|
||||||
|
arm_mpu_enabled = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief configure the base address and size for an MPU region
|
||||||
|
*
|
||||||
|
* @param type MPU region type
|
||||||
|
* @param base base address in RAM
|
||||||
|
* @param size size of the region
|
||||||
|
*/
|
||||||
|
void arm_core_mpu_configure(u8_t type, u32_t base, u32_t size)
|
||||||
|
{
|
||||||
|
SYS_LOG_DBG("Region info: 0x%x 0x%x", base, size);
|
||||||
|
/*
|
||||||
|
* The new MPU regions are are allocated per type after the statically
|
||||||
|
* configured regions.
|
||||||
|
*/
|
||||||
|
u32_t region_index = mpu_config.num_regions + type;
|
||||||
|
u32_t region_attr = _get_region_attr_by_type(type, size);
|
||||||
|
|
||||||
|
/* ARM MPU supports up to 16 Regions */
|
||||||
|
if (region_index > _get_num_regions()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_region_init(region_index, base, region_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARM MPU Driver Initial Setup */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief MPU default configuration
|
* @brief MPU default configuration
|
||||||
*
|
*
|
||||||
|
@ -58,7 +149,9 @@ static void _arm_mpu_config(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable MPU */
|
/* Enable MPU */
|
||||||
ARM_MPU_DEV->ctrl = 1;
|
ARM_MPU_DEV->ctrl = ARM_MPU_ENABLE | ARM_MPU_PRIVDEFENA;
|
||||||
|
|
||||||
|
arm_mpu_enabled = 1;
|
||||||
|
|
||||||
/* Make sure that all the registers are set before proceeding */
|
/* Make sure that all the registers are set before proceeding */
|
||||||
__DSB();
|
__DSB();
|
||||||
|
|
|
@ -35,6 +35,14 @@ struct arm_mpu {
|
||||||
|
|
||||||
#define ARM_MPU_BASE 0xE000ED90
|
#define ARM_MPU_BASE 0xE000ED90
|
||||||
|
|
||||||
|
/* ARM MPU CTRL Register */
|
||||||
|
/* Enable MPU */
|
||||||
|
#define ARM_MPU_ENABLE (1 << 0)
|
||||||
|
/* Enable MPU during hard fault, NMI, and FAULTMASK handlers */
|
||||||
|
#define ARM_MPU_HFNMIENA (1 << 1)
|
||||||
|
/* Enable privileged software access to the default memory map */
|
||||||
|
#define ARM_MPU_PRIVDEFENA (1 << 2)
|
||||||
|
|
||||||
#define REGION_VALID (1 << 4)
|
#define REGION_VALID (1 << 4)
|
||||||
|
|
||||||
/* eXecute Never */
|
/* eXecute Never */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue