/*
 * 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/trusty_ipc.h>
#include <trusty/trusty_mem.h>
#include <trusty/util.h>

#define NS_PTE_PHYSADDR(pte) ((pte)&0xFFFFFFFFF000ULL)

#define QL_TIPC_DEV_RESP 0x8000
#define QL_TIPC_DEV_CONNECT 0x1
#define QL_TIPC_DEV_GET_EVENT 0x2
#define QL_TIPC_DEV_SEND 0x3
#define QL_TIPC_DEV_RECV 0x4
#define QL_TIPC_DEV_DISCONNECT 0x5

#define QL_TIPC_DEV_FC_HAS_EVENT 0x100

#define LOCAL_LOG 0

struct trusty_ipc_cmd_hdr {
    uint16_t opcode;
    uint16_t flags;
    uint32_t status;
    uint32_t handle;
    uint32_t payload_len;
    uint8_t payload[0];
};

struct trusty_ipc_wait_req {
    uint64_t reserved;
};

struct trusty_ipc_connect_req {
    uint64_t cookie;
    uint64_t reserved;
    uint8_t name[0];
};

static size_t iovec_size(const struct trusty_ipc_iovec* iovs, size_t iovs_cnt) {
    size_t i;
    size_t cb = 0;

    trusty_assert(iovs);

    for (i = 0; i < iovs_cnt; i++) {
        cb += iovs[i].len;
    }

    return cb;
}

static size_t iovec_to_buf(void* buf,
                           size_t buf_len,
                           const struct trusty_ipc_iovec* iovs,
                           size_t iovs_cnt) {
    size_t i;
    size_t buf_pos = 0;

    trusty_assert(iovs);

    for (i = 0; i < iovs_cnt; i++) {
        size_t to_copy = (size_t)iovs[i].len;

        if (!to_copy)
            continue;

        if (to_copy > buf_len)
            to_copy = buf_len;

        trusty_memcpy((uint8_t*)buf + buf_pos, iovs[i].base, to_copy);

        buf_pos += to_copy;
        buf_len -= to_copy;

        if (buf_len == 0)
            break;
    }

    return buf_pos;
}

static size_t buf_to_iovec(const struct trusty_ipc_iovec* iovs,
                           size_t iovs_cnt,
                           const void* buf,
                           size_t buf_len) {
    size_t i;
    size_t copied = 0;
    const uint8_t* buf_ptr = buf;

    trusty_assert(buf_ptr);
    trusty_assert(iovs);

    if (iovs_cnt == 0 || buf_len == 0)
        return 0;

    for (i = 0; i < iovs_cnt; i++) {
        size_t to_copy = buf_len;

        if (to_copy > iovs[i].len)
            to_copy = iovs[i].len;

        if (!to_copy)
            continue;

        trusty_memcpy(iovs[i].base, buf_ptr, to_copy);

        copied += to_copy;
        buf_ptr += to_copy;
        buf_len -= to_copy;

        if (buf_len == 0)
            break;
    }

    return copied;
}

static int check_response(struct trusty_ipc_dev* dev,
                          volatile struct trusty_ipc_cmd_hdr* hdr,
                          uint16_t cmd) {
    if (hdr->opcode != (cmd | QL_TIPC_DEV_RESP)) {
        /* malformed response */
        trusty_error("%s: malformed response cmd: 0x%x\n", __func__,
                     hdr->opcode);
        return TRUSTY_ERR_SECOS_ERR;
    }

    if (hdr->status) {
        /* secure OS responded with error: TODO need error code */
        trusty_error("%s: cmd 0x%x: status = %d\n", __func__, hdr->opcode,
                     hdr->status);
        return TRUSTY_ERR_SECOS_ERR;
    }

    return TRUSTY_ERR_NONE;
}

int trusty_ipc_dev_create(struct trusty_ipc_dev** idev,
                          struct trusty_dev* tdev,
                          size_t shared_buf_size) {
    int rc;
    int rc2;
    struct trusty_ipc_dev* dev;

    trusty_assert(idev);
    trusty_assert(!(shared_buf_size % PAGE_SIZE));
    trusty_debug("%s: Create new Trusty IPC device (%zu)\n", __func__,
                 shared_buf_size);

    /* allocate device context */
    dev = trusty_calloc(1, sizeof(*dev));
    if (!dev) {
        trusty_error("%s: failed to allocate Trusty IPC device\n", __func__);
        return TRUSTY_ERR_NO_MEMORY;
    }
    dev->tdev = tdev;

    /* allocate shared buffer */
    dev->buf_size = shared_buf_size;
    dev->buf_vaddr = trusty_alloc_pages(shared_buf_size / PAGE_SIZE);
    if (!dev->buf_vaddr) {
        trusty_error("%s: failed to allocate shared memory\n", __func__);
        rc = TRUSTY_ERR_NO_MEMORY;
        goto err_alloc_pages;
    }

    /* Get memory attributes */
    rc = trusty_encode_page_info(&dev->buf_ns, dev->buf_vaddr);
    if (rc != 0) {
        trusty_error("%s: failed to get shared memory attributes\n", __func__);
        rc = TRUSTY_ERR_GENERIC;
        goto err_page_info;
    }
    /* call secure OS to register shared buffer */
    rc = trusty_dev_share_memory(dev->tdev, &dev->buf_id, &dev->buf_ns,
                                 dev->buf_size / PAGE_SIZE);
    if (rc != 0) {
        trusty_error("%s: failed (%d) to share memory\n", __func__, rc);
        rc = TRUSTY_ERR_SECOS_ERR;
        goto err_share_memory;
    }

    rc = trusty_dev_init_ipc(dev->tdev, dev->buf_id, dev->buf_size);
    if (rc != 0) {
        trusty_error("%s: failed (%d) to create Trusty IPC device\n", __func__,
                     rc);
        rc = TRUSTY_ERR_SECOS_ERR;
        goto err_create_sec_dev;
    }

    trusty_debug("%s: new Trusty IPC device (%p)\n", __func__, dev);

    *idev = dev;
    return TRUSTY_ERR_NONE;

err_page_info:
err_create_sec_dev:
    rc2 = trusty_dev_reclaim_memory(dev->tdev, dev->buf_id);
    if (rc2) {
        trusty_fatal("%s: failed to remove shared memory\n", __func__);
    }
err_share_memory:
    trusty_free_pages(dev->buf_vaddr, dev->buf_size / PAGE_SIZE);
err_alloc_pages:
    trusty_free(dev);
    return rc;
}

void trusty_ipc_dev_shutdown(struct trusty_ipc_dev* dev) {
    int rc;
    trusty_assert(dev);

    trusty_debug("%s: shutting down Trusty IPC device (%p)\n", __func__, dev);

    /* shutdown Trusty IPC device */
    rc = trusty_dev_shutdown_ipc(dev->tdev, dev->buf_id, dev->buf_size);
    trusty_assert(!rc);
    if (rc != 0) {
        trusty_error("%s: failed (%d) to shutdown Trusty IPC device\n",
                     __func__, rc);
    }
    rc = trusty_dev_reclaim_memory(dev->tdev, dev->buf_id);
    if (rc) {
        trusty_fatal("%s: failed to remove shared memory\n", __func__);
    }
    trusty_free_pages(dev->buf_vaddr, dev->buf_size / PAGE_SIZE);
    trusty_free(dev);
}

