Merge pull request #10829 from devran01/feature_trusted-firmware-m_e7efdc6

PSA: TFM import
pull/10838/head
Martin Kojtal 2019-07-01 14:35:54 +01:00 committed by GitHub
commit 1aad06b394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 644 additions and 1357 deletions

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
* *
@ -28,7 +28,7 @@
*/ */
struct tfm_spm_partition_platform_data_t; 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 * \brief Holds SPM db fields that define the memory regions used by a
* partition. * partition.
@ -147,7 +147,7 @@ uint32_t tfm_spm_hal_get_ns_MSP(void);
uint32_t tfm_spm_hal_get_ns_entry_point(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. * \brief Configure the sandbox for a partition.
* *

View File

@ -75,6 +75,16 @@ struct tfm_spm_ipc_partition_t {
*/ */
uint32_t tfm_spm_partition_get_running_partition_id_ext(void); 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 ********************/ /******************** 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); 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] buffer Pointer of memory reference
* \param[in] len Length of memory reference in bytes * \param[in] len Length of memory reference in bytes
* \param[in] ns_caller From non-secure caller * \param[in] ns_caller From non-secure caller
* \param[in] access Type of access specified by the * \param[in] access Type of access specified by the
* \ref tfm_memory_access_e * \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_SUCCESS Success
* \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
* \retval IPC_ERROR_MEMORY_CHECK Check failed * \retval IPC_ERROR_MEMORY_CHECK Check failed
*/ */
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller, 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 */ /* This function should be called before schedule function */
void tfm_spm_init(void); 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 #endif

View File

@ -177,6 +177,19 @@ struct tfm_thrd_ctx *tfm_thrd_curr_thread(void);
*/ */
struct tfm_thrd_ctx *tfm_thrd_next_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. * 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); struct tfm_thrd_ctx *next);
/* /*
* Exit current running thread. * Svcall to exit current running thread.
* *
* Notes : * Notes :
* Remove current thread out of schedulable list. * Remove current thread out of schedulable list.
*/ */
void tfm_thrd_do_exit(void); void tfm_svcall_thrd_exit(void);
/* /*
* PendSV specified function. * Exit current running thread for client.
*
* Parameters :
* ctxb - State context storage pointer
* *
* Notes: * Notes:
* This is a staging API. Scheduler should be called in SPM finally and * Must be called in thread mode.
* this function will be obsoleted later.
*/ */
void tfm_pendsv_do_schedule(struct tfm_state_context_ext *ctxb); void tfm_thrd_exit(void);
#endif #endif

View File

@ -10,7 +10,7 @@
#include "tfm_svc.h" #include "tfm_svc.h"
#include "psa_client.h" #include "psa_client.h"
__attribute__((naked)) __attribute__((naked, section("SFN")))
uint32_t psa_framework_version(void) uint32_t psa_framework_version(void)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"
@ -18,7 +18,7 @@ uint32_t psa_framework_version(void)
: : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION)); : : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
uint32_t psa_version(uint32_t sid) uint32_t psa_version(uint32_t sid)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"
@ -26,7 +26,7 @@ uint32_t psa_version(uint32_t sid)
: : "I" (TFM_SVC_PSA_VERSION)); : : "I" (TFM_SVC_PSA_VERSION));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version) psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
{ {
__ASM volatile("SVC %0 \n" __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)); : : "I" (TFM_SVC_PSA_CONNECT));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
psa_status_t psa_call(psa_handle_t handle, psa_status_t psa_call(psa_handle_t handle,
const psa_invec *in_vec, const psa_invec *in_vec,
size_t in_len, size_t in_len,
@ -46,7 +46,7 @@ psa_status_t psa_call(psa_handle_t handle,
: : "I" (TFM_SVC_PSA_CALL)); : : "I" (TFM_SVC_PSA_CALL));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_close(psa_handle_t handle) void psa_close(psa_handle_t handle)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"

View File

@ -11,7 +11,7 @@
#include "psa_client.h" #include "psa_client.h"
#include "psa_service.h" #include "psa_service.h"
__attribute__((naked)) __attribute__((naked, section("SFN")))
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout) 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)); : : "I" (TFM_SVC_PSA_WAIT));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg) psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
{ {
__ASM volatile("SVC %0 \n" __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)); : : "I" (TFM_SVC_PSA_GET));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle) void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
{ {
__ASM volatile("SVC %0 \n" __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)); : : "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, size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
void *buffer, size_t num_bytes) 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)); : : "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) size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
{ {
__ASM volatile("SVC %0 \n" __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)); : : "I" (TFM_SVC_PSA_SKIP));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
const void *buffer, size_t num_bytes) 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)); : : "I" (TFM_SVC_PSA_WRITE));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_reply(psa_handle_t msg_handle, psa_status_t retval) void psa_reply(psa_handle_t msg_handle, psa_status_t retval)
{ {
__ASM volatile("SVC %0 \n" __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)); : : "I" (TFM_SVC_PSA_REPLY));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_notify(int32_t partition_id) void psa_notify(int32_t partition_id)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"
@ -79,7 +79,7 @@ void psa_notify(int32_t partition_id)
: : "I" (TFM_SVC_PSA_NOTIFY)); : : "I" (TFM_SVC_PSA_NOTIFY));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_clear(void) void psa_clear(void)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"
@ -87,7 +87,7 @@ void psa_clear(void)
: : "I" (TFM_SVC_PSA_CLEAR)); : : "I" (TFM_SVC_PSA_CLEAR));
} }
__attribute__((naked)) __attribute__((naked, section("SFN")))
void psa_eoi(psa_signal_t irq_signal) void psa_eoi(psa_signal_t irq_signal)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"

