/*
 * RISC-V ACLINT (Advanced Core Local Interruptor)
 * URL: https://github.com/riscv/riscv-aclint
 *
 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
 * Copyright (c) 2017 SiFive, Inc.
 * Copyright (c) 2021 Western Digital Corporation or its affiliates.
 *
 * This provides real-time clock, timer and interprocessor interrupts.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "hw/sysbus.h"
#include "target/riscv/cpu.h"
#include "hw/qdev-properties.h"
#include "hw/intc/riscv_aclint.h"
#include "qemu/timer.h"
#include "hw/irq.h"
#include "migration/vmstate.h"

typedef struct riscv_aclint_mtimer_callback {
    RISCVAclintMTimerState *s;
    int num;
} riscv_aclint_mtimer_callback;

static uint64_t cpu_riscv_read_rtc_raw(uint32_t timebase_freq)
{
    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
        timebase_freq, NANOSECONDS_PER_SECOND);
}

static uint64_t cpu_riscv_read_rtc(void *opaque)
{
    RISCVAclintMTimerState *mtimer = opaque;
    return cpu_riscv_read_rtc_raw(mtimer->timebase_freq) + mtimer->time_delta;
}

/*
 * Called when timecmp is written to update the QEMU timer or immediately
 * trigger timer interrupt if mtimecmp <= current timer value.
 */
static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
                                              RISCVCPU *cpu,
                                              int hartid,
                                              uint64_t value)
{
    uint32_t timebase_freq = mtimer->timebase_freq;
    uint64_t next;
    uint64_t diff;

    uint64_t rtc = cpu_riscv_read_rtc(mtimer);

    /* Compute the relative hartid w.r.t the socket */
    hartid = hartid - mtimer->hartid_base;

    mtimer->timecmp[hartid] = value;
    if (mtimer->timecmp[hartid] <= rtc) {
        /*
         * If we're setting an MTIMECMP value in the "past",
         * immediately raise the timer interrupt
         */
        qemu_irq_raise(mtimer->timer_irqs[hartid]);
        return;
    }

    /* otherwise, set up the future timer interrupt */
    qemu_irq_lower(mtimer->timer_irqs[hartid]);
    diff = mtimer->timecmp[hartid] - rtc;
    /* back to ns (note args switched in muldiv64) */
    uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);

    /*
     * check if ns_diff overflowed and check if the addition would potentially
     * overflow
     */
    if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) ||
        ns_diff > INT64_MAX) {
        next = INT64_MAX;
    } else {
        /*
         * as it is very unlikely qemu_clock_get_ns will return a value
         * greater than INT64_MAX, no additional check is needed for an
         * unsigned integer overflow.
         */
        next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff;
        /*
         * if ns_diff is INT64_MAX next may still be outside the range
         * of a signed integer.
         */
        next = MIN(next, INT64_MAX);
    }

    timer_mod(mtimer->timers[hartid], next);
}

/*
 * Callback used when the timer set using timer_mod expires.
 * Should raise the timer interrupt line
 */
static void riscv_aclint_mtimer_cb(void *opaque)
{
    riscv_aclint_mtimer_callback *state = opaque;

    qemu_irq_raise(state->s->timer_irqs[state->num]);
}

/* CPU read MTIMER register */
static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr,
    unsigned size)
{
    RISCVAclintMTimerState *mtimer = opaque;

    if (addr >= mtimer->timecmp_base &&
        addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
        size_t hartid = mtimer->hartid_base +
                        ((addr - mtimer->timecmp_base) >> 3);
        CPUState *cpu = cpu_by_arch_id(hartid);
        CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
        if (!env) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "aclint-mtimer: invalid hartid: %zu", hartid);
        } else if ((addr & 0x7) == 0) {
            /* timecmp_lo for RV32/RV64 or timecmp for RV64 */
            uint64_t timecmp = mtimer->timecmp[hartid];
            return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp;
        } else if ((addr & 0x7) == 4) {
            /* timecmp_hi */
            uint64_t timecmp = mtimer->timecmp[hartid];
            return (timecmp >> 32) & 0xFFFFFFFF;
        } else {
            qemu_log_mask(LOG_UNIMP,
                          "aclint-mtimer: invalid read: %08x", (uint32_t)addr);
            return 0;
        }
    } else if (addr == mtimer->time_base) {
        /* time_lo for RV32/RV64 or timecmp for RV64 */
        uint64_t rtc = cpu_riscv_read_rtc(mtimer);
        return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc;
    } else if (addr == mtimer->time_base + 4) {
        /* time_hi */
        return (cpu_riscv_read_rtc(mtimer) >> 32) & 0xFFFFFFFF;
    }

    qemu_log_mask(LOG_UNIMP,
                  "aclint-mtimer: invalid read: %08x", (uint32_t)addr);
    return 0;
}

/* CPU write MTIMER register */
static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
    uint64_t value, unsigned size)
{
    RISCVAclintMTimerState *mtimer = opaque;
    int i;

    if (addr >= mtimer->timecmp_base &&
        addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) {
        size_t hartid = mtimer->hartid_base +
                        ((addr - mtimer->timecmp_base) >> 3);
        CPUState *cpu = cpu_by_arch_id(hartid);
        CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
        if (!env) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "aclint-mtimer: invalid hartid: %zu", hartid);
        } else if ((addr & 0x7) == 0) {
            if (size == 4) {
                /* timecmp_lo for RV32/RV64 */
                uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32;
                riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
                    timecmp_hi << 32 | (value & 0xFFFFFFFF));
            } else {
                /* timecmp for RV64 */
                riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
                                                  value);
            }
        } else if ((addr & 0x7) == 4) {
            if (size == 4) {
                /* timecmp_hi for RV32/RV64 */
                uint64_t timecmp_lo = mtimer->timecmp[hartid];
                riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid,
                    value << 32 | (timecmp_lo & 0xFFFFFFFF));
            } else {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "aclint-mtimer: invalid timecmp_hi write: %08x",
                              (uint32_t)addr);
            }
        } else {
            qemu_log_mask(LOG_UNIMP,
                          "aclint-mtimer: invalid timecmp write: %08x",
                          (uint32_t)addr);
        }
        return;
    } else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
        uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
        uint64_t rtc = cpu_riscv_read_rtc(mtimer);

        if (addr == mtimer->time_base) {
            if (size == 4) {
                /* time_lo for RV32/RV64 */
                mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
            } else {
                /* time for RV64 */
                mtimer->time_delta = value - rtc_r;
            }
        } else {
            if (size == 4) {
                /* time_hi for RV32/RV64 */
                mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
            } else {
                qemu_log_mask(LOG_GUEST_ERROR,
                              "aclint-mtimer: invalid time_hi write: %08x",
                              (uint32_t)addr);
                return;
            }
        }

        /* Check if timer interrupt is triggered for each hart. */
        for (i = 0; i < mtimer->num_harts; i++) {
            CPUState *cpu = cpu_by_arch_id(mtimer->hartid_base + i);
            CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
            if (!env) {
                continue;
            }
            riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu),
                                              mtimer->hartid_base + i,
                                              mtimer->timecmp[i]);
        }
        return;
    }

    qemu_log_mask(LOG_UNIMP,
                  "aclint-mtimer: invalid write: %08x", (uint32_t)addr);
}

static const MemoryRegionOps riscv_aclint_mtimer_ops = {
    .read = riscv_aclint_mtimer_read,
    .write = riscv_aclint_mtimer_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 8,
    }
};

static const Property riscv_aclint_mtimer_properties[] = {
    DEFINE_PROP_UINT32("hartid-base", RISCVAclintMTimerState,
        hartid_base, 0),
    DEFINE_PROP_UINT32("num-harts", RISCVAclintMTimerState, num_harts, 1),
    DEFINE_PROP_UINT32("timecmp-base", RISCVAclintMTimerState,
        timecmp_base, RISCV_ACLINT_DEFAULT_MTIMECMP),
    DEFINE_PROP_UINT32("time-base", RISCVAclintMTimerState,
        time_base, RISCV_ACLINT_DEFAULT_MTIME),
    DEFINE_PROP_UINT32("aperture-size", RISCVAclintMTimerState,
        aperture_size, RISCV_ACLINT_DEFAULT_MTIMER_SIZE),
    DEFINE_PROP_UINT32("timebase-freq", RISCVAclintMTimerState,
        timebase_freq, 0),
};

static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp)
{
    RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev);
    int i;

    memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_aclint_mtimer_ops,
                          s, TYPE_RISCV_ACLINT_MTIMER, s->aperture_size);
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);

    s->timer_irqs = g_new(qemu_irq, s->num_harts);
    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);

    s->timers = g_new0(QEMUTimer *, s->num_harts);
    s->timecmp = g_new0(uint64_t, s->num_harts);
    /* Claim timer interrupt bits */
    for (i = 0; i < s->num_harts; i++) {
        RISCVCPU *cpu = RISCV_CPU(cpu_by_arch_id(s->hartid_base + i));
        if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) {
            error_report("MTIP already claimed");
            exit(1);
        }
    }
}

static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type)
{
    /*
     * According to RISC-V ACLINT spec:
     *   - On MTIMER device reset, the MTIME register is cleared to zero.
     *   - On MTIMER device reset, the MTIMECMP registers are in unknown state.
     */
    RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj);

    /*
     * Clear mtime register by writing to 0 it.
     * Pending mtime interrupts will also be cleared at the same time.
     */
    riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8);
}

static const VMStateDescription vmstate_riscv_mtimer = {
    .name = "riscv_mtimer",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
            VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState,
                                  num_harts, 0,
                                  vmstate_info_uint64, uint64_t),
            VMSTATE_END_OF_LIST()
        }
};

static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    dc->realize = riscv_aclint_mtimer_realize;
    device_class_set_props(dc, riscv_aclint_mtimer_properties);
    ResettableClass *rc = RESETTABLE_CLASS(klass);
    rc->phases.enter = riscv_aclint_mtimer_reset_enter;
    dc->vmsd = &vmstate_riscv_mtimer;
}

static const TypeInfo riscv_aclint_mtimer_info = {
    .name          = TYPE_RISCV_ACLINT_MTIMER,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(RISCVAclintMTimerState),
    .class_init    = riscv_aclint_mtimer_class_init,
};

/*
 * Create ACLINT MTIMER device.
 */
DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size,
    uint32_t hartid_base, uint32_t num_harts,
    uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq,
    bool provide_rdtime)
{
    int i;
    DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER);
    RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev);

    assert(num_harts <= RISCV_ACLINT_MAX_HARTS);
    assert(!(addr & 0x7));
    assert(!(timecmp_base & 0x7));
    assert(!(time_base & 0x7));

    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
    qdev_prop_set_uint32(dev, "num-harts", num_harts);
    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
    qdev_prop_set_uint32(dev, "time-base", time_base);
    qdev_prop_set_uint32(dev, "aperture-size", size);
    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);

    for (i = 0; i < num_harts; i++) {
        CPUState *cpu = cpu_by_arch_id(hartid_base + i);
        RISCVCPU *rvcpu = RISCV_CPU(cpu);
        CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
        riscv_aclint_mtimer_callback *cb =
            g_new0(riscv_aclint_mtimer_callback, 1);

        if (!env) {
            g_free(cb);
            continue;
        }
        if (provide_rdtime) {
            riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev);
        }

        cb->s = s;
        cb->num = i;
        s->timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                  &riscv_aclint_mtimer_cb, cb);
        s->timecmp[i] = 0;

        qdev_connect_gpio_out(dev, i,
                              qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
    }

    return dev;
}

/* CPU read [M|S]SWI register */
static uint64_t riscv_aclint_swi_read(void *opaque, hwaddr addr,
    unsigned size)
{
    RISCVAclintSwiState *swi = opaque;

    if (addr < (swi->num_harts << 2)) {
        size_t hartid = swi->hartid_base + (addr >> 2);
        CPUState *cpu = cpu_by_arch_id(hartid);
        CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
        if (!env) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "aclint-swi: invalid hartid: %zu", hartid);
        } else if ((addr & 0x3) == 0) {
            return (swi->sswi) ? 0 : ((env->mip & MIP_MSIP) > 0);
        }
    }

    qemu_log_mask(LOG_UNIMP,
                  "aclint-swi: invalid read: %08x", (uint32_t)addr);
    return 0;
}

/* CPU write [M|S]SWI register */
static void riscv_aclint_swi_write(void *opaque, hwaddr addr, uint64_t value,
        unsigned size)
{
    RISCVAclintSwiState *swi = opaque;

    if (addr < (swi->num_harts << 2)) {
        size_t hartid = swi->hartid_base + (addr >> 2);
        CPUState *cpu = cpu_by_arch_id(hartid);
        CPURISCVState *env = cpu ? cpu_env(cpu) : NULL;
        if (!env) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "aclint-swi: invalid hartid: %zu", hartid);
        } else if ((addr & 0x3) == 0) {
            if (value & 0x1) {
                qemu_irq_raise(swi->soft_irqs[hartid - swi->hartid_base]);
            } else {
                if (!swi->sswi) {
                    qemu_irq_lower(swi->soft_irqs[hartid - swi->hartid_base]);
                }
            }
            return;
        }
    }

    qemu_log_mask(LOG_UNIMP,
                  "aclint-swi: invalid write: %08x", (uint32_t)addr);
}

static const MemoryRegionOps riscv_aclint_swi_ops = {
    .read = riscv_aclint_swi_read,
    .write = riscv_aclint_swi_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4
    }
};

static const Property riscv_aclint_swi_properties[] = {
    DEFINE_PROP_UINT32("hartid-base", RISCVAclintSwiState, hartid_base, 0),
    DEFINE_PROP_UINT32("num-harts", RISCVAclintSwiState, num_harts, 1),
    DEFINE_PROP_UINT32("sswi", RISCVAclintSwiState, sswi, false),
};

static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp)
{
    RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(dev);
    int i;

    memory_region_init_io(&swi->mmio, OBJECT(dev), &riscv_aclint_swi_ops, swi,
                          TYPE_RISCV_ACLINT_SWI, RISCV_ACLINT_SWI_SIZE);
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &swi->mmio);

    swi->soft_irqs = g_new(qemu_irq, swi->num_harts);
    qdev_init_gpio_out(dev, swi->soft_irqs, swi->num_harts);

    /* Claim software interrupt bits */
    for (i = 0; i < swi->num_harts; i++) {
        RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i));
        /* We don't claim mip.SSIP because it is writable by software */
        if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) {
            error_report("MSIP already claimed");
            exit(1);
        }
    }
}

static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type)
{
    /*
     * According to RISC-V ACLINT spec:
     *   - On MSWI device reset, each MSIP register is cleared to zero.
     *
     * p.s. SSWI device reset does nothing since SETSIP register always reads 0.
     */
    RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj);
    int i;

    if (!swi->sswi) {
        for (i = 0; i < swi->num_harts; i++) {
            /* Clear MSIP registers by lowering software interrupts. */
            qemu_irq_lower(swi->soft_irqs[i]);
        }
    }
}

static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    dc->realize = riscv_aclint_swi_realize;
    device_class_set_props(dc, riscv_aclint_swi_properties);
    ResettableClass *rc = RESETTABLE_CLASS(klass);
    rc->phases.enter = riscv_aclint_swi_reset_enter;
}

static const TypeInfo riscv_aclint_swi_info = {
    .name          = TYPE_RISCV_ACLINT_SWI,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(RISCVAclintSwiState),
    .class_init    = riscv_aclint_swi_class_init,
};

/*
 * Create ACLINT [M|S]SWI device.
 */
DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base,
    uint32_t num_harts, bool sswi)
{
    int i;
    DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_SWI);

    assert(num_harts <= RISCV_ACLINT_MAX_HARTS);
    assert(!(addr & 0x3));

    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
    qdev_prop_set_uint32(dev, "num-harts", num_harts);
    qdev_prop_set_uint32(dev, "sswi", sswi ? true : false);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);

    for (i = 0; i < num_harts; i++) {
        CPUState *cpu = cpu_by_arch_id(hartid_base + i);
        RISCVCPU *rvcpu = RISCV_CPU(cpu);

        qdev_connect_gpio_out(dev, i,
                              qdev_get_gpio_in(DEVICE(rvcpu),
                                  (sswi) ? IRQ_S_SOFT : IRQ_M_SOFT));
    }

    return dev;
}

static void riscv_aclint_register_types(void)
{
    type_register_static(&riscv_aclint_mtimer_info);
    type_register_static(&riscv_aclint_swi_info);
}

type_init(riscv_aclint_register_types)
