blob: e2551f00db41d4ea804082392a6d4556748f0568 [file] [log] [blame]
/*
* Copyright (c) 2019,2020 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <sys/printk.h>
#include "tfm_api.h"
#include "tfm_ns_interface.h"
#ifdef TFM_PSA_API
#include "psa_manifest/sid.h"
#endif
K_MUTEX_DEFINE(tfm_mutex);
int32_t tfm_ns_interface_dispatch(veneer_fn fn,
uint32_t arg0, uint32_t arg1,
uint32_t arg2, uint32_t arg3)
{
int32_t result;
/* TFM request protected by NS lock */
if (k_mutex_lock(&tfm_mutex, K_FOREVER) != 0) {
return (int32_t)TFM_ERROR_GENERIC;
}
result = fn(arg0, arg1, arg2, arg3);
k_mutex_unlock(&tfm_mutex);
return result;
}
enum tfm_status_e tfm_ns_interface_init(void)
{
/* The static K_MUTEX_DEFINE handles mutex init, so just return. */
return TFM_SUCCESS;
}
/**
* \brief Retrieve the version of the PSA Framework API.
*
* \note This is a functional test only and doesn't
* mean to test all possible combinations of
* input parameters and return values.
*/
static void tfm_ipc_test_1001(void)
{
uint32_t version;
version = psa_framework_version();
if (version == PSA_FRAMEWORK_VERSION) {
printk("The version of the PSA Framework API is %d.\n",
version);
} else {
printk("The version of the PSA Framework API is not valid!\n");
return;
}
}
/**
* Retrieve the minor version of a RoT Service.
*
* @return N/A
*/
static void tfm_ipc_test_1002(void)
{
uint32_t version;
version = psa_version(IPC_SERVICE_TEST_BASIC_SID);
if (version == PSA_VERSION_NONE) {
printk("RoT Service is not implemented or caller is not ");
printk("authorized to access it!\n");
return;
}
/* Valid version number */
printk("The minor version is %d.\n", version);
}
/**
* Connect to a RoT Service by its SID.
*
* @return N/A
*/
static void tfm_ipc_test_1003(void)
{
psa_handle_t handle;
handle = psa_connect(IPC_SERVICE_TEST_BASIC_SID,
IPC_SERVICE_TEST_BASIC_VERSION);
if (handle > 0) {
printk("Connect success!\n");
} else {
printk("The RoT Service has refused the connection!\n");
return;
}
psa_close(handle);
}
/**
* Call a RoT Service.
*
* @return N/A
*/
static void tfm_ipc_test_1004(void)
{
char str1[] = "str1";
char str2[] = "str2";
char str3[128], str4[128];
struct psa_invec invecs[2] = { { str1, sizeof(str1) /
sizeof(char) },
{ str2, sizeof(str2) /
sizeof(char) } };
struct psa_outvec outvecs[2] = { { str3, sizeof(str3) /
sizeof(char) },
{ str4, sizeof(str4) /
sizeof(char) } };
psa_handle_t handle;
psa_status_t status;
uint32_t version;
version = psa_version(IPC_SERVICE_TEST_BASIC_SID);
printk("TFM service support version is %d.\n", version);
handle = psa_connect(IPC_SERVICE_TEST_BASIC_SID,
IPC_SERVICE_TEST_BASIC_VERSION);
status = psa_call(handle, PSA_IPC_CALL, invecs, 2, outvecs, 2);
if (status >= 0) {
printk("psa_call is successful!\n");
} else {
printk("psa_call is failed!\n");
return;
}
printk("outvec1 is: %s\n", (char *)(outvecs[0].base));
printk("outvec2 is: %s\n", (char *)(outvecs[1].base));
psa_close(handle);
}
/**
* \brief Call IPC_CLIENT_TEST_BASIC_SID RoT Service to run the IPC basic test.
*/
static void tfm_ipc_test_1005(void)
{
psa_handle_t handle;
psa_status_t status;
int test_result;
struct psa_outvec outvecs[1] = { { &test_result,
sizeof(test_result) } };
handle = psa_connect(IPC_CLIENT_TEST_BASIC_SID,
IPC_CLIENT_TEST_BASIC_VERSION);
if (handle > 0) {
printk("Connect success!\n");
} else {
printk("The RoT Service has refused the connection!\n");
return;
}
status = psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
if (status >= 0) {
printk("Call success!\n");
} else {
printk("Call failed!\n");
}
psa_close(handle);
}
/**
* \brief Call IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_SID RoT Service
* to run the IPC PSA access APP mem test.
*/
static void tfm_ipc_test_1006(void)
{
psa_handle_t handle;
psa_status_t status;
int test_result;
struct psa_outvec outvecs[1] = { { &test_result,
sizeof(test_result) } };
handle = psa_connect(
IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_SID,
IPC_CLIENT_TEST_PSA_ACCESS_APP_MEM_VERSION);
if (handle > 0) {
printk("Connect success!\n");
} else {
printk("The RoT Service has refused the connection!\n");
return;
}
status = psa_call(handle, PSA_IPC_CALL, NULL, 0, outvecs, 1);
if (status >= 0) {
printk("Call success!\n");
} else {
printk("Call failed!\n");
}
psa_close(handle);
}
void main(void)
{
tfm_ipc_test_1001();
tfm_ipc_test_1002();
tfm_ipc_test_1003();
tfm_ipc_test_1004();
tfm_ipc_test_1005();
tfm_ipc_test_1006();
printk("TF-M IPC on %s\n", CONFIG_BOARD);
}