Merge pull request #6630 from OpenNuvoton/nuvoton_add_nonsecure_flash

Support secure/non-secure flash IAP for Cortex-M23/M33
pull/6686/head
Martin Kojtal 2018-04-19 17:24:27 +02:00 committed by GitHub
commit c6b6bab2f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 135 additions and 11 deletions

View File

@ -17,6 +17,13 @@
#include "flash_api.h"
#include "flash_data.h"
#include "mbed_critical.h"
#include "mbed_toolchain.h"
#ifndef __DOMAIN_NS
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
#include <arm_cmse.h>
#endif
#define MBED_FLASH_ALGO_ERASE 1UL
#define MBED_FLASH_ALGO_PROGRAM 2UL
@ -82,20 +89,62 @@ static int32_t flash_algo_uninit(flash_t *obj, uint32_t address, uint32_t functi
return ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments);
}
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/* Check if address range [start_addr, end_addr] is in non-secure flash
*
* @param obj The flash object
* @param start_addr Start address to check
* @param end_addr End address to check. Could be the same as start_addr to just check start_addr
* for e.g. flash_erase_sector.
* @return 0 for success, -1 for error
*/
static int32_t flash_check_nonsecure(flash_t *obj, uint32_t start_addr, uint32_t end_addr)
{
/* Check if end address wraps around */
if (end_addr < start_addr) {
return -1;
}
int32_t flash_init(flash_t *obj)
/* Check if start address is in non-secure flash */
if ((start_addr < obj->target_config_ns->flash_start) ||
(start_addr >= (obj->target_config_ns->flash_start + obj->target_config_ns->flash_size))) {
return -1;
}
/* Check if end address is in non-secure flash */
if (end_addr != start_addr) {
if ((end_addr < obj->target_config_ns->flash_start) ||
(end_addr >= (obj->target_config_ns->flash_start + obj->target_config_ns->flash_size))) {
return -1;
}
}
return 0;
}
#endif
MBED_NONSECURE_ENTRY int32_t flash_init(flash_t *obj)
{
flash_set_target_config(obj);
return 0;
}
int32_t flash_free(flash_t *obj)
MBED_NONSECURE_ENTRY int32_t flash_free(flash_t *obj)
{
return 0;
}
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
MBED_NONSECURE_ENTRY int32_t flash_erase_sector(flash_t *obj, uint32_t address)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (cmse_nonsecure_caller()) {
// Confine non-secure access to non-secure flash
if (flash_check_nonsecure(obj, address, address)) {
return -1;
}
}
#endif
core_util_critical_section_enter();
flash_algo_init(obj, address, MBED_FLASH_ALGO_ERASE);
@ -114,9 +163,17 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
return ret ? -1 : 0;
}
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
MBED_NONSECURE_ENTRY int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (cmse_nonsecure_caller()) {
// Confine non-secure access to non-secure flash
if (flash_check_nonsecure(obj, address, address + size - 1)) {
return -1;
}
}
#endif
core_util_critical_section_enter();
flash_algo_init(obj, address, MBED_FLASH_ALGO_PROGRAM);
@ -135,9 +192,26 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
return ret ? -1 : 0;
}
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
MBED_NONSECURE_ENTRY uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (cmse_nonsecure_caller()) {
const sector_info_t *sectors = obj->target_config_ns->sectors;
if (address >= obj->target_config_ns->flash_start + obj->target_config_ns->flash_size) {
return MBED_FLASH_INVALID_SIZE;
}
int sector_index = obj->target_config_ns->sector_info_count - 1;
for (; sector_index >= 0; sector_index--) {
if (address >= sectors[sector_index].start) {
return sectors[sector_index].size;
}
}
return MBED_FLASH_INVALID_SIZE;
}
#endif
const sector_info_t *sectors = obj->target_config->sectors;
if (address >= obj->target_config->flash_start + obj->target_config->flash_size) {
@ -153,17 +227,37 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
return MBED_FLASH_INVALID_SIZE;
}
uint32_t flash_get_page_size(const flash_t *obj)
MBED_NONSECURE_ENTRY uint32_t flash_get_page_size(const flash_t *obj)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (cmse_nonsecure_caller()) {
return obj->target_config_ns->page_size;
}
#endif
return obj->target_config->page_size;
}
uint32_t flash_get_start_address(const flash_t *obj)
MBED_NONSECURE_ENTRY uint32_t flash_get_start_address(const flash_t *obj)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (cmse_nonsecure_caller()) {
return obj->target_config_ns->flash_start;
}
#endif
return obj->target_config->flash_start;
}
uint32_t flash_get_size(const flash_t *obj)
MBED_NONSECURE_ENTRY uint32_t flash_get_size(const flash_t *obj)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
if (cmse_nonsecure_caller()) {
return obj->target_config_ns->flash_size;
}
#endif
return obj->target_config->flash_size;
}
#endif // #ifndef __DOMAIN_NS

View File

@ -47,9 +47,18 @@ typedef struct {
} flash_target_config_t;
/** Target flash configuration
* For targets not supporting TrustZone, its flash_set_target_config must define target_config.
* For targets supporting TrustZone, it has the following requirements:
* -# Flash IAP H/W can only configure to secure. It can access both secure/non-secure flash.
* -# Flash IAP port is for secure build only. It exports secure functions for non-secure build.
* -# In Flash IAP port, flash_set_target_config must define both target_config/target_config_ns for secure/non-secure flash respectively.
* -# Non-secure application can access its non-secure flash only through secure flash IAP functions. It cannot access secure flash.
*/
struct flash_s {
const flash_target_config_t *target_config;
const flash_target_config_t *target_config; /**< Normal/secure flash configuration structure for targets not supporting/supporting TrustZone */
#if defined(__CORTEX_M23) || defined(__CORTEX_M33)
const flash_target_config_t *target_config_ns; /**< Non-secure flash configuration structure for targets supporting TrustZone */
#endif
const flash_algo_t *flash_algo;
};

View File

@ -412,6 +412,27 @@
#define EXTERN extern
#endif
/** MBED_NONSECURE_ENTRY
* Declare a function that can be called from non-secure world or secure world
*
* @code
* #include "mbed_toolchain.h"
*
* MBED_NONSECURE_ENTRY void foo() {
*
* }
* @endcode
*/
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
#if defined (__ICCARM__)
#define MBED_NONSECURE_ENTRY __cmse_nonsecure_entry
#else
#define MBED_NONSECURE_ENTRY __attribute__((cmse_nonsecure_entry))
#endif
#else
#define MBED_NONSECURE_ENTRY
#endif
#endif
/** @}*/