Skip to content

Support secure/non-secure flash IAP for Cortex-M23/M33 #6630

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 6 commits into from
Apr 19, 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
114 changes: 104 additions & 10 deletions hal/TARGET_FLASH_CMSIS_ALGO/flash_common_algo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

/* 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

int32_t flash_init(flash_t *obj)
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a common static function/macro to check range of non-secure flash, which can be called ftom all API's?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deepikabhavnani I refactored the code in 00147b5.

if (flash_check_nonsecure(obj, address, address)) {
return -1;
}
}
#endif

core_util_critical_section_enter();
flash_algo_init(obj, address, MBED_FLASH_ALGO_ERASE);

Expand All @@ -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);

Expand All @@ -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) {
Expand All @@ -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
11 changes: 10 additions & 1 deletion hal/TARGET_FLASH_CMSIS_ALGO/flash_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down
21 changes: 21 additions & 0 deletions platform/mbed_toolchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

/** @}*/
Expand Down