[PATCH rtems v2 3/7] cpu/armv7m: Add table based init for ARMV7M_MPU
Christian Mauderer
christian.mauderer at embedded-brains.de
Wed Nov 18 14:45:15 UTC 2020
Modify the MPU functions of the stm32h7 BSP to be table based and
available for all ARMV7M BSPs.
Update #4180
---
bsps/arm/stm32h7/start/bspstarthooks.c | 168 ++++++------------
.../cpu/arm/include/rtems/score/armv7m.h | 100 +++++++++++
2 files changed, 150 insertions(+), 118 deletions(-)
diff --git a/bsps/arm/stm32h7/start/bspstarthooks.c b/bsps/arm/stm32h7/start/bspstarthooks.c
index 565bd6876a..41c510aa4c 100644
--- a/bsps/arm/stm32h7/start/bspstarthooks.c
+++ b/bsps/arm/stm32h7/start/bspstarthooks.c
@@ -35,6 +35,52 @@
#include <string.h>
+const ARMV7M_MPU_Region_Config
+ stm32h7_start_config_mpu_region [] = {
+ {
+ .begin = stm32h7_memory_sram_axi_begin,
+ .end = stm32h7_memory_sram_axi_end,
+ .flags = ARMV7M_MPU_RASR_XN
+ | ARMV7M_MPU_RASR_AP(0x3)
+ | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
+ | ARMV7M_MPU_RASR_ENABLE,
+ }, {
+ .begin = stm32h7_memory_sdram_1_begin,
+ .end = stm32h7_memory_sdram_1_end,
+ .flags = ARMV7M_MPU_RASR_XN
+ | ARMV7M_MPU_RASR_AP(0x3)
+ | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
+ | ARMV7M_MPU_RASR_ENABLE,
+ }, {
+ .begin = bsp_section_start_begin,
+ .end = bsp_section_text_end,
+ .flags = ARMV7M_MPU_RASR_AP(0x5)
+ | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
+ | ARMV7M_MPU_RASR_ENABLE,
+ }, {
+ .begin = bsp_section_rodata_begin,
+ .end = bsp_section_rodata_end,
+ .flags = ARMV7M_MPU_RASR_XN
+ | ARMV7M_MPU_RASR_AP(0x5)
+ | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
+ | ARMV7M_MPU_RASR_ENABLE,
+ }, {
+ .begin = bsp_section_nocache_begin,
+ .end = bsp_section_nocachenoload_end,
+ .flags = ARMV7M_MPU_RASR_XN
+ | ARMV7M_MPU_RASR_AP(0x3)
+ | ARMV7M_MPU_RASR_TEX(0x2)
+ | ARMV7M_MPU_RASR_ENABLE,
+ }, {
+ .begin = stm32h7_memory_null_begin,
+ .end = stm32h7_memory_null_end,
+ .flags = ARMV7M_MPU_RASR_XN | ARMV7M_MPU_RASR_ENABLE,
+ }
+ };
+
+const size_t stm32h7_start_config_mpu_region_count =
+ RTEMS_ARRAY_SIZE(stm32h7_start_config_mpu_region);
+
void HAL_MspInit(void)
{
__HAL_RCC_SYSCFG_CLK_ENABLE();
@@ -83,123 +129,6 @@ static void init_peripheral_clocks(void)
}
}
-static uint32_t get_region_size(uintptr_t size)
-{
- if ((size & (size - 1)) == 0) {
- return ARMV7M_MPU_RASR_SIZE(30 - __builtin_clz(size));
- } else {
- return ARMV7M_MPU_RASR_SIZE(31 - __builtin_clz(size));
- }
-}
-
-static void set_region(
- volatile ARMV7M_MPU *mpu,
- uint32_t region,
- uint32_t rasr,
- const void *begin,
- const void *end
-)
-{
- uintptr_t size;
- uint32_t rbar;
-
- RTEMS_OBFUSCATE_VARIABLE(begin);
- RTEMS_OBFUSCATE_VARIABLE(end);
- size = (uintptr_t) end - (uintptr_t) begin;
-
- if ( size > 0 ) {
- rbar = (uintptr_t) begin | region | ARMV7M_MPU_RBAR_VALID;
- rasr |= get_region_size(size);
- } else {
- rbar = region;
- rasr = 0;
- }
-
- mpu->rbar = rbar;
- mpu->rasr = rasr;
-}
-
-static void init_mpu(void)
-{
- volatile ARMV7M_MPU *mpu;
- volatile ARMV7M_SCB *scb;
- uint32_t region_count;
- uint32_t region;
-
- mpu = _ARMV7M_MPU;
- scb = _ARMV7M_SCB;
-
- region_count = ARMV7M_MPU_TYPE_DREGION_GET(mpu->type);
-
- for (region = 0; region < region_count; ++region) {
- mpu->rbar = ARMV7M_MPU_RBAR_VALID | region;
- mpu->rasr = 0;
- }
-
- set_region(
- mpu,
- 0,
- ARMV7M_MPU_RASR_XN
- | ARMV7M_MPU_RASR_AP(0x3)
- | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
- | ARMV7M_MPU_RASR_ENABLE,
- stm32h7_memory_sram_axi_begin,
- stm32h7_memory_sram_axi_end
- );
- set_region(
- mpu,
- 1,
- ARMV7M_MPU_RASR_XN
- | ARMV7M_MPU_RASR_AP(0x3)
- | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
- | ARMV7M_MPU_RASR_ENABLE,
- stm32h7_memory_sdram_1_begin,
- stm32h7_memory_sdram_1_end
- );
- set_region(
- mpu,
- 2,
- ARMV7M_MPU_RASR_AP(0x5)
- | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
- | ARMV7M_MPU_RASR_ENABLE,
- bsp_section_start_begin,
- bsp_section_text_end
- );
- set_region(
- mpu,
- 3,
- ARMV7M_MPU_RASR_XN
- | ARMV7M_MPU_RASR_AP(0x5)
- | ARMV7M_MPU_RASR_TEX(0x1) | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B
- | ARMV7M_MPU_RASR_ENABLE,
- bsp_section_rodata_begin,
- bsp_section_rodata_end
- );
- set_region(
- mpu,
- 4,
- ARMV7M_MPU_RASR_XN
- | ARMV7M_MPU_RASR_AP(0x3)
- | ARMV7M_MPU_RASR_TEX(0x2)
- | ARMV7M_MPU_RASR_ENABLE,
- bsp_section_nocache_begin,
- bsp_section_nocachenoload_end
- );
- set_region(
- mpu,
- region - 1,
- ARMV7M_MPU_RASR_XN | ARMV7M_MPU_RASR_ENABLE,
- stm32h7_memory_null_begin,
- stm32h7_memory_null_end
- );
-
- mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE | ARMV7M_MPU_CTRL_PRIVDEFENA;
- scb->shcsr |= ARMV7M_SCB_SHCSR_MEMFAULTENA;
-
- _ARM_Data_synchronization_barrier();
- _ARM_Instruction_synchronization_barrier();
-}
-
void bsp_start_hook_0(void)
{
if ((RCC->AHB3ENR & RCC_AHB3ENR_FMCEN) == 0) {
@@ -226,7 +155,10 @@ void bsp_start_hook_0(void)
SCB_EnableDCache();
}
- init_mpu();
+ _ARMV7M_MPU_setup_from_config_and_enable(
+ stm32h7_start_config_mpu_region,
+ stm32h7_start_config_mpu_region_count
+ );
}
void bsp_start_hook_1(void)
diff --git a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
index c701e1037c..212fbfe44c 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
@@ -22,6 +22,9 @@
#define RTEMS_SCORE_ARMV7M_H
#include <rtems/score/cpu.h>
+#ifndef ASM
+#include <rtems/fatal.h>
+#endif
#ifdef __cplusplus
extern "C" {
@@ -347,6 +350,24 @@ typedef struct {
0 \
}
+/**
+ * Higher level region configuration.
+ *
+ * Allows to configure with begin and end which is more convenient for
+ * calculating the sizes from linker command file. Note that you still have to
+ * follow the following rules:
+ *
+ * - Begin address has to be aligned to 0x20 (lower 5 bits set to 0)
+ * - Sizes can only be a value of 2^x with a minimum of 32 Byte. If you have an
+ * end address that is not aligned, the region will get bigger.
+ * - Later regions have higher priority.
+ */
+typedef struct {
+ const void *begin;
+ const void *end;
+ uint32_t flags;
+} ARMV7M_MPU_Region_Config;
+
typedef struct {
uint32_t dhcsr;
uint32_t dcrsr;
@@ -611,6 +632,85 @@ void _ARMV7M_Supervisor_call( void );
void _ARMV7M_Clock_handler( void );
+static inline uint32_t _ARMV7M_MPU_get_region_size(uintptr_t size)
+{
+ if ((size & (size - 1)) == 0) {
+ return ARMV7M_MPU_RASR_SIZE(30 - __builtin_clz(size));
+ } else {
+ return ARMV7M_MPU_RASR_SIZE(31 - __builtin_clz(size));
+ }
+}
+
+static inline void _ARMV7M_MPU_set_region(
+ volatile ARMV7M_MPU *mpu,
+ uint32_t region,
+ uint32_t rasr,
+ const void *begin,
+ const void *end
+)
+{
+ uintptr_t size;
+ uint32_t rbar;
+
+ RTEMS_OBFUSCATE_VARIABLE(begin);
+ RTEMS_OBFUSCATE_VARIABLE(end);
+ size = (uintptr_t) end - (uintptr_t) begin;
+
+ if ( size > 0 ) {
+ rbar = (uintptr_t) begin | region | ARMV7M_MPU_RBAR_VALID;
+ rasr |= _ARMV7M_MPU_get_region_size(size);
+ } else {
+ rbar = region;
+ rasr = 0;
+ }
+
+ mpu->rbar = rbar;
+ mpu->rasr = rasr;
+}
+
+static inline void _ARMV7M_MPU_disable_region(
+ volatile ARMV7M_MPU *mpu,
+ uint32_t region
+)
+{
+ mpu->rbar = ARMV7M_MPU_RBAR_VALID | region;
+ mpu->rasr = 0;
+}
+
+static inline void _ARMV7M_MPU_setup_from_config_and_enable(
+ const ARMV7M_MPU_Region_Config *cfg,
+ size_t cfg_count
+)
+{
+ volatile ARMV7M_MPU *mpu;
+ volatile ARMV7M_SCB *scb;
+ uint32_t region_count;
+ uint32_t region;
+
+ mpu = _ARMV7M_MPU;
+ scb = _ARMV7M_SCB;
+
+ region_count = ARMV7M_MPU_TYPE_DREGION_GET(mpu->type);
+
+ if (cfg_count > region_count) {
+ rtems_panic("invalid MPU config");
+ }
+
+ for (region = 0; region < region_count; ++region) {
+ _ARMV7M_MPU_disable_region(mpu, region);
+ }
+
+ for (region = 0; region < cfg_count; ++region) {
+ _ARMV7M_MPU_set_region(mpu, region, cfg->flags, cfg->begin, cfg->end);
+ }
+
+ mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE | ARMV7M_MPU_CTRL_PRIVDEFENA;
+ scb->shcsr |= ARMV7M_SCB_SHCSR_MEMFAULTENA;
+
+ _ARM_Data_synchronization_barrier();
+ _ARM_Instruction_synchronization_barrier();
+}
+
#endif /* ASM */
#endif /* ARM_MULTILIB_ARCH_V7M */
--
2.26.2
More information about the devel
mailing list