/*
 * Arm SSE Subsystem System Counter
 *
 * Copyright (c) 2020 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 "System counter" which is documented in
 * the Arm SSE-123 Example Subsystem Technical Reference Manual:
 * https://developer.arm.com/documentation/101370/latest/
 *
 * The system counter is a non-stop 64-bit up-counter. It provides
 * this count value to other devices like the SSE system timer,
 * which are driven by this system timestamp rather than directly
 * from a clock. Internally to the counter the count is actually
 * 88-bit precision (64.24 fixed point), with a programmable scale factor.
 *
 * The hardware has the optional feature that it supports dynamic
 * clock switching, where two clock inputs are connected, and which
 * one is used is selected via a CLKSEL input signal. Since the
 * users of this device in QEMU don't use this feature, we only model
 * the HWCLKSW=0 configuration.
 */
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/timer.h"
#include "qapi/error.h"
#include "trace.h"
#include "hw/timer/sse-counter.h"
#include "hw/sysbus.h"
#include "hw/registerfields.h"
#include "hw/clock.h"
#include "hw/qdev-clock.h"
#include "migration/vmstate.h"

/* Registers in the control frame */
REG32(CNTCR, 0x0)
    FIELD(CNTCR, EN, 0, 1)
    FIELD(CNTCR, HDBG, 1, 1)
    FIELD(CNTCR, SCEN, 2, 1)
    FIELD(CNTCR, INTRMASK, 3, 1)
    FIELD(CNTCR, PSLVERRDIS, 4, 1)
    FIELD(CNTCR, INTRCLR, 5, 1)
/*
 * Although CNTCR defines interrupt-related bits, the counter doesn't
 * appear to actually have an interrupt output. So INTRCLR is
 * effectively a RAZ/WI bit, as are the reserved bits [31:6].
 */
#define CNTCR_VALID_MASK (R_CNTCR_EN_MASK | R_CNTCR_HDBG_MASK | \
                          R_CNTCR_SCEN_MASK | R_CNTCR_INTRMASK_MASK | \
                          R_CNTCR_PSLVERRDIS_MASK)
REG32(CNTSR, 0x4)
REG32(CNTCV_LO, 0x8)
REG32(CNTCV_HI, 0xc)
REG32(CNTSCR, 0x10) /* Aliased with CNTSCR0 */
REG32(CNTID, 0x1c)
    FIELD(CNTID, CNTSC, 0, 4)
    FIELD(CNTID, CNTCS, 16, 1)
    FIELD(CNTID, CNTSELCLK, 17, 2)
    FIELD(CNTID, CNTSCR_OVR, 19, 1)
REG32(CNTSCR0, 0xd0)
REG32(CNTSCR1, 0xd4)

/* Registers in the status frame */
REG32(STATUS_CNTCV_LO, 0x0)
REG32(STATUS_CNTCV_HI, 0x4)

/* Standard ID registers, present in both frames */
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 int control_id[] = {
    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0xba, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

static const int status_id[] = {
    0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
    0xbb, 0xb0, 0x0b, 0x00, /* PID0..PID3 */
    0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
};

static void sse_counter_notify_users(SSECounter *s)
{
    /*
     * Notify users of the count timestamp that they may
     * need to recalculate.
     */
    notifier_list_notify(&s->notifier_list, NULL);
}

static bool sse_counter_enabled(SSECounter *s)
{
    return (s->cntcr & R_CNTCR_EN_MASK) != 0;
}

uint64_t sse_counter_tick_to_time(SSECounter *s, uint64_t tick)
{
    if (!sse_counter_enabled(s)) {
        return UINT64_MAX;
    }

    tick -= s->ticks_then;

    if (s->cntcr & R_CNTCR_SCEN_MASK) {
        /* Adjust the tick count to account for the scale factor */
        tick = muldiv64(tick, 0x01000000, s->cntscr0);
    }

    return s->ns_then + clock_ticks_to_ns(s->clk, tick);
}

void sse_counter_register_consumer(SSECounter *s, Notifier *notifier)
{
    /*
     * For the moment we assume that both we and the devices
     * which consume us last for the life of the simulation,
     * and so there is no mechanism for removing a notifier.
     */
    notifier_list_add(&s->notifier_list, notifier);
}

uint64_t sse_counter_for_timestamp(SSECounter *s, uint64_t now)
{
    /* Return the CNTCV value for a particular timestamp (clock ns value). */
    uint64_t ticks;

    if (!sse_counter_enabled(s)) {
        /* Counter is disabled and does not increment */
        return s->ticks_then;
    }

    ticks = clock_ns_to_ticks(s->clk, now - s->ns_then);
    if (s->cntcr & R_CNTCR_SCEN_MASK) {
        /*
         * Scaling is enabled. The CNTSCR value is the amount added to
         * the underlying 88-bit counter for every tick of the
         * underlying clock; CNTCV is the top 64 bits of that full
         * 88-bit value. Multiplying the tick count by CNTSCR tells us
         * how much the full 88-bit counter has moved on; we then
         * divide that by 0x01000000 to find out how much the 64-bit
         * visible portion has advanced. muldiv64() gives us the
         * necessary at-least-88-bit precision for the intermediate
         * result.
         */
        ticks = muldiv64(ticks, s->cntscr0, 0x01000000);
    }
    return s->ticks_then + ticks;
}

static uint64_t sse_cntcv(SSECounter *s)
{
    /* Return the CNTCV value for the current time */
    return sse_counter_for_timestamp(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
}

static void sse_write_cntcv(SSECounter *s, uint32_t value, unsigned startbit)
{
    /*
     * Write one 32-bit half of the counter value; startbit is the
     * bit position of this half in the 64-bit word, either 0 or 32.
     */
    uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    uint64_t cntcv = sse_counter_for_timestamp(s, now);

    cntcv = deposit64(cntcv, startbit, 32, value);
    s->ticks_then = cntcv;
    s->ns_then = now;
    sse_counter_notify_users(s);
}

static uint64_t sse_counter_control_read(void *opaque, hwaddr offset,
                                         unsigned size)
{
    SSECounter *s = SSE_COUNTER(opaque);
    uint64_t r;

    switch (offset) {
    case A_CNTCR:
        r = s->cntcr;
        break;
    case A_CNTSR:
        /*
         * The only bit here is DBGH, indicating that the counter has been
         * halted via the Halt-on-Debug signal. We don't implement halting
         * debug, so the whole register always reads as zero.
         */
        r = 0;
        break;
    case A_CNTCV_LO:
        r = extract64(sse_cntcv(s), 0, 32);
        break;
    case A_CNTCV_HI:
        r = extract64(sse_cntcv(s), 32, 32);
        break;
    case A_CNTID:
        /*
         * For our implementation:
         *  - CNTSCR can only be written when CNTCR.EN == 0
         *  - HWCLKSW=0, so selected clock is always CLK0
         *  - counter scaling is implemented
         */
        r = (1 << R_CNTID_CNTSELCLK_SHIFT) | (1 << R_CNTID_CNTSC_SHIFT);
        break;
    case A_CNTSCR:
    case A_CNTSCR0:
        r = s->cntscr0;
        break;
    case A_CNTSCR1:
        /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
        r = 0;
        break;
    case A_PID4 ... A_CID3:
        r = control_id[(offset - A_PID4) / 4];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE System Counter control frame read: bad offset 0x%x",
                      (unsigned)offset);
        r = 0;
        break;
    }

    trace_sse_counter_control_read(offset, r, size);
    return r;
}

static void sse_counter_control_write(void *opaque, hwaddr offset,
                                      uint64_t value, unsigned size)
{
    SSECounter *s = SSE_COUNTER(opaque);

    trace_sse_counter_control_write(offset, value, size);

    switch (offset) {
    case A_CNTCR:
        /*
         * Although CNTCR defines interrupt-related bits, the counter doesn't
         * appear to actually have an interrupt output. So INTRCLR is
         * effectively a RAZ/WI bit, as are the reserved bits [31:6].
         * The documentation does not explicitly say so, but we assume
         * that changing the scale factor while the counter is enabled
         * by toggling CNTCR.SCEN has the same behaviour (making the counter
         * value UNKNOWN) as changing it by writing to CNTSCR, and so we
         * don't need to try to recalculate for that case.
         */
        value &= CNTCR_VALID_MASK;
        if ((value ^ s->cntcr) & R_CNTCR_EN_MASK) {
            /*
             * Whether the counter is being enabled or disabled, the
             * required action is the same: sync the (ns_then, ticks_then)
             * tuple.
             */
            uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
            s->ticks_then = sse_counter_for_timestamp(s, now);
            s->ns_then = now;
            sse_counter_notify_users(s);
        }
        s->cntcr = value;
        break;
    case A_CNTCV_LO:
        sse_write_cntcv(s, value, 0);
        break;
    case A_CNTCV_HI:
        sse_write_cntcv(s, value, 32);
        break;
    case A_CNTSCR:
    case A_CNTSCR0:
        /*
         * If the scale registers are changed when the counter is enabled,
         * the count value becomes UNKNOWN. So we don't try to recalculate
         * anything here but only do it on a write to CNTCR.EN.
         */
        s->cntscr0 = value;
        break;
    case A_CNTSCR1:
        /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */
        break;
    case A_CNTSR:
    case A_CNTID:
    case A_PID4 ... A_CID3:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE System Counter control frame: write to RO offset 0x%x\n",
                      (unsigned)offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE System Counter control frame: write to bad offset 0x%x\n",
                      (unsigned)offset);
        break;
    }
}

static uint64_t sse_counter_status_read(void *opaque, hwaddr offset,
                                        unsigned size)
{
    SSECounter *s = SSE_COUNTER(opaque);
    uint64_t r;

    switch (offset) {
    case A_STATUS_CNTCV_LO:
        r = extract64(sse_cntcv(s), 0, 32);
        break;
    case A_STATUS_CNTCV_HI:
        r = extract64(sse_cntcv(s), 32, 32);
        break;
    case A_PID4 ... A_CID3:
        r = status_id[(offset - A_PID4) / 4];
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE System Counter status frame read: bad offset 0x%x",
                      (unsigned)offset);
        r = 0;
        break;
    }

    trace_sse_counter_status_read(offset, r, size);
    return r;
}

static void sse_counter_status_write(void *opaque, hwaddr offset,
                                     uint64_t value, unsigned size)
{
    trace_sse_counter_status_write(offset, value, size);

    switch (offset) {
    case A_STATUS_CNTCV_LO:
    case A_STATUS_CNTCV_HI:
    case A_PID4 ... A_CID3:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE System Counter status frame: write to RO offset 0x%x\n",
                      (unsigned)offset);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "SSE System Counter status frame: write to bad offset 0x%x\n",
                      (unsigned)offset);
        break;
    }
}

static const MemoryRegionOps sse_counter_control_ops = {
    .read = sse_counter_control_read,
    .write = sse_counter_control_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
};

static const MemoryRegionOps sse_counter_status_ops = {
    .read = sse_counter_status_read,
    .write = sse_counter_status_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
};

static void sse_counter_reset(DeviceState *dev)
{
    SSECounter *s = SSE_COUNTER(dev);

    trace_sse_counter_reset();

    s->cntcr = 0;
    s->cntscr0 = 0x01000000;
    s->ns_then = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    s->ticks_then = 0;
}

static void sse_clk_callback(void *opaque, ClockEvent event)
{
    SSECounter *s = SSE_COUNTER(opaque);
    uint64_t now;

    switch (event) {
    case ClockPreUpdate:
        /*
         * Before the clock period updates, set (ticks_then, ns_then)
         * to the current time and tick count (as calculated with
         * the old clock period).
         */
        if (sse_counter_enabled(s)) {
            now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
            s->ticks_then = sse_counter_for_timestamp(s, now);
            s->ns_then = now;
        }
        break;
    case ClockUpdate:
        sse_counter_notify_users(s);
        break;
    default:
        break;
    }
}

static void sse_counter_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    SSECounter *s = SSE_COUNTER(obj);

    notifier_list_init(&s->notifier_list);

    s->clk = qdev_init_clock_in(DEVICE(obj), "CLK", sse_clk_callback, s,
                                ClockPreUpdate | ClockUpdate);
    memory_region_init_io(&s->control_mr, obj, &sse_counter_control_ops,
                          s, "sse-counter-control", 0x1000);
    memory_region_init_io(&s->status_mr, obj, &sse_counter_status_ops,
                          s, "sse-counter-status", 0x1000);
    sysbus_init_mmio(sbd, &s->control_mr);
    sysbus_init_mmio(sbd, &s->status_mr);
}

static void sse_counter_realize(DeviceState *dev, Error **errp)
{
    SSECounter *s = SSE_COUNTER(dev);

    if (!clock_has_source(s->clk)) {
        error_setg(errp, "SSE system counter: CLK must be connected");
        return;
    }
}

static const VMStateDescription sse_counter_vmstate = {
    .name = "sse-counter",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_CLOCK(clk, SSECounter),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->realize = sse_counter_realize;
    dc->vmsd = &sse_counter_vmstate;
    dc->reset = sse_counter_reset;
}

static const TypeInfo sse_counter_info = {
    .name = TYPE_SSE_COUNTER,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SSECounter),
    .instance_init = sse_counter_init,
    .class_init = sse_counter_class_init,
};

static void sse_counter_register_types(void)
{
    type_register_static(&sse_counter_info);
}

type_init(sse_counter_register_types);
