mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #10502 from kfnta/feature_trusted-firmware-m_f2dea5b
PSA: TFM importpull/10512/head
commit
47205bfd02
|
@ -54,11 +54,15 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TFM request protected by NS lock */
|
/* TFM request protected by NS lock */
|
||||||
osMutexAcquire(ns_lock.id,osWaitForever);
|
if (osMutexAcquire(ns_lock.id,osWaitForever) != osOK) {
|
||||||
|
return TFM_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
result = fn(arg0, arg1, arg2, arg3);
|
result = fn(arg0, arg1, arg2, arg3);
|
||||||
|
|
||||||
osMutexRelease(ns_lock.id);
|
if (osMutexRelease(ns_lock.id) != osOK) {
|
||||||
|
return TFM_ERROR_GENERIC;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +70,7 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
|
||||||
/**
|
/**
|
||||||
* \brief NS world, Init NS lock
|
* \brief NS world, Init NS lock
|
||||||
*/
|
*/
|
||||||
uint32_t tfm_ns_lock_init()
|
enum tfm_status_e tfm_ns_lock_init()
|
||||||
{
|
{
|
||||||
if (ns_lock.init == false) {
|
if (ns_lock.init == false) {
|
||||||
ns_lock.id = osMutexNew(&ns_lock_attrib);
|
ns_lock.id = osMutexNew(&ns_lock_attrib);
|
||||||
|
|
|
@ -197,6 +197,16 @@ struct shared_data_tlv_entry {
|
||||||
uint16_t tlv_len; /* size of single TLV entry (including this header). */
|
uint16_t tlv_len; /* size of single TLV entry (including this header). */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \struct tfm_boot_data
|
||||||
|
*
|
||||||
|
* \brief Store the data for the runtime SW
|
||||||
|
*/
|
||||||
|
struct tfm_boot_data {
|
||||||
|
struct shared_data_tlv_header header;
|
||||||
|
uint8_t data[];
|
||||||
|
};
|
||||||
|
|
||||||
#define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry)
|
#define SHARED_DATA_ENTRY_HEADER_SIZE sizeof(struct shared_data_tlv_entry)
|
||||||
#define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)
|
#define SHARED_DATA_ENTRY_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "tfm_list.h"
|
#include "tfm_list.h"
|
||||||
|
#include "tfm_secure_api.h"
|
||||||
|
|
||||||
#ifndef TFM_SPM_MAX_ROT_SERV_NUM
|
#ifndef TFM_SPM_MAX_ROT_SERV_NUM
|
||||||
#define TFM_SPM_MAX_ROT_SERV_NUM 28
|
#define TFM_SPM_MAX_ROT_SERV_NUM 28
|
||||||
|
@ -283,12 +284,15 @@ int32_t tfm_spm_check_client_version(struct tfm_spm_service_t *service,
|
||||||
* \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
|
||||||
|
* \ref tfm_memory_access_e
|
||||||
*
|
*
|
||||||
* \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);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
|
@ -13,25 +13,25 @@
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
uint32_t psa_framework_version(void)
|
uint32_t psa_framework_version(void)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
|
: : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
uint32_t psa_version(uint32_t sid)
|
uint32_t psa_version(uint32_t sid)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_VERSION));
|
: : "I" (TFM_SVC_PSA_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
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("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_CONNECT));
|
: : "I" (TFM_SVC_PSA_CONNECT));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
|
@ -41,15 +41,15 @@ psa_status_t psa_call(psa_handle_t handle,
|
||||||
psa_outvec *out_vec,
|
psa_outvec *out_vec,
|
||||||
size_t out_len)
|
size_t out_len)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_CALL));
|
: : "I" (TFM_SVC_PSA_CALL));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
void psa_close(psa_handle_t handle)
|
void psa_close(psa_handle_t handle)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_CLOSE));
|
: : "I" (TFM_SVC_PSA_CLOSE));
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,25 +15,25 @@ __attribute__((naked))
|
||||||
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)
|
||||||
|
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_WAIT));
|
: : "I" (TFM_SVC_PSA_WAIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
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("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_GET));
|
: : "I" (TFM_SVC_PSA_GET));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
|
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_SET_RHANDLE));
|
: : "I" (TFM_SVC_PSA_SET_RHANDLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
|
@ -41,56 +41,56 @@ 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)
|
||||||
|
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_READ));
|
: : "I" (TFM_SVC_PSA_READ));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
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("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_SKIP));
|
: : "I" (TFM_SVC_PSA_SKIP));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
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)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_WRITE));
|
: : "I" (TFM_SVC_PSA_WRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
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("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_REPLY));
|
: : "I" (TFM_SVC_PSA_REPLY));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
void psa_notify(int32_t partition_id)
|
void psa_notify(int32_t partition_id)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_NOTIFY));
|
: : "I" (TFM_SVC_PSA_NOTIFY));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
void psa_clear(void)
|
void psa_clear(void)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_CLEAR));
|
: : "I" (TFM_SVC_PSA_CLEAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
void psa_eoi(psa_signal_t irq_signal)
|
void psa_eoi(psa_signal_t irq_signal)
|
||||||
{
|
{
|
||||||
__ASM("SVC %0 \n"
|
__ASM volatile("SVC %0 \n"
|
||||||
"BX LR \n"
|
"BX LR \n"
|
||||||
: : "I" (TFM_SVC_PSA_EOI));
|
: : "I" (TFM_SVC_PSA_EOI));
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ void tfm_initialize_context(struct tfm_state_context *ctx,
|
||||||
#if defined(__ARM_ARCH_8M_MAIN__)
|
#if defined(__ARM_ARCH_8M_MAIN__)
|
||||||
__attribute__((naked)) void PendSV_Handler(void)
|
__attribute__((naked)) void PendSV_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"mrs r0, psp \n"
|
"mrs r0, psp \n"
|
||||||
"mrs r1, psplim \n"
|
"mrs r1, psplim \n"
|
||||||
"push {r0, r1, r2, lr} \n"
|
"push {r0, r1, r2, lr} \n"
|
||||||
|
@ -111,7 +111,7 @@ __attribute__((naked)) void PendSV_Handler(void)
|
||||||
#elif defined(__ARM_ARCH_8M_BASE__)
|
#elif defined(__ARM_ARCH_8M_BASE__)
|
||||||
__attribute__((naked)) void PendSV_Handler(void)
|
__attribute__((naked)) void PendSV_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"mrs r0, psp \n"
|
"mrs r0, psp \n"
|
||||||
"mrs r1, psplim \n"
|
"mrs r1, psplim \n"
|
||||||
"push {r0, r1, r2, lr} \n"
|
"push {r0, r1, r2, lr} \n"
|
||||||
|
@ -143,14 +143,14 @@ __attribute__((naked)) void PendSV_Handler(void)
|
||||||
/* Reserved for future usage */
|
/* Reserved for future usage */
|
||||||
__attribute__((naked)) void MemManage_Handler(void)
|
__attribute__((naked)) void MemManage_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM("b .");
|
__ASM volatile("b .");
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked)) void BusFault_Handler(void)
|
__attribute__((naked)) void BusFault_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM("b .");
|
__ASM volatile("b .");
|
||||||
}
|
}
|
||||||
__attribute__((naked)) void UsageFault_Handler(void)
|
__attribute__((naked)) void UsageFault_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM("b .");
|
__ASM volatile("b .");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "psa_client.h"
|
#include "psa_client.h"
|
||||||
#include "psa_service.h"
|
#include "psa_service.h"
|
||||||
#include "tfm_utils.h"
|
#include "tfm_utils.h"
|
||||||
|
#include "platform/include/tfm_spm_hal.h"
|
||||||
#include "spm_api.h"
|
#include "spm_api.h"
|
||||||
#include "spm_db.h"
|
#include "spm_db.h"
|
||||||
#include "spm_db_setup.h"
|
#include "spm_db_setup.h"
|
||||||
|
@ -460,46 +461,11 @@ static uint32_t tfm_spm_partition_get_priority_ext(uint32_t partition_idx)
|
||||||
partition_priority;
|
partition_priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Macros to pick linker symbols and allow references to sections in all level*/
|
|
||||||
#define REGION_DECLARE_EXT(a, b, c) extern uint32_t REGION_NAME(a, b, c)
|
|
||||||
|
|
||||||
REGION_DECLARE_EXT(Image$$, ARM_LIB_HEAP, $$ZI$$Base);
|
|
||||||
REGION_DECLARE_EXT(Image$$, ARM_LIB_HEAP, $$ZI$$Limit);
|
|
||||||
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$ZI$$Base);
|
|
||||||
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$ZI$$Limit);
|
|
||||||
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$RW$$Base);
|
|
||||||
REGION_DECLARE_EXT(Image$$, ER_TFM_DATA, $$RW$$Limit);
|
|
||||||
REGION_DECLARE_EXT(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
|
|
||||||
REGION_DECLARE_EXT(Image$$, TFM_SECURE_STACK, $$ZI$$Limit);
|
|
||||||
REGION_DECLARE_EXT(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
|
|
||||||
REGION_DECLARE_EXT(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* \brief Check the memory whether in the given range.
|
|
||||||
*
|
|
||||||
* \param[in] buffer Pointer of memory reference
|
|
||||||
* \param[in] len Length of memory reference in bytes
|
|
||||||
* \param[in] base The base address
|
|
||||||
* \param[in] limit The limit address, the first byte of next
|
|
||||||
* area memory
|
|
||||||
*
|
|
||||||
* \retval IPC_SUCCESS Success
|
|
||||||
* \retval IPC_ERROR_MEMORY_CHECK Check failed
|
|
||||||
*/
|
|
||||||
static int32_t memory_check_range(const void *buffer, size_t len,
|
|
||||||
uintptr_t base, uintptr_t limit)
|
|
||||||
{
|
|
||||||
if (((uintptr_t)buffer >= base) &&
|
|
||||||
((uintptr_t)((uint8_t *)buffer + len - 1) < limit)) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
return IPC_ERROR_MEMORY_CHECK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FixMe: This is only valid for TFM LVL 1 now */
|
/* 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)
|
||||||
{
|
{
|
||||||
uintptr_t base, limit;
|
int32_t err;
|
||||||
|
|
||||||
/* If len is zero, this indicates an empty buffer and base is ignored */
|
/* If len is zero, this indicates an empty buffer and base is ignored */
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
|
@ -514,55 +480,13 @@ int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller)
|
||||||
return IPC_ERROR_MEMORY_CHECK;
|
return IPC_ERROR_MEMORY_CHECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ns_caller) {
|
if (access == TFM_MEMORY_ACCESS_RW) {
|
||||||
base = (uintptr_t)NS_DATA_START;
|
err = tfm_core_has_write_access_to_region(buffer, len, ns_caller);
|
||||||
limit = (uintptr_t)(NS_DATA_START + NS_DATA_SIZE);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = (uintptr_t)NS_CODE_START;
|
|
||||||
limit = (uintptr_t)(NS_CODE_START + NS_CODE_SIZE);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
base = (uintptr_t)®ION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Base);
|
err = tfm_core_has_read_access_to_region(buffer, len, ns_caller);
|
||||||
limit = (uintptr_t)®ION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Limit);
|
}
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
if (err == 1) {
|
||||||
return IPC_SUCCESS;
|
return IPC_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
base = (uintptr_t)®ION_NAME(Image$$, ER_TFM_DATA, $$RW$$Base);
|
|
||||||
limit = (uintptr_t)®ION_NAME(Image$$, ER_TFM_DATA, $$RW$$Limit);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = (uintptr_t)®ION_NAME(Image$$, ER_TFM_DATA, $$ZI$$Base);
|
|
||||||
limit = (uintptr_t)®ION_NAME(Image$$, ER_TFM_DATA, $$ZI$$Limit);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = (uintptr_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Base);
|
|
||||||
limit = (uintptr_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = (uintptr_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
|
|
||||||
limit = (uintptr_t)®ION_NAME(Image$$, TFM_UNPRIV_SCRATCH,
|
|
||||||
$$ZI$$Limit);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
base = (uintptr_t)S_CODE_START;
|
|
||||||
limit = (uintptr_t)(S_CODE_START + S_CODE_SIZE);
|
|
||||||
if (memory_check_range(buffer, len, base, limit) == IPC_SUCCESS) {
|
|
||||||
return IPC_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPC_ERROR_MEMORY_CHECK;
|
return IPC_ERROR_MEMORY_CHECK;
|
||||||
|
|
|
@ -148,12 +148,16 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
||||||
* FixMe: From non-secure caller, vec and len are composed into a new
|
* FixMe: From non-secure caller, vec and len are composed into a new
|
||||||
* struct parameter. Need to extract them.
|
* struct parameter. Need to extract them.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Read parameters from the arguments. It is a fatal error if the
|
||||||
|
* 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) != IPC_SUCCESS) {
|
ns_caller, TFM_MEMORY_ACCESS_RO) != 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) != IPC_SUCCESS) {
|
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,13 +179,22 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It is a fatal error if an invalid memory reference was provide. */
|
/*
|
||||||
|
* Read client invecs from the wrap input vector. It is a fatal error
|
||||||
|
* if the memory reference for the wrap input vector is invalid or not
|
||||||
|
* 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) != IPC_SUCCESS) {
|
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Read client outvecs from the wrap output vector and will update the
|
||||||
|
* actual length later. It is a fatal error if the memory reference for
|
||||||
|
* 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) != IPC_SUCCESS) {
|
ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,18 +206,22 @@ psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
|
||||||
tfm_memcpy(outvecs, outptr, out_num * sizeof(psa_outvec));
|
tfm_memcpy(outvecs, outptr, out_num * sizeof(psa_outvec));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is a fatal error if an invalid payload memory reference
|
* For client input vector, it is a fatal error if the provided payload
|
||||||
* was provided.
|
* memory reference was invalid or not readable.
|
||||||
*/
|
*/
|
||||||
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) != IPC_SUCCESS) {
|
ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* For client output vector, it is a fatal error if the provided payload
|
||||||
|
* memory reference was invalid or not read-write.
|
||||||
|
*/
|
||||||
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) != IPC_SUCCESS) {
|
ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,11 +377,11 @@ static psa_status_t tfm_svcall_psa_get(uint32_t *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is a fatal error if the input msg pointer is not a valid memory
|
* Write the message to the service buffer. It is a fatal error if the
|
||||||
* reference.
|
* 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) != IPC_SUCCESS) {
|
false, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,11 +534,11 @@ static size_t tfm_svcall_psa_read(uint32_t *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It is a fatal error if the memory reference for buffer is invalid or
|
* Copy the client data to the service buffer. It is a fatal error
|
||||||
* not writable
|
* if the memory reference for buffer is invalid or not read-write.
|
||||||
*/
|
*/
|
||||||
/* FixMe: write permission check to be added */
|
if (tfm_memory_check(buffer, num_bytes, false,
|
||||||
if (tfm_memory_check(buffer, num_bytes, false) != IPC_SUCCESS) {
|
TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,8 +688,12 @@ static void tfm_svcall_psa_write(uint32_t *args)
|
||||||
tfm_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It is a fatal error if the memory reference for buffer is valid */
|
/*
|
||||||
if (tfm_memory_check(buffer, num_bytes, false) != IPC_SUCCESS) {
|
* Copy the service buffer to client outvecs. It is a fatal error
|
||||||
|
* 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_panic();
|
tfm_panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,9 @@ struct tfm_exc_stack_t {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LOG_MSG_THR(MSG) \
|
#define LOG_MSG_THR(MSG) \
|
||||||
__ASM("MOV r0, %0\n" \
|
__ASM volatile("MOV r0, %0\n" \
|
||||||
"SVC %1\n" \
|
"SVC %1\n" \
|
||||||
: : "r" (MSG), "I" (TFM_SVC_PRINT))
|
: : "r" (MSG), "I" (TFM_SVC_PRINT))
|
||||||
|
|
||||||
#define LOG_MSG(MSG) \
|
#define LOG_MSG(MSG) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -96,14 +96,14 @@ __STATIC_INLINE uint32_t __get_active_exc_num(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((always_inline))
|
__attribute__ ((always_inline))
|
||||||
__STATIC_INLINE void __set_CONTROL_SPSEL(int32_t SPSEL)
|
__STATIC_INLINE void __set_CONTROL_SPSEL(uint32_t SPSEL)
|
||||||
{
|
{
|
||||||
CONTROL_Type ctrl;
|
CONTROL_Type ctrl;
|
||||||
|
|
||||||
ctrl.w = __get_CONTROL();
|
ctrl.w = __get_CONTROL();
|
||||||
ctrl.b.SPSEL = SPSEL;
|
ctrl.b.SPSEL = SPSEL;
|
||||||
__set_CONTROL(ctrl.w);
|
__set_CONTROL(ctrl.w);
|
||||||
__asm("ISB");
|
__ISB();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __SECURE_UTILITIES_H__ */
|
#endif /* __SECURE_UTILITIES_H__ */
|
||||||
|
|
|
@ -39,9 +39,9 @@ static uint32_t is_boot_data_valid = BOOT_DATA_INVALID;
|
||||||
|
|
||||||
void tfm_core_validate_boot_data(void)
|
void tfm_core_validate_boot_data(void)
|
||||||
{
|
{
|
||||||
struct shared_data_tlv_header *tlv_header;
|
struct tfm_boot_data *boot_data;
|
||||||
|
|
||||||
tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
|
boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
|
||||||
|
|
||||||
/* FixMe: Enhance sanity check of shared memory area, it might be invalid:
|
/* FixMe: Enhance sanity check of shared memory area, it might be invalid:
|
||||||
* - temporal exposure of RAM to non-secure actors
|
* - temporal exposure of RAM to non-secure actors
|
||||||
|
@ -49,7 +49,7 @@ void tfm_core_validate_boot_data(void)
|
||||||
* - version mismatch between bootloader and runtime binary
|
* - version mismatch between bootloader and runtime binary
|
||||||
* - etc.
|
* - etc.
|
||||||
*/
|
*/
|
||||||
if (tlv_header->tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
|
if (boot_data->header.tlv_magic == SHARED_DATA_TLV_INFO_MAGIC) {
|
||||||
is_boot_data_valid = BOOT_DATA_VALID;
|
is_boot_data_valid = BOOT_DATA_VALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
uint32_t running_partition_idx =
|
uint32_t running_partition_idx =
|
||||||
tfm_spm_partition_get_running_partition_idx();
|
tfm_spm_partition_get_running_partition_idx();
|
||||||
struct shared_data_tlv_header *tlv_header;
|
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;
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
|
@ -88,8 +88,8 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the boundaries of TLV section */
|
/* Get the boundaries of TLV section */
|
||||||
tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
|
boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
|
||||||
tlv_end = BOOT_TFM_SHARED_DATA_BASE + tlv_header->tlv_tot_len;
|
tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->header.tlv_tot_len;
|
||||||
offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
|
offset = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
|
||||||
|
|
||||||
/* Add header to output buffer as well */
|
/* Add header to output buffer as well */
|
||||||
|
@ -97,10 +97,10 @@ 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 {
|
} else {
|
||||||
tlv_header = (struct shared_data_tlv_header *)buf_start;
|
boot_data = (struct tfm_boot_data *)buf_start;
|
||||||
tlv_header->tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
|
boot_data->header.tlv_magic = SHARED_DATA_TLV_INFO_MAGIC;
|
||||||
tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
|
boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
|
||||||
ptr = (uint8_t *)tlv_header + SHARED_DATA_HEADER_SIZE;
|
ptr = boot_data->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterates over the TLV section and copy TLVs with requested major
|
/* Iterates over the TLV section and copy TLVs with requested major
|
||||||
|
@ -113,7 +113,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
|
||||||
SHARED_DATA_ENTRY_HEADER_SIZE);
|
SHARED_DATA_ENTRY_HEADER_SIZE);
|
||||||
if (GET_MAJOR(tlv_entry.tlv_type) == tlv_major) {
|
if (GET_MAJOR(tlv_entry.tlv_type) == tlv_major) {
|
||||||
/* Check buffer overflow */
|
/* Check buffer overflow */
|
||||||
if ((ptr - buf_start + tlv_entry.tlv_len) > buf_size) {
|
if (((ptr - buf_start) + tlv_entry.tlv_len) > buf_size) {
|
||||||
args[0] = TFM_ERROR_INVALID_PARAMETER;
|
args[0] = TFM_ERROR_INVALID_PARAMETER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
|
||||||
tfm_memcpy(ptr, (const void *)offset, tlv_entry.tlv_len);
|
tfm_memcpy(ptr, (const void *)offset, tlv_entry.tlv_len);
|
||||||
|
|
||||||
ptr += tlv_entry.tlv_len;
|
ptr += tlv_entry.tlv_len;
|
||||||
tlv_header->tlv_tot_len += tlv_entry.tlv_len;
|
boot_data->header.tlv_tot_len += tlv_entry.tlv_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
args[0] = TFM_SUCCESS;
|
args[0] = TFM_SUCCESS;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -43,8 +43,8 @@ __asm(" .global __ARM_use_no_argv\n");
|
||||||
#ifndef TFM_LVL
|
#ifndef TFM_LVL
|
||||||
#error TFM_LVL is not defined!
|
#error TFM_LVL is not defined!
|
||||||
#endif
|
#endif
|
||||||
#if (TFM_LVL != 1) && (TFM_LVL != 3)
|
#if (TFM_LVL != 1) && (TFM_LVL != 2) && (TFM_LVL != 3)
|
||||||
#error Only TFM_LVL 1 and 3 are supported!
|
#error Only TFM_LVL 1, 2 and 3 are supported!
|
||||||
#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 */
|
||||||
|
@ -129,6 +129,23 @@ static int32_t tfm_core_set_secure_exception_priorities(void)
|
||||||
|
|
||||||
/* FixMe: Explicitly set secure fault and Secure SVC priority to highest */
|
/* FixMe: Explicitly set secure fault and Secure SVC priority to highest */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set secure PendSV priority to the lowest in SECURE state.
|
||||||
|
*
|
||||||
|
* IMPORTANT NOTE:
|
||||||
|
*
|
||||||
|
* Although the priority of the secure PendSV must be the lowest possible
|
||||||
|
* among other interrupts in the Secure state, it must be ensured that
|
||||||
|
* PendSV is not preempted nor masked by Non-Secure interrupts to ensure
|
||||||
|
* the integrity of the Secure operation.
|
||||||
|
* When AIRCR.PRIS is set, the Non-Secure execution can act on
|
||||||
|
* FAULTMASK_NS, PRIMASK_NS or BASEPRI_NS register to boost its priority
|
||||||
|
* number up to the value 0x80.
|
||||||
|
* For this reason, set the priority of the PendSV interrupt to the next
|
||||||
|
* priority level configurable on the platform, just below 0x80.
|
||||||
|
*/
|
||||||
|
NVIC_SetPriority(PendSV_IRQn, (1 << (__NVIC_PRIO_BITS - 1)) - 1);
|
||||||
|
|
||||||
return TFM_SUCCESS;
|
return TFM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,9 +169,13 @@ void tfm_core_spm_request_handler(const struct tfm_exc_stack_t *svc_ctx)
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
tfm_core_init();
|
if (tfm_core_init() != 0) {
|
||||||
|
/* Placeholder for error handling, currently ignored. */
|
||||||
|
}
|
||||||
|
|
||||||
tfm_spm_db_init();
|
if (tfm_spm_db_init() != SPM_ERR_OK) {
|
||||||
|
/* Placeholder for error handling, currently ignored. */
|
||||||
|
}
|
||||||
|
|
||||||
tfm_spm_hal_setup_isolation_hw();
|
tfm_spm_hal_setup_isolation_hw();
|
||||||
|
|
||||||
|
@ -171,6 +192,12 @@ int main(void)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
|
||||||
#ifdef TFM_PSA_API
|
#ifdef TFM_PSA_API
|
||||||
tfm_spm_init();
|
tfm_spm_init();
|
||||||
#endif
|
#endif
|
||||||
|
@ -187,10 +214,5 @@ int main(void)
|
||||||
tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID,
|
tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID,
|
||||||
SPM_PARTITION_STATE_RUNNING);
|
SPM_PARTITION_STATE_RUNNING);
|
||||||
|
|
||||||
/* Prioritise secure exceptions to avoid NS being able to pre-empt secure
|
|
||||||
* SVC or SecureFault
|
|
||||||
*/
|
|
||||||
tfm_core_set_secure_exception_priorities();
|
|
||||||
|
|
||||||
jump_to_ns_code();
|
jump_to_ns_code();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -8,11 +8,11 @@
|
||||||
#ifndef __TFM_CORE_H__
|
#ifndef __TFM_CORE_H__
|
||||||
#define __TFM_CORE_H__
|
#define __TFM_CORE_H__
|
||||||
|
|
||||||
#include "arm_cmse.h"
|
#include <arm_cmse.h>
|
||||||
#include "tfm_svc.h"
|
#include "tfm_svc.h"
|
||||||
#include "secure_utilities.h"
|
#include "secure_utilities.h"
|
||||||
|
|
||||||
extern int32_t tfm_scratch_area_size;
|
extern uint32_t tfm_scratch_area_size;
|
||||||
extern uint8_t *tfm_scratch_area;
|
extern uint8_t *tfm_scratch_area;
|
||||||
|
|
||||||
#endif /* __TFM_CORE_H__ */
|
#endif /* __TFM_CORE_H__ */
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "secure_utilities.h"
|
#include "secure_utilities.h"
|
||||||
#include "arm_acle.h"
|
|
||||||
#include "tfm_svc.h"
|
#include "tfm_svc.h"
|
||||||
#include "tfm_secure_api.h"
|
#include "tfm_secure_api.h"
|
||||||
#include "region_defs.h"
|
#include "region_defs.h"
|
||||||
|
@ -66,9 +65,9 @@ void SecureFault_Handler(void)
|
||||||
|
|
||||||
/* Only save the context if sp is valid */
|
/* Only save the context if sp is valid */
|
||||||
if ((sp >= S_DATA_START &&
|
if ((sp >= S_DATA_START &&
|
||||||
sp <= S_DATA_LIMIT - sizeof(tfm_fault_context) + 1) ||
|
sp <= (S_DATA_LIMIT - sizeof(tfm_fault_context)) + 1) ||
|
||||||
(sp >= NS_DATA_START &&
|
(sp >= NS_DATA_START &&
|
||||||
sp <= NS_DATA_LIMIT - sizeof(tfm_fault_context) + 1)) {
|
sp <= (NS_DATA_LIMIT - sizeof(tfm_fault_context)) + 1)) {
|
||||||
tfm_memcpy(&tfm_fault_context,
|
tfm_memcpy(&tfm_fault_context,
|
||||||
(const void *)sp,
|
(const void *)sp,
|
||||||
sizeof(tfm_fault_context));
|
sizeof(tfm_fault_context));
|
||||||
|
@ -103,7 +102,7 @@ void HardFault_Handler(void)
|
||||||
#if defined(__ARM_ARCH_8M_MAIN__)
|
#if defined(__ARM_ARCH_8M_MAIN__)
|
||||||
__attribute__((naked)) void SVC_Handler(void)
|
__attribute__((naked)) void SVC_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"TST lr, #4\n" /* Check store SP in thread mode to r0 */
|
"TST lr, #4\n" /* Check store SP in thread mode to r0 */
|
||||||
"IT EQ\n"
|
"IT EQ\n"
|
||||||
"BXEQ lr\n"
|
"BXEQ lr\n"
|
||||||
|
@ -116,7 +115,7 @@ __attribute__((naked)) void SVC_Handler(void)
|
||||||
#elif defined(__ARM_ARCH_8M_BASE__)
|
#elif defined(__ARM_ARCH_8M_BASE__)
|
||||||
__attribute__((naked)) void SVC_Handler(void)
|
__attribute__((naked)) void SVC_Handler(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
".syntax unified\n"
|
".syntax unified\n"
|
||||||
"MOVS r0, #4\n" /* Check store SP in thread mode to r0 */
|
"MOVS r0, #4\n" /* Check store SP in thread mode to r0 */
|
||||||
"MOV r1, lr\n"
|
"MOV r1, lr\n"
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,7 @@ void jump_to_ns_code(void);
|
||||||
* \brief Called if veneer is running in thread mode
|
* \brief Called if veneer is running in thread mode
|
||||||
*/
|
*/
|
||||||
uint32_t tfm_core_partition_request_svc_handler(
|
uint32_t tfm_core_partition_request_svc_handler(
|
||||||
uint32_t *svc_args, uint32_t lr);
|
const uint32_t *svc_args, uint32_t lr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Called when secure service returns
|
* \brief Called when secure service returns
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -121,7 +121,7 @@ TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TZ_MemoryId_t must be a positive integer */
|
/* TZ_MemoryId_t must be a positive integer */
|
||||||
tz_id = free_index + 1;
|
tz_id = (TZ_MemoryId_t)free_index + 1;
|
||||||
NsClientIdList[free_index].ns_client_id = get_next_ns_client_id();
|
NsClientIdList[free_index].ns_client_id = get_next_ns_client_id();
|
||||||
#ifdef PRINT_NSPM_DEBUG
|
#ifdef PRINT_NSPM_DEBUG
|
||||||
printf("TZ_AllocModuleContext_S called, returning id %d\r\n",
|
printf("TZ_AllocModuleContext_S called, returning id %d\r\n",
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -43,14 +43,20 @@ 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))
|
||||||
|
static int32_t tfm_core_ipc_request(const struct tfm_sfn_req_s *desc_ptr)
|
||||||
|
{
|
||||||
|
__ASM volatile("SVC %0 \n"
|
||||||
|
"BX LR \n"
|
||||||
|
: : "I" (TFM_SVC_IPC_REQUEST));
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__ ((always_inline)) __STATIC_INLINE
|
__attribute__ ((always_inline)) __STATIC_INLINE
|
||||||
int32_t tfm_core_ns_ipc_request(void *fn, int32_t arg1, int32_t arg2,
|
int32_t tfm_core_ns_ipc_request(void *fn, int32_t arg1, int32_t arg2,
|
||||||
int32_t arg3, int32_t arg4)
|
int32_t arg3, int32_t arg4)
|
||||||
{
|
{
|
||||||
int32_t args[4] = {arg1, arg2, arg3, arg4};
|
int32_t args[4] = {arg1, arg2, arg3, arg4};
|
||||||
volatile struct tfm_sfn_req_s desc;
|
struct tfm_sfn_req_s desc = {0};
|
||||||
struct tfm_sfn_req_s *desc_ptr = &desc;
|
|
||||||
int32_t res;
|
|
||||||
|
|
||||||
desc.sfn = fn;
|
desc.sfn = fn;
|
||||||
desc.args = args;
|
desc.args = args;
|
||||||
|
@ -61,13 +67,7 @@ int32_t tfm_core_ns_ipc_request(void *fn, int32_t arg1, int32_t arg2,
|
||||||
/* FIXME: Proper error handling to be implemented */
|
/* FIXME: Proper error handling to be implemented */
|
||||||
return TFM_ERROR_INVALID_EXC_MODE;
|
return TFM_ERROR_INVALID_EXC_MODE;
|
||||||
} else {
|
} else {
|
||||||
__ASM("MOV r0, %1\n"
|
return tfm_core_ipc_request(&desc);
|
||||||
"SVC %2\n"
|
|
||||||
"MOV %0, r0\n"
|
|
||||||
: "=r" (res)
|
|
||||||
: "r" (desc_ptr), "I" (TFM_SVC_IPC_REQUEST)
|
|
||||||
: "r0");
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,17 +50,17 @@ static int32_t is_iovec_api_call(void)
|
||||||
return curr_part_data->iovec_api;
|
return curr_part_data->iovec_api;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t *prepare_partition_ctx(
|
static uint32_t *prepare_partition_ctx(
|
||||||
struct tfm_exc_stack_t *svc_ctx,
|
const struct tfm_exc_stack_t *svc_ctx,
|
||||||
struct tfm_sfn_req_s *desc_ptr,
|
const struct tfm_sfn_req_s *desc_ptr,
|
||||||
int32_t *dst)
|
uint32_t *dst)
|
||||||
{
|
{
|
||||||
/* XPSR = as was when called, but make sure it's thread mode */
|
/* XPSR = as was when called, but make sure it's thread mode */
|
||||||
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00;
|
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00U;
|
||||||
/* ReturnAddress = resume veneer in new context */
|
/* ReturnAddress = resume veneer in new context */
|
||||||
*(--dst) = svc_ctx->RetAddr;
|
*(--dst) = svc_ctx->RetAddr;
|
||||||
/* LR = sfn address */
|
/* LR = sfn address */
|
||||||
*(--dst) = (int32_t)desc_ptr->sfn;
|
*(--dst) = (uint32_t)desc_ptr->sfn;
|
||||||
/* R12 = don't care */
|
/* R12 = don't care */
|
||||||
*(--dst) = 0;
|
*(--dst) = 0;
|
||||||
|
|
||||||
|
@ -74,20 +74,20 @@ static int32_t *prepare_partition_ctx(
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t *prepare_partition_iovec_ctx(
|
static uint32_t *prepare_partition_iovec_ctx(
|
||||||
struct tfm_exc_stack_t *svc_ctx,
|
const struct tfm_exc_stack_t *svc_ctx,
|
||||||
struct tfm_sfn_req_s *desc_ptr,
|
const struct tfm_sfn_req_s *desc_ptr,
|
||||||
struct iovec_args_t *iovec_args,
|
const struct iovec_args_t *iovec_args,
|
||||||
int32_t *dst)
|
uint32_t *dst)
|
||||||
{
|
{
|
||||||
/* XPSR = as was when called, but make sure it's thread mode */
|
/* XPSR = as was when called, but make sure it's thread mode */
|
||||||
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00;
|
*(--dst) = svc_ctx->XPSR & 0xFFFFFE00U;
|
||||||
/* ReturnAddress = resume veneer in new context */
|
/* ReturnAddress = resume veneer in new context */
|
||||||
*(--dst) = svc_ctx->RetAddr;
|
*(--dst) = svc_ctx->RetAddr;
|
||||||
/* LR = sfn address */
|
/* LR = sfn address */
|
||||||
*(--dst) = (int32_t)desc_ptr->sfn;
|
*(--dst) = (uint32_t)desc_ptr->sfn;
|
||||||
/* R12 = don't care */
|
/* R12 = don't care */
|
||||||
*(--dst) = 0;
|
*(--dst) = 0U;
|
||||||
|
|
||||||
/* R0-R3 = sfn arguments */
|
/* R0-R3 = sfn arguments */
|
||||||
*(--dst) = iovec_args->out_len;
|
*(--dst) = iovec_args->out_len;
|
||||||
|
@ -99,7 +99,7 @@ static int32_t *prepare_partition_iovec_ctx(
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restore_caller_ctx(
|
static void restore_caller_ctx(
|
||||||
struct tfm_exc_stack_t *svc_ctx,
|
const struct tfm_exc_stack_t *svc_ctx,
|
||||||
struct tfm_exc_stack_t *target_ctx)
|
struct tfm_exc_stack_t *target_ctx)
|
||||||
{
|
{
|
||||||
/* ReturnAddress = resume veneer after second SVC */
|
/* ReturnAddress = resume veneer after second SVC */
|
||||||
|
@ -157,7 +157,7 @@ static int32_t check_address_range(const void *p, size_t s,
|
||||||
*
|
*
|
||||||
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int32_t has_access_to_region(const void *p, size_t s, uint32_t flags)
|
static int32_t has_access_to_region(const void *p, size_t s, int flags)
|
||||||
{
|
{
|
||||||
int32_t range_access_allowed_by_mpu;
|
int32_t range_access_allowed_by_mpu;
|
||||||
|
|
||||||
|
@ -192,22 +192,10 @@ static int32_t has_access_to_region(const void *p, size_t s, uint32_t flags)
|
||||||
check_address_range(p, s, NS_DATA_START, NS_DATA_LIMIT+1-NS_DATA_START);
|
check_address_range(p, s, NS_DATA_START, NS_DATA_LIMIT+1-NS_DATA_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
|
||||||
* \brief Check whether the current partition has read access to a memory range
|
uint32_t ns_caller)
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
|
||||||
*/
|
|
||||||
static int32_t has_read_access_to_region(const void *p, size_t s,
|
|
||||||
int32_t ns_caller)
|
|
||||||
{
|
{
|
||||||
uint32_t flags = CMSE_MPU_UNPRIV|CMSE_MPU_READ;
|
int flags = CMSE_MPU_UNPRIV|CMSE_MPU_READ;
|
||||||
|
|
||||||
if (ns_caller) {
|
if (ns_caller) {
|
||||||
flags |= CMSE_NONSECURE;
|
flags |= CMSE_NONSECURE;
|
||||||
|
@ -216,21 +204,10 @@ static int32_t has_read_access_to_region(const void *p, size_t s,
|
||||||
return has_access_to_region(p, s, flags);
|
return has_access_to_region(p, s, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
|
||||||
* \brief Check whether the current partition has write access to a memory range
|
uint32_t ns_caller)
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
|
||||||
*/
|
|
||||||
static int32_t has_write_access_to_region(void *p, size_t s, int32_t ns_caller)
|
|
||||||
{
|
{
|
||||||
uint32_t flags = CMSE_MPU_UNPRIV|CMSE_MPU_READWRITE;
|
int flags = CMSE_MPU_UNPRIV|CMSE_MPU_READWRITE;
|
||||||
|
|
||||||
if (ns_caller) {
|
if (ns_caller) {
|
||||||
flags |= CMSE_NONSECURE;
|
flags |= CMSE_NONSECURE;
|
||||||
|
@ -247,15 +224,23 @@ static int32_t has_write_access_to_region(void *p, size_t s, int32_t ns_caller)
|
||||||
* \return Return /ref TFM_SUCCESS if the iovec parameters are valid, error code
|
* \return Return /ref TFM_SUCCESS if the iovec parameters are valid, error code
|
||||||
* otherwise as in /ref tfm_status_e
|
* otherwise as in /ref tfm_status_e
|
||||||
*/
|
*/
|
||||||
static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
|
static int32_t tfm_core_check_sfn_parameters(
|
||||||
|
const struct tfm_sfn_req_s *desc_ptr)
|
||||||
{
|
{
|
||||||
struct psa_invec *in_vec = (psa_invec *)desc_ptr->args[0];
|
struct psa_invec *in_vec = (psa_invec *)desc_ptr->args[0];
|
||||||
size_t in_len = desc_ptr->args[1];
|
size_t in_len;
|
||||||
struct psa_outvec *out_vec = (psa_outvec *)desc_ptr->args[2];
|
struct psa_outvec *out_vec = (psa_outvec *)desc_ptr->args[2];
|
||||||
size_t out_len = desc_ptr->args[3];
|
size_t out_len;
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
if ((desc_ptr->args[1] < 0) || (desc_ptr->args[3] < 0)) {
|
||||||
|
return TFM_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_len = (size_t)(desc_ptr->args[1]);
|
||||||
|
out_len = (size_t)(desc_ptr->args[3]);
|
||||||
|
|
||||||
/* The number of vectors are within range. Extra checks to avoid overflow */
|
/* The number of vectors are within range. Extra checks to avoid overflow */
|
||||||
if ((in_len > PSA_MAX_IOVEC) || (out_len > PSA_MAX_IOVEC) ||
|
if ((in_len > PSA_MAX_IOVEC) || (out_len > PSA_MAX_IOVEC) ||
|
||||||
(in_len + out_len > PSA_MAX_IOVEC)) {
|
(in_len + out_len > PSA_MAX_IOVEC)) {
|
||||||
|
@ -267,8 +252,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
|
||||||
*/
|
*/
|
||||||
if (in_len > 0) {
|
if (in_len > 0) {
|
||||||
if ((in_vec == NULL) ||
|
if ((in_vec == NULL) ||
|
||||||
(has_write_access_to_region(in_vec, sizeof(psa_invec)*in_len,
|
(tfm_core_has_write_access_to_region(in_vec,
|
||||||
desc_ptr->ns_caller) != 1)) {
|
sizeof(psa_invec)*in_len,
|
||||||
|
desc_ptr->ns_caller) != 1)) {
|
||||||
return TFM_ERROR_INVALID_PARAMETER;
|
return TFM_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -278,8 +264,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
|
||||||
}
|
}
|
||||||
if (out_len > 0) {
|
if (out_len > 0) {
|
||||||
if ((out_vec == NULL) ||
|
if ((out_vec == NULL) ||
|
||||||
(has_write_access_to_region(out_vec, sizeof(psa_outvec)*out_len,
|
(tfm_core_has_write_access_to_region(out_vec,
|
||||||
desc_ptr->ns_caller) != 1)) {
|
sizeof(psa_outvec)*out_len,
|
||||||
|
desc_ptr->ns_caller) != 1)) {
|
||||||
return TFM_ERROR_INVALID_PARAMETER;
|
return TFM_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -294,8 +281,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
|
||||||
for (i = 0; i < in_len; ++i) {
|
for (i = 0; i < in_len; ++i) {
|
||||||
if (in_vec[i].len > 0) {
|
if (in_vec[i].len > 0) {
|
||||||
if ((in_vec[i].base == NULL) ||
|
if ((in_vec[i].base == NULL) ||
|
||||||
(has_read_access_to_region(in_vec[i].base, in_vec[i].len,
|
(tfm_core_has_read_access_to_region(in_vec[i].base,
|
||||||
desc_ptr->ns_caller) != 1)) {
|
in_vec[i].len,
|
||||||
|
desc_ptr->ns_caller) != 1)) {
|
||||||
return TFM_ERROR_INVALID_PARAMETER;
|
return TFM_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,8 +291,9 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
|
||||||
for (i = 0; i < out_len; ++i) {
|
for (i = 0; i < out_len; ++i) {
|
||||||
if (out_vec[i].len > 0) {
|
if (out_vec[i].len > 0) {
|
||||||
if ((out_vec[i].base == NULL) ||
|
if ((out_vec[i].base == NULL) ||
|
||||||
(has_write_access_to_region(out_vec[i].base, out_vec[i].len,
|
(tfm_core_has_write_access_to_region(out_vec[i].base,
|
||||||
desc_ptr->ns_caller) != 1)) {
|
out_vec[i].len,
|
||||||
|
desc_ptr->ns_caller) != 1)) {
|
||||||
return TFM_ERROR_INVALID_PARAMETER;
|
return TFM_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,7 +305,7 @@ static int32_t tfm_core_check_sfn_parameters(struct tfm_sfn_req_s *desc_ptr)
|
||||||
static void tfm_copy_iovec_parameters(struct iovec_args_t *target,
|
static void tfm_copy_iovec_parameters(struct iovec_args_t *target,
|
||||||
const struct iovec_args_t *source)
|
const struct iovec_args_t *source)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
target->in_len = source->in_len;
|
target->in_len = source->in_len;
|
||||||
for (i = 0; i < source->in_len; ++i) {
|
for (i = 0; i < source->in_len; ++i) {
|
||||||
|
@ -346,7 +335,7 @@ static void tfm_clear_iovec_parameters(struct iovec_args_t *args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
|
static int32_t tfm_start_partition(const struct tfm_sfn_req_s *desc_ptr,
|
||||||
uint32_t excReturn)
|
uint32_t excReturn)
|
||||||
{
|
{
|
||||||
uint32_t caller_partition_idx = desc_ptr->caller_part_idx;
|
uint32_t caller_partition_idx = desc_ptr->caller_part_idx;
|
||||||
|
@ -479,18 +468,21 @@ static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
|
||||||
iovec_args = (struct iovec_args_t *)
|
iovec_args = (struct iovec_args_t *)
|
||||||
((uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
|
((uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
|
||||||
sizeof(struct iovec_args_t));
|
sizeof(struct iovec_args_t));
|
||||||
tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args);
|
if (tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args) !=
|
||||||
|
SPM_ERR_OK) {
|
||||||
|
return TFM_ERROR_GENERIC;
|
||||||
|
}
|
||||||
tfm_copy_iovec_parameters(iovec_args,
|
tfm_copy_iovec_parameters(iovec_args,
|
||||||
&(curr_part_data->iovec_args));
|
&(curr_part_data->iovec_args));
|
||||||
|
|
||||||
/* Prepare the partition context, update stack ptr */
|
/* Prepare the partition context, update stack ptr */
|
||||||
psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
|
psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
|
||||||
iovec_args,
|
iovec_args,
|
||||||
(int32_t *)partition_psp);
|
(uint32_t *)partition_psp);
|
||||||
} else {
|
} else {
|
||||||
/* Prepare the partition context, update stack ptr */
|
/* Prepare the partition context, update stack ptr */
|
||||||
psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
|
psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
|
||||||
(int32_t *)partition_psp);
|
(uint32_t *)partition_psp);
|
||||||
}
|
}
|
||||||
__set_PSP(psp);
|
__set_PSP(psp);
|
||||||
__set_PSPLIM(partition_psplim);
|
__set_PSPLIM(partition_psplim);
|
||||||
|
@ -505,17 +497,20 @@ static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
|
||||||
iovec_args =
|
iovec_args =
|
||||||
(struct iovec_args_t *)(tfm_spm_partition_get_stack_top(partition_idx) -
|
(struct iovec_args_t *)(tfm_spm_partition_get_stack_top(partition_idx) -
|
||||||
sizeof(struct iovec_args_t));
|
sizeof(struct iovec_args_t));
|
||||||
tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args);
|
if (tfm_spm_partition_set_iovec(partition_idx, desc_ptr->args) !=
|
||||||
|
SPM_ERR_OK) {
|
||||||
|
return TFM_ERROR_GENERIC;
|
||||||
|
}
|
||||||
tfm_copy_iovec_parameters(iovec_args, &(curr_part_data->iovec_args));
|
tfm_copy_iovec_parameters(iovec_args, &(curr_part_data->iovec_args));
|
||||||
|
|
||||||
/* Prepare the partition context, update stack ptr */
|
/* Prepare the partition context, update stack ptr */
|
||||||
psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
|
psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
|
||||||
iovec_args,
|
iovec_args,
|
||||||
(int32_t *)partition_psp);
|
(uint32_t *)partition_psp);
|
||||||
} else {
|
} else {
|
||||||
/* Prepare the partition context, update stack ptr */
|
/* Prepare the partition context, update stack ptr */
|
||||||
psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
|
psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
|
||||||
(int32_t *)partition_psp);
|
(uint32_t *)partition_psp);
|
||||||
}
|
}
|
||||||
__set_PSP(psp);
|
__set_PSP(psp);
|
||||||
__set_PSPLIM(partition_psplim);
|
__set_PSPLIM(partition_psplim);
|
||||||
|
@ -538,7 +533,7 @@ static int32_t tfm_return_from_partition(uint32_t *excReturn)
|
||||||
uint32_t return_partition_idx;
|
uint32_t return_partition_idx;
|
||||||
uint32_t return_partition_flags;
|
uint32_t return_partition_flags;
|
||||||
uint32_t psp = __get_PSP();
|
uint32_t psp = __get_PSP();
|
||||||
int i;
|
size_t i;
|
||||||
struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
|
struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
|
||||||
struct iovec_args_t *iovec_args;
|
struct iovec_args_t *iovec_args;
|
||||||
|
|
||||||
|
@ -676,7 +671,7 @@ void tfm_secure_api_error_handler(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tfm_check_sfn_req_integrity(struct tfm_sfn_req_s *desc_ptr)
|
static int32_t tfm_check_sfn_req_integrity(const struct tfm_sfn_req_s *desc_ptr)
|
||||||
{
|
{
|
||||||
if ((desc_ptr == NULL) ||
|
if ((desc_ptr == NULL) ||
|
||||||
(desc_ptr->sp_id == 0) ||
|
(desc_ptr->sp_id == 0) ||
|
||||||
|
@ -688,7 +683,7 @@ static int32_t tfm_check_sfn_req_integrity(struct tfm_sfn_req_s *desc_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t tfm_core_check_sfn_req_rules(
|
static int32_t tfm_core_check_sfn_req_rules(
|
||||||
struct tfm_sfn_req_s *desc_ptr)
|
const struct tfm_sfn_req_s *desc_ptr)
|
||||||
{
|
{
|
||||||
/* Check partition idx validity */
|
/* Check partition idx validity */
|
||||||
if (desc_ptr->caller_part_idx == SPM_INVALID_PARTITION_IDX) {
|
if (desc_ptr->caller_part_idx == SPM_INVALID_PARTITION_IDX) {
|
||||||
|
@ -1046,7 +1041,7 @@ void tfm_core_memory_permission_check_handler(uint32_t *svc_args)
|
||||||
|
|
||||||
/* This SVC handler is called if veneer is running in thread mode */
|
/* This SVC handler is called if veneer is running in thread mode */
|
||||||
uint32_t tfm_core_partition_request_svc_handler(
|
uint32_t tfm_core_partition_request_svc_handler(
|
||||||
struct tfm_exc_stack_t *svc_ctx, uint32_t excReturn)
|
const struct tfm_exc_stack_t *svc_ctx, uint32_t excReturn)
|
||||||
{
|
{
|
||||||
struct tfm_sfn_req_s *desc_ptr;
|
struct tfm_sfn_req_s *desc_ptr;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -8,11 +8,12 @@
|
||||||
#ifndef __TFM_SECURE_API_H__
|
#ifndef __TFM_SECURE_API_H__
|
||||||
#define __TFM_SECURE_API_H__
|
#define __TFM_SECURE_API_H__
|
||||||
|
|
||||||
#include "arm_cmse.h"
|
#include <arm_cmse.h>
|
||||||
#include "tfm_svc.h"
|
#include "tfm_svc.h"
|
||||||
#include "secure_utilities.h"
|
#include "secure_utilities.h"
|
||||||
#include "tfm_core.h"
|
#include "tfm_core.h"
|
||||||
#include "tfm_api.h"
|
#include "tfm_api.h"
|
||||||
|
#include "bl2/include/tfm_boot_status.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \def __tfm_secure_gateway_attributes__
|
* \def __tfm_secure_gateway_attributes__
|
||||||
|
@ -46,7 +47,7 @@ struct tfm_sfn_req_s {
|
||||||
int32_t *args;
|
int32_t *args;
|
||||||
uint32_t caller_part_idx;
|
uint32_t caller_part_idx;
|
||||||
int32_t iovec_api;
|
int32_t iovec_api;
|
||||||
int32_t ns_caller : 1;
|
uint32_t ns_caller;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum tfm_buffer_share_region_e {
|
enum tfm_buffer_share_region_e {
|
||||||
|
@ -81,13 +82,44 @@ extern int32_t tfm_core_memory_permission_check(const void *ptr,
|
||||||
uint32_t size,
|
uint32_t size,
|
||||||
int32_t access);
|
int32_t access);
|
||||||
|
|
||||||
extern int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr,
|
extern int32_t tfm_core_get_boot_data(uint8_t major_type,
|
||||||
|
struct tfm_boot_data *boot_data,
|
||||||
uint32_t len);
|
uint32_t len);
|
||||||
|
|
||||||
int32_t tfm_core_sfn_request(struct tfm_sfn_req_s *desc_ptr);
|
int32_t tfm_core_sfn_request(const struct tfm_sfn_req_s *desc_ptr);
|
||||||
|
|
||||||
int32_t tfm_core_sfn_request_thread_mode(struct tfm_sfn_req_s *desc_ptr);
|
int32_t tfm_core_sfn_request_thread_mode(struct tfm_sfn_req_s *desc_ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check whether the current partition has read access to a memory range
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
|
||||||
|
uint32_t ns_caller);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check whether the current partition has write access to a memory range
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* \return 1 if the partition has access to the memory range, 0 otherwise.
|
||||||
|
*/
|
||||||
|
int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
|
||||||
|
uint32_t ns_caller);
|
||||||
|
|
||||||
#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)
|
||||||
|
@ -106,7 +138,31 @@ int32_t tfm_core_partition_request(uint32_t id, void *fn, int32_t iovec_api,
|
||||||
desc.sp_id = id;
|
desc.sp_id = id;
|
||||||
desc.sfn = fn;
|
desc.sfn = fn;
|
||||||
desc.args = args;
|
desc.args = args;
|
||||||
desc.ns_caller = cmse_nonsecure_caller();
|
/*
|
||||||
|
* This preprocessor condition checks if a version of GCC smaller than
|
||||||
|
* 7.3.1 is being used to compile the code.
|
||||||
|
* These versions are affected by a bug on the cmse_nonsecure_caller
|
||||||
|
* intrinsic which returns incorrect results.
|
||||||
|
* Please check Bug 85203 on GCC Bugzilla for more information.
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__) && !defined(__ARMCC_VERSION) && \
|
||||||
|
(__GNUC__ < 7 || \
|
||||||
|
(__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || \
|
||||||
|
(__GNUC_MINOR__ == 3 && __GNUC_PATCHLEVEL__ < 1))))
|
||||||
|
/*
|
||||||
|
* Use the fact that, if called from Non-Secure, the LSB of the return
|
||||||
|
* address is set to 0.
|
||||||
|
*/
|
||||||
|
desc.ns_caller = (uint32_t)!(
|
||||||
|
(intptr_t)__builtin_extract_return_addr(__builtin_return_address(0U))
|
||||||
|
& 1);
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Convert the result of cmse_nonsecure_caller from an int to a uint32_t
|
||||||
|
* to prevent using an int in the tfm_sfn_req_s structure.
|
||||||
|
*/
|
||||||
|
desc.ns_caller = (cmse_nonsecure_caller() != 0) ? 1U : 0U;
|
||||||
|
#endif /* Check for GCC compiler version smaller than 7.3.1 */
|
||||||
desc.iovec_api = iovec_api;
|
desc.iovec_api = iovec_api;
|
||||||
if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
|
if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
|
||||||
/* FixMe: Error severity TBD */
|
/* FixMe: Error severity TBD */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
#include "secure_fw/include/tfm_spm_services_api.h"
|
#include "secure_fw/include/tfm_spm_services_api.h"
|
||||||
|
|
||||||
uint8_t *tfm_scratch_area;
|
uint8_t *tfm_scratch_area;
|
||||||
int32_t tfm_scratch_area_size;
|
uint32_t tfm_scratch_area_size;
|
||||||
nsfptr_t ns_entry;
|
nsfptr_t ns_entry;
|
||||||
|
|
||||||
void jump_to_ns_code(void)
|
void jump_to_ns_code(void)
|
||||||
|
@ -36,9 +36,9 @@ void jump_to_ns_code(void)
|
||||||
|
|
||||||
#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(
|
||||||
struct tfm_sfn_req_s *desc_ptr)
|
const struct tfm_sfn_req_s *desc_ptr)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"PUSH {r4-r12, lr}\n"
|
"PUSH {r4-r12, lr}\n"
|
||||||
"SVC %[SVC_REQ]\n"
|
"SVC %[SVC_REQ]\n"
|
||||||
"MOV r4, #0\n"
|
"MOV r4, #0\n"
|
||||||
|
@ -58,9 +58,9 @@ __attribute__((naked)) int32_t tfm_core_sfn_request(
|
||||||
}
|
}
|
||||||
#elif defined(__ARM_ARCH_8M_BASE__)
|
#elif defined(__ARM_ARCH_8M_BASE__)
|
||||||
__attribute__((naked)) int32_t tfm_core_sfn_request(
|
__attribute__((naked)) int32_t tfm_core_sfn_request(
|
||||||
struct tfm_sfn_req_s *desc_ptr)
|
const struct tfm_sfn_req_s *desc_ptr)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
".syntax unified\n"
|
".syntax unified\n"
|
||||||
"PUSH {lr}\n"
|
"PUSH {lr}\n"
|
||||||
"PUSH {r4-r7}\n"
|
"PUSH {r4-r7}\n"
|
||||||
|
@ -104,7 +104,7 @@ int32_t tfm_core_memory_permission_check(const void *ptr,
|
||||||
uint32_t len,
|
uint32_t len,
|
||||||
int32_t access)
|
int32_t access)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"SVC %0\n"
|
"SVC %0\n"
|
||||||
"BX lr\n"
|
"BX lr\n"
|
||||||
: : "I" (TFM_SVC_MEMORY_CHECK));
|
: : "I" (TFM_SVC_MEMORY_CHECK));
|
||||||
|
@ -113,7 +113,7 @@ int32_t tfm_core_memory_permission_check(const void *ptr,
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
|
int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"SVC %0\n"
|
"SVC %0\n"
|
||||||
"BX LR\n"
|
"BX LR\n"
|
||||||
: : "I" (TFM_SVC_GET_CALLER_CLIENT_ID));
|
: : "I" (TFM_SVC_GET_CALLER_CLIENT_ID));
|
||||||
|
@ -122,7 +122,7 @@ int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
int32_t tfm_spm_request_reset_vote(void)
|
int32_t tfm_spm_request_reset_vote(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"MOVS R0, %0\n"
|
"MOVS R0, %0\n"
|
||||||
"B tfm_spm_request\n"
|
"B tfm_spm_request\n"
|
||||||
: : "I" (TFM_SPM_REQUEST_RESET_VOTE));
|
: : "I" (TFM_SPM_REQUEST_RESET_VOTE));
|
||||||
|
@ -131,7 +131,7 @@ int32_t tfm_spm_request_reset_vote(void)
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
int32_t tfm_spm_request(void)
|
int32_t tfm_spm_request(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"SVC %0\n"
|
"SVC %0\n"
|
||||||
"BX lr\n"
|
"BX lr\n"
|
||||||
: : "I" (TFM_SVC_SPM_REQUEST));
|
: : "I" (TFM_SVC_SPM_REQUEST));
|
||||||
|
@ -140,7 +140,7 @@ int32_t tfm_spm_request(void)
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
int32_t tfm_core_validate_secure_caller(void)
|
int32_t tfm_core_validate_secure_caller(void)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"SVC %0\n"
|
"SVC %0\n"
|
||||||
"BX lr\n"
|
"BX lr\n"
|
||||||
: : "I" (TFM_SVC_VALIDATE_SECURE_CALLER));
|
: : "I" (TFM_SVC_VALIDATE_SECURE_CALLER));
|
||||||
|
@ -149,16 +149,18 @@ int32_t tfm_core_validate_secure_caller(void)
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
int32_t tfm_core_set_buffer_area(enum tfm_buffer_share_region_e share)
|
int32_t tfm_core_set_buffer_area(enum tfm_buffer_share_region_e share)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"SVC %0\n"
|
"SVC %0\n"
|
||||||
"BX lr\n"
|
"BX lr\n"
|
||||||
: : "I" (TFM_SVC_SET_SHARE_AREA));
|
: : "I" (TFM_SVC_SET_SHARE_AREA));
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
int32_t tfm_core_get_boot_data(uint8_t major_type, void *ptr, uint32_t len)
|
int32_t tfm_core_get_boot_data(uint8_t major_type,
|
||||||
|
struct tfm_boot_data *boot_status,
|
||||||
|
uint32_t len)
|
||||||
{
|
{
|
||||||
__ASM(
|
__ASM volatile(
|
||||||
"SVC %0\n"
|
"SVC %0\n"
|
||||||
"BX lr\n"
|
"BX lr\n"
|
||||||
: : "I" (TFM_SVC_GET_BOOT_DATA));
|
: : "I" (TFM_SVC_GET_BOOT_DATA));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -43,6 +43,6 @@ typedef enum {
|
||||||
#endif
|
#endif
|
||||||
} tfm_svc_number_t;
|
} tfm_svc_number_t;
|
||||||
|
|
||||||
#define SVC(code) __ASM("svc %0" : : "I" (code))
|
#define SVC(code) __ASM volatile("svc %0" : : "I" (code))
|
||||||
|
|
||||||
#endif /* __TFM_SVC_H__ */
|
#endif /* __TFM_SVC_H__ */
|
||||||
|
|
|
@ -33,7 +33,7 @@ typedef enum {
|
||||||
* returned.
|
* returned.
|
||||||
*/
|
*/
|
||||||
static void tfm_spm_partition_err_handler(
|
static void tfm_spm_partition_err_handler(
|
||||||
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,
|
||||||
int32_t err_code)
|
int32_t err_code)
|
||||||
{
|
{
|
||||||
|
@ -42,17 +42,32 @@ static void tfm_spm_partition_err_handler(
|
||||||
printf("Partition init failed for partition id 0x%08X\r\n",
|
printf("Partition init failed for partition id 0x%08X\r\n",
|
||||||
partition->static_data.partition_id);
|
partition->static_data.partition_id);
|
||||||
} else {
|
} else {
|
||||||
printf("Unknown partition error %d for partition id 0x%08X\r\n",
|
printf(
|
||||||
err_type, partition->static_data.partition_id);
|
"Unknown partition error %d (code: %d) for partition id 0x%08X\r\n",
|
||||||
|
err_type, err_code, partition->static_data.partition_id);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)err_type;
|
||||||
|
(void)err_code;
|
||||||
#endif
|
#endif
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function prevents name clashes between the variable names accessibles in
|
||||||
|
* the scope of where tfm_partition_list.inc is included and the varaible names
|
||||||
|
* defined inside tfm_partition_list.inc file.
|
||||||
|
*/
|
||||||
|
static inline enum spm_err_t add_user_defined_partitions(void) {
|
||||||
|
#include "tfm_partition_list.inc"
|
||||||
|
|
||||||
|
return SPM_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t get_partition_idx(uint32_t partition_id)
|
uint32_t get_partition_idx(uint32_t partition_id)
|
||||||
{
|
{
|
||||||
int i;
|
uint32_t i;
|
||||||
|
|
||||||
if (partition_id == INVALID_PARTITION_ID) {
|
if (partition_id == INVALID_PARTITION_ID) {
|
||||||
return SPM_INVALID_PARTITION_IDX;
|
return SPM_INVALID_PARTITION_IDX;
|
||||||
|
@ -70,8 +85,9 @@ uint32_t get_partition_idx(uint32_t partition_id)
|
||||||
enum spm_err_t tfm_spm_db_init(void)
|
enum spm_err_t tfm_spm_db_init(void)
|
||||||
{
|
{
|
||||||
struct spm_partition_desc_t *part_ptr;
|
struct spm_partition_desc_t *part_ptr;
|
||||||
|
enum spm_err_t err;
|
||||||
|
|
||||||
tfm_memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
|
(void)tfm_memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
|
||||||
|
|
||||||
/* This function initialises partition db */
|
/* This function initialises partition db */
|
||||||
g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
|
g_spm_partition_db.running_partition_idx = SPM_INVALID_PARTITION_IDX;
|
||||||
|
@ -82,12 +98,11 @@ 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
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +118,9 @@ enum spm_err_t tfm_spm_db_init(void)
|
||||||
* 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;
|
||||||
|
@ -121,8 +139,10 @@ enum spm_err_t tfm_spm_db_init(void)
|
||||||
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
|
part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
|
||||||
++g_spm_partition_db.partition_count;
|
++g_spm_partition_db.partition_count;
|
||||||
|
|
||||||
/* Add user-defined secure partitions */
|
err = add_user_defined_partitions();
|
||||||
#include "tfm_partition_list.inc"
|
if (err != SPM_ERR_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
g_spm_partition_db.is_init = 1;
|
g_spm_partition_db.is_init = 1;
|
||||||
|
|
||||||
|
@ -154,7 +174,7 @@ enum spm_err_t tfm_spm_partition_init(void)
|
||||||
int32_t res;
|
int32_t res;
|
||||||
|
|
||||||
desc.args = args;
|
desc.args = args;
|
||||||
desc.ns_caller = 0;
|
desc.ns_caller = 0U;
|
||||||
desc.iovec_api = TFM_SFN_API_IOVEC;
|
desc.iovec_api = TFM_SFN_API_IOVEC;
|
||||||
desc.sfn = (sfn_t)part->static_data.partition_init;
|
desc.sfn = (sfn_t)part->static_data.partition_init;
|
||||||
desc.sp_id = part->static_data.partition_id;
|
desc.sp_id = part->static_data.partition_id;
|
||||||
|
@ -314,20 +334,25 @@ enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tfm_spm_partition_set_iovec(uint32_t partition_idx, int32_t *args)
|
enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
|
||||||
|
const int32_t *args)
|
||||||
{
|
{
|
||||||
struct spm_partition_runtime_data_t *runtime_data =
|
struct spm_partition_runtime_data_t *runtime_data =
|
||||||
&g_spm_partition_db.partitions[partition_idx].runtime_data;
|
&g_spm_partition_db.partitions[partition_idx].runtime_data;
|
||||||
int32_t i;
|
size_t i;
|
||||||
|
|
||||||
runtime_data->iovec_args.in_len = args[1];
|
if ((args[1] < 0) || (args[3] < 0)) {
|
||||||
for (i = 0; i < runtime_data->iovec_args.in_len; ++i) {
|
return SPM_ERR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime_data->iovec_args.in_len = (size_t)args[1];
|
||||||
|
for (i = 0U; i < runtime_data->iovec_args.in_len; ++i) {
|
||||||
runtime_data->iovec_args.in_vec[i].base =
|
runtime_data->iovec_args.in_vec[i].base =
|
||||||
((psa_invec *)args[0])[i].base;
|
((psa_invec *)args[0])[i].base;
|
||||||
runtime_data->iovec_args.in_vec[i].len = ((psa_invec *)args[0])[i].len;
|
runtime_data->iovec_args.in_vec[i].len = ((psa_invec *)args[0])[i].len;
|
||||||
}
|
}
|
||||||
runtime_data->iovec_args.out_len = args[3];
|
runtime_data->iovec_args.out_len = (size_t)args[3];
|
||||||
for (i = 0; i < runtime_data->iovec_args.out_len; ++i) {
|
for (i = 0U; i < runtime_data->iovec_args.out_len; ++i) {
|
||||||
runtime_data->iovec_args.out_vec[i].base =
|
runtime_data->iovec_args.out_vec[i].base =
|
||||||
((psa_outvec *)args[2])[i].base;
|
((psa_outvec *)args[2])[i].base;
|
||||||
runtime_data->iovec_args.out_vec[i].len =
|
runtime_data->iovec_args.out_vec[i].len =
|
||||||
|
@ -335,6 +360,8 @@ void tfm_spm_partition_set_iovec(uint32_t partition_idx, int32_t *args)
|
||||||
}
|
}
|
||||||
runtime_data->orig_outvec = (psa_outvec *)args[2];
|
runtime_data->orig_outvec = (psa_outvec *)args[2];
|
||||||
runtime_data->iovec_api = 1;
|
runtime_data->iovec_api = 1;
|
||||||
|
|
||||||
|
return SPM_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tfm_spm_partition_get_running_partition_idx(void)
|
uint32_t tfm_spm_partition_get_running_partition_idx(void)
|
||||||
|
|
|
@ -20,6 +20,7 @@ enum spm_err_t {
|
||||||
SPM_ERR_PARTITION_DB_NOT_INIT,
|
SPM_ERR_PARTITION_DB_NOT_INIT,
|
||||||
SPM_ERR_PARTITION_ALREADY_ACTIVE,
|
SPM_ERR_PARTITION_ALREADY_ACTIVE,
|
||||||
SPM_ERR_PARTITION_NOT_AVAILABLE,
|
SPM_ERR_PARTITION_NOT_AVAILABLE,
|
||||||
|
SPM_ERR_INVALID_PARAMETER,
|
||||||
SPM_ERR_INVALID_CONFIG,
|
SPM_ERR_INVALID_CONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -297,11 +298,14 @@ enum spm_err_t tfm_spm_partition_set_share(uint32_t partition_idx,
|
||||||
* args[2] is out_vec
|
* args[2] is out_vec
|
||||||
* args[3] is out_len
|
* args[3] is out_len
|
||||||
*
|
*
|
||||||
|
* \return Error code \ref spm_err_t
|
||||||
|
*
|
||||||
* \note This function doesn't check if partition_idx is valid.
|
* \note This function doesn't check if partition_idx is valid.
|
||||||
* \note This function assumes that the iovecs that are passed in args are
|
* \note This function assumes that the iovecs that are passed in args are
|
||||||
* valid, and does no sanity check on them at all.
|
* valid, and does no sanity check on them at all.
|
||||||
*/
|
*/
|
||||||
void tfm_spm_partition_set_iovec(uint32_t partition_idx, int32_t *args);
|
enum spm_err_t tfm_spm_partition_set_iovec(uint32_t partition_idx,
|
||||||
|
const int32_t *args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Initialize partition database
|
* \brief Initialize partition database
|
||||||
|
|
|
@ -21,7 +21,7 @@ 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
|
#define TFM_STACK_SIZE (1024 * 5)
|
||||||
|
|
||||||
#ifdef TFM_PSA_API
|
#ifdef TFM_PSA_API
|
||||||
enum tfm_partition_priority {
|
enum tfm_partition_priority {
|
||||||
|
|
|
@ -115,21 +115,21 @@ struct spm_partition_db_t {
|
||||||
++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__ */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -12,6 +12,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "tfm_api.h"
|
||||||
|
|
||||||
typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1,
|
typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1,
|
||||||
uint32_t arg2, uint32_t arg3);
|
uint32_t arg2, uint32_t arg3);
|
||||||
|
@ -32,7 +33,7 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
|
||||||
* \details Needs to be called during non-secure app init
|
* \details Needs to be called during non-secure app init
|
||||||
* to initialize the TFM NS lock object
|
* to initialize the TFM NS lock object
|
||||||
*/
|
*/
|
||||||
uint32_t tfm_ns_lock_init();
|
enum tfm_status_e tfm_ns_lock_init();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2018, Arm Limited. All rights reserved.
|
* Copyright (c) 2017-2019, Arm Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*
|
*
|
||||||
|
@ -24,7 +24,7 @@ extern "C" {
|
||||||
* \brief Macro to encode an svc instruction
|
* \brief Macro to encode an svc instruction
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define SVC(code) __ASM("svc %0" : : "I" (code))
|
#define SVC(code) __ASM volatile("svc %0" : : "I" (code))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \def LIST_SVC_NSPM
|
* \def LIST_SVC_NSPM
|
||||||
|
@ -59,7 +59,7 @@ enum tfm_svc_num {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* number of user SVC functions */
|
/* number of user SVC functions */
|
||||||
#define USER_SVC_COUNT (SVC_TFM_MAX - 1)
|
#define USER_SVC_COUNT ((uint32_t)SVC_TFM_MAX - 1)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +1,75 @@
|
||||||
{
|
{
|
||||||
"files" : [
|
"files": [
|
||||||
{
|
{
|
||||||
"src_file" : "interface/src/tfm_ns_lock_rtx.c",
|
"src_file": "interface/src/tfm_ns_lock_rtx.c",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_ns_lock_rtx.c"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_ns_lock_rtx.c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/src/tfm_psa_ns_api.c",
|
"src_file": "interface/src/tfm_psa_ns_api.c",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_psa_ns_api.c"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/COMPONENT_NSPE/interface/src/tfm_psa_ns_api.c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/include/psa_client.h",
|
"src_file": "interface/include/psa_client.h",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/psa_client.h"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/psa_client.h"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/include/psa_service.h",
|
"src_file": "interface/include/psa_service.h",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/psa_service.h"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/psa_service.h"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/include/tfm_api.h",
|
"src_file": "interface/include/tfm_api.h",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_api.h"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_api.h"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/include/tfm_ns_lock.h",
|
"src_file": "interface/include/tfm_ns_lock.h",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_lock.h"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_lock.h"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/include/tfm_ns_svc.h",
|
"src_file": "interface/include/tfm_ns_svc.h",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_svc.h"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_ns_svc.h"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_file" : "interface/include/tfm_nspm_svc_handler.h",
|
"src_file": "interface/include/tfm_nspm_svc_handler.h",
|
||||||
"dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_nspm_svc_handler.h"
|
"dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_nspm_svc_handler.h"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"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"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"folders" : [
|
"folders": [
|
||||||
{
|
{
|
||||||
"src_folder" : "secure_fw/core",
|
"src_folder": "secure_fw/core",
|
||||||
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core"
|
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_folder" : "secure_fw/core/ipc",
|
"src_folder": "secure_fw/core/ipc",
|
||||||
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc"
|
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_folder" : "secure_fw/core/ipc/include",
|
"src_folder": "secure_fw/core/ipc/include",
|
||||||
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc/include"
|
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc/include"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_folder" : "secure_fw/include",
|
"src_folder": "secure_fw/include",
|
||||||
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/include"
|
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/include"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_folder" : "secure_fw/spm",
|
"src_folder": "secure_fw/spm",
|
||||||
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/spm"
|
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/spm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"src_folder" : "bl2/include",
|
"src_folder": "bl2/include",
|
||||||
"dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/bl2/include"
|
"dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/bl2/include"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"commit_sha" : [
|
"commit_sha": [
|
||||||
"185d2865da45cc2c6ac3acb755b90c196934d7d5",
|
"fb068d2cb4e89cacf0e9f413075bb4b211f1484f",
|
||||||
"e89c1a68ce8f690ce0d6029cd9196b03906060de",
|
"5d41a2aeae71b13f2763bea4e55899646291e0eb",
|
||||||
"3fbc73e046e59e45b58ea2935c5d2fe5e89e67d8",
|
"9c1e080e39adc7211c8c2c12cd652da3dc124299",
|
||||||
"f0e4583b72c887c87bd06797d1dc815f4f9e3300",
|
"78ed87028718b1b926d847ff6fc2f91d44e53d6d",
|
||||||
"ad8ddd8e6e4f8cb378e16617931cfd80515fb51f",
|
"280715f9b74ab29459d81edaf02b39e7a6acb13c",
|
||||||
"3badc126cf4c3b6ff224d57cb469f9be546b30e2",
|
"ea81bf91c90ae23dd9de012bfd7498613be00601",
|
||||||
"5a9dff2e04c3471caafb94962fe6fc1357305c1a"
|
"5342015bb12a486a1c563175a8a7129f0737c925"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue