/*
 * ARM GIC support - common bits of emulated and KVM kernel model
 *
 * Copyright (c) 2012 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 as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that 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 "gic_internal.h"
#include "hw/arm/linux-boot-if.h"

static int gic_pre_save(void *opaque)
{
    GICState *s = (GICState *)opaque;
    ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);

    if (c->pre_save) {
        c->pre_save(s);
    }

    return 0;
}

static int gic_post_load(void *opaque, int version_id)
{
    GICState *s = (GICState *)opaque;
    ARMGICCommonClass *c = ARM_GIC_COMMON_GET_CLASS(s);

    if (c->post_load) {
        c->post_load(s);
    }
    return 0;
}

static bool gic_virt_state_needed(void *opaque)
{
    GICState *s = (GICState *)opaque;

    return s->virt_extn;
}

static const VMStateDescription vmstate_gic_irq_state = {
    .name = "arm_gic_irq_state",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(enabled, gic_irq_state),
        VMSTATE_UINT8(pending, gic_irq_state),
        VMSTATE_UINT8(active, gic_irq_state),
        VMSTATE_UINT8(level, gic_irq_state),
        VMSTATE_BOOL(model, gic_irq_state),
        VMSTATE_BOOL(edge_trigger, gic_irq_state),
        VMSTATE_UINT8(group, gic_irq_state),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_gic_virt_state = {
    .name = "arm_gic_virt_state",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = gic_virt_state_needed,
    .fields = (VMStateField[]) {
        /* Virtual interface */
        VMSTATE_UINT32_ARRAY(h_hcr, GICState, GIC_NCPU),
        VMSTATE_UINT32_ARRAY(h_misr, GICState, GIC_NCPU),
        VMSTATE_UINT32_2DARRAY(h_lr, GICState, GIC_MAX_LR, GIC_NCPU),
        VMSTATE_UINT32_ARRAY(h_apr, GICState, GIC_NCPU),

        /* Virtual CPU interfaces */
        VMSTATE_UINT32_SUB_ARRAY(cpu_ctlr, GICState, GIC_NCPU, GIC_NCPU),
        VMSTATE_UINT16_SUB_ARRAY(priority_mask, GICState, GIC_NCPU, GIC_NCPU),
        VMSTATE_UINT16_SUB_ARRAY(running_priority, GICState, GIC_NCPU, GIC_NCPU),
        VMSTATE_UINT16_SUB_ARRAY(current_pending, GICState, GIC_NCPU, GIC_NCPU),
        VMSTATE_UINT8_SUB_ARRAY(bpr, GICState, GIC_NCPU, GIC_NCPU),
        VMSTATE_UINT8_SUB_ARRAY(abpr, GICState, GIC_NCPU, GIC_NCPU),

        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_gic = {
    .name = "arm_gic",
    .version_id = 12,
    .minimum_version_id = 12,
    .pre_save = gic_pre_save,
    .post_load = gic_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(ctlr, GICState),
        VMSTATE_UINT32_SUB_ARRAY(cpu_ctlr, GICState, 0, GIC_NCPU),
        VMSTATE_STRUCT_ARRAY(irq_state, GICState, GIC_MAXIRQ, 1,
                             vmstate_gic_irq_state, gic_irq_state),
        VMSTATE_UINT8_ARRAY(irq_target, GICState, GIC_MAXIRQ),
        VMSTATE_UINT8_2DARRAY(priority1, GICState, GIC_INTERNAL, GIC_NCPU),
        VMSTATE_UINT8_ARRAY(priority2, GICState, GIC_MAXIRQ - GIC_INTERNAL),
        VMSTATE_UINT8_2DARRAY(sgi_pending, GICState, GIC_NR_SGIS, GIC_NCPU),
        VMSTATE_UINT16_SUB_ARRAY(priority_mask, GICState, 0, GIC_NCPU),
        VMSTATE_UINT16_SUB_ARRAY(running_priority, GICState, 0, GIC_NCPU),
        VMSTATE_UINT16_SUB_ARRAY(current_pending, GICState, 0, GIC_NCPU),
        VMSTATE_UINT8_SUB_ARRAY(bpr, GICState, 0, GIC_NCPU),
        VMSTATE_UINT8_SUB_ARRAY(abpr, GICState, 0, GIC_NCPU),
        VMSTATE_UINT32_2DARRAY(apr, GICState, GIC_NR_APRS, GIC_NCPU),
        VMSTATE_UINT32_2DARRAY(nsapr, GICState, GIC_NR_APRS, GIC_NCPU),
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * []) {
        &vmstate_gic_virt_state,
        NULL
    }
};

void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler,
                            const MemoryRegionOps *ops,
                            const MemoryRegionOps *virt_ops)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(s);
    int i = s->num_irq - GIC_INTERNAL;

    /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
     * GPIO array layout is thus:
     *  [0..N-1] SPIs
     *  [N..N+31] PPIs for CPU 0
     *  [N+32..N+63] PPIs for CPU 1
     *   ...
     */
    i += (GIC_INTERNAL * s->num_cpu);
    qdev_init_gpio_in(DEVICE(s), handler, i);

    for (i = 0; i < s->num_cpu; i++) {
        sysbus_init_irq(sbd, &s->parent_irq[i]);
    }
    for (i = 0; i < s->num_cpu; i++) {
        sysbus_init_irq(sbd, &s->parent_fiq[i]);
    }
    for (i = 0; i < s->num_cpu; i++) {
        sysbus_init_irq(sbd, &s->parent_virq[i]);
    }
    for (i = 0; i < s->num_cpu; i++) {
        sysbus_init_irq(sbd, &s->parent_vfiq[i]);
    }
    if (s->virt_extn) {
        for (i = 0; i < s->num_cpu; i++) {
            sysbus_init_irq(sbd, &s->maintenance_irq[i]);
        }
    }

    /* Distributor */
    memory_region_init_io(&s->iomem, OBJECT(s), ops, s, "gic_dist", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);

    /* This is the main CPU interface "for this core". It is always
     * present because it is required by both software emulation and KVM.
     */
    memory_region_init_io(&s->cpuiomem[0], OBJECT(s), ops ? &ops[1] : NULL,
                          s, "gic_cpu", s->revision == 2 ? 0x2000 : 0x100);
    sysbus_init_mmio(sbd, &s->cpuiomem[0]);

    if (s->virt_extn) {
        memory_region_init_io(&s->vifaceiomem[0], OBJECT(s), virt_ops,
                              s, "gic_viface", 0x1000);
        sysbus_init_mmio(sbd, &s->vifaceiomem[0]);

        memory_region_init_io(&s->vcpuiomem, OBJECT(s),
                              virt_ops ? &virt_ops[1] : NULL,
                              s, "gic_vcpu", 0x2000);
        sysbus_init_mmio(sbd, &s->vcpuiomem);
    }
}

static void arm_gic_common_realize(DeviceState *dev, Error **errp)
{
    GICState *s = ARM_GIC_COMMON(dev);
    int num_irq = s->num_irq;

    if (s->num_cpu > GIC_NCPU) {
        error_setg(errp, "requested %u CPUs exceeds GIC maximum %d",
                   s->num_cpu, GIC_NCPU);
        return;
    }
    if (s->num_irq > GIC_MAXIRQ) {
        error_setg(errp,
                   "requested %u interrupt lines exceeds GIC maximum %d",
                   num_irq, GIC_MAXIRQ);
        return;
    }
    /* ITLinesNumber is represented as (N / 32) - 1 (see
     * gic_dist_readb) so this is an implementation imposed
     * restriction, not an architectural one:
     */
    if (s->num_irq < 32 || (s->num_irq % 32)) {
        error_setg(errp,
                   "%d interrupt lines unsupported: not divisible by 32",
                   num_irq);
        return;
    }

    if (s->security_extn &&
        (s->revision == REV_11MPCORE)) {
        error_setg(errp, "this GIC revision does not implement "
                   "the security extensions");
        return;
    }

    if (s->virt_extn) {
        if (s->revision != 2) {
            error_setg(errp, "GIC virtualization extensions are only "
                       "supported by revision 2");
            return;
        }

        /* For now, set the number of implemented LRs to 4, as found in most
         * real GICv2. This could be promoted as a QOM property if we need to
         * emulate a variant with another num_lrs.
         */
        s->num_lrs = 4;
    }
}

static inline void arm_gic_common_reset_irq_state(GICState *s, int first_cpu,
                                                  int resetprio)
{
    int i, j;

    for (i = first_cpu; i < first_cpu + s->num_cpu; i++) {
        if (s->revision == REV_11MPCORE) {
            s->priority_mask[i] = 0xf0;
        } else {
            s->priority_mask[i] = resetprio;
        }
        s->current_pending[i] = 1023;
        s->running_priority[i] = 0x100;
        s->cpu_ctlr[i] = 0;
        s->bpr[i] = gic_is_vcpu(i) ? GIC_VIRT_MIN_BPR : GIC_MIN_BPR;
        s->abpr[i] = gic_is_vcpu(i) ? GIC_VIRT_MIN_ABPR : GIC_MIN_ABPR;

        if (!gic_is_vcpu(i)) {
            for (j = 0; j < GIC_INTERNAL; j++) {
                s->priority1[j][i] = resetprio;
            }
            for (j = 0; j < GIC_NR_SGIS; j++) {
                s->sgi_pending[j][i] = 0;
            }
        }
    }
}

static void arm_gic_common_reset(DeviceState *dev)
{
    GICState *s = ARM_GIC_COMMON(dev);
    int i, j;
    int resetprio;

    /* If we're resetting a TZ-aware GIC as if secure firmware
     * had set it up ready to start a kernel in non-secure,
     * we need to set interrupt priorities to a "zero for the
     * NS view" value. This is particularly critical for the
     * priority_mask[] values, because if they are zero then NS
     * code cannot ever rewrite the priority to anything else.
     */
    if (s->security_extn && s->irq_reset_nonsecure) {
        resetprio = 0x80;
    } else {
        resetprio = 0;
    }

    memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
    arm_gic_common_reset_irq_state(s, 0, resetprio);

    if (s->virt_extn) {
        /* vCPU states are stored at indexes GIC_NCPU .. GIC_NCPU+num_cpu.
         * The exposed vCPU interface does not have security extensions.
         */
        arm_gic_common_reset_irq_state(s, GIC_NCPU, 0);
    }

    for (i = 0; i < GIC_NR_SGIS; i++) {
        GIC_DIST_SET_ENABLED(i, ALL_CPU_MASK);
        GIC_DIST_SET_EDGE_TRIGGER(i);
    }

    for (i = 0; i < ARRAY_SIZE(s->priority2); i++) {
        s->priority2[i] = resetprio;
    }

    for (i = 0; i < GIC_MAXIRQ; i++) {
        /* For uniprocessor GICs all interrupts always target the sole CPU */
        if (s->num_cpu == 1) {
            s->irq_target[i] = 1;
        } else {
            s->irq_target[i] = 0;
        }
    }
    if (s->security_extn && s->irq_reset_nonsecure) {
        for (i = 0; i < GIC_MAXIRQ; i++) {
            GIC_DIST_SET_GROUP(i, ALL_CPU_MASK);
        }
    }

    if (s->virt_extn) {
        for (i = 0; i < s->num_lrs; i++) {
            for (j = 0; j < s->num_cpu; j++) {
                s->h_lr[i][j] = 0;
            }
        }

        for (i = 0; i < s->num_cpu; i++) {
            s->h_hcr[i] = 0;
            s->h_misr[i] = 0;
        }
    }

    s->ctlr = 0;
}

static void arm_gic_common_linux_init(ARMLinuxBootIf *obj,
                                      bool secure_boot)
{
    GICState *s = ARM_GIC_COMMON(obj);

    if (s->security_extn && !secure_boot) {
        /* We're directly booting a kernel into NonSecure. If this GIC
         * implements the security extensions then we must configure it
         * to have all the interrupts be NonSecure (this is a job that
         * is done by the Secure boot firmware in real hardware, and in
         * this mode QEMU is acting as a minimalist firmware-and-bootloader
         * equivalent).
         */
        s->irq_reset_nonsecure = true;
    }
}

static Property arm_gic_common_properties[] = {
    DEFINE_PROP_UINT32("num-cpu", GICState, num_cpu, 1),
    DEFINE_PROP_UINT32("num-irq", GICState, num_irq, 32),
    /* Revision can be 1 or 2 for GIC architecture specification
     * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
     */
    DEFINE_PROP_UINT32("revision", GICState, revision, 1),
    /* True if the GIC should implement the security extensions */
    DEFINE_PROP_BOOL("has-security-extensions", GICState, security_extn, 0),
    /* True if the GIC should implement the virtualization extensions */
    DEFINE_PROP_BOOL("has-virtualization-extensions", GICState, virt_extn, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void arm_gic_common_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_CLASS(klass);

    dc->reset = arm_gic_common_reset;
    dc->realize = arm_gic_common_realize;
    dc->props = arm_gic_common_properties;
    dc->vmsd = &vmstate_gic;
    albifc->arm_linux_init = arm_gic_common_linux_init;
}

static const TypeInfo arm_gic_common_type = {
    .name = TYPE_ARM_GIC_COMMON,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(GICState),
    .class_size = sizeof(ARMGICCommonClass),
    .class_init = arm_gic_common_class_init,
    .abstract = true,
    .interfaces = (InterfaceInfo []) {
        { TYPE_ARM_LINUX_BOOT_IF },
        { },
    },
};

static void register_types(void)
{
    type_register_static(&arm_gic_common_type);
}

type_init(register_types)
