/*
 * ARM CMSDK APB watchdog emulation
 *
 * Copyright (c) 2018 Linaro Limited
 * Written by Peter Maydell
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 or
 *  (at your option) any later version.
 */

/*
 * This is a model of the "APB watchdog" which is part of the Cortex-M
 * System Design Kit (CMSDK) and documented in the Cortex-M System
 * Design Kit Technical Reference Manual (ARM DDI0479):
 * https://developer.arm.com/documentation/ddi0479/
 *
 * We also support the variant of this device found in the TI
 * Stellaris/Luminary boards and documented in:
 * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "trace.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "sysemu/watchdog.h"
#include "hw/sysbus.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/registerfields.h"
#include "hw/qdev-clock.h"
#include "hw/watchdog/cmsdk-apb-watchdog.h"
#include "migration/vmstate.h"

REG32(WDOGLOAD, 0x0)
REG32(WDOGVALUE, 0x4)
REG32(WDOGCONTROL, 0x8)
    FIELD(WDOGCONTROL, INTEN, 0, 1)
    FIELD(WDOGCONTROL, RESEN, 1, 1)
#define R_WDOGCONTROL_VALID_MASK (R_WDOGCONTROL_INTEN_MASK | \
                                  R_WDOGCONTROL_RESEN_MASK)
REG32(WDOGINTCLR, 0xc)
REG32(WDOGRIS, 0x10)
    FIELD(WDOGRIS, INT, 0, 1)
REG32(WDOGMIS, 0x14)
REG32(WDOGTEST, 0x418) /* only in Stellaris/Luminary version of the device */
REG32(WDOGLOCK, 0xc00)
#define WDOG_UNLOCK_VALUE 0x1ACCE551
REG32(WDOGITCR, 0xf00)
    FIELD(WDOGITCR, ENABLE, 0, 1)
#define R_WDOGITCR_VALID_MASK R_WDOGITCR_ENABLE_MASK
REG32(WDOGITOP, 0xf04)
    FIELD(WDOGITOP, WDOGRES, 0, 1)
    FIELD(WDOGITOP, WDOGINT, 1, 1)
#define R_WDOGITOP_VALID_MASK (R_WDOGITOP_WDOGRES_MASK | \
                               R_WDOGITOP_WDOGINT_MASK)
REG32(PID4, 0xfd0)
REG32(PID5, 0xfd4)
REG32(PID6, 0xfd8)
REG32(PID7, 0xfdc)
REG32(PID0, 0xfe0)
REG32(PID1, 0xfe4)
REG32(PID2, 0xfe8)
REG32(PID3, 0xfec)
REG32(CID0, 0xff0)
REG32(CID1, 0xff4)
REG32(CID2, 0xff8)
REG32(CID3, 0xffc)

/* PID/CID values */
static const uint32_t cmsdk_apb_watchdog_id[] = {
    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

static const uint32_t luminary_watchdog_id[] = {
    0x00, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0x05, 0x18, 0x18, 0x01, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
{
    /* Return masked interrupt status */
    return s->intstatus && (s->control & R_WDOGCONTROL_INTEN_MASK);
}

static bool cmsdk_apb_watchdog_resetstatus(CMSDKAPBWatchdog *s)
{
    /* Return masked reset status */
    return s->resetstatus && (s->control & R_WDOGCONTROL_RESEN_MASK);
}

static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
{
    bool wdogint;
    bool wdogres;

    if (s->itcr) {
        /*
         * Not checking that !s->is_luminary since s->itcr can't be written
         * when s->is_luminary in the first place.
         */
        wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
        wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
    } else {
        wdogint = cmsdk_apb_watchdog_intstatus(s);
        wdogres = cmsdk_apb_watchdog_resetstatus(s);
    }

    qemu_set_irq(s->wdogint, wdogint);
    if (wdogres) {
        watchdog_perform_action();
    }
}

static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
                                        unsigned size)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
    uint64_t r;

    switch (offset) {
    case A_WDOGLOAD:
        r = ptimer_get_limit(s->timer);
        break;
    case A_WDOGVALUE:
        r = ptimer_get_count(s->timer);
        break;
    case A_WDOGCONTROL:
        r = s->control;
        break;
    case A_WDOGRIS:
        r = s->intstatus;
        break;
    case A_WDOGMIS:
        r = cmsdk_apb_watchdog_intstatus(s);
        break;
    case A_WDOGLOCK:
        r = s->lock;
        break;
    case A_WDOGITCR:
        if (s->is_luminary) {
            goto bad_offset;
        }
        r = s->itcr;
        break;
    case A_PID4 ... A_CID3:
        r = s->id[(offset - A_PID4) / 4];
        break;
    case A_WDOGINTCLR:
    case A_WDOGITOP:
        if (s->is_luminary) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB watchdog read: read of WO offset %x\n",
                      (int)offset);
        r = 0;
        break;
    case A_WDOGTEST:
        if (!s->is_luminary) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "Luminary watchdog read: stall not implemented\n");
        r = 0;
        break;
    default:
bad_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB watchdog read: bad offset %x\n", (int)offset);
        r = 0;
        break;
    }
    trace_cmsdk_apb_watchdog_read(offset, r, size);
    return r;
}

static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
                                     uint64_t value, unsigned size)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);

    trace_cmsdk_apb_watchdog_write(offset, value, size);

    if (s->lock && offset != A_WDOGLOCK) {
        /* Write access is disabled via WDOGLOCK */
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB watchdog write: write to locked watchdog\n");
        return;
    }

    switch (offset) {
    case A_WDOGLOAD:
        /* Reset the load value and the current count. */
        ptimer_transaction_begin(s->timer);
        ptimer_set_limit(s->timer, value, 1);
        ptimer_transaction_commit(s->timer);
        break;
    case A_WDOGCONTROL: {
        uint32_t prev_control = s->control;
        if (s->is_luminary && 0 != (R_WDOGCONTROL_INTEN_MASK & s->control)) {
            /*
             * The Luminary version of this device ignores writes to
             * this register after the guest has enabled interrupts
             * (so they can only be disabled again via reset).
             */
            break;
        }
        s->control = value & R_WDOGCONTROL_VALID_MASK;
        if (R_WDOGCONTROL_INTEN_MASK & (s->control ^ prev_control)) {
            ptimer_transaction_begin(s->timer);
            if (R_WDOGCONTROL_INTEN_MASK & s->control) {
                /*
                 * Set HIGH to enable the counter and the interrupt. Reloads
                 * the counter from the value in WDOGLOAD when the interrupt
                 * is enabled, after previously being disabled.
                 */
                ptimer_set_count(s->timer, ptimer_get_limit(s->timer));
                ptimer_run(s->timer, 0);
            } else {
                /* Or LOW to disable the counter and interrupt. */
                ptimer_stop(s->timer);
            }
            ptimer_transaction_commit(s->timer);
        }
        cmsdk_apb_watchdog_update(s);
        break;
    }
    case A_WDOGINTCLR:
        s->intstatus = 0;
        ptimer_transaction_begin(s->timer);
        ptimer_set_count(s->timer, ptimer_get_limit(s->timer));
        ptimer_transaction_commit(s->timer);
        cmsdk_apb_watchdog_update(s);
        break;
    case A_WDOGLOCK:
        s->lock = (value != WDOG_UNLOCK_VALUE);
        trace_cmsdk_apb_watchdog_lock(s->lock);
        break;
    case A_WDOGITCR:
        if (s->is_luminary) {
            goto bad_offset;
        }
        s->itcr = value & R_WDOGITCR_VALID_MASK;
        cmsdk_apb_watchdog_update(s);
        break;
    case A_WDOGITOP:
        if (s->is_luminary) {
            goto bad_offset;
        }
        s->itop = value & R_WDOGITOP_VALID_MASK;
        cmsdk_apb_watchdog_update(s);
        break;
    case A_WDOGVALUE:
    case A_WDOGRIS:
    case A_WDOGMIS:
    case A_PID4 ... A_CID3:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB watchdog write: write to RO offset 0x%x\n",
                      (int)offset);
        break;
    case A_WDOGTEST:
        if (!s->is_luminary) {
            goto bad_offset;
        }
        qemu_log_mask(LOG_UNIMP,
                      "Luminary watchdog write: stall not implemented\n");
        break;
    default:
bad_offset:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "CMSDK APB watchdog write: bad offset 0x%x\n",
                      (int)offset);
        break;
    }
}

static const MemoryRegionOps cmsdk_apb_watchdog_ops = {
    .read = cmsdk_apb_watchdog_read,
    .write = cmsdk_apb_watchdog_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    /* byte/halfword accesses are just zero-padded on reads and writes */
    .impl.min_access_size = 4,
    .impl.max_access_size = 4,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
};

static void cmsdk_apb_watchdog_tick(void *opaque)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);

    if (!s->intstatus) {
        /* Count expired for the first time: raise interrupt */
        s->intstatus = R_WDOGRIS_INT_MASK;
    } else {
        /* Count expired for the second time: raise reset and stop clock */
        s->resetstatus = 1;
        ptimer_stop(s->timer);
    }
    cmsdk_apb_watchdog_update(s);
}

static void cmsdk_apb_watchdog_reset(DeviceState *dev)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);

    trace_cmsdk_apb_watchdog_reset();
    s->control = 0;
    s->intstatus = 0;
    s->lock = 0;
    s->itcr = 0;
    s->itop = 0;
    s->resetstatus = 0;
    /* Set the limit and the count */
    ptimer_transaction_begin(s->timer);
    /*
     * We need to stop the ptimer before setting its limit reset value. If the
     * order is the opposite when the code executes the stop after setting a new
     * limit it may want to recalculate the count based on the current time (if
     * the timer was currently running) and it won't get the proper reset value.
     */
    ptimer_stop(s->timer);
    ptimer_set_limit(s->timer, 0xffffffff, 1);
    ptimer_transaction_commit(s->timer);
}

static void cmsdk_apb_watchdog_clk_update(void *opaque, ClockEvent event)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);

    ptimer_transaction_begin(s->timer);
    ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
    ptimer_transaction_commit(s->timer);
}

static void cmsdk_apb_watchdog_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);

    memory_region_init_io(&s->iomem, obj, &cmsdk_apb_watchdog_ops,
                          s, "cmsdk-apb-watchdog", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->wdogint);
    s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
                                    cmsdk_apb_watchdog_clk_update, s,
                                    ClockUpdate);

    s->is_luminary = false;
    s->id = cmsdk_apb_watchdog_id;
}

static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);

    if (!clock_has_source(s->wdogclk)) {
        error_setg(errp,
                   "CMSDK APB watchdog: WDOGCLK clock must be connected");
        return;
    }

    s->timer = ptimer_init(cmsdk_apb_watchdog_tick, s,
                           PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
                           PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
                           PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
                           PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);

    ptimer_transaction_begin(s->timer);
    ptimer_set_period_from_clock(s->timer, s->wdogclk, 1);
    ptimer_transaction_commit(s->timer);
}

static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
    .name = "cmsdk-apb-watchdog",
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (const VMStateField[]) {
        VMSTATE_CLOCK(wdogclk, CMSDKAPBWatchdog),
        VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
        VMSTATE_UINT32(control, CMSDKAPBWatchdog),
        VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
        VMSTATE_UINT32(lock, CMSDKAPBWatchdog),
        VMSTATE_UINT32(itcr, CMSDKAPBWatchdog),
        VMSTATE_UINT32(itop, CMSDKAPBWatchdog),
        VMSTATE_UINT32(resetstatus, CMSDKAPBWatchdog),
        VMSTATE_END_OF_LIST()
    }
};

static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = cmsdk_apb_watchdog_realize;
    dc->vmsd = &cmsdk_apb_watchdog_vmstate;
    device_class_set_legacy_reset(dc, cmsdk_apb_watchdog_reset);
}

static const TypeInfo cmsdk_apb_watchdog_info = {
    .name = TYPE_CMSDK_APB_WATCHDOG,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(CMSDKAPBWatchdog),
    .instance_init = cmsdk_apb_watchdog_init,
    .class_init = cmsdk_apb_watchdog_class_init,
};

static void luminary_watchdog_init(Object *obj)
{
    CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);

    s->is_luminary = true;
    s->id = luminary_watchdog_id;
}

static const TypeInfo luminary_watchdog_info = {
    .name = TYPE_LUMINARY_WATCHDOG,
    .parent = TYPE_CMSDK_APB_WATCHDOG,
    .instance_init = luminary_watchdog_init
};

static void cmsdk_apb_watchdog_register_types(void)
{
    type_register_static(&cmsdk_apb_watchdog_info);
    type_register_static(&luminary_watchdog_info);
}

type_init(cmsdk_apb_watchdog_register_types);
