Skip to content

Commit c6b6bab

Browse files
authored
Merge pull request #6630 from OpenNuvoton/nuvoton_add_nonsecure_flash
Support secure/non-secure flash IAP for Cortex-M23/M33
2 parents 7f98f5b + 076a160 commit c6b6bab

File tree

3 files changed

+135
-11
lines changed

3 files changed

+135
-11
lines changed

hal/TARGET_FLASH_CMSIS_ALGO/flash_common_algo.c

Lines changed: 104 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
#include "flash_api.h"
1818
#include "flash_data.h"
1919
#include "mbed_critical.h"
20+
#include "mbed_toolchain.h"
21+
22+
#ifndef __DOMAIN_NS
23+
24+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
25+
#include <arm_cmse.h>
26+
#endif
2027

2128
#define MBED_FLASH_ALGO_ERASE 1UL
2229
#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
8289
return ((flash_algo_jump_t)(((uint32_t)&jump_to_flash_algo) | 1))(&arguments);
8390
}
8491

92+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
93+
/* Check if address range [start_addr, end_addr] is in non-secure flash
94+
*
95+
* @param obj The flash object
96+
* @param start_addr Start address to check
97+
* @param end_addr End address to check. Could be the same as start_addr to just check start_addr
98+
* for e.g. flash_erase_sector.
99+
* @return 0 for success, -1 for error
100+
*/
101+
static int32_t flash_check_nonsecure(flash_t *obj, uint32_t start_addr, uint32_t end_addr)
102+
{
103+
/* Check if end address wraps around */
104+
if (end_addr < start_addr) {
105+
return -1;
106+
}
107+
108+
/* Check if start address is in non-secure flash */
109+
if ((start_addr < obj->target_config_ns->flash_start) ||
110+
(start_addr >= (obj->target_config_ns->flash_start + obj->target_config_ns->flash_size))) {
111+
return -1;
112+
}
113+
114+
/* Check if end address is in non-secure flash */
115+
if (end_addr != start_addr) {
116+
if ((end_addr < obj->target_config_ns->flash_start) ||
117+
(end_addr >= (obj->target_config_ns->flash_start + obj->target_config_ns->flash_size))) {
118+
return -1;
119+
}
120+
}
121+
122+
return 0;
123+
}
124+
#endif
85125

86-
int32_t flash_init(flash_t *obj)
126+
MBED_NONSECURE_ENTRY int32_t flash_init(flash_t *obj)
87127
{
88128
flash_set_target_config(obj);
89129
return 0;
90130
}
91131

92-
int32_t flash_free(flash_t *obj)
132+
MBED_NONSECURE_ENTRY int32_t flash_free(flash_t *obj)
93133
{
94134
return 0;
95135
}
96136

97-
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
137+
MBED_NONSECURE_ENTRY int32_t flash_erase_sector(flash_t *obj, uint32_t address)
98138
{
139+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
140+
if (cmse_nonsecure_caller()) {
141+
// Confine non-secure access to non-secure flash
142+
if (flash_check_nonsecure(obj, address, address)) {
143+
return -1;
144+
}
145+
}
146+
#endif
147+
99148
core_util_critical_section_enter();
100149
flash_algo_init(obj, address, MBED_FLASH_ALGO_ERASE);
101150

@@ -114,9 +163,17 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
114163
return ret ? -1 : 0;
115164
}
116165

117-
118-
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
166+
MBED_NONSECURE_ENTRY int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
119167
{
168+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
169+
if (cmse_nonsecure_caller()) {
170+
// Confine non-secure access to non-secure flash
171+
if (flash_check_nonsecure(obj, address, address + size - 1)) {
172+
return -1;
173+
}
174+
}
175+
#endif
176+
120177
core_util_critical_section_enter();
121178
flash_algo_init(obj, address, MBED_FLASH_ALGO_PROGRAM);
122179

@@ -135,9 +192,26 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data,
135192
return ret ? -1 : 0;
136193
}
137194

