Skip to content

Reduce ROM impact of MPU code #9030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions TESTS/mbed_hal/mpu/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,9 @@ static void hard_fault_handler_test()

static void mpu_fault_test(const volatile uint16_t *mem_function)
{
mbed_mpu_init();

// Verify that the mpu causes faults when executing ram
// Verify that the mpu causes faults when executing ram after init
fault_count = 0;
mbed_mpu_enable_ram_xn(true);
mbed_mpu_init();
call_mem(mem_function);
TEST_ASSERT_EQUAL(1, fault_count);

Expand All @@ -86,7 +84,7 @@ static void mpu_fault_test(const volatile uint16_t *mem_function)
call_mem(mem_function);
TEST_ASSERT_EQUAL(0, fault_count);

// Verify that the mpu causes faults when executing ram
// Verify that the mpu can be turned back on
fault_count = 0;
mbed_mpu_enable_ram_xn(true);
call_mem(mem_function);
Expand Down
12 changes: 8 additions & 4 deletions hal/mpu/mbed_mpu_v8m.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ void mbed_mpu_init()
(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 << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
(1 << MPU_RLAR_EN_Pos); // Region enabled

region = 1;
MPU->RNR = region;
Expand All @@ -90,7 +91,8 @@ void mbed_mpu_init()
(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 << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
(1 << MPU_RLAR_EN_Pos); // Region enabled

region = 2;
MPU->RNR = region;
Expand All @@ -102,7 +104,8 @@ void mbed_mpu_init()
(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 << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
(1 << MPU_RLAR_EN_Pos); // Region enabled

region = 3;
MPU->RNR = region;
Expand All @@ -114,7 +117,8 @@ void mbed_mpu_init()
(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
(region << MPU_RLAR_AttrIndx_Pos) | // Attribute index - configured to be the same as the region number
(1 << MPU_RLAR_EN_Pos); // Region enabled

// Enable the MPU
MPU->CTRL =
Expand Down
12 changes: 8 additions & 4 deletions hal/mpu_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ extern "C" {
* Initialize the MPU
*
* Initialize or re-initialize the memory protection unit.
* It is implementation defined what region are protected
* by the MPU after initialization.
* After initialization or re-initialization, ROM and RAM protection
* are both enabled.
*/
void mbed_mpu_init(void);

Expand All @@ -75,7 +75,9 @@ void mbed_mpu_init(void);
* 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
* By default writes to ROM are disabled.
*
* @param enable true to disable writes to ROM, false otherwise
*/
void mbed_mpu_enable_rom_wn(bool enable);

Expand All @@ -85,7 +87,9 @@ void mbed_mpu_enable_rom_wn(bool enable);
* 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
* By default execution from RAM is disabled.
*
* @param enable true to disable execution from RAM, false otherwise
*/
void mbed_mpu_enable_ram_xn(bool enable);

Expand Down
25 changes: 9 additions & 16 deletions platform/mbed_mpu_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
#include "platform/mbed_mpu_mgmt.h"
#include "platform/mbed_critical.h"
#include "platform/mbed_error.h"
#include "platform/mbed_assert.h"
#include "hal/mpu_api.h"
#include <limits.h>

#if DEVICE_MPU

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);
}
MBED_ASSERT(mem_xn_lock != USHRT_MAX);
if (mem_xn_lock == 0) {
mbed_mpu_enable_ram_xn(false);
}
Expand All @@ -40,10 +40,7 @@ void mbed_mpu_manager_lock_ram_execution()
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);
}
MBED_ASSERT(mem_xn_lock != 0);
mem_xn_lock--;
if (mem_xn_lock == 0) {
mbed_mpu_enable_ram_xn(true);
Expand All @@ -54,10 +51,7 @@ void mbed_mpu_manager_unlock_ram_execution()
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);
}
MBED_ASSERT(mem_wn_lock != USHRT_MAX);
if (mem_wn_lock == 0) {
mbed_mpu_enable_rom_wn(false);
}
Expand All @@ -68,13 +62,12 @@ void mbed_mpu_manager_lock_rom_write()
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);
}
MBED_ASSERT(mem_wn_lock != 0);
mem_wn_lock--;
if (mem_wn_lock == 0) {
mbed_mpu_enable_rom_wn(true);
}
core_util_critical_section_exit();
}

#endif
14 changes: 14 additions & 0 deletions platform/mbed_mpu_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
extern "C" {
#endif

#if DEVICE_MPU

/** Lock ram execute never mode off
*
* This disables the MPU's execute never ram protection and allows
Expand Down Expand Up @@ -80,6 +82,18 @@ void mbed_mpu_manager_lock_rom_write(void);
*/
void mbed_mpu_manager_unlock_rom_write(void);

#else

#define mbed_mpu_manager_lock_ram_execution() (void)0

#define mbed_mpu_manager_unlock_ram_execution() (void)0

#define mbed_mpu_manager_lock_rom_write() (void)0

#define mbed_mpu_manager_unlock_rom_write() (void)0

#endif

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 0 additions & 2 deletions rtos/TARGET_CORTEX/mbed_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ 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();
Expand Down