summaryrefslogtreecommitdiff
path: root/ports/stm32/mpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/mpu.h')
-rw-r--r--ports/stm32/mpu.h52
1 files changed, 51 insertions, 1 deletions
diff --git a/ports/stm32/mpu.h b/ports/stm32/mpu.h
index 106112073..e95a07da9 100644
--- a/ports/stm32/mpu.h
+++ b/ports/stm32/mpu.h
@@ -26,7 +26,7 @@
#ifndef MICROPY_INCLUDED_STM32_MPU_H
#define MICROPY_INCLUDED_STM32_MPU_H
-#if defined(STM32F7) || defined(STM32H7) || defined(MICROPY_HW_ETH_MDC)
+#if (defined(STM32F4) && defined(MICROPY_HW_ETH_MDC)) || defined(STM32F7) || defined(STM32H7)
#define MPU_REGION_ETH (MPU_REGION_NUMBER0)
#define MPU_REGION_QSPI1 (MPU_REGION_NUMBER1)
@@ -97,9 +97,16 @@ static inline void mpu_config_end(uint32_t irq_state) {
#elif defined(STM32H5)
+#define MPU_REGION_SIG (MPU_REGION_NUMBER0)
+#define MPU_REGION_ETH (MPU_REGION_NUMBER1)
+
#define ST_DEVICE_SIGNATURE_BASE (0x08fff800)
#define ST_DEVICE_SIGNATURE_LIMIT (0x08ffffff)
+// STM32H5 Cortex-M33 MPU works differently from older cores.
+// Macro only takes region size in bytes, Attributes are coded in mpu_config_region().
+#define MPU_CONFIG_ETH(size) (size)
+
static inline void mpu_init(void) {
// Configure attribute 0, inner-outer non-cacheable (=0x44).
__DMB();
@@ -125,6 +132,49 @@ static inline void mpu_init(void) {
__ISB();
}
+static inline uint32_t mpu_config_start(void) {
+ return disable_irq();
+}
+
+static inline void mpu_config_region(uint32_t region, uint32_t base_addr, uint32_t size) {
+ if (region == MPU_REGION_ETH) {
+ // Configure region 1 to make DMA memory non-cacheable.
+
+ __DMB();
+ // Configure attribute 1, inner-outer non-cacheable (=0x44).
+ MPU->MAIR0 = (MPU->MAIR0 & ~MPU_MAIR0_Attr1_Msk)
+ | 0x44 << MPU_MAIR0_Attr1_Pos;
+ __DMB();
+
+ // RBAR
+ // BASE Bits [31:5] of base address
+ // SH[4:3] 00 = Non-shareable
+ // AP[2:1] 01 = Read/write by any privilege level
+ // XN[0]: 1 = No execution
+
+ // RLAR
+ // LIMIT Limit address. Contains bits[31:5] of the upper inclusive limit of the selected MPU memory region
+ // AT[3:1] 001 = Attribute 1
+ // EN[0] 1 = Enabled
+ MPU->RNR = region;
+ MPU->RBAR = (base_addr & MPU_RBAR_BASE_Msk)
+ | MPU_ACCESS_NOT_SHAREABLE << MPU_RBAR_SH_Pos
+ | MPU_REGION_ALL_RW << MPU_RBAR_AP_Pos
+ | MPU_INSTRUCTION_ACCESS_DISABLE << MPU_RBAR_XN_Pos;
+ MPU->RLAR = ((base_addr + size - 1) & MPU_RLAR_LIMIT_Msk)
+ | MPU_ATTRIBUTES_NUMBER1 << MPU_RLAR_AttrIndx_Pos
+ | MPU_REGION_ENABLE << MPU_RLAR_EN_Pos;
+ }
+ __DMB();
+}
+
+static inline void mpu_config_end(uint32_t irq_state) {
+ __ISB();
+ __DSB();
+ __DMB();
+ enable_irq(irq_state);
+}
+
#else
static inline void mpu_init(void) {