View File

@ -17,19 +17,10 @@
/* This file contains the ARCH code for ARM V8M */ /* This file contains the ARCH code for ARM V8M */
/* __attribute__((section("SFN")))
* 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.
*/
static void exit_zone(void) static void exit_zone(void)
{ {
tfm_thrd_do_exit(); tfm_thrd_exit();
} }
void tfm_initialize_context(struct tfm_state_context *ctx, void tfm_initialize_context(struct tfm_state_context *ctx,

View File

@ -38,6 +38,8 @@ static struct tfm_spm_ipc_partition_t
/* Extern SPM variable */ /* Extern SPM variable */
extern struct spm_partition_db_t g_spm_partition_db; extern struct spm_partition_db_t g_spm_partition_db;
/* Extern secure lock variable */
extern int32_t tfm_secure_lock;
/* Pools */ /* Pools */
TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t), TFM_POOL_DECLARE(conn_handle_pool, sizeof(struct tfm_conn_handle_t),
TFM_CONN_HANDLE_MAX_NUM); 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; 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 static tfm_thrd_func_t
tfm_spm_partition_get_init_func_ext(uint32_t partition_idx) 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; 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, 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; 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) { 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 { } 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_SUCCESS;
} }
return IPC_ERROR_MEMORY_CHECK; 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 ************************/ /********************** SPM functions for thread mode ************************/
void tfm_spm_init(void) void tfm_spm_init(void)
@ -499,7 +497,8 @@ void tfm_spm_init(void)
uint32_t i, num; uint32_t i, num;
struct tfm_spm_ipc_partition_t *partition; struct tfm_spm_ipc_partition_t *partition;
struct tfm_spm_service_t *service; 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, tfm_pool_init(conn_handle_pool,
POOL_BUFFER_SIZE(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 */ /* Init partition first for it will be used when init service */
for (i = 0; i < SPM_MAX_PARTITIONS; i++) { 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) { if ((tfm_spm_partition_get_flags(i) & SPM_PART_FLAG_IPC) == 0) {
continue; continue;
} }
g_spm_ipc_partition[i].index = i;
g_spm_ipc_partition[i].id = tfm_spm_partition_get_partition_id(i); g_spm_ipc_partition[i].id = tfm_spm_partition_get_partition_id(i);
tfm_event_init(&g_spm_ipc_partition[i].signal_evnt); tfm_event_init(&g_spm_ipc_partition[i].signal_evnt);
@ -531,8 +532,9 @@ void tfm_spm_init(void)
tfm_thrd_init(pth, tfm_thrd_init(pth,
tfm_spm_partition_get_init_func_ext(i), tfm_spm_partition_get_init_func_ext(i),
NULL, NULL,
(uint8_t *)tfm_spm_partition_get_stack_base_ext(i), (uint8_t *)tfm_spm_partition_get_stack_top(i),
(uint8_t *)tfm_spm_partition_get_stack_limit_ext(i)); (uint8_t *)tfm_spm_partition_get_stack_bottom(i));
pth->prior = tfm_spm_partition_get_priority_ext(i); pth->prior = tfm_spm_partition_get_priority_ext(i);
/* Kick off */ /* Kick off */
@ -559,6 +561,58 @@ void tfm_spm_init(void)
tfm_list_add_tail(&partition->service_list, &service->list); 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);
}
} }

View File