138-
139-
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
195+
MBED_NONSECURE_ENTRY uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
140196
{
197+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
198+
if (cmse_nonsecure_caller()) {
199+
const sector_info_t *sectors = obj->target_config_ns->sectors;
200+
201+
if (address >= obj->target_config_ns->flash_start + obj->target_config_ns->flash_size) {
202+
return MBED_FLASH_INVALID_SIZE;
203+
}
204+
205+
int sector_index = obj->target_config_ns->sector_info_count - 1;
206+
for (; sector_index >= 0; sector_index--) {
207+
if (address >= sectors[sector_index].start) {
208+
return sectors[sector_index].size;
209+
}
210+
}
211+
return MBED_FLASH_INVALID_SIZE;
212+
}
213+
#endif
214+
141215
const sector_info_t *sectors = obj->target_config->sectors;
142216

143217
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)
153227
return MBED_FLASH_INVALID_SIZE;
154228
}
155229

156-
uint32_t flash_get_page_size(const flash_t *obj)
230+
MBED_NONSECURE_ENTRY uint32_t flash_get_page_size(const flash_t *obj)
157231
{
232+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
233+
if (cmse_nonsecure_caller()) {
234+
return obj->target_config_ns->page_size;
235+
}
236+
#endif
237+
158238
return obj->target_config->page_size;
159239
}
160240

161-
uint32_t flash_get_start_address(const flash_t *obj)
241+
MBED_NONSECURE_ENTRY uint32_t flash_get_start_address(const flash_t *obj)
162242
{
243+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
244+
if (cmse_nonsecure_caller()) {
245+
return obj->target_config_ns->flash_start;
246+
}
247+
#endif
248+
163249
return obj->target_config->flash_start;
164250
}
165251

166-
uint32_t flash_get_size(const flash_t *obj)
252+
MBED_NONSECURE_ENTRY uint32_t flash_get_size(const flash_t *obj)
167253
{
254+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
255+
if (cmse_nonsecure_caller()) {
256+
return obj->target_config_ns->flash_size;
257+
}
258+
#endif
259+
168260
return obj->target_config->flash_size;
169261
}
262+
263+
#endif // #ifndef __DOMAIN_NS

hal/TARGET_FLASH_CMSIS_ALGO/flash_data.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,18 @@ typedef struct {
4747
} flash_target_config_t;
4848

4949
/** Target flash configuration
50+
* For targets not supporting TrustZone, its flash_set_target_config must define target_config.
51+
* For targets supporting TrustZone, it has the following requirements:
52+
* -# Flash IAP H/W can only configure to secure. It can access both secure/non-secure flash.
53+
* -# Flash IAP port is for secure build only. It exports secure functions for non-secure build.
54+
* -# In Flash IAP port, flash_set_target_config must define both target_config/target_config_ns for secure/non-secure flash respectively.
55+
* -# Non-secure application can access its non-secure flash only through secure flash IAP functions. It cannot access secure flash.
5056
*/
5157
struct flash_s {
52-
const flash_target_config_t *target_config;
58+
const flash_target_config_t *target_config; /**< Normal/secure flash configuration structure for targets not supporting/supporting TrustZone */
59+
#if defined(__CORTEX_M23) || defined(__CORTEX_M33)
60+
const flash_target_config_t *target_config_ns; /**< Non-secure flash configuration structure for targets supporting TrustZone */
61+
#endif
5362
const flash_algo_t *flash_algo;
5463
};
5564

platform/mbed_toolchain.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,27 @@
412412
#define EXTERN extern
413413
#endif
414414

415+
/** MBED_NONSECURE_ENTRY
416+
* Declare a function that can be called from non-secure world or secure world
417+
*
418+
* @code
419+
* #include "mbed_toolchain.h"
420+
*
421+
* MBED_NONSECURE_ENTRY void foo() {
422+
*
423+
* }
424+
* @endcode
425+
*/
426+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
427+
#if defined (__ICCARM__)
428+
#define MBED_NONSECURE_ENTRY __cmse_nonsecure_entry
429+
#else
430+
#define MBED_NONSECURE_ENTRY __attribute__((cmse_nonsecure_entry))
431+
#endif
432+
#else
433+
#define MBED_NONSECURE_ENTRY
434+
#endif
435+
415436
#endif
416437

417438
/** @}*/

0 commit comments

Comments
 (0)