/*
 * QEMU ICH9 TCO emulation
 *
 * 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 "sysemu/watchdog.h"
#include "hw/i386/ich9.h"
#include "migration/vmstate.h"

#include "hw/acpi/tco.h"
#include "trace.h"

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,
};

static inline void tco_timer_reload(TCOIORegs *tr)
{
    int ticks = tr->tco.tmr & TCO_TMR_MASK;
    int64_t nsec = (int64_t)ticks * TCO_TICK_NSEC;

    trace_tco_timer_reload(ticks, nsec / 1000000);
    tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + nsec;
    timer_mod(tr->tco_timer, tr->expire_time);
}

static inline void tco_timer_stop(TCOIORegs *tr)
{
    tr->expire_time = -1;
    timer_del(tr->tco_timer);
}

static void tco_timer_expired(void *opaque)
{
    TCOIORegs *tr = opaque;
    ICH9LPCPMRegs *pm = container_of(tr, ICH9LPCPMRegs, tco_regs);
    ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm);
    uint32_t gcs = pci_get_long(lpc->chip_config + ICH9_CC_GCS);

    trace_tco_timer_expired(tr->timeouts_no,
                            lpc->pin_strap.spkr_hi,
                            !!(gcs & ICH9_CC_GCS_NO_REBOOT));
    tr->tco.rld = 0;
    tr->tco.sts1 |= TCO_TIMEOUT;
    if (++tr->timeouts_no == 2) {
        tr->tco.sts2 |= TCO_SECOND_TO_STS;
        tr->tco.sts2 |= TCO_BOOT_STS;
        tr->timeouts_no = 0;

        if (!lpc->pin_strap.spkr_hi && !(gcs & ICH9_CC_GCS_NO_REBOOT)) {
            watchdog_perform_action();
            tco_timer_stop(tr);
            return;
        }
    }

    if (pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN) {
        ich9_generate_smi();
    }
    tr->tco.rld = tr->tco.tmr;
    tco_timer_reload(tr);
}

/* NOTE: values of 0 or 1 will be ignored by ICH */
static inline int can_start_tco_timer(TCOIORegs *tr)
{
    return !(tr->tco.cnt1 & TCO_TMR_HLT) && tr->tco.tmr > 1;
}

static uint32_t tco_ioport_readw(TCOIORegs *tr, uint32_t addr)
{
    uint16_t rld;

    switch (addr) {
    case TCO_RLD:
        if (tr->expire_time != -1) {
            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
            int64_t elapsed = (tr->expire_time - now) / TCO_TICK_NSEC;
            rld = (uint16_t)elapsed | (tr->tco.rld & ~TCO_RLD_MASK);
        } else {
            rld = tr->tco.rld;
        }
        return rld;
    case TCO_DAT_IN:
        return tr->tco.din;
    case TCO_DAT_OUT:
        return tr->tco.dout;
    case TCO1_STS:
        return tr->tco.sts1;
    case TCO2_STS:
        return tr->tco.sts2;
    case TCO1_CNT:
        return tr->tco.cnt1;
    case TCO2_CNT:
        return tr->tco.cnt2;
    case TCO_MESSAGE1:
        return tr->tco.msg1;
    case TCO_MESSAGE2:
        return tr->tco.msg2;
    case TCO_WDCNT:
        return tr->tco.wdcnt;
    case TCO_TMR:
        return tr->tco.tmr;
    case SW_IRQ_GEN:
        return tr->sw_irq_gen;
    }
    return 0;
}

static void tco_ioport_writew(TCOIORegs *tr, uint32_t addr, uint32_t val)
{
    switch (addr) {
    case TCO_RLD:
        tr->timeouts_no = 0;
        if (can_start_tco_timer(tr)) {
            tr->tco.rld = tr->tco.tmr;
            tco_timer_reload(tr);
        } else {
            tr->tco.rld = val;
        }
        break;
    case TCO_DAT_IN:
        tr->tco.din = val;
        tr->tco.sts1 |= SW_TCO_SMI;
        ich9_generate_smi();
        break;
    case TCO_DAT_OUT:
        tr->tco.dout = val;
        tr->tco.sts1 |= TCO_INT_STS;
        /* TODO: cause an interrupt, as selected by the TCO_INT_SEL bits */
        break;
    case TCO1_STS:
        tr->tco.sts1 = val & TCO1_STS_MASK;
        break;
    case TCO2_STS:
        tr->tco.sts2 = val & TCO2_STS_MASK;
        break;
    case TCO1_CNT:
        val &= TCO1_CNT_MASK;
        /*
         * once TCO_LOCK bit is set, it can not be cleared by software. a reset
         * is required to change this bit from 1 to 0 -- it defaults to 0.
         */
        tr->tco.cnt1 = val | (tr->tco.cnt1 & TCO_LOCK);
        if (can_start_tco_timer(tr)) {
            tr->tco.rld = tr->tco.tmr;
            tco_timer_reload(tr);
        } else {
            tco_timer_stop(tr);
        }
        break;
    case TCO2_CNT:
        tr->tco.cnt2 = val;
        break;
    case TCO_MESSAGE1:
        tr->tco.msg1 = val;
        break;
    case TCO_MESSAGE2:
        tr->tco.msg2 = val;
        break;
    case TCO_WDCNT:
        tr->tco.wdcnt = val;
        break;
    case TCO_TMR:
        tr->tco.tmr = val;
        break;
    case SW_IRQ_GEN:
        tr->sw_irq_gen = val;
        break;
    }
}

static uint64_t tco_io_readw(void *opaque, hwaddr addr, unsigned width)
{
    TCOIORegs *tr = opaque;
    return tco_ioport_readw(tr, addr);
}

static void tco_io_writew(void *opaque, hwaddr addr, uint64_t val,
                          unsigned width)
{
    TCOIORegs *tr = opaque;
    tco_ioport_writew(tr, addr, val);
}

static const MemoryRegionOps tco_io_ops = {
    .read = tco_io_readw,
    .write = tco_io_writew,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .impl.min_access_size = 1,
    .impl.max_access_size = 2,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

void acpi_pm_tco_init(TCOIORegs *tr, MemoryRegion *parent)
{
    *tr = (TCOIORegs) {
        .tco = {
            .rld      = TCO_RLD_DEFAULT,
            .din      = TCO_DAT_IN_DEFAULT,
            .dout     = TCO_DAT_OUT_DEFAULT,
            .sts1     = TCO1_STS_DEFAULT,
            .sts2     = TCO2_STS_DEFAULT,
            .cnt1     = TCO1_CNT_DEFAULT,
            .cnt2     = TCO2_CNT_DEFAULT,
            .msg1     = TCO_MESSAGE1_DEFAULT,
            .msg2     = TCO_MESSAGE2_DEFAULT,
            .wdcnt    = TCO_WDCNT_DEFAULT,
            .tmr      = TCO_TMR_DEFAULT,
        },
        .sw_irq_gen    = SW_IRQ_GEN_DEFAULT,
        .tco_timer     = timer_new_ns(QEMU_CLOCK_VIRTUAL, tco_timer_expired, tr),
        .expire_time   = -1,
        .timeouts_no   = 0,
    };
    memory_region_init_io(&tr->io, memory_region_owner(parent),
                          &tco_io_ops, tr, "sm-tco", ICH9_PMIO_TCO_LEN);
    memory_region_add_subregion(parent, ICH9_PMIO_TCO_RLD, &tr->io);
}

const VMStateDescription vmstate_tco_io_sts = {
    .name = "tco io device status",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT16(tco.rld, TCOIORegs),
        VMSTATE_UINT8(tco.din, TCOIORegs),
        VMSTATE_UINT8(tco.dout, TCOIORegs),
        VMSTATE_UINT16(tco.sts1, TCOIORegs),
        VMSTATE_UINT16(tco.sts2, TCOIORegs),
        VMSTATE_UINT16(tco.cnt1, TCOIORegs),
        VMSTATE_UINT16(tco.cnt2, TCOIORegs),
        VMSTATE_UINT8(tco.msg1, TCOIORegs),
        VMSTATE_UINT8(tco.msg2, TCOIORegs),
        VMSTATE_UINT8(tco.wdcnt, TCOIORegs),
        VMSTATE_UINT16(tco.tmr, TCOIORegs),
        VMSTATE_UINT8(sw_irq_gen, TCOIORegs),
        VMSTATE_TIMER_PTR(tco_timer, TCOIORegs),
        VMSTATE_INT64(expire_time, TCOIORegs),
        VMSTATE_UINT8(timeouts_no, TCOIORegs),
        VMSTATE_END_OF_LIST()
    }
};
