/*
 * Virtual hardware watchdog.
 *
 * Copyright (C) 2009 Red Hat Inc.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 * By Richard W.M. Jones (rjones@redhat.com).
 */

#include <inttypes.h>

#include "qemu-common.h"
#include "qemu/timer.h"
#include "sysemu/watchdog.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"

/*#define I6300ESB_DEBUG 1*/

#ifdef I6300ESB_DEBUG
#define i6300esb_debug(fs,...) \
    fprintf(stderr,"i6300esb: %s: "fs,__func__,##__VA_ARGS__)
#else
#define i6300esb_debug(fs,...)
#endif

/* PCI configuration registers */
#define ESB_CONFIG_REG  0x60            /* Config register                   */
#define ESB_LOCK_REG    0x68            /* WDT lock register                 */

/* Memory mapped registers (offset from base address) */
#define ESB_TIMER1_REG  0x00            /* Timer1 value after each reset     */
#define ESB_TIMER2_REG  0x04            /* Timer2 value after each reset     */
#define ESB_GINTSR_REG  0x08            /* General Interrupt Status Register */
#define ESB_RELOAD_REG  0x0c            /* Reload register                   */

/* Lock register bits */
#define ESB_WDT_FUNC    (0x01 << 2)   /* Watchdog functionality            */
#define ESB_WDT_ENABLE  (0x01 << 1)   /* Enable WDT                        */
#define ESB_WDT_LOCK    (0x01 << 0)   /* Lock (nowayout)                   */

/* Config register bits */
#define ESB_WDT_REBOOT  (0x01 << 5)   /* Enable reboot on timeout          */
#define ESB_WDT_FREQ    (0x01 << 2)   /* Decrement frequency               */
#define ESB_WDT_INTTYPE (0x11 << 0)   /* Interrupt type on timer1 timeout  */

/* Reload register bits */
#define ESB_WDT_RELOAD  (0x01 << 8)    /* prevent timeout                   */

/* Magic constants */
#define ESB_UNLOCK1     0x80            /* Step 1 to unlock reset registers  */
#define ESB_UNLOCK2     0x86            /* Step 2 to unlock reset registers  */

/* Device state. */
struct I6300State {
    PCIDevice dev;
    MemoryRegion io_mem;

    int reboot_enabled;         /* "Reboot" on timer expiry.  The real action
                                 * performed depends on the -watchdog-action
                                 * param passed on QEMU command line.
                                 */
    int clock_scale;            /* Clock scale. */
#define CLOCK_SCALE_1KHZ 0
#define CLOCK_SCALE_1MHZ 1

    int int_type;               /* Interrupt type generated. */
#define INT_TYPE_IRQ 0          /* APIC 1, INT 10 */
#define INT_TYPE_SMI 2
#define INT_TYPE_DISABLED 3

    int free_run;               /* If true, reload timer on expiry. */
    int locked;                 /* If true, enabled field cannot be changed. */
    int enabled;                /* If true, watchdog is enabled. */

    QEMUTimer *timer;           /* The actual watchdog timer. */

    uint32_t timer1_preload;    /* Values preloaded into timer1, timer2. */
    uint32_t timer2_preload;
    int stage;                  /* Stage (1 or 2). */

    int unlock_state;           /* Guest writes 0x80, 0x86 to unlock the
                                 * registers, and we transition through
                                 * states 0 -> 1 -> 2 when this happens.
                                 */

    int previous_reboot_flag;   /* If the watchdog caused the previous
                                 * reboot, this flag will be set.
                                 */
};

typedef struct I6300State I6300State;

/* This function is called when the watchdog has either been enabled
 * (hence it starts counting down) or has been keep-alived.
 */
static void i6300esb_restart_timer(I6300State *d, int stage)
{
    int64_t timeout;

    if (!d->enabled)
        return;

    d->stage = stage;

    if (d->stage <= 1)
        timeout = d->timer1_preload;
    else
        timeout = d->timer2_preload;

    if (d->clock_scale == CLOCK_SCALE_1KHZ)
        timeout <<= 15;
    else
        timeout <<= 5;

    /* Get the timeout in units of ticks_per_sec. */
    timeout = get_ticks_per_sec() * timeout / 33000000;

    i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);

    timer_mod(d->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
}

/* This is called when the guest disables the watchdog. */
static void i6300esb_disable_timer(I6300State *d)
{
    i6300esb_debug("timer disabled\n");

    timer_del(d->timer);
}

static void i6300esb_reset(DeviceState *dev)
{
    PCIDevice *pdev = PCI_DEVICE(dev);
    I6300State *d = DO_UPCAST(I6300State, dev, pdev);

    i6300esb_debug("I6300State = %p\n", d);

    i6300esb_disable_timer(d);

    /* NB: Don't change d->previous_reboot_flag in this function. */

    d->reboot_enabled = 1;
    d->clock_scale = CLOCK_SCALE_1KHZ;
    d->int_type = INT_TYPE_IRQ;
    d->free_run = 0;
    d->locked = 0;
    d->enabled = 0;
    d->timer1_preload = 0xfffff;
    d->timer2_preload = 0xfffff;
    d->stage = 1;
    d->unlock_state = 0;
}

/* This function is called when the watchdog expires.  Note that
 * the hardware has two timers, and so expiry happens in two stages.
 * If d->stage == 1 then we perform the first stage action (usually,
 * sending an interrupt) and then restart the timer again for the
 * second stage.  If the second stage expires then the watchdog
 * really has run out.
 */
static void i6300esb_timer_expired(void *vp)
{
    I6300State *d = vp;

    i6300esb_debug("stage %d\n", d->stage);

    if (d->stage == 1) {
        /* What to do at the end of stage 1? */
        switch (d->int_type) {
        case INT_TYPE_IRQ:
            fprintf(stderr, "i6300esb_timer_expired: I would send APIC 1 INT 10 here if I knew how (XXX)\n");
            break;
        case INT_TYPE_SMI:
            fprintf(stderr, "i6300esb_timer_expired: I would send SMI here if I knew how (XXX)\n");
            break;
        }

        /* Start the second stage. */
        i6300esb_restart_timer(d, 2);
    } else {
        /* Second stage expired, reboot for real. */
        if (d->reboot_enabled) {
            d->previous_reboot_flag = 1;
            watchdog_perform_action(); /* This reboots, exits, etc */
            i6300esb_reset(&d->dev.qdev);
        }

        /* In "free running mode" we start stage 1 again. */
        if (d->free_run)
            i6300esb_restart_timer(d, 1);
    }
}

static void i6300esb_config_write(PCIDevice *dev, uint32_t addr,
                                  uint32_t data, int len)
{
    I6300State *d = DO_UPCAST(I6300State, dev, dev);
    int old;

    i6300esb_debug("addr = %x, data = %x, len = %d\n", addr, data, len);

    if (addr == ESB_CONFIG_REG && len == 2) {
        d->reboot_enabled = (data & ESB_WDT_REBOOT) == 0;
        d->clock_scale =
            (data & ESB_WDT_FREQ) != 0 ? CLOCK_SCALE_1MHZ : CLOCK_SCALE_1KHZ;
        d->int_type = (data & ESB_WDT_INTTYPE);
    } else if (addr == ESB_LOCK_REG && len == 1) {
        if (!d->locked) {
            d->locked = (data & ESB_WDT_LOCK) != 0;
            d->free_run = (data & ESB_WDT_FUNC) != 0;
            old = d->enabled;
            d->enabled = (data & ESB_WDT_ENABLE) != 0;
            if (!old && d->enabled) /* Enabled transitioned from 0 -> 1 */
                i6300esb_restart_timer(d, 1);
            else if (!d->enabled)
                i6300esb_disable_timer(d);
        }
    } else {
        pci_default_write_config(dev, addr, data, len);
    }
}

static uint32_t i6300esb_config_read(PCIDevice *dev, uint32_t addr, int len)
{
    I6300State *d = DO_UPCAST(I6300State, dev, dev);
    uint32_t data;

    i6300esb_debug ("addr = %x, len = %d\n", addr, len);

    if (addr == ESB_CONFIG_REG && len == 2) {
        data =
            (d->reboot_enabled ? 0 : ESB_WDT_REBOOT) |
            (d->clock_scale == CLOCK_SCALE_1MHZ ? ESB_WDT_FREQ : 0) |
            d->int_type;
        return data;
    } else if (addr == ESB_LOCK_REG && len == 1) {
        data =
            (d->free_run ? ESB_WDT_FUNC : 0) |
            (d->locked ? ESB_WDT_LOCK : 0) |
            (d->enabled ? ESB_WDT_ENABLE : 0);
        return data;
    } else {
        return pci_default_read_config(dev, addr, len);
    }
}

static uint32_t i6300esb_mem_readb(void *vp, hwaddr addr)
{
    i6300esb_debug ("addr = %x\n", (int) addr);

    return 0;
}

static uint32_t i6300esb_mem_readw(void *vp, hwaddr addr)
{
    uint32_t data = 0;
    I6300State *d = vp;

    i6300esb_debug("addr = %x\n", (int) addr);

    if (addr == 0xc) {
        /* The previous reboot flag is really bit 9, but there is
         * a bug in the Linux driver where it thinks it's bit 12.
         * Set both.
         */
        data = d->previous_reboot_flag ? 0x1200 : 0;
    }

    return data;
}

static uint32_t i6300esb_mem_readl(void *vp, hwaddr addr)
{
    i6300esb_debug("addr = %x\n", (int) addr);

    return 0;
}

static void i6300esb_mem_writeb(void *vp, hwaddr addr, uint32_t val)
{
    I6300State *d = vp;

    i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);

    if (addr == 0xc && val == 0x80)
        d->unlock_state = 1;
    else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
        d->unlock_state = 2;
}

static void i6300esb_mem_writew(void *vp, hwaddr addr, uint32_t val)
{
    I6300State *d = vp;

    i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);

    if (addr == 0xc && val == 0x80)
        d->unlock_state = 1;
    else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
        d->unlock_state = 2;
    else {
        if (d->unlock_state == 2) {
            if (addr == 0xc) {
                if ((val & 0x100) != 0)
                    /* This is the "ping" from the userspace watchdog in
                     * the guest ...
                     */
                    i6300esb_restart_timer(d, 1);

                /* Setting bit 9 resets the previous reboot flag.
                 * There's a bug in the Linux driver where it sets
                 * bit 12 instead.
                 */
                if ((val & 0x200) != 0 || (val & 0x1000) != 0) {
                    d->previous_reboot_flag = 0;
                }
            }

            d->unlock_state = 0;
        }
    }
}

static void i6300esb_mem_writel(void *vp, hwaddr addr, uint32_t val)
{
    I6300State *d = vp;

    i6300esb_debug ("addr = %x, val = %x\n", (int) addr, val);

    if (addr == 0xc && val == 0x80)
        d->unlock_state = 1;
    else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
        d->unlock_state = 2;
    else {
        if (d->unlock_state == 2) {
            if (addr == 0)
                d->timer1_preload = val & 0xfffff;
            else if (addr == 4)
                d->timer2_preload = val & 0xfffff;

            d->unlock_state = 0;
        }
    }
}

static const MemoryRegionOps i6300esb_ops = {
    .old_mmio = {
        .read = {
            i6300esb_mem_readb,
            i6300esb_mem_readw,
            i6300esb_mem_readl,
        },
        .write = {
            i6300esb_mem_writeb,
            i6300esb_mem_writew,
            i6300esb_mem_writel,
        },
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static const VMStateDescription vmstate_i6300esb = {
    .name = "i6300esb_wdt",
    /* With this VMSD's introduction, version_id/minimum_version_id were
     * erroneously set to sizeof(I6300State), causing a somewhat random
     * version_id to be set for every build. This eventually broke
     * migration.
     *
     * To correct this without breaking old->new migration for older versions
     * of QEMU, we've set version_id to a value high enough to exceed all past
     * values of sizeof(I6300State) across various build environments, and have
     * reset minimum_version_id_old/minimum_version_id to 1, since this VMSD
     * has never changed and thus can accept all past versions.
     *
     * For future changes we can treat these values as we normally would.
     */
    .version_id = 10000,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField []) {
        VMSTATE_PCI_DEVICE(dev, I6300State),
        VMSTATE_INT32(reboot_enabled, I6300State),
        VMSTATE_INT32(clock_scale, I6300State),
        VMSTATE_INT32(int_type, I6300State),
        VMSTATE_INT32(free_run, I6300State),
        VMSTATE_INT32(locked, I6300State),
        VMSTATE_INT32(enabled, I6300State),
        VMSTATE_TIMER(timer, I6300State),
        VMSTATE_UINT32(timer1_preload, I6300State),
        VMSTATE_UINT32(timer2_preload, I6300State),
        VMSTATE_INT32(stage, I6300State),
        VMSTATE_INT32(unlock_state, I6300State),
        VMSTATE_INT32(previous_reboot_flag, I6300State),
        VMSTATE_END_OF_LIST()
    }
};

static int i6300esb_init(PCIDevice *dev)
{
    I6300State *d = DO_UPCAST(I6300State, dev, dev);

    i6300esb_debug("I6300State = %p\n", d);

    d->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, i6300esb_timer_expired, d);
    d->previous_reboot_flag = 0;

    memory_region_init_io(&d->io_mem, OBJECT(d), &i6300esb_ops, d,
                          "i6300esb", 0x10);
    pci_register_bar(&d->dev, 0, 0, &d->io_mem);
    /* qemu_register_coalesced_mmio (addr, 0x10); ? */

    return 0;
}

static void i6300esb_exit(PCIDevice *dev)
{
    I6300State *d = DO_UPCAST(I6300State, dev, dev);

    memory_region_destroy(&d->io_mem);
}

static WatchdogTimerModel model = {
    .wdt_name = "i6300esb",
    .wdt_description = "Intel 6300ESB",
};

static void i6300esb_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->config_read = i6300esb_config_read;
    k->config_write = i6300esb_config_write;
    k->init = i6300esb_init;
    k->exit = i6300esb_exit;
    k->vendor_id = PCI_VENDOR_ID_INTEL;
    k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
    k->class_id = PCI_CLASS_SYSTEM_OTHER;
    dc->reset = i6300esb_reset;
    dc->vmsd = &vmstate_i6300esb;
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}

static const TypeInfo i6300esb_info = {
    .name          = "i6300esb",
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(I6300State),
    .class_init    = i6300esb_class_init,
};

static void i6300esb_register_types(void)
{
    watchdog_add_model(&model);
    type_register_static(&i6300esb_info);
}

type_init(i6300esb_register_types)
