Integrate MPU with mbed

Enable the MPU as part of the boot sequence and disable it before
starting a new application. Also add reference counted MPU lock and
unlock functions to allow code to execute from ram when necessary.
pull/8871/head
Russ Butler 2018-10-05 20:25:50 -05:00 committed by Martin Kojtal
parent 8e2fd1a5cc
commit ecd0414494
4 changed files with 122 additions and 0 deletions

View File

@ -18,6 +18,7 @@
#include <stdarg.h>
#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);

51
platform/mbed_mpu_mgmt.c Normal file
View File

@ -0,0 +1,51 @@
/* 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 <limits.h>
static uint16_t mem_xn_lock;
void mbed_mpu_manager_lock_mem_xn()
{
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), "Memory 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_mem_xn()
{
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), "Memory 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();
}

66
platform/mbed_mpu_mgmt.h Normal file
View File

@ -0,0 +1,66 @@
/** \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 <stdbool.h>
#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_mem_xn(void);
/** Unlock ram execute never mode
*
* Use unlocking in pair with mbed_mpu_manager_lock_mem_xn().
*
* The lock is a counter, should be equally unlocked as locked
* This function is IRQ and thread safe
*/
void mbed_mpu_manager_unlock_mem_xn(void);
#ifdef __cplusplus
}
#endif
#endif
/** @}*/
/** @}*/

View File

@ -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,8 @@ uint32_t mbed_stack_isr_size = 0;
void mbed_init(void)
{
mbed_mpu_init();
mbed_mpu_enable_ram_xn(true);
mbed_cpy_nvic();
mbed_sdk_init();
mbed_rtos_init();