arch: arc: Add mpu support
* add arc mpu driver * modify the corresponding kconfig and kbuild * currently only em_starterkit 2.2's em7d configuration has mpu feature (mpu version 2) * as the minimum region size of arc mpu version 2 is 2048 bytes and region size should be power of 2, the stack size of threads (including main thread and idle thread) should be at least 2048 bytes and power of 2 * for mpu stack guard feature, a stack guard region of 2048 bytes is generated. This brings more memory footprint * For arc mpu version 3, the minimum region size is 32 bytes. * the codes are tested by the mpu_stack_guard_test and stackprot Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
parent
e314de5d53
commit
12cc6598b0
16 changed files with 548 additions and 1 deletions
|
@ -186,6 +186,21 @@ config FP_SHARING
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
menu "ARC MPU Options"
|
||||||
|
depends on CPU_HAS_MPU
|
||||||
|
|
||||||
|
config ARC_MPU_ENABLE
|
||||||
|
bool "Enable MPU"
|
||||||
|
depends on CPU_HAS_MPU
|
||||||
|
select ARC_MPU
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable MPU
|
||||||
|
|
||||||
|
source "arch/arc/core/mpu/Kconfig"
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
config ICCM_SIZE
|
config ICCM_SIZE
|
||||||
int "ICCM Size in kB"
|
int "ICCM Size in kB"
|
||||||
help
|
help
|
||||||
|
|
|
@ -16,3 +16,5 @@ obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
||||||
# Some ARC cores like the EM4 lack the atomic LLOCK/SCOND and
|
# Some ARC cores like the EM4 lack the atomic LLOCK/SCOND and
|
||||||
# can't use these.
|
# can't use these.
|
||||||
obj-$(CONFIG_ATOMIC_OPERATIONS_CUSTOM) += atomic.o
|
obj-$(CONFIG_ATOMIC_OPERATIONS_CUSTOM) += atomic.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_CPU_HAS_MPU) += mpu/
|
||||||
|
|
|
@ -257,6 +257,13 @@ _firq_reschedule:
|
||||||
*/
|
*/
|
||||||
_load_callee_saved_regs
|
_load_callee_saved_regs
|
||||||
|
|
||||||
|
#ifdef CONFIG_MPU_STACK_GUARD
|
||||||
|
push_s r2
|
||||||
|
mov r0, r2
|
||||||
|
bl configure_mpu_stack_guard
|
||||||
|
pop_s r2
|
||||||
|
#endif
|
||||||
|
|
||||||
ld_s r3, [r2, _thread_offset_to_relinquish_cause]
|
ld_s r3, [r2, _thread_offset_to_relinquish_cause]
|
||||||
|
|
||||||
breq r3, _CAUSE_RIRQ, _firq_return_from_rirq
|
breq r3, _CAUSE_RIRQ, _firq_return_from_rirq
|
||||||
|
|
38
arch/arc/core/mpu/Kconfig
Normal file
38
arch/arc/core/mpu/Kconfig
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Kconfig - Memory Protection Unit (MPU) configuration options
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017 Synopsys
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
config ARC_MPU_VER
|
||||||
|
int
|
||||||
|
prompt "ARC MPU version"
|
||||||
|
range 2 4
|
||||||
|
default 2
|
||||||
|
help
|
||||||
|
ARC MPU has several versions. For MPU v2, the minimum region is 2048 bytes;
|
||||||
|
For MPU v3, the minimum region is 32 bytes
|
||||||
|
|
||||||
|
config ARC_CORE_MPU
|
||||||
|
bool "ARC Core MPU functionalities"
|
||||||
|
depends on CPU_HAS_MPU
|
||||||
|
select THREAD_STACK_INFO
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
ARC Core MPU functionalities
|
||||||
|
|
||||||
|
config MPU_STACK_GUARD
|
||||||
|
bool "Thread Stack Guards"
|
||||||
|
depends on ARC_CORE_MPU
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable Thread Stack Guards via MPU
|
||||||
|
|
||||||
|
config ARC_MPU
|
||||||
|
bool "ARC MPU Support"
|
||||||
|
depends on CPU_HAS_MPU
|
||||||
|
select ARC_CORE_MPU
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Target has ARC MPU (currently only works for EMSK 2.2 ARCEM7D)
|
2
arch/arc/core/mpu/Makefile
Normal file
2
arch/arc/core/mpu/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
obj-$(CONFIG_ARC_CORE_MPU) += arc_core_mpu.o
|
||||||
|
obj-$(CONFIG_ARC_MPU) += arc_mpu.o
|
30
arch/arc/core/mpu/arc_core_mpu.c
Normal file
30
arch/arc/core/mpu/arc_core_mpu.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Synopsys.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <soc.h>
|
||||||
|
#include <arch/arc/v2/mpu/arc_core_mpu.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_MPU_STACK_GUARD)
|
||||||
|
/*
|
||||||
|
* @brief Configure MPU stack guard
|
||||||
|
*
|
||||||
|
* This function configures per thread stack guards reprogramming the MPU.
|
||||||
|
* The functionality is meant to be used during context switch.
|
||||||
|
*
|
||||||
|
* @param thread thread info data structure.
|
||||||
|
*/
|
||||||
|
void configure_mpu_stack_guard(struct k_thread *thread)
|
||||||
|
{
|
||||||
|
arc_core_mpu_disable();
|
||||||
|
arc_core_mpu_configure(THREAD_STACK_GUARD_REGION,
|
||||||
|
thread->stack_info.start - STACK_ALIGN,
|
||||||
|
thread->stack_info.size);
|
||||||
|
arc_core_mpu_enable();
|
||||||
|
}
|
||||||
|
#endif
|
201
arch/arc/core/mpu/arc_mpu.c
Normal file
201
arch/arc/core/mpu/arc_mpu.c
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Synopsys.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <soc.h>
|
||||||
|
#include <arch/arc/v2/aux_regs.h>
|
||||||
|
#include <arch/arc/v2/mpu/arc_mpu.h>
|
||||||
|
#include <arch/arc/v2/mpu/arc_core_mpu.h>
|
||||||
|
#include <logging/sys_log.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define AUX_MPU_RDB_VALID_MASK (0x1)
|
||||||
|
#define AUX_MPU_EN_ENABLE (0x40000000)
|
||||||
|
#define AUX_MPU_EN_DISABLE (0x0)
|
||||||
|
|
||||||
|
#define AUX_MPU_RDP_REGION_SIZE(bits) \
|
||||||
|
(((bits - 1) & 0x3) | (((bits - 1) & 0x1C) << 7))
|
||||||
|
|
||||||
|
#define _ARC_V2_MPU_EN (0x409)
|
||||||
|
#define _ARC_V2_MPU_RDB0 (0x422)
|
||||||
|
#define _ARC_V2_MPU_RDP0 (0x423)
|
||||||
|
|
||||||
|
/* For MPU version 2, the minimum protection region size is 2048 bytes */
|
||||||
|
/* FOr MPU version 3, the minimum protection region size is 32 bytes */
|
||||||
|
#if CONFIG_ARC_MPU_VER == 2
|
||||||
|
#define ARC_FEATURE_MPU_ALIGNMENT_BITS 11
|
||||||
|
#elif CONFIG_ARC_MPU_VER == 3
|
||||||
|
#define ARC_FEATURE_MPU_ALIGNMENT_BITS 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the number of supported mpu regions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static inline u8_t _get_num_regions(void)
|
||||||
|
{
|
||||||
|
u32_t num = _arc_v2_aux_reg_read(_ARC_V2_MPU_BUILD);
|
||||||
|
|
||||||
|
num = (num & 0xFF00) >> 8;
|
||||||
|
|
||||||
|
return (u8_t)num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
||||||
|
/* no Read, Write and Execute to guard region */
|
||||||
|
return AUX_MPU_RDP_REGION_SIZE(
|
||||||
|
ARC_FEATURE_MPU_ALIGNMENT_BITS);
|
||||||
|
default:
|
||||||
|
/* Size 0 region */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _region_init(u32_t index, u32_t region_addr,
|
||||||
|
u32_t region_attr)
|
||||||
|
{
|
||||||
|
|
||||||
|
index = 2 * index;
|
||||||
|
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_MPU_RDP0 + index, region_attr);
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_MPU_RDB0 + index, region_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ARC Core MPU Driver API Implementation for ARC MPU */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief enable the MPU
|
||||||
|
*/
|
||||||
|
void arc_core_mpu_enable(void)
|
||||||
|
{
|
||||||
|
/* Enable MPU */
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_MPU_EN, AUX_MPU_EN_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief disable the MPU
|
||||||
|
*/
|
||||||
|
void arc_core_mpu_disable(void)
|
||||||
|
{
|
||||||
|
/* Disable MPU */
|
||||||
|
_arc_v2_aux_reg_write(_ARC_V2_MPU_EN, AUX_MPU_EN_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 arc_core_mpu_configure(u8_t type, u32_t base, u32_t size)
|
||||||
|
{
|
||||||
|
u32_t region_index;
|
||||||
|
u32_t region_attr;
|
||||||
|
|
||||||
|
SYS_LOG_DBG("Region info: 0x%x 0x%x", base, size);
|
||||||
|
/*
|
||||||
|
* The new MPU regions are allocated per type before
|
||||||
|
* the statically configured regions.
|
||||||
|
*
|
||||||
|
* For ARC MPU v2, MPU regions can be overlapped, smaller
|
||||||
|
* region index has higher priority.
|
||||||
|
*/
|
||||||
|
|
||||||
|
region_index = _get_num_regions() - mpu_config.num_regions;
|
||||||
|
|
||||||
|
if (type > region_index) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
region_index -= type;
|
||||||
|
region_attr = _get_region_attr_by_type(type, size);
|
||||||
|
|
||||||
|
if (region_attr == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base |= AUX_MPU_RDB_VALID_MASK;
|
||||||
|
|
||||||
|
_region_init(region_index, base, region_attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARC MPU Driver Initial Setup */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief MPU default configuration
|
||||||
|
*
|
||||||
|
* This function provides the default configuration mechanism for the Memory
|
||||||
|
* Protection Unit (MPU).
|
||||||
|
*/
|
||||||
|
static void _arc_mpu_config(void)
|
||||||
|
{
|
||||||
|
u32_t r_index;
|
||||||
|
u32_t num_regions;
|
||||||
|
u32_t i;
|
||||||
|
|
||||||
|
num_regions = _get_num_regions();
|
||||||
|
|
||||||
|
/* ARC MPU supports up to 16 Regions */
|
||||||
|
if (mpu_config.num_regions > num_regions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the MPU regions are filled in the reverse order.
|
||||||
|
* According to ARCv2 ISA, the mpu region with smaller
|
||||||
|
* index has higher priority. The static background mpu
|
||||||
|
* regions in mpu_config will be in the bottom. Then
|
||||||
|
* the special type regions will be above.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
r_index = num_regions - mpu_config.num_regions;
|
||||||
|
/* Disable MPU */
|
||||||
|
arc_core_mpu_disable();
|
||||||
|
|
||||||
|
/* clear the regions reserved for special type */
|
||||||
|
for (i = 0; i < r_index; i++) {
|
||||||
|
_region_init(i, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* configure the static regions */
|
||||||
|
for (r_index = 0; i < num_regions; i++) {
|
||||||
|
_region_init(i,
|
||||||
|
mpu_config.mpu_regions[r_index].base
|
||||||
|
| AUX_MPU_RDB_VALID_MASK,
|
||||||
|
mpu_config.mpu_regions[r_index].attr);
|
||||||
|
r_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable MPU */
|
||||||
|
arc_core_mpu_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_mpu_init(struct device *arg)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(arg);
|
||||||
|
|
||||||
|
_arc_mpu_config();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_INIT(arc_mpu_init, PRE_KERNEL_1,
|
||||||
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
|
|
@ -161,6 +161,13 @@ _rirq_common_interrupt_swap:
|
||||||
*/
|
*/
|
||||||
_load_callee_saved_regs
|
_load_callee_saved_regs
|
||||||
|
|
||||||
|
#ifdef CONFIG_MPU_STACK_GUARD
|
||||||
|
push_s r2
|
||||||
|
mov r0, r2
|
||||||
|
bl configure_mpu_stack_guard
|
||||||
|
pop_s r2
|
||||||
|
#endif
|
||||||
|
|
||||||
ld_s r3, [r2, _thread_offset_to_relinquish_cause]
|
ld_s r3, [r2, _thread_offset_to_relinquish_cause]
|
||||||
|
|
||||||
breq r3, _CAUSE_RIRQ, _rirq_return_from_rirq
|
breq r3, _CAUSE_RIRQ, _rirq_return_from_rirq
|
||||||
|
|
|
@ -110,6 +110,13 @@ SECTION_FUNC(TEXT, __swap)
|
||||||
|
|
||||||
_load_callee_saved_regs
|
_load_callee_saved_regs
|
||||||
|
|
||||||
|
#ifdef CONFIG_MPU_STACK_GUARD
|
||||||
|
push_s r2
|
||||||
|
mov r0, r2
|
||||||
|
bl configure_mpu_stack_guard
|
||||||
|
pop_s r2
|
||||||
|
#endif
|
||||||
|
|
||||||
ld_s r3, [r2, _thread_offset_to_relinquish_cause]
|
ld_s r3, [r2, _thread_offset_to_relinquish_cause]
|
||||||
|
|
||||||
breq r3, _CAUSE_RIRQ, _swap_return_from_rirq
|
breq r3, _CAUSE_RIRQ, _swap_return_from_rirq
|
||||||
|
|
|
@ -5,4 +5,6 @@ ccflags-y +=-I$(srctree)/drivers
|
||||||
|
|
||||||
asflags-y := ${ccflags-y}
|
asflags-y := ${ccflags-y}
|
||||||
|
|
||||||
obj-y = soc.o soc_config.o
|
obj-y += soc.o soc_config.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_ARC_MPU_ENABLE) += arc_mpu_regions.o
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
config SOC_EM7D
|
config SOC_EM7D
|
||||||
bool "Synopsys ARC EM7D"
|
bool "Synopsys ARC EM7D"
|
||||||
|
select CPU_HAS_MPU
|
||||||
|
|
38
arch/arc/soc/em7d/arc_mpu_regions.c
Normal file
38
arch/arc/soc/em7d/arc_mpu_regions.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Synopsys
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <soc.h>
|
||||||
|
#include <arch/arc/v2/mpu/arc_mpu.h>
|
||||||
|
|
||||||
|
static struct arc_mpu_region mpu_regions[] = {
|
||||||
|
#if CONFIG_ICCM_SIZE > 0
|
||||||
|
/* Region ICCM */
|
||||||
|
MPU_REGION_ENTRY("ICCM",
|
||||||
|
CONFIG_ICCM_BASE_ADDRESS,
|
||||||
|
REGION_FLASH_ATTR(REGION_256K)),
|
||||||
|
#endif
|
||||||
|
#if CONFIG_DCCM_SIZE > 0
|
||||||
|
/* Region DCCM */
|
||||||
|
MPU_REGION_ENTRY("DCCM",
|
||||||
|
CONFIG_DCCM_BASE_ADDRESS,
|
||||||
|
REGION_RAM_ATTR(REGION_128K)),
|
||||||
|
#endif
|
||||||
|
#if CONFIG_SRAM_SIZE > 0
|
||||||
|
/* Region DDR RAM */
|
||||||
|
MPU_REGION_ENTRY("DDR RAM",
|
||||||
|
CONFIG_SRAM_BASE_ADDRESS,
|
||||||
|
REGION_ALL_ATTR(REGION_128M)),
|
||||||
|
#endif
|
||||||
|
/* Region Peripheral */
|
||||||
|
MPU_REGION_ENTRY("PERIPHERAL",
|
||||||
|
0xF0000000,
|
||||||
|
REGION_IO_ATTR(REGION_64K)),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arc_mpu_config mpu_config = {
|
||||||
|
.num_regions = ARRAY_SIZE(mpu_regions),
|
||||||
|
.mpu_regions = mpu_regions,
|
||||||
|
};
|
|
@ -16,6 +16,7 @@ choice
|
||||||
bool "2.2"
|
bool "2.2"
|
||||||
|
|
||||||
config BOARD_EM_STARTERKIT_R23
|
config BOARD_EM_STARTERKIT_R23
|
||||||
|
depends on (SOC_EM9D || SOC_EM11D)
|
||||||
bool "2.3"
|
bool "2.3"
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
|
@ -38,7 +38,37 @@ extern "C" {
|
||||||
#include <arch/arc/v2/addr_types.h>
|
#include <arch/arc/v2/addr_types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_MPU_STACK_GUARD)
|
||||||
|
#if defined(CONFIG_ARC_CORE_MPU)
|
||||||
|
#if CONFIG_ARC_MPU_VER == 2
|
||||||
|
/* The minimum MPU region of MPU v2 is 2048 bytes */
|
||||||
|
#define STACK_ALIGN 2048
|
||||||
|
#elif CONFIG_ARC_MPU_VER == 3
|
||||||
|
#define STACK_ALIGN 32
|
||||||
|
#endif
|
||||||
|
#else /* CONFIG_ARC_CORE_MPU */
|
||||||
|
#error "Unsupported STACK_ALIGN"
|
||||||
|
#endif
|
||||||
|
#else /* CONFIG_MPU_STACK_GUARD */
|
||||||
#define STACK_ALIGN 4
|
#define STACK_ALIGN 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _ARCH_THREAD_STACK_DEFINE(sym, size) \
|
||||||
|
struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) \
|
||||||
|
sym[size+STACK_ALIGN]
|
||||||
|
|
||||||
|
#define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \
|
||||||
|
struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) \
|
||||||
|
sym[nmemb][size+STACK_ALIGN]
|
||||||
|
|
||||||
|
#define _ARCH_THREAD_STACK_MEMBER(sym, size) \
|
||||||
|
struct _k_thread_stack_element __aligned(STACK_ALIGN) \
|
||||||
|
sym[size+STACK_ALIGN]
|
||||||
|
|
||||||
|
#define _ARCH_THREAD_STACK_SIZEOF(sym) (sizeof(sym) - STACK_ALIGN)
|
||||||
|
|
||||||
|
#define _ARCH_THREAD_STACK_BUFFER(sym) ((char *)(sym + STACK_ALIGN))
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
66
include/arch/arc/v2/mpu/arc_core_mpu.h
Normal file
66
include/arch/arc/v2/mpu/arc_core_mpu.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Synopsys.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#ifndef _ARC_CORE_MPU_H_
|
||||||
|
#define _ARC_CORE_MPU_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The defines below represent the region types. The MPU driver is responsible
|
||||||
|
* to allocate the region accordingly to the type and set the correct
|
||||||
|
* attributes.
|
||||||
|
*
|
||||||
|
* Each MPU is different and has a different set of attributes, hence instead
|
||||||
|
* of having the attributes at this level the arm_mpu_core defines the intent
|
||||||
|
* types.
|
||||||
|
* An intent type (i.e. THREAD_STACK_GUARD) can correspond to a different set
|
||||||
|
* of operations and attributes for each MPU and it is responsibility of the
|
||||||
|
* MPU driver to select the correct ones.
|
||||||
|
*
|
||||||
|
* The intent based configuration can't fail hence at this level no error
|
||||||
|
* is returned by the configuration functions.
|
||||||
|
* If one of the operations corresponding to an intent fails the error has to
|
||||||
|
* be managed inside the MPU driver and not escalated.
|
||||||
|
*/
|
||||||
|
/* Thread Stack Region Intent Type */
|
||||||
|
#define THREAD_STACK_REGION 0x1
|
||||||
|
#define THREAD_STACK_GUARD_REGION 0x2
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARC_CORE_MPU)
|
||||||
|
/* ARC Core MPU Driver API */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This API has to be implemented by all the MPU drivers that have
|
||||||
|
* ARC_CORE_MPU support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief enable the MPU
|
||||||
|
*/
|
||||||
|
void arc_core_mpu_enable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief disable the MPU
|
||||||
|
*/
|
||||||
|
void arc_core_mpu_disable(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 arc_core_mpu_configure(u8_t type, u32_t base, u32_t size);
|
||||||
|
#endif /* CONFIG_ARC_CORE_MPU */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _ARC_CORE_MPU_H_ */
|
100
include/arch/arc/v2/mpu/arc_mpu.h
Normal file
100
include/arch/arc/v2/mpu/arc_mpu.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017 Synopsys.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#ifndef _ARC_MPU_H_
|
||||||
|
#define _ARC_MPU_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define AUX_MPU_RDP_UE 0x008 /* allow user execution */
|
||||||
|
#define AUX_MPU_RDP_UW 0x010 /* allow user write */
|
||||||
|
#define AUX_MPU_RDP_UR 0x020 /* allow user read */
|
||||||
|
#define AUX_MPU_RDP_KE 0x040 /* only allow kernel execution */
|
||||||
|
#define AUX_MPU_RDP_KW 0x080 /* only allow kernel write */
|
||||||
|
#define AUX_MPU_RDP_KR 0x100 /* only allow kernel read */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Some helper defines for common regions */
|
||||||
|
#define REGION_RAM_ATTR(size) \
|
||||||
|
(AUX_MPU_RDP_UW | AUX_MPU_RDP_UR | \
|
||||||
|
AUX_MPU_RDP_KW | AUX_MPU_RDP_KR | \
|
||||||
|
size)
|
||||||
|
|
||||||
|
#define REGION_FLASH_ATTR(size) \
|
||||||
|
(AUX_MPU_RDP_UE | AUX_MPU_RDP_UR | \
|
||||||
|
AUX_MPU_RDP_KE | AUX_MPU_RDP_KR | \
|
||||||
|
size)
|
||||||
|
|
||||||
|
#define REGION_IO_ATTR(size) \
|
||||||
|
(AUX_MPU_RDP_UW | AUX_MPU_RDP_UR | \
|
||||||
|
AUX_MPU_RDP_KW | AUX_MPU_RDP_KR | \
|
||||||
|
size)
|
||||||
|
|
||||||
|
#define REGION_ALL_ATTR(size) \
|
||||||
|
(AUX_MPU_RDP_UW | AUX_MPU_RDP_UR | \
|
||||||
|
AUX_MPU_RDP_KW | AUX_MPU_RDP_KR | \
|
||||||
|
AUX_MPU_RDP_KE | AUX_MPU_RDP_UE | \
|
||||||
|
size)
|
||||||
|
|
||||||
|
|
||||||
|
#define REGION_32B 0x200
|
||||||
|
#define REGION_64B 0x201
|
||||||
|
#define REGION_128B 0x202
|
||||||
|
#define REGION_256B 0x203
|
||||||
|
#define REGION_512B 0x400
|
||||||
|
#define REGION_1K 0x401
|
||||||
|
#define REGION_2K 0x402
|
||||||
|
#define REGION_4K 0x403
|
||||||
|
#define REGION_8K 0x600
|
||||||
|
#define REGION_16K 0x601
|
||||||
|
#define REGION_32K 0x602
|
||||||
|
#define REGION_64K 0x603
|
||||||
|
#define REGION_128K 0x800
|
||||||
|
#define REGION_256K 0x801
|
||||||
|
#define REGION_512K 0x802
|
||||||
|
#define REGION_1M 0x803
|
||||||
|
#define REGION_2M 0xA00
|
||||||
|
#define REGION_4M 0xA01
|
||||||
|
#define REGION_8M 0xA02
|
||||||
|
#define REGION_16M 0xA03
|
||||||
|
#define REGION_32M 0xC00
|
||||||
|
#define REGION_64M 0xC01
|
||||||
|
#define REGION_128M 0xC02
|
||||||
|
#define REGION_256M 0xC03
|
||||||
|
#define REGION_512M 0xE00
|
||||||
|
#define REGION_1G 0xE01
|
||||||
|
#define REGION_2G 0xE02
|
||||||
|
#define REGION_4G 0xE03
|
||||||
|
|
||||||
|
/* Region definition data structure */
|
||||||
|
struct arc_mpu_region {
|
||||||
|
/* Region Base Address */
|
||||||
|
u32_t base;
|
||||||
|
/* Region Name */
|
||||||
|
const char *name;
|
||||||
|
/* Region Attributes */
|
||||||
|
u32_t attr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MPU_REGION_ENTRY(_name, _base, _attr) \
|
||||||
|
{\
|
||||||
|
.name = _name, \
|
||||||
|
.base = _base, \
|
||||||
|
.attr = _attr, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MPU configuration data structure */
|
||||||
|
struct arc_mpu_config {
|
||||||
|
/* Number of regions */
|
||||||
|
u32_t num_regions;
|
||||||
|
/* Regions */
|
||||||
|
struct arc_mpu_region *mpu_regions;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Reference to the MPU configuration */
|
||||||
|
extern struct arc_mpu_config mpu_config;
|
||||||
|
|
||||||
|
#endif /* _ARC_CORE_MPU_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue