-
Notifications
You must be signed in to change notification settings - Fork 3k
CMSE Secure library creation #5180
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
Changes from all commits
6eed3c5
988b0dd
c4a1697
87afc6b
6ba2bf9
7b5604e
07cbb98
af83953
e8ef7b2
c459188
b7358f8
4d9aeef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
/* mbed Microcontroller Library | ||
* Copyright (c) 2006-2016 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. | ||
*/ | ||
|
||
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) | ||
|
||
#include "cmsis.h" | ||
#include "mbed_rtx.h" | ||
#include "tz_context.h" | ||
|
||
|
||
/// Number of process slots (threads may call secure library code) | ||
#ifndef TZ_PROCESS_STACK_SLOTS | ||
#define TZ_PROCESS_STACK_SLOTS 8U | ||
#endif | ||
|
||
/// Stack size of the secure library code | ||
#ifndef TZ_PROCESS_STACK_SIZE | ||
#define TZ_PROCESS_STACK_SIZE 512U | ||
#endif | ||
|
||
typedef struct { | ||
uint32_t sp_top; // stack space top | ||
uint32_t sp_limit; // stack space limit | ||
uint32_t sp; // current stack pointer | ||
} stack_info_t; | ||
|
||
static stack_info_t ProcessStackInfo [TZ_PROCESS_STACK_SLOTS]; | ||
static uint64_t ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U]; | ||
static uint32_t ProcessStackFreeSlot = 0xFFFFFFFFU; | ||
|
||
|
||
/// Initialize secure context memory system | ||
/// \return execution status (1: success, 0: error) | ||
__attribute__((cmse_nonsecure_entry)) | ||
uint32_t TZ_InitContextSystem_S (void) | ||
{ | ||
uint32_t n; | ||
|
||
if (__get_IPSR() == 0U) { | ||
return 0U; // Thread Mode | ||
} | ||
|
||
for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) { | ||
ProcessStackInfo[n].sp = 0U; | ||
ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n]; | ||
ProcessStackInfo[n].sp_top = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE; | ||
*((uint32_t *)ProcessStackMemory[n]) = n + 1U; | ||
} | ||
*((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU; | ||
|
||
ProcessStackFreeSlot = 0U; | ||
|
||
// Default process stack pointer and stack limit | ||
__set_PSPLIM ((uint32_t)ProcessStackMemory); | ||
__set_PSP ((uint32_t)ProcessStackMemory); | ||
|
||
// Privileged Thread Mode using PSP | ||
__set_CONTROL(0x02U); | ||
|
||
return 1U; // Success | ||
} | ||
|
||
|
||
/// Allocate context memory for calling secure software modules in TrustZone | ||
/// \param[in] module identifies software modules called from non-secure mode | ||
/// \return value != 0 id TrustZone memory slot identifier | ||
/// \return value 0 no memory available or internal error | ||
__attribute__((cmse_nonsecure_entry)) | ||
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) | ||
{ | ||
uint32_t slot; | ||
|
||
(void)module; // Ignore (fixed Stack size) | ||
|
||
if (__get_IPSR() == 0U) { | ||
return 0U; // Thread Mode | ||
} | ||
|
||
if (ProcessStackFreeSlot == 0xFFFFFFFFU) { | ||
return 0U; // No slot available | ||
} | ||
|
||
slot = ProcessStackFreeSlot; | ||
ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]); | ||
|
||
ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top; | ||
|
||
return (slot + 1U); | ||
} | ||
|
||
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S | ||
/// \param[in] id TrustZone memory slot identifier | ||
/// \return execution status (1: success, 0: error) | ||
__attribute__((cmse_nonsecure_entry)) | ||
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) | ||
{ | ||
uint32_t slot; | ||
|
||
if (__get_IPSR() == 0U) { | ||
return 0U; // Thread Mode | ||
} | ||
|
||
if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { | ||
return 0U; // Invalid ID | ||
} | ||
|
||
slot = id - 1U; | ||
|
||
if (ProcessStackInfo[slot].sp == 0U) { | ||
return 0U; // Inactive slot | ||
} | ||
ProcessStackInfo[slot].sp = 0U; | ||
|
||
*((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot; | ||
ProcessStackFreeSlot = slot; | ||
|
||
return 1U; // Success | ||
} | ||
|
||
|
||
/// Load secure context (called on RTOS thread context switch) | ||
/// \param[in] id TrustZone memory slot identifier | ||
/// \return execution status (1: success, 0: error) | ||
__attribute__((cmse_nonsecure_entry)) | ||
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) | ||
{ | ||
uint32_t slot; | ||
|
||
if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { | ||
return 0U; // Thread Mode or using Main Stack for threads | ||
} | ||
|
||
if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { | ||
return 0U; // Invalid ID | ||
} | ||
|
||
slot = id - 1U; | ||
|
||
if (ProcessStackInfo[slot].sp == 0U) { | ||
return 0U; // Inactive slot | ||
} | ||
|
||
// Setup process stack pointer and stack limit | ||
__set_PSPLIM(ProcessStackInfo[slot].sp_limit); | ||
__set_PSP (ProcessStackInfo[slot].sp); | ||
|
||
return 1U; // Success | ||
} | ||
|
||
|
||
/// Store secure context (called on RTOS thread context switch) | ||
/// \param[in] id TrustZone memory slot identifier | ||
/// \return execution status (1: success, 0: error) | ||
__attribute__((cmse_nonsecure_entry)) | ||
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) | ||
{ | ||
uint32_t slot; | ||
uint32_t sp; | ||
|
||
if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { | ||
return 0U; // Thread Mode or using Main Stack for threads | ||
} | ||
|
||
if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { | ||
return 0U; // Invalid ID | ||
} | ||
|
||
slot = id - 1U; | ||
|
||
if (ProcessStackInfo[slot].sp == 0U) { | ||
return 0U; // Inactive slot | ||
} | ||
|
||
sp = __get_PSP(); | ||
if ((sp < ProcessStackInfo[slot].sp_limit) || | ||
(sp > ProcessStackInfo[slot].sp_top)) { | ||
return 0U; // SP out of range | ||
} | ||
ProcessStackInfo[slot].sp = sp; | ||
|
||
// Default process stack pointer and stack limit | ||
__set_PSPLIM((uint32_t)ProcessStackMemory); | ||
__set_PSP ((uint32_t)ProcessStackMemory); | ||
|
||
return 1U; // Success | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -320,6 +320,12 @@ void mbed_start_main(void) | |||
_main_thread_attr.cb_mem = &_main_obj; | ||||
_main_thread_attr.priority = osPriorityNormal; | ||||
_main_thread_attr.name = "main_thread"; | ||||
|
||||
/* Allow main thread to call secure functions */ | ||||
#if (__DOMAIN_NS == 1U) | ||||
|
#ifndef __DOMAIN_NS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't worry about it for this PR, but this file is becoming unreadable with more ifdefs than anything else, we should find better way of doing this.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -60,4 +60,22 @@ | |
# define OS_PRIVILEGE_MODE 0 | ||
#endif | ||
|
||
#define OS_SECURE_CALLABLE_THREAD 1 | ||
|
||
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) | ||
|
||
/* Number of process slots (threads may call secure library code) */ | ||
#ifndef MBED_CONF_APP_TZ_PROCESS_STACK_SLOTS | ||
#define MBED_CONF_APP_TZ_PROCESS_STACK_SLOTS 8U | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why 8? Can we document that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally it should be number of threads we allow in mbed-os. (Considering all of them have access to secure library). Or do we want to restrict threads from using secure library? |
||
#endif | ||
|
||
/* Stack size of the secure library code */ | ||
#ifndef MBED_CONF_APP_TZ_PROCESS_STACK_SIZE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this stack for exactly? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is stack for NSC region. i.e Secure library code executed from non-secure process. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be worth extending the comment ? Are we using code defaults instead of config - (this could be in the config file set, always present if not overriden) ? All in one place, this can however be fixed, as we already have this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @0xc0170 - In case of secure build, we ignore rtos (mbed_rtx_conf.h) hence I am exploring other correct options to update this flag. |
||
#define MBED_CONF_APP_TZ_PROCESS_STACK_SIZE 512U | ||
#endif | ||
|
||
#define TZ_PROCESS_STACK_SLOTS MBED_CONF_APP_TZ_PROCESS_STACK_SLOTS | ||
#define TZ_PROCESS_STACK_SIZE MBED_CONF_APP_TZ_PROCESS_STACK_SIZE | ||
#endif | ||
|
||
#endif /* MBED_RTX_CONF_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change main of secure thread will never be called, any initialization required needs to be done in mbed_sdk_init.