Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
Diff: hal/mpu/mbed_mpu_v8m.c
- Revision:
- 0:5b88d5760320
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hal/mpu/mbed_mpu_v8m.c Tue Dec 17 23:23:45 2019 +0000
@@ -0,0 +1,211 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2018 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "hal/mpu_api.h"
+#include "platform/mbed_assert.h"
+#include "cmsis.h"
+
+#if ((__ARM_ARCH_8M_BASE__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U)) && \
+ defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) && \
+ !defined(MBED_MPU_CUSTOM)
+
+#if !DEVICE_MPU
+#error "Device has v8m MPU but it is not enabled. Add 'MPU' to device_has in targets.json"
+#endif
+
+#ifdef MBED_CONF_TARGET_MPU_ROM_END
+#define MBED_MPU_ROM_END MBED_CONF_TARGET_MPU_ROM_END
+#else
+#define MBED_MPU_ROM_END (0x10000000 - 1)
+#endif
+#define MBED_MPU_RAM_START (MBED_MPU_ROM_END + 1)
+
+MBED_STATIC_ASSERT(MBED_MPU_ROM_END <= 0x20000000 - 1,
+ "Unsupported value for MBED_MPU_ROM_END");
+
+void mbed_mpu_init()
+{
+ // Flush memory writes before configuring the MPU.
+ __DMB();
+
+ const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
+
+ // Our MPU setup requires 4 or 5 regions - if this assert is hit, remove
+ // a region by setting MPU_ROM_END to 0x1fffffff, or remove MPU from device_has
+#if MBED_MPU_RAM_START == 0x20000000
+ MBED_ASSERT(regions >= 4);
+#else
+ MBED_ASSERT(regions >= 5);
+#endif
+
+ // Disable the MCU
+ MPU->CTRL = 0;
+
+ // Reset all mapping
+ for (uint32_t i = 0; i < regions; i++) {
+ ARM_MPU_ClrRegion(i);
+ }
+
+ /*
+ * ARMv8-M memory map:
+ *
+ * Start End Name Executable by default Default cache Mbed MPU protection
+ * 0x00000000 - 0x1FFFFFFF Code Yes WT, WA Write disabled for first portion and execute disabled for the rest
+ * 0x20000000 - 0x3FFFFFFF SRAM Yes WB, WA, RA Execute disabled
+ * 0x40000000 - 0x5FFFFFFF Peripheral No
+ * 0x60000000 - 0x7FFFFFFF RAM Yes WB, WA, RA Execute disabled
+ * 0x80000000 - 0x9FFFFFFF RAM Yes WT, RA Execute disabled
+ * 0xA0000000 - 0xBFFFFFFF Device No
+ * 0xC0000000 - 0xDFFFFFFF Device No
+ * 0xE0000000 - 0xFFFFFFFF System No
+ */
+
+ const uint8_t WTRA = ARM_MPU_ATTR_MEMORY_(1, 0, 1, 0); // Non-transient, Write-Through, Read-allocate, Not Write-allocate
+ const uint8_t WBWARA = ARM_MPU_ATTR_MEMORY_(1, 1, 1, 1); // Non-transient, Write-Back, Read-allocate, Write-allocate
+ enum {
+ AttrIndex_WTRA,
+ AttrIndex_WBWARA,
+ };
+
+ ARM_MPU_SetMemAttr(AttrIndex_WTRA, ARM_MPU_ATTR(WTRA, WTRA));
+ ARM_MPU_SetMemAttr(AttrIndex_WBWARA, ARM_MPU_ATTR(WBWARA, WBWARA));
+
+ ARM_MPU_SetRegion(
+ 0, // Region
+ ARM_MPU_RBAR(
+ 0x00000000, // Base
+ ARM_MPU_SH_NON, // Non-shareable
+ 1, // Read-Only
+ 1, // Non-Privileged
+ 0), // Execute Never disabled
+ ARM_MPU_RLAR(
+ MBED_MPU_ROM_END, // Limit
+ AttrIndex_WTRA) // Attribute index - Write-Through, Read-allocate
+ );
+
+#if MBED_MPU_RAM_START != 0x20000000
+ ARM_MPU_SetRegion(
+ 4, // Region
+ ARM_MPU_RBAR(
+ MBED_MPU_RAM_START, // Base
+ ARM_MPU_SH_NON, // Non-shareable
+ 0, // Read-Write
+ 1, // Non-Privileged
+ 1), // Execute Never enabled
+ ARM_MPU_RLAR(
+ 0x1FFFFFFF, // Limit
+ AttrIndex_WTRA) // Attribute index - Write-Through, Read-allocate
+ );
+#define LAST_RAM_REGION 4
+#else
+#define LAST_RAM_REGION 3
+#endif
+
+ ARM_MPU_SetRegion(
+ 1, // Region
+ ARM_MPU_RBAR(
+ 0x20000000, // Base
+ ARM_MPU_SH_NON, // Non-shareable
+ 0, // Read-Write
+ 1, // Non-Privileged
+ 1), // Execute Never enabled
+ ARM_MPU_RLAR(
+ 0x3FFFFFFF, // Limit
+ AttrIndex_WBWARA) // Attribute index - Write-Back, Write-allocate
+ );
+
+ ARM_MPU_SetRegion(
+ 2, // Region
+ ARM_MPU_RBAR(
+ 0x60000000, // Base
+ ARM_MPU_SH_NON, // Non-shareable
+ 0, // Read-Write
+ 1, // Non-Privileged
+ 1), // Execute Never enabled
+ ARM_MPU_RLAR(
+ 0x7FFFFFFF, // Limit
+ AttrIndex_WBWARA) // Attribute index - Write-Back, Write-allocate
+ );
+
+ ARM_MPU_SetRegion(
+ 3, // Region
+ ARM_MPU_RBAR(
+ 0x80000000, // Base
+ ARM_MPU_SH_NON, // Non-shareable
+ 0, // Read-Write
+ 1, // Non-Privileged
+ 1), // Execute Never enabled
+ ARM_MPU_RLAR(
+ 0x9FFFFFFF, // Limit
+ AttrIndex_WTRA) // Attribute index - Write-Through, Read-allocate
+ );
+
+ // Enable the MPU
+ MPU->CTRL =
+ (1 << MPU_CTRL_PRIVDEFENA_Pos) | // Use the default memory map for unmapped addresses
+ (1 << MPU_CTRL_HFNMIENA_Pos) | // Keep MPU turned on for faults
+ (1 << MPU_CTRL_ENABLE_Pos); // Enable MPU
+
+ // Ensure changes take effect
+ __DSB();
+ __ISB();
+}
+
+void mbed_mpu_free()
+{
+ // Flush memory writes before configuring the MPU.
+ __DMB();
+
+ // Disable the MCU
+ MPU->CTRL = 0;
+
+ // Ensure changes take effect
+ __DSB();
+ __ISB();
+}
+
+static void enable_region(bool enable, uint32_t region)
+{
+ MPU->RNR = region;
+ MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable << MPU_RLAR_EN_Pos);
+}
+
+void mbed_mpu_enable_rom_wn(bool enable)
+{
+ // Flush memory writes before configuring the MPU.
+ __DMB();
+
+ enable_region(enable, 0);
+
+ // Ensure changes take effect
+ __DSB();
+ __ISB();
+}
+
+void mbed_mpu_enable_ram_xn(bool enable)
+{
+ // Flush memory writes before configuring the MPU.
+ __DMB();
+
+ for (uint32_t region = 1; region <= LAST_RAM_REGION; region++) {
+ enable_region(enable, region);
+ }
+
+ // Ensure changes take effect
+ __DSB();
+ __ISB();
+}
+
+#endif