/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <trusty/trusty_dev.h>
#include <trusty/util.h>

#include "sm_err.h"
#include "smcall.h"

struct trusty_dev;

#define LOCAL_LOG 0

#ifndef __asmeq
#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
#endif

#ifdef  NS_ARCH_ARM64
#define SMC_ARG0                "x0"
#define SMC_ARG1                "x1"
#define SMC_ARG2                "x2"
#define SMC_ARG3                "x3"
#define SMC_ARCH_EXTENSION      ""
#define SMC_REGISTERS_TRASHED   "x4","x5","x6","x7","x8","x9","x10","x11", \
                                "x12","x13","x14","x15","x16","x17"
#else
#define SMC_ARG0                "r0"
#define SMC_ARG1                "r1"
#define SMC_ARG2                "r2"
#define SMC_ARG3                "r3"
#define SMC_ARCH_EXTENSION      ".arch_extension sec\n"
#define SMC_REGISTERS_TRASHED   "ip"
#endif

/*
 * Execute SMC call into trusty
 */
static unsigned long smc(unsigned long r0,
                         unsigned long r1,
                         unsigned long r2,
                         unsigned long r3)
{
    register unsigned long _r0 asm(SMC_ARG0) = r0;
    register unsigned long _r1 asm(SMC_ARG1) = r1;
    register unsigned long _r2 asm(SMC_ARG2) = r2;
    register unsigned long _r3 asm(SMC_ARG3) = r3;

    asm volatile(
        __asmeq("%0", SMC_ARG0)
        __asmeq("%1", SMC_ARG1)
        __asmeq("%2", SMC_ARG2)
        __asmeq("%3", SMC_ARG3)
        __asmeq("%4", SMC_ARG0)
        __asmeq("%5", SMC_ARG1)
        __asmeq("%6", SMC_ARG2)
        __asmeq("%7", SMC_ARG3)
        SMC_ARCH_EXTENSION
        "smc    #0" /* switch to secure world */
        : "=r" (_r0), "=r" (_r1), "=r" (_r2), "=r" (_r3)
        : "r" (_r0), "r" (_r1), "r" (_r2), "r" (_r3)
        : SMC_REGISTERS_TRASHED);
    return _r0;
}

static int32_t trusty_fast_call32(struct trusty_dev *dev, uint32_t smcnr,
                                  uint32_t a0, uint32_t a1, uint32_t a2)
{
    trusty_assert(dev);
    trusty_assert(SMC_IS_FASTCALL(smcnr));

    return smc(smcnr, a0, a1, a2);
}

static unsigned long trusty_std_call_inner(struct trusty_dev *dev,
                                           unsigned long smcnr,
                                           unsigned long a0,
                                           unsigned long a1,
                                           unsigned long a2)
{
    unsigned long ret;
    int retry = 5;

    trusty_debug("%s(0x%lx 0x%lx 0x%lx 0x%lx)\n", __func__, smcnr, a0, a1, a2);

    while (true) {
        ret = smc(smcnr, a0, a1, a2);
        while ((int32_t)ret == SM_ERR_FIQ_INTERRUPTED)
            ret = smc(SMC_SC_RESTART_FIQ, 0, 0, 0);
        if ((int)ret != SM_ERR_BUSY || !retry)
            break;

        trusty_debug("%s(0x%lx 0x%lx 0x%lx 0x%lx) returned busy, retry\n",
                     __func__, smcnr, a0, a1, a2);

        retry--;
    }

    return ret;
}

static unsigned long trusty_std_call_helper(struct trusty_dev *dev,
                                            unsigned long smcnr,
                                            unsigned long a0,
                                            unsigned long a1,
                                            unsigned long a2)
{
    unsigned long ret;
    unsigned long irq_state;

    while (true) {
        trusty_local_irq_disable(&irq_state);
        ret = trusty_std_call_inner(dev, smcnr, a0, a1, a2);
        trusty_local_irq_restore(&irq_state);

        if ((int)ret != SM_ERR_BUSY)
            break;

        trusty_idle(dev);
    }

    return ret;
}

static int32_t trusty_std_call32(struct trusty_dev *dev, uint32_t smcnr,
                                 uint32_t a0, uint32_t a1, uint32_t a2)
{
    int ret;

    trusty_assert(dev);
    trusty_assert(!SMC_IS_FASTCALL(smcnr));

    if (smcnr != SMC_SC_NOP) {
        trusty_lock(dev);
    }

    trusty_debug("%s(0x%x 0x%x 0x%x 0x%x) started\n", __func__,
                 smcnr, a0, a1, a2);

    ret = trusty_std_call_helper(dev, smcnr, a0, a1, a2);
    while (ret == SM_ERR_INTERRUPTED || ret == SM_ERR_CPU_IDLE) {
        trusty_debug("%s(0x%x 0x%x 0x%x 0x%x) interrupted\n", __func__,
                     smcnr, a0, a1, a2);
        if (ret == SM_ERR_CPU_IDLE) {
            trusty_idle(dev);
        }
        ret = trusty_std_call_helper(dev, SMC_SC_RESTART_LAST, 0, 0, 0);
    }

    trusty_debug("%s(0x%x 0x%x 0x%x 0x%x) returned 0x%x\n",
                 __func__, smcnr, a0, a1, a2, ret);

    if (smcnr != SMC_SC_NOP) {
        trusty_unlock(dev);
    }

    return ret;
}

static int trusty_call32_mem_buf(struct trusty_dev *dev, uint32_t smcnr,
                                 struct ns_mem_page_info *page, uint32_t size)
{
    trusty_assert(dev);
    trusty_assert(page);

    if (SMC_IS_FASTCALL(smcnr)) {
        return trusty_fast_call32(dev, smcnr,
                                  (uint32_t)page->attr,
                                  (uint32_t)(page->attr >> 32), size);
    } else {
        return trusty_std_call32(dev, smcnr,
                                 (uint32_t)page->attr,
                                 (uint32_t)(page->attr >> 32), size);
    }
}

int trusty_dev_init_ipc(struct trusty_dev *dev,
                        struct ns_mem_page_info *buf, uint32_t buf_size)
{
    return trusty_call32_mem_buf(dev, SMC_SC_TRUSTY_IPC_CREATE_QL_DEV,
                                 buf, buf_size);
}

int trusty_dev_exec_ipc(struct trusty_dev *dev,
                        struct ns_mem_page_info *buf, uint32_t buf_size)
{
    return trusty_call32_mem_buf(dev, SMC_SC_TRUSTY_IPC_HANDLE_QL_DEV_CMD,
                                 buf, buf_size);
}

int trusty_dev_shutdown_ipc(struct trusty_dev *dev,
                            struct ns_mem_page_info *buf, uint32_t buf_size)
{
    return trusty_call32_mem_buf(dev, SMC_SC_TRUSTY_IPC_SHUTDOWN_QL_DEV,
                                 buf, buf_size);
}


static int trusty_init_api_version(struct trusty_dev *dev)
{
    uint32_t api_version;

    api_version = trusty_fast_call32(dev, SMC_FC_API_VERSION,
                                     TRUSTY_API_VERSION_CURRENT, 0, 0);
    if (api_version == SM_ERR_UNDEFINED_SMC)
        api_version = 0;

    if (api_version > TRUSTY_API_VERSION_CURRENT) {
        trusty_error("unsupported trusty api version %u > %u\n",
                     api_version, TRUSTY_API_VERSION_CURRENT);
        return -1;
    }

    trusty_info("selected trusty api version: %u (requested %u)\n",
                api_version, TRUSTY_API_VERSION_CURRENT);

    dev->api_version = api_version;

    return 0;
}

int trusty_dev_init(struct trusty_dev *dev, void *priv_data)
{
    trusty_assert(dev);

    dev->priv_data = priv_data;
    return trusty_init_api_version(dev);
}

int trusty_dev_shutdown(struct trusty_dev *dev)
{
    trusty_assert(dev);

    dev->priv_data = NULL;
    return 0;
}

