/*
 * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use _this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*****************************************************************************
 * Includes
 *****************************************************************************/

#include "remoteproc.hpp"

#include <cinttypes>

#include <ethosu_log.h>

namespace {
void setupRProcMem(remoteproc &rproc,
                   metal_phys_addr_t pa,
                   metal_phys_addr_t da,
                   size_t size,
                   remoteproc_mem &mem,
                   metal_io_region &region) {

    remoteproc_init_mem(&mem, nullptr, pa, da, size, &region);
    metal_io_init(&region, (void *)da, &mem.pa, size, -1, 0, nullptr);
    remoteproc_add_mem(&rproc, &mem);
}
}; // namespace

/*****************************************************************************
 * RProc
 *****************************************************************************/

RProc::RProc(Mailbox::Mailbox &_mailbox, resource_table &table, size_t tableSize) :
    mailbox(_mailbox), ops({}), vdev(nullptr), mems(), regions(), notifySemaphore(xSemaphoreCreateBinary()) {
    ops.init       = init;       // initialize the remoteproc instance
    ops.remove     = remove;     // remove the remoteproc instance
    ops.handle_rsc = handle_rsc; // handle the vendor specific resource
    ops.notify     = notify;     // notify the remote
    mailbox.registerCallback(mailboxCallback, static_cast<void *>(this));

    if (!remoteproc_init(&rproc, &ops, this)) {
        LOG_ERR("Failed to intialize remoteproc");
        abort();
    }

    // Setup memory region for resource table
    const metal_phys_addr_t rsc_addr = reinterpret_cast<metal_phys_addr_t>(&table);
    // No translation is needed for rsc_addr because it already contains the DA
    // so PA is set to DA
    setupRProcMem(rproc, rsc_addr, rsc_addr, tableSize, rsc_mem, rsc_region);

    int ret = remoteproc_set_rsc_table(&rproc, &table, tableSize);
    if (ret) {
        LOG_ERR("Failed to set resource table. ret=%d", ret);
        abort();
    }

    vdev = remoteproc_create_virtio(&rproc, 0, VIRTIO_DEV_DEVICE, nullptr);
    if (!vdev) {
        LOG_ERR("Failed to create vdev");
        abort();
    }

    BaseType_t taskret = xTaskCreate(notifyTask, "notifyTask", 1024, this, 2, &notifyHandle);
    if (taskret != pdPASS) {
        LOG_ERR("Failed to create remoteproc notify task");
        abort();
    }
}

RProc::~RProc() {
    mailbox.deregisterCallback(mailboxCallback, static_cast<void *>(this));
    vTaskDelete(notifyHandle);
}

remoteproc *RProc::getRProc() {
    return &rproc;
}

virtio_device *RProc::getVDev() {
    return vdev;
}

void RProc::mailboxCallback(void *userArg) {
    auto _this = static_cast<RProc *>(userArg);

    xSemaphoreGiveFromISR(_this->notifySemaphore, nullptr);
}

void RProc::notifyTask(void *param) {
    LOG_DEBUG("Starting message notify task");

    auto _this = static_cast<RProc *>(param);

    while (true) {
        // Wait for event
        xSemaphoreTake(_this->notifySemaphore, portMAX_DELAY);

        // Read virtio queue and notify all rpmsg clients
        rproc_virtio_notified(_this->vdev, RSC_NOTIFY_ID_ANY);
    }
}

struct remoteproc *RProc::init(remoteproc *rproc, const remoteproc_ops *ops, void *arg) {
    LOG_DEBUG("");

    rproc->ops  = ops;
    rproc->priv = arg;

    return rproc;
}

int RProc::handle_rsc(remoteproc *rproc, void *rsc, size_t len) {
    auto _this                     = static_cast<RProc *>(rproc->priv);
    struct fw_rsc_mapping *mapping = static_cast<fw_rsc_mapping *>(rsc);

    if (mapping->type != RSC_MAPPING) {
        LOG_ERR("Unknown resource type %" PRIu32, mapping->type);
        return -RPROC_ERR_RSC_TAB_NS;
    }

    for (uint32_t i = 0; i < mapping->num_ranges; ++i) {
        const fw_rsc_map_range *range = &mapping->range[i];
        if (range->len == 0) {
            LOG_DEBUG("Ignored zero length memory map range[%" PRIu32 "]", i);
            continue;
        }
        setupRProcMem(*rproc, range->pa, range->da, range->len, _this->mems[i], _this->regions[i]);
    }

    return 0;
}

void RProc::remove(remoteproc *rproc) {
    LOG_DEBUG("");
}

int RProc::notify(remoteproc *rproc, uint32_t id) {
    LOG_DEBUG("");

    auto *_this = static_cast<RProc *>(rproc->priv);
    _this->mailbox.sendMessage();
    return 0;
}

/*****************************************************************************
 * Rpmsg
 *****************************************************************************/

Rpmsg::Rpmsg(RProc &rproc, const char *const name) : rvdev({}), rdev(), endpoint({}) {
    struct virtio_device *vdev = rproc.getVDev();

    if (vdev->vrings_num != ResourceTable::NUM_VRINGS) {
        LOG_ERR("Invalid number of vrings");
        abort();
    }

    // Vdev can use the same IO region for translations as the vring
    if (rpmsg_init_vdev(&rvdev, vdev, nullptr, vdev->vrings_info[0].io, nullptr)) {
        LOG_ERR("Failed to initialize rpmsg vdev");
        abort();
    }

    rdev = rpmsg_virtio_get_rpmsg_device(&rvdev);
    if (!rdev) {
        LOG_ERR("Failed to get rpmsg dev");
        abort();
    }

    int ret =
        rpmsg_create_ept(&endpoint, rdev, name, RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, endpointCallback, nsUnbindCallback);
    if (ret != RPMSG_SUCCESS) {
        LOG_ERR("Failed to create rpmsg endpoint. ret=%d", ret);
        abort();
    }

    endpoint.priv = static_cast<void *>(this);
}

int Rpmsg::send(void *data, size_t len, uint32_t dst) {
    LOG_DEBUG("Sending rpmsg. dst=%" PRIu32 ", len=%zu", dst, len);

    int ret = rpmsg_sendto(&endpoint, data, len, dst);
    return ret;
}

void *Rpmsg::physicalToVirtual(metal_phys_addr_t pa) {
    return metal_io_phys_to_virt(rvdev.shbuf_io, pa);
}

void Rpmsg::rpmsgNsBind(rpmsg_device *rdev, const char *name, uint32_t dest) {
    LOG_DEBUG("");
}

void Rpmsg::nsUnbindCallback(rpmsg_endpoint *ept) {
    LOG_DEBUG("");
}

int Rpmsg::endpointCallback(rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) {
    LOG_DEBUG("src=%" PRIX32 ", len=%zu", src, len);

    auto _this = static_cast<Rpmsg *>(priv);
    _this->handleMessage(data, len, src);

    return 0;
}

int Rpmsg::handleMessage(void *data, size_t len, uint32_t src) {
    LOG_DEBUG("Receiving rpmsg. src=%" PRIu32 ", len=%zu", src, len);

    auto c = static_cast<char *>(data);
    for (size_t i = 0; i < len; i++) {
        printf("%c", c[i]);
    }
    printf("\n");

    return 0;
}