@ -21,6 +21,7 @@
#include "tfm_api.h" #include "tfm_api.h"
#include "tfm_secure_api.h" #include "tfm_secure_api.h"
#include "tfm_memory_utils.h" #include "tfm_memory_utils.h"
#include "spm_api.h"
#define PSA_TIMEOUT_MASK PSA_BLOCK #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_spm_service_t *service;
struct tfm_msg_body_t *msg; struct tfm_msg_body_t *msg;
int i; int i;
struct tfm_spm_ipc_partition_t *partition = NULL;
uint32_t privileged;
TFM_ASSERT(args != NULL); TFM_ASSERT(args != NULL);
handle = (psa_handle_t)args[0]; 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) { if (!ns_caller) {
inptr = (psa_invec *)args[1]; inptr = (psa_invec *)args[1];
in_num = (size_t)args[2]; 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. * memory reference for buffer is invalid or not readable.
*/ */
if (tfm_memory_check((void *)args[1], sizeof(uint32_t), 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(); tfm_panic();
} }
if (tfm_memory_check((void *)args[2], sizeof(uint32_t), 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(); tfm_panic();
} }
@ -185,7 +195,7 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
* readable. * readable.
*/ */
if (tfm_memory_check((void *)inptr, in_num * sizeof(psa_invec), 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(); 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. * the wrap output vector is invalid or not read-write.
*/ */
if (tfm_memory_check((void *)outptr, out_num * sizeof(psa_outvec), 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(); 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++) { for (i = 0; i < in_num; i++) {
if (tfm_memory_check((void *)invecs[i].base, invecs[i].len, 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(); 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++) { for (i = 0; i < out_num; i++) {
if (tfm_memory_check(outvecs[i].base, outvecs[i].len, 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(); 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_spm_service_t *service = NULL;
struct tfm_msg_body_t *tmp_msg = NULL; struct tfm_msg_body_t *tmp_msg = NULL;
struct tfm_spm_ipc_partition_t *partition = NULL; struct tfm_spm_ipc_partition_t *partition = NULL;
uint32_t privileged;
TFM_ASSERT(args != NULL); TFM_ASSERT(args != NULL);
signal = (psa_signal_t)args[0]; signal = (psa_signal_t)args[0];
@ -376,17 +387,18 @@ static psa_status_t tfm_svcall_psa_get(uint32_t *args)
tfm_panic(); 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 * 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. * input msg pointer is not a valid memory reference or not read-write.
*/ */
if (tfm_memory_check((void *)msg, sizeof(psa_msg_t), if (tfm_memory_check((void *)msg, sizeof(psa_msg_t),
false, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) { false, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
tfm_panic();
}
partition = tfm_spm_get_running_partition();
if (!partition) {
tfm_panic(); tfm_panic();
} }
@ -499,6 +511,8 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
size_t num_bytes; size_t num_bytes;
size_t bytes; size_t bytes;
struct tfm_msg_body_t *msg = NULL; struct tfm_msg_body_t *msg = NULL;
uint32_t privileged;
struct tfm_spm_ipc_partition_t *partition = NULL;
TFM_ASSERT(args != NULL); TFM_ASSERT(args != NULL);
msg_handle = (psa_handle_t)args[0]; msg_handle = (psa_handle_t)args[0];
@ -512,6 +526,9 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
tfm_panic(); 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 * It is a fatal error if message handle does not refer to a PSA_IPC_CALL
* message * 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 the memory reference for buffer is invalid or not read-write.
*/ */
if (tfm_memory_check(buffer, num_bytes, false, if (tfm_memory_check(buffer, num_bytes, false,
TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) { TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
tfm_panic(); tfm_panic();
} }
@ -650,6 +667,8 @@ static void tfm_svcall_psa_write(uint32_t *args)
void *buffer = NULL; void *buffer = NULL;
size_t num_bytes; size_t num_bytes;
struct tfm_msg_body_t *msg = NULL; struct tfm_msg_body_t *msg = NULL;
uint32_t privileged;
struct tfm_spm_ipc_partition_t *partition = NULL;
TFM_ASSERT(args != NULL); TFM_ASSERT(args != NULL);
msg_handle = (psa_handle_t)args[0]; msg_handle = (psa_handle_t)args[0];
@ -663,6 +682,9 @@ static void tfm_svcall_psa_write(uint32_t *args)
tfm_panic(); 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 * It is a fatal error if message handle does not refer to a PSA_IPC_CALL
* message * 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 the memory reference for buffer is invalid or not readable.
*/ */
if (tfm_memory_check(buffer, num_bytes, false, if (tfm_memory_check(buffer, num_bytes, false,
TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) { TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
tfm_panic(); 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: case TFM_SVC_SCHEDULE:
tfm_thrd_activate_schedule(); tfm_thrd_activate_schedule();
break; break;
case TFM_SVC_EXIT_THRD:
tfm_svcall_thrd_exit();
break;
case TFM_SVC_PSA_FRAMEWORK_VERSION: case TFM_SVC_PSA_FRAMEWORK_VERSION:
return tfm_svcall_psa_framework_version(); return tfm_svcall_psa_framework_version();
case TFM_SVC_PSA_VERSION: case TFM_SVC_PSA_VERSION:

View File

@ -10,6 +10,8 @@
#include "tfm_thread.h" #include "tfm_thread.h"
#include "tfm_utils.h" #include "tfm_utils.h"
#include "tfm_memory_utils.h" #include "tfm_memory_utils.h"
#include "tfm_svc.h"
#include "spm_api.h"
/* Force ZERO in case ZI(bss) clear is missing */ /* Force ZERO in case ZI(bss) clear is missing */
static struct tfm_thrd_ctx *p_thrd_head = NULL; 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); 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 */ /* Scheduling won't happen immediately but after the exception returns */
void tfm_thrd_activate_schedule(void) 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(); 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 */ /* 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; CURR_THRD->status = THRD_STAT_DETACH;
tfm_trigger_pendsv(); 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, void tfm_thrd_context_switch(struct tfm_state_context_ext *ctxb,
struct tfm_thrd_ctx *prev, struct tfm_thrd_ctx *prev,
struct tfm_thrd_ctx *next) 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)); 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)); 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; 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);
}
}

View File

@ -12,6 +12,15 @@
#include "tfm_api.h" #include "tfm_api.h"
#include "flash_layout.h" #include "flash_layout.h"
#include "secure_fw/spm/spm_api.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 * \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]; uint8_t *buf_start = (uint8_t *)args[1];
uint16_t buf_size = (uint16_t)args[2]; uint16_t buf_size = (uint16_t)args[2];
uint8_t *ptr; uint8_t *ptr;
uint32_t running_partition_idx =
tfm_spm_partition_get_running_partition_idx();
struct tfm_boot_data *boot_data; struct tfm_boot_data *boot_data;
struct shared_data_tlv_entry tlv_entry; struct shared_data_tlv_entry tlv_entry;
uintptr_t tlv_end, offset; uintptr_t tlv_end, offset;
#ifndef TFM_PSA_API
uint32_t running_partition_idx =
tfm_spm_partition_get_running_partition_idx();
uint32_t res; 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 /* Make sure that the output pointer points to a memory area that is owned
* by the partition * by the partition
*/ */
@ -79,6 +94,20 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
args[0] = TFM_ERROR_INVALID_PARAMETER; args[0] = TFM_ERROR_INVALID_PARAMETER;
return; 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 */ /* FixMe: Check whether caller has access right to given tlv_major_type */

View File

@ -47,6 +47,7 @@ __asm(" .global __ARM_use_no_argv\n");
#error Only TFM_LVL 1, 2 and 3 are supported! #error Only TFM_LVL 1, 2 and 3 are supported!
#endif #endif
#ifndef TFM_PSA_API
/* Macros to pick linker symbols and allow to form the partition data base */ /* Macros to pick linker symbols and allow to form the partition data base */
#define REGION(a, b, c) a##b##c #define REGION(a, b, c) a##b##c
#define REGION_NAME(a, b, c) REGION(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$$Base);
REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit); REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
#endif
void configure_ns_code(void) void configure_ns_code(void)
{ {
@ -106,11 +108,20 @@ int32_t tfm_core_init(void)
/* Enable secure peripherals interrupts */ /* Enable secure peripherals interrupts */
nvic_interrupt_enable(); 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 = tfm_scratch_area =
(uint8_t *)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); (uint8_t *)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
tfm_scratch_area_size = tfm_scratch_area_size =
(uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit) - (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit) -
(uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base); (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
#endif
return 0; return 0;
} }
@ -179,6 +190,7 @@ int main(void)
tfm_spm_hal_setup_isolation_hw(); tfm_spm_hal_setup_isolation_hw();
#ifndef TFM_PSA_API
tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_RUNNING); tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_RUNNING);
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[]; extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
@ -198,21 +210,25 @@ int main(void)
*/ */
tfm_core_set_secure_exception_priorities(); tfm_core_set_secure_exception_priorities();
#ifdef TFM_PSA_API /* We close the TFM_SP_CORE_ID partition, because its only purpose is
tfm_spm_init(); * to be able to pass the state checks for the tests started from secure.
#endif */
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 #ifdef TFM_CORE_DEBUG
/* Jumps to non-secure code */ /* Jumps to non-secure code */
LOG_MSG("Jumping to non-secure code..."); LOG_MSG("Jumping to non-secure code...");
#endif #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(); 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
} }

View File

@ -156,6 +156,30 @@ uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr)
return lr; return lr;
} }
switch (svc_number) { 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: case TFM_SVC_SFN_REQUEST:
lr = tfm_core_partition_request_svc_handler(svc_args, lr); lr = tfm_core_partition_request_svc_handler(svc_args, lr);
break; break;
@ -177,10 +201,6 @@ uint32_t SVCHandler_main(uint32_t *svc_args, uint32_t lr)
case TFM_SVC_SET_SHARE_AREA: case TFM_SVC_SET_SHARE_AREA:
tfm_core_set_buffer_area_handler(svc_args); tfm_core_set_buffer_area_handler(svc_args);
break; break;
#ifdef TFM_PSA_API
case TFM_SVC_IPC_REQUEST:
tfm_psa_ipc_request_handler(svc_args);
break;
#endif #endif
case TFM_SVC_PRINT: case TFM_SVC_PRINT:
printf("\e[1;34m[Sec Thread] %s\e[0m\r\n", (char *)svc_args[0]); 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: case TFM_SVC_GET_BOOT_DATA:
tfm_core_get_boot_data_handler(svc_args); tfm_core_get_boot_data_handler(svc_args);
break; 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: default:
LOG_MSG("Unknown SVC number requested!"); LOG_MSG("Unknown SVC number requested!");
break; break;

View File

@ -6,8 +6,13 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "secure_utilities.h" #include "secure_utilities.h"
#include "tfm_api.h" #include "tfm_api.h"
#ifdef TFM_PSA_API
#include "tfm_utils.h"
#include "tfm_internal.h"
#endif
#ifndef TFM_MAX_NS_THREAD_COUNT #ifndef TFM_MAX_NS_THREAD_COUNT
#define TFM_MAX_NS_THREAD_COUNT 8 #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; return TFM_SUCCESS;
} }
#endif #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

View File

@ -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 * 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); 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__ */ #endif /* __TFM_NSPM_H__ */

View File

@ -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 * This function assumes, that the current MPU configuration is set for the
* partition to be checked. * partition to be checked.
* *
* \param[in] p The start address of the range to check * \param[in] p The start address of the range to check
* \param[in] s The size 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] 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, 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 * \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 * This function assumes, that the current MPU configuration is set for the
* partition to be checked. * partition to be checked.
* *
* \param[in] p The start address of the range to check * \param[in] p The start address of the range to check
* \param[in] s The size 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] 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, 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) \ #define TFM_CORE_IOVEC_SFN_REQUEST(id, fn, a, b, c, d) \
return tfm_core_partition_request(id, fn, TFM_SFN_API_IOVEC, \ return tfm_core_partition_request(id, fn, TFM_SFN_API_IOVEC, \
(int32_t)a, (int32_t)b, (int32_t)c, (int32_t)d) (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; struct tfm_sfn_req_s desc, *desc_ptr = &desc;
desc.sp_id = id; desc.sp_id = id;
desc.sfn = fn; desc.sfn = (sfn_t) fn;
desc.args = args; desc.args = args;
/* /*
* This preprocessor condition checks if a version of GCC smaller than * 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__ */ #endif /* __TFM_SECURE_API_H__ */

View File

@ -11,6 +11,7 @@
#include "tfm_secure_api.h" #include "tfm_secure_api.h"
#include "tfm_internal.h" #include "tfm_internal.h"
#include "secure_fw/include/tfm_spm_services_api.h" #include "secure_fw/include/tfm_spm_services_api.h"
#include "spm_api.h"
uint8_t *tfm_scratch_area; uint8_t *tfm_scratch_area;
uint32_t tfm_scratch_area_size; uint32_t tfm_scratch_area_size;
@ -18,13 +19,9 @@ nsfptr_t ns_entry;
void jump_to_ns_code(void) 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. */ /* Initialization is done, set thread mode to unprivileged. */
CONTROL_Type ctrl; tfm_spm_partition_change_privilege(TFM_PARTITION_UNPRIVILEGED_MODE);
ctrl.w = __get_CONTROL();
ctrl.b.nPRIV = 1;
__set_CONTROL(ctrl.w);
#endif #endif
/* All changes made to memory will be effective after this point */ /* All changes made to memory will be effective after this point */
__DSB(); __DSB();
@ -34,6 +31,7 @@ void jump_to_ns_code(void)
ns_entry(); ns_entry();
} }
#ifndef TFM_PSA_API
#if defined(__ARM_ARCH_8M_MAIN__) #if defined(__ARM_ARCH_8M_MAIN__)
__attribute__((naked)) int32_t tfm_core_sfn_request( __attribute__((naked)) int32_t tfm_core_sfn_request(
const struct tfm_sfn_req_s *desc_ptr) 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" "BX lr\n"
: : "I" (TFM_SVC_SET_SHARE_AREA)); : : "I" (TFM_SVC_SET_SHARE_AREA));
} }
#endif
__attribute__((naked)) __attribute__((naked))
int32_t tfm_core_get_boot_data(uint8_t major_type, int32_t tfm_core_get_boot_data(uint8_t major_type,

View File

@ -23,6 +23,7 @@ typedef enum {
#ifdef TFM_PSA_API #ifdef TFM_PSA_API
TFM_SVC_IPC_REQUEST, TFM_SVC_IPC_REQUEST,
TFM_SVC_SCHEDULE, TFM_SVC_SCHEDULE,
TFM_SVC_EXIT_THRD,
/* PSA Client SVC */ /* PSA Client SVC */
TFM_SVC_PSA_FRAMEWORK_VERSION, TFM_SVC_PSA_FRAMEWORK_VERSION,
TFM_SVC_PSA_VERSION, TFM_SVC_PSA_VERSION,

View File

@ -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, \ return tfm_core_ns_ipc_request(fn, (int32_t)a, (int32_t)b, \
(int32_t)c, (int32_t)d) (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) static int32_t tfm_core_ipc_request(const struct tfm_sfn_req_s *desc_ptr)
{ {
__ASM volatile("SVC %0 \n" __ASM volatile("SVC %0 \n"

View File

@ -32,6 +32,7 @@ typedef enum {
* In case of an error in the error handling, a non-zero value have to be * In case of an error in the error handling, a non-zero value have to be
* returned. * returned.
*/ */
#ifndef TFM_PSA_API
static void tfm_spm_partition_err_handler( static void tfm_spm_partition_err_handler(
const struct spm_partition_desc_t *partition, const struct spm_partition_desc_t *partition,
sp_error_type_t err_type, 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, tfm_spm_partition_set_state(partition->static_data.partition_id,
SPM_PARTITION_STATE_CLOSED); SPM_PARTITION_STATE_CLOSED);
} }
#endif /* !defined(TFM_PSA_API) */
/* /*
* This function prevents name clashes between the variable names accessibles in * 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 */ /* 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$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[]; 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_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
uint32_t psp_stack_top = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit; uint32_t psp_stack_top = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit;
#endif
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
return SPM_ERR_INVALID_CONFIG; return SPM_ERR_INVALID_CONFIG;
} }
part_ptr = &(g_spm_partition_db.partitions[ part_ptr = &(g_spm_partition_db.partitions[
g_spm_partition_db.partition_count]); g_spm_partition_db.partition_count]);
part_ptr->static_data.partition_id = TFM_SP_NON_SECURE_ID; 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; 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_bottom = psp_stack_bottom;
part_ptr->memory_data.stack_top = psp_stack_top; part_ptr->memory_data.stack_top = psp_stack_top;
/* Since RW, ZI and stack are configured as one MPU region, configure /* 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 * RW start address to psp_stack_bottom to get RW access to stack
*/ */
part_ptr->memory_data.rw_start = psp_stack_bottom; 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 #endif
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT; 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; return SPM_ERR_OK;
} }
#ifndef TFM_PSA_API
enum spm_err_t tfm_spm_partition_init(void) enum spm_err_t tfm_spm_partition_init(void)
{ {
struct spm_partition_desc_t *part; 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) { for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
part = &g_spm_partition_db.partitions[idx]; part = &g_spm_partition_db.partitions[idx];
tfm_spm_hal_configure_default_isolation(part->platform_data); 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) { if (part->static_data.partition_init == NULL) {
tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE); tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
tfm_spm_partition_set_caller_partition_idx(idx, 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; 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) enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
{ {
struct spm_partition_desc_t *part; 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); 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) uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx)
{ {
return g_spm_partition_db.partitions[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 #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) uint32_t tfm_spm_partition_get_partition_id(uint32_t partition_idx)
{ {
return g_spm_partition_db.partitions[partition_idx].static_data. 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; 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 * const struct spm_partition_runtime_data_t *
tfm_spm_partition_get_runtime_data(uint32_t partition_idx) 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.orig_outvec = 0;
partition->runtime_data.iovec_api = 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);
}

View File

@ -15,6 +15,10 @@
#define SPM_INVALID_PARTITION_IDX (~0U) #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 { enum spm_err_t {
SPM_ERR_OK = 0, SPM_ERR_OK = 0,
SPM_ERR_PARTITION_DB_NOT_INIT, 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); uint32_t get_partition_idx(uint32_t partition_id);
#if TFM_LVL != 1 #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 bottom of stack region for a partition * \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. * \note This function doesn't check if partition_idx is valid.
*/ */
uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx); 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 * \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); void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr);
#endif #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 * \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); uint32_t tfm_spm_partition_get_flags(uint32_t partition_idx);
#ifndef TFM_PSA_API
/** /**
* \brief Get the current runtime data of a partition * \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, void tfm_spm_partition_store_context(uint32_t partition_idx,
uint32_t stack_ptr, uint32_t lr); 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 * \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, enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
const int32_t *args); 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 * \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. * \note This function doesn't check if partition_idx is valid.
*/ */
void tfm_spm_partition_cleanup_context(uint32_t partition_idx); 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__ */ #endif /*__SPM_API_H__ */

View File

@ -21,8 +21,6 @@ typedef psa_status_t(*sp_init_function)(void);
#define TFM_PARTITION_TYPE_APP "APPLICATION-ROT" #define TFM_PARTITION_TYPE_APP "APPLICATION-ROT"
#define TFM_PARTITION_TYPE_PSA "PSA-ROT" #define TFM_PARTITION_TYPE_PSA "PSA-ROT"
#define TFM_STACK_SIZE (1024 * 5)
#ifdef TFM_PSA_API #ifdef TFM_PSA_API
enum tfm_partition_priority { enum tfm_partition_priority {
TFM_PRIORITY_LOW = THRD_PRIOR_LOWEST, 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_static_data_t static_data;
struct spm_partition_runtime_data_t runtime_data; struct spm_partition_runtime_data_t runtime_data;
struct tfm_spm_partition_platform_data_t *platform_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; struct tfm_spm_partition_memory_data_t memory_data;
#endif #endif
#ifdef TFM_PSA_API #ifdef TFM_PSA_API
struct tfm_thrd_ctx sp_thrd; 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 #endif
}; };
/* Macros to pick linker symbols and allow to form the partition data base */ /* Macros to pick linker symbols and allow to form the partition data base */
#define REGION(a, b, c) a##b##c #define REGION(a, b, c) a##b##c
#define REGION_NAME(a, b, c) REGION(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) #define REGION_DECLARE(a, b, c)
#else #else
#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c) #define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)

View File

@ -38,7 +38,11 @@ struct spm_partition_db_t {
data.partition_priority = TFM_PRIORITY(priority); \ data.partition_priority = TFM_PRIORITY(priority); \
} while (0) } 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) #define PARTITION_INIT_MEMORY_DATA(data, partition)
#else #else
#define PARTITION_INIT_MEMORY_DATA(data, partition) \ #define PARTITION_INIT_MEMORY_DATA(data, partition) \
@ -56,7 +60,6 @@ struct spm_partition_db_t {
} while (0) } while (0)
#endif #endif
#if TFM_LVL == 1 #if TFM_LVL == 1
#define PARTITION_INIT_RUNTIME_DATA(data, partition) \ #define PARTITION_INIT_RUNTIME_DATA(data, partition) \
do { \ do { \
@ -76,60 +79,60 @@ struct spm_partition_db_t {
} while (0) } while (0)
#endif #endif
#define PARTITION_DECLARE(partition, flag, type, id, priority, part_stack_size) \ #define PARTITION_DECLARE(partition, flag, type, id, priority, part_stack_size) \
do { \ do { \
REGION_DECLARE(Image$$, partition, $$Base); \ REGION_DECLARE(Image$$, partition, $$Base); \
REGION_DECLARE(Image$$, partition, $$Limit); \ REGION_DECLARE(Image$$, partition, $$Limit); \
REGION_DECLARE(Image$$, partition, $$RO$$Base); \ REGION_DECLARE(Image$$, partition, $$RO$$Base); \
REGION_DECLARE(Image$$, partition, $$RO$$Limit); \ REGION_DECLARE(Image$$, partition, $$RO$$Limit); \
REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \ REGION_DECLARE(Image$$, partition, _DATA$$RW$$Base); \
REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \ REGION_DECLARE(Image$$, partition, _DATA$$RW$$Limit); \
REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \ REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Base); \
REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \ REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit); \
REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \ REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base); \
REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \ REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit); \
int32_t flags = flag; \ int32_t flags = flag; \
if (tfm_memcmp(type, TFM_PARTITION_TYPE_APP, \ if (tfm_memcmp(type, TFM_PARTITION_TYPE_APP, \
strlen(TFM_PARTITION_TYPE_APP)) == 0) { \ strlen(TFM_PARTITION_TYPE_APP)) == 0) { \
flags |= SPM_PART_FLAG_APP_ROT; \ flags |= SPM_PART_FLAG_APP_ROT; \
} else if (tfm_memcmp(type, TFM_PARTITION_TYPE_PSA, \ } else if (tfm_memcmp(type, TFM_PARTITION_TYPE_PSA, \
strlen(TFM_PARTITION_TYPE_PSA)) == 0) { \ strlen(TFM_PARTITION_TYPE_PSA)) == 0) { \
flags |= SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT; \ flags |= SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT; \
} else { \ } else { \
return SPM_ERR_INVALID_CONFIG; \ return SPM_ERR_INVALID_CONFIG; \
} \ } \
struct spm_partition_desc_t *part_ptr; \ struct spm_partition_desc_t *part_ptr; \
if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \ if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) { \
return SPM_ERR_INVALID_CONFIG; \ return SPM_ERR_INVALID_CONFIG; \
} \ } \
__attribute__((section(".data.partitions_stacks"))) \ __attribute__((section(".data.partitions_stacks"))) \
static uint8_t partition##_stack[part_stack_size] __attribute__((aligned(8))); \ static uint8_t partition##_stack[part_stack_size] __attribute__((aligned(8))); \
part_ptr = &(g_spm_partition_db.partitions[ \ part_ptr = &(g_spm_partition_db.partitions[ \
g_spm_partition_db.partition_count]); \ g_spm_partition_db.partition_count]); \
part_ptr->stack_limit = (uint32_t)partition##_stack; \ part_ptr->memory_data.stack_bottom = (uint32_t)partition##_stack; \
part_ptr->stack_size = part_stack_size; \ 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, \ PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags, \
id, priority); \ id, priority); \
PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \ PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition); \
PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \ PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition); \
++g_spm_partition_db.partition_count; \ ++g_spm_partition_db.partition_count; \
} while (0) } while (0)
#define PARTITION_ADD_INIT_FUNC(partition, init_func) \ #define PARTITION_ADD_INIT_FUNC(partition, init_func) \
do { \ do { \
extern int32_t init_func(void); \ extern int32_t init_func(void); \
uint32_t partition_idx = get_partition_idx(partition##_ID); \ uint32_t partition_idx = get_partition_idx(partition##_ID); \
struct spm_partition_desc_t *part_ptr = \ struct spm_partition_desc_t *part_ptr = \
&(g_spm_partition_db.partitions[partition_idx]); \ &(g_spm_partition_db.partitions[partition_idx]); \
part_ptr->static_data.partition_init = init_func; \ part_ptr->static_data.partition_init = init_func; \
} while (0) } while (0)
#define PARTITION_ADD_PERIPHERAL(partition, peripheral) \ #define PARTITION_ADD_PERIPHERAL(partition, peripheral) \
do { \ do { \
uint32_t partition_idx = get_partition_idx(partition##_ID); \ uint32_t partition_idx = get_partition_idx(partition##_ID); \
struct spm_partition_desc_t *part_ptr = \ struct spm_partition_desc_t *part_ptr = \
&(g_spm_partition_db.partitions[partition_idx]); \ &(g_spm_partition_db.partitions[partition_idx]); \
part_ptr->platform_data = peripheral; \ part_ptr->platform_data = peripheral; \
} while (0) } while (0)
#endif /* __SPM_DB_SETUP_H__ */ #endif /* __SPM_DB_SETUP_H__ */

View File

@ -35,6 +35,10 @@
{ {
"src_file": "platform/include/tfm_spm_hal.h", "src_file": "platform/include/tfm_spm_hal.h",
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/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": [ "folders": [
@ -64,12 +68,33 @@
} }
], ],
"commit_sha": [ "commit_sha": [
"fb068d2cb4e89cacf0e9f413075bb4b211f1484f", {
"5d41a2aeae71b13f2763bea4e55899646291e0eb", "sha": "11bff3f3cbfbd3e2c284e884d0066531e6b47d7e",
"9c1e080e39adc7211c8c2c12cd652da3dc124299", "msg": "TF-M patch: General modifications, Remove un-needed files, Disable printf and uart, Modify include paths, Guard macros from mbed_lib with ifndef"
"78ed87028718b1b926d847ff6fc2f91d44e53d6d", },
"280715f9b74ab29459d81edaf02b39e7a6acb13c", {
"ea81bf91c90ae23dd9de012bfd7498613be00601", "sha": "795e6418d0e73841868b351b605659a05c04e1f6",
"5342015bb12a486a1c563175a8a7129f0737c925" "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."
}
] ]
} }