armv7-m,armv7-r,armv8-m:MPU Add mpu_reset and ARM_MPU_EARLY_RESET
When NuttX is booted from a foreign (non NuttX) bootloader. There as a possibility that the bootloader configured the MPU, in an incompatible way for the NuttX memory usage. The option to reset the MPU before it is initialized may not succeed if the bss and data initialization code violated the previous MPU configurations. Added herein are ARM_MPU_RESET and ARM_MPU_EARLY_RESET. The former can be used If the system is capable of booting and running NuttX MPU configuration code without an MPU violation. The latter is used if the system can not run the bss and data initialization code. These are options so that a NuttX may be configured to not clobber a bootloader MPU configuration in a system that is architected to share the MPU configuration task.
This commit is contained in:
parent
cf1a04d0a2
commit
9d8f7126f6
@ -879,6 +879,34 @@ config ARM_MPU_NREGIONS
|
||||
---help---
|
||||
This is the number of protection regions supported by the MPU.
|
||||
|
||||
config ARM_MPU_RESET
|
||||
bool "MPU Reset before MPU initialization"
|
||||
default n
|
||||
depends on ARM_MPU
|
||||
---help---
|
||||
Configures the MPU initialization sequence to disable the MPU
|
||||
before configuring it.
|
||||
|
||||
This may be needed in a system with a bootloader that has
|
||||
configured the MPU prior to running NuttX. This may be all that is
|
||||
needed to allow booting if the previous MPU configuration allow
|
||||
the system to execute the MPU initialization code. If not use
|
||||
ARM_MPU_EARLY_RESET.
|
||||
|
||||
config ARM_MPU_EARLY_RESET
|
||||
bool "MPU Early Reset"
|
||||
default n
|
||||
depends on ARCH_HAVE_MPU
|
||||
---help---
|
||||
Configures the early system initialization sequence to disable the MPU.
|
||||
|
||||
This may be needed in a system with a bootloader that has
|
||||
configured the MPU prior to running NuttX. This is useful if the system
|
||||
faults during bbs, or data initialization or before the
|
||||
stm32_mpuinitialize can be called.
|
||||
|
||||
Note: This can be used without MPU Support enabled.
|
||||
|
||||
config ARCH_HAVE_LOWVECTORS
|
||||
bool
|
||||
|
||||
|
@ -177,6 +177,33 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
||||
return g_ls_regionmask[nsrs];
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset_internal
|
||||
*
|
||||
* Description:
|
||||
* Resets the MPU to disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
static void mpu_reset_internal()
|
||||
{
|
||||
int region;
|
||||
int regions;
|
||||
regions = (getreg32(MPU_TYPE) & MPU_TYPE_DREGION_MASK)
|
||||
>> MPU_TYPE_DREGION_SHIFT;
|
||||
|
||||
for (region = 0; region < regions; region++)
|
||||
{
|
||||
putreg32(region, MPU_RNR);
|
||||
putreg32(0, MPU_RASR);
|
||||
putreg32(0, MPU_RBAR);
|
||||
}
|
||||
|
||||
putreg32(0, MPU_CTRL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -387,3 +414,33 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
||||
flags;
|
||||
putreg32(regval, MPU_RASR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_MPU_RESET)
|
||||
void mpu_reset()
|
||||
{
|
||||
mpu_reset_internal();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_early_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset()
|
||||
{
|
||||
mpu_reset_internal();
|
||||
}
|
||||
#endif
|
||||
|
@ -132,6 +132,36 @@
|
||||
# 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 */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_MPU_RESET)
|
||||
void mpu_reset(void);
|
||||
#else
|
||||
# define mpu_reset() do { } while (0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_early_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset(void);
|
||||
#else
|
||||
# define mpu_early_reset() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_MPU
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -177,6 +177,33 @@ static inline uint32_t mpu_subregion_ls(size_t offset, uint8_t l2size)
|
||||
return g_ls_regionmask[nsrs];
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset_internal
|
||||
*
|
||||
* Description:
|
||||
* Resets the MPU to disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
static void mpu_reset_internal()
|
||||
{
|
||||
int region;
|
||||
int regions;
|
||||
regions = (getreg32(MPU_TYPE) & MPU_TYPE_DREGION_MASK)
|
||||
>> MPU_TYPE_DREGION_SHIFT;
|
||||
|
||||
for (region = 0; region < regions; region++)
|
||||
{
|
||||
putreg32(region, MPU_RNR);
|
||||
putreg32(0, MPU_RASR);
|
||||
putreg32(0, MPU_RBAR);
|
||||
}
|
||||
|
||||
putreg32(0, MPU_CTRL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -300,3 +327,33 @@ uint32_t mpu_subregion(uintptr_t base, size_t size, uint8_t l2size)
|
||||
ret |= mpu_subregion_ls(offset, l2size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_MPU_RESET)
|
||||
void mpu_reset()
|
||||
{
|
||||
mpu_reset_internal();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_early_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset()
|
||||
{
|
||||
mpu_reset_internal();
|
||||
}
|
||||
#endif
|
||||
|
@ -120,6 +120,36 @@ extern "C"
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_MPU_RESET)
|
||||
void mpu_reset(void);
|
||||
#else
|
||||
# define mpu_reset() do { } while (0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_early_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset(void);
|
||||
#else
|
||||
# define mpu_early_reset() do { } while (0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_allocregion
|
||||
*
|
||||
|
@ -71,6 +71,33 @@ unsigned int mpu_allocregion(void)
|
||||
return (unsigned int)g_region++;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset_internal
|
||||
*
|
||||
* Description:
|
||||
* Resets the MPU to disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_MPU_RESET) || defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
static void mpu_reset_internal()
|
||||
{
|
||||
int region;
|
||||
int regions;
|
||||
regions = (getreg32(MPU_TYPE) & MPU_TYPE_DREGION_MASK)
|
||||
>> MPU_TYPE_DREGION_SHIFT;
|
||||
|
||||
for (region = 0; region < regions; region++)
|
||||
{
|
||||
putreg32(region, MPU_RNR);
|
||||
putreg32(0, MPU_RASR);
|
||||
putreg32(0, MPU_RBAR);
|
||||
}
|
||||
|
||||
putreg32(0, MPU_CTRL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -148,3 +175,33 @@ void mpu_configure_region(uintptr_t base, size_t size,
|
||||
putreg32(base | flags1, MPU_RBAR);
|
||||
putreg32(limit | flags2 | MPU_RLAR_ENABLE, MPU_RLAR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_MPU_RESET)
|
||||
void mpu_reset()
|
||||
{
|
||||
mpu_reset_internal();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_early_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset()
|
||||
{
|
||||
mpu_reset_internal();
|
||||
}
|
||||
#endif
|
||||
|
@ -171,6 +171,36 @@
|
||||
MPU_MAIR_INNER_NT | MPU_MAIR_INNER_WB | \
|
||||
MPU_MAIR_INNER_RA | MPU_MAIR_INNER_WA)
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled during
|
||||
* MPU initialization.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_MPU_RESET)
|
||||
void mpu_reset(void);
|
||||
#else
|
||||
# define mpu_reset() do { } while (0)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpu_early_reset
|
||||
*
|
||||
* Description:
|
||||
* Conditional public interface that resets the MPU to disabled immediately
|
||||
* after reset.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARM_MPU_EARLY_RESET)
|
||||
void mpu_early_reset(void);
|
||||
#else
|
||||
# define mpu_early_reset() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM_MPU
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user