diff --git a/TESTS/mbed_hal/flash/functional_tests/main.cpp b/TESTS/mbed_hal/flash/functional_tests/main.cpp index aec1ffea813..06c876dfdd9 100644 --- a/TESTS/mbed_hal/flash/functional_tests/main.cpp +++ b/TESTS/mbed_hal/flash/functional_tests/main.cpp @@ -21,6 +21,7 @@ #include "utest/utest.h" #include "unity/unity.h" #include "greentea-client/test_env.h" +#include "platform/mbed_mpu_mgmt.h" #include "mbed.h" #include "flash_api.h" @@ -251,11 +252,22 @@ Case cases[] = { utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + mbed_mpu_manager_lock_ram_execution(); + mbed_mpu_manager_lock_rom_write(); + GREENTEA_SETUP(20, "default_auto"); return greentea_test_setup_handler(number_of_cases); } -Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); +void greentea_test_teardown(const size_t passed, const size_t failed, const failure_t failure) +{ + mbed_mpu_manager_unlock_ram_execution(); + mbed_mpu_manager_unlock_rom_write(); + + greentea_test_teardown_handler(passed, failed, failure); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown); int main() { diff --git a/TESTS/mbed_hal/mpu/main.cpp b/TESTS/mbed_hal/mpu/main.cpp new file mode 100644 index 00000000000..fa12658d9ae --- /dev/null +++ b/TESTS/mbed_hal/mpu/main.cpp @@ -0,0 +1,201 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 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 "utest/utest.h" +#include "unity/unity.h" +#include "greentea-client/test_env.h" + +#include "cmsis.h" +#include + +#include "mpu_api.h" +#include "mpu_test.h" + +#if !DEVICE_MPU +#error [NOT_SUPPORTED] MPU API not supported for this target +#endif + +using namespace utest::v1; + +#define HARDFAULT_IRQn ((IRQn_Type)-13) +#define MEMFAULT_IRQn ((IRQn_Type)-12) + +// Assembly return instruction: bx lr +#define ASM_BX_LR 0x4770 + +volatile uint32_t fault_count; +uint32_t real_hard_fault_handler; +uint32_t real_mem_fault_handler; + +static volatile uint16_t data_function = ASM_BX_LR; +static volatile uint16_t bss_function; + +static void clear_caches() +{ +#if defined(__CORTEX_M7) + /* Data cache clean and invalid */ + SCB_CleanInvalidateDCache(); + + /* Instruction cache invalid */ + SCB_InvalidateICache(); +#endif + + __ISB(); + __DSB(); + +} + +static void call_mem(const volatile uint16_t *mem_function) +{ + // or the address with 1 to ensure the thumb bit is set + ((void (*)())((uint32_t)mem_function | 1))(); +} + +static void hard_fault_handler_test() +{ + fault_count++; + mbed_mpu_enable_ram_xn(false); +} + +static void mpu_fault_test(const volatile uint16_t *mem_function) +{ + mbed_mpu_init(); + + // Verify that the mpu causes faults when executing ram + fault_count = 0; + mbed_mpu_enable_ram_xn(true); + call_mem(mem_function); + TEST_ASSERT_EQUAL(1, fault_count); + + // Verify that the mpu can be turned off + fault_count = 0; + mbed_mpu_enable_ram_xn(false); + call_mem(mem_function); + TEST_ASSERT_EQUAL(0, fault_count); + + // Verify that the mpu causes faults when executing ram + fault_count = 0; + mbed_mpu_enable_ram_xn(true); + call_mem(mem_function); + TEST_ASSERT_EQUAL(1, fault_count); + + // Verify that free turns off the mpu + fault_count = 0; + mbed_mpu_free(); + call_mem(mem_function); + TEST_ASSERT_EQUAL(0, fault_count); +} + +void mpu_init_test() +{ + for (int i = 0; i < 10; i++) { + mbed_mpu_init(); + } + + mbed_mpu_free(); +} + +void mpu_free_test() +{ + mbed_mpu_init(); + + // Enable the MPU + mbed_mpu_enable_ram_xn(true); + + // Free and ensure execution from RAM is allowed + mbed_mpu_free(); + + call_mem(&data_function); +} + +void mpu_fault_test_data() +{ + mpu_fault_test(&data_function); +} + +void mpu_fault_test_bss() +{ + bss_function = ASM_BX_LR; + clear_caches(); + mpu_fault_test(&bss_function); +} + +void mpu_fault_test_stack() +{ + uint16_t stack_function; + + stack_function = ASM_BX_LR; + clear_caches(); + mpu_fault_test(&stack_function); +} + +void mpu_fault_test_heap() +{ + uint16_t *heap_function = (uint16_t *)malloc(2); + + TEST_ASSERT_NOT_EQUAL(NULL, heap_function); + *heap_function = ASM_BX_LR; + clear_caches(); + mpu_fault_test(heap_function); + + free(heap_function); +} + +utest::v1::status_t fault_override_setup(const Case *const source, const size_t index_of_case) +{ + // Save old fault handlers and replace it with a new one + real_hard_fault_handler = NVIC_GetVector(HARDFAULT_IRQn); + real_mem_fault_handler = NVIC_GetVector(MEMFAULT_IRQn); + NVIC_SetVector(HARDFAULT_IRQn, (uint32_t)&hard_fault_handler_test); + NVIC_SetVector(MEMFAULT_IRQn, (uint32_t)&hard_fault_handler_test); + + return greentea_case_setup_handler(source, index_of_case); +} + +utest::v1::status_t fault_override_teardown(const Case *const source, const size_t passed, const size_t failed, + const failure_t reason) +{ + // Restore real fault handlers + NVIC_SetVector(HARDFAULT_IRQn, real_hard_fault_handler); + NVIC_SetVector(MEMFAULT_IRQn, real_mem_fault_handler); + + return greentea_case_teardown_handler(source, passed, failed, reason); +} + +Case cases[] = { + Case("MPU - init", fault_override_setup, mpu_init_test, fault_override_teardown), + Case("MPU - free", fault_override_setup, mpu_free_test, fault_override_teardown), +#if !((__ARM_ARCH_8M_BASE__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U)) + // Skip fault tests for ARMv8-M until a fault handler hook is provided + Case("MPU - data fault", fault_override_setup, mpu_fault_test_data, fault_override_teardown), + Case("MPU - bss fault", fault_override_setup, mpu_fault_test_bss, fault_override_teardown), + Case("MPU - stack fault", fault_override_setup, mpu_fault_test_stack, fault_override_teardown), + Case("MPU - heap fault", fault_override_setup, mpu_fault_test_heap, fault_override_teardown) +#endif +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(20, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() +{ + Harness::run(specification); +} diff --git a/TESTS/mbed_hal/mpu/mpu_test.h b/TESTS/mbed_hal/mpu/mpu_test.h new file mode 100644 index 00000000000..1230fc8b05f --- /dev/null +++ b/TESTS/mbed_hal/mpu/mpu_test.h @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018-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. + */ + +/** \addtogroup hal_mpu_tests + * @{ + */ + +#ifndef MBED_MPU_TEST_H +#define MBED_MPU_TEST_H + +#if DEVICE_MPU + +#ifdef __cplusplus +extern "C" { +#endif + +/** Test that ::mbed_mpu_init can be called multiple times. + * + * Given board provides MPU. + * When ::mbed_mpu_init is called multiple times. + * Then ::mbed_mpu_init are successfully performed (no exception is generated). + * + */ +void mpu_init_test(void); + +/** Test that ::mbed_mpu_free disables the MPU + * + * Given board provides MPU. + * When ::mbed_mpu_free is called. + * Then execution from RAM is allowed. + * + */ +void mpu_free_test(void); + +/** Test that MPU protection works for global data + * + * Given board provides MPU. + * When RAM execution is disabled with a call to ::mbed_mpu_enable_ram_xn. + * Then execution from global initialized data results in a fault. + * + */ +void mpu_fault_test_data(void); + +/** Test that MPU protection works for zero initialized data + * + * Given board provides MPU. + * When RAM execution is disabled with a call to ::mbed_mpu_enable_ram_xn. + * Then execution from global uninitialized data results in a fault. + * + */ +void mpu_fault_test_bss(void); + +/** Test that MPU protection works for the stack + * + * Given board provides MPU. + * When RAM execution is disabled with a call to ::mbed_mpu_enable_ram_xn. + * Then execution from stack memory results in a fault. + * + */ +void mpu_fault_test_stack(void); + +/** Test that MPU protection works for the heap + * + * Given board provides MPU. + * When RAM execution is disabled with a call to ::mbed_mpu_enable_ram_xn. + * Then execution from heap memory results in a fault. + * + */ +void mpu_fault_test_heap(void); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +/** @}*/ diff --git a/doxyfile_options b/doxyfile_options index c2571187196..43aca60d4de 100644 --- a/doxyfile_options +++ b/doxyfile_options @@ -2083,6 +2083,7 @@ PREDEFINED = DOXYGEN_ONLY \ DEVICE_INTERRUPTIN \ DEVICE_ITM \ DEVICE_LPTICKER \ + DEVICE_MPU \ DEVICE_PORTIN \ DEVICE_PORTINOUT \ DEVICE_PORTOUT \ diff --git a/doxygen_options.json b/doxygen_options.json index 5cb33a46125..fc1279a5ece 100644 --- a/doxygen_options.json +++ b/doxygen_options.json @@ -6,7 +6,7 @@ "SEARCH_INCLUDES": "YES", "INCLUDE_PATH": "", "INCLUDE_FILE_PATTERNS": "", - "PREDEFINED": "DOXYGEN_ONLY DEVICE_ANALOGIN DEVICE_ANALOGOUT DEVICE_CAN DEVICE_CRC DEVICE_ETHERNET DEVICE_EMAC DEVICE_FLASH DEVICE_I2C DEVICE_I2CSLAVE DEVICE_I2C_ASYNCH DEVICE_INTERRUPTIN DEVICE_ITM DEVICE_LPTICKER DEVICE_PORTIN DEVICE_PORTINOUT DEVICE_PORTOUT DEVICE_PWMOUT DEVICE_RTC DEVICE_TRNG DEVICE_SERIAL DEVICE_SERIAL_ASYNCH DEVICE_SERIAL_FC DEVICE_SLEEP DEVICE_SPI DEVICE_SPI_ASYNCH DEVICE_SPISLAVE DEVICE_QSPI DEVICE_STORAGE \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\" \"MBED_DEPRECATED(s)=\"", + "PREDEFINED": "DOXYGEN_ONLY DEVICE_ANALOGIN DEVICE_ANALOGOUT DEVICE_CAN DEVICE_CRC DEVICE_ETHERNET DEVICE_EMAC DEVICE_FLASH DEVICE_I2C DEVICE_I2CSLAVE DEVICE_I2C_ASYNCH DEVICE_INTERRUPTIN DEVICE_ITM DEVICE_LPTICKER DEVICE_MPU DEVICE_PORTIN DEVICE_PORTINOUT DEVICE_PORTOUT DEVICE_PWMOUT DEVICE_RTC DEVICE_TRNG DEVICE_SERIAL DEVICE_SERIAL_ASYNCH DEVICE_SERIAL_FC DEVICE_SLEEP DEVICE_SPI DEVICE_SPI_ASYNCH DEVICE_SPISLAVE DEVICE_QSPI DEVICE_STORAGE \"MBED_DEPRECATED_SINCE(f, g)=\" \"MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)=\" \"MBED_DEPRECATED(s)=\"", "EXPAND_AS_DEFINED": "", "SKIP_FUNCTION_MACROS": "NO", "STRIP_CODE_COMMENTS": "NO", diff --git a/drivers/FlashIAP.cpp b/drivers/FlashIAP.cpp index b6b1c2377da..8ef6f6e1b0b 100644 --- a/drivers/FlashIAP.cpp +++ b/drivers/FlashIAP.cpp @@ -25,6 +25,8 @@ #include #include "FlashIAP.h" #include "platform/mbed_assert.h" +#include "platform/ScopedRamExecutionLock.h" +#include "platform/ScopedRomWriteLock.h" #ifdef DEVICE_FLASH @@ -56,8 +58,12 @@ int FlashIAP::init() { int ret = 0; _mutex->lock(); - if (flash_init(&_flash)) { - ret = -1; + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + if (flash_init(&_flash)) { + ret = -1; + } } uint32_t page_size = get_page_size(); _page_buf = new uint8_t[page_size]; @@ -70,8 +76,12 @@ int FlashIAP::deinit() { int ret = 0; _mutex->lock(); - if (flash_free(&_flash)) { - ret = -1; + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + if (flash_free(&_flash)) { + ret = -1; + } } delete[] _page_buf; _mutex->unlock(); @@ -83,7 +93,11 @@ int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size) { int32_t ret = -1; _mutex->lock(); - ret = flash_read(&_flash, addr, (uint8_t *) buffer, size); + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + ret = flash_read(&_flash, addr, (uint8_t *) buffer, size); + } _mutex->unlock(); return ret; } @@ -126,9 +140,13 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size) prog_buf = buf; prog_size = chunk; } - if (flash_program_page(&_flash, addr, prog_buf, prog_size)) { - ret = -1; - break; + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + if (flash_program_page(&_flash, addr, prog_buf, prog_size)) { + ret = -1; + break; + } } size -= chunk; addr += chunk; @@ -170,7 +188,11 @@ int FlashIAP::erase(uint32_t addr, uint32_t size) int32_t ret = 0; _mutex->lock(); while (size) { - ret = flash_erase_sector(&_flash, addr); + { + ScopedRamExecutionLock make_ram_executable; + ScopedRomWriteLock make_rom_writable; + ret = flash_erase_sector(&_flash, addr); + } if (ret != 0) { ret = -1; break; diff --git a/hal/mpu/mbed_mpu_v7m.c b/hal/mpu/mbed_mpu_v7m.c new file mode 100644 index 00000000000..5778e747399 --- /dev/null +++ b/hal/mpu/mbed_mpu_v7m.c @@ -0,0 +1,230 @@ +/* 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 "platform/mbed_error.h" +#include "cmsis.h" + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_6M__ == 1U)) && \ + defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) && \ + !defined(MBED_MPU_CUSTOM) + +#if !DEVICE_MPU +#error "Device has v7m MPU but it is not enabled. Add 'MPU' to device_has in targets.json" +#endif + +#if !defined(MBED_MPU_ROM_END) +#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 == 0x04000000 - 1 || + MBED_MPU_ROM_END == 0x08000000 - 1 || + MBED_MPU_ROM_END == 0x0C000000 - 1 || + MBED_MPU_ROM_END == 0x10000000 - 1 || + MBED_MPU_ROM_END == 0x14000000 - 1 || + MBED_MPU_ROM_END == 0x18000000 - 1 || + MBED_MPU_ROM_END == 0x1C000000 - 1 || + MBED_MPU_ROM_END == 0x20000000 - 1, + "Unsupported value for MBED_MPU_ROM_END"); + +void mbed_mpu_init() +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; + if (regions < 4) { + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_EINVAL), "Device is not capable of supporting an MPU - remove DEVICE_MPU for device_has."); + } + + // Disable the MCU + MPU->CTRL = 0; + + // Reset all mapping + for (uint32_t i = 0; i < regions; i++) { + ARM_MPU_ClrRegion(i); + } + + /* + * ARMv6m and ARMv7-M memory map: + * + * Start End Name Executable by default Mbed MPU protection + * 0x00000000 - 0x1FFFFFFF Code Yes Write disabled for first portion and execute disabled for the rest + * 0x20000000 - 0x3FFFFFFF SRAM Yes Execute disabled + * 0x40000000 - 0x5FFFFFFF Peripheral No + * 0x60000000 - 0x7FFFFFFF RAM Yes Execute disabled + * 0x80000000 - 0x9FFFFFFF RAM Yes Execute disabled + * 0xA0000000 - 0xBFFFFFFF Device No + * 0xC0000000 - 0xDFFFFFFF Device No + * 0xE0000000 - 0xFFFFFFFF System No + */ + + // Select region 1 and used it for the WT rom region + // - RAM 0x00000000 to MBED_MPU_ROM_END + MPU->RNR = 0; + // Set address to 0 + MPU->RBAR = 0; + // Configure and enable region + MPU->RASR = + ARM_MPU_RASR( + 0, // DisableExec + ARM_MPU_AP_RO, // AccessPermission + 0, // TypeExtField + 0, // IsShareable + 1, // IsCacheable + 0, // IsBufferable + // SubRegionDisable - based on where ROM ends + ((MBED_MPU_ROM_END >= 0x00000000) ? 0 : (1 << 0)) | // 0 to enable, 1 << n to disable + ((MBED_MPU_ROM_END >= 0x04000000) ? 0 : (1 << 1)) | + ((MBED_MPU_ROM_END >= 0x08000000) ? 0 : (1 << 2)) | + ((MBED_MPU_ROM_END >= 0x0C000000) ? 0 : (1 << 3)) | + ((MBED_MPU_ROM_END >= 0x10000000) ? 0 : (1 << 4)) | + ((MBED_MPU_ROM_END >= 0x14000000) ? 0 : (1 << 5)) | + ((MBED_MPU_ROM_END >= 0x18000000) ? 0 : (1 << 6)) | + ((MBED_MPU_ROM_END >= 0x1C000000) ? 0 : (1 << 7)), + ARM_MPU_REGION_SIZE_512MB // Size + ); + + // Select region 1 and used it for the WT rom region + // - RAM MBED_MPU_ROM_END + 1 to 0x1FFFFFFF + MPU->RNR = 1; + // Set address to 0 + MPU->RBAR = 0; + // Configure and enable region + MPU->RASR = + ARM_MPU_RASR( + 1, // DisableExec + ARM_MPU_AP_FULL, // AccessPermission + 0, // TypeExtField + 0, // IsShareable + 1, // IsCacheable + 0, // IsBufferable + // SubRegionDisable - based on where RAM starts + ((MBED_MPU_RAM_START <= 0x04000000) ? 0 : (1 << 0)) | // 0 to enable, 1 << n to disable + ((MBED_MPU_RAM_START <= 0x08000000) ? 0 : (1 << 1)) | + ((MBED_MPU_RAM_START <= 0x0C000000) ? 0 : (1 << 2)) | + ((MBED_MPU_RAM_START <= 0x10000000) ? 0 : (1 << 3)) | + ((MBED_MPU_RAM_START <= 0x14000000) ? 0 : (1 << 4)) | + ((MBED_MPU_RAM_START <= 0x18000000) ? 0 : (1 << 5)) | + ((MBED_MPU_RAM_START <= 0x1C000000) ? 0 : (1 << 6)) | + ((MBED_MPU_RAM_START <= 0x20000000) ? 0 : (1 << 7)), + ARM_MPU_REGION_SIZE_512MB // Size + ); + + // Select region 2 and used it for WBWA ram regions + // - SRAM 0x20000000 to 0x3FFFFFFF + // - RAM 0x60000000 to 0x7FFFFFFF + MPU->RNR = 2; + // Set address to 0 + MPU->RBAR = 0; + // Configure and enable region + MPU->RASR = + ARM_MPU_RASR( + 1, // DisableExec + ARM_MPU_AP_FULL, // AccessPermission + 1, // TypeExtField + 0, // IsShareable + 1, // IsCacheable + 1, // IsBufferable + // SubRegionDisable + (1 << 0) | // Disable Sub-region + (0 << 1) | // Enable Sub-region SRAM 0x20000000 - 0x3FFFFFFF + (1 << 2) | // Disable Sub-region + (0 << 3) | // Enable Sub-region RAM 0x60000000 - 0x7FFFFFFF + (1 << 4) | // Disable Sub-region + (1 << 5) | // Disable Sub-region + (1 << 6) | // Disable Sub-region + (1 << 7), // Disable Sub-region + ARM_MPU_REGION_SIZE_4GB // Size + ); + + // Select region 3 and used it for the WT ram region + // - RAM RAM 0x80000000 to 0x9FFFFFFF + MPU->RNR = 3; + // Set address + MPU->RBAR = 0x80000000; + // Configure and enable region + MPU->RASR = + ARM_MPU_RASR( + 1, // DisableExec + ARM_MPU_AP_FULL, // AccessPermission + 0, // TypeExtField + 0, // IsShareable + 1, // IsCacheable + 0, // IsBufferable + ~0U, // SubRegionDisable + ARM_MPU_REGION_SIZE_512MB // Size + ); + + // 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 + __ISB(); + __DSB(); +} + +void mbed_mpu_free() +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + // Disable the MPU + MPU->CTRL = 0; + + // Ensure changes take effect + __ISB(); + __DSB(); +} + +void mbed_mpu_enable_rom_wn(bool enable) +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + MPU->RNR = 0; + MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); + + // Ensure changes take effect + __ISB(); + __DSB(); +} + +void mbed_mpu_enable_ram_xn(bool enable) +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + MPU->RNR = 1; + MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); + + MPU->RNR = 2; + MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); + + MPU->RNR = 3; + MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); + + // Ensure changes take effect + __ISB(); + __DSB(); +} + +#endif diff --git a/hal/mpu/mbed_mpu_v8m.c b/hal/mpu/mbed_mpu_v8m.c new file mode 100644 index 00000000000..a0bab96532f --- /dev/null +++ b/hal/mpu/mbed_mpu_v8m.c @@ -0,0 +1,175 @@ +/* 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 "platform/mbed_error.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 + +#if !defined(MBED_MPU_ROM_END) +#define MBED_MPU_ROM_END (0x20000000 - 1) +#endif + +MBED_STATIC_ASSERT(MBED_MPU_ROM_END == 0x1fffffff, "Changing MBED_MPU_ROM_END for ARMv8-M is not supported."); + +void mbed_mpu_init() +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; + if (regions < 4) { + MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_EINVAL), "Device is not capable of supporting an MPU - remove DEVICE_MPU for device_has."); + } + + // Disable the MCU + MPU->CTRL = 0; + + // Reset all mapping + for (uint32_t i = 0; i < regions; i++) { + ARM_MPU_ClrRegionEx(MPU, i); + } + + /* + * ARMv8-M memory map: + * + * Start End Name Executable by default Default cache Mbed MPU protection + * 0x00000000 - 0x1FFFFFFF Code Yes WT, WA Write disabled + * 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 + */ + + uint32_t region; + uint8_t outer; + uint8_t inner; + + region = 0; + MPU->RNR = region; + outer = 0xA; // Write-Through, Non-transient, Read-allocate + inner = 0xA; // Write-Through, Non-transient, Read-allocate + ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0)); + MPU->RBAR = (0x00000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x00000000 + (0 << MPU_RBAR_SH_Pos) | // Not shareable + (3 << MPU_RBAR_AP_Pos) | // RO allowed by all privilege levels + (0 << MPU_RBAR_XN_Pos); // Execute Never disabled + MPU->RLAR = (0x1FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x1FFFFFFF + (region << MPU_RLAR_AttrIndx_Pos); // Attribute index - configured to be the same as the region number + + region = 1; + MPU->RNR = region; + outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate + outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate + ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0)); + MPU->RBAR = (0x20000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x20000000 + (0 << MPU_RBAR_SH_Pos) | // Not shareable + (1 << MPU_RBAR_AP_Pos) | // RW allowed by all privilege levels + (1 << MPU_RBAR_XN_Pos); // Execute Never enabled + MPU->RLAR = (0x3FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x3FFFFFFF + (region << MPU_RLAR_AttrIndx_Pos); // Attribute index - configured to be the same as the region number + + region = 2; + MPU->RNR = region; + outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate + outer = 0xF; // Write-Back, Non-transient, Read-allocate, Write-allocate + ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0)); + MPU->RBAR = (0x60000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x60000000 + (0 << MPU_RBAR_SH_Pos) | // Not shareable + (1 << MPU_RBAR_AP_Pos) | // RW allowed by all privilege levels + (1 << MPU_RBAR_XN_Pos); // Execute Never enabled + MPU->RLAR = (0x7FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x7FFFFFFF + (region << MPU_RLAR_AttrIndx_Pos); // Attribute index - configured to be the same as the region number + + region = 3; + MPU->RNR = region; + outer = 0xA; // Write-Through, Non-transient, Read-allocate + inner = 0xA; // Write-Through, Non-transient, Read-allocate + ARM_MPU_SetMemAttrEx(MPU, region, (outer << 4) | (inner << 0)); + MPU->RBAR = (0x80000000 & MPU_RBAR_BASE_Msk) | // Start address is 0x80000000 + (0 << MPU_RBAR_SH_Pos) | // Not shareable + (1 << MPU_RBAR_AP_Pos) | // RW allowed by all privilege levels + (1 << MPU_RBAR_XN_Pos); // Execute Never enabled + MPU->RLAR = (0x9FFFFFFF & MPU_RLAR_LIMIT_Msk) | // Last address is 0x9FFFFFFF + (region << MPU_RLAR_AttrIndx_Pos); // Attribute index - configured to be the same as the region number + + // 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 + __ISB(); + __DSB(); +} + +void mbed_mpu_free() +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + // Disable the MCU + MPU->CTRL = 0; + + // Ensure changes take effect + __ISB(); + __DSB(); +} + +void mbed_mpu_enable_rom_wn(bool enable) +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + MPU->RNR = 0; + MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); + + // Ensure changes take effect + __ISB(); + __DSB(); +} + +void mbed_mpu_enable_ram_xn(bool enable) +{ + // Flush memory writes before configuring the MPU. + __DSB(); + + MPU->RNR = 1; + MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); + + MPU->RNR = 2; + MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); + + MPU->RNR = 3; + MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); + + // Ensure changes take effect + __ISB(); + __DSB(); +} + +#endif diff --git a/hal/mpu_api.h b/hal/mpu_api.h new file mode 100644 index 00000000000..5c02c740ffc --- /dev/null +++ b/hal/mpu_api.h @@ -0,0 +1,118 @@ + +/** \addtogroup hal */ +/** @{*/ +/* mbed Microcontroller Library + * Copyright (c) 2018-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. + */ +#ifndef MBED_MPU_API_H +#define MBED_MPU_API_H + +#include "device.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if DEVICE_MPU + +/** + * \defgroup hal_mpu MPU hal + * + * The MPU hal provides a simple MPU API to enhance device security by preventing + * execution from ram. + * + * # Defined behavior + * * The function ::mbed_mpu_init is safe to call repeatedly - Verified by ::mpu_init_test + * * The function ::mbed_mpu_free disables MPU protection - Verified by ::mpu_free_test + * * Execution from RAM results in a fault when execute never is enabled. + * This RAM includes heap, stack, data and zero init - Verified by ::mpu_fault_test_data, + * ::mpu_fault_test_bss, ::mpu_fault_test_stack and ::mpu_fault_test_heap. + * * Writing to ROM results in a fault when write never is enabled - Not verified + * + * # Undefined behavior + * * Calling any function other than ::mbed_mpu_init before the initialization of the MPU. + * + * @see hal_mpu_tests + * + * @{ + */ + +/** + * \defgroup hal_mpu_tests MPU hal tests + * The MPU test validates proper implementation of the MPU hal. + * + * To run the MPU hal tests use the command: + * + * mbed test -t -m -n tests-mbed_hal-mpu* + */ + + +/** + * Initialize the MPU + * + * Initialize or re-initialize the memory protection unit. + * It is implementation defined what region are protected + * by the MPU after initialization. + */ +void mbed_mpu_init(void); + +/** + * Enable or disable ROM MPU protection + * + * This function is used to mark all of ROM as read and execute only. + * When enabled writes to ROM cause a fault. + * + * @param enable true to disable execution in ram, false otherwise + */ +void mbed_mpu_enable_rom_wn(bool enable); + +/** + * Enable or disable ram MPU protection + * + * This function is used to mark all of RAM as execute never. + * When enabled code is only allowed to execute from flash. + * + * @param enable true to disable execution in ram, false otherwise + */ +void mbed_mpu_enable_ram_xn(bool enable); + +/** Deinitialize the MPU + * + * Powerdown the MPU in preparation for powerdown, reset or jumping to another application. + */ +void mbed_mpu_free(void); + +/**@}*/ + +#else + +#define mbed_mpu_init() + +#define mbed_mpu_enable_rom_wn(enable) (void)enable + +#define mbed_mpu_enable_ram_xn(enable) (void)enable + +#define mbed_mpu_free() + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +/** @}*/ diff --git a/mbed.h b/mbed.h index 662f07599e0..6e1e9619125 100644 --- a/mbed.h +++ b/mbed.h @@ -95,6 +95,8 @@ #include "platform/DirHandle.h" #include "platform/CriticalSectionLock.h" #include "platform/DeepSleepLock.h" +#include "platform/ScopedRomWriteLock.h" +#include "platform/ScopedRamExecutionLock.h" #include "platform/mbed_stats.h" // mbed Non-hardware components diff --git a/platform/ScopedRamExecutionLock.h b/platform/ScopedRamExecutionLock.h new file mode 100644 index 00000000000..d45b3f90668 --- /dev/null +++ b/platform/ScopedRamExecutionLock.h @@ -0,0 +1,72 @@ +/* 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. + */ +#ifndef MBED_SCOPEDRAMEXECUTIONLOCK_H +#define MBED_SCOPEDRAMEXECUTIONLOCK_H + +#include "platform/mbed_mpu_mgmt.h" +#include "platform/NonCopyable.h" + +namespace mbed { + +/** \addtogroup platform */ +/** @{*/ + +/** RAII object for disabling, then restoring RAM execute never mode + * Usage: + * @code + * + * void f() { + * // some code here + * { + * ScopedRamExecutionLock make_ram_executable; + * // Code in this block is allowed to call functions in RAM + * } + * // Execution from RAM is no longer allowed + * } + * @endcode + */ +class ScopedRamExecutionLock : private mbed::NonCopyable { +public: + + /** + * Allow execution from RAM + * + * Increment the execute never lock to ensure code can + * be executed from RAM. This class uses RAII to allow + * execution from ram while it is in scope. + */ + ScopedRamExecutionLock() + { + mbed_mpu_manager_lock_ram_execution(); + } + + /** + * Restore previous execution from RAM settings + * + * Decrement the execute never lock to return execute from RAM + * to its prior state. + */ + ~ScopedRamExecutionLock() + { + mbed_mpu_manager_unlock_ram_execution(); + } +}; + +/**@}*/ + +} + +#endif diff --git a/platform/ScopedRomWriteLock.h b/platform/ScopedRomWriteLock.h new file mode 100644 index 00000000000..7cd6d5f355a --- /dev/null +++ b/platform/ScopedRomWriteLock.h @@ -0,0 +1,72 @@ +/* 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. + */ +#ifndef MBED_SCOPEDROMWRITELOCK_H +#define MBED_SCOPEDROMWRITELOCK_H + +#include "platform/mbed_mpu_mgmt.h" +#include "platform/NonCopyable.h" + +namespace mbed { + +/** \addtogroup platform */ +/** @{*/ + +/** RAII object for disabling, then restoring ROM write never mode + * Usage: + * @code + * + * void f() { + * // some code here + * { + * ScopedRomWriteLock make_ram_executable; + * // Code in this block is allowed to write to ROM + * } + * // Writing to ROM is no longer allowed + * } + * @endcode + */ +class ScopedRomWriteLock : private mbed::NonCopyable { +public: + + /** + * Allow writing to ROM + * + * Increment the ROM write lock to ensure code can + * write to ROM. This class uses RAII to allow + * writing to ROM while it is in scope. + */ + ScopedRomWriteLock() + { + mbed_mpu_manager_lock_rom_write(); + } + + /** + * Restore previous write to ROM settings + * + * Decrement the ROM write lock to return ROM write + * to its prior state. + */ + ~ScopedRomWriteLock() + { + mbed_mpu_manager_unlock_rom_write(); + } +}; + +/**@}*/ + +} + +#endif diff --git a/platform/mbed_application.c b/platform/mbed_application.c index bd2388dc149..eab55bc1cdc 100644 --- a/platform/mbed_application.c +++ b/platform/mbed_application.c @@ -18,6 +18,7 @@ #include #include "device.h" #include "platform/mbed_application.h" +#include "hal/mpu_api.h" #if MBED_APPLICATION_SUPPORT @@ -67,6 +68,7 @@ void mbed_start_application(uintptr_t address) SysTick->CTRL = 0x00000000; powerdown_nvic(); powerdown_scb(address); + mbed_mpu_free(); sp = *((void **)address + 0); pc = *((void **)address + 1); diff --git a/platform/mbed_mpu_mgmt.c b/platform/mbed_mpu_mgmt.c new file mode 100644 index 00000000000..fa8bc545cc3 --- /dev/null +++ b/platform/mbed_mpu_mgmt.c @@ -0,0 +1,80 @@ +/* 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 "platform/mbed_mpu_mgmt.h" +#include "platform/mbed_critical.h" +#include "platform/mbed_error.h" +#include "hal/mpu_api.h" +#include + +static uint16_t mem_xn_lock; +static uint16_t mem_wn_lock; + +void mbed_mpu_manager_lock_ram_execution() +{ + core_util_critical_section_enter(); + if (mem_xn_lock == USHRT_MAX) { + core_util_critical_section_exit(); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OVERFLOW), "Ram execute never lock overflow (> USHRT_MAX)", mem_xn_lock); + } + if (mem_xn_lock == 0) { + mbed_mpu_enable_ram_xn(false); + } + mem_xn_lock++; + core_util_critical_section_exit(); +} + +void mbed_mpu_manager_unlock_ram_execution() +{ + core_util_critical_section_enter(); + if (mem_xn_lock == 0) { + core_util_critical_section_exit(); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNDERFLOW), "Ram execute never lock underflow (< 0)", mem_xn_lock); + } + mem_xn_lock--; + if (mem_xn_lock == 0) { + mbed_mpu_enable_ram_xn(true); + } + core_util_critical_section_exit(); +} + +void mbed_mpu_manager_lock_rom_write() +{ + core_util_critical_section_enter(); + if (mem_wn_lock == USHRT_MAX) { + core_util_critical_section_exit(); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OVERFLOW), "Rom write never lock overflow (> USHRT_MAX)", mem_wn_lock); + } + if (mem_wn_lock == 0) { + mbed_mpu_enable_rom_wn(false); + } + mem_wn_lock++; + core_util_critical_section_exit(); +} + +void mbed_mpu_manager_unlock_rom_write() +{ + core_util_critical_section_enter(); + if (mem_wn_lock == 0) { + core_util_critical_section_exit(); + MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_UNDERFLOW), "Rom write never lock underflow (< 0)", mem_wn_lock); + } + mem_wn_lock--; + if (mem_wn_lock == 0) { + mbed_mpu_enable_rom_wn(true); + } + core_util_critical_section_exit(); +} diff --git a/platform/mbed_mpu_mgmt.h b/platform/mbed_mpu_mgmt.h new file mode 100644 index 00000000000..7af043f586e --- /dev/null +++ b/platform/mbed_mpu_mgmt.h @@ -0,0 +1,90 @@ +/** \addtogroup platform */ +/** @{*/ +/** + * \defgroup platform_mpu_mgmt MPU management functions + * @{ + */ + +/* mbed Microcontroller Library + * Copyright (c) 2006-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. + */ +#ifndef MBED_MPU_MGMT_H +#define MBED_MPU_MGMT_H + +#include "hal/sleep_api.h" +#include "mbed_toolchain.h" +#include "hal/ticker_api.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Lock ram execute never mode off + * + * This disables the MPU's execute never ram protection and allows + * functions to run from RAM. Execution directly from ram will be + * allowed if this function is invoked at least once (the internal + * counter is non-zero). + * + * Use this locking mechanism for code which needs to execute from + * ram such as flash programming algorithms and ram thunks. + * + * The lock is a counter, can be locked up to USHRT_MAX + * This function is IRQ and thread safe + */ +void mbed_mpu_manager_lock_ram_execution(void); + +/** Unlock ram execute never mode + * + * Use unlocking in pair with mbed_mpu_manager_lock_ram_execution(). + * + * The lock is a counter, should be equally unlocked as locked + * This function is IRQ and thread safe + */ +void mbed_mpu_manager_unlock_ram_execution(void); + +/** Lock rom write never mode off + * + * This disables the MPU's read only ROM protection and allows + * ROM to be written to. Writing to ROM will not result in an MPU + * fault if this function is invoked at least once (the internal + * counter is non-zero). + * + * Use this locking mechanism for code which needs to write to + * ROM such as flash programming algorithms. + * + * The lock is a counter, can be locked up to USHRT_MAX + * This function is IRQ and thread safe + */ +void mbed_mpu_manager_lock_rom_write(void); + +/** Unlock rom write never mode + * + * Use unlocking in pair with mbed_mpu_manager_lock_rom_write(). + * + * The lock is a counter, should be equally unlocked as locked + * This function is IRQ and thread safe + */ +void mbed_mpu_manager_unlock_rom_write(void); + +#ifdef __cplusplus +} +#endif + +#endif + +/** @}*/ +/** @}*/ diff --git a/rtos/TARGET_CORTEX/mbed_boot.c b/rtos/TARGET_CORTEX/mbed_boot.c index 7ae4efb0afa..ccca64aa729 100644 --- a/rtos/TARGET_CORTEX/mbed_boot.c +++ b/rtos/TARGET_CORTEX/mbed_boot.c @@ -76,6 +76,7 @@ #include "mbed_toolchain.h" #include "mbed_boot.h" #include "mbed_error.h" +#include "mpu_api.h" int main(void); static void mbed_cpy_nvic(void); @@ -86,6 +87,9 @@ uint32_t mbed_stack_isr_size = 0; void mbed_init(void) { + mbed_mpu_init(); + mbed_mpu_enable_ram_xn(true); + mbed_mpu_enable_rom_wn(true); mbed_cpy_nvic(); mbed_sdk_init(); mbed_rtos_init(); diff --git a/targets/targets.json b/targets/targets.json index 135a6b48394..4fbd15a60e1 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -29,6 +29,11 @@ "boot-stack-size": { "help": "Define the boot stack size in bytes. This value must be a multiple of 8", "value": "0x1000" + }, + "mpu-rom-end": { + "help": "Last address of ROM protected by the MPU", + "value": "0x0fffffff", + "macro_name": "MPU_ROM_END" } } }, @@ -513,7 +518,8 @@ "SPI", "SPISLAVE", "STDIO_MESSAGES", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "LPC1768", @@ -559,7 +565,8 @@ "SPI", "SPISLAVE", "STDIO_MESSAGES", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "LPC1768", @@ -608,7 +615,8 @@ "SPI", "SPISLAVE", "STDIO_MESSAGES", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "LPC1768", @@ -645,7 +653,8 @@ "SPI", "SPISLAVE", "STDIO_MESSAGES", - "FLASH" + "FLASH", + "MPU" ], "device_name": "LPC1768" }, @@ -765,7 +774,8 @@ "SLEEP", "SPI", "SPISLAVE", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "device_name": "LPC4088FBD144", "overrides": { @@ -801,7 +811,8 @@ "SLEEP", "SPI", "SPISLAVE", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "device_name": "LPC4330" }, @@ -850,7 +861,8 @@ "SLEEP", "SPI", "SPISLAVE", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "release_versions": ["2"], "device_name": "LPC4337" @@ -1434,7 +1446,8 @@ "INTERRUPTIN", "SPI", "I2C", - "ANALOGIN" + "ANALOGIN", + "MPU" ], "device_name": "ADuCM4050", "detect_code": ["0603"], @@ -1464,7 +1477,8 @@ "INTERRUPTIN", "SPI", "I2C", - "ANALOGIN" + "ANALOGIN", + "MPU" ], "device_name": "ADuCM3029", "detect_code": ["0602"], @@ -1776,7 +1790,8 @@ "SERIAL", "SPI", "SPISLAVE", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "release_versions": ["2", "5"], "features": ["LWIP"], @@ -1815,7 +1830,8 @@ "SPI", "SPISLAVE", "STDIO_MESSAGES", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "post_binary_hook": { "function": "LPCTargetCode.lpc_patch" }, @@ -1851,7 +1867,8 @@ "STDIO_MESSAGES", "FLASH", "TRNG", - "QSPI" + "QSPI", + "MPU" ], "device_name": "LPC54628J512ET180", "post_binary_hook": { "function": "LPCTargetCode.lpc_patch" }, @@ -2070,7 +2087,8 @@ "EMAC", "SERIAL_ASYNCH", "SERIAL_FC", - "FLASH" + "FLASH", + "MPU" ], "device_has_remove": ["LPTICKER"], "release_versions": ["2", "5"], @@ -2142,7 +2160,8 @@ "CRC", "SERIAL_ASYNCH", "SERIAL_FC", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "bootloader_supported": true, @@ -2161,7 +2180,7 @@ } }, "detect_code": ["0747"], - "device_has_add": ["ANALOGOUT", "CAN", "CRC", "FLASH"], + "device_has_add": ["ANALOGOUT", "CAN", "CRC", "FLASH", "MPU"], "release_versions": ["2", "5"], "device_name": "STM32F303ZE" }, @@ -2203,7 +2222,7 @@ }, "detect_code": ["0720"], "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], - "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], + "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH", "MPU"], "release_versions": ["2", "5"], "device_name": "STM32F401RE" }, @@ -2219,7 +2238,7 @@ } }, "macros_add": ["USB_STM_HAL", "USBHOST_OTHER", "HSE_VALUE=25000000"], - "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], + "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH", "MPU"], "overrides": { "lse_available": 0 }, "release_versions": ["2", "5"], "device_name": "STM32F401VE" @@ -2251,7 +2270,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F410RB" @@ -2275,7 +2295,7 @@ } }, "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], - "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], + "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH", "MPU"], "release_versions": ["2", "5"], "device_name": "STM32F411RE", "bootloader_supported": true @@ -2299,7 +2319,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F412ZG", @@ -2321,7 +2342,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["5"], "device_name": "STM32F412ZG", @@ -2351,7 +2373,13 @@ ], "features": ["BLE", "STORAGE"], "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], - "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"], + "device_has_add": [ + "SERIAL_ASYNCH", + "SERIAL_FC", + "TRNG", + "FLASH", + "MPU" + ], "release_versions": ["5"], "device_name": "STM32F412ZG", "bootloader_supported": true, @@ -2416,7 +2444,8 @@ "SERIAL_FC", "TRNG", "FLASH", - "QSPI" + "QSPI", + "MPU" ], "bootloader_supported": true, "release_versions": ["2", "5"], @@ -2451,7 +2480,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "bootloader_supported": true, "release_versions": ["2", "5"], @@ -2465,7 +2495,7 @@ "extra_labels_add": ["STM32F4", "STM32F411xE", "STM32F411RE"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM"], "detect_code": ["----"], - "device_has_add": [], + "device_has_add": ["MPU"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32F411RE" @@ -2507,7 +2537,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "detect_code": ["0796"], "release_versions": ["2", "5"], @@ -2557,7 +2588,8 @@ "EMAC", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "detect_code": ["0797"], "release_versions": ["2", "5"], @@ -2586,7 +2618,8 @@ "CAN", "SERIAL_ASYNCH", "SERIAL_FC", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F446RE", @@ -2611,7 +2644,8 @@ "CAN", "SERIAL_ASYNCH", "SERIAL_FC", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F446ZE" @@ -2627,7 +2661,8 @@ "CAN", "SERIAL_ASYNCH", "SERIAL_FC", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F446VE" @@ -2668,7 +2703,8 @@ "EMAC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F746ZG", @@ -2717,7 +2753,8 @@ "EMAC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F756ZG", @@ -2765,7 +2802,8 @@ "EMAC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F767ZI", @@ -2846,7 +2884,8 @@ "CRC", "SERIAL_FC", "SERIAL_ASYNCH", - "FLASH" + "FLASH", + "MPU" ], "default_lib": "small", "release_versions": ["2"], @@ -2876,7 +2915,8 @@ "SERIAL_FC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L073RZ" @@ -2894,7 +2934,13 @@ } }, "detect_code": ["0710"], - "device_has_add": ["ANALOGOUT", "SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], + "device_has_add": [ + "ANALOGOUT", + "SERIAL_ASYNCH", + "SERIAL_FC", + "FLASH", + "MPU" + ], "release_versions": ["2", "5"], "device_name": "STM32L152RE" }, @@ -2922,7 +2968,8 @@ "SERIAL_ASYNCH", "CAN", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L432KC", @@ -2952,7 +2999,8 @@ "SERIAL_ASYNCH", "CAN", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L433RC", @@ -2978,7 +3026,8 @@ "SERIAL_ASYNCH", "CAN", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "device_has_remove": ["LPTICKER"], "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"], @@ -3011,7 +3060,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L476RG", @@ -3038,7 +3088,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["5"], "device_name": "STM32L476JG" @@ -3072,7 +3123,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L486RG" @@ -3107,7 +3159,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "device_has_remove": ["LPTICKER"], "release_versions": ["5"], @@ -3127,7 +3180,7 @@ "STM32F407xG", "STM32F407VG" ], - "device_has_add": ["ANALOGOUT", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "TRNG", "FLASH", "MPU"], "release_versions": ["2"], "device_name": "STM32F407VG" }, @@ -3174,7 +3227,8 @@ "LOWPOWERTIMER", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "detect_code": ["9014"], "release_versions": ["2", "5"], @@ -3200,7 +3254,7 @@ "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"" ], - "device_has_add": ["CRC", "SERIAL_FC"], + "device_has_add": ["CRC", "SERIAL_FC", "MPU"], "device_has_remove": ["LPTICKER"], "device_name": "STM32F051R8" }, @@ -3232,7 +3286,7 @@ }, "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], "release_versions": ["2", "5"], - "device_has_add": ["ANALOGOUT", "CAN", "CRC", "SERIAL_FC"], + "device_has_add": ["ANALOGOUT", "CAN", "CRC", "SERIAL_FC", "MPU"], "device_name": "STM32F303VC" }, "DISCO_F334C8": { @@ -3272,7 +3326,7 @@ }, "macros_add": ["USB_STM_HAL"], "overrides": { "lse_available": 0 }, - "device_has_add": ["ANALOGOUT", "TRNG", "FLASH"], + "device_has_add": ["ANALOGOUT", "TRNG", "FLASH", "MPU"], "release_versions": ["2", "5"], "device_name": "STM32F407VG" }, @@ -3306,7 +3360,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F429ZI", @@ -3339,7 +3394,8 @@ "SERIAL_FC", "TRNG", "FLASH", - "QSPI" + "QSPI", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F469NI" @@ -3363,7 +3419,7 @@ "lse_available": 0, "lpticker_delay_ticks": 4 }, - "device_has_add": ["ANALOGOUT", "CRC", "SERIAL_FC", "FLASH"], + "device_has_add": ["ANALOGOUT", "CRC", "SERIAL_FC", "FLASH", "MPU"], "default_lib": "small", "release_versions": ["2"], "device_name": "STM32L053C8" @@ -3396,7 +3452,8 @@ "SERIAL_FC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L072CZ" @@ -3416,7 +3473,8 @@ "SERIAL_FC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "device_has_remove": ["LPTICKER"], "release_versions": ["5"], @@ -3457,7 +3515,8 @@ "SERIAL_ASYNCH", "TRNG", "FLASH", - "QSPI" + "QSPI", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32F746NG", @@ -3500,7 +3559,8 @@ "EMAC", "SERIAL_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "bootloader_supported": true, "release_versions": ["2", "5"], @@ -3534,7 +3594,8 @@ "SERIAL_FC", "TRNG", "FLASH", - "QSPI" + "QSPI", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L475VG", @@ -3564,7 +3625,8 @@ "SERIAL_FC", "TRNG", "FLASH", - "QSPI" + "QSPI", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L476VG", @@ -3576,7 +3638,7 @@ "extra_labels_add": ["STM32F4", "STM32F405RG"], "is_disk_virtual": true, "macros_add": ["HSE_VALUE=26000000"], - "device_has_add": ["ANALOGOUT"], + "device_has_add": ["ANALOGOUT", "MPU"], "release_versions": ["2"], "device_name": "STM32F405RG" }, @@ -3593,7 +3655,7 @@ "function": "MTSCode.combine_bins_mts_dot", "toolchains": ["GCC_ARM", "ARM_STD", "ARM_MICRO", "IAR"] }, - "device_has_add": [], + "device_has_add": ["MPU"], "release_versions": ["2", "5"], "device_name": "STM32F411RE" }, @@ -3619,7 +3681,7 @@ "function": "MTSCode.combine_bins_mts_dragonfly", "toolchains": ["GCC_ARM", "ARM_STD", "ARM_MICRO", "IAR"] }, - "device_has_add": [], + "device_has_add": ["MPU"], "release_versions": ["2", "5"], "device_name": "STM32F411RE" }, @@ -3658,7 +3720,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L471QG", @@ -3668,6 +3731,7 @@ "inherits": ["FAMILY_STM32"], "core": "Cortex-M4F", "extra_labels_add": ["STM32F4", "STM32F411RE"], + "device_has_add": ["MPU"], "config": { "modem_is_on_board": { "help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.", @@ -3704,7 +3768,7 @@ } }, "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "device_has_add": ["ANALOGOUT", "FLASH"], + "device_has_add": ["ANALOGOUT", "FLASH", "MPU"], "release_versions": ["5"], "device_name": "STM32L151CC", "bootloader_supported": true @@ -3730,7 +3794,7 @@ "stdio_uart_rx": "PA_3" }, "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "device_has_add": ["ANALOGOUT", "FLASH"], + "device_has_add": ["ANALOGOUT", "FLASH", "MPU"], "release_versions": ["5"], "device_name": "STM32L151CC", "bootloader_supported": true @@ -3741,7 +3805,7 @@ "default_toolchain": "ARM", "extra_labels_add": ["STM32L1", "STM32L151xBA", "STM32L151CBA"], "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "device_has_add": ["ANALOGOUT"], + "device_has_add": ["ANALOGOUT", "MPU"], "release_versions": ["5"], "device_name": "STM32L151CBxxA", "bootloader_supported": true @@ -3754,7 +3818,7 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels_add": ["STM32L1", "STM32L152RC"], "detect_code": ["4100"], - "device_has_add": ["ANALOGOUT", "SERIAL_ASYNCH", "FLASH"], + "device_has_add": ["ANALOGOUT", "SERIAL_ASYNCH", "FLASH", "MPU"], "release_versions": ["2", "5"], "device_name": "STM32L152RC" }, @@ -3769,7 +3833,7 @@ "STM32F401VC" ], "supported_toolchains": ["GCC_ARM"], - "device_has_add": [], + "device_has_add": ["MPU"], "device_name": "STM32F401VC" }, "MODULE_UBLOX_ODIN_W2": { @@ -3808,7 +3872,8 @@ "FLASH", "WIFI", "SERIAL_FC", - "SERIAL" + "SERIAL", + "MPU" ], "features": ["BLE"], "device_has_remove": [], @@ -3896,7 +3961,14 @@ "GNSSBAUD=9600" ], "overrides": { "lse_available": 0 }, - "device_has_add": ["ANALOGOUT", "EMAC", "SERIAL_FC", "TRNG", "FLASH"], + "device_has_add": [ + "ANALOGOUT", + "EMAC", + "SERIAL_FC", + "TRNG", + "FLASH", + "MPU" + ], "public": false, "device_name": "STM32F437VG", "bootloader_supported": true, @@ -3924,7 +3996,7 @@ "extra_labels_add": ["STM32L1", "STM32L151RC"], "overrides": { "lse_available": 0 }, "supported_toolchains": ["ARM", "uARM", "GCC_ARM"], - "device_has_add": ["ANALOGOUT"], + "device_has_add": ["ANALOGOUT", "MPU"], "default_lib": "small", "device_name": "STM32L151RC" }, @@ -4516,7 +4588,8 @@ "SERIAL_FC", "SPI", "SPISLAVE", - "TSC" + "TSC", + "MPU" ], "release_versions": ["2"] }, @@ -4540,7 +4613,8 @@ "SERIAL_FC", "SPI", "SPISLAVE", - "TSC" + "TSC", + "MPU" ], "release_versions": ["2"] }, @@ -4564,7 +4638,8 @@ "SERIAL_FC", "SPI", "SPISLAVE", - "TSC" + "TSC", + "MPU" ], "release_versions": ["2"] }, @@ -4588,7 +4663,8 @@ "SERIAL_FC", "SPI", "SPISLAVE", - "TSC" + "TSC", + "MPU" ], "release_versions": ["2"] }, @@ -4609,7 +4685,8 @@ "SERIAL_FC", "SPI", "SPISLAVE", - "TSC" + "TSC", + "MPU" ] }, "ARM_IOTSS_BEID": { @@ -4632,7 +4709,8 @@ "SERIAL_FC", "SPI", "SPISLAVE", - "TSC" + "TSC", + "MPU" ], "release_versions": ["2"] }, @@ -4659,7 +4737,8 @@ "SLEEP", "SPI", "TRNG", - "USTICKER" + "USTICKER", + "MPU" ], "release_versions": ["2", "5"], "copy_method": "mps2", @@ -4699,7 +4778,8 @@ "PORTOUT", "SERIAL", "SLEEP", - "SPI" + "SPI", + "MPU" ], "features": ["BLE"], "release_versions": ["2", "5"] @@ -4963,7 +5043,8 @@ "SERIAL_FC", "SPI", "STDIO_MESSAGES", - "USTICKER" + "USTICKER", + "MPU" ], "features": ["BLE"], "release_versions": ["2", "5"] @@ -5014,7 +5095,8 @@ "STDIO_MESSAGES", "USTICKER", "FLASH", - "ITM" + "ITM", + "MPU" ], "forced_reset_timeout": 2, "config": { @@ -5089,7 +5171,8 @@ "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 2, "device_name": "EFM32LG990F256", @@ -5166,7 +5249,8 @@ "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 2, "config": { @@ -5387,7 +5471,8 @@ "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 2, "config": { @@ -5485,7 +5570,8 @@ "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 2, "config": { @@ -5554,7 +5640,8 @@ "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 5, "config": { @@ -5631,7 +5718,8 @@ "STDIO_MESSAGES", "USTICKER", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 2, "config": { @@ -5718,7 +5806,8 @@ "STDIO_MESSAGES", "USTICKER", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 5, "config": { @@ -5798,7 +5887,8 @@ "STDIO_MESSAGES", "USTICKER", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "forced_reset_timeout": 5, "config": { @@ -6085,7 +6175,8 @@ "SLEEP", "SPI", "SPISLAVE", - "SPI_ASYNCH" + "SPI_ASYNCH", + "MPU" ], "default_lib": "std", "device_name": "ATSAMG55J19" @@ -6291,6 +6382,7 @@ "INTERRUPTIN", "ITM", "LPTICKER", + "MPU", "PORTIN", "PORTINOUT", "PORTOUT", @@ -6402,6 +6494,7 @@ "INTERRUPTIN", "ITM", "LPTICKER", + "MPU", "PORTIN", "PORTINOUT", "PORTOUT", @@ -6530,7 +6623,8 @@ "TRNG", "CAN", "FLASH", - "EMAC" + "EMAC", + "MPU" ], "release_versions": ["5"], "device_name": "NUC472HI8AE", @@ -6595,7 +6689,8 @@ "SPI", "TRNG", "SPISLAVE", - "802_15_4_PHY" + "802_15_4_PHY", + "MPU" ], "release_versions": ["2", "5"] }, @@ -6653,7 +6748,8 @@ "SPISLAVE", "SPI_ASYNCH", "CAN", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "M453VG6AE", @@ -6768,7 +6864,8 @@ "CONFIG_PLATFORM_8195A", "CONFIG_MBED_ENABLED", "PLATFORM_CMSIS_RTOS", - "MBED_FAULT_HANDLER_DISABLED" + "MBED_FAULT_HANDLER_DISABLED", + "MBED_MPU_CUSTOM" ], "inherits": ["Target"], "extra_labels": ["Realtek", "AMEBA", "RTW_EMAC"], @@ -6878,7 +6975,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L496AG", @@ -6908,7 +7006,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L496ZG", @@ -6942,7 +7041,8 @@ "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "release_versions": ["2", "5"], "device_name": "STM32L4R5ZI", @@ -7013,7 +7113,8 @@ "TRNG", "FLASH", "CAN", - "EMAC" + "EMAC", + "MPU" ], "release_versions": ["5"], "bootloader_supported": true, @@ -7078,7 +7179,8 @@ "SPI", "SPISLAVE", "SPI_ASYNCH", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "config": { "clock_source": { @@ -7163,22 +7265,26 @@ "FVP_MPS2_M0P": { "inherits": ["FVP_MPS2"], "core": "Cortex-M0+", - "macros_add": ["CMSDK_CM0plus"] + "macros_add": ["CMSDK_CM0plus"], + "device_has_add": ["MPU"] }, "FVP_MPS2_M3": { "inherits": ["FVP_MPS2"], "core": "Cortex-M3", - "macros_add": ["CMSDK_CM3"] + "macros_add": ["CMSDK_CM3"], + "device_has_add": ["MPU"] }, "FVP_MPS2_M4": { "inherits": ["FVP_MPS2"], "core": "Cortex-M4", - "macros_add": ["CMSDK_CM4"] + "macros_add": ["CMSDK_CM4"], + "device_has_add": ["MPU"] }, "FVP_MPS2_M7": { "inherits": ["FVP_MPS2"], "core": "Cortex-M7", - "macros_add": ["CMSDK_CM7"] + "macros_add": ["CMSDK_CM7"], + "device_has_add": ["MPU"] }, "NUMAKER_PFM_M2351": { "core": "Cortex-M23-NS", @@ -7238,7 +7344,8 @@ "SPISLAVE", "SPI_ASYNCH", "TRNG", - "FLASH" + "FLASH", + "MPU" ], "detect_code": ["1305"], "release_versions": ["5"], @@ -7266,7 +7373,8 @@ "SPI", "I2C", "I2CSLAVE", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "device_name": "TMPM3H6FWFG", "detect_code": ["7012"], @@ -7294,7 +7402,8 @@ "STDIO_MESSAGES", "FLASH", "SLEEP", - "USTICKER" + "USTICKER", + "MPU" ], "device_name": "TMPM4G9F15FG", "detect_code": ["7015"], @@ -7327,8 +7436,12 @@ "STDIO_MESSAGES", "LPTICKER", "SLEEP", - "FLASH" + "FLASH", + "MPU" ], + "overrides": { + "mpu-rom-end": "0x1fffffff" + }, "release_versions": ["5"], "extra_labels": ["Cypress", "PSOC6"], "public": false @@ -7421,7 +7534,8 @@ "SPI", "I2C", "I2CSLAVE", - "STDIO_MESSAGES" + "STDIO_MESSAGES", + "MPU" ], "device_name": "TMPM3HQFDFG", "detect_code": ["7014"], @@ -7434,7 +7548,7 @@ "extra_labels": ["RDA", "UNO_91H", "FLASH_CMSIS_ALGO"], "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "macros": ["TWO_RAM_REGIONS", "CMSIS_NVIC_VIRTUAL", "CMSIS_NVIC_VIRTUAL_HEADER_FILE=\"RDA5981_nvic_virtual.h\""], - "device_has": ["USTICKER", "PORTIN", "PORTOUT", "PORTINOUT", "INTERRUPTIN", "SERIAL", "STDIO_MESSAGES", "PWMOUT", "SPI", "SLEEP", "ANALOGIN", "FLASH", "TRNG"], + "device_has": ["USTICKER", "PORTIN", "PORTOUT", "PORTINOUT", "INTERRUPTIN", "SERIAL", "STDIO_MESSAGES", "PWMOUT", "SPI", "SLEEP", "ANALOGIN", "FLASH", "TRNG", "MPU"], "release_versions": ["2", "5"] }, "UNO_91H": {