/*
 * QEMU ICH9 TCO emulation tests
 *
 * Copyright (c) 2015 Paulo Alcantara <pcacjr@zytor.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 "libqtest.h"
#include "libqos/pci.h"
#include "libqos/pci-pc.h"
#include "hw/pci/pci_regs.h"
#include "hw/i386/ich9.h"
#include "hw/acpi/ich9.h"
#include "hw/acpi/tco.h"

#define RCBA_BASE_ADDR    0xfed1c000
#define PM_IO_BASE_ADDR   0xb000

enum {
    TCO_RLD_DEFAULT         = 0x0000,
    TCO_DAT_IN_DEFAULT      = 0x00,
    TCO_DAT_OUT_DEFAULT     = 0x00,
    TCO1_STS_DEFAULT        = 0x0000,
    TCO2_STS_DEFAULT        = 0x0000,
    TCO1_CNT_DEFAULT        = 0x0000,
    TCO2_CNT_DEFAULT        = 0x0008,
    TCO_MESSAGE1_DEFAULT    = 0x00,
    TCO_MESSAGE2_DEFAULT    = 0x00,
    TCO_WDCNT_DEFAULT       = 0x00,
    TCO_TMR_DEFAULT         = 0x0004,
    SW_IRQ_GEN_DEFAULT      = 0x03,
};

#define TCO_SECS_TO_TICKS(secs)     (((secs) * 10) / 6)
#define TCO_TICKS_TO_SECS(ticks)    (((ticks) * 6) / 10)

typedef struct {
    const char *args;
    bool noreboot;
    QPCIDevice *dev;
    void *tco_io_base;
} TestData;

static void test_init(TestData *d)
{
    QPCIBus *bus;
    QTestState *qs;
    char *s;

    s = g_strdup_printf("-machine q35 %s %s",
                        d->noreboot ? "" : "-global ICH9-LPC.noreboot=false",
                        !d->args ? "" : d->args);
    qs = qtest_start(s);
    qtest_irq_intercept_in(qs, "ioapic");
    g_free(s);

    bus = qpci_init_pc();
    d->dev = qpci_device_find(bus, QPCI_DEVFN(0x1f, 0x00));
    g_assert(d->dev != NULL);

    qpci_device_enable(d->dev);

    /* set ACPI PM I/O space base address */
    qpci_config_writel(d->dev, ICH9_LPC_PMBASE, PM_IO_BASE_ADDR | 0x1);
    /* enable ACPI I/O */
    qpci_config_writeb(d->dev, ICH9_LPC_ACPI_CTRL, 0x80);
    /* set Root Complex BAR */
    qpci_config_writel(d->dev, ICH9_LPC_RCBA, RCBA_BASE_ADDR | 0x1);

    d->tco_io_base = (void *)((uintptr_t)PM_IO_BASE_ADDR + 0x60);
}

static void stop_tco(const TestData *d)
{
    uint32_t val;

    val = qpci_io_readw(d->dev, d->tco_io_base + TCO1_CNT);
    val |= TCO_TMR_HLT;
    qpci_io_writew(d->dev, d->tco_io_base + TCO1_CNT, val);
}

static void start_tco(const TestData *d)
{
    uint32_t val;

    val = qpci_io_readw(d->dev, d->tco_io_base + TCO1_CNT);
    val &= ~TCO_TMR_HLT;
    qpci_io_writew(d->dev, d->tco_io_base + TCO1_CNT, val);
}

static void load_tco(const TestData *d)
{
    qpci_io_writew(d->dev, d->tco_io_base + TCO_RLD, 4);
}

static void set_tco_timeout(const TestData *d, uint16_t ticks)
{
    qpci_io_writew(d->dev, d->tco_io_base + TCO_TMR, ticks);
}

static void clear_tco_status(const TestData *d)
{
    qpci_io_writew(d->dev, d->tco_io_base + TCO1_STS, 0x0008);
    qpci_io_writew(d->dev, d->tco_io_base + TCO2_STS, 0x0002);
    qpci_io_writew(d->dev, d->tco_io_base + TCO2_STS, 0x0004);
}

static void reset_on_second_timeout(bool enable)
{
    uint32_t val;

    val = readl(RCBA_BASE_ADDR + ICH9_CC_GCS);
    if (enable) {
        val &= ~ICH9_CC_GCS_NO_REBOOT;
    } else {
        val |= ICH9_CC_GCS_NO_REBOOT;
    }
    writel(RCBA_BASE_ADDR + ICH9_CC_GCS, val);
}

