mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #10829 from devran01/feature_trusted-firmware-m_e7efdc6
PSA: TFM importpull/10838/head
commit
1aad06b394
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
|
@ -28,7 +28,7 @@
|
|||
*/
|
||||
struct tfm_spm_partition_platform_data_t;
|
||||
|
||||
#if TFM_LVL != 1
|
||||
#if defined (TFM_PSA_API) || (TFM_LVL != 1)
|
||||
/**
|
||||
* \brief Holds SPM db fields that define the memory regions used by a
|
||||
* partition.
|
||||
|
@ -147,7 +147,7 @@ uint32_t tfm_spm_hal_get_ns_MSP(void);
|
|||
uint32_t tfm_spm_hal_get_ns_entry_point(void);
|
||||
|
||||
|
||||
#if TFM_LVL != 1
|
||||
#if (TFM_LVL != 1) && !defined(TFM_PSA_API)
|
||||
/**
|
||||
* \brief Configure the sandbox for a partition.
|
||||
*
|
||||
|
|
|
@ -75,6 +75,16 @@ struct tfm_spm_ipc_partition_t {
|
|||
*/
|
||||
uint32_t tfm_spm_partition_get_running_partition_id_ext(void);
|
||||
|
||||
/**
|
||||
* \brief Get the current partition mode.
|
||||
*
|
||||
* \param[in] partition_idx Index of current partition
|
||||
*
|
||||
* \retval TFM_PARTITION_PRIVILEGED_MODE Privileged mode
|
||||
* \retval TFM_PARTITION_UNPRIVILEGED_MODE Unprivileged mode
|
||||
*/
|
||||
uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx);
|
||||
|
||||
/******************** Service handle management functions ********************/
|
||||
|
||||
/**
|
||||
|
@ -279,22 +289,38 @@ int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
|
|||
uint32_t minor_version);
|
||||
|
||||
/**
|
||||
* \brief Check the memory reference is valid.
|
||||
* \brief Check the memory reference is valid.
|
||||
*
|
||||
* \param[in] buffer Pointer of memory reference
|
||||
* \param[in] len Length of memory reference in bytes
|
||||
* \param[in] ns_caller From non-secure caller
|
||||
* \param[in] access Type of access specified by the
|
||||
* \ref tfm_memory_access_e
|
||||
* \param[in] buffer Pointer of memory reference
|
||||
* \param[in] len Length of memory reference in bytes
|
||||
* \param[in] ns_caller From non-secure caller
|
||||
* \param[in] access Type of access specified by the
|
||||
* \ref tfm_memory_access_e
|
||||
* \param[in] privileged Privileged mode or unprivileged mode:
|
||||
* \ref TFM_PARTITION_UNPRIVILEGED_MODE
|
||||
* \ref TFM_PARTITION_PRIVILEGED_MODE
|
||||
*
|
||||
* \retval IPC_SUCCESS Success
|
||||
* \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
|
||||
* \retval IPC_ERROR_MEMORY_CHECK Check failed
|
||||
* \retval IPC_SUCCESS Success
|
||||
* \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
|
||||
* \retval IPC_ERROR_MEMORY_CHECK Check failed
|
||||
*/
|
||||
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
|
||||
enum tfm_memory_access_e access);
|
||||
enum tfm_memory_access_e access,
|
||||
uint32_t privileged);
|
||||
|
||||
/* This function should be called before schedule function */
|
||||
void tfm_spm_init(void);
|
||||
|
||||
/*
|
||||
* PendSV specified function.
|
||||
*
|
||||
* Parameters :
|
||||
* ctxb - State context storage pointer
|
||||
*
|
||||
* Notes:
|
||||
* This is a staging API. Scheduler should be called in SPM finally and
|
||||
* this function will be obsoleted later.
|
||||
*/
|
||||
void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -177,6 +177,19 @@ struct tfm_thrd_ctx *tfm_thrd_curr_thread(void);
|
|||
*/
|
||||
struct tfm_thrd_ctx *tfm_thrd_next_thread(void);
|
||||
|
||||
/*
|
||||
* Start scheduler for existing threads
|
||||
*
|
||||
* Parameters:
|
||||
* pth - pointer of the caller context collecting thread
|
||||
*
|
||||
* Notes :
|
||||
* This function should be called only ONCE to start the scheduler.
|
||||
* Caller needs to provide a thread object to collect current context.
|
||||
* The usage of the collected context is caller defined.
|
||||
*/
|
||||
void tfm_thrd_start_scheduler(struct tfm_thrd_ctx *pth);
|
||||
|
||||
/*
|
||||
* Activate a scheduling action after exception.
|
||||
*
|
||||
|
@ -201,23 +214,19 @@ void tfm_thrd_context_switch(struct tfm_state_context_ext *ctxb,
|
|||
struct tfm_thrd_ctx *next);
|
||||
|
||||
/*
|
||||
* Exit current running thread.
|
||||
* Svcall to exit current running thread.
|
||||
*
|
||||
* Notes :
|
||||
* Remove current thread out of schedulable list.
|
||||
*/
|
||||
void tfm_thrd_do_exit(void);
|
||||
void tfm_svcall_thrd_exit(void);
|
||||
|
||||
/*
|
||||
* PendSV specified function.
|
||||
*
|
||||
* Parameters :
|
||||
* ctxb - State context storage pointer
|
||||
* Exit current running thread for client.
|
||||
*
|
||||
* Notes:
|
||||
* This is a staging API. Scheduler should be called in SPM finally and
|
||||
* this function will be obsoleted later.
|
||||
* Must be called in thread mode.
|
||||
*/
|
||||
void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb);
|
||||
void tfm_thrd_exit(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "tfm_svc.h"
|
||||
#include "psa_client.h"
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
uint32_t psa_framework_version(void)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -18,7 +18,7 @@ uint32_t psa_framework_version(void)
|
|||
: : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
uint32_t psa_version(uint32_t sid)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -26,7 +26,7 @@ uint32_t psa_version(uint32_t sid)
|
|||
: : "I" (TFM_SVC_PSA_VERSION));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -34,7 +34,7 @@ psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
|
|||
: : "I" (TFM_SVC_PSA_CONNECT));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
psa_status_t psa_call(psa_handle_t handle,
|
||||
const psa_invec *in_vec,
|
||||
size_t in_len,
|
||||
|
@ -46,7 +46,7 @@ psa_status_t psa_call(psa_handle_t handle,
|
|||
: : "I" (TFM_SVC_PSA_CALL));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_close(psa_handle_t handle)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "psa_client.h"
|
||||
#include "psa_service.h"
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
||||
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
|
|||
: : "I" (TFM_SVC_PSA_WAIT));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -28,7 +28,7 @@ psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
|
|||
: : "I" (TFM_SVC_PSA_GET));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -36,7 +36,7 @@ void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
|
|||
: : "I" (TFM_SVC_PSA_SET_RHANDLE));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
||||
void *buffer, size_t num_bytes)
|
||||
|
||||
|
@ -46,7 +46,7 @@ size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
|||
: : "I" (TFM_SVC_PSA_READ));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -54,7 +54,7 @@ size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
|
|||
: : "I" (TFM_SVC_PSA_SKIP));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
||||
const void *buffer, size_t num_bytes)
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
|||
: : "I" (TFM_SVC_PSA_WRITE));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_reply(psa_handle_t msg_handle, psa_status_t retval)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -71,7 +71,7 @@ void psa_reply(psa_handle_t msg_handle, psa_status_t retval)
|
|||
: : "I" (TFM_SVC_PSA_REPLY));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_notify(int32_t partition_id)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -79,7 +79,7 @@ void psa_notify(int32_t partition_id)
|
|||
: : "I" (TFM_SVC_PSA_NOTIFY));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_clear(void)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
@ -87,7 +87,7 @@ void psa_clear(void)
|
|||
: : "I" (TFM_SVC_PSA_CLEAR));
|
||||
}
|
||||
|
||||
__attribute__((naked))
|
||||
__attribute__((naked, section("SFN")))
|
||||
void psa_eoi(psa_signal_t irq_signal)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
||||
|
|
|
@ -17,19 +17,10 @@
|
|||
|
||||
/* This file contains the ARCH code for ARM V8M */
|
||||
|
||||
/*
|
||||
* Thread exit zone.
|
||||
* This function is set as the return address of thread entry and only
|
||||
* privileged thread could return here. Un-privileged thread triggers
|
||||
* fault if it tries to jump here and it gets exit by fault handler.
|
||||
*
|
||||
* The reason of putting this function here is for fault handler checking.
|
||||
* Function address could be checked in fault handler to know it is a REAL
|
||||
* thread exit or just an exception.
|
||||
*/
|
||||
__attribute__((section("SFN")))
|
||||
static void exit_zone(void)
|
||||
{
|
||||
tfm_thrd_do_exit();
|
||||
tfm_thrd_exit();
|
||||
}
|
||||
|
||||
void tfm_initialize_context(struct tfm_state_context *ctx,
|
||||
|
|
|
@ -38,6 +38,8 @@ static struct tfm_spm_ipc_partition_t
|
|||
/* Extern SPM variable */
|
||||
extern struct spm_partition_db_t g_spm_partition_db;
|
||||
|
||||
/* Extern secure lock variable */
|
||||
extern int32_t tfm_secure_lock;
|
||||
/* Pools */
|
||||
TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t),
|
||||
TFM_CONN_HANDLE_MAX_NUM);
|
||||
|
@ -433,21 +435,6 @@ tfm_spm_partition_get_thread_info_ext(uint32_t partition_idx)
|
|||
return &g_spm_partition_db.partitions[partition_idx].sp_thrd;
|
||||
}
|
||||
|
||||
static uint32_t tfm_spm_partition_get_stack_size_ext(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].stack_size;
|
||||
}
|
||||
|
||||
static uint32_t tfm_spm_partition_get_stack_limit_ext(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].stack_limit;
|
||||
}
|
||||
|
||||
static uint32_t tfm_spm_partition_get_stack_base_ext(uint32_t partition_idx)
|
||||
{
|
||||
return tfm_spm_partition_get_stack_limit_ext(partition_idx) + tfm_spm_partition_get_stack_size_ext(partition_idx);
|
||||
}
|
||||
|
||||
static tfm_thrd_func_t
|
||||
tfm_spm_partition_get_init_func_ext(uint32_t partition_idx)
|
||||
{
|
||||
|
@ -461,9 +448,9 @@ static uint32_t tfm_spm_partition_get_priority_ext(uint32_t partition_idx)
|
|||
partition_priority;
|
||||
}
|
||||
|
||||
/* FixMe: This is only valid for TFM LVL 1 now */
|
||||
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
|
||||
enum tfm_memory_access_e access)
|
||||
enum tfm_memory_access_e access,
|
||||
uint32_t privileged)
|
||||
{
|
||||
int32_t err;
|
||||
|
||||
|
@ -481,17 +468,28 @@ int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller,
|
|||
}
|
||||
|
||||
if (access == TFM_MEMORY_ACCESS_RW) {
|
||||
err = tfm_core_has_write_access_to_region(buffer, len, ns_caller);
|
||||
err = tfm_core_has_write_access_to_region(buffer, len, ns_caller,
|
||||
privileged);
|
||||
} else {
|
||||
err = tfm_core_has_read_access_to_region(buffer, len, ns_caller);
|
||||
err = tfm_core_has_read_access_to_region(buffer, len, ns_caller,
|
||||
privileged);
|
||||
}
|
||||
if (err == 1) {
|
||||
if (err == TFM_SUCCESS) {
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
|
||||
return IPC_ERROR_MEMORY_CHECK;
|
||||
}
|
||||
|
||||
uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_idx)
|
||||
{
|
||||
if (tfm_spm_partition_get_flags(partition_idx) & SPM_PART_FLAG_PSA_ROT) {
|
||||
return TFM_PARTITION_PRIVILEGED_MODE;
|
||||
} else {
|
||||
return TFM_PARTITION_UNPRIVILEGED_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
/********************** SPM functions for thread mode ************************/
|
||||
|
||||
void tfm_spm_init(void)
|
||||
|
@ -499,7 +497,8 @@ void tfm_spm_init(void)
|
|||
uint32_t i, num;
|
||||
struct tfm_spm_ipc_partition_t *partition;
|
||||
struct tfm_spm_service_t *service;
|
||||
struct tfm_thrd_ctx *pth;
|
||||
struct tfm_thrd_ctx *pth, this_thrd;
|
||||
struct spm_partition_desc_t *part;
|
||||
|
||||
tfm_pool_init(conn_handle_pool,
|
||||
POOL_BUFFER_SIZE(conn_handle_pool),
|
||||
|
@ -514,10 +513,12 @@ void tfm_spm_init(void)
|
|||
|
||||
/* Init partition first for it will be used when init service */
|
||||
for (i = 0; i < SPM_MAX_PARTITIONS; i++) {
|
||||
part = &g_spm_partition_db.partitions[i];
|
||||
tfm_spm_hal_configure_default_isolation(part->platform_data);
|
||||
g_spm_ipc_partition[i].index = i;
|
||||
if ((tfm_spm_partition_get_flags(i) & SPM_PART_FLAG_IPC) == 0) {
|
||||
continue;
|
||||
}
|
||||
g_spm_ipc_partition[i].index = i;
|
||||
g_spm_ipc_partition[i].id = tfm_spm_partition_get_partition_id(i);
|
||||
|
||||
tfm_event_init(&g_spm_ipc_partition[i].signal_evnt);
|
||||
|
@ -531,8 +532,9 @@ void tfm_spm_init(void)
|
|||
tfm_thrd_init(pth,
|
||||
tfm_spm_partition_get_init_func_ext(i),
|
||||
NULL,
|
||||
(uint8_t *)tfm_spm_partition_get_stack_base_ext(i),
|
||||
(uint8_t *)tfm_spm_partition_get_stack_limit_ext(i));
|
||||
(uint8_t *)tfm_spm_partition_get_stack_top(i),
|
||||
(uint8_t *)tfm_spm_partition_get_stack_bottom(i));
|
||||
|
||||
pth->prior = tfm_spm_partition_get_priority_ext(i);
|
||||
|
||||
/* Kick off */
|
||||
|
@ -559,6 +561,58 @@ void tfm_spm_init(void)
|
|||
tfm_list_add_tail(&partition->service_list, &service->list);
|
||||
}
|
||||
|
||||
/* All thread inited.... trigger scheduler */
|
||||
tfm_thrd_activate_schedule();
|
||||
/*
|
||||
* All threads initialized, start the scheduler.
|
||||
*
|
||||
* NOTE:
|
||||
* Here is the booting privileged thread mode, and will never
|
||||
* return to this place after scheduler is started. The start
|
||||
* function has to save current runtime context to act as a
|
||||
* 'current thread' to avoid repeating NULL 'current thread'
|
||||
* checking while context switching. This saved context is worthy
|
||||
* of being saved somewhere if there are potential usage purpose.
|
||||
* Let's save this context in a local variable 'this_thrd' at
|
||||
* current since there is no usage for it.
|
||||
* Also set tfm_nspm_thread_entry as pfn for this thread to
|
||||
* use in detecting NS/S thread scheduling changes.
|
||||
*/
|
||||
this_thrd.pfn = (tfm_thrd_func_t)tfm_nspm_thread_entry;
|
||||
tfm_thrd_start_scheduler(&this_thrd);
|
||||
}
|
||||
|
||||
void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb)
|
||||
{
|
||||
#if TFM_LVL == 2
|
||||
struct spm_partition_desc_t *p_next_partition;
|
||||
uint32_t is_privileged;
|
||||
#endif
|
||||
struct tfm_thrd_ctx *pth_next = tfm_thrd_next_thread();
|
||||
struct tfm_thrd_ctx *pth_curr = tfm_thrd_curr_thread();
|
||||
|
||||
if (pth_curr != pth_next) {
|
||||
#if TFM_LVL == 2
|
||||
p_next_partition = TFM_GET_CONTAINER_PTR(pth_next,
|
||||
struct spm_partition_desc_t,
|
||||
sp_thrd);
|
||||
|
||||
if (p_next_partition->static_data.partition_flags &
|
||||
SPM_PART_FLAG_PSA_ROT) {
|
||||
is_privileged = TFM_PARTITION_PRIVILEGED_MODE;
|
||||
} else {
|
||||
is_privileged = TFM_PARTITION_UNPRIVILEGED_MODE;
|
||||
}
|
||||
|
||||
tfm_spm_partition_change_privilege(is_privileged);
|
||||
#endif
|
||||
/* Increase the secure lock, if we enter secure from non-secure */
|
||||
if ((void *)pth_curr->pfn == (void *)tfm_nspm_thread_entry) {
|
||||
++tfm_secure_lock;
|
||||
}
|
||||
/* Decrease the secure lock, if we return from secure to non-secure */
|
||||
if ((void *)pth_next->pfn == (void *)tfm_nspm_thread_entry) {
|
||||
--tfm_secure_lock;
|
||||
}
|
||||
|
||||
tfm_thrd_context_switch(ctxb, pth_curr, pth_next);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "tfm_api.h"
|
||||
#include "tfm_secure_api.h"
|
||||
#include "tfm_memory_utils.h"
|
||||
#include "spm_api.h"
|
||||
|
||||
#define PSA_TIMEOUT_MASK PSA_BLOCK
|
||||
|
||||
|
@ -116,9 +117,18 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
|||
struct tfm_spm_service_t *service;
|
||||
struct tfm_msg_body_t *msg;
|
||||
int i;
|
||||
struct tfm_spm_ipc_partition_t *partition = NULL;
|
||||
uint32_t privileged;
|
||||
|
||||
TFM_ASSERT(args != NULL);
|
||||
handle = (psa_handle_t)args[0];
|
||||
|
||||
partition = tfm_spm_get_running_partition();
|
||||
if (!partition) {
|
||||
tfm_panic();
|
||||
}
|
||||
privileged = tfm_spm_partition_get_privileged_mode(partition->index);
|
||||
|
||||
if (!ns_caller) {
|
||||
inptr = (psa_invec *)args[1];
|
||||
in_num = (size_t)args[2];
|
||||
|
@ -153,11 +163,11 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
|||
* memory reference for buffer is invalid or not readable.
|
||||
*/
|
||||
if (tfm_memory_check((void *)args[1], sizeof(uint32_t),
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
if (tfm_memory_check((void *)args[2], sizeof(uint32_t),
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
|
||||
|
@ -185,7 +195,7 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
|||
* readable.
|
||||
*/
|
||||
if (tfm_memory_check((void *)inptr, in_num * sizeof(psa_invec),
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
/*
|
||||
|
@ -194,7 +204,7 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
|||
* the wrap output vector is invalid or not read-write.
|
||||
*/
|
||||
if (tfm_memory_check((void *)outptr, out_num * sizeof(psa_outvec),
|
||||
ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||
ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
|
||||
|
@ -211,7 +221,7 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
|||
*/
|
||||
for (i = 0; i < in_num; i++) {
|
||||
if (tfm_memory_check((void *)invecs[i].base, invecs[i].len,
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||
ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +231,7 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
|||
*/
|
||||
for (i = 0; i < out_num; i++) {
|
||||
if (tfm_memory_check(outvecs[i].base, outvecs[i].len,
|
||||
ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||
ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
}
|
||||
|
@ -363,6 +373,7 @@ static psa_status_t tfm_svcall_psa_get(uint32_t *args)
|
|||
struct tfm_spm_service_t *service = NULL;
|
||||
struct tfm_msg_body_t *tmp_msg = NULL;
|
||||
struct tfm_spm_ipc_partition_t *partition = NULL;
|
||||
uint32_t privileged;
|
||||
|
||||
TFM_ASSERT(args != NULL);
|
||||
signal = (psa_signal_t)args[0];
|
||||
|
@ -376,17 +387,18 @@ static psa_status_t tfm_svcall_psa_get(uint32_t *args)
|
|||
tfm_panic();
|
||||
}
|
||||
|
||||
partition = tfm_spm_get_running_partition();
|
||||
if (!partition) {
|
||||
tfm_panic();
|
||||
}
|
||||
privileged = tfm_spm_partition_get_privileged_mode(partition->index);
|
||||
|
||||
/*
|
||||
* Write the message to the service buffer. It is a fatal error if the
|
||||
* input msg pointer is not a valid memory reference or not read-write.
|
||||
*/
|
||||
if (tfm_memory_check((void *)msg, sizeof(psa_msg_t),
|
||||
false, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
|
||||
partition = tfm_spm_get_running_partition();
|
||||
if (!partition) {
|
||||
false, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
|
||||
|
@ -499,6 +511,8 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
|
|||
size_t num_bytes;
|
||||
size_t bytes;
|
||||
struct tfm_msg_body_t *msg = NULL;
|
||||
uint32_t privileged;
|
||||
struct tfm_spm_ipc_partition_t *partition = NULL;
|
||||
|
||||
TFM_ASSERT(args != NULL);
|
||||
msg_handle = (psa_handle_t)args[0];
|
||||
|
@ -512,6 +526,9 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
|
|||
tfm_panic();
|
||||
}
|
||||
|
||||
partition = msg->service->partition;
|
||||
privileged = tfm_spm_partition_get_privileged_mode(partition->index);
|
||||
|
||||
/*
|
||||
* It is a fatal error if message handle does not refer to a PSA_IPC_CALL
|
||||
* message
|
||||
|
@ -538,7 +555,7 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
|
|||
* if the memory reference for buffer is invalid or not read-write.
|
||||
*/
|
||||
if (tfm_memory_check(buffer, num_bytes, false,
|
||||
TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||
TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
|
||||
|
@ -650,6 +667,8 @@ static void tfm_svcall_psa_write(uint32_t *args)
|
|||
void *buffer = NULL;
|
||||
size_t num_bytes;
|
||||
struct tfm_msg_body_t *msg = NULL;
|
||||
uint32_t privileged;
|
||||
struct tfm_spm_ipc_partition_t *partition = NULL;
|
||||
|
||||
TFM_ASSERT(args != NULL);
|
||||
msg_handle = (psa_handle_t)args[0];
|
||||
|
@ -663,6 +682,9 @@ static void tfm_svcall_psa_write(uint32_t *args)
|
|||
tfm_panic();
|
||||
}
|
||||
|
||||
partition = msg->service->partition;
|
||||
privileged = tfm_spm_partition_get_privileged_mode(partition->index);
|
||||
|
||||
/*
|
||||
* It is a fatal error if message handle does not refer to a PSA_IPC_CALL
|
||||
* message
|
||||
|
@ -693,7 +715,7 @@ static void tfm_svcall_psa_write(uint32_t *args)
|
|||
* if the memory reference for buffer is invalid or not readable.
|
||||
*/
|
||||
if (tfm_memory_check(buffer, num_bytes, false,
|
||||
TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||
TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
|
||||
tfm_panic();
|
||||
}
|
||||
|
||||
|
@ -957,6 +979,9 @@ int32_t SVC_Handler_IPC(tfm_svc_number_t svc_num, uint32_t *ctx, uint32_t lr)
|
|||
case TFM_SVC_SCHEDULE:
|
||||
tfm_thrd_activate_schedule();
|
||||
break;
|
||||
case TFM_SVC_EXIT_THRD:
|
||||
tfm_svcall_thrd_exit();
|
||||
break;
|
||||
case TFM_SVC_PSA_FRAMEWORK_VERSION:
|
||||
return tfm_svcall_psa_framework_version();
|
||||
case TFM_SVC_PSA_VERSION:
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "tfm_thread.h"
|
||||
#include "tfm_utils.h"
|
||||
#include "tfm_memory_utils.h"
|
||||
#include "tfm_svc.h"
|
||||
#include "spm_api.h"
|
||||
|
||||
/* Force ZERO in case ZI(bss) clear is missing */
|
||||
static struct tfm_thrd_ctx *p_thrd_head = NULL;
|
||||
|
@ -124,75 +126,56 @@ void tfm_thrd_set_status(struct tfm_thrd_ctx *pth, uint32_t new_status)
|
|||
update_running_head(&RUNN_HEAD, pth);
|
||||
}
|
||||
|
||||
/*
|
||||
* TEMP WORKAROUND: The caller function who called thread module init needs to
|
||||
* be returned. The caller is not a thread. Create a dummy IDLE thread to
|
||||
* collect caller context; and schedule back to the caller with this context
|
||||
* after all other real threads blocked.
|
||||
*
|
||||
* This WORKAROUND needs to be removed after IPC NSPM takes place.
|
||||
*/
|
||||
#define DUMMY_IDLE_TAG 0xDEEDDEED
|
||||
static uint8_t idle_stack[32] __attribute__((aligned(8)));
|
||||
static struct tfm_thrd_ctx idle_thread;
|
||||
static struct tfm_thrd_ctx *init_idle_thread(struct tfm_thrd_ctx *pth)
|
||||
{
|
||||
/*
|
||||
* IDLE thread is a thread with the lowest priority.
|
||||
* It gets scheduled after all other higher priority threads get blocked.
|
||||
* The entry of IDLE thread is a dummy and has no mean.
|
||||
*/
|
||||
tfm_thrd_init(pth, (tfm_thrd_func_t)DUMMY_IDLE_TAG, NULL,
|
||||
(uint8_t *)&idle_stack[32], (uint8_t *)idle_stack);
|
||||
tfm_thrd_priority(pth, THRD_PRIOR_LOWEST);
|
||||
tfm_thrd_start(pth);
|
||||
return pth;
|
||||
}
|
||||
|
||||
/* Scheduling won't happen immediately but after the exception returns */
|
||||
void tfm_thrd_activate_schedule(void)
|
||||
{
|
||||
/*
|
||||
* The current thread can be NULL only when initializing. Create the IDLE
|
||||
* thread and set it as the current thread to collect caller context.
|
||||
*/
|
||||
if (CURR_THRD == NULL) {
|
||||
CURR_THRD = init_idle_thread(&idle_thread);
|
||||
}
|
||||
|
||||
tfm_trigger_pendsv();
|
||||
}
|
||||
|
||||
void tfm_thrd_start_scheduler(struct tfm_thrd_ctx *pth)
|
||||
{
|
||||
/*
|
||||
* There is no selected thread before scheduler start, assign
|
||||
* a caller provided thread as current thread. This function
|
||||
* should get called only ONCE; further calling triggers assert.
|
||||
*/
|
||||
TFM_ASSERT(CURR_THRD == NULL);
|
||||
TFM_ASSERT(pth != NULL);
|
||||
|
||||
CURR_THRD = pth;
|
||||
tfm_thrd_activate_schedule();
|
||||
}
|
||||
|
||||
/* Remove current thread out of the schedulable list */
|
||||
void tfm_thrd_do_exit(void)
|
||||
void tfm_svcall_thrd_exit(void)
|
||||
{
|
||||
CURR_THRD->status = THRD_STAT_DETACH;
|
||||
tfm_trigger_pendsv();
|
||||
}
|
||||
|
||||
__attribute__((section("SFN")))
|
||||
void tfm_thrd_exit(void)
|
||||
{
|
||||
SVC(TFM_SVC_EXIT_THRD);
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void tfm_thrd_context_switch(struct tfm_state_context_ext *ctxb,
|
||||
struct tfm_thrd_ctx *prev,
|
||||
struct tfm_thrd_ctx *next)
|
||||
{
|
||||
/* Update latest context into the current thread context */
|
||||
TFM_ASSERT(prev != NULL);
|
||||
TFM_ASSERT(next != NULL);
|
||||
|
||||
/*
|
||||
* First, update latest context into the current thread context.
|
||||
* Then, update background context with next thread's context.
|
||||
*/
|
||||
tfm_memcpy(&prev->state_ctx.ctxb, ctxb, sizeof(*ctxb));
|
||||
/* Update background context with next thread's context */
|
||||
tfm_memcpy(ctxb, &next->state_ctx.ctxb, sizeof(next->state_ctx.ctxb));
|
||||
/* Set current thread indicator with next thread */
|
||||
|
||||
/* Update current thread indicator */
|
||||
CURR_THRD = next;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is a reference implementation for PendSV handler in
|
||||
* isolation level 1. More jobs (sandboxing e.g.) need to be done while
|
||||
* scheduling in other isolation levels.
|
||||
*/
|
||||
void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb)
|
||||
{
|
||||
struct tfm_thrd_ctx *pth = tfm_thrd_next_thread();
|
||||
|
||||
/* Swith context if another thread ready to run */
|
||||
if (pth && pth != CURR_THRD) {
|
||||
tfm_thrd_context_switch(ctxb, CURR_THRD, pth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,15 @@
|
|||
#include "tfm_api.h"
|
||||
#include "flash_layout.h"
|
||||
#include "secure_fw/spm/spm_api.h"
|
||||
#ifdef TFM_PSA_API
|
||||
#include "tfm_internal_defines.h"
|
||||
#include "tfm_utils.h"
|
||||
#include "psa_service.h"
|
||||
#include "tfm_thread.h"
|
||||
#include "tfm_wait.h"
|
||||
#include "tfm_message_queue.h"
|
||||
#include "tfm_spm.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \def BOOT_DATA_VALID
|
||||
|
@ -60,13 +69,19 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
|
|||
uint8_t *buf_start = (uint8_t *)args[1];
|
||||
uint16_t buf_size = (uint16_t)args[2];
|
||||
uint8_t *ptr;
|
||||
uint32_t running_partition_idx =
|
||||
tfm_spm_partition_get_running_partition_idx();
|
||||
struct tfm_boot_data *boot_data;
|
||||
struct shared_data_tlv_entry tlv_entry;
|
||||
uintptr_t tlv_end, offset;
|
||||
#ifndef TFM_PSA_API
|
||||
uint32_t running_partition_idx =
|
||||
tfm_spm_partition_get_running_partition_idx();
|
||||
uint32_t res;
|
||||
#else
|
||||
struct tfm_spm_ipc_partition_t *partition = NULL;
|
||||
uint32_t privileged;
|
||||
#endif
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
/* Make sure that the output pointer points to a memory area that is owned
|
||||
* by the partition
|
||||
*/
|
||||
|
@ -79,6 +94,20 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
|
|||
args[0] = TFM_ERROR_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
partition = tfm_spm_get_running_partition();
|
||||
if (!partition) {
|
||||
tfm_panic();
|
||||
}
|
||||
privileged = tfm_spm_partition_get_privileged_mode(partition->index);
|
||||
|
||||
if (tfm_memory_check(buf_start, buf_size, false, TFM_MEMORY_ACCESS_RW,
|
||||
privileged) != IPC_SUCCESS) {
|
||||
/* Not in accessible range, return error */
|
||||
args[0] = TFM_ERROR_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FixMe: Check whether caller has access right to given tlv_major_type */
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ __asm(" .global __ARM_use_no_argv\n");
|
|||
#error Only TFM_LVL 1, 2 and 3 are supported!
|
||||
#endif
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
/* Macros to pick linker symbols and allow to form the partition data base */
|
||||
#define REGION(a, b, c) a##b##c
|
||||
#define REGION_NAME(a, b, c) REGION(a, b, c)
|
||||
|
@ -54,6 +55,7 @@ __asm(" .global __ARM_use_no_argv\n");
|
|||
|
||||
REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
|
||||
REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
|
||||
#endif
|
||||
|
||||
void configure_ns_code(void)
|
||||
{
|
||||
|
@ -106,11 +108,20 @@ int32_t tfm_core_init(void)
|
|||
/* Enable secure peripherals interrupts */
|
||||
nvic_interrupt_enable();
|
||||
|
||||
#ifdef TFM_PSA_API
|
||||
/* FixMe: In case of IPC messaging, scratch area must not be referenced
|
||||
* These variables should be removed when all obsolete references are
|
||||
* removed from the codebase
|
||||
*/
|
||||
tfm_scratch_area = NULL;
|
||||
tfm_scratch_area_size = 0;
|
||||
#else
|
||||
tfm_scratch_area =
|
||||
(uint8_t *)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
|
||||
tfm_scratch_area_size =
|
||||
(uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit) -
|
||||
(uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -179,6 +190,7 @@ int main(void)
|
|||
|
||||
tfm_spm_hal_setup_isolation_hw();
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_RUNNING);
|
||||
|
||||
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
|
||||
|
@ -198,21 +210,25 @@ int main(void)
|
|||
*/
|
||||
tfm_core_set_secure_exception_priorities();
|
||||
|
||||
#ifdef TFM_PSA_API
|
||||
tfm_spm_init();
|
||||
#endif
|
||||
/* We close the TFM_SP_CORE_ID partition, because its only purpose is
|
||||
* to be able to pass the state checks for the tests started from secure.
|
||||
*/
|
||||
tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_CLOSED);
|
||||
tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID,
|
||||
SPM_PARTITION_STATE_RUNNING);
|
||||
|
||||
#ifdef TFM_CORE_DEBUG
|
||||
/* Jumps to non-secure code */
|
||||
LOG_MSG("Jumping to non-secure code...");
|
||||
#endif
|
||||
|
||||
/* We close the TFM_SP_CORE_ID partition, because its only purpose is
|
||||
* to be able to pass the state checks for the tests started from secure.
|
||||
*/
|
||||
tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_CLOSED);
|
||||
tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID,
|
||||
SPM_PARTITION_STATE_RUNNING);
|
||||
|
||||
jump_to_ns_code();
|
||||
#else
|
||||
/*
|
||||
* Prioritise secure exceptions to avoid NS being able to pre-empt
|
||||
* secure SVC or SecureFault. Do it before PSA API initialization.
|
||||
*/
|
||||
tfm_core_set_secure_exception_priorities();
|
||||
tfm_spm_init();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -156,6 +156,30 @@ uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr)
|
|||
return lr;
|
||||
}
|
||||
switch (svc_number) {
|
||||
#ifdef TFM_PSA_API
|
||||
case TFM_SVC_IPC_REQUEST:
|
||||
tfm_psa_ipc_request_handler(svc_args);
|
||||
break;
|
||||
case TFM_SVC_SCHEDULE:
|
||||
case TFM_SVC_EXIT_THRD:
|
||||
case TFM_SVC_PSA_FRAMEWORK_VERSION:
|
||||
case TFM_SVC_PSA_VERSION:
|
||||
case TFM_SVC_PSA_CONNECT:
|
||||
case TFM_SVC_PSA_CALL:
|
||||
case TFM_SVC_PSA_CLOSE:
|
||||
case TFM_SVC_PSA_WAIT:
|
||||
case TFM_SVC_PSA_GET:
|
||||
case TFM_SVC_PSA_SET_RHANDLE:
|
||||
case TFM_SVC_PSA_READ:
|
||||
case TFM_SVC_PSA_SKIP:
|
||||
case TFM_SVC_PSA_WRITE:
|
||||
case TFM_SVC_PSA_REPLY:
|
||||
case TFM_SVC_PSA_NOTIFY:
|
||||
case TFM_SVC_PSA_CLEAR:
|
||||
case TFM_SVC_PSA_EOI:
|
||||
svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, lr);
|
||||
break;
|
||||
#else
|
||||
case TFM_SVC_SFN_REQUEST:
|
||||
lr = tfm_core_partition_request_svc_handler(svc_args, lr);
|
||||
break;
|
||||
|
@ -177,10 +201,6 @@ uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr)
|
|||
case TFM_SVC_SET_SHARE_AREA:
|
||||
tfm_core_set_buffer_area_handler(svc_args);
|
||||
break;
|
||||
#ifdef TFM_PSA_API
|
||||
case TFM_SVC_IPC_REQUEST:
|
||||
tfm_psa_ipc_request_handler(svc_args);
|
||||
break;
|
||||
#endif
|
||||
case TFM_SVC_PRINT:
|
||||
printf("\e[1;34m[Sec Thread] %s\e[0m\r\n", (char *)svc_args[0]);
|
||||
|
@ -188,25 +208,6 @@ uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr)
|
|||
case TFM_SVC_GET_BOOT_DATA:
|
||||
tfm_core_get_boot_data_handler(svc_args);
|
||||
break;
|
||||
#ifdef TFM_PSA_API
|
||||
case TFM_SVC_PSA_FRAMEWORK_VERSION:
|
||||
case TFM_SVC_PSA_VERSION:
|
||||
case TFM_SVC_PSA_CONNECT:
|
||||
case TFM_SVC_PSA_CALL:
|
||||
case TFM_SVC_PSA_CLOSE:
|
||||
case TFM_SVC_PSA_WAIT:
|
||||
case TFM_SVC_PSA_GET:
|
||||
case TFM_SVC_PSA_SET_RHANDLE:
|
||||
case TFM_SVC_PSA_READ:
|
||||
case TFM_SVC_PSA_SKIP:
|
||||
case TFM_SVC_PSA_WRITE:
|
||||
case TFM_SVC_PSA_REPLY:
|
||||
case TFM_SVC_PSA_NOTIFY:
|
||||
case TFM_SVC_PSA_CLEAR:
|
||||
case TFM_SVC_PSA_EOI:
|
||||
svc_args[0] = SVC_Handler_IPC(svc_number, svc_args, lr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
LOG_MSG("Unknown SVC number requested!");
|
||||
break;
|
||||
|
|
|
@ -6,8 +6,13 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "secure_utilities.h"
|
||||
#include "tfm_api.h"
|
||||
#ifdef TFM_PSA_API
|
||||
#include "tfm_utils.h"
|
||||
#include "tfm_internal.h"
|
||||
#endif
|
||||
|
||||
#ifndef TFM_MAX_NS_THREAD_COUNT
|
||||
#define TFM_MAX_NS_THREAD_COUNT 8
|
||||
|
@ -300,3 +305,20 @@ enum tfm_status_e tfm_register_client_id (int32_t ns_client_id)
|
|||
return TFM_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TFM_PSA_API
|
||||
__attribute__((section("SFN")))
|
||||
psa_status_t tfm_nspm_thread_entry(void)
|
||||
{
|
||||
#ifdef TFM_CORE_DEBUG
|
||||
/* Jumps to non-secure code */
|
||||
LOG_MSG("Jumping to non-secure code...");
|
||||
#endif
|
||||
|
||||
jump_to_ns_code();
|
||||
|
||||
/* Should not run here */
|
||||
TFM_ASSERT(false);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2018-2019, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
|
@ -23,4 +23,15 @@ void tfm_nspm_configure_clients(void);
|
|||
*/
|
||||
int32_t tfm_nspm_get_current_client_id(void);
|
||||
|
||||
#ifdef TFM_PSA_API
|
||||
/**
|
||||
* \brief NSPM thread main entry function
|
||||
*
|
||||
* \return PSA_SUCCESS indicates failed.
|
||||
*
|
||||
* Note: This function should not return back.
|
||||
*/
|
||||
psa_status_t tfm_nspm_thread_entry(void);
|
||||
#endif
|
||||
|
||||
#endif /* __TFM_NSPM_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -96,14 +96,19 @@ int32_t tfm_core_sfn_request_thread_mode(struct tfm_sfn_req_s *desc_ptr);
|
|||
* This function assumes, that the current MPU configuration is set for the
|
||||
* partition to be checked.
|
||||
*
|
||||
* \param[in] p The start address of the range to check
|
||||
* \param[in] s The size of the range to check
|
||||
* \param[in] ns_caller Whether the current partition is a non-secure one
|
||||
* \param[in] p The start address of the range to check
|
||||
* \param[in] s The size of the range to check
|
||||
* \param[in] ns_caller Whether the current partition is a non-secure one
|
||||
* \param[in] privileged Privileged mode or unprivileged mode:
|
||||
* \ref TFM_PARTITION_UNPRIVILEGED_MODE
|
||||
* \ref TFM_PARTITION_PRIVILEGED_MODE
|
||||
*
|
||||
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
||||
* \return TFM_SUCCESS if the partition has access to the memory range,
|
||||
* TFM_ERROR_GENERIC otherwise.
|
||||
*/
|
||||
int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
|
||||
uint32_t ns_caller);
|
||||
uint32_t ns_caller,
|
||||
uint32_t privileged);
|
||||
|
||||
/**
|
||||
* \brief Check whether the current partition has write access to a memory range
|
||||
|
@ -111,15 +116,39 @@ int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
|
|||
* This function assumes, that the current MPU configuration is set for the
|
||||
* partition to be checked.
|
||||
*
|
||||
* \param[in] p The start address of the range to check
|
||||
* \param[in] s The size of the range to check
|
||||
* \param[in] ns_caller Whether the current partition is a non-secure one
|
||||
* \param[in] p The start address of the range to check
|
||||
* \param[in] s The size of the range to check
|
||||
* \param[in] ns_caller Whether the current partition is a non-secure one
|
||||
* \param[in] privileged Privileged mode or unprivileged mode:
|
||||
* \ref TFM_PARTITION_UNPRIVILEGED_MODE
|
||||
* \ref TFM_PARTITION_PRIVILEGED_MODE
|
||||
*
|
||||
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
||||
* \return TFM_SUCCESS if the partition has access to the memory range,
|
||||
* TFM_ERROR_GENERIC otherwise.
|
||||
*/
|
||||
int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
|
||||
uint32_t ns_caller);
|
||||
uint32_t ns_caller,
|
||||
uint32_t privileged);
|
||||
|
||||
#ifdef TFM_PSA_API
|
||||
/* The following macros are only valid if secure services can be called
|
||||
* using veneer functions. This is not the case if IPC messaging is enabled
|
||||
*/
|
||||
#define TFM_CORE_IOVEC_SFN_REQUEST(id, fn, a, b, c, d) \
|
||||
do { \
|
||||
ERROR_MSG("Invalid TF-M configuration detected"); \
|
||||
tfm_secure_api_error_handler(); \
|
||||
/* This point never reached */ \
|
||||
return (int32_t)TFM_ERROR_GENERIC; \
|
||||
} while (0)
|
||||
#define TFM_CORE_SFN_REQUEST(id, fn, a, b, c, d) \
|
||||
do { \
|
||||
ERROR_MSG("Invalid TF-M configuration detected"); \
|
||||
tfm_secure_api_error_handler(); \
|
||||
/* This point never reached */ \
|
||||
return (int32_t)TFM_ERROR_GENERIC; \
|
||||
} while (0)
|
||||
#else
|
||||
#define TFM_CORE_IOVEC_SFN_REQUEST(id, fn, a, b, c, d) \
|
||||
return tfm_core_partition_request(id, fn, TFM_SFN_API_IOVEC, \
|
||||
(int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d)
|
||||
|
@ -136,7 +165,7 @@ int32_t tfm_core_partition_request(uint32_t id, void *fn, int32_t iovec_api,
|
|||
struct tfm_sfn_req_s desc, *desc_ptr = &desc;
|
||||
|
||||
desc.sp_id = id;
|
||||
desc.sfn = fn;
|
||||
desc.sfn = (sfn_t) fn;
|
||||
desc.args = args;
|
||||
/*
|
||||
* This preprocessor condition checks if a version of GCC smaller than
|
||||
|
@ -180,5 +209,6 @@ int32_t tfm_core_partition_request(uint32_t id, void *fn, int32_t iovec_api,
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TFM_SECURE_API_H__ */
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "tfm_secure_api.h"
|
||||
#include "tfm_internal.h"
|
||||
#include "secure_fw/include/tfm_spm_services_api.h"
|
||||
#include "spm_api.h"
|
||||
|
||||
uint8_t *tfm_scratch_area;
|
||||
uint32_t tfm_scratch_area_size;
|
||||
|
@ -18,13 +19,9 @@ nsfptr_t ns_entry;
|
|||
|
||||
void jump_to_ns_code(void)
|
||||
{
|
||||
#if TFM_LVL != 1
|
||||
#if TFM_LVL == 3 || ((!defined(TFM_PSA_API)) && (TFM_LVL != 1))
|
||||
/* Initialization is done, set thread mode to unprivileged. */
|
||||
CONTROL_Type ctrl;
|
||||
|
||||
ctrl.w = __get_CONTROL();
|
||||
ctrl.b.nPRIV = 1;
|
||||
__set_CONTROL(ctrl.w);
|
||||
tfm_spm_partition_change_privilege(TFM_PARTITION_UNPRIVILEGED_MODE);
|
||||
#endif
|
||||
/* All changes made to memory will be effective after this point */
|
||||
__DSB();
|
||||
|
@ -34,6 +31,7 @@ void jump_to_ns_code(void)
|
|||
ns_entry();
|
||||
}
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
#if defined(__ARM_ARCH_8M_MAIN__)
|
||||
__attribute__((naked)) int32_t tfm_core_sfn_request(
|
||||
const struct tfm_sfn_req_s *desc_ptr)
|
||||
|
@ -154,6 +152,7 @@ int32_t tfm_core_set_buffer_area(enum tfm_buffer_share_region_e share)
|
|||
"BX lr\n"
|
||||
: : "I" (TFM_SVC_SET_SHARE_AREA));
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((naked))
|
||||
int32_t tfm_core_get_boot_data(uint8_t major_type,
|
||||
|
|
|
@ -23,6 +23,7 @@ typedef enum {
|
|||
#ifdef TFM_PSA_API
|
||||
TFM_SVC_IPC_REQUEST,
|
||||
TFM_SVC_SCHEDULE,
|
||||
TFM_SVC_EXIT_THRD,
|
||||
/* PSA Client SVC */
|
||||
TFM_SVC_PSA_FRAMEWORK_VERSION,
|
||||
TFM_SVC_PSA_VERSION,
|
||||
|
|
|
@ -43,7 +43,7 @@ int32_t tfm_psa_veneer_sanity_check(struct tfm_sfn_req_s *desc_ptr)
|
|||
return tfm_core_ns_ipc_request(fn, (int32_t)a, (int32_t)b, \
|
||||
(int32_t)c, (int32_t)d)
|
||||
|
||||
__attribute__ ((naked))
|
||||
__attribute__ ((naked, section("SFN")))
|
||||
static int32_t tfm_core_ipc_request(const struct tfm_sfn_req_s *desc_ptr)
|
||||
{
|
||||
__ASM volatile("SVC %0 \n"
|
|
@ -32,6 +32,7 @@ typedef enum {
|
|||
* In case of an error in the error handling, a non-zero value have to be
|
||||
* returned.
|
||||
*/
|
||||
#ifndef TFM_PSA_API
|
||||
static void tfm_spm_partition_err_handler(
|
||||
const struct spm_partition_desc_t *partition,
|
||||
sp_error_type_t err_type,
|
||||
|
@ -53,6 +54,7 @@ static void tfm_spm_partition_err_handler(
|
|||
tfm_spm_partition_set_state(partition->static_data.partition_id,
|
||||
SPM_PARTITION_STATE_CLOSED);
|
||||
}
|
||||
#endif /* !defined(TFM_PSA_API) */
|
||||
|
||||
/*
|
||||
* This function prevents name clashes between the variable names accessibles in
|
||||
|
@ -98,29 +100,34 @@ enum spm_err_t tfm_spm_db_init(void)
|
|||
*/
|
||||
|
||||
/* For the non secure Execution environment */
|
||||
#if (TFM_LVL != 1) || defined(TFM_PSA_API)
|
||||
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
|
||||
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
|
||||
uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
|
||||
uint32_t psp_stack_top = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit;
|
||||
|
||||
#endif
|
||||
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
|
||||
return SPM_ERR_INVALID_CONFIG;
|
||||
}
|
||||
part_ptr = &(g_spm_partition_db.partitions[
|
||||
g_spm_partition_db.partition_count]);
|
||||
part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID;
|
||||
#ifdef TFM_PSA_API
|
||||
part_ptr->static_data.partition_flags = SPM_PART_FLAG_APP_ROT |
|
||||
SPM_PART_FLAG_IPC;
|
||||
part_ptr->static_data.partition_priority = TFM_PRIORITY_LOW;
|
||||
part_ptr->static_data.partition_init = tfm_nspm_thread_entry;
|
||||
#else
|
||||
part_ptr->static_data.partition_flags = 0;
|
||||
#endif
|
||||
|
||||
#if TFM_LVL != 1
|
||||
#if (TFM_LVL != 1) || defined(TFM_PSA_API)
|
||||
part_ptr->memory_data.stack_bottom = psp_stack_bottom;
|
||||
part_ptr->memory_data.stack_top = psp_stack_top;
|
||||
/* Since RW, ZI and stack are configured as one MPU region, configure
|
||||
* RW start address to psp_stack_bottom to get RW access to stack
|
||||
*/
|
||||
part_ptr->memory_data.rw_start = psp_stack_bottom;
|
||||
#else
|
||||
part_ptr->stack_limit = psp_stack_bottom;
|
||||
part_ptr->stack_size = psp_stack_top - psp_stack_bottom;
|
||||
#endif
|
||||
|
||||
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
|
||||
|
@ -149,6 +156,7 @@ enum spm_err_t tfm_spm_db_init(void)
|
|||
return SPM_ERR_OK;
|
||||
}
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
enum spm_err_t tfm_spm_partition_init(void)
|
||||
{
|
||||
struct spm_partition_desc_t *part;
|
||||
|
@ -161,11 +169,6 @@ enum spm_err_t tfm_spm_partition_init(void)
|
|||
for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
|
||||
part = &g_spm_partition_db.partitions[idx];
|
||||
tfm_spm_hal_configure_default_isolation(part->platform_data);
|
||||
#ifdef TFM_PSA_API
|
||||
if (part->static_data.partition_flags & SPM_PART_FLAG_IPC) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (part->static_data.partition_init == NULL) {
|
||||
tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
|
||||
tfm_spm_partition_set_caller_partition_idx(idx,
|
||||
|
@ -196,8 +199,22 @@ enum spm_err_t tfm_spm_partition_init(void)
|
|||
return SPM_ERR_PARTITION_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
#endif /* !defined(TFM_PSA_API) */
|
||||
|
||||
#if TFM_LVL != 1
|
||||
#if (TFM_LVL != 1) || defined(TFM_PSA_API)
|
||||
uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].
|
||||
memory_data.stack_bottom;
|
||||
}
|
||||
|
||||
uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (TFM_LVL != 1) && !defined(TFM_PSA_API)
|
||||
enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
|
||||
{
|
||||
struct spm_partition_desc_t *part;
|
||||
|
@ -226,17 +243,6 @@ enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
|
|||
part->platform_data);
|
||||
}
|
||||
|
||||
uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].
|
||||
memory_data.stack_bottom;
|
||||
}
|
||||
|
||||
uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
|
||||
}
|
||||
|
||||
uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].
|
||||
|
@ -268,15 +274,6 @@ void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
|
|||
}
|
||||
#endif
|
||||
|
||||
void tfm_spm_partition_store_context(uint32_t partition_idx,
|
||||
uint32_t stack_ptr, uint32_t lr)
|
||||
{
|
||||
g_spm_partition_db.partitions[partition_idx].
|
||||
runtime_data.stack_ptr = stack_ptr;
|
||||
g_spm_partition_db.partitions[partition_idx].
|
||||
runtime_data.lr = lr;
|
||||
}
|
||||
|
||||
uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
|
||||
{
|
||||
return g_spm_partition_db.partitions[partition_idx].static_data.
|
||||
|
@ -289,6 +286,16 @@ uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx)
|
|||
partition_flags;
|
||||
}
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
void tfm_spm_partition_store_context(uint32_t partition_idx,
|
||||
uint32_t stack_ptr, uint32_t lr)
|
||||
{
|
||||
g_spm_partition_db.partitions[partition_idx].
|
||||
runtime_data.stack_ptr = stack_ptr;
|
||||
g_spm_partition_db.partitions[partition_idx].
|
||||
runtime_data.lr = lr;
|
||||
}
|
||||
|
||||
const struct spm_partition_runtime_data_t *
|
||||
tfm_spm_partition_get_runtime_data(uint32_t partition_idx)
|
||||
{
|
||||
|
@ -390,3 +397,20 @@ void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
|
|||
partition->runtime_data.orig_outvec = 0;
|
||||
partition->runtime_data.iovec_api = 0;
|
||||
}
|
||||
#endif /* !defined(TFM_PSA_API) */
|
||||
|
||||
__attribute__((section("SFN")))
|
||||
void tfm_spm_partition_change_privilege(uint32_t privileged)
|
||||
{
|
||||
CONTROL_Type ctrl;
|
||||
|
||||
ctrl.w = __get_CONTROL();
|
||||
|
||||
if (privileged == TFM_PARTITION_PRIVILEGED_MODE) {
|
||||
ctrl.b.nPRIV = 0;
|
||||
} else {
|
||||
ctrl.b.nPRIV = 1;
|
||||
}
|
||||
|
||||
__set_CONTROL(ctrl.w);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
#define SPM_INVALID_PARTITION_IDX (~0U)
|
||||
|
||||
/* Privileged definitions for partition thread mode */
|
||||
#define TFM_PARTITION_PRIVILEGED_MODE 1
|
||||
#define TFM_PARTITION_UNPRIVILEGED_MODE 0
|
||||
|
||||
enum spm_err_t {
|
||||
SPM_ERR_OK = 0,
|
||||
SPM_ERR_PARTITION_DB_NOT_INIT,
|
||||
|
@ -83,29 +87,7 @@ struct spm_partition_runtime_data_t {
|
|||
*/
|
||||
uint32_t get_partition_idx(uint32_t partition_id);
|
||||
|
||||
#if TFM_LVL != 1
|
||||
/**
|
||||
* \brief Configure isolated sandbox for a partition
|
||||
*
|
||||
* \param[in] partition_idx Partition index
|
||||
*
|
||||
* \return Error code \ref spm_err_t
|
||||
*
|
||||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx);
|
||||
|
||||
/**
|
||||
* \brief Deconfigure sandbox for a partition
|
||||
*
|
||||
* \param[in] partition_idx Partition index
|
||||
*
|
||||
* \return Error code \ref spm_err_t
|
||||
*
|
||||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
|
||||
|
||||
#if (TFM_LVL != 1) || defined(TFM_PSA_API)
|
||||
/**
|
||||
* \brief Get bottom of stack region for a partition
|
||||
*
|
||||
|
@ -127,6 +109,30 @@ uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
|
|||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
|
||||
#endif
|
||||
|
||||
#if (TFM_LVL != 1) && !defined(TFM_PSA_API)
|
||||
/**
|
||||
* \brief Configure isolated sandbox for a partition
|
||||
*
|
||||
* \param[in] partition_idx Partition index
|
||||
*
|
||||
* \return Error code \ref spm_err_t
|
||||
*
|
||||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx);
|
||||
|
||||
/**
|
||||
* \brief Deconfigure sandbox for a partition
|
||||
*
|
||||
* \param[in] partition_idx Partition index
|
||||
*
|
||||
* \return Error code \ref spm_err_t
|
||||
*
|
||||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
|
||||
|
||||
/**
|
||||
* \brief Get the start of the zero-initialised region for a partition
|
||||
|
@ -185,6 +191,17 @@ uint32_t tfm_spm_partition_get_rw_limit(uint32_t partition_idx);
|
|||
void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Get the id of the partition for its index from the db
|
||||
*
|
||||
* \param[in] partition_idx Partition index
|
||||
*
|
||||
* \return Partition ID for that partition
|
||||
*
|
||||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
|
||||
|
||||
/**
|
||||
* \brief Get the flags associated with a partition
|
||||
*
|
||||
|
@ -196,6 +213,7 @@ void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr);
|
|||
*/
|
||||
uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
|
||||
|
||||
#ifndef TFM_PSA_API
|
||||
/**
|
||||
* \brief Get the current runtime data of a partition
|
||||
*
|
||||
|
@ -228,17 +246,6 @@ uint32_t tfm_spm_partition_get_running_partition_idx(void);
|
|||
void tfm_spm_partition_store_context(uint32_t partition_idx,
|
||||
uint32_t stack_ptr, uint32_t lr);
|
||||
|
||||
/**
|
||||
* \brief Get the id of the partition for its index from the db
|
||||
*
|
||||
* \param[in] partition_idx Partition index
|
||||
*
|
||||
* \return Partition ID for that partition
|
||||
*
|
||||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx);
|
||||
|
||||
/**
|
||||
* \brief Set the current state of a partition
|
||||
*
|
||||
|
@ -307,13 +314,6 @@ enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
|
|||
enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
|
||||
const int32_t *args);
|
||||
|
||||
/**
|
||||
* \brief Initialize partition database
|
||||
*
|
||||
* \return Error code \ref spm_err_t
|
||||
*/
|
||||
enum spm_err_t tfm_spm_db_init(void);
|
||||
|
||||
/**
|
||||
* \brief Execute partition init function
|
||||
*
|
||||
|
@ -329,5 +329,27 @@ enum spm_err_t tfm_spm_partition_init(void);
|
|||
* \note This function doesn't check if partition_idx is valid.
|
||||
*/
|
||||
void tfm_spm_partition_cleanup_context(uint32_t partition_idx);
|
||||
#endif /* !defined(TFM_PSA_API) */
|
||||
|
||||
/**
|
||||
* \brief Initialize partition database
|
||||
*
|
||||
* \return Error code \ref spm_err_t
|
||||
*/
|
||||
enum spm_err_t tfm_spm_db_init(void);
|
||||
|
||||
/**
|
||||
* \brief Change the privilege mode for partition thread mode.
|
||||
*
|
||||
* \param[in] privileged Privileged mode,
|
||||
* \ref TFM_PARTITION_PRIVILEGED_MODE
|
||||
* and \ref TFM_PARTITION_UNPRIVILEGED_MODE
|
||||
*
|
||||
* \note Barrier instructions are not called by this function, and if
|
||||
* it is called in thread mode, it might be necessary to call
|
||||
* them after this function returns (just like it is done in
|
||||
* jump_to_ns_code()).
|
||||
*/
|
||||
void tfm_spm_partition_change_privilege(uint32_t privileged);
|
||||
|
||||
#endif /*__SPM_API_H__ */
|
||||
|
|
|
@ -21,8 +21,6 @@ typedef psa_status_t(*sp_init_function)(void);
|
|||
#define TFM_PARTITION_TYPE_APP "APPLICATION-ROT"
|
||||
#define TFM_PARTITION_TYPE_PSA "PSA-ROT"
|
||||
|
||||
#define TFM_STACK_SIZE (1024 * 5)
|
||||
|
||||
#ifdef TFM_PSA_API
|
||||
enum tfm_partition_priority {
|
||||
TFM_PRIORITY_LOW = THRD_PRIOR_LOWEST,
|
||||
|
@ -59,23 +57,22 @@ struct spm_partition_desc_t {
|
|||
struct spm_partition_static_data_t static_data;
|
||||
struct spm_partition_runtime_data_t runtime_data;
|
||||
struct tfm_spm_partition_platform_data_t *platform_data;
|
||||
#if TFM_LVL != 1
|
||||
#if (TFM_LVL != 1) || defined(TFM_PSA_API)
|
||||
struct tfm_spm_partition_memory_data_t memory_data;
|
||||
#endif
|
||||
#ifdef TFM_PSA_API
|
||||
struct tfm_thrd_ctx sp_thrd;
|
||||
/*
|
||||
* stack_limit points to starting address of the partitions' stack plus the partitions' stack size.
|
||||
*/
|
||||
uint32_t stack_limit;
|
||||
uint32_t stack_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Macros to pick linker symbols and allow to form the partition data base */
|
||||
#define REGION(a, b, c) a##b##c
|
||||
#define REGION_NAME(a, b, c) REGION(a, b, c)
|
||||
#if TFM_LVL == 1
|
||||
/* Changed from #if (TFM_LVL == 1) && !defined(TFM_PSA_API) to #if (TFM_LVL == 1) to avoid linker error.
|
||||
TF-M build autogenerates region details (code, ro, rw, zi and stack ) using linker scripts. We do not
|
||||
hve that in mbed-os build yet.
|
||||
*/
|
||||
#if (TFM_LVL == 1)
|
||||
#define REGION_DECLARE(a, b, c)
|
||||
#else
|
||||
#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
|
||||
|
|
|
@ -38,7 +38,11 @@ struct spm_partition_db_t {
|
|||
data.partition_priority = TFM_PRIORITY(priority); \
|
||||
} while (0)
|
||||
|
||||
#if TFM_LVL == 1
|
||||
/* Changed from #if (TFM_LVL == 1) && !defined(TFM_PSA_API) to #if (TFM_LVL == 1) to avoid linker error.
|
||||
TF-M build autogenerates region details (code, ro, rw, zi and stack ) using linker scripts. We do not
|
||||
hve that in mbed-os build yet.
|
||||
*/
|
||||
#if (TFM_LVL == 1)
|
||||
#define PARTITION_INIT_MEMORY_DATA(data, partition)
|
||||
#else
|
||||
#define PARTITION_INIT_MEMORY_DATA(data, partition) \
|
||||
|
@ -56,7 +60,6 @@ struct spm_partition_db_t {
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
#if TFM_LVL == 1
|
||||
#define PARTITION_INIT_RUNTIME_DATA(data, partition) \
|
||||
do { \
|
||||
|
@ -76,60 +79,60 @@ struct spm_partition_db_t {
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
#define PARTITION_DECLARE(partition, flag, type, id, priority, part_stack_size) \
|
||||
do { \
|
||||
REGION_DECLARE(Image$$, partition, $$Base); \
|
||||
REGION_DECLARE(Image$$, partition, $$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, $$RO$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
|
||||
int32_t flags = flag; \
|
||||
if (tfm_memcmp(type, TFM_PARTITION_TYPE_APP, \
|
||||
strlen(TFM_PARTITION_TYPE_APP)) == 0) { \
|
||||
flags |= SPM_PART_FLAG_APP_ROT; \
|
||||
} else if (tfm_memcmp(type, TFM_PARTITION_TYPE_PSA, \
|
||||
strlen(TFM_PARTITION_TYPE_PSA)) == 0) { \
|
||||
flags |= SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT; \
|
||||
} else { \
|
||||
return SPM_ERR_INVALID_CONFIG; \
|
||||
} \
|
||||
struct spm_partition_desc_t *part_ptr; \
|
||||
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
|
||||
return SPM_ERR_INVALID_CONFIG; \
|
||||
} \
|
||||
__attribute__((section(".data.partitions_stacks"))) \
|
||||
static uint8_t partition##_stack[part_stack_size] __attribute__((aligned(8))); \
|
||||
part_ptr = &(g_spm_partition_db.partitions[ \
|
||||
g_spm_partition_db.partition_count]); \
|
||||
part_ptr->stack_limit = (uint32_t)partition##_stack; \
|
||||
part_ptr->stack_size = part_stack_size; \
|
||||
PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags, \
|
||||
id, priority); \
|
||||
PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
|
||||
PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \
|
||||
++g_spm_partition_db.partition_count; \
|
||||
#define PARTITION_DECLARE(partition, flag, type, id, priority, part_stack_size) \
|
||||
do { \
|
||||
REGION_DECLARE(Image$$, partition, $$Base); \
|
||||
REGION_DECLARE(Image$$, partition, $$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, $$RO$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
|
||||
REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
|
||||
REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
|
||||
int32_t flags = flag; \
|
||||
if (tfm_memcmp(type, TFM_PARTITION_TYPE_APP, \
|
||||
strlen(TFM_PARTITION_TYPE_APP)) == 0) { \
|
||||
flags |= SPM_PART_FLAG_APP_ROT; \
|
||||
} else if (tfm_memcmp(type, TFM_PARTITION_TYPE_PSA, \
|
||||
strlen(TFM_PARTITION_TYPE_PSA)) == 0) { \
|
||||
flags |= SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT; \
|
||||
} else { \
|
||||
return SPM_ERR_INVALID_CONFIG; \
|
||||
} \
|
||||
struct spm_partition_desc_t *part_ptr; \
|
||||
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
|
||||
return SPM_ERR_INVALID_CONFIG; \
|
||||
} \
|
||||
__attribute__((section(".data.partitions_stacks"))) \
|
||||
static uint8_t partition##_stack[part_stack_size] __attribute__((aligned(8))); \
|
||||
part_ptr = &(g_spm_partition_db.partitions[ \
|
||||
g_spm_partition_db.partition_count]); \
|
||||
part_ptr->memory_data.stack_bottom = (uint32_t)partition##_stack; \
|
||||
part_ptr->memory_data.stack_top = part_ptr->memory_data.stack_bottom + part_stack_size; \
|
||||
PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags, \
|
||||
id, priority); \
|
||||
PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
|
||||
PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \
|
||||
++g_spm_partition_db.partition_count; \
|
||||
} while (0)
|
||||
|
||||
#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
|
||||
do { \
|
||||
extern int32_t init_func(void); \
|
||||
uint32_t partition_idx = get_partition_idx(partition##_ID); \
|
||||
struct spm_partition_desc_t *part_ptr = \
|
||||
&(g_spm_partition_db.partitions[partition_idx]); \
|
||||
part_ptr->static_data.partition_init = init_func; \
|
||||
#define PARTITION_ADD_INIT_FUNC(partition, init_func) \
|
||||
do { \
|
||||
extern int32_t init_func(void); \
|
||||
uint32_t partition_idx = get_partition_idx(partition##_ID); \
|
||||
struct spm_partition_desc_t *part_ptr = \
|
||||
&(g_spm_partition_db.partitions[partition_idx]); \
|
||||
part_ptr->static_data.partition_init = init_func; \
|
||||
} while (0)
|
||||
|
||||
#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
|
||||
do { \
|
||||
uint32_t partition_idx = get_partition_idx(partition##_ID); \
|
||||
struct spm_partition_desc_t *part_ptr = \
|
||||
&(g_spm_partition_db.partitions[partition_idx]); \
|
||||
part_ptr->platform_data = peripheral; \
|
||||
#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
|
||||
do { \
|
||||
uint32_t partition_idx = get_partition_idx(partition##_ID); \
|
||||
struct spm_partition_desc_t *part_ptr = \
|
||||
&(g_spm_partition_db.partitions[partition_idx]); \
|
||||
part_ptr->platform_data = peripheral; \
|
||||
} while (0)
|
||||
|
||||
#endif /* __SPM_DB_SETUP_H__ */
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
{
|
||||
"src_file": "platform/include/tfm_spm_hal.h",
|
||||
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/platform/include/tfm_spm_hal.h"
|
||||
},
|
||||
{
|
||||
"src_file": "secure_fw/ns_callable/tfm_psa_api_veneers.c",
|
||||
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/ns_callable/tfm_psa_api_veneers.c"
|
||||
}
|
||||
],
|
||||
"folders": [
|
||||
|
@ -64,12 +68,33 @@
|
|||
}
|
||||
],
|
||||
"commit_sha": [
|
||||
"fb068d2cb4e89cacf0e9f413075bb4b211f1484f",
|
||||
"5d41a2aeae71b13f2763bea4e55899646291e0eb",
|
||||
"9c1e080e39adc7211c8c2c12cd652da3dc124299",
|
||||
"78ed87028718b1b926d847ff6fc2f91d44e53d6d",
|
||||
"280715f9b74ab29459d81edaf02b39e7a6acb13c",
|
||||
"ea81bf91c90ae23dd9de012bfd7498613be00601",
|
||||
"5342015bb12a486a1c563175a8a7129f0737c925"
|
||||
{
|
||||
"sha": "11bff3f3cbfbd3e2c284e884d0066531e6b47d7e",
|
||||
"msg": "TF-M patch: General modifications, Remove un-needed files, Disable printf and uart, Modify include paths, Guard macros from mbed_lib with ifndef"
|
||||
},
|
||||
{
|
||||
"sha": "795e6418d0e73841868b351b605659a05c04e1f6",
|
||||
"msg": "TF-M patch: Fix tfm_ns_lock_init issue (TF-M issue #239), Link to bug tracking: https://developer.trustedfirmware.org/T239"
|
||||
},
|
||||
{
|
||||
"sha": "35938a407133fe0c20c25b6fae2836148d1adfca",
|
||||
"msg": "TF-M patch: Fix service handles not cleared issue (TF-M issue #230), Link to bug tracking: https://developer.trustedfirmware.org/T230"
|
||||
},
|
||||
{
|
||||
"sha": "910a402ce6c96b654cb6ae1a5b679e4f856c5419",
|
||||
"msg": "TF-M patch: Fix tfm_psa_call_venner wrong argument type (TF-M issue #241), Link to bug tracking: https://developer.trustedfirmware.org/T241"
|
||||
},
|
||||
{
|
||||
"sha": "cb748c5608cd68a1dbecde5b3b2c1488c3d0d17b",
|
||||
"msg": "TF-M patch: Change #if TFM_PSA_API to #ifdef TFM_PSA_API to avoid compiler errors as mbed-cli only generates "-D" macros only for "macros" defined in targets.json, TF-M task link: https://developer.trustedfirmware.org/T396"
|
||||
},
|
||||
{
|
||||
"sha": "9a5110561a60ec9f663079a25ec54f7ad0832743",
|
||||
"msg": "TF-M patch: Remove secure_fw/core/tfm_func_api.c which is required only when TFM_PSA_API is not set"
|
||||
},
|
||||
{
|
||||
"sha": "6e899b3cc98c3e1811a160df09abbccddb2fa014",
|
||||
"msg": "TF-M patch/workaround related to (TF-M issue #T240), Link to bug tracking: https://developer.trustedfirmware.org/T240, The issue is fixed by TF-M team. However they autogenerate region details (code, ro, rw, zi and stack ) using linker scripts and in mbed-os we also autogenerate region details but using mix of service definition in json file and other template files."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue