/*
 * Test Server
 *
 * Copyright IBM, Corp. 2011
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * 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 "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
#include "sysemu/qtest.h"
#include "hw/qdev.h"
#include "sysemu/char.h"
#include "exec/ioport.h"
#include "exec/memory.h"
#include "hw/irq.h"
#include "sysemu/accel.h"
#include "sysemu/sysemu.h"
#include "sysemu/cpus.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
#ifdef TARGET_PPC64
#include "hw/ppc/spapr_rtas.h"
#endif

#define MAX_IRQ 256

bool qtest_allowed;

static DeviceState *irq_intercept_dev;
static FILE *qtest_log_fp;
static CharBackend qtest_chr;
static GString *inbuf;
static int irq_levels[MAX_IRQ];
static qemu_timeval start_time;
static bool qtest_opened;

#define FMT_timeval "%ld.%06ld"

/**
 * QTest Protocol
 *
 * Line based protocol, request/response based.  Server can send async messages
 * so clients should always handle many async messages before the response
 * comes in.
 *
 * Valid requests
 *
 * Clock management:
 *
 * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL.  qtest commands
 * let you adjust the value of the clock (monotonically).  All the commands
 * return the current value of the clock in nanoseconds.
 *
 *  > clock_step
 *  < OK VALUE
 *
 *     Advance the clock to the next deadline.  Useful when waiting for
 *     asynchronous events.
 *
 *  > clock_step NS
 *  < OK VALUE
 *
 *     Advance the clock by NS nanoseconds.
 *
 *  > clock_set NS
 *  < OK VALUE
 *
 *     Advance the clock to NS nanoseconds (do nothing if it's already past).
 *
 * PIO and memory access:
 *
 *  > outb ADDR VALUE
 *  < OK
 *
 *  > outw ADDR VALUE
 *  < OK
 *
 *  > outl ADDR VALUE
 *  < OK
 *
 *  > inb ADDR
 *  < OK VALUE
 *
 *  > inw ADDR
 *  < OK VALUE
 *
 *  > inl ADDR
 *  < OK VALUE
 *
 *  > writeb ADDR VALUE
 *  < OK
 *
 *  > writew ADDR VALUE
 *  < OK
 *
 *  > writel ADDR VALUE
 *  < OK
 *
 *  > writeq ADDR VALUE
 *  < OK
 *
 *  > readb ADDR
 *  < OK VALUE
 *
 *  > readw ADDR
 *  < OK VALUE
 *
 *  > readl ADDR
 *  < OK VALUE
 *
 *  > readq ADDR
 *  < OK VALUE
 *
 *  > read ADDR SIZE
 *  < OK DATA
 *
 *  > write ADDR SIZE DATA
 *  < OK
 *
 *  > b64read ADDR SIZE
 *  < OK B64_DATA
 *
 *  > b64write ADDR SIZE B64_DATA
 *  < OK
 *
 *  > memset ADDR SIZE VALUE
 *  < OK
 *
 * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
 * For 'memset' a zero size is permitted and does nothing.
 *
 * DATA is an arbitrarily long hex number prefixed with '0x'.  If it's smaller
 * than the expected size, the value will be zero filled at the end of the data
 * sequence.
 *
 * B64_DATA is an arbitrarily long base64 encoded string.
 * If the sizes do not match, the data will be truncated.
 *
 * IRQ management:
 *
 *  > irq_intercept_in QOM-PATH
 *  < OK
 *
 *  > irq_intercept_out QOM-PATH
 *  < OK
 *
 * Attach to the gpio-in (resp. gpio-out) pins exported by the device at
 * QOM-PATH.  When the pin is triggered, one of the following async messages
 * will be printed to the qtest stream:
 *
 *  IRQ raise NUM
 *  IRQ lower NUM
 *
 * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
 * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
 * NUM=0 even though it is remapped to GSI 2).
 */

