arm: soc: nxp k6x: Add Initial support for NXP MPU
This patch adds initial MPU support to NXP K6x family. The boot configuration prevents the following security issues: * Prevent to read at an address that is reserved in the memory map. * Prevent to write into the boot Flash/ROM. * Prevent from running code located in SRAM. This driver has been tested on FRDM-K64F. Change-Id: I907168fff0c6028f1c665f1d3c224cbeec31be32 Signed-off-by: Vincenzo Frascino <vincenzo.frascino@linaro.org>
This commit is contained in:
parent
d30d90257c
commit
adf0bf90b6
10 changed files with 267 additions and 0 deletions
|
@ -13,3 +13,11 @@ config ARM_MPU
|
|||
default n
|
||||
help
|
||||
MCU has ARM MPU
|
||||
|
||||
config NXP_MPU
|
||||
bool "NXP MPU Support"
|
||||
depends on CPU_HAS_MPU
|
||||
depends on SOC_FAMILY_KINETIS
|
||||
default n
|
||||
help
|
||||
MCU has NXP MPU
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
obj-$(CONFIG_ARM_MPU) += arm_mpu.o
|
||||
obj-$(CONFIG_NXP_MPU) += nxp_mpu.o
|
||||
|
|
128
arch/arm/core/cortex_m/mpu/nxp_mpu.c
Normal file
128
arch/arm/core/cortex_m/mpu/nxp_mpu.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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/nxp_mpu.h>
|
||||
#include <logging/sys_log.h>
|
||||
#include <misc/__assert.h>
|
||||
|
||||
static inline u8_t _get_num_regions(void)
|
||||
{
|
||||
u32_t type = (SYSMPU->CESR & SYSMPU_CESR_NRGD_MASK)
|
||||
>> SYSMPU_CESR_NRGD_SHIFT;
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
return 8;
|
||||
case 1:
|
||||
return 12;
|
||||
case 2:
|
||||
return 16;
|
||||
default:
|
||||
__ASSERT(0, "Unsupported MPU configuration.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return NXP_MPU_REGION_NUMBER;
|
||||
}
|
||||
|
||||
static void _region_init(u32_t index, u32_t region_base,
|
||||
u32_t region_end, u32_t region_attr)
|
||||
{
|
||||
SYSMPU->WORD[index][0] = region_base;
|
||||
SYSMPU->WORD[index][1] = region_end;
|
||||
SYSMPU->WORD[index][2] = region_attr;
|
||||
SYSMPU->WORD[index][3] = SYSMPU_WORD_VLD_MASK;
|
||||
|
||||
SYS_LOG_DBG("[%d] 0x%08x 0x%08x 0x%08x 0x%08x", index,
|
||||
SYSMPU->WORD[index][0],
|
||||
SYSMPU->WORD[index][1],
|
||||
SYSMPU->WORD[index][2],
|
||||
SYSMPU->WORD[index][3]);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief MPU default configuration
|
||||
*
|
||||
* This function provides the default configuration mechanism for the Memory
|
||||
* Protection Unit (MPU).
|
||||
*/
|
||||
static void _nxp_mpu_config(void)
|
||||
{
|
||||
u32_t r_index;
|
||||
|
||||
SYS_LOG_DBG("region number: %d", _get_num_regions());
|
||||
|
||||
/* NXP MPU supports up to 16 Regions */
|
||||
if (mpu_config.num_regions > _get_num_regions()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable MPU */
|
||||
SYSMPU->CESR &= ~SYSMPU_CESR_VLD_MASK;
|
||||
/* Clear Interrupts */
|
||||
SYSMPU->CESR |= SYSMPU_CESR_SPERR_MASK;
|
||||
|
||||
/* MPU Configuration */
|
||||
|
||||
/* Disable Region 0 */
|
||||
SYSMPU->WORD[0][2] = 0;
|
||||
|
||||
/*
|
||||
* Configure regions:
|
||||
* r_index starts from 0 but is passed to region_init as r_index + 1,
|
||||
* region 0 is not configurable
|
||||
*/
|
||||
for (r_index = 0; r_index < mpu_config.num_regions; r_index++) {
|
||||
_region_init(r_index + 1,
|
||||
mpu_config.mpu_regions[r_index].base,
|
||||
mpu_config.mpu_regions[r_index].end,
|
||||
mpu_config.mpu_regions[r_index].attr);
|
||||
}
|
||||
|
||||
/* Enable MPU */
|
||||
SYSMPU->CESR |= SYSMPU_CESR_VLD_MASK;
|
||||
|
||||
/* Make sure that all the registers are set before proceeding */
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief MPU clock configuration
|
||||
*
|
||||
* This function provides the clock configuration for the Memory Protection
|
||||
* Unit (MPU).
|
||||
*/
|
||||
static void _nxp_mpu_clock_cfg(void)
|
||||
{
|
||||
/* Enable Clock */
|
||||
CLOCK_EnableClock(kCLOCK_Sysmpu0);
|
||||
}
|
||||
|
||||
static int nxp_mpu_init(struct device *arg)
|
||||
{
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
_nxp_mpu_clock_cfg();
|
||||
|
||||
_nxp_mpu_config();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYS_LOG)
|
||||
/* To have logging the driver needs to be initialized later */
|
||||
SYS_INIT(nxp_mpu_init, POST_KERNEL,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||
#else
|
||||
SYS_INIT(nxp_mpu_init, PRE_KERNEL_1,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue