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 */
 | 
			
		||||
    osMutexAcquire(ns_lock.id,osWaitForever);
 | 
			
		||||
    if (osMutexAcquire(ns_lock.id,osWaitForever) != osOK) {
 | 
			
		||||
        return TFM_ERROR_GENERIC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result = fn(arg0, arg1, arg2, arg3);
 | 
			
		||||
 | 
			
		||||
    osMutexRelease(ns_lock.id);
 | 
			
		||||
    if (osMutexRelease(ns_lock.id) != osOK) {
 | 
			
		||||
        return TFM_ERROR_GENERIC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +70,7 @@ uint32_t tfm_ns_lock_dispatch(veneer_fn fn,
 | 
			
		|||
/**
 | 
			
		||||
 * \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) {
 | 
			
		||||
        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). */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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_SIZE(size) (size + SHARED_DATA_ENTRY_HEADER_SIZE)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@
 | 
			
		|||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include "tfm_list.h"
 | 
			
		||||
#include "tfm_secure_api.h"
 | 
			
		||||
 | 
			
		||||
#ifndef TFM_SPM_MAX_ROT_SERV_NUM
 | 
			
		||||
#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] len           Length of memory reference in bytes
 | 
			
		||||
 * \param[in] ns_caller     From non-secure caller
 | 
			
		||||
 * \param[in] access        Type of access specified by the
 | 
			
		||||
 *                          \ref tfm_memory_access_e
 | 
			
		||||
 *
 | 
			
		||||
 * \retval IPC_SUCCESS      Success
 | 
			
		||||
 * \retval IPC_ERROR_BAD_PARAMETERS Bad parameters input
 | 
			
		||||
 * \retval IPC_ERROR_MEMORY_CHECK Check failed
 | 
			
		||||
 */
 | 
			
		||||
int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller);
 | 
			
		||||
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 */
 | 
			
		||||
void tfm_spm_init(void);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,25 +13,25 @@
 | 
			
		|||
__attribute__((naked))
 | 
			
		||||
uint32_t psa_framework_version(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_FRAMEWORK_VERSION));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
uint32_t psa_version(uint32_t sid)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_VERSION));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_VERSION));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_CONNECT));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_CONNECT));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
| 
						 | 
				
			
			@ -41,15 +41,15 @@ psa_status_t psa_call(psa_handle_t handle,
 | 
			
		|||
                      psa_outvec *out_vec,
 | 
			
		||||
                      size_t out_len)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_CALL));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_CALL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_close(psa_handle_t handle)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_CLOSE));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_CLOSE));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,25 +15,25 @@ __attribute__((naked))
 | 
			
		|||
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_WAIT));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_WAIT));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_GET));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_GET));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_SET_RHANDLE));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_SET_RHANDLE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__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)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_READ));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_READ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, size_t num_bytes)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_SKIP));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_SKIP));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
 | 
			
		||||
               const void *buffer, size_t num_bytes)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_WRITE));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_WRITE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_reply(psa_handle_t msg_handle, psa_status_t retval)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_REPLY));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_REPLY));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_notify(int32_t partition_id)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_NOTIFY));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_NOTIFY));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_clear(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_CLEAR));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_CLEAR));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked))
 | 
			
		||||
void psa_eoi(psa_signal_t irq_signal)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("SVC %0           \n"
 | 
			
		||||
          "BX LR            \n"
 | 
			
		||||
          : : "I" (TFM_SVC_PSA_EOI));
 | 
			
		||||
    __ASM volatile("SVC %0           \n"
 | 
			
		||||
                   "BX LR            \n"
 | 
			
		||||
                   : : "I" (TFM_SVC_PSA_EOI));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ void tfm_initialize_context(struct tfm_state_context *ctx,
 | 
			
		|||
#if defined(__ARM_ARCH_8M_MAIN__)
 | 
			
		||||
__attribute__((naked)) void PendSV_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "mrs     r0, psp                    \n"
 | 
			
		||||
        "mrs     r1, psplim                 \n"
 | 
			
		||||
        "push    {r0, r1, r2, lr}           \n"
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ __attribute__((naked)) void PendSV_Handler(void)
 | 
			
		|||
#elif defined(__ARM_ARCH_8M_BASE__)
 | 
			
		||||
__attribute__((naked)) void PendSV_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "mrs     r0, psp                    \n"
 | 
			
		||||
        "mrs     r1, psplim                 \n"
 | 
			
		||||
        "push    {r0, r1, r2, lr}           \n"
 | 
			
		||||
| 
						 | 
				
			
			@ -143,14 +143,14 @@ __attribute__((naked)) void PendSV_Handler(void)
 | 
			
		|||
/* Reserved for future usage */
 | 
			
		||||
__attribute__((naked)) void MemManage_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("b    .");
 | 
			
		||||
    __ASM volatile("b    .");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__attribute__((naked)) void BusFault_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("b    .");
 | 
			
		||||
    __ASM volatile("b    .");
 | 
			
		||||
}
 | 
			
		||||
__attribute__((naked)) void UsageFault_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM("b    .");
 | 
			
		||||
    __ASM volatile("b    .");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
#include "psa_client.h"
 | 
			
		||||
#include "psa_service.h"
 | 
			
		||||
#include "tfm_utils.h"
 | 
			
		||||
#include "platform/include/tfm_spm_hal.h"
 | 
			
		||||
#include "spm_api.h"
 | 
			
		||||