static int hex2nib(char ch)
{
    if (ch >= '0' && ch <= '9') {
        return ch - '0';
    } else if (ch >= 'a' && ch <= 'f') {
        return 10 + (ch - 'a');
    } else if (ch >= 'A' && ch <= 'F') {
        return 10 + (ch - 'A');
    } else {
        return -1;
    }
}

static void qtest_get_time(qemu_timeval *tv)
{
    qemu_gettimeofday(tv);
    tv->tv_sec -= start_time.tv_sec;
    tv->tv_usec -= start_time.tv_usec;
    if (tv->tv_usec < 0) {
        tv->tv_usec += 1000000;
        tv->tv_sec -= 1;
    }
}

static void qtest_send_prefix(CharBackend *chr)
{
    qemu_timeval tv;

    if (!qtest_log_fp || !qtest_opened) {
        return;
    }

    qtest_get_time(&tv);
    fprintf(qtest_log_fp, "[S +" FMT_timeval "] ",
            (long) tv.tv_sec, (long) tv.tv_usec);
}

static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char *fmt, ...)
{
    va_list ap;

    if (!qtest_log_fp || !qtest_opened) {
        return;
    }

    qtest_send_prefix(NULL);

    va_start(ap, fmt);
    vfprintf(qtest_log_fp, fmt, ap);
    va_end(ap);
}

static void do_qtest_send(CharBackend *chr, const char *str, size_t len)
{
    qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
    if (qtest_log_fp && qtest_opened) {
        fprintf(qtest_log_fp, "%s", str);
    }
}

static void qtest_send(CharBackend *chr, const char *str)
{
    do_qtest_send(chr, str, strlen(str));
}

static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr,
                                           const char *fmt, ...)
{
    va_list ap;
    gchar *buffer;

    va_start(ap, fmt);
    buffer = g_strdup_vprintf(fmt, ap);
    qtest_send(chr, buffer);
    va_end(ap);
}

static void qtest_irq_handler(void *opaque, int n, int level)
{
    qemu_irq old_irq = *(qemu_irq *)opaque;
    qemu_set_irq(old_irq, level);

    if (irq_levels[n] != level) {
        CharBackend *chr = &qtest_chr;
        irq_levels[n] = level;
        qtest_send_prefix(chr);
        qtest_sendf(chr, "IRQ %s %d\n",
                    level ? "raise" : "lower", n);
    }
}

