arm_mpu:Reentrant allocation Region
Changes have been completed: 1.armv7m 2.armv8m 3.armv7r 4.arm64 Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
This commit is contained in:
parent
3a25286862
commit
62f598e547
8 changed files with 1753 additions and 693 deletions
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "mpu.h"
|
||||
#include "arm_internal.h"
|
||||
|
@ -69,9 +70,9 @@ static const uint8_t g_ls_regionmask[9] =
|
|||
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
|
||||
};
|
||||
|
||||
/* The next available region number */
|
||||
/* The available region bitmap */
|
||||
|
||||
static uint8_t g_region;
|
||||
static unsigned int g_mpu_region;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -89,6 +90,13 @@ static uint8_t g_region;
|
|||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* size: The size of the region.
|
||||
* l2size: The L2 size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The sub-region bitmask.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size)
|
||||
|
@ -140,6 +148,13 @@ static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size)
|
|||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* offset: The offset of the region.
|
||||
* l2size: The L2 size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The sub-region bitmask.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
||||
|
@ -184,6 +199,12 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
|||
* Description:
|
||||
* Resets the MPU to disabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
|
@ -218,17 +239,51 @@ static void mpu_reset_internal()
|
|||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Assumptions:
|
||||
* - Regions are never deallocated
|
||||
* - Regions are only allocated early in initialization, so no special
|
||||
* protection against re-entrancy is required;
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void)
|
||||
{
|
||||
DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS);
|
||||
return (unsigned int)g_region++;
|
||||
unsigned int i = ffs(~g_mpu_region) - 1;
|
||||
|
||||
/* There are not enough regions to apply */
|
||||
|
||||
DEBUGASSERT(i < CONFIG_ARM_MPU_NREGIONS);
|
||||
g_mpu_region |= 1 << i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region)
|
||||
{
|
||||
DEBUGASSERT(region < CONFIG_ARM_MPU_NREGIONS);
|
||||
|
||||
/* Clear and disable the given MPU Region */
|
||||
|
||||
putreg32(region, MPU_RNR);
|
||||
putreg32(0, MPU_RASR);
|
||||
putreg32(0, MPU_RBAR);
|
||||
g_mpu_region &= ~(1 << region);
|
||||
ARM_DSB();
|
||||
ARM_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -240,6 +295,12 @@ unsigned int mpu_allocregion(void)
|
|||
*
|
||||
* size <= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the ceiling value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionceil(size_t size)
|
||||
|
@ -261,6 +322,12 @@ uint8_t mpu_log2regionceil(size_t size)
|
|||
*
|
||||
* size >= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the floor value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionfloor(size_t size)
|
||||
|
@ -287,6 +354,14 @@ uint8_t mpu_log2regionfloor(size_t size)
|
|||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* l2size - Log2 of the actual region size is <= (1 << l2size).
|
||||
*
|
||||
* Returned Value:
|
||||
* The subregion settings as a 32-bit value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
||||
|
@ -338,6 +413,16 @@ uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
|||
* Description:
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - Flag indicating whether to enable the MPU.
|
||||
* hfnmiena - Flag indicating whether to enable the MPU during hard
|
||||
* fult, NMI, and FAULTMAS.
|
||||
* privdefena - Flag indicating whether to enable privileged access to
|
||||
* the default memory map.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_control(bool enable, bool hfnmiena, bool privdefena)
|
||||
|
@ -368,22 +453,34 @@ void mpu_control(bool enable, bool hfnmiena, bool privdefena)
|
|||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - Region number to modify.
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags)
|
||||
void mpu_modify_region(unsigned int region, uintptr_t base, size_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
uintptr_t alignedbase;
|
||||
|
||||
/* Check that the region is valid */
|
||||
|
||||
DEBUGASSERT(g_mpu_region & (1 << region));
|
||||
|
||||
/* Ensure the base address alignment
|
||||
*
|
||||
* ARMv7-M Architecture Reference Manual
|
||||
|
@ -429,6 +526,111 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
ARM_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
mpu_modify_region(region, base, size, flags);
|
||||
return region;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - MPU initialization table.
|
||||
* hfnmiena - A boolean indicating whether the MPU should enable the
|
||||
* HFNMIENA bit.
|
||||
* privdefena - A boolean indicating whether the MPU should enable the
|
||||
* PRIVDEFENA bit.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_initialize(const struct mpu_region_s *table, bool hfnmiena,
|
||||
bool privdefena)
|
||||
{
|
||||
const struct mpu_region_s *conf;
|
||||
int index;
|
||||
|
||||
mpu_control(false, false, false);
|
||||
for (index = 0; index < nitems(table); index++)
|
||||
{
|
||||
conf = &table[index];
|
||||
mpu_configure_region(conf->base, conf->size, conf->flags);
|
||||
}
|
||||
|
||||
mpu_control(true, hfnmiena, privdefena);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
uint32_t rasr;
|
||||
uint32_t rbar;
|
||||
uint32_t ctrl;
|
||||
|
||||
/* Get free region */
|
||||
|
||||
ctrl = getreg32(MPU_CTRL);
|
||||
_info("MPU-CTRL Enable:%" PRIu32 ", HFNMIENA:%"PRIu32","
|
||||
"PRIVDEFENA:%" PRIu32 "\n", ctrl & MPU_CTRL_ENABLE,
|
||||
ctrl & MPU_CTRL_HFNMIENA, ctrl & MPU_CTRL_PRIVDEFENA);
|
||||
for (i = 0; i < CONFIG_ARM_MPU_NREGIONS; i++)
|
||||
{
|
||||
putreg32(i, MPU_RNR);
|
||||
rasr = getreg32(MPU_RASR);
|
||||
rbar = getreg32(MPU_RBAR);
|
||||
_info("MPU-%d, alignedbase=0%08X l2size=%"PRIu32" SRD=%X"
|
||||
"AP=%X XN=%u\n", i, rbar & MPU_RBAR_ADDR_MASK,
|
||||
rasr & MPU_RASR_SIZE_MASK, rasr & MPU_RASR_SRD_MASK,
|
||||
rasr & MPU_RASR_AP_MASK, rasr & MPU_RASR_XN);
|
||||
if (rasr & MPU_RASR_ENABLE)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
_info("Total Use Region:%d, Remaining Available:%d\n", count,
|
||||
CONFIG_ARM_MPU_NREGIONS - count);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
|
@ -436,6 +638,12 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_RESET)
|
||||
void mpu_reset()
|
||||
|
@ -451,6 +659,12 @@ void mpu_reset()
|
|||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset()
|
||||
|
|
|
@ -130,6 +130,21 @@
|
|||
# define MPU_RASR_AP_RORO (6 << MPU_RASR_AP_SHIFT) /* P:RO U:RO */
|
||||
# define MPU_RASR_XN (1 << 28) /* Bit 28: Instruction access disable */
|
||||
|
||||
struct mpu_region_s
|
||||
{
|
||||
/* Region Base Address */
|
||||
|
||||
uintptr_t base;
|
||||
|
||||
/* Region Size */
|
||||
|
||||
size_t size;
|
||||
|
||||
/* Region Attributes */
|
||||
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
|
@ -137,6 +152,12 @@
|
|||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_RESET)
|
||||
|
@ -152,6 +173,12 @@ void mpu_reset(void);
|
|||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
|
@ -180,12 +207,34 @@ extern "C"
|
|||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
* Allocate the next region
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_log2regionceil
|
||||
*
|
||||
|
@ -195,6 +244,12 @@ unsigned int mpu_allocregion(void);
|
|||
*
|
||||
* size <= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the ceiling value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionceil(size_t size);
|
||||
|
@ -208,6 +263,12 @@ uint8_t mpu_log2regionceil(size_t size);
|
|||
*
|
||||
* size >= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the floor value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionfloor(size_t size);
|
||||
|
@ -216,14 +277,22 @@ uint8_t mpu_log2regionfloor(size_t size);
|
|||
* Name: mpu_subregion
|
||||
*
|
||||
* Description:
|
||||
* Given (1) the offset to the beginning of valid data, (2) the size of the
|
||||
* memory to be mapped and (2) the log2 size of the mapping to use,
|
||||
* determine the minimal sub-region set to span that memory region.
|
||||
* Given the size of the (1) memory to be mapped and (2) the log2 size
|
||||
* of the mapping to use, determine the minimal sub-region set to span
|
||||
* that memory region.
|
||||
*
|
||||
* Assumption:
|
||||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* l2size - Log2 of the actual region size is <= (1 << l2size).
|
||||
*
|
||||
* Returned Value:
|
||||
* The subregion settings as a 32-bit value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size);
|
||||
|
@ -234,19 +303,95 @@ uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size);
|
|||
* Description:
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - Flag indicating whether to enable the MPU.
|
||||
* hfnmiena - Flag indicating whether to enable the MPU during hard
|
||||
* fult, NMI, and FAULTMAS.
|
||||
* privdefena - Flag indicating whether to enable privileged access to
|
||||
* the default memory map.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_control(bool enable, bool hfnmiena, bool privdefena);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - Region number to modify.
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_modify_region(unsigned int region, uintptr_t base, size_t size,
|
||||
uint32_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
||||
unsigned int mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - MPU initialization table.
|
||||
* hfnmiena - A boolean indicating whether the MPU should enable the
|
||||
* HFNMIENA bit.
|
||||
* privdefena - A boolean indicating whether the MPU should enable the
|
||||
* PRIVDEFENA bit.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_initialize(const struct mpu_region_s *table, bool hfnmiena,
|
||||
bool privdefena);
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
|
@ -284,18 +429,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_stronglyordered(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
/* Not Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */); \
|
||||
} \
|
||||
while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
/* Not Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_flash
|
||||
|
@ -306,18 +447,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_flash(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Not Shareable */ \
|
||||
MPU_RASR_AP_RORO /* P:RO U:RO */ \
|
||||
/* Instruction access */); \
|
||||
} \
|
||||
while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Not Shareable */ \
|
||||
MPU_RASR_AP_RORO /* P:RO U:RO */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_flash
|
||||
|
@ -328,18 +465,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_flash(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Not Shareable */ \
|
||||
MPU_RASR_AP_RONO /* P:RO U:None */ \
|
||||
/* Instruction access */); \
|
||||
} \
|
||||
while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Not Shareable */ \
|
||||
MPU_RASR_AP_RONO /* P:RO U:None */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_intsram
|
||||
|
@ -350,18 +483,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_intsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW /* P:RW U:RW */ \
|
||||
/* Instruction access */); \
|
||||
} \
|
||||
while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW /* P:RW U:RW */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_intsram
|
||||
|
@ -372,18 +501,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_intsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */); \
|
||||
} \
|
||||
while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_shmem
|
||||
|
@ -393,18 +518,15 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_shmem(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO | /* P:RW U:None */ \
|
||||
MPU_RASR_XN /* No Instruction access */); \
|
||||
} while (0)
|
||||
#define mpu_priv_shmem(base, size) \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO | /* P:RW U:None */ \
|
||||
MPU_RASR_XN /* No Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_extsram
|
||||
|
@ -415,17 +537,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_extsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW /* P:RW U:RW */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW /* P:RW U:RW */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_extsram
|
||||
|
@ -436,17 +555,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_extsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_SO | /* Ordered */ \
|
||||
MPU_RASR_C | /* Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO /* P:RW U:None */ \
|
||||
/* Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_peripheral
|
||||
|
@ -457,17 +573,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_peripheral(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_DEV | /* Device */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO | /* P:RW U:None */ \
|
||||
MPU_RASR_XN /* No Instruction access */); \
|
||||
} while (0)
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_DEV | /* Device */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWNO | /* P:RW U:None */ \
|
||||
MPU_RASR_XN /* No Instruction access */)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_peripheral
|
||||
|
@ -478,17 +591,14 @@ void mpu_configure_region(uintptr_t base, size_t size, uint32_t flags);
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_peripheral(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_DEV | /* Device */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW | /* P:RW U:RW */ \
|
||||
MPU_RASR_XN /* No Instruction access */); \
|
||||
} while (0)
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RASR_TEX_DEV | /* Device */ \
|
||||
/* Not Cacheable */ \
|
||||
MPU_RASR_B | /* Bufferable */ \
|
||||
MPU_RASR_S | /* Shareable */ \
|
||||
MPU_RASR_AP_RWRW | /* P:RW U:RW */ \
|
||||
MPU_RASR_XN /* No Instruction access */)
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "mpu.h"
|
||||
#include "arm_internal.h"
|
||||
|
@ -68,9 +69,9 @@ static const uint8_t g_ls_regionmask[9] =
|
|||
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
|
||||
};
|
||||
|
||||
/* The next available region number */
|
||||
/* The available region bitmap */
|
||||
|
||||
static uint8_t g_region;
|
||||
static unsigned int g_mpu_region;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -88,6 +89,13 @@ static uint8_t g_region;
|
|||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* size: The size of the region.
|
||||
* l2size: The L2 size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The sub-region bitmask.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size)
|
||||
|
@ -139,6 +147,13 @@ static inline uint32_t mpu_subregion_ms(size_t size, uint8_t l2size)
|
|||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* offset: The offset of the region.
|
||||
* l2size: The L2 size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The sub-region bitmask.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
||||
|
@ -183,6 +198,12 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
|||
* Description:
|
||||
* Resets the MPU to disabled.
|
||||
*
|
||||
* * Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
|
@ -214,17 +235,52 @@ static void mpu_reset_internal()
|
|||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Assumptions:
|
||||
* - Regions are never deallocated
|
||||
* - Regions are only allocated early in initialization, so no special
|
||||
* protection against re-entrancy is required;
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void)
|
||||
{
|
||||
DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS);
|
||||
return (unsigned int)g_region++;
|
||||
unsigned int i = ffs(~g_mpu_region) - 1;
|
||||
|
||||
/* There are not enough regions to apply */
|
||||
|
||||
DEBUGASSERT(i < CONFIG_ARM_MPU_NREGIONS);
|
||||
g_mpu_region |= 1 << i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region)
|
||||
{
|
||||
DEBUGASSERT(region < CONFIG_ARM_MPU_NREGIONS);
|
||||
|
||||
/* Clear and disable the given MPU Region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
mpu_set_drbar(0);
|
||||
mpu_set_dracr(0);
|
||||
mpu_set_drsr(0);
|
||||
g_mpu_region &= ~(1 << region);
|
||||
ARM_DSB();
|
||||
ARM_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -236,6 +292,12 @@ unsigned int mpu_allocregion(void)
|
|||
*
|
||||
* size <= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the ceiling value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionceil(size_t size)
|
||||
|
@ -257,6 +319,12 @@ uint8_t mpu_log2regionceil(size_t size)
|
|||
*
|
||||
* size >= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the floor value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionfloor(size_t size)
|
||||
|
@ -283,6 +351,14 @@ uint8_t mpu_log2regionfloor(size_t size)
|
|||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* l2size - Log2 of the actual region size is <= (1 << l2size).
|
||||
*
|
||||
* Returned Value:
|
||||
* The subregion settings as a 32-bit value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
||||
|
@ -328,6 +404,156 @@ uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - Region number to modify.
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_modify_region(unsigned int region, uintptr_t base, size_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Check that the region is valid */
|
||||
|
||||
DEBUGASSERT(g_mpu_region & (1 << region));
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* Configure the Region */
|
||||
|
||||
mpu_set_dracr(flags);
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2(l2size) | /* Region size */
|
||||
(subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
mpu_modify_region(region, base, size, flags);
|
||||
return region;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - MPU Initiaze table.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_initialize(const struct mpu_region_s *table)
|
||||
{
|
||||
const struct mpu_region_s *conf;
|
||||
int index;
|
||||
|
||||
mpu_control(false);
|
||||
for (index = 0; index < nitems(table); index++)
|
||||
{
|
||||
conf = &table[index];
|
||||
mpu_configure_region(conf->base, conf->size, conf->flags);
|
||||
}
|
||||
|
||||
mpu_control(true);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
uint32_t dracr;
|
||||
uint32_t drbar;
|
||||
uint32_t drsr;
|
||||
uint32_t sctrl;
|
||||
|
||||
/* Get free region */
|
||||
|
||||
sctrl = cp15_rdsctlr();
|
||||
_info("MPU-SCTRL Enable:%" PRIu32 "\n", sctrl & SCTLR_M);
|
||||
for (i = 0; i < CONFIG_ARM_MPU_NREGIONS; i++)
|
||||
{
|
||||
mpu_set_rgnr(i);
|
||||
drbar = mpu_get_drbar();
|
||||
dracr = mpu_get_dracr();
|
||||
drsr = mpu_get_drsr();
|
||||
_info("MPU-%d, base=0%08X l2size=%"PRIu32" bufferable=%u"
|
||||
"cacheable=%u shareable=%u\n", i, drbar & MPU_RBAR_ADDR_MASK,
|
||||
drsr & MPU_RASR_RSIZE_MASK, dracr & MPU_RACR_B,
|
||||
dracr & MPU_RACR_C, dracr & MPU_RACR_S);
|
||||
if (drsr & MPU_RASR_ENABLE)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
_info("Total Use Region:%d, Remaining Available:%d\n", count,
|
||||
CONFIG_ARM_MPU_NREGIONS - count);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
|
@ -335,6 +561,12 @@ uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
|||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_RESET)
|
||||
void mpu_reset()
|
||||
|
@ -350,6 +582,12 @@ void mpu_reset()
|
|||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset()
|
||||
|
|
|
@ -126,6 +126,12 @@ extern "C"
|
|||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_RESET)
|
||||
|
@ -141,6 +147,12 @@ void mpu_reset(void);
|
|||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
|
@ -153,12 +165,34 @@ void mpu_early_reset(void);
|
|||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
* Allocate the next region
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_log2regionceil
|
||||
*
|
||||
|
@ -168,6 +202,12 @@ unsigned int mpu_allocregion(void);
|
|||
*
|
||||
* size <= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the ceiling value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionceil(size_t size);
|
||||
|
@ -181,26 +221,111 @@ uint8_t mpu_log2regionceil(size_t size);
|
|||
*
|
||||
* size >= (1 << l2size)
|
||||
*
|
||||
* Input Parameters:
|
||||
* size - The size of the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The logarithm base 2 of the floor value for the MPU region size.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mpu_log2regionfloor(size_t size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_subregion
|
||||
*
|
||||
* Description:
|
||||
* Given (1) the offset to the beginning of valid data, (2) the size of the
|
||||
* memory to be mapped and (2) the log2 size of the mapping to use,
|
||||
* determine the minimal sub-region set to span that memory region.
|
||||
* Given the size of the (1) memory to be mapped and (2) the log2 size
|
||||
* of the mapping to use, determine the minimal sub-region set to span
|
||||
* that memory region.
|
||||
*
|
||||
* Assumption:
|
||||
* l2size has the same properties as the return value from
|
||||
* mpu_log2regionceil()
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* l2size - Log2 of the actual region size is <= (1 << l2size).
|
||||
*
|
||||
* Returned Value:
|
||||
* The subregion settings as a 32-bit value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - Region number to modify.
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_modify_region(unsigned int region, uintptr_t base, size_t size,
|
||||
uint32_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - Base address of the region.
|
||||
* size - Size of the region.
|
||||
* flags - Flags to configure the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - MPU Initiaze table.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_initialize(const struct mpu_region_s *table);
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
@ -218,6 +343,45 @@ static inline unsigned int mpu_get_mpuir(void)
|
|||
return CP15_GET(MPUIR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_get_drbar
|
||||
*
|
||||
* Description:
|
||||
* Get the DRBAR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline unsigned int mpu_get_drbar(void)
|
||||
{
|
||||
return CP15_GET(DRBAR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_get_drsr
|
||||
*
|
||||
* Description:
|
||||
* Get the DRSR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline unsigned int mpu_get_drsr(void)
|
||||
{
|
||||
return CP15_GET(DRSR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_get_dracr
|
||||
*
|
||||
* Description:
|
||||
* Get the DRACR register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline unsigned int mpu_get_dracr(void)
|
||||
{
|
||||
return CP15_GET(DRACR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_set_drbar
|
||||
*
|
||||
|
@ -338,7 +502,13 @@ static inline void mpu_showtype(void)
|
|||
* Name: mpu_control
|
||||
*
|
||||
* Description:
|
||||
* Enable (or disable) the MPU
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - Flag indicating whether to enable the MPU.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -373,39 +543,12 @@ static inline void mpu_control(bool enable)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = /* Not Cacheable */
|
||||
/* Not Bufferable */
|
||||
MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_AP_RWNO; /* P:RW U:None */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_priv_stronglyordered(base, size) \
|
||||
/* Not Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Shareable */ \
|
||||
/* P:RW U:None */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | MPU_RACR_AP_RWNO)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_flash
|
||||
|
@ -415,38 +558,10 @@ static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_user_flash(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = /* Not Cacheable */
|
||||
MPU_RACR_C | /* Cacheable */
|
||||
MPU_RACR_AP_RORO; /* P:RO U:RO */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_user_flash(base, size) \
|
||||
/* Cacheable */ \
|
||||
/* P:RO U:RO */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_C | MPU_RACR_AP_RORO)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_noncache
|
||||
|
@ -456,43 +571,18 @@ static inline void mpu_user_flash(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_priv_noncache(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region
|
||||
* inner/outer non-cache : TEX(4), C(0), B(0), S(1)
|
||||
*/
|
||||
|
||||
regval = /* Not Cacheable */
|
||||
/* Not Bufferable */
|
||||
MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_TEX(4) | /* TEX */
|
||||
MPU_RACR_AP_RWRW | /* P:RO U:None */
|
||||
MPU_RACR_XN; /* Instruction access disable */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_priv_noncache(base, size) \
|
||||
/* inner/outer non-cache : TEX(4), C(0), B(0), S(1) */ \
|
||||
/* Not Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* Shareable */ \
|
||||
/* TEX */ \
|
||||
/* P:RO U:None ` */ \
|
||||
/* Instruction access disable */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | \
|
||||
MPU_RACR_TEX(4) | \
|
||||
MPU_RACR_AP_RWRW | \
|
||||
MPU_RACR_XN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_flash
|
||||
|
@ -502,37 +592,10 @@ static inline void mpu_priv_noncache(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_priv_flash(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = MPU_RACR_C | /* Cacheable */
|
||||
MPU_RACR_AP_RONO; /* P:RO U:None */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_priv_flash(base, size) \
|
||||
/* Cacheable */ \
|
||||
/* P:RO U:None */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_C | MPU_RACR_AP_RONO)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_intsram
|
||||
|
@ -542,38 +605,13 @@ static inline void mpu_priv_flash(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_user_intsram(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_C | /* Cacheable */
|
||||
MPU_RACR_AP_RWRW; /* P:RW U:RW */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_user_intsram(base, size) \
|
||||
/* Shareable */ \
|
||||
/* Cacheable */ \
|
||||
/* P:RW U:RW */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | \
|
||||
MPU_RACR_C | \
|
||||
MPU_RACR_AP_RWRW)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_intsram
|
||||
|
@ -583,38 +621,13 @@ static inline void mpu_user_intsram(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_priv_intsram(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_C | /* Cacheable */
|
||||
MPU_RACR_AP_RWNO; /* P:RW U:None */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_priv_intsram(base, size) \
|
||||
/* Shareable */ \
|
||||
/* Cacheable */ \
|
||||
/* P:RW U:None */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | \
|
||||
MPU_RACR_C | \
|
||||
MPU_RACR_AP_RWNO)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_extsram
|
||||
|
@ -624,39 +637,15 @@ static inline void mpu_priv_intsram(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_user_extsram(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_C | /* Cacheable */
|
||||
MPU_RACR_B | /* Bufferable */
|
||||
MPU_RACR_AP_RWRW; /* P:RW U:RW */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_user_extsram(base, size) \
|
||||
/* Shareable */ \
|
||||
/* Cacheable */ \
|
||||
/* Bufferable */ \
|
||||
/* P:RW U:RW */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | \
|
||||
MPU_RACR_C | \
|
||||
MPU_RACR_B | \
|
||||
MPU_RACR_AP_RWRW)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_extsram
|
||||
|
@ -666,39 +655,15 @@ static inline void mpu_user_extsram(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_priv_extsram(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region */
|
||||
|
||||
regval = MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_C | /* Cacheable */
|
||||
MPU_RACR_B | /* Bufferable */
|
||||
MPU_RACR_AP_RWNO; /* P:RW U:None */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_priv_extsram(base, size) \
|
||||
/* Shareable */ \
|
||||
/* Cacheable */ \
|
||||
/* Bufferable */ \
|
||||
/* P:RW U:None */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | \
|
||||
MPU_RACR_C | \
|
||||
MPU_RACR_B | \
|
||||
MPU_RACR_AP_RWNO)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_peripheral
|
||||
|
@ -708,39 +673,15 @@ static inline void mpu_priv_extsram(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_peripheral(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* Then configure the region */
|
||||
|
||||
regval = MPU_RACR_S | /* Shareable */
|
||||
MPU_RACR_B | /* Bufferable */
|
||||
MPU_RACR_AP_RWNO | /* P:RW U:None */
|
||||
MPU_RACR_XN; /* Instruction access disable */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_peripheral(base, size) \
|
||||
/* Shareable */ \
|
||||
/* Bufferable */ \
|
||||
/* P:RW U:None */ \
|
||||
/* Instruction access disable */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_S | \
|
||||
MPU_RACR_B | \
|
||||
MPU_RACR_AP_RWNO | \
|
||||
MPU_RACR_XN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_intsram_wb
|
||||
|
@ -751,41 +692,14 @@ static inline void mpu_peripheral(uintptr_t base, size_t size)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mpu_user_intsram_wb(uintptr_t base, size_t size)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uint32_t regval;
|
||||
uint8_t l2size;
|
||||
uint8_t subregions;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
mpu_set_rgnr(region);
|
||||
|
||||
/* Select the region base address */
|
||||
|
||||
mpu_set_drbar(base & MPU_RBAR_ADDR_MASK);
|
||||
|
||||
/* Select the region size and the sub-region map */
|
||||
|
||||
l2size = mpu_log2regionceil(size);
|
||||
subregions = mpu_subregion(base, size, l2size);
|
||||
|
||||
/* The configure the region
|
||||
* WB/Write Allocate: TEX(5), C(0), B(1), S(1)
|
||||
*/
|
||||
|
||||
regval = /* Not Cacheable */
|
||||
MPU_RACR_B | /* Not Bufferable */
|
||||
MPU_RACR_TEX(5) | /* TEX */
|
||||
MPU_RACR_AP_RWRW; /* P:RW U:RW */
|
||||
mpu_set_dracr(regval);
|
||||
|
||||
regval = MPU_RASR_ENABLE | /* Enable region */
|
||||
MPU_RASR_RSIZE_LOG2((uint32_t)l2size) | /* Region size */
|
||||
((uint32_t)subregions << MPU_RASR_SRD_SHIFT); /* Sub-regions */
|
||||
mpu_set_drsr(regval);
|
||||
}
|
||||
#define mpu_user_intsram_wb(base, size) \
|
||||
/* Not Cacheable */ \
|
||||
/* Not Bufferable */ \
|
||||
/* TEX */ \
|
||||
/* P:RW U:RW */ \
|
||||
mpu_configure_region(base, size, MPU_RACR_B | \
|
||||
MPU_RACR_TEX(5) | \
|
||||
MPU_RACR_AP_RWRW)
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "mpu.h"
|
||||
#include "arm_internal.h"
|
||||
|
@ -45,39 +47,26 @@
|
|||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The next available region number */
|
||||
/* The available region bitmap */
|
||||
|
||||
static uint8_t g_region;
|
||||
static unsigned int g_mpu_region;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Assumptions:
|
||||
* - Regions are never deallocated
|
||||
* - Regions are only allocated early in initialization, so no special
|
||||
* protection against re-entrancy is required;
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void)
|
||||
{
|
||||
DEBUGASSERT(g_region < CONFIG_ARM_MPU_NREGIONS);
|
||||
return (unsigned int)g_region++;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset_internal
|
||||
*
|
||||
* Description:
|
||||
* Resets the MPU to disabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
|
@ -91,7 +80,7 @@ static void mpu_reset_internal()
|
|||
for (region = 0; region < regions; region++)
|
||||
{
|
||||
putreg32(region, MPU_RNR);
|
||||
putreg32(0, MPU_RASR);
|
||||
putreg32(0, MPU_RLAR);
|
||||
putreg32(0, MPU_RBAR);
|
||||
}
|
||||
|
||||
|
@ -106,12 +95,75 @@ static void mpu_reset_internal()
|
|||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void)
|
||||
{
|
||||
unsigned int i = ffs(~g_mpu_region) - 1;
|
||||
|
||||
/* There are not enough regions to apply */
|
||||
|
||||
DEBUGASSERT(i < CONFIG_ARM_MPU_NREGIONS);
|
||||
g_mpu_region |= 1 << i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region)
|
||||
{
|
||||
DEBUGASSERT(region < CONFIG_ARM_MPU_NREGIONS);
|
||||
|
||||
/* Clear and disable the given MPU Region */
|
||||
|
||||
putreg32(region, MPU_RNR);
|
||||
putreg32(0, MPU_RLAR);
|
||||
putreg32(0, MPU_RBAR);
|
||||
g_mpu_region &= ~(1 << region);
|
||||
ARM_DSB();
|
||||
ARM_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_control
|
||||
*
|
||||
* Description:
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - Flag indicating whether to enable the MPU.
|
||||
* hfnmiena - Flag indicating whether to enable the MPU during hard
|
||||
* fult, NMI, and FAULTMAS.
|
||||
* privdefena - Flag indicating whether to enable privileged access to
|
||||
* the default memory map.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_control(bool enable, bool hfnmiena, bool privdefena)
|
||||
|
@ -151,18 +203,32 @@ void mpu_control(bool enable, bool hfnmiena, bool privdefena)
|
|||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the MPU region to modify.
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* flags1 - Additional flags for the region.
|
||||
* flags2 - Additional flags for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags1, uint32_t flags2)
|
||||
void mpu_modify_region(unsigned int region, uintptr_t base, size_t size,
|
||||
uint32_t flags1, uint32_t flags2)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
uintptr_t limit;
|
||||
uintptr_t limit;
|
||||
uintptr_t rbase;
|
||||
|
||||
/* Check that the region is valid */
|
||||
|
||||
DEBUGASSERT(g_mpu_region & (1 << region));
|
||||
|
||||
/* Ensure the base address alignment
|
||||
*
|
||||
|
@ -173,7 +239,7 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
*/
|
||||
|
||||
limit = (base + size - 1) & MPU_RLAR_LIMIT_MASK;
|
||||
base &= MPU_RBAR_BASE_MASK;
|
||||
rbase = base & MPU_RBAR_BASE_MASK;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
|
@ -181,7 +247,7 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
|
||||
/* Set the region base, limit and attribute */
|
||||
|
||||
putreg32(base | flags1, MPU_RBAR);
|
||||
putreg32(rbase | flags1, MPU_RBAR);
|
||||
putreg32(limit | flags2 | MPU_RLAR_ENABLE, MPU_RLAR);
|
||||
|
||||
/* Ensure MPU setting take effects */
|
||||
|
@ -190,6 +256,113 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
ARM_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* flags1 - Additional flags for the region.
|
||||
* flags2 - Additional flags for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags1, uint32_t flags2)
|
||||
{
|
||||
unsigned int region = mpu_allocregion();
|
||||
mpu_modify_region(region, base, size, flags1, flags2);
|
||||
return region;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - MPU initialization table.
|
||||
* hfnmiena - A boolean indicating whether the MPU should enable the
|
||||
* HFNMIENA bit.
|
||||
* privdefena - A boolean indicating whether the MPU should enable the
|
||||
* PRIVDEFENA bit.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_initialize(const struct mpu_region_s *table, bool hfnmiena,
|
||||
bool privdefena)
|
||||
{
|
||||
const struct mpu_region_s *conf;
|
||||
int index;
|
||||
|
||||
mpu_control(false, false, false);
|
||||
for (index = 0; index < nitems(table); index++)
|
||||
{
|
||||
conf = &table[index];
|
||||
mpu_configure_region(conf->base, conf->size, conf->flags1,
|
||||
conf->flags2);
|
||||
}
|
||||
|
||||
mpu_control(true, hfnmiena, privdefena);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
uint32_t rlar;
|
||||
uint32_t rbar;
|
||||
uint32_t ctrl;
|
||||
|
||||
/* Get free region */
|
||||
|
||||
ctrl = getreg32(MPU_CTRL);
|
||||
_info("MPU-CTRL Enable:%" PRIu32 ", HFNMIENA:%"PRIu32","
|
||||
"PRIVDEFENA:%" PRIu32 "\n", ctrl & MPU_CTRL_ENABLE,
|
||||
ctrl & MPU_CTRL_HFNMIENA, ctrl & MPU_CTRL_PRIVDEFENA);
|
||||
for (i = 0; i < CONFIG_ARM_MPU_NREGIONS; i++)
|
||||
{
|
||||
putreg32(i, MPU_RNR);
|
||||
rlar = getreg32(MPU_RLAR);
|
||||
rbar = getreg32(MPU_RBAR);
|
||||
_info("MPU-%d, 0x%08X-0x%08X SH=%X AP=%X XN=%u\n",
|
||||
i, rbar & MPU_RBAR_BASE_MASK, rlar & MPU_RLAR_LIMIT_MASK,
|
||||
rbar & MPU_RBAR_SH_MASK, rbar & MPU_RBAR_AP_MASK,
|
||||
rbar & MPU_RBAR_XN);
|
||||
if (rlar & MPU_RLAR_ENABLE)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
_info("Total Use Region:%d, Remaining Available:%d\n", count,
|
||||
CONFIG_ARM_MPU_NREGIONS - count);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
|
@ -197,6 +370,12 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_RESET)
|
||||
void mpu_reset()
|
||||
|
@ -212,6 +391,12 @@ void mpu_reset()
|
|||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset()
|
||||
|
|
|
@ -168,6 +168,21 @@
|
|||
MPU_MAIR_OUTER_RA | MPU_MAIR_OUTER_WA | \
|
||||
MPU_MAIR_INNER_NT | MPU_MAIR_INNER_WB | \
|
||||
MPU_MAIR_INNER_RA | MPU_MAIR_INNER_WA)
|
||||
struct mpu_region_s
|
||||
{
|
||||
/* Region Base Address */
|
||||
|
||||
uintptr_t base;
|
||||
|
||||
/* Region Size */
|
||||
|
||||
size_t size;
|
||||
|
||||
/* Region Attributes */
|
||||
|
||||
uint32_t flags1;
|
||||
uint32_t flags2;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
|
@ -215,26 +230,135 @@ extern "C"
|
|||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_control
|
||||
*
|
||||
* Description:
|
||||
* Configure and enable (or disable) the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* enable - Flag indicating whether to enable the MPU.
|
||||
* hfnmiena - Flag indicating whether to enable the MPU during hard
|
||||
* fult, NMI, and FAULTMAS.
|
||||
* privdefena - Flag indicating whether to enable privileged access to
|
||||
* the default memory map.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_control(bool enable, bool hfnmiena, bool privdefena);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the MPU region to modify.
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* flags1 - Additional flags for the region.
|
||||
* flags2 - Additional flags for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_modify_region(unsigned int region, uintptr_t base, size_t size,
|
||||
uint32_t flags1, uint32_t flags2);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* base - The base address of the region.
|
||||
* size - The size of the region.
|
||||
* flags1 - Additional flags for the region.
|
||||
* flags2 - Additional flags for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags1, uint32_t flags2);
|
||||
unsigned int mpu_configure_region(uintptr_t base, size_t size,
|
||||
uint32_t flags1, uint32_t flags2);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_initialize
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - MPU initialization table.
|
||||
* hfnmiena - A boolean indicating whether the MPU should enable the
|
||||
* HFNMIENA bit.
|
||||
* privdefena - A boolean indicating whether the MPU should enable the
|
||||
* PRIVDEFENA bit.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_initialize(const struct mpu_region_s *table, bool hfnmiena,
|
||||
bool privdefena);
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
|
@ -271,14 +395,11 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_stronglyordered(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_STRONGLY_ORDER | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_STRONGLY_ORDER | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_flash
|
||||
|
@ -289,13 +410,10 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_flash(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RORO, \
|
||||
MPU_RLAR_WRITE_BACK); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RORO, \
|
||||
MPU_RLAR_WRITE_BACK)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_flash
|
||||
|
@ -306,13 +424,10 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_flash(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RONO, \
|
||||
MPU_RLAR_WRITE_BACK); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RONO, \
|
||||
MPU_RLAR_WRITE_BACK)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_intsram
|
||||
|
@ -323,15 +438,12 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_intsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_XN | \
|
||||
MPU_RBAR_AP_RWRW, \
|
||||
MPU_RLAR_NONCACHEABLE | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_XN | \
|
||||
MPU_RBAR_AP_RWRW, \
|
||||
MPU_RLAR_NONCACHEABLE | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_intsram
|
||||
|
@ -342,14 +454,11 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_intsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_NONCACHEABLE | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_NONCACHEABLE | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_shmem
|
||||
|
@ -359,16 +468,13 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_shmem(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_NONCACHEABLE | \
|
||||
MPU_RBAR_SH_INNER | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
#define mpu_priv_shmem(base, size) \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_NONCACHEABLE | \
|
||||
MPU_RBAR_SH_INNER | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_extsram
|
||||
|
@ -379,16 +485,13 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_extsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_XN | \
|
||||
MPU_RBAR_AP_RWRW | \
|
||||
MPU_RBAR_SH_OUTER, \
|
||||
MPU_RLAR_WRITE_BACK | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_XN | \
|
||||
MPU_RBAR_AP_RWRW | \
|
||||
MPU_RBAR_SH_OUTER, \
|
||||
MPU_RLAR_WRITE_BACK | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_priv_extsram
|
||||
|
@ -399,15 +502,12 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_priv_extsram(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO | \
|
||||
MPU_RBAR_SH_OUTER, \
|
||||
MPU_RLAR_WRITE_BACK | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* The configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO | \
|
||||
MPU_RBAR_SH_OUTER, \
|
||||
MPU_RLAR_WRITE_BACK | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_peripheral
|
||||
|
@ -418,14 +518,11 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_peripheral(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_DEVICE | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_AP_RWNO, \
|
||||
MPU_RLAR_DEVICE | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_user_peripheral
|
||||
|
@ -436,15 +533,12 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
|||
****************************************************************************/
|
||||
|
||||
#define mpu_user_peripheral(base, size) \
|
||||
do \
|
||||
{ \
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_XN | \
|
||||
MPU_RBAR_AP_RWRW, \
|
||||
MPU_RLAR_DEVICE | \
|
||||
MPU_RLAR_PXN); \
|
||||
} while (0)
|
||||
/* Then configure the region */ \
|
||||
mpu_configure_region(base, size, \
|
||||
MPU_RBAR_XN | \
|
||||
MPU_RBAR_AP_RWRW, \
|
||||
MPU_RLAR_DEVICE | \
|
||||
MPU_RLAR_PXN)
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/***************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm64/src/common/arm64_mpu.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
|
@ -16,11 +16,11 @@
|
|||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
***************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <stdint.h>
|
||||
|
@ -36,9 +36,9 @@
|
|||
#include "arm64_fatal.h"
|
||||
#include "arm64_mpu.h"
|
||||
|
||||
/***************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
***************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#define __MPU_ASSERT(__cond, fmt, ...) \
|
||||
do \
|
||||
|
@ -70,65 +70,50 @@
|
|||
* regions.
|
||||
*/
|
||||
|
||||
static uint8_t static_regions_num;
|
||||
static unsigned int g_mpu_region;
|
||||
|
||||
/***************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
***************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/* Get the number of supported MPU regions. */
|
||||
/****************************************************************************
|
||||
* Name: get_num_regions
|
||||
*
|
||||
* Description:
|
||||
* Get the number of supported MPU regions.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Numbers of the region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t get_num_regions(void)
|
||||
static inline unsigned int get_num_regions(void)
|
||||
{
|
||||
uint64_t type;
|
||||
|
||||
type = read_sysreg(mpuir_el1);
|
||||
type = type & MPU_IR_REGION_MSK;
|
||||
|
||||
return (uint8_t)type;
|
||||
return (unsigned int)type;
|
||||
}
|
||||
|
||||
/* ARM Core MPU Driver API Implementation for ARM MPU */
|
||||
|
||||
/* Enable the MPU */
|
||||
|
||||
void arm64_core_mpu_enable(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
val = read_sysreg(sctlr_el1);
|
||||
val |= (SCTLR_M_BIT
|
||||
#ifndef CONFIG_ARM64_DCACHE_DISABLE
|
||||
| SCTLR_C_BIT
|
||||
#endif
|
||||
);
|
||||
write_sysreg(val, sctlr_el1);
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/* Disable the MPU */
|
||||
|
||||
void arm64_core_mpu_disable(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
/* Force any outstanding transfers to complete before disabling MPU */
|
||||
|
||||
ARM64_DMB();
|
||||
|
||||
val = read_sysreg(sctlr_el1);
|
||||
val &= ~(SCTLR_M_BIT | SCTLR_C_BIT);
|
||||
write_sysreg(val, sctlr_el1);
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/* ARM MPU Driver Initial Setup
|
||||
/****************************************************************************
|
||||
* Name: mpu_init
|
||||
*
|
||||
* Configure the cache-ability attributes for all the
|
||||
* different types of memory regions.
|
||||
*/
|
||||
* Description:
|
||||
* Configure the cache-ability attributes for all the different types
|
||||
* of memory regions.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mpu_init(void)
|
||||
{
|
||||
|
@ -145,44 +130,257 @@ static void mpu_init(void)
|
|||
ARM64_ISB();
|
||||
}
|
||||
|
||||
static inline void mpu_set_region(uint32_t rnr, uint64_t rbar,
|
||||
uint64_t rlar)
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void)
|
||||
{
|
||||
write_sysreg(rnr, prselr_el1);
|
||||
unsigned int num_regions = get_num_regions();
|
||||
unsigned int i = ffs(~g_mpu_region) - 1;
|
||||
|
||||
/* There are not enough regions to apply */
|
||||
|
||||
DEBUGASSERT(i < num_regions);
|
||||
g_mpu_region |= 1 << i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region)
|
||||
{
|
||||
unsigned int num_regions = get_num_regions();
|
||||
|
||||
/* Check region vaild */
|
||||
|
||||
DEBUGASSERT(region < num_regions);
|
||||
|
||||
write_sysreg(region, prselr_el1);
|
||||
ARM64_DSB();
|
||||
|
||||
/* Set the region base, limit and attribute */
|
||||
|
||||
write_sysreg(0, prbar_el1);
|
||||
write_sysreg(0, prlar_el1);
|
||||
g_mpu_region &= ~(1 << region);
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_mpu_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_mpu_enable(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
val = read_sysreg(sctlr_el1);
|
||||
val |= (SCTLR_M_BIT
|
||||
#ifndef CONFIG_ARM64_DCACHE_DISABLE
|
||||
| SCTLR_C_BIT
|
||||
#endif
|
||||
);
|
||||
write_sysreg(val, sctlr_el1);
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_mpu_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_mpu_disable(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
/* Force any outstanding transfers to complete before disabling MPU */
|
||||
|
||||
ARM64_DMB();
|
||||
|
||||
val = read_sysreg(sctlr_el1);
|
||||
val &= ~(SCTLR_M_BIT | SCTLR_C_BIT);
|
||||
write_sysreg(val, sctlr_el1);
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the MPU region to modify.
|
||||
* table - Pointer to a struct containing the configuration
|
||||
* parameters for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_modify_region(unsigned int region,
|
||||
const struct arm64_mpu_region *table)
|
||||
{
|
||||
uint64_t rbar = table->base & MPU_RBAR_BASE_MSK;
|
||||
uint64_t rlar = (table->limit - 1) & MPU_RLAR_LIMIT_MSK;
|
||||
|
||||
/* Check that the region is valid */
|
||||
|
||||
DEBUGASSERT(g_mpu_region & (1 << region));
|
||||
|
||||
rbar |= table->attr.rbar &
|
||||
(MPU_RBAR_XN_MSK | MPU_RBAR_AP_MSK | MPU_RBAR_SH_MSK);
|
||||
rlar |=
|
||||
(table->attr.mair_idx <<
|
||||
MPU_RLAR_ATTRINDX_POS) & MPU_RLAR_ATTRINDX_MSK;
|
||||
rlar |= MPU_RLAR_EN_MSK;
|
||||
|
||||
/* Select the region */
|
||||
|
||||
write_sysreg(region, prselr_el1);
|
||||
ARM64_DSB();
|
||||
|
||||
/* Set the region base, limit and attribute */
|
||||
|
||||
write_sysreg(rbar, prbar_el1);
|
||||
write_sysreg(rlar, prlar_el1);
|
||||
ARM64_DSB();
|
||||
ARM64_ISB();
|
||||
}
|
||||
|
||||
/* This internal functions performs MPU region initialization. */
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - Pointer to a struct containing the configuration
|
||||
* parameters for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void region_init(const uint32_t index,
|
||||
const struct arm64_mpu_region *region_conf)
|
||||
unsigned int mpu_configure_region(const struct arm64_mpu_region *
|
||||
table)
|
||||
{
|
||||
uint64_t rbar = region_conf->base & MPU_RBAR_BASE_MSK;
|
||||
uint64_t rlar = (region_conf->limit - 1) & MPU_RLAR_LIMIT_MSK;
|
||||
|
||||
rbar |= region_conf->attr.rbar &
|
||||
(MPU_RBAR_XN_MSK | MPU_RBAR_AP_MSK | MPU_RBAR_SH_MSK);
|
||||
rlar |=
|
||||
(region_conf->attr.mair_idx <<
|
||||
MPU_RLAR_ATTRINDX_POS) & MPU_RLAR_ATTRINDX_MSK;
|
||||
rlar |= MPU_RLAR_EN_MSK;
|
||||
|
||||
mpu_set_region(index, rbar, rlar);
|
||||
unsigned int region = mpu_allocregion();
|
||||
mpu_modify_region(region, table);
|
||||
return region;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Public Functions
|
||||
***************************************************************************/
|
||||
|
||||
/* @brief MPU default configuration
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* This function here provides the default configuration mechanism
|
||||
* for the Memory Protection Unit (MPU).
|
||||
*/
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void)
|
||||
{
|
||||
uint64_t sctlr_el1;
|
||||
uint64_t prlar;
|
||||
uint64_t prbar;
|
||||
unsigned int num_regions;
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
num_regions = get_num_regions();
|
||||
sctlr_el1 = read_sysreg(sctlr_el1);
|
||||
_info("MPU-SCTLR_EL1 Enable:%" PRIu64 ", Cacheable: %" PRIu64 "\n",
|
||||
sctlr_el1 & SCTLR_M_BIT, sctlr_el1 & SCTLR_C_BIT);
|
||||
for (i = 0; i < num_regions; i++)
|
||||
{
|
||||
write_sysreg(i, prselr_el1);
|
||||
prlar = read_sysreg(prlar_el1);
|
||||
prbar = read_sysreg(prbar_el1);
|
||||
_info("MPU-%d, 0x%08X-0x%08X SH=%X AP=%X XN=%X\n", i,
|
||||
prbar & MPU_RBAR_BASE_MSK, prlar & MPU_RLAR_LIMIT_MSK,
|
||||
prbar & MPU_RBAR_SH_MSK, prbar & MPU_RBAR_AP_MSK,
|
||||
prbar & MPU_RBAR_XN_MSK);
|
||||
if (prlar & MPU_RLAR_EN_MSK)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
_info("Total Use Region:%d, Remaining Available:%d\n", count,
|
||||
num_regions - count);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_mpu_init
|
||||
*
|
||||
* Description:
|
||||
* This function here provides the default configuration mechanism
|
||||
* for the Memory Protection Unit (MPU).
|
||||
*
|
||||
* Input Parameters:
|
||||
* is_primary_core: A boolean indicating whether the current core is the
|
||||
* primary core.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_mpu_init(bool is_primary_core)
|
||||
{
|
||||
|
@ -206,21 +404,7 @@ void arm64_mpu_init(bool is_primary_core)
|
|||
return;
|
||||
}
|
||||
|
||||
if (g_mpu_config.num_regions > get_num_regions())
|
||||
{
|
||||
/* Attempt to configure more MPU regions than
|
||||
* what is supported by hardware. As this operation
|
||||
* is executed during system (pre-kernel) initialization,
|
||||
* we want to ensure we can detect an attempt to
|
||||
* perform invalid configuration.
|
||||
*/
|
||||
|
||||
__MPU_ASSERT(0, "Request to configure: %u regions (supported: %u)\n",
|
||||
g_mpu_config.num_regions, get_num_regions());
|
||||
return;
|
||||
}
|
||||
|
||||
arm64_core_mpu_disable();
|
||||
arm64_mpu_disable();
|
||||
|
||||
/* Architecture-specific configuration */
|
||||
|
||||
|
@ -230,12 +414,8 @@ void arm64_mpu_init(bool is_primary_core)
|
|||
|
||||
for (r_index = 0U; r_index < g_mpu_config.num_regions; r_index++)
|
||||
{
|
||||
region_init(r_index, &g_mpu_config.mpu_regions[r_index]);
|
||||
mpu_configure_region(&g_mpu_config.mpu_regions[r_index]);
|
||||
}
|
||||
|
||||
/* Update the number of programmed MPU regions. */
|
||||
|
||||
static_regions_num = g_mpu_config.num_regions;
|
||||
|
||||
arm64_core_mpu_enable();
|
||||
arm64_mpu_enable();
|
||||
}
|
||||
|
|
|
@ -304,6 +304,131 @@ extern const struct arm64_mpu_config g_mpu_config;
|
|||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
* Description:
|
||||
* Allocate the next region
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The index of the allocated region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_allocregion(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_freeregion
|
||||
*
|
||||
* Description:
|
||||
* Free target region.
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the region to be freed.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_freeregion(unsigned int region);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_mpu_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_mpu_enable(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_mpu_disable
|
||||
*
|
||||
* Description:
|
||||
* Disable the MPU
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_mpu_disable(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_dump_region
|
||||
*
|
||||
* Description:
|
||||
* Dump the region that has been used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_dump_region(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_modify_region
|
||||
*
|
||||
* Description:
|
||||
* Modify a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* region - The index of the MPU region to modify.
|
||||
* table - Pointer to a struct containing the configuration
|
||||
* parameters for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mpu_modify_region(unsigned int region,
|
||||
const struct arm64_mpu_region *table);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_configure_region
|
||||
*
|
||||
* Description:
|
||||
* Configure a region for privileged, strongly ordered memory
|
||||
*
|
||||
* Input Parameters:
|
||||
* table - Pointer to a struct containing the configuration
|
||||
* parameters for the region.
|
||||
*
|
||||
* Returned Value:
|
||||
* The region number allocated for the configured region.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int mpu_configure_region(const struct arm64_mpu_region *
|
||||
table);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm64_mpu_init
|
||||
*
|
||||
* Description:
|
||||
* This function here provides the default configuration mechanism
|
||||
* for the Memory Protection Unit (MPU).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_mpu_init(bool is_primary_core);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
|
Loading…
Reference in a new issue