/*
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "libqtest.h"
#include "libqos/rtas.h"

static void qrtas_copy_args(uint64_t target_args, uint32_t nargs,
                            uint32_t *args)
{
    int i;

    for (i = 0; i < nargs; i++) {
        writel(target_args + i * sizeof(uint32_t), args[i]);
    }
}

static void qrtas_copy_ret(uint64_t target_ret, uint32_t nret, uint32_t *ret)
{
    int i;

    for (i = 0; i < nret; i++) {
        ret[i] = readl(target_ret + i * sizeof(uint32_t));
    }
}

static uint64_t qrtas_call(QGuestAllocator *alloc, const char *name,
                           uint32_t nargs, uint32_t *args,
                           uint32_t nret, uint32_t *ret)
{
    uint64_t res;
    uint64_t target_args, target_ret;

    target_args = guest_alloc(alloc, nargs * sizeof(uint32_t));
    target_ret = guest_alloc(alloc, nret * sizeof(uint32_t));

    qrtas_copy_args(target_args, nargs, args);
    res = qtest_rtas_call(global_qtest, name,
                          nargs, target_args, nret, target_ret);
    qrtas_copy_ret(target_ret, nret, ret);

    guest_free(alloc, target_ret);
    guest_free(alloc, target_args);

    return res;
}

int qrtas_get_time_of_day(QGuestAllocator *alloc, struct tm *tm, uint32_t *ns)
{
    int res;
    uint32_t ret[8];

    res = qrtas_call(alloc, "get-time-of-day", 0, NULL, 8, ret);
    if (res != 0) {
        return res;
    }

    res = ret[0];
    memset(tm, 0, sizeof(*tm));
    tm->tm_year = ret[1] - 1900;
    tm->tm_mon = ret[2] - 1;
    tm->tm_mday = ret[3];
    tm->tm_hour = ret[4];
    tm->tm_min = ret[5];
    tm->tm_sec = ret[6];
    *ns = ret[7];

    return res;
}

uint32_t qrtas_ibm_read_pci_config(QGuestAllocator *alloc, uint64_t buid,
                                   uint32_t addr, uint32_t size)
{
    int res;
    uint32_t args[4], ret[2];

    args[0] = addr;
    args[1] = buid >> 32;
    args[2] = buid & 0xffffffff;
    args[3] = size;
    res = qrtas_call(alloc, "ibm,read-pci-config", 4, args, 2, ret);
    if (res != 0) {
        return -1;
    }

    if (ret[0] != 0) {
        return -1;
    }

    return ret[1];
}

int qrtas_ibm_write_pci_config(QGuestAllocator *alloc, uint64_t buid,
                               uint32_t addr, uint32_t size, uint32_t val)
{
    int res;
    uint32_t args[5], ret[1];

    args[0] = addr;
    args[1] = buid >> 32;
    args[2] = buid & 0xffffffff;
    args[3] = size;
    args[4] = val;
    res = qrtas_call(alloc, "ibm,write-pci-config", 5, args, 1, ret);
    if (res != 0) {
        return -1;
    }

    if (ret[0] != 0) {
        return -1;
    }

    return 0;
}