#include "spm_db.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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 */
 | 
			
		||||
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 == 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -514,55 +480,13 @@ int32_t tfm_memory_check(void *buffer, size_t len, int32_t ns_caller)
 | 
			
		|||
        return IPC_ERROR_MEMORY_CHECK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ns_caller) {
 | 
			
		||||
        base = (uintptr_t)NS_DATA_START;
 | 
			
		||||
        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;
 | 
			
		||||
        }
 | 
			
		||||
    if (access == TFM_MEMORY_ACCESS_RW) {
 | 
			
		||||
        err = tfm_core_has_write_access_to_region(buffer, len, ns_caller);
 | 
			
		||||
    } else {
 | 
			
		||||
        base = (uintptr_t)®ION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Base);
 | 
			
		||||
        limit = (uintptr_t)®ION_NAME(Image$$, ARM_LIB_HEAP, $$ZI$$Limit);
 | 
			
		||||
        if (memory_check_range(buffer, len, base, limit) == 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;
 | 
			
		||||
        }
 | 
			
		||||
        err = tfm_core_has_read_access_to_region(buffer, len, ns_caller);
 | 
			
		||||
    }
 | 
			
		||||
    if (err == 1) {
 | 
			
		||||
        return IPC_SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
         * 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),
 | 
			
		||||
            ns_caller) != IPC_SUCCESS) {
 | 
			
		||||
            ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
 | 
			
		||||
            tfm_panic();
 | 
			
		||||
        }
 | 
			
		||||
        if (tfm_memory_check((void *)args[2], sizeof(uint32_t),
 | 
			
		||||
            ns_caller) != IPC_SUCCESS) {
 | 
			
		||||
            ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
 | 
			
		||||
            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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 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),
 | 
			
		||||
        ns_caller) != IPC_SUCCESS) {
 | 
			
		||||
        ns_caller, TFM_MEMORY_ACCESS_RO) != IPC_SUCCESS) {
 | 
			
		||||
        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),
 | 
			
		||||
        ns_caller) != IPC_SUCCESS) {
 | 
			
		||||
        ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
 | 
			
		||||
        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));
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * It is a fatal error if an invalid payload memory reference
 | 
			
		||||
     * was provided.
 | 
			
		||||
     * For client input vector, it is a fatal error if the provided payload
 | 
			
		||||
     * memory reference was invalid or not readable.
 | 
			
		||||
     */
 | 
			
		||||
    for (i = 0; i < in_num; i++) {
 | 
			
		||||
        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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /*
 | 
			
		||||
     * 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++) {
 | 
			
		||||
        if (tfm_memory_check(outvecs[i].base, outvecs[i].len,
 | 
			
		||||
            ns_caller) != IPC_SUCCESS) {
 | 
			
		||||
            ns_caller, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
 | 
			
		||||
            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
 | 
			
		||||
     * reference.
 | 
			
		||||
     * Write the message to the service buffer. It is a fatal error if the
 | 
			
		||||
     * input msg pointer is not a valid memory reference or not read-write.
 | 
			
		||||
     */
 | 
			
		||||
    if (tfm_memory_check((void *)msg, sizeof(psa_msg_t),
 | 
			
		||||
        false) != IPC_SUCCESS) {
 | 
			
		||||
        false, TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
 | 
			
		||||
        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
 | 
			
		||||
     * not writable
 | 
			
		||||
     * Copy the client data to the service buffer. It is a fatal error
 | 
			
		||||
     * 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) != IPC_SUCCESS) {
 | 
			
		||||
    if (tfm_memory_check(buffer, num_bytes, false,
 | 
			
		||||
        TFM_MEMORY_ACCESS_RW) != IPC_SUCCESS) {
 | 
			
		||||
        tfm_panic();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -671,8 +688,12 @@ static void tfm_svcall_psa_write(uint32_t *args)
 | 
			
		|||
        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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,9 +51,9 @@ struct tfm_exc_stack_t {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#define LOG_MSG_THR(MSG) \
 | 
			
		||||
            __ASM("MOV r0, %0\n" \
 | 
			
		||||
                  "SVC %1\n" \
 | 
			
		||||
                  : : "r" (MSG), "I" (TFM_SVC_PRINT))
 | 
			
		||||
            __ASM volatile("MOV r0, %0\n" \
 | 
			
		||||
                           "SVC %1\n" \
 | 
			
		||||
                           : : "r" (MSG), "I" (TFM_SVC_PRINT))
 | 
			
		||||
 | 
			
		||||
#define LOG_MSG(MSG) \
 | 
			
		||||
            do { \
 | 
			
		||||
| 
						 | 
				
			
			@ -96,14 +96,14 @@ __STATIC_INLINE uint32_t __get_active_exc_num(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
__attribute__ ((always_inline))
 | 
			
		||||
__STATIC_INLINE void __set_CONTROL_SPSEL(int32_t SPSEL)
 | 
			
		||||
__STATIC_INLINE void __set_CONTROL_SPSEL(uint32_t SPSEL)
 | 
			
		||||
{
 | 
			
		||||
    CONTROL_Type ctrl;
 | 
			
		||||
 | 
			
		||||
    ctrl.w = __get_CONTROL();
 | 
			
		||||
    ctrl.b.SPSEL = SPSEL;
 | 
			
		||||
    __set_CONTROL(ctrl.w);
 | 
			
		||||
    __asm("ISB");
 | 
			
		||||
    __ISB();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
{
 | 
			
		||||
    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:
 | 
			
		||||
     *        - 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
 | 
			
		||||
     *        - 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
 | 
			
		|||
    uint8_t *ptr;
 | 
			
		||||
    uint32_t 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;
 | 
			
		||||
    uintptr_t tlv_end, offset;
 | 
			
		||||
    uint32_t res;
 | 
			
		||||
| 
						 | 
				
			
			@ -88,8 +88,8 @@ void tfm_core_get_boot_data_handler(uint32_t args[])
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* Get the boundaries of TLV section */
 | 
			
		||||
    tlv_header = (struct shared_data_tlv_header *)BOOT_TFM_SHARED_DATA_BASE;
 | 
			
		||||
    tlv_end = BOOT_TFM_SHARED_DATA_BASE + tlv_header->tlv_tot_len;
 | 
			
		||||
    boot_data = (struct tfm_boot_data *)BOOT_TFM_SHARED_DATA_BASE;
 | 
			
		||||
    tlv_end = BOOT_TFM_SHARED_DATA_BASE + boot_data->header.tlv_tot_len;
 | 
			
		||||
    offset  = BOOT_TFM_SHARED_DATA_BASE + SHARED_DATA_HEADER_SIZE;
 | 
			
		||||
 | 
			
		||||
    /* 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;
 | 
			
		||||
        return;
 | 
			
		||||
    } else {
 | 
			
		||||
        tlv_header = (struct shared_data_tlv_header *)buf_start;
 | 
			
		||||
        tlv_header->tlv_magic   = SHARED_DATA_TLV_INFO_MAGIC;
 | 
			
		||||
        tlv_header->tlv_tot_len = SHARED_DATA_HEADER_SIZE;
 | 
			
		||||
        ptr = (uint8_t *)tlv_header + SHARED_DATA_HEADER_SIZE;
 | 
			
		||||
        boot_data = (struct tfm_boot_data *)buf_start;
 | 
			
		||||
        boot_data->header.tlv_magic   = SHARED_DATA_TLV_INFO_MAGIC;
 | 
			
		||||
        boot_data->header.tlv_tot_len = SHARED_DATA_HEADER_SIZE;
 | 
			
		||||
        ptr = boot_data->data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 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);
 | 
			
		||||
        if (GET_MAJOR(tlv_entry.tlv_type) == tlv_major) {
 | 
			
		||||
            /* 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;
 | 
			
		||||
                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);
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -43,8 +43,8 @@ __asm("  .global __ARM_use_no_argv\n");
 | 
			
		|||
#ifndef TFM_LVL
 | 
			
		||||
#error TFM_LVL is not defined!
 | 
			
		||||
#endif
 | 
			
		||||
#if (TFM_LVL != 1) && (TFM_LVL != 3)
 | 
			
		||||
#error Only TFM_LVL 1 and 3 are supported!
 | 
			
		||||
#if (TFM_LVL != 1) && (TFM_LVL != 2) && (TFM_LVL != 3)
 | 
			
		||||
#error Only TFM_LVL 1, 2 and 3 are supported!
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* 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 */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -152,9 +169,13 @@ void tfm_core_spm_request_handler(const struct tfm_exc_stack_t *svc_ctx)
 | 
			
		|||
 | 
			
		||||
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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
    tfm_spm_init();
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -187,10 +214,5 @@ int main(void)
 | 
			
		|||
    tfm_spm_partition_set_state(TFM_SP_NON_SECURE_ID,
 | 
			
		||||
                              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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -8,11 +8,11 @@
 | 
			
		|||
#ifndef __TFM_CORE_H__
 | 
			
		||||
#define __TFM_CORE_H__
 | 
			
		||||
 | 
			
		||||
#include "arm_cmse.h"
 | 
			
		||||
#include <arm_cmse.h>
 | 
			
		||||
#include "tfm_svc.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;
 | 
			
		||||
 | 
			
		||||
#endif /* __TFM_CORE_H__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,6 @@
 | 
			
		|||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "secure_utilities.h"
 | 
			
		||||
#include "arm_acle.h"
 | 
			
		||||
#include "tfm_svc.h"
 | 
			
		||||
#include "tfm_secure_api.h"
 | 
			
		||||
#include "region_defs.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -66,9 +65,9 @@ void SecureFault_Handler(void)
 | 
			
		|||
 | 
			
		||||
    /* Only save the context if sp is valid */
 | 
			
		||||
    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_LIMIT - sizeof(tfm_fault_context) + 1)) {
 | 
			
		||||
         sp <= (NS_DATA_LIMIT - sizeof(tfm_fault_context)) + 1)) {
 | 
			
		||||
        tfm_memcpy(&tfm_fault_context,
 | 
			
		||||
                   (const void *)sp,
 | 
			
		||||
                   sizeof(tfm_fault_context));
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +102,7 @@ void HardFault_Handler(void)
 | 
			
		|||
#if defined(__ARM_ARCH_8M_MAIN__)
 | 
			
		||||
__attribute__((naked)) void SVC_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
    "TST     lr, #4\n"  /* Check store SP in thread mode to r0 */
 | 
			
		||||
    "IT      EQ\n"
 | 
			
		||||
    "BXEQ    lr\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +115,7 @@ __attribute__((naked)) void SVC_Handler(void)
 | 
			
		|||
#elif defined(__ARM_ARCH_8M_BASE__)
 | 
			
		||||
__attribute__((naked)) void SVC_Handler(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
    ".syntax unified\n"
 | 
			
		||||
    "MOVS    r0, #4\n"  /* Check store SP in thread mode to r0 */
 | 
			
		||||
    "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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ void jump_to_ns_code(void);
 | 
			
		|||
 * \brief Called if veneer is running in thread mode
 | 
			
		||||
 */
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /* 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();
 | 
			
		||||
#ifdef PRINT_NSPM_DEBUG
 | 
			
		||||
    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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -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, \
 | 
			
		||||
                (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
 | 
			
		||||
int32_t tfm_core_ns_ipc_request(void *fn, int32_t arg1, int32_t arg2,
 | 
			
		||||
                                int32_t arg3, int32_t arg4)
 | 
			
		||||
{
 | 
			
		||||
    int32_t args[4] = {arg1, arg2, arg3, arg4};
 | 
			
		||||
    volatile struct tfm_sfn_req_s desc;
 | 
			
		||||
    struct tfm_sfn_req_s *desc_ptr = &desc;
 | 
			
		||||
    int32_t res;
 | 
			
		||||
    struct tfm_sfn_req_s desc = {0};
 | 
			
		||||
 | 
			
		||||
    desc.sfn = fn;
 | 
			
		||||
    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 */
 | 
			
		||||
        return TFM_ERROR_INVALID_EXC_MODE;
 | 
			
		||||
    } else {
 | 
			
		||||
        __ASM("MOV r0, %1\n"
 | 
			
		||||
              "SVC %2\n"
 | 
			
		||||
              "MOV %0, r0\n"
 | 
			
		||||
              : "=r" (res)
 | 
			
		||||
              : "r" (desc_ptr), "I" (TFM_SVC_IPC_REQUEST)
 | 
			
		||||
              : "r0");
 | 
			
		||||
        return res;
 | 
			
		||||
        return tfm_core_ipc_request(&desc);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,17 +50,17 @@ static int32_t is_iovec_api_call(void)
 | 
			
		|||
    return curr_part_data->iovec_api;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32_t *prepare_partition_ctx(
 | 
			
		||||
            struct tfm_exc_stack_t *svc_ctx,
 | 
			
		||||
            struct tfm_sfn_req_s *desc_ptr,
 | 
			
		||||
            int32_t *dst)
 | 
			
		||||
static uint32_t *prepare_partition_ctx(
 | 
			
		||||
            const struct tfm_exc_stack_t *svc_ctx,
 | 
			
		||||
            const struct tfm_sfn_req_s *desc_ptr,
 | 
			
		||||
            uint32_t *dst)
 | 
			
		||||
{
 | 
			
		||||
    /* 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 */
 | 
			
		||||
    *(--dst) = svc_ctx->RetAddr;
 | 
			
		||||
    /* LR = sfn address */
 | 
			
		||||
    *(--dst) = (int32_t)desc_ptr->sfn;
 | 
			
		||||
    *(--dst) = (uint32_t)desc_ptr->sfn;
 | 
			
		||||
    /* R12 = don't care */
 | 
			
		||||
    *(--dst) = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,20 +74,20 @@ static int32_t *prepare_partition_ctx(
 | 
			
		|||
    return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int32_t *prepare_partition_iovec_ctx(
 | 
			
		||||
                             struct tfm_exc_stack_t *svc_ctx,
 | 
			
		||||
                             struct tfm_sfn_req_s *desc_ptr,
 | 
			
		||||
                             struct iovec_args_t *iovec_args,
 | 
			
		||||
                             int32_t *dst)
 | 
			
		||||
static uint32_t *prepare_partition_iovec_ctx(
 | 
			
		||||
                             const struct tfm_exc_stack_t *svc_ctx,
 | 
			
		||||
                             const struct tfm_sfn_req_s *desc_ptr,
 | 
			
		||||
                             const struct iovec_args_t *iovec_args,
 | 
			
		||||
                             uint32_t *dst)
 | 
			
		||||
{
 | 
			
		||||
    /* 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 */
 | 
			
		||||
    *(--dst) = svc_ctx->RetAddr;
 | 
			
		||||
    /* LR = sfn address */
 | 
			
		||||
    *(--dst) = (int32_t)desc_ptr->sfn;
 | 
			
		||||
    *(--dst) = (uint32_t)desc_ptr->sfn;
 | 
			
		||||
    /* R12 = don't care */
 | 
			
		||||
    *(--dst) = 0;
 | 
			
		||||
    *(--dst) = 0U;
 | 
			
		||||
 | 
			
		||||
    /* R0-R3 = sfn arguments */
 | 
			
		||||
    *(--dst) = iovec_args->out_len;
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ static int32_t *prepare_partition_iovec_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)
 | 
			
		||||
{
 | 
			
		||||
    /* 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.
 | 
			
		||||
 */
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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.
 | 
			
		||||
 */
 | 
			
		||||
static int32_t has_read_access_to_region(const void *p, size_t s,
 | 
			
		||||
                                         int32_t ns_caller)
 | 
			
		||||
int32_t tfm_core_has_read_access_to_region(const void *p, size_t s,
 | 
			
		||||
                                           uint32_t ns_caller)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t flags = CMSE_MPU_UNPRIV|CMSE_MPU_READ;
 | 
			
		||||
    int flags = CMSE_MPU_UNPRIV|CMSE_MPU_READ;
 | 
			
		||||
 | 
			
		||||
    if (ns_caller) {
 | 
			
		||||
        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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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.
 | 
			
		||||
 */
 | 
			
		||||
static int32_t has_write_access_to_region(void *p, size_t s, int32_t ns_caller)
 | 
			
		||||
int32_t tfm_core_has_write_access_to_region(void *p, size_t s,
 | 
			
		||||
                                            uint32_t ns_caller)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t flags = CMSE_MPU_UNPRIV|CMSE_MPU_READWRITE;
 | 
			
		||||
    int flags = CMSE_MPU_UNPRIV|CMSE_MPU_READWRITE;
 | 
			
		||||
 | 
			
		||||
    if (ns_caller) {
 | 
			
		||||
        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
 | 
			
		||||
 *         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];
 | 
			
		||||
    size_t in_len = desc_ptr->args[1];
 | 
			
		||||
    size_t in_len;
 | 
			
		||||
    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;
 | 
			
		||||
 | 
			
		||||
    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 */
 | 
			
		||||
    if ((in_len > PSA_MAX_IOVEC) || (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_vec == NULL) ||
 | 
			
		||||
            (has_write_access_to_region(in_vec, sizeof(psa_invec)*in_len,
 | 
			
		||||
                                      desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
            (tfm_core_has_write_access_to_region(in_vec,
 | 
			
		||||
                                                 sizeof(psa_invec)*in_len,
 | 
			
		||||
                                                 desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
            return TFM_ERROR_INVALID_PARAMETER;
 | 
			
		||||
        }
 | 
			
		||||
    } 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_vec == NULL) ||
 | 
			
		||||
            (has_write_access_to_region(out_vec, sizeof(psa_outvec)*out_len,
 | 
			
		||||
                                      desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
            (tfm_core_has_write_access_to_region(out_vec,
 | 
			
		||||
                                                 sizeof(psa_outvec)*out_len,
 | 
			
		||||
                                                 desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
            return TFM_ERROR_INVALID_PARAMETER;
 | 
			
		||||
        }
 | 
			
		||||
    } 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) {
 | 
			
		||||
        if (in_vec[i].len > 0) {
 | 
			
		||||
            if ((in_vec[i].base == NULL) ||
 | 
			
		||||
                (has_read_access_to_region(in_vec[i].base, in_vec[i].len,
 | 
			
		||||
                                          desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
                (tfm_core_has_read_access_to_region(in_vec[i].base,
 | 
			
		||||
                                                  in_vec[i].len,
 | 
			
		||||
                                                  desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
                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) {
 | 
			
		||||
        if (out_vec[i].len > 0) {
 | 
			
		||||
            if ((out_vec[i].base == NULL) ||
 | 
			
		||||
                (has_write_access_to_region(out_vec[i].base, out_vec[i].len,
 | 
			
		||||
                                           desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
                (tfm_core_has_write_access_to_region(out_vec[i].base,
 | 
			
		||||
                                                  out_vec[i].len,
 | 
			
		||||
                                                  desc_ptr->ns_caller) != 1)) {
 | 
			
		||||
                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,
 | 
			
		||||
                               const struct iovec_args_t *source)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    size_t i;
 | 
			
		||||
 | 
			
		||||
    target->in_len = source->in_len;
 | 
			
		||||
    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 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 *)
 | 
			
		||||
                    ((uint32_t)®ION_NAME(Image$$, TFM_SECURE_STACK, $$ZI$$Limit)-
 | 
			
		||||
                     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));
 | 
			
		||||
 | 
			
		||||
            /* Prepare the partition context, update stack ptr */
 | 
			
		||||
            psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
 | 
			
		||||
                                                        iovec_args,
 | 
			
		||||
                                                     (int32_t *)partition_psp);
 | 
			
		||||
                                                     (uint32_t *)partition_psp);
 | 
			
		||||
        } else {
 | 
			
		||||
            /* Prepare the partition context, update stack ptr */
 | 
			
		||||
            psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
 | 
			
		||||
                                                  (int32_t *)partition_psp);
 | 
			
		||||
                                                  (uint32_t *)partition_psp);
 | 
			
		||||
        }
 | 
			
		||||
        __set_PSP(psp);
 | 
			
		||||
        __set_PSPLIM(partition_psplim);
 | 
			
		||||
| 
						 | 
				
			
			@ -505,17 +497,20 @@ static int32_t tfm_start_partition(struct tfm_sfn_req_s *desc_ptr,
 | 
			
		|||
        iovec_args =
 | 
			
		||||
        (struct iovec_args_t *)(tfm_spm_partition_get_stack_top(partition_idx) -
 | 
			
		||||
        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));
 | 
			
		||||
 | 
			
		||||
        /* Prepare the partition context, update stack ptr */
 | 
			
		||||
        psp = (uint32_t)prepare_partition_iovec_ctx(svc_ctx, desc_ptr,
 | 
			
		||||
                                                    iovec_args,
 | 
			
		||||
                                                    (int32_t *)partition_psp);
 | 
			
		||||
                                                    (uint32_t *)partition_psp);
 | 
			
		||||
    } else {
 | 
			
		||||
        /* Prepare the partition context, update stack ptr */
 | 
			
		||||
        psp = (uint32_t)prepare_partition_ctx(svc_ctx, desc_ptr,
 | 
			
		||||
                                              (int32_t *)partition_psp);
 | 
			
		||||
                                              (uint32_t *)partition_psp);
 | 
			
		||||
    }
 | 
			
		||||
    __set_PSP(psp);
 | 
			
		||||
    __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_flags;
 | 
			
		||||
    uint32_t psp = __get_PSP();
 | 
			
		||||
    int i;
 | 
			
		||||
    size_t i;
 | 
			
		||||
    struct tfm_exc_stack_t *svc_ctx = (struct tfm_exc_stack_t *)psp;
 | 
			
		||||
    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) ||
 | 
			
		||||
        (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(
 | 
			
		||||
        struct tfm_sfn_req_s *desc_ptr)
 | 
			
		||||
        const struct tfm_sfn_req_s *desc_ptr)
 | 
			
		||||
{
 | 
			
		||||
    /* Check partition idx validity */
 | 
			
		||||
    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 */
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -8,11 +8,12 @@
 | 
			
		|||
#ifndef __TFM_SECURE_API_H__
 | 
			
		||||
#define __TFM_SECURE_API_H__
 | 
			
		||||
 | 
			
		||||
#include "arm_cmse.h"
 | 
			
		||||
#include <arm_cmse.h>
 | 
			
		||||
#include "tfm_svc.h"
 | 
			
		||||
#include "secure_utilities.h"
 | 
			
		||||
#include "tfm_core.h"
 | 
			
		||||
#include "tfm_api.h"
 | 
			
		||||
#include "bl2/include/tfm_boot_status.h"
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * \def __tfm_secure_gateway_attributes__
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +47,7 @@ struct tfm_sfn_req_s {
 | 
			
		|||
    int32_t *args;
 | 
			
		||||
    uint32_t caller_part_idx;
 | 
			
		||||
    int32_t iovec_api;
 | 
			
		||||
    int32_t ns_caller : 1;
 | 
			
		||||
    uint32_t ns_caller;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum tfm_buffer_share_region_e {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,13 +82,44 @@ extern int32_t tfm_core_memory_permission_check(const void *ptr,
 | 
			
		|||
                                                uint32_t size,
 | 
			
		||||
                                                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);
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \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) \
 | 
			
		||||
        return tfm_core_partition_request(id, fn, TFM_SFN_API_IOVEC, \
 | 
			
		||||
                (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.sfn = fn;
 | 
			
		||||
    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;
 | 
			
		||||
    if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
 | 
			
		||||
        /* 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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +13,7 @@
 | 
			
		|||
#include "secure_fw/include/tfm_spm_services_api.h"
 | 
			
		||||
 | 
			
		||||
uint8_t *tfm_scratch_area;
 | 
			
		||||
int32_t tfm_scratch_area_size;
 | 
			
		||||
uint32_t tfm_scratch_area_size;
 | 
			
		||||
nsfptr_t ns_entry;
 | 
			
		||||
 | 
			
		||||
void jump_to_ns_code(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -36,9 +36,9 @@ void jump_to_ns_code(void)
 | 
			
		|||
 | 
			
		||||
#if defined(__ARM_ARCH_8M_MAIN__)
 | 
			
		||||
__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"
 | 
			
		||||
          "SVC    %[SVC_REQ]\n"
 | 
			
		||||
          "MOV    r4, #0\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -58,9 +58,9 @@ __attribute__((naked)) int32_t tfm_core_sfn_request(
 | 
			
		|||
}
 | 
			
		||||
#elif defined(__ARM_ARCH_8M_BASE__)
 | 
			
		||||
__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"
 | 
			
		||||
          "PUSH   {lr}\n"
 | 
			
		||||
          "PUSH   {r4-r7}\n"
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ int32_t tfm_core_memory_permission_check(const void *ptr,
 | 
			
		|||
                                         uint32_t len,
 | 
			
		||||
                                         int32_t access)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
  __ASM volatile(
 | 
			
		||||
        "SVC    %0\n"
 | 
			
		||||
        "BX     lr\n"
 | 
			
		||||
        : : "I" (TFM_SVC_MEMORY_CHECK));
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +113,7 @@ int32_t tfm_core_memory_permission_check(const void *ptr,
 | 
			
		|||
__attribute__((naked))
 | 
			
		||||
int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "SVC %0\n"
 | 
			
		||||
        "BX LR\n"
 | 
			
		||||
        : : "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))
 | 
			
		||||
int32_t tfm_spm_request_reset_vote(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "MOVS   R0, %0\n"
 | 
			
		||||
        "B      tfm_spm_request\n"
 | 
			
		||||
        : : "I" (TFM_SPM_REQUEST_RESET_VOTE));
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ int32_t tfm_spm_request_reset_vote(void)
 | 
			
		|||
__attribute__((naked))
 | 
			
		||||
int32_t tfm_spm_request(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "SVC    %0\n"
 | 
			
		||||
        "BX     lr\n"
 | 
			
		||||
        : : "I" (TFM_SVC_SPM_REQUEST));
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ int32_t tfm_spm_request(void)
 | 
			
		|||
__attribute__((naked))
 | 
			
		||||
int32_t tfm_core_validate_secure_caller(void)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "SVC    %0\n"
 | 
			
		||||
        "BX     lr\n"
 | 
			
		||||
        : : "I" (TFM_SVC_VALIDATE_SECURE_CALLER));
 | 
			
		||||
| 
						 | 
				
			
			@ -149,16 +149,18 @@ int32_t tfm_core_validate_secure_caller(void)
 | 
			
		|||
__attribute__((naked))
 | 
			
		||||
int32_t tfm_core_set_buffer_area(enum tfm_buffer_share_region_e share)
 | 
			
		||||
{
 | 
			
		||||
    __ASM(
 | 
			
		||||
    __ASM volatile(
 | 
			
		||||
        "SVC    %0\n"
 | 
			
		||||
        "BX     lr\n"
 | 
			
		||||
        : : "I" (TFM_SVC_SET_SHARE_AREA));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__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"
 | 
			
		||||
        "BX     lr\n"
 | 
			
		||||
        : : "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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +43,6 @@ typedef enum {
 | 
			
		|||
#endif
 | 
			
		||||
} 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__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ typedef enum {
 | 
			
		|||
 * returned.
 | 
			
		||||
 */
 | 
			
		||||
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,
 | 
			
		||||
    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",
 | 
			
		||||
                partition->static_data.partition_id);
 | 
			
		||||
    } else {
 | 
			
		||||
        printf("Unknown partition error %d for partition id 0x%08X\r\n",
 | 
			
		||||
            err_type, partition->static_data.partition_id);
 | 
			
		||||
        printf(
 | 
			
		||||
            "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
 | 
			
		||||
    tfm_spm_partition_set_state(partition->static_data.partition_id,
 | 
			
		||||
            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)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
 | 
			
		||||
    if (partition_id == INVALID_PARTITION_ID) {
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    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 */
 | 
			
		||||
    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 */
 | 
			
		||||
#if TFM_LVL != 1
 | 
			
		||||
    extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
 | 
			
		||||
    extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
 | 
			
		||||
    uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
 | 
			
		||||
    uint32_t psp_stack_top    = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
 | 
			
		||||
        return SPM_ERR_INVALID_CONFIG;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
     */
 | 
			
		||||
    part_ptr->memory_data.rw_start     = psp_stack_bottom;
 | 
			
		||||
#else
 | 
			
		||||
    part_ptr->stack_limit = psp_stack_bottom;
 | 
			
		||||
    part_ptr->stack_size = psp_stack_top - psp_stack_bottom;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
 | 
			
		||||
| 
						 | 
				
			
			@ -121,8 +139,10 @@ enum spm_err_t tfm_spm_db_init(void)
 | 
			
		|||
    part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
 | 
			
		||||
    ++g_spm_partition_db.partition_count;
 | 
			
		||||
 | 
			
		||||
    /* Add user-defined secure partitions */
 | 
			
		||||
    #include "tfm_partition_list.inc"
 | 
			
		||||
    err = add_user_defined_partitions();
 | 
			
		||||
    if (err != SPM_ERR_OK) {
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_spm_partition_db.is_init = 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +174,7 @@ enum spm_err_t tfm_spm_partition_init(void)
 | 
			
		|||
            int32_t res;
 | 
			
		||||
 | 
			
		||||
            desc.args = args;
 | 
			
		||||
            desc.ns_caller = 0;
 | 
			
		||||
            desc.ns_caller = 0U;
 | 
			
		||||
            desc.iovec_api = TFM_SFN_API_IOVEC;
 | 
			
		||||
            desc.sfn = (sfn_t)part->static_data.partition_init;
 | 
			
		||||
            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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 =
 | 
			
		||||
            &g_spm_partition_db.partitions[partition_idx].runtime_data;
 | 
			
		||||
    int32_t i;
 | 
			
		||||
    size_t i;
 | 
			
		||||
 | 
			
		||||
    runtime_data->iovec_args.in_len = args[1];
 | 
			
		||||
    for (i = 0; i < runtime_data->iovec_args.in_len; ++i) {
 | 
			
		||||
    if ((args[1] < 0) || (args[3] < 0)) {
 | 
			
		||||
        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 =
 | 
			
		||||
                                                 ((psa_invec *)args[0])[i].base;
 | 
			
		||||
        runtime_data->iovec_args.in_vec[i].len = ((psa_invec *)args[0])[i].len;
 | 
			
		||||
    }
 | 
			
		||||
    runtime_data->iovec_args.out_len = args[3];
 | 
			
		||||
    for (i = 0; i < runtime_data->iovec_args.out_len; ++i) {
 | 
			
		||||
    runtime_data->iovec_args.out_len = (size_t)args[3];
 | 
			
		||||
    for (i = 0U; i < runtime_data->iovec_args.out_len; ++i) {
 | 
			
		||||
        runtime_data->iovec_args.out_vec[i].base =
 | 
			
		||||
                                                ((psa_outvec *)args[2])[i].base;
 | 
			
		||||
        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->iovec_api = 1;
 | 
			
		||||
 | 
			
		||||
    return SPM_ERR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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_ALREADY_ACTIVE,
 | 
			
		||||
    SPM_ERR_PARTITION_NOT_AVAILABLE,
 | 
			
		||||
    SPM_ERR_INVALID_PARAMETER,
 | 
			
		||||
    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[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 assumes that the iovecs that are passed in args are
 | 
			
		||||
 *       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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ typedef psa_status_t(*sp_init_function)(void);
 | 
			
		|||
#define TFM_PARTITION_TYPE_APP   "APPLICATION-ROT"
 | 
			
		||||
#define TFM_PARTITION_TYPE_PSA   "PSA-ROT"
 | 
			
		||||
 | 
			
		||||
#define TFM_STACK_SIZE  1024
 | 
			
		||||
#define TFM_STACK_SIZE           (1024 * 5)
 | 
			
		||||
 | 
			
		||||
#ifdef TFM_PSA_API
 | 
			
		||||
enum tfm_partition_priority {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,21 +115,21 @@ struct spm_partition_db_t {
 | 
			
		|||
        ++g_spm_partition_db.partition_count;                                \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
#define PARTITION_ADD_INIT_FUNC(partition, init_func)                 \
 | 
			
		||||
    do {                                                              \
 | 
			
		||||
        extern int32_t init_func(void);                               \
 | 
			
		||||
        uint32_t partition_idx = get_partition_idx(partition##_ID);   \
 | 
			
		||||
        struct spm_partition_desc_t *part_ptr =                       \
 | 
			
		||||
            &(g_spm_partition_db.partitions[partition_idx]);          \
 | 
			
		||||
        part_ptr->static_data.partition_init = init_func;             \
 | 
			
		||||
#define PARTITION_ADD_INIT_FUNC(partition, init_func)                     \
 | 
			
		||||
    do {                                                                  \
 | 
			
		||||
        extern int32_t init_func(void);                                   \
 | 
			
		||||
        uint32_t partition_idx = get_partition_idx(partition##_ID);       \
 | 
			
		||||
        struct spm_partition_desc_t *part_ptr =                           \
 | 
			
		||||
            &(g_spm_partition_db.partitions[partition_idx]);              \
 | 
			
		||||
        part_ptr->static_data.partition_init = init_func;                 \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
#define PARTITION_ADD_PERIPHERAL(partition, peripheral)               \
 | 
			
		||||
    do {                                                               \
 | 
			
		||||
        uint32_t partition_idx = get_partition_idx(partition##_ID);    \
 | 
			
		||||
        struct spm_partition_desc_t *part_ptr =                        \
 | 
			
		||||
            &(g_spm_partition_db.partitions[partition_idx]);           \
 | 
			
		||||
        part_ptr->platform_data = peripheral;                          \
 | 
			
		||||
#define PARTITION_ADD_PERIPHERAL(partition, peripheral)                    \
 | 
			
		||||
    do {                                                                   \
 | 
			
		||||
        uint32_t partition_idx = get_partition_idx(partition##_ID);        \
 | 
			
		||||
        struct spm_partition_desc_t *part_ptr =                            \
 | 
			
		||||
            &(g_spm_partition_db.partitions[partition_idx]);               \
 | 
			
		||||
        part_ptr->platform_data = peripheral;                              \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
#endif /* __SPM_DB_SETUP_H__ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ extern "C" {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "tfm_api.h"
 | 
			
		||||
 | 
			
		||||
typedef int32_t (*veneer_fn) (uint32_t arg0, uint32_t arg1,
 | 
			
		||||
                      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
 | 
			
		||||
 *          to initialize the TFM NS lock object
 | 
			
		||||
 */
 | 
			
		||||
uint32_t tfm_ns_lock_init();
 | 
			
		||||
enum tfm_status_e tfm_ns_lock_init();
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ extern "C" {
 | 
			
		|||
 * \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
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ enum tfm_svc_num {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
/* 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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,75 +1,75 @@
 | 
			
		|||
{
 | 
			
		||||
  "files" : [
 | 
			
		||||
  "files": [
 | 
			
		||||
    {
 | 
			
		||||
      "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"
 | 
			
		||||
      "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"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "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"
 | 
			
		||||
      "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"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_file" : "interface/include/psa_client.h",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/psa_client.h"
 | 
			
		||||
      "src_file": "interface/include/psa_client.h",
 | 
			
		||||
      "dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/psa_client.h"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_file" : "interface/include/psa_service.h",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/psa_service.h"
 | 
			
		||||
      "src_file": "interface/include/psa_service.h",
 | 
			
		||||
      "dest_file": "components/TARGET_PSA/TARGET_TFM/interface/include/psa_service.h"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_file" : "interface/include/tfm_api.h",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/interface/include/tfm_api.h"
 | 
			
		||||
      "src_file": "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",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/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"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_file" : "interface/include/tfm_ns_svc.h",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/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"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_file" : "interface/include/tfm_nspm_svc_handler.h",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/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"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_file" : "platform/include/tfm_spm_hal.h",
 | 
			
		||||
      "dest_file" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/platform/include/tfm_spm_hal.h"
 | 
			
		||||
      "src_file": "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",
 | 
			
		||||
      "dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core"
 | 
			
		||||
      "src_folder": "secure_fw/core",
 | 
			
		||||
      "dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_folder" : "secure_fw/core/ipc",
 | 
			
		||||
      "dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc"
 | 
			
		||||
      "src_folder": "secure_fw/core/ipc",
 | 
			
		||||
      "dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/core/ipc"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_folder" : "secure_fw/core/ipc/include",
 | 
			
		||||
      "dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/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"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_folder" : "secure_fw/include",
 | 
			
		||||
      "dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/include"
 | 
			
		||||
      "src_folder": "secure_fw/include",
 | 
			
		||||
      "dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/include"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_folder" : "secure_fw/spm",
 | 
			
		||||
      "dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/spm"
 | 
			
		||||
      "src_folder": "secure_fw/spm",
 | 
			
		||||
      "dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/secure_fw/spm"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src_folder" : "bl2/include",
 | 
			
		||||
      "dest_folder" : "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/bl2/include"
 | 
			
		||||
      "src_folder": "bl2/include",
 | 
			
		||||
      "dest_folder": "components/TARGET_PSA/TARGET_TFM/COMPONENT_SPE/bl2/include"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "commit_sha" : [
 | 
			
		||||
    "185d2865da45cc2c6ac3acb755b90c196934d7d5",
 | 
			
		||||
    "e89c1a68ce8f690ce0d6029cd9196b03906060de",
 | 
			
		||||
    "3fbc73e046e59e45b58ea2935c5d2fe5e89e67d8",
 | 
			
		||||
    "f0e4583b72c887c87bd06797d1dc815f4f9e3300",
 | 
			
		||||
    "ad8ddd8e6e4f8cb378e16617931cfd80515fb51f",
 | 
			
		||||
    "3badc126cf4c3b6ff224d57cb469f9be546b30e2",
 | 
			
		||||
    "5a9dff2e04c3471caafb94962fe6fc1357305c1a"
 | 
			
		||||
  "commit_sha": [
 | 
			
		||||
    "fb068d2cb4e89cacf0e9f413075bb4b211f1484f",
 | 
			
		||||
    "5d41a2aeae71b13f2763bea4e55899646291e0eb",
 | 
			
		||||
    "9c1e080e39adc7211c8c2c12cd652da3dc124299",
 | 
			
		||||
    "78ed87028718b1b926d847ff6fc2f91d44e53d6d",
 | 
			
		||||
    "280715f9b74ab29459d81edaf02b39e7a6acb13c",
 | 
			
		||||
    "ea81bf91c90ae23dd9de012bfd7498613be00601",
 | 
			
		||||
    "5342015bb12a486a1c563175a8a7129f0737c925"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue