/*
 * ARM Generic Interrupt Controller v3
 *
 * Copyright (c) 2015 Huawei.
 * Copyright (c) 2016 Linaro Limited
 * Written by Shlomo Pongratz, Peter Maydell
 *
 * This code is licensed under the GPL, version 2 or (at your option)
 * any later version.
 */

/* This file contains implementation code for an interrupt controller
 * which implements the GICv3 architecture. Specifically this is where
 * the device class itself and the functions for handling interrupts
 * coming in and going out live.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "hw/intc/arm_gicv3.h"
#include "gicv3_internal.h"

static bool irqbetter(GICv3CPUState *cs, int irq, uint8_t prio)
{
    /* Return true if this IRQ at this priority should take
     * precedence over the current recorded highest priority
     * pending interrupt for this CPU. We also return true if
     * the current recorded highest priority pending interrupt
     * is the same as this one (a property which the calling code
     * relies on).
     */
    if (prio < cs->hppi.prio) {
        return true;
    }
    /* If multiple pending interrupts have the same priority then it is an
     * IMPDEF choice which of them to signal to the CPU. We choose to
     * signal the one with the lowest interrupt number.
     */
    if (prio == cs->hppi.prio && irq <= cs->hppi.irq) {
        return true;
    }
    return false;
}

static uint32_t gicd_int_pending(GICv3State *s, int irq)
{
    /* Recalculate which distributor interrupts are actually pending
     * in the group of 32 interrupts starting at irq (which should be a multiple
     * of 32), and return a 32-bit integer which has a bit set for each
     * interrupt that is eligible to be signaled to the CPU interface.
     *
     * An interrupt is pending if:
     *  + the PENDING latch is set OR it is level triggered and the input is 1
     *  + its ENABLE bit is set
     *  + the GICD enable bit for its group is set
     * Conveniently we can bulk-calculate this with bitwise operations.
     */
    uint32_t pend, grpmask;
    uint32_t pending = *gic_bmp_ptr32(s->pending, irq);
    uint32_t edge_trigger = *gic_bmp_ptr32(s->edge_trigger, irq);
    uint32_t level = *gic_bmp_ptr32(s->level, irq);
    uint32_t group = *gic_bmp_ptr32(s->group, irq);
    uint32_t grpmod = *gic_bmp_ptr32(s->grpmod, irq);
    uint32_t enable = *gic_bmp_ptr32(s->enabled, irq);

    pend = pending | (~edge_trigger & level);
    pend &= enable;

    if (s->gicd_ctlr & GICD_CTLR_DS) {
        grpmod = 0;
    }

    grpmask = 0;
    if (s->gicd_ctlr & GICD_CTLR_EN_GRP1NS) {
        grpmask |= group;
    }
    if (s->gicd_ctlr & GICD_CTLR_EN_GRP1S) {
        grpmask |= (~group & grpmod);
    }
    if (s->gicd_ctlr & GICD_CTLR_EN_GRP0) {
        grpmask |= (~group & ~grpmod);
    }
    pend &= grpmask;

    return pend;
}

static uint32_t gicr_int_pending(GICv3CPUState *cs)
{
    /* Recalculate which redistributor interrupts are actually pending,
     * and return a 32-bit integer which has a bit set for each interrupt
     * that is eligible to be signaled to the CPU interface.
     *
     * An interrupt is pending if:
     *  + the PENDING latch is set OR it is level triggered and the input is 1
     *  + its ENABLE bit is set
     *  + the GICD enable bit for its group is set
     * Conveniently we can bulk-calculate this with bitwise operations.
     */
    uint32_t pend, grpmask, grpmod;

    pend = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level);
    pend &= cs->gicr_ienabler0;

    if (cs->gic->gicd_ctlr & GICD_CTLR_DS) {
        grpmod = 0;
    } else {
        grpmod = cs->gicr_igrpmodr0;
    }

    grpmask = 0;
    if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) {
        grpmask |= cs->gicr_igroupr0;
    }
    if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1S) {
        grpmask |= (~cs->gicr_igroupr0 & grpmod);
    }
    if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP0) {
        grpmask |= (~cs->gicr_igroupr0 & ~grpmod);
    }
    pend &= grpmask;

    return pend;
}

/* Update the interrupt status after state in a redistributor
 * or CPU interface has changed, but don't tell the CPU i/f.
 */
static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
{
    /* Find the highest priority pending interrupt among the
     * redistributor interrupts (SGIs and PPIs).
     */
    bool seenbetter = false;
    uint8_t prio;
    int i;
    uint32_t pend;

    /* Find out which redistributor interrupts are eligible to be
     * signaled to the CPU interface.
     */
    pend = gicr_int_pending(cs);

    if (pend) {
        for (i = 0; i < GIC_INTERNAL; i++) {
            if (!(pend & (1 << i))) {
                continue;
            }
            prio = cs->gicr_ipriorityr[i];
            if (irqbetter(cs, i, prio)) {
                cs->hppi.irq = i;
                cs->hppi.prio = prio;
                seenbetter = true;
            }
        }
    }

    if (seenbetter) {
        cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
    }

    /* If the best interrupt we just found would preempt whatever
     * was the previous best interrupt before this update, then
     * we know it's definitely the best one now.
     * If we didn't find an interrupt that would preempt the previous
     * best, and the previous best is outside our range (or there was no
     * previous pending interrupt at all), then that is still valid, and
     * we leave it as the best.
     * Otherwise, we need to do a full update (because the previous best
     * interrupt has reduced in priority and any other interrupt could
     * now be the new best one).
     */
    if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) {
        gicv3_full_update_noirqset(cs->gic);
    }
}

/* Update the GIC status after state in a redistributor or
 * CPU interface has changed, and inform the CPU i/f of
 * its new highest priority pending interrupt.
 */
void gicv3_redist_update(GICv3CPUState *cs)
{
    gicv3_redist_update_noirqset(cs);
    gicv3_cpuif_update(cs);
}

/* Update the GIC status after state in the distributor has
 * changed affecting @len interrupts starting at @start,
 * but don't tell the CPU i/f.
 */
static void gicv3_update_noirqset(GICv3State *s, int start, int len)
{
    int i;
    uint8_t prio;
    uint32_t pend = 0;

    assert(start >= GIC_INTERNAL);
    assert(len > 0);

    for (i = 0; i < s->num_cpu; i++) {
        s->cpu[i].seenbetter = false;
    }

    /* Find the highest priority pending interrupt in this range. */
    for (i = start; i < start + len; i++) {
        GICv3CPUState *cs;

        if (i == start || (i & 0x1f) == 0) {
            /* Calculate the next 32 bits worth of pending status */
            pend = gicd_int_pending(s, i & ~0x1f);
        }

        if (!(pend & (1 << (i & 0x1f)))) {
            continue;
        }
        cs = s->gicd_irouter_target[i];
        if (!cs) {
            /* Interrupts targeting no implemented CPU should remain pending
             * and not be forwarded to any CPU.
             */
            continue;
        }
        prio = s->gicd_ipriority[i];
        if (irqbetter(cs, i, prio)) {
            cs->hppi.irq = i;
            cs->hppi.prio = prio;
            cs->seenbetter = true;
        }
    }

    /* If the best interrupt we just found would preempt whatever
     * was the previous best interrupt before this update, then
     * we know it's definitely the best one now.
     * If we didn't find an interrupt that would preempt the previous
     * best, and the previous best is outside our range (or there was
     * no previous pending interrupt at all), then that
     * is still valid, and we leave it as the best.
     * Otherwise, we need to do a full update (because the previous best
     * interrupt has reduced in priority and any other interrupt could
     * now be the new best one).
     */
    for (i = 0; i < s->num_cpu; i++) {
        GICv3CPUState *cs = &s->cpu[i];

        if (cs->seenbetter) {
            cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
        }

        if (!cs->seenbetter && cs->hppi.prio != 0xff &&
            cs->hppi.irq >= start && cs->hppi.irq < start + len) {
            gicv3_full_update_noirqset(s);
            break;
        }
    }
}

void gicv3_update(GICv3State *s, int start, int len)
{
    int i;

    gicv3_update_noirqset(s, start, len);
    for (i = 0; i < s->num_cpu; i++) {
        gicv3_cpuif_update(&s->cpu[i]);
    }
}

void gicv3_full_update_noirqset(GICv3State *s)
{
    /* Completely recalculate the GIC status from scratch, but
     * don't update any outbound IRQ lines.
     */
    int i;

    for (i = 0; i < s->num_cpu; i++) {
        s->cpu[i].hppi.prio = 0xff;
    }

    /* Note that we can guarantee that these functions will not
     * recursively call back into gicv3_full_update(), because
     * at each point the "previous best" is always outside the
     * range we ask them to update.
     */
    gicv3_update_noirqset(s, GIC_INTERNAL, s->num_irq - GIC_INTERNAL);

    for (i = 0; i < s->num_cpu; i++) {
        gicv3_redist_update_noirqset(&s->cpu[i]);
    }
}

void gicv3_full_update(GICv3State *s)
{
    /* Completely recalculate the GIC status from scratch, including
     * updating outbound IRQ lines.
     */
    int i;

    gicv3_full_update_noirqset(s);
    for (i = 0; i < s->num_cpu; i++) {
        gicv3_cpuif_update(&s->cpu[i]);
    }
}

/* Process a change in an external IRQ input. */
static void gicv3_set_irq(void *opaque, int irq, int level)
{
    /* Meaning of the 'irq' parameter:
     *  [0..N-1] : external interrupts
     *  [N..N+31] : PPI (internal) interrupts for CPU 0
     *  [N+32..N+63] : PPI (internal interrupts for CPU 1
     *  ...
     */
    GICv3State *s = opaque;

    if (irq < (s->num_irq - GIC_INTERNAL)) {
        /* external interrupt (SPI) */
        gicv3_dist_set_irq(s, irq + GIC_INTERNAL, level);
    } else {
        /* per-cpu interrupt (PPI) */
        int cpu;

        irq -= (s->num_irq - GIC_INTERNAL);
        cpu = irq / GIC_INTERNAL;
        irq %= GIC_INTERNAL;
        assert(cpu < s->num_cpu);
        /* Raising SGIs via this function would be a bug in how the board
         * model wires up interrupts.
         */
        assert(irq >= GIC_NR_SGIS);
        gicv3_redist_set_irq(&s->cpu[cpu], irq, level);
    }
}

static void arm_gicv3_post_load(GICv3State *s)
{
    /* Recalculate our cached idea of the current highest priority
     * pending interrupt, but don't set IRQ or FIQ lines.
     */
    gicv3_full_update_noirqset(s);
    /* Repopulate the cache of GICv3CPUState pointers for target CPUs */
    gicv3_cache_all_target_cpustates(s);
}

static const MemoryRegionOps gic_ops[] = {
    {
        .read_with_attrs = gicv3_dist_read,
        .write_with_attrs = gicv3_dist_write,
        .endianness = DEVICE_NATIVE_ENDIAN,
    },
    {
        .read_with_attrs = gicv3_redist_read,
        .write_with_attrs = gicv3_redist_write,
        .endianness = DEVICE_NATIVE_ENDIAN,
    }
};

static void arm_gic_realize(DeviceState *dev, Error **errp)
{
    /* Device instance realize function for the GIC sysbus device */
    GICv3State *s = ARM_GICV3(dev);
    ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s);
    Error *local_err = NULL;

    agc->parent_realize(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);

    gicv3_init_cpuif(s);
}

static void arm_gicv3_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass);
    ARMGICv3Class *agc = ARM_GICV3_CLASS(klass);

    agcc->post_load = arm_gicv3_post_load;
    agc->parent_realize = dc->realize;
    dc->realize = arm_gic_realize;
}

static const TypeInfo arm_gicv3_info = {
    .name = TYPE_ARM_GICV3,
    .parent = TYPE_ARM_GICV3_COMMON,
    .instance_size = sizeof(GICv3State),
    .class_init = arm_gicv3_class_init,
    .class_size = sizeof(ARMGICv3Class),
};

static void arm_gicv3_register_types(void)
{
    type_register_static(&arm_gicv3_info);
}

type_init(arm_gicv3_register_types)