static void test_tco_defaults(void)
{
    TestData d;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD), ==,
                    TCO_RLD_DEFAULT);
    /* TCO_DAT_IN & TCO_DAT_OUT */
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_DAT_IN), ==,
                    (TCO_DAT_OUT_DEFAULT << 8) | TCO_DAT_IN_DEFAULT);
    /* TCO1_STS & TCO2_STS */
    g_assert_cmpint(qpci_io_readl(d.dev, d.tco_io_base + TCO1_STS), ==,
                    (TCO2_STS_DEFAULT << 16) | TCO1_STS_DEFAULT);
    /* TCO1_CNT & TCO2_CNT */
    g_assert_cmpint(qpci_io_readl(d.dev, d.tco_io_base + TCO1_CNT), ==,
                    (TCO2_CNT_DEFAULT << 16) | TCO1_CNT_DEFAULT);
    /* TCO_MESSAGE1 & TCO_MESSAGE2 */
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_MESSAGE1), ==,
                    (TCO_MESSAGE2_DEFAULT << 8) | TCO_MESSAGE1_DEFAULT);
    g_assert_cmpint(qpci_io_readb(d.dev, d.tco_io_base + TCO_WDCNT), ==,
                    TCO_WDCNT_DEFAULT);
    g_assert_cmpint(qpci_io_readb(d.dev, d.tco_io_base + SW_IRQ_GEN), ==,
                    SW_IRQ_GEN_DEFAULT);
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO_TMR), ==,
                    TCO_TMR_DEFAULT);
    qtest_end();
}

static void test_tco_timeout(void)
{
    TestData d;
    const uint16_t ticks = TCO_SECS_TO_TICKS(4);
    uint32_t val;
    int ret;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);

    stop_tco(&d);
    clear_tco_status(&d);
    reset_on_second_timeout(false);
    set_tco_timeout(&d, ticks);
    load_tco(&d);
    start_tco(&d);
    clock_step(ticks * TCO_TICK_NSEC);

    /* test first timeout */
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
    ret = val & TCO_TIMEOUT ? 1 : 0;
    g_assert(ret == 1);

    /* test clearing timeout bit */
    val |= TCO_TIMEOUT;
    qpci_io_writew(d.dev, d.tco_io_base + TCO1_STS, val);
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
    ret = val & TCO_TIMEOUT ? 1 : 0;
    g_assert(ret == 0);

    /* test second timeout */
    clock_step(ticks * TCO_TICK_NSEC);
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
    ret = val & TCO_TIMEOUT ? 1 : 0;
    g_assert(ret == 1);
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS);
    ret = val & TCO_SECOND_TO_STS ? 1 : 0;
    g_assert(ret == 1);

    stop_tco(&d);
    qtest_end();
}

static void test_tco_max_timeout(void)
{
    TestData d;
    const uint16_t ticks = 0xffff;
    uint32_t val;
    int ret;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);

    stop_tco(&d);
    clear_tco_status(&d);
    reset_on_second_timeout(false);
    set_tco_timeout(&d, ticks);
    load_tco(&d);
    start_tco(&d);
    clock_step(((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC);

    val = qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD);
    g_assert_cmpint(val & TCO_RLD_MASK, ==, 1);
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
    ret = val & TCO_TIMEOUT ? 1 : 0;
    g_assert(ret == 0);
    clock_step(TCO_TICK_NSEC);
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
    ret = val & TCO_TIMEOUT ? 1 : 0;
    g_assert(ret == 1);

    stop_tco(&d);
    qtest_end();
}

static QDict *get_watchdog_action(void)
{
    QDict *ev = qmp("");
    QDict *data;
    g_assert(!strcmp(qdict_get_str(ev, "event"), "WATCHDOG"));

    data = qdict_get_qdict(ev, "data");
    QINCREF(data);
    QDECREF(ev);
    return data;
}

static void test_tco_second_timeout_pause(void)
{
    TestData td;
    const uint16_t ticks = TCO_SECS_TO_TICKS(32);
    QDict *ad;

    td.args = "-watchdog-action pause";
    td.noreboot = false;
    test_init(&td);

    stop_tco(&td);
    clear_tco_status(&td);
    reset_on_second_timeout(true);
    set_tco_timeout(&td, TCO_SECS_TO_TICKS(16));
    load_tco(&td);
    start_tco(&td);
    clock_step(ticks * TCO_TICK_NSEC * 2);
    ad = get_watchdog_action();
    g_assert(!strcmp(qdict_get_str(ad, "action"), "pause"));
    QDECREF(ad);

    stop_tco(&td);
    qtest_end();
}

static void test_tco_second_timeout_reset(void)
{
    TestData td;
    const uint16_t ticks = TCO_SECS_TO_TICKS(16);
    QDict *ad;

    td.args = "-watchdog-action reset";
    td.noreboot = false;
    test_init(&td);

    stop_tco(&td);
    clear_tco_status(&td);
    reset_on_second_timeout(true);
    set_tco_timeout(&td, TCO_SECS_TO_TICKS(16));
    load_tco(&td);
    start_tco(&td);
    clock_step(ticks * TCO_TICK_NSEC * 2);
    ad = get_watchdog_action();
    g_assert(!strcmp(qdict_get_str(ad, "action"), "reset"));
    QDECREF(ad);

    stop_tco(&td);
    qtest_end();
}

