/*
 * QTests for Nuvoton NPCM7xx Timer Watchdog Modules.
 *
 * Copyright 2020 Google LLC
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */

#include "qemu/osdep.h"
#include "qemu/timer.h"

#include "libqtest.h"
#include "qapi/qmp/qdict.h"

#define WTCR_OFFSET     0x1c
#define REF_HZ          (25000000)

/* WTCR bit fields */
#define WTCLK(rv)       ((rv) << 10)
#define WTE             BIT(7)
#define WTIE            BIT(6)
#define WTIS(rv)        ((rv) << 4)
#define WTIF            BIT(3)
#define WTRF            BIT(2)
#define WTRE            BIT(1)
#define WTR             BIT(0)

typedef struct Watchdog {
    int irq;
    uint64_t base_addr;
} Watchdog;

static const Watchdog watchdog_list[] = {
    {
        .irq        = 47,
        .base_addr  = 0xf0008000
    },
    {
        .irq        = 48,
        .base_addr  = 0xf0009000
    },
    {
        .irq        = 49,
        .base_addr  = 0xf000a000
    }
};

static int watchdog_index(const Watchdog *wd)
{
    ptrdiff_t diff = wd - watchdog_list;

    g_assert(diff >= 0 && diff < ARRAY_SIZE(watchdog_list));

    return diff;
}

static uint32_t watchdog_read_wtcr(QTestState *qts, const Watchdog *wd)
{
    return qtest_readl(qts, wd->base_addr + WTCR_OFFSET);
}

static void watchdog_write_wtcr(QTestState *qts, const Watchdog *wd,
        uint32_t value)
{
    qtest_writel(qts, wd->base_addr + WTCR_OFFSET, value);
}

static uint32_t watchdog_prescaler(QTestState *qts, const Watchdog *wd)
{
    switch (extract32(watchdog_read_wtcr(qts, wd), 10, 2)) {
    case 0:
        return 1;
    case 1:
        return 256;
    case 2:
        return 2048;
    case 3:
        return 65536;
    default:
        g_assert_not_reached();
    }
}

static QDict *get_watchdog_action(QTestState *qts)
{
    QDict *ev = qtest_qmp_eventwait_ref(qts, "WATCHDOG");
    QDict *data;

    data = qdict_get_qdict(ev, "data");
    qobject_ref(data);
    qobject_unref(ev);
    return data;
}

#define RESET_CYCLES 1024
static uint32_t watchdog_interrupt_cycles(QTestState *qts, const Watchdog *wd)
{
    uint32_t wtis = extract32(watchdog_read_wtcr(qts, wd), 4, 2);
    return 1 << (14 + 2 * wtis);
}

static int64_t watchdog_calculate_steps(uint32_t count, uint32_t prescale)
{
    return (NANOSECONDS_PER_SECOND / REF_HZ) * count * prescale;
}

static int64_t watchdog_interrupt_steps(QTestState *qts, const Watchdog *wd)
{
    return watchdog_calculate_steps(watchdog_interrupt_cycles(qts, wd),
            watchdog_prescaler(qts, wd));
}

/* Check wtcr can be reset to default value */
static void test_init(gconstpointer watchdog)
{
    const Watchdog *wd = watchdog;
    QTestState *qts = qtest_init("-machine quanta-gsj");

    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");

    watchdog_write_wtcr(qts, wd, WTCLK(1) | WTRF | WTIF | WTR);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==, WTCLK(1));

    qtest_quit(qts);
}

/* Check a watchdog can generate interrupt and reset actions */
static void test_reset_action(gconstpointer watchdog)
{
    const Watchdog *wd = watchdog;
    QTestState *qts = qtest_init("-machine quanta-gsj");
    QDict *ad;

    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");

    watchdog_write_wtcr(qts, wd,
            WTCLK(0) | WTE | WTRF | WTRE | WTIF | WTIE | WTR);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==,
            WTCLK(0) | WTE | WTRE | WTIE);

    /* Check a watchdog can generate an interrupt */
    qtest_clock_step(qts, watchdog_interrupt_steps(qts, wd));
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==,
            WTCLK(0) | WTE | WTIF | WTIE | WTRE);
    g_assert_true(qtest_get_irq(qts, wd->irq));

    /* Check a watchdog can generate a reset signal */
    qtest_clock_step(qts, watchdog_calculate_steps(RESET_CYCLES,
                watchdog_prescaler(qts, wd)));
    ad = get_watchdog_action(qts);
    /* The signal is a reset signal */
    g_assert_false(strcmp(qdict_get_str(ad, "action"), "reset"));
    qobject_unref(ad);
    qtest_qmp_eventwait(qts, "RESET");
    /*
     * Make sure WTCR is reset to default except for WTRF bit which shouldn't
     * be reset.
     */
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==, WTCLK(1) | WTRF);
    qtest_quit(qts);
}

/* Check a watchdog works with all possible WTCLK prescalers and WTIS cycles */
static void test_prescaler(gconstpointer watchdog)
{
    const Watchdog *wd = watchdog;

    for (int wtclk = 0; wtclk < 4; ++wtclk) {
        for (int wtis = 0; wtis < 4; ++wtis) {
            QTestState *qts = qtest_init("-machine quanta-gsj");

            qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
            watchdog_write_wtcr(qts, wd,
                    WTCLK(wtclk) | WTE | WTIF | WTIS(wtis) | WTIE | WTR);
            /*
             * The interrupt doesn't fire until watchdog_interrupt_steps()
             * cycles passed
             */
            qtest_clock_step(qts, watchdog_interrupt_steps(qts, wd) - 1);
            g_assert_false(watchdog_read_wtcr(qts, wd) & WTIF);
            g_assert_false(qtest_get_irq(qts, wd->irq));
            qtest_clock_step(qts, 1);
            g_assert_true(watchdog_read_wtcr(qts, wd) & WTIF);
            g_assert_true(qtest_get_irq(qts, wd->irq));

            qtest_quit(qts);
        }
    }
}

/*
 * Check a watchdog doesn't fire if corresponding flags (WTIE and WTRE) are not
 * set.
 */
static void test_enabling_flags(gconstpointer watchdog)
{
    const Watchdog *wd = watchdog;
    QTestState *qts;
    QDict *rsp;

    /* Neither WTIE or WTRE is set, no interrupt or reset should happen */
    qts = qtest_init("-machine quanta-gsj");
    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
    watchdog_write_wtcr(qts, wd, WTCLK(0) | WTE | WTIF | WTRF | WTR);
    qtest_clock_step(qts, watchdog_interrupt_steps(qts, wd));
    g_assert_true(watchdog_read_wtcr(qts, wd) & WTIF);
    g_assert_false(qtest_get_irq(qts, wd->irq));
    qtest_clock_step(qts, watchdog_calculate_steps(RESET_CYCLES,
                watchdog_prescaler(qts, wd)));
    g_assert_true(watchdog_read_wtcr(qts, wd) & WTIF);
    g_assert_false(watchdog_read_wtcr(qts, wd) & WTRF);
    qtest_quit(qts);

    /* Only WTIE is set, interrupt is triggered but reset should not happen */
    qts = qtest_init("-machine quanta-gsj");
    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
    watchdog_write_wtcr(qts, wd, WTCLK(0) | WTE | WTIF | WTIE | WTRF | WTR);
    qtest_clock_step(qts, watchdog_interrupt_steps(qts, wd));
    g_assert_true(watchdog_read_wtcr(qts, wd) & WTIF);
    g_assert_true(qtest_get_irq(qts, wd->irq));
    qtest_clock_step(qts, watchdog_calculate_steps(RESET_CYCLES,
                watchdog_prescaler(qts, wd)));
    g_assert_true(watchdog_read_wtcr(qts, wd) & WTIF);
    g_assert_false(watchdog_read_wtcr(qts, wd) & WTRF);
    qtest_quit(qts);

    /* Only WTRE is set, interrupt is triggered but reset should not happen */
    qts = qtest_init("-machine quanta-gsj");
    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
    watchdog_write_wtcr(qts, wd, WTCLK(0) | WTE | WTIF | WTRE | WTRF | WTR);
    qtest_clock_step(qts, watchdog_interrupt_steps(qts, wd));
    g_assert_true(watchdog_read_wtcr(qts, wd) & WTIF);
    g_assert_false(qtest_get_irq(qts, wd->irq));
    qtest_clock_step(qts, watchdog_calculate_steps(RESET_CYCLES,
                watchdog_prescaler(qts, wd)));
    rsp = get_watchdog_action(qts);
    g_assert_false(strcmp(qdict_get_str(rsp, "action"), "reset"));
    qobject_unref(rsp);
    qtest_qmp_eventwait(qts, "RESET");
    qtest_quit(qts);

    /*
     * The case when both flags are set is already tested in
     * test_reset_action().
     */
}

/* Check a watchdog can pause and resume by setting WTE bits */
static void test_pause(gconstpointer watchdog)
{
    const Watchdog *wd = watchdog;
    QTestState *qts;
    int64_t remaining_steps, steps;

    qts = qtest_init("-machine quanta-gsj");
    qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
    watchdog_write_wtcr(qts, wd, WTCLK(0) | WTE | WTIF | WTIE | WTRF | WTR);
    remaining_steps = watchdog_interrupt_steps(qts, wd);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==, WTCLK(0) | WTE | WTIE);

    /* Run for half of the execution period. */
    steps = remaining_steps / 2;
    remaining_steps -= steps;
    qtest_clock_step(qts, steps);

    /* Pause the watchdog */
    watchdog_write_wtcr(qts, wd, WTCLK(0) | WTIE);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==, WTCLK(0) | WTIE);

    /* Run for a long period of time, the watchdog shouldn't fire */
    qtest_clock_step(qts, steps << 4);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==, WTCLK(0) | WTIE);
    g_assert_false(qtest_get_irq(qts, wd->irq));

    /* Resume the watchdog */
    watchdog_write_wtcr(qts, wd, WTCLK(0) | WTE | WTIE);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==, WTCLK(0) | WTE | WTIE);

    /* Run for the reset of the execution period, the watchdog should fire */
    qtest_clock_step(qts, remaining_steps);
    g_assert_cmphex(watchdog_read_wtcr(qts, wd), ==,
            WTCLK(0) | WTE | WTIF | WTIE);
    g_assert_true(qtest_get_irq(qts, wd->irq));

    qtest_quit(qts);
}

static void watchdog_add_test(const char *name, const Watchdog* wd,
        GTestDataFunc fn)
{
    g_autofree char *full_name = g_strdup_printf(
            "npcm7xx_watchdog_timer[%d]/%s", watchdog_index(wd), name);
    qtest_add_data_func(full_name, wd, fn);
}
#define add_test(name, td) watchdog_add_test(#name, td, test_##name)

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

    for (int i = 0; i < ARRAY_SIZE(watchdog_list); ++i) {
        const Watchdog *wd = &watchdog_list[i];

        add_test(init, wd);
        add_test(reset_action, wd);
        add_test(prescaler, wd);
        add_test(enabling_flags, wd);
        add_test(pause, wd);
    }

    return g_test_run();
}
