blob: ffaea859d2a0c8982f683ddbb68355f18b5ce7b5 [file] [log] [blame]
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <stdint.h>
#include "psa/service.h"
#include "psa_manifest/tfm_example_partition.h"
#include "log/tfm_log.h"
#include "tfm/tfm_spm_services.h"
#include "tfm_plat_test.h"
/**
* \brief An example service implementation that prints out an argument from the
* client and then starts a timer.
*/
static void tfm_example_service(void)
{
psa_status_t status;
uint32_t arg;
psa_msg_t msg;
/* Retrieve the message corresponding to the example service signal */
status = psa_get(TFM_EXAMPLE_SERVICE_SIGNAL, &msg);
if (status != PSA_SUCCESS) {
return;
}
/* Decode the message */
switch (msg.type) {
case PSA_IPC_CONNECT:
case PSA_IPC_DISCONNECT:
/* This service does not require any setup or teardown on connect or
* disconnect, so just reply with success.
*/
status = PSA_SUCCESS;
break;
case PSA_IPC_CALL:
if (msg.in_size[0] != sizeof(arg)) {
status = PSA_ERROR_PROGRAMMER_ERROR;
break;
}
/* Print arg from client */
psa_read(msg.handle, 0, &arg, sizeof(arg));
LOG_MSG("[Example partition] Service called! arg=%p\r\n", arg);
/* Start timer. The interrupt triggered when it expires will be handled
* by tfm_example_timer_handler().
*/
tfm_plat_test_secure_timer_start();
LOG_MSG("[Example partition] Timer started...\r\n");
status = PSA_SUCCESS;
break;
default:
/* Invalid message type */
status = PSA_ERROR_PROGRAMMER_ERROR;
break;
}
/* Reply with the message result status to unblock the client */
psa_reply(msg.handle, status);
}
/**
* \brief An example interrupt handler.
*/
static void tfm_example_timer_handler(void)
{
/* Stop timer */
tfm_plat_test_secure_timer_stop();
/* Inform the SPM that the timer interrupt has been handled */
psa_eoi(TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ);
}
/**
* \brief The example partition's entry function.
*/
void tfm_example_partition_main(void)
{
psa_signal_t signals;
/* Enable timer IRQ */
tfm_enable_irq(TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ);
/* Continually wait for one or more of the partition's RoT Service or
* interrupt signals to be asserted and then handle the asserted signal(s).
*/
while (1) {
signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
if (signals & TFM_EXAMPLE_SERVICE_SIGNAL) {
tfm_example_service();
}
if (signals & TFM_EXAMPLE_SIGNAL_TIMER_0_IRQ) {
tfm_example_timer_handler();
}
}
}