[PATCH rtems v3 3/7] cpu/armv7m: Add table based init for ARMV7M_MPU
Christian Mauderer
christian.mauderer at embedded-brains.de
Thu Nov 19 08:51:31 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/include/stm32h7/mpu-config.h | 44 +++++++
bsps/arm/stm32h7/start/bspstarthooks.c | 120 +-----------------
bsps/arm/stm32h7/start/mpu-config.c | 75 +++++++++++
.../cpu/arm/include/rtems/score/armv7m.h | 102 +++++++++++++++
spec/build/bsps/arm/stm32h7/bspstm32h7.yml | 2 +
5 files changed, 225 insertions(+), 118 deletions(-)
create mode 100644 bsps/arm/stm32h7/include/stm32h7/mpu-config.h
create mode 100644 bsps/arm/stm32h7/start/mpu-config.c
diff --git a/bsps/arm/stm32h7/include/stm32h7/mpu-config.h b/bsps/arm/stm32h7/include/stm32h7/mpu-config.h
new file mode 100644
index 0000000000..27dddd4532
--- /dev/null
+++ b/bsps/arm/stm32h7/include/stm32h7/mpu-config.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBBSP_ARM_STM32H7_STM32H7_MPU_CONFIG_H
+#define LIBBSP_ARM_STM32H7_STM32H7_MPU_CONFIG_H
+
+#include <rtems/score/armv7m.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern const ARMV7M_MPU_Region_config stm32h7_config_mpu_region[];
+extern const size_t stm32h7_config_mpu_region_count;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBBSP_ARM_STM32H7_STM32H7_MPU_CONFIG_H */
diff --git a/bsps/arm/stm32h7/start/bspstarthooks.c b/bsps/arm/stm32h7/start/bspstarthooks.c
index 565bd6876a..dcd4b0bef2 100644
--- a/bsps/arm/stm32h7/start/bspstarthooks.c
+++ b/bsps/arm/stm32h7/start/bspstarthooks.c
@@ -31,6 +31,7 @@
#include <bsp/start.h>
#include <stm32h7/hal.h>
#include <stm32h7/memory.h>
+#include <stm32h7/mpu-config.h>
#include <rtems/score/armv7m.h>
#include <string.h>
@@ -83,123 +84,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 +110,7 @@ void bsp_start_hook_0(void)
SCB_EnableDCache();
}
- init_mpu();
+ _ARMV7M_MPU_Setup(stm32h7_config_mpu_region, stm32h7_config_mpu_region_count);
}
void bsp_start_hook_1(void)
diff --git a/bsps/arm/stm32h7/start/mpu-config.c b/bsps/arm/stm32h7/start/mpu-config.c
new file mode 100644
index 0000000000..8140e73c37
--- /dev/null
+++ b/bsps/arm/stm32h7/start/mpu-config.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bsp/linker-symbols.h>
+#include <stm32h7/memory.h>
+#include <stm32h7/mpu-config.h>
+
+const ARMV7M_MPU_Region_config stm32h7_config_mpu_region [] = {
+ {
+ .begin = stm32h7_memory_sram_axi_begin,
+ .end = stm32h7_memory_sram_axi_end,
+ .rasr = 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,
+ .rasr = 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,
+ .rasr = 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,
+ .rasr = 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,
+ .rasr = 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,
+ .rasr = ARMV7M_MPU_RASR_XN | ARMV7M_MPU_RASR_ENABLE,
+ }
+ };
+
+const size_t stm32h7_config_mpu_region_count =
+ RTEMS_ARRAY_SIZE(stm32h7_config_mpu_region);
diff --git a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
index c701e1037c..1c4e1a5aea 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/armv7m.h
@@ -22,6 +22,7 @@
#define RTEMS_SCORE_ARMV7M_H
#include <rtems/score/cpu.h>
+#include <rtems/score/assert.h>
#ifdef __cplusplus
extern "C" {
@@ -347,6 +348,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 rasr;
+} ARMV7M_MPU_Region_config;
+
typedef struct {
uint32_t dhcsr;
uint32_t dcrsr;
@@ -611,6 +630,89 @@ 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(
+ 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;
+
+ scb->shcsr &= ~ARMV7M_SCB_SHCSR_MEMFAULTENA;
+ mpu->ctrl = 0;
+
+ _ARM_Data_synchronization_barrier();
+ _ARM_Instruction_synchronization_barrier();
+
+ region_count = ARMV7M_MPU_TYPE_DREGION_GET(mpu->type);
+
+ _Assert(cfg_count > region_count);
+
+ for (region = 0; region < cfg_count; ++region) {
+ _ARMV7M_MPU_Set_region(mpu, region, cfg->rasr, cfg->begin, cfg->end);
+ }
+
+ for (region = cfg_count; region < region_count; ++region) {
+ _ARMV7M_MPU_Disable_region(mpu, region);
+ }
+
+ 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 */
diff --git a/spec/build/bsps/arm/stm32h7/bspstm32h7.yml b/spec/build/bsps/arm/stm32h7/bspstm32h7.yml
index 9fb7d3611f..835247316c 100644
--- a/spec/build/bsps/arm/stm32h7/bspstm32h7.yml
+++ b/spec/build/bsps/arm/stm32h7/bspstm32h7.yml
@@ -167,6 +167,7 @@ install:
source:
- bsps/arm/stm32h7/include/stm32h7/hal.h
- bsps/arm/stm32h7/include/stm32h7/memory.h
+ - bsps/arm/stm32h7/include/stm32h7/mpu-config.h
- destination: ${BSP_LIBDIR}
source:
- bsps/arm/stm32h7/start/bsp_specs
@@ -396,6 +397,7 @@ source:
- bsps/arm/stm32h7/start/bspstarthooks.c
- bsps/arm/stm32h7/start/ext-mem-ctl.c
- bsps/arm/stm32h7/start/getentropy-rng.c
+- bsps/arm/stm32h7/start/mpu-config.c
- bsps/arm/stm32h7/start/stm32h7-config.c
- bsps/arm/stm32h7/start/stm32h7-hal.c
- bsps/arm/stm32h7/start/stm32h7-hal-eth.c
--
2.26.2
More information about the devel
mailing list