/*
 * 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();
        }
    }
}