static void qtest_process_command(CharBackend *chr, gchar **words)
{
    const gchar *command;

    g_assert(words);

    command = words[0];

    if (qtest_log_fp) {
        qemu_timeval tv;
        int i;

        qtest_get_time(&tv);
        fprintf(qtest_log_fp, "[R +" FMT_timeval "]",
                (long) tv.tv_sec, (long) tv.tv_usec);
        for (i = 0; words[i]; i++) {
            fprintf(qtest_log_fp, " %s", words[i]);
        }
        fprintf(qtest_log_fp, "\n");
    }

    g_assert(command);
    if (strcmp(words[0], "irq_intercept_out") == 0
        || strcmp(words[0], "irq_intercept_in") == 0) {
        DeviceState *dev;
        NamedGPIOList *ngl;

        g_assert(words[1]);
        dev = DEVICE(object_resolve_path(words[1], NULL));
        if (!dev) {
            qtest_send_prefix(chr);
            qtest_send(chr, "FAIL Unknown device\n");
	    return;
        }

        if (irq_intercept_dev) {
            qtest_send_prefix(chr);
            if (irq_intercept_dev != dev) {
                qtest_send(chr, "FAIL IRQ intercept already enabled\n");
            } else {
                qtest_send(chr, "OK\n");
            }
	    return;
        }

        QLIST_FOREACH(ngl, &dev->gpios, node) {
            /* We don't support intercept of named GPIOs yet */
            if (ngl->name) {
                continue;
            }
            if (words[0][14] == 'o') {
                int i;
                for (i = 0; i < ngl->num_out; ++i) {
                    qemu_irq *disconnected = g_new0(qemu_irq, 1);
                    qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
                                                      disconnected, i);

                    *disconnected = qdev_intercept_gpio_out(dev, icpt,
                                                            ngl->name, i);
                }
            } else {
                qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
                                      ngl->num_in);
            }
        }
        irq_intercept_dev = dev;
        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");

    } else if (strcmp(words[0], "outb") == 0 ||
               strcmp(words[0], "outw") == 0 ||
               strcmp(words[0], "outl") == 0) {
        unsigned long addr;
        unsigned long value;

        g_assert(words[1] && words[2]);
        g_assert(qemu_strtoul(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoul(words[2], NULL, 0, &value) == 0);
        g_assert(addr <= 0xffff);

        if (words[0][3] == 'b') {
            cpu_outb(addr, value);
        } else if (words[0][3] == 'w') {
            cpu_outw(addr, value);
        } else if (words[0][3] == 'l') {
            cpu_outl(addr, value);
        }
        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "inb") == 0 ||
        strcmp(words[0], "inw") == 0 ||
        strcmp(words[0], "inl") == 0) {
        unsigned long addr;
        uint32_t value = -1U;

        g_assert(words[1]);
        g_assert(qemu_strtoul(words[1], NULL, 0, &addr) == 0);
        g_assert(addr <= 0xffff);

        if (words[0][2] == 'b') {
            value = cpu_inb(addr);
        } else if (words[0][2] == 'w') {
            value = cpu_inw(addr);
        } else if (words[0][2] == 'l') {
            value = cpu_inl(addr);
        }
        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK 0x%04x\n", value);
    } else if (strcmp(words[0], "writeb") == 0 ||
               strcmp(words[0], "writew") == 0 ||
               strcmp(words[0], "writel") == 0 ||
               strcmp(words[0], "writeq") == 0) {
        uint64_t addr;
        uint64_t value;

        g_assert(words[1] && words[2]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoull(words[2], NULL, 0, &value) == 0);

        if (words[0][5] == 'b') {
            uint8_t data = value;
            cpu_physical_memory_write(addr, &data, 1);
        } else if (words[0][5] == 'w') {
            uint16_t data = value;
            tswap16s(&data);
            cpu_physical_memory_write(addr, &data, 2);
        } else if (words[0][5] == 'l') {
            uint32_t data = value;
            tswap32s(&data);
            cpu_physical_memory_write(addr, &data, 4);
        } else if (words[0][5] == 'q') {
            uint64_t data = value;
            tswap64s(&data);
            cpu_physical_memory_write(addr, &data, 8);
        }
        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "readb") == 0 ||
               strcmp(words[0], "readw") == 0 ||
               strcmp(words[0], "readl") == 0 ||
               strcmp(words[0], "readq") == 0) {
        uint64_t addr;
        uint64_t value = UINT64_C(-1);

        g_assert(words[1]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);

        if (words[0][4] == 'b') {
            uint8_t data;
            cpu_physical_memory_read(addr, &data, 1);
            value = data;
        } else if (words[0][4] == 'w') {
            uint16_t data;
            cpu_physical_memory_read(addr, &data, 2);
            value = tswap16(data);
        } else if (words[0][4] == 'l') {
            uint32_t data;
            cpu_physical_memory_read(addr, &data, 4);
            value = tswap32(data);
        } else if (words[0][4] == 'q') {
            cpu_physical_memory_read(addr, &value, 8);
            tswap64s(&value);
        }
        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
    } else if (strcmp(words[0], "read") == 0) {
        uint64_t addr, len, i;
        uint8_t *data;
        char *enc;

        g_assert(words[1] && words[2]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);

        data = g_malloc(len);
        cpu_physical_memory_read(addr, data, len);

        enc = g_malloc(2 * len + 1);
        for (i = 0; i < len; i++) {
            sprintf(&enc[i * 2], "%02x", data[i]);
        }

        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK 0x%s\n", enc);

        g_free(data);
        g_free(enc);
    } else if (strcmp(words[0], "b64read") == 0) {
        uint64_t addr, len;
        uint8_t *data;
        gchar *b64_data;

        g_assert(words[1] && words[2]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);

        data = g_malloc(len);
        cpu_physical_memory_read(addr, data, len);
        b64_data = g_base64_encode(data, len);
        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK %s\n", b64_data);

        g_free(data);
        g_free(b64_data);
    } else if (strcmp(words[0], "write") == 0) {
        uint64_t addr, len, i;
        uint8_t *data;
        size_t data_len;

        g_assert(words[1] && words[2] && words[3]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);

        data_len = strlen(words[3]);
        if (data_len < 3) {
            qtest_send(chr, "ERR invalid argument size\n");
            return;
        }

        data = g_malloc(len);
        for (i = 0; i < len; i++) {
            if ((i * 2 + 4) <= data_len) {
                data[i] = hex2nib(words[3][i * 2 + 2]) << 4;
                data[i] |= hex2nib(words[3][i * 2 + 3]);
            } else {
                data[i] = 0;
            }
        }
        cpu_physical_memory_write(addr, data, len);
        g_free(data);

        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "memset") == 0) {
        uint64_t addr, len;
        uint8_t *data;
        unsigned long pattern;

        g_assert(words[1] && words[2] && words[3]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);
        g_assert(qemu_strtoul(words[3], NULL, 0, &pattern) == 0);

        if (len) {
            data = g_malloc(len);
            memset(data, pattern, len);
            cpu_physical_memory_write(addr, data, len);
            g_free(data);
        }

        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");
    }  else if (strcmp(words[0], "b64write") == 0) {
        uint64_t addr, len;
        uint8_t *data;
        size_t data_len;
        gsize out_len;

        g_assert(words[1] && words[2] && words[3]);
        g_assert(qemu_strtoull(words[1], NULL, 0, &addr) == 0);
        g_assert(qemu_strtoull(words[2], NULL, 0, &len) == 0);

        data_len = strlen(words[3]);
        if (data_len < 3) {
            qtest_send(chr, "ERR invalid argument size\n");
            return;
        }

        data = g_base64_decode_inplace(words[3], &out_len);
        if (out_len != len) {
            qtest_log_send("b64write: data length mismatch (told %"PRIu64", "
                           "found %zu)\n",
                           len, out_len);
            out_len = MIN(out_len, len);
        }

        cpu_physical_memory_write(addr, data, out_len);

        qtest_send_prefix(chr);
        qtest_send(chr, "OK\n");
    } else if (strcmp(words[0], "endianness") == 0) {
        qtest_send_prefix(chr);
#if defined(TARGET_WORDS_BIGENDIAN)
        qtest_sendf(chr, "OK big\n");
#else
        qtest_sendf(chr, "OK little\n");
#endif
#ifdef TARGET_PPC64
    } else if (strcmp(words[0], "rtas") == 0) {
        uint64_t res, args, ret;
        unsigned long nargs, nret;

        g_assert(qemu_strtoul(words[2], NULL, 0, &nargs) == 0);
        g_assert(qemu_strtoull(words[3], NULL, 0, &args) == 0);
        g_assert(qemu_strtoul(words[4], NULL, 0, &nret) == 0);
        g_assert(qemu_strtoull(words[5], NULL, 0, &ret) == 0);
        res = qtest_rtas_call(words[1], nargs, args, nret, ret);

        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK %"PRIu64"\n", res);
#endif
    } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
        int64_t ns;

        if (words[1]) {
            g_assert(qemu_strtoll(words[1], NULL, 0, &ns) == 0);
        } else {
            ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
        }
        qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK %"PRIi64"\n",
                    (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
    } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
        int64_t ns;

        g_assert(words[1]);
        g_assert(qemu_strtoll(words[1], NULL, 0, &ns) == 0);
        qtest_clock_warp(ns);
        qtest_send_prefix(chr);
        qtest_sendf(chr, "OK %"PRIi64"\n",
                    (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
    } else {
        qtest_send_prefix(chr);
        qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
    }
}

static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
{
    char *end;

    while ((end = strchr(inbuf->str, '\n')) != NULL) {
        size_t offset;
        GString *cmd;
        gchar **words;

        offset = end - inbuf->str;

        cmd = g_string_new_len(inbuf->str, offset);
        g_string_erase(inbuf, 0, offset + 1);

        words = g_strsplit(cmd->str, " ", 0);
        qtest_process_command(chr, words);
        g_strfreev(words);

        g_string_free(cmd, TRUE);
    }
}

static void qtest_read(void *opaque, const uint8_t *buf, int size)
{
    CharBackend *chr = opaque;

    g_string_append_len(inbuf, (const gchar *)buf, size);
    qtest_process_inbuf(chr, inbuf);
}

static int qtest_can_read(void *opaque)
{
    return 1024;
}

static void qtest_event(void *opaque, int event)
{
    int i;

    switch (event) {
    case CHR_EVENT_OPENED:
        /*
         * We used to call qemu_system_reset() here, hoping we could
         * use the same process for multiple tests that way.  Never
         * used.  Injects an extra reset even when it's not used, and
         * that can mess up tests, e.g. -boot once.
         */
        for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
            irq_levels[i] = 0;
        }
        qemu_gettimeofday(&start_time);
        qtest_opened = true;
        if (qtest_log_fp) {
            fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n",
                    (long) start_time.tv_sec, (long) start_time.tv_usec);
        }
        break;
    case CHR_EVENT_CLOSED:
        qtest_opened = false;
        if (qtest_log_fp) {
            qemu_timeval tv;
            qtest_get_time(&tv);
            fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n",
                    (long) tv.tv_sec, (long) tv.tv_usec);
        }
        break;
    default:
        break;
    }
}

static int qtest_init_accel(MachineState *ms)
{
    QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0,
                                      &error_abort);
    qemu_opt_set(opts, "shift", "0", &error_abort);
    configure_icount(opts, &error_abort);
    qemu_opts_del(opts);
    return 0;
}

void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
{
    CharDriverState *chr;

    chr = qemu_chr_new("qtest", qtest_chrdev);

    if (chr == NULL) {
        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
                   qtest_chrdev);
        return;
    }

    if (qtest_log) {
        if (strcmp(qtest_log, "none") != 0) {
            qtest_log_fp = fopen(qtest_log, "w+");
        }
    } else {
        qtest_log_fp = stderr;
    }

    qemu_chr_fe_init(&qtest_chr, chr, errp);
    qemu_chr_fe_set_handlers(&qtest_chr, qtest_can_read, qtest_read,
                             qtest_event, &qtest_chr, NULL, true);
    qemu_chr_fe_set_echo(&qtest_chr, true);

    inbuf = g_string_new("");
}

bool qtest_driver(void)
{
    return qtest_chr.chr != NULL;
}

static void qtest_accel_class_init(ObjectClass *oc, void *data)
{
    AccelClass *ac = ACCEL_CLASS(oc);
    ac->name = "QTest";
    ac->available = qtest_available;
    ac->init_machine = qtest_init_accel;
    ac->allowed = &qtest_allowed;
}

#define TYPE_QTEST_ACCEL ACCEL_CLASS_NAME("qtest")

static const TypeInfo qtest_accel_type = {
    .name = TYPE_QTEST_ACCEL,
    .parent = TYPE_ACCEL,
    .class_init = qtest_accel_class_init,
};

static void qtest_type_init(void)
{
    type_register_static(&qtest_accel_type);
}

type_init(qtest_type_init);
