arm: core: mpu: Add ARM MPU support

This patch adds an initial driver for the ARM MPU.
This driver has been tested on ARM Beetle and STM32F4.

Change-Id: I2bc4031961ec5a1d569929249237646f4a349f16
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@linaro.org>
This commit is contained in:
Vincenzo Frascino 2017-03-16 14:28:35 +00:00 committed by Kumar Gala
commit e37214062c
5 changed files with 98 additions and 0 deletions

View file

@ -96,3 +96,7 @@ endmenu
if CPU_CORTEX_M
source "arch/arm/core/cortex_m/Kconfig"
endif
if CPU_HAS_MPU
source "arch/arm/core/cortex_m/mpu/Kconfig"
endif

View file

@ -8,3 +8,4 @@ obj-$(CONFIG_GEN_SW_ISR_TABLE) += isr_wrapper.o
obj-$(CONFIG_CPLUSPLUS) += __aeabi_atexit.o
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
obj-$(CONFIG_CPU_CORTEX_M) += cortex_m/
obj-$(CONFIG_CPU_HAS_MPU) += cortex_m/mpu/

View file

@ -0,0 +1,14 @@
# Kconfig - Memory Protection Unit (MPU) configuration options
#
# Copyright (c) 2017 Linaro Limited
#
# SPDX-License-Identifier: Apache-2.0
#
config ARM_MPU
bool "ARM MPU Support"
depends on CPU_HAS_MPU
default n
help
MCU has ARM MPU

View file

@ -0,0 +1 @@
obj-$(CONFIG_ARM_MPU) += arm_mpu.o

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2017 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <init.h>
#include <kernel.h>
#include <soc.h>
#include <arch/arm/cortex_m/cmsis.h>
#include <arch/arm/cortex_m/mpu/arm_mpu.h>
#define ARM_MPU_DEV ((volatile struct arm_mpu *) ARM_MPU_BASE)
static inline u8_t _get_num_regions(void)
{
u32_t type = ARM_MPU_DEV->type;
type = (type & 0xFF00) >> 8;
return (u8_t)type;
}
static void _region_init(u32_t index, u32_t region_addr,
u32_t region_attr)
{
/* Select the region you want to access */
ARM_MPU_DEV->rnr = index;
/* Configure the region */
ARM_MPU_DEV->rbar = region_addr | REGION_VALID | index;
ARM_MPU_DEV->rasr = region_attr | REGION_ENABLE;
}
/*
* @brief MPU default configuration
*
* This function provides the default configuration mechanism for the Memory
* Protection Unit (MPU).
*/
static void _arm_mpu_config(void)
{
u32_t r_index;
/* ARM MPU supports up to 16 Regions */
if (mpu_config.num_regions > _get_num_regions()) {
return;
}
/* Disable MPU */
ARM_MPU_DEV->ctrl = 0;
/* Configure regions */
for (r_index = 0; r_index < mpu_config.num_regions; r_index++) {
_region_init(r_index,
mpu_config.mpu_regions[r_index].base,
mpu_config.mpu_regions[r_index].attr);
}
/* Enable MPU */
ARM_MPU_DEV->ctrl = 1;
/* Make sure that all the registers are set before proceeding */
__DSB();
__ISB();
}
static int arm_mpu_init(struct device *arg)
{
ARG_UNUSED(arg);
_arm_mpu_config();
return 0;
}
SYS_INIT(arm_mpu_init, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);