int trusty_ipc_dev_connect(struct trusty_ipc_dev* dev,
                           const char* port,
                           uint64_t cookie) {
    int rc;
    size_t port_len;
    volatile struct trusty_ipc_cmd_hdr* cmd;
    struct trusty_ipc_connect_req* req;

    trusty_assert(dev);
    trusty_assert(port);

    trusty_debug("%s: connecting to '%s'\n", __func__, port);

    /* check port name length */
    port_len = trusty_strlen(port) + 1;
    if (port_len > (dev->buf_size - sizeof(*cmd) - sizeof(*req))) {
        /* it would not fit into buffer */
        trusty_error("%s: port name is too long (%zu)\n", __func__, port_len);
        return TRUSTY_ERR_INVALID_ARGS;
    }

    /* prepare command */
    cmd = dev->buf_vaddr;
    trusty_memset((void*)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_CONNECT;

    /* prepare payload  */
    req = (struct trusty_ipc_connect_req*)cmd->payload;
    trusty_memset((void*)req, 0, sizeof(*req));
    req->cookie = cookie;
    trusty_strcpy((char*)req->name, port);
    cmd->payload_len = sizeof(*req) + port_len;

    /* call secure os */
    rc = trusty_dev_exec_ipc(dev->tdev, dev->buf_id,
                             sizeof(*cmd) + cmd->payload_len);
    if (rc) {
        /* secure OS returned an error */
        trusty_error("%s: secure OS returned (%d)\n", __func__, rc);
        return TRUSTY_ERR_SECOS_ERR;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_CONNECT);
    if (rc) {
        trusty_error("%s: connect cmd failed (%d)\n", __func__, rc);
        return rc;
    }

    /* success */
    return cmd->handle;
}

int trusty_ipc_dev_close(struct trusty_ipc_dev* dev, handle_t handle) {
    int rc;
    volatile struct trusty_ipc_cmd_hdr* cmd;

    trusty_assert(dev);

    trusty_debug("%s: chan %d: closing\n", __func__, handle);

    /* prepare command */
    cmd = dev->buf_vaddr;
    trusty_memset((void*)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_DISCONNECT;
    cmd->handle = handle;
    /* no payload */

    /* call into secure os */
    rc = trusty_dev_exec_ipc(dev->tdev, dev->buf_id,
                             sizeof(*cmd) + cmd->payload_len);
    if (rc) {
        trusty_error("%s: secure OS returned (%d)\n", __func__, rc);
        return TRUSTY_ERR_SECOS_ERR;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_DISCONNECT);
    if (rc) {
        trusty_error("%s: disconnect cmd failed (%d)\n", __func__, rc);
        return rc;
    }

    trusty_debug("%s: chan %d: closed\n", __func__, handle);

    return TRUSTY_ERR_NONE;
}

bool trusty_ipc_dev_has_event(struct trusty_ipc_dev* dev, handle_t chan) {
    int rc;
    bool has_event;
    volatile struct trusty_ipc_cmd_hdr* cmd;

    trusty_assert(dev);

    /* prepare command */
    cmd = dev->buf_vaddr;
    trusty_memset((void*)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_FC_HAS_EVENT;
    cmd->handle = chan;

    /* prepare payload  */
    cmd->payload_len = 0;

    /* call into secure os */
    rc = trusty_dev_exec_fc_ipc(dev->tdev, dev->buf_id,
                                sizeof(*cmd) + cmd->payload_len);
    if (rc) {
        trusty_error("%s: secure OS returned (%d)\n", __func__, rc);
        return false;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_FC_HAS_EVENT);
    if (rc) {
        trusty_error("%s: get event cmd failed (%d)\n", __func__, rc);
        return false;
    }

    if ((size_t)cmd->payload_len < sizeof(has_event)) {
        trusty_error("%s: invalid response length (%zd)\n", __func__,
                     (size_t)cmd->payload_len);
        return false;
    }

    /* copy out event */
    trusty_memcpy(&has_event, (const void*)cmd->payload, sizeof(has_event));
    return has_event;
}

int trusty_ipc_dev_get_event(struct trusty_ipc_dev* dev,
                             handle_t chan,
                             struct trusty_ipc_event* event) {
    int rc;
    volatile struct trusty_ipc_cmd_hdr* cmd;

    trusty_assert(dev);
    trusty_assert(event);

    /* prepare command */
    cmd = dev->buf_vaddr;
    trusty_memset((void*)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_GET_EVENT;
    cmd->handle = chan;

    /* prepare payload  */
    trusty_memset((void*)cmd->payload, 0, sizeof(struct trusty_ipc_wait_req));
    cmd->payload_len = sizeof(struct trusty_ipc_wait_req);

    /* call into secure os */
    rc = trusty_dev_exec_ipc(dev->tdev, dev->buf_id,
                             sizeof(*cmd) + cmd->payload_len);
    if (rc) {
        trusty_error("%s: secure OS returned (%d)\n", __func__, rc);
        return TRUSTY_ERR_SECOS_ERR;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_GET_EVENT);
    if (rc) {
        trusty_error("%s: get event cmd failed (%d)\n", __func__, rc);
        return rc;
    }

    if ((size_t)cmd->payload_len < sizeof(*event)) {
        trusty_error("%s: invalid response length (%zd)\n", __func__,
                     (size_t)cmd->payload_len);
        return TRUSTY_ERR_SECOS_ERR;
    }

    /* copy out event */
    trusty_memcpy(event, (const void*)cmd->payload, sizeof(*event));
    return TRUSTY_ERR_NONE;
}

int trusty_ipc_dev_send(struct trusty_ipc_dev* dev,
                        handle_t chan,
                        const struct trusty_ipc_iovec* iovs,
                        size_t iovs_cnt) {
    int rc;
    size_t msg_size;
    volatile struct trusty_ipc_cmd_hdr* cmd;

    trusty_assert(dev);
    /* calc message length */
    msg_size = iovec_size(iovs, iovs_cnt);
    if (msg_size > dev->buf_size - sizeof(*cmd)) {
        /* msg is too big to fit provided buffer */
        trusty_error("%s: chan %d: msg is too long (%zu)\n", __func__, chan,
                     msg_size);
        return TRUSTY_ERR_MSG_TOO_BIG;
    }

    /* prepare command */
    cmd = dev->buf_vaddr;
    trusty_memset((void*)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_SEND;
    cmd->handle = chan;

    /* copy in message data */
    cmd->payload_len = (uint32_t)msg_size;
    msg_size = iovec_to_buf(dev->buf_vaddr + sizeof(*cmd),
                            dev->buf_size - sizeof(*cmd), iovs, iovs_cnt);
    trusty_assert(msg_size == (size_t)cmd->payload_len);

    /* call into secure os */
    rc = trusty_dev_exec_ipc(dev->tdev, dev->buf_id,
                             sizeof(*cmd) + cmd->payload_len);
    if (rc < 0) {
        trusty_error("%s: secure OS returned (%d)\n", __func__, rc);
        return TRUSTY_ERR_SECOS_ERR;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_SEND);
    if (rc) {
        trusty_error("%s: send msg failed (%d)\n", __func__, rc);
    }

    return rc;
}

int trusty_ipc_dev_recv(struct trusty_ipc_dev* dev,
                        handle_t chan,
                        const struct trusty_ipc_iovec* iovs,
                        size_t iovs_cnt) {
    int rc;
    size_t copied;
    volatile struct trusty_ipc_cmd_hdr* cmd;

    trusty_assert(dev);

    /* prepare command */
    cmd = dev->buf_vaddr;
    trusty_memset((void*)cmd, 0, sizeof(*cmd));
    cmd->opcode = QL_TIPC_DEV_RECV;
    cmd->handle = chan;
    /* no payload */

    /* call into secure os */
    rc = trusty_dev_exec_ipc(dev->tdev, dev->buf_id,
                             sizeof(*cmd) + cmd->payload_len);
    if (rc < 0) {
        trusty_error("%s: secure OS returned (%d)\n", __func__, rc);
        return TRUSTY_ERR_SECOS_ERR;
    }

    rc = check_response(dev, cmd, QL_TIPC_DEV_RECV);
    if (rc) {
        trusty_error("%s: recv cmd failed (%d)\n", __func__, rc);
        return rc;
    }

    /* copy data out to proper destination */
    copied = buf_to_iovec(iovs, iovs_cnt, (const void*)cmd->payload,
                          cmd->payload_len);
    if (copied != (size_t)cmd->payload_len) {
        /* msg is too big to fit provided buffer */
        trusty_error("%s: chan %d: buffer too small (%zu vs. %zu)\n", __func__,
                     chan, copied, (size_t)cmd->payload_len);
        return TRUSTY_ERR_MSG_TOO_BIG;
    }

    return (int)copied;
}

void trusty_ipc_dev_idle(struct trusty_ipc_dev* dev, bool event_poll) {
    trusty_idle(dev->tdev, event_poll);
}
