From e37214062cc3c8150aaa3e8d532c4d30748869b3 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Thu, 16 Mar 2017 14:28:35 +0000 Subject: [PATCH] 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 --- arch/arm/core/Kconfig | 4 ++ arch/arm/core/Makefile | 1 + arch/arm/core/cortex_m/mpu/Kconfig | 14 +++++ arch/arm/core/cortex_m/mpu/Makefile | 1 + arch/arm/core/cortex_m/mpu/arm_mpu.c | 78 ++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 arch/arm/core/cortex_m/mpu/Kconfig create mode 100644 arch/arm/core/cortex_m/mpu/Makefile create mode 100644 arch/arm/core/cortex_m/mpu/arm_mpu.c diff --git a/arch/arm/core/Kconfig b/arch/arm/core/Kconfig index 9f60e63b87f..7053a3172a2 100644 --- a/arch/arm/core/Kconfig +++ b/arch/arm/core/Kconfig @@ -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 diff --git a/arch/arm/core/Makefile b/arch/arm/core/Makefile index 0e237f796ec..b30ecf885e2 100644 --- a/arch/arm/core/Makefile +++ b/arch/arm/core/Makefile @@ -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/ diff --git a/arch/arm/core/cortex_m/mpu/Kconfig b/arch/arm/core/cortex_m/mpu/Kconfig new file mode 100644 index 00000000000..1fe13ae0408 --- /dev/null +++ b/arch/arm/core/cortex_m/mpu/Kconfig @@ -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 diff --git a/arch/arm/core/cortex_m/mpu/Makefile b/arch/arm/core/cortex_m/mpu/Makefile new file mode 100644 index 00000000000..2b08f730435 --- /dev/null +++ b/arch/arm/core/cortex_m/mpu/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ARM_MPU) += arm_mpu.o diff --git a/arch/arm/core/cortex_m/mpu/arm_mpu.c b/arch/arm/core/cortex_m/mpu/arm_mpu.c new file mode 100644 index 00000000000..6b3452e7954 --- /dev/null +++ b/arch/arm/core/cortex_m/mpu/arm_mpu.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017 Linaro Limited. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#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);