static void test_tco_second_timeout_shutdown(void)
{
    TestData td;
    const uint16_t ticks = TCO_SECS_TO_TICKS(128);
    QDict *ad;

    td.args = "-watchdog-action shutdown";
    td.noreboot = false;
    test_init(&td);

    stop_tco(&td);
    clear_tco_status(&td);
    reset_on_second_timeout(true);
    set_tco_timeout(&td, ticks);
    load_tco(&td);
    start_tco(&td);
    clock_step(ticks * TCO_TICK_NSEC * 2);
    ad = get_watchdog_action();
    g_assert(!strcmp(qdict_get_str(ad, "action"), "shutdown"));
    QDECREF(ad);

    stop_tco(&td);
    qtest_end();
}

static void test_tco_second_timeout_none(void)
{
    TestData td;
    const uint16_t ticks = TCO_SECS_TO_TICKS(256);
    QDict *ad;

    td.args = "-watchdog-action none";
    td.noreboot = false;
    test_init(&td);

    stop_tco(&td);
    clear_tco_status(&td);
    reset_on_second_timeout(true);
    set_tco_timeout(&td, ticks);
    load_tco(&td);
    start_tco(&td);
    clock_step(ticks * TCO_TICK_NSEC * 2);
    ad = get_watchdog_action();
    g_assert(!strcmp(qdict_get_str(ad, "action"), "none"));
    QDECREF(ad);

    stop_tco(&td);
    qtest_end();
}

static void test_tco_ticks_counter(void)
{
    TestData d;
    uint16_t ticks = TCO_SECS_TO_TICKS(8);
    uint16_t rld;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);

    stop_tco(&d);
    clear_tco_status(&d);
    reset_on_second_timeout(false);
    set_tco_timeout(&d, ticks);
    load_tco(&d);
    start_tco(&d);

    do {
        rld = qpci_io_readw(d.dev, d.tco_io_base + TCO_RLD) & TCO_RLD_MASK;
        g_assert_cmpint(rld, ==, ticks);
        clock_step(TCO_TICK_NSEC);
        ticks--;
    } while (!(qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS) & TCO_TIMEOUT));

    stop_tco(&d);
    qtest_end();
}

static void test_tco1_control_bits(void)
{
    TestData d;
    uint16_t val;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);

    val = TCO_LOCK;
    qpci_io_writew(d.dev, d.tco_io_base + TCO1_CNT, val);
    val &= ~TCO_LOCK;
    qpci_io_writew(d.dev, d.tco_io_base + TCO1_CNT, val);
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO1_CNT), ==,
                    TCO_LOCK);
    qtest_end();
}

static void test_tco1_status_bits(void)
{
    TestData d;
    uint16_t ticks = 8;
    uint16_t val;
    int ret;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);

    stop_tco(&d);
    clear_tco_status(&d);
    reset_on_second_timeout(false);
    set_tco_timeout(&d, ticks);
    load_tco(&d);
    start_tco(&d);
    clock_step(ticks * TCO_TICK_NSEC);

    qpci_io_writeb(d.dev, d.tco_io_base + TCO_DAT_IN, 0);
    qpci_io_writeb(d.dev, d.tco_io_base + TCO_DAT_OUT, 0);
    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);
    ret = val & (TCO_TIMEOUT | SW_TCO_SMI | TCO_INT_STS) ? 1 : 0;
    g_assert(ret == 1);
    qpci_io_writew(d.dev, d.tco_io_base + TCO1_STS, val);
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS), ==, 0);
    qtest_end();
}

static void test_tco2_status_bits(void)
{
    TestData d;
    uint16_t ticks = 8;
    uint16_t val;
    int ret;

    d.args = NULL;
    d.noreboot = true;
    test_init(&d);

    stop_tco(&d);
    clear_tco_status(&d);
    reset_on_second_timeout(true);
    set_tco_timeout(&d, ticks);
    load_tco(&d);
    start_tco(&d);
    clock_step(ticks * TCO_TICK_NSEC * 2);

    val = qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS);
    ret = val & (TCO_SECOND_TO_STS | TCO_BOOT_STS) ? 1 : 0;
    g_assert(ret == 1);
    qpci_io_writew(d.dev, d.tco_io_base + TCO2_STS, val);
    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS), ==, 0);
    qtest_end();
}

int main(int argc, char **argv)
{
    g_test_init(&argc, &argv, NULL);

    qtest_add_func("tco/defaults", test_tco_defaults);
    qtest_add_func("tco/timeout/no_action", test_tco_timeout);
    qtest_add_func("tco/timeout/no_action/max", test_tco_max_timeout);
    qtest_add_func("tco/second_timeout/pause", test_tco_second_timeout_pause);
    qtest_add_func("tco/second_timeout/reset", test_tco_second_timeout_reset);
    qtest_add_func("tco/second_timeout/shutdown",
                   test_tco_second_timeout_shutdown);
    qtest_add_func("tco/second_timeout/none", test_tco_second_timeout_none);
    qtest_add_func("tco/counter", test_tco_ticks_counter);
    qtest_add_func("tco/tco1_control/bits", test_tco1_control_bits);
    qtest_add_func("tco/tco1_status/bits", test_tco1_status_bits);
    qtest_add_func("tco/tco2_status/bits", test_tco2_status_bits);
    return g_test_run();
}
