/*
 * Xilinx Versal SoC model.
 *
 * Copyright (c) 2018 Xilinx Inc.
 * Written by Edgar E. Iglesias
 *
 * 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.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "hw/arm/boot.h"
#include "kvm_arm.h"
#include "hw/misc/unimp.h"
#include "hw/arm/xlnx-versal.h"
#include "qemu/log.h"

#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
#define GEM_REVISION        0x40070106

#define VERSAL_NUM_PMC_APB_IRQS 18
#define NUM_OSPI_IRQ_LINES 3

static void versal_create_apu_cpus(Versal *s)
{
    int i;

    object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
                            TYPE_CPU_CLUSTER);
    qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);

    for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
        Object *obj;

        object_initialize_child(OBJECT(&s->fpd.apu.cluster),
                                "apu-cpu[*]", &s->fpd.apu.cpu[i],
                                XLNX_VERSAL_ACPU_TYPE);
        obj = OBJECT(&s->fpd.apu.cpu[i]);
        if (i) {
            /* Secondary CPUs start in powered-down state */
            object_property_set_bool(obj, "start-powered-off", true,
                                     &error_abort);
        }

        object_property_set_int(obj, "core-count", ARRAY_SIZE(s->fpd.apu.cpu),
                                &error_abort);
        object_property_set_link(obj, "memory", OBJECT(&s->fpd.apu.mr),
                                 &error_abort);
        qdev_realize(DEVICE(obj), NULL, &error_fatal);
    }

    qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
}

static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
{
    static const uint64_t addrs[] = {
        MM_GIC_APU_DIST_MAIN,
        MM_GIC_APU_REDIST_0
    };
    SysBusDevice *gicbusdev;
    DeviceState *gicdev;
    int nr_apu_cpus = ARRAY_SIZE(s->fpd.apu.cpu);
    int i;

    object_initialize_child(OBJECT(s), "apu-gic", &s->fpd.apu.gic,
                            gicv3_class_name());
    gicbusdev = SYS_BUS_DEVICE(&s->fpd.apu.gic);
    gicdev = DEVICE(&s->fpd.apu.gic);
    qdev_prop_set_uint32(gicdev, "revision", 3);
    qdev_prop_set_uint32(gicdev, "num-cpu", nr_apu_cpus);
    qdev_prop_set_uint32(gicdev, "num-irq", XLNX_VERSAL_NR_IRQS + 32);
    qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
    qdev_prop_set_uint32(gicdev, "redist-region-count[0]", nr_apu_cpus);
    qdev_prop_set_bit(gicdev, "has-security-extensions", true);

    sysbus_realize(SYS_BUS_DEVICE(&s->fpd.apu.gic), &error_fatal);

    for (i = 0; i < ARRAY_SIZE(addrs); i++) {
        MemoryRegion *mr;

        mr = sysbus_mmio_get_region(gicbusdev, i);
        memory_region_add_subregion(&s->fpd.apu.mr, addrs[i], mr);
    }

    for (i = 0; i < nr_apu_cpus; i++) {
        DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
        int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
        qemu_irq maint_irq;
        int ti;
        /* Mapping from the output timer irq lines from the CPU to the
         * GIC PPI inputs.
         */
        const int timer_irq[] = {
            [GTIMER_PHYS] = VERSAL_TIMER_NS_EL1_IRQ,
            [GTIMER_VIRT] = VERSAL_TIMER_VIRT_IRQ,
            [GTIMER_HYP]  = VERSAL_TIMER_NS_EL2_IRQ,
            [GTIMER_SEC]  = VERSAL_TIMER_S_EL1_IRQ,
        };

        for (ti = 0; ti < ARRAY_SIZE(timer_irq); ti++) {
            qdev_connect_gpio_out(cpudev, ti,
                                  qdev_get_gpio_in(gicdev,
                                                   ppibase + timer_irq[ti]));
        }
        maint_irq = qdev_get_gpio_in(gicdev,
                                        ppibase + VERSAL_GIC_MAINT_IRQ);
        qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
                                    0, maint_irq);
        sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
        sysbus_connect_irq(gicbusdev, i + nr_apu_cpus,
                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
        sysbus_connect_irq(gicbusdev, i + 2 * nr_apu_cpus,
                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
        sysbus_connect_irq(gicbusdev, i + 3 * nr_apu_cpus,
                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
    }

    for (i = 0; i < XLNX_VERSAL_NR_IRQS; i++) {
        pic[i] = qdev_get_gpio_in(gicdev, i);
    }
}

static void versal_create_rpu_cpus(Versal *s)
{
    int i;

    object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
                            TYPE_CPU_CLUSTER);
    qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);

    for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
        Object *obj;

        object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
                                "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
                                XLNX_VERSAL_RCPU_TYPE);
        obj = OBJECT(&s->lpd.rpu.cpu[i]);
        object_property_set_bool(obj, "start-powered-off", true,
                                 &error_abort);

        object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
        object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
                                &error_abort);
        object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
                                 &error_abort);
        qdev_realize(DEVICE(obj), NULL, &error_fatal);
    }

    qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
}

static void versal_create_uarts(Versal *s, qemu_irq *pic)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
        static const int irqs[] = { VERSAL_UART0_IRQ_0, VERSAL_UART1_IRQ_0};
        static const uint64_t addrs[] = { MM_UART0, MM_UART1 };
        char *name = g_strdup_printf("uart%d", i);
        DeviceState *dev;
        MemoryRegion *mr;

        object_initialize_child(OBJECT(s), name, &s->lpd.iou.uart[i],
                                TYPE_PL011);
        dev = DEVICE(&s->lpd.iou.uart[i]);
        qdev_prop_set_chr(dev, "chardev", serial_hd(i));
        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

        mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
        memory_region_add_subregion(&s->mr_ps, addrs[i], mr);

        sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
        g_free(name);
    }
}

static void versal_create_canfds(Versal *s, qemu_irq *pic)
{
    int i;
    uint32_t irqs[] = { VERSAL_CANFD0_IRQ_0, VERSAL_CANFD1_IRQ_0};
    uint64_t addrs[] = { MM_CANFD0, MM_CANFD1 };

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.canfd); i++) {
        char *name = g_strdup_printf("canfd%d", i);
        SysBusDevice *sbd;
        MemoryRegion *mr;

        object_initialize_child(OBJECT(s), name, &s->lpd.iou.canfd[i],
                                TYPE_XILINX_CANFD);
        sbd = SYS_BUS_DEVICE(&s->lpd.iou.canfd[i]);

        object_property_set_int(OBJECT(&s->lpd.iou.canfd[i]), "ext_clk_freq",
                                XLNX_VERSAL_CANFD_REF_CLK , &error_abort);

        object_property_set_link(OBJECT(&s->lpd.iou.canfd[i]), "canfdbus",
                                 OBJECT(s->lpd.iou.canbus[i]),
                                 &error_abort);

        sysbus_realize(sbd, &error_fatal);

        mr = sysbus_mmio_get_region(sbd, 0);
        memory_region_add_subregion(&s->mr_ps, addrs[i], mr);

        sysbus_connect_irq(sbd, 0, pic[irqs[i]]);
        g_free(name);
    }
}

static void versal_create_usbs(Versal *s, qemu_irq *pic)
{
    DeviceState *dev;
    MemoryRegion *mr;

    object_initialize_child(OBJECT(s), "usb2", &s->lpd.iou.usb,
                            TYPE_XILINX_VERSAL_USB2);
    dev = DEVICE(&s->lpd.iou.usb);

    object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
                             &error_abort);
    qdev_prop_set_uint32(dev, "intrs", 1);
    qdev_prop_set_uint32(dev, "slots", 2);

    sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
    memory_region_add_subregion(&s->mr_ps, MM_USB_0, mr);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_USB0_IRQ_0]);

    mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
    memory_region_add_subregion(&s->mr_ps, MM_USB2_CTRL_REGS, mr);
}

static void versal_create_gems(Versal *s, qemu_irq *pic)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
        static const int irqs[] = { VERSAL_GEM0_IRQ_0, VERSAL_GEM1_IRQ_0};
        static const uint64_t addrs[] = { MM_GEM0, MM_GEM1 };
        char *name = g_strdup_printf("gem%d", i);
        NICInfo *nd = &nd_table[i];
        DeviceState *dev;
        MemoryRegion *mr;

        object_initialize_child(OBJECT(s), name, &s->lpd.iou.gem[i],
                                TYPE_CADENCE_GEM);
        dev = DEVICE(&s->lpd.iou.gem[i]);
        /* FIXME use qdev NIC properties instead of nd_table[] */
        if (nd->used) {
            qemu_check_nic_model(nd, "cadence_gem");
            qdev_set_nic_properties(dev, nd);
        }
        object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
        object_property_set_int(OBJECT(dev), "num-priority-queues", 2,
                                &error_abort);
        object_property_set_link(OBJECT(dev), "dma", OBJECT(&s->mr_ps),
                                 &error_abort);
        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

        mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
        memory_region_add_subregion(&s->mr_ps, addrs[i], mr);

        sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
        g_free(name);
    }
}

static void versal_create_admas(Versal *s, qemu_irq *pic)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
        char *name = g_strdup_printf("adma%d", i);
        DeviceState *dev;
        MemoryRegion *mr;

        object_initialize_child(OBJECT(s), name, &s->lpd.iou.adma[i],
                                TYPE_XLNX_ZDMA);
        dev = DEVICE(&s->lpd.iou.adma[i]);
        object_property_set_int(OBJECT(dev), "bus-width", 128, &error_abort);
        object_property_set_link(OBJECT(dev), "dma",
                                 OBJECT(get_system_memory()), &error_fatal);
        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

        mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
        memory_region_add_subregion(&s->mr_ps,
                                    MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);

        sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
        g_free(name);
    }
}

#define SDHCI_CAPABILITIES  0x280737ec6481 /* Same as on ZynqMP.  */
static void versal_create_sds(Versal *s, qemu_irq *pic)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
        DeviceState *dev;
        MemoryRegion *mr;

        object_initialize_child(OBJECT(s), "sd[*]", &s->pmc.iou.sd[i],
                                TYPE_SYSBUS_SDHCI);
        dev = DEVICE(&s->pmc.iou.sd[i]);

        object_property_set_uint(OBJECT(dev), "sd-spec-version", 3,
                                 &error_fatal);
        object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES,
                                 &error_fatal);
        object_property_set_uint(OBJECT(dev), "uhs", UHS_I, &error_fatal);
        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

        mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
        memory_region_add_subregion(&s->mr_ps,
                                    MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);

        sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
                           pic[VERSAL_SD0_IRQ_0 + i * 2]);
    }
}

static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
{
    DeviceState *orgate;

    /*
     * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following
     * models:
     *  - RTC
     *  - BBRAM
     *  - PMC SLCR
     *  - CFRAME regs (input 3 - 17 to the orgate)
     */
    object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
                            &s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
    orgate = DEVICE(&s->pmc.apb_irq_orgate);
    object_property_set_int(OBJECT(orgate),
                            "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal);
    qdev_realize(orgate, NULL, &error_fatal);
    qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]);
}

static void versal_create_rtc(Versal *s, qemu_irq *pic)
{
    SysBusDevice *sbd;
    MemoryRegion *mr;

    object_initialize_child(OBJECT(s), "rtc", &s->pmc.rtc,
                            TYPE_XLNX_ZYNQMP_RTC);
    sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
    sysbus_realize(sbd, &error_fatal);

    mr = sysbus_mmio_get_region(sbd, 0);
    memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);

    /*
     * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
     * supports them.
     */
    sysbus_connect_irq(sbd, 1,
                       qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0));
}

static void versal_create_xrams(Versal *s, qemu_irq *pic)
{
    int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl);
    DeviceState *orgate;
    int i;

    /* XRAM IRQs get ORed into a single line.  */
    object_initialize_child(OBJECT(s), "xram-irq-orgate",
                            &s->lpd.xram.irq_orgate, TYPE_OR_IRQ);
    orgate = DEVICE(&s->lpd.xram.irq_orgate);
    object_property_set_int(OBJECT(orgate),
                            "num-lines", nr_xrams, &error_fatal);
    qdev_realize(orgate, NULL, &error_fatal);
    qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]);

    for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) {
        SysBusDevice *sbd;
        MemoryRegion *mr;

        object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i],
                                TYPE_XLNX_XRAM_CTRL);
        sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]);
        sysbus_realize(sbd, &error_fatal);

        mr = sysbus_mmio_get_region(sbd, 0);
        memory_region_add_subregion(&s->mr_ps,
                                    MM_XRAMC + i * MM_XRAMC_SIZE, mr);
        mr = sysbus_mmio_get_region(sbd, 1);
        memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr);

        sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i));
    }
}

static void versal_create_bbram(Versal *s, qemu_irq *pic)
{
    SysBusDevice *sbd;

    object_initialize_child_with_props(OBJECT(s), "bbram", &s->pmc.bbram,
                                       sizeof(s->pmc.bbram), TYPE_XLNX_BBRAM,
                                       &error_fatal,
                                       "crc-zpads", "0",
                                       NULL);
    sbd = SYS_BUS_DEVICE(&s->pmc.bbram);

    sysbus_realize(sbd, &error_fatal);
    memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL,
                                sysbus_mmio_get_region(sbd, 0));
    sysbus_connect_irq(sbd, 0,
                       qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1));
}

static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base)
{
    SysBusDevice *part = SYS_BUS_DEVICE(dev);

    object_property_set_link(OBJECT(part), "efuse",
                             OBJECT(&s->pmc.efuse), &error_abort);

    sysbus_realize(part, &error_abort);
    memory_region_add_subregion(&s->mr_ps, base,
                                sysbus_mmio_get_region(part, 0));
}

static void versal_create_efuse(Versal *s, qemu_irq *pic)
{
    Object *bits = OBJECT(&s->pmc.efuse);
    Object *ctrl = OBJECT(&s->pmc.efuse_ctrl);
    Object *cache = OBJECT(&s->pmc.efuse_cache);

    object_initialize_child(OBJECT(s), "efuse-ctrl", &s->pmc.efuse_ctrl,
                            TYPE_XLNX_VERSAL_EFUSE_CTRL);

    object_initialize_child(OBJECT(s), "efuse-cache", &s->pmc.efuse_cache,
                            TYPE_XLNX_VERSAL_EFUSE_CACHE);

    object_initialize_child_with_props(ctrl, "xlnx-efuse@0", bits,
                                       sizeof(s->pmc.efuse),
                                       TYPE_XLNX_EFUSE, &error_abort,
                                       "efuse-nr", "3",
                                       "efuse-size", "8192",
                                       NULL);

    qdev_realize(DEVICE(bits), NULL, &error_abort);
    versal_realize_efuse_part(s, ctrl, MM_PMC_EFUSE_CTRL);
    versal_realize_efuse_part(s, cache, MM_PMC_EFUSE_CACHE);

    sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]);
}

static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic)
{
    SysBusDevice *sbd;

    object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr,
                            TYPE_XILINX_VERSAL_PMC_IOU_SLCR);

    sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr);
    sysbus_realize(sbd, &error_fatal);

    memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR,
                                sysbus_mmio_get_region(sbd, 0));

    sysbus_connect_irq(sbd, 0,
                       qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2));
}

static void versal_create_ospi(Versal *s, qemu_irq *pic)
{
    SysBusDevice *sbd;
    MemoryRegion *mr_dac;
    qemu_irq ospi_mux_sel;
    DeviceState *orgate;

    memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s),
                       "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE);

    object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi,
                            TYPE_XILINX_VERSAL_OSPI);

    mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1);
    memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac);

    /* Create the OSPI destination DMA */
    object_initialize_child(OBJECT(s), "versal-ospi-dma-dst",
                            &s->pmc.iou.ospi.dma_dst,
                            TYPE_XLNX_CSU_DMA);

    object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst),
                            "dma", OBJECT(get_system_memory()),
                             &error_abort);

    sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst);
    sysbus_realize(sbd, &error_fatal);

    memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST,
                                sysbus_mmio_get_region(sbd, 0));

    /* Create the OSPI source DMA */
    object_initialize_child(OBJECT(s), "versal-ospi-dma-src",
                            &s->pmc.iou.ospi.dma_src,
                            TYPE_XLNX_CSU_DMA);

    object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst",
                             false, &error_abort);

    object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
                            "dma", OBJECT(mr_dac), &error_abort);

    object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src),
                            "stream-connected-dma",
                             OBJECT(&s->pmc.iou.ospi.dma_dst),
                             &error_abort);

    sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src);
    sysbus_realize(sbd, &error_fatal);

    memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC,
                                sysbus_mmio_get_region(sbd, 0));

    /* Realize the OSPI */
    object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src",
                             OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort);

    sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi);
    sysbus_realize(sbd, &error_fatal);

    memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI,
                                sysbus_mmio_get_region(sbd, 0));

    memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC,
                                &s->pmc.iou.ospi.linear_mr);

    /* ospi_mux_sel */
    ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi),
                                          "ospi-mux-sel", 0);
    qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0,
                                ospi_mux_sel);

    /* OSPI irq */
    object_initialize_child(OBJECT(s), "ospi-irq-orgate",
                            &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ);
    object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate),
                            "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal);

    orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate);
    qdev_realize(orgate, NULL, &error_fatal);

    sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0,
                       qdev_get_gpio_in(orgate, 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0,
                       qdev_get_gpio_in(orgate, 1));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0,
                       qdev_get_gpio_in(orgate, 2));

    qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
}

static void versal_create_cfu(Versal *s, qemu_irq *pic)
{
    SysBusDevice *sbd;
    DeviceState *dev;
    int i;
    const struct {
        uint64_t reg_base;
        uint64_t fdri_base;
    } cframe_addr[] = {
        { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI },
        { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI },
        { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI },
        { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI },
        { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI },
        { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI },
        { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI },
        { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI },
        { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI },
        { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI },
        { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI },
        { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI },
        { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI },
        { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI },
        { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI },
    };
    const struct {
        uint32_t blktype0_frames;
        uint32_t blktype1_frames;
        uint32_t blktype2_frames;
        uint32_t blktype3_frames;
        uint32_t blktype4_frames;
        uint32_t blktype5_frames;
        uint32_t blktype6_frames;
    } cframe_cfg[] = {
        [0] = { 34111, 3528, 12800, 11, 5, 1, 1 },
        [1] = { 38498, 3841, 15361, 13, 7, 3, 1 },
        [2] = { 38498, 3841, 15361, 13, 7, 3, 1 },
        [3] = { 38498, 3841, 15361, 13, 7, 3, 1 },
    };

    /* CFU FDRO */
    object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro,
                            TYPE_XLNX_VERSAL_CFU_FDRO);
    sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro);

    sysbus_realize(sbd, &error_fatal);
    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO,
                                sysbus_mmio_get_region(sbd, 0));

    /* CFRAME REG */
    for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
        g_autofree char *name = g_strdup_printf("cframe%d", i);

        object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i],
                                TYPE_XLNX_VERSAL_CFRAME_REG);

        sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]);
        dev = DEVICE(&s->pmc.cframe[i]);

        if (i < ARRAY_SIZE(cframe_cfg)) {
            object_property_set_int(OBJECT(dev), "blktype0-frames",
                                    cframe_cfg[i].blktype0_frames,
                                    &error_abort);
            object_property_set_int(OBJECT(dev), "blktype1-frames",
                                    cframe_cfg[i].blktype1_frames,
                                    &error_abort);
            object_property_set_int(OBJECT(dev), "blktype2-frames",
                                    cframe_cfg[i].blktype2_frames,
                                    &error_abort);
            object_property_set_int(OBJECT(dev), "blktype3-frames",
                                    cframe_cfg[i].blktype3_frames,
                                    &error_abort);
            object_property_set_int(OBJECT(dev), "blktype4-frames",
                                    cframe_cfg[i].blktype4_frames,
                                    &error_abort);
            object_property_set_int(OBJECT(dev), "blktype5-frames",
                                    cframe_cfg[i].blktype5_frames,
                                    &error_abort);
            object_property_set_int(OBJECT(dev), "blktype6-frames",
                                    cframe_cfg[i].blktype6_frames,
                                    &error_abort);
        }
        object_property_set_link(OBJECT(dev), "cfu-fdro",
                                 OBJECT(&s->pmc.cfu_fdro), &error_fatal);

        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);

        memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base,
                                    sysbus_mmio_get_region(sbd, 0));
        memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base,
                                    sysbus_mmio_get_region(sbd, 1));
        sysbus_connect_irq(sbd, 0,
                           qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate),
                                            3 + i));
    }

    /* CFRAME BCAST */
    object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast,
                            TYPE_XLNX_VERSAL_CFRAME_BCAST_REG);

    sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast);
    dev = DEVICE(&s->pmc.cframe_bcast);

    for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
        g_autofree char *propname = g_strdup_printf("cframe%d", i);
        object_property_set_link(OBJECT(dev), propname,
                                 OBJECT(&s->pmc.cframe[i]), &error_fatal);
    }

    sysbus_realize(sbd, &error_fatal);

    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG,
                                sysbus_mmio_get_region(sbd, 0));
    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI,
                                sysbus_mmio_get_region(sbd, 1));

    /* CFU APB */
    object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb,
                            TYPE_XLNX_VERSAL_CFU_APB);
    sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb);
    dev = DEVICE(&s->pmc.cfu_apb);

    for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
        g_autofree char *propname = g_strdup_printf("cframe%d", i);
        object_property_set_link(OBJECT(dev), propname,
                                 OBJECT(&s->pmc.cframe[i]), &error_fatal);
    }

    sysbus_realize(sbd, &error_fatal);
    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB,
                                sysbus_mmio_get_region(sbd, 0));
    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM,
                                sysbus_mmio_get_region(sbd, 1));
    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2,
                                sysbus_mmio_get_region(sbd, 2));
    sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]);

    /* CFU SFR */
    object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr,
                            TYPE_XLNX_VERSAL_CFU_SFR);

    sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr);

    object_property_set_link(OBJECT(&s->pmc.cfu_sfr),
                            "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort);

    sysbus_realize(sbd, &error_fatal);
    memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR,
                                sysbus_mmio_get_region(sbd, 0));
}

static void versal_create_crl(Versal *s, qemu_irq *pic)
{
    SysBusDevice *sbd;
    int i;

    object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
                            TYPE_XLNX_VERSAL_CRL);
    sbd = SYS_BUS_DEVICE(&s->lpd.crl);

    for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
        g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);

        object_property_set_link(OBJECT(&s->lpd.crl),
                                 name, OBJECT(&s->lpd.rpu.cpu[i]),
                                 &error_abort);
    }

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
        g_autofree gchar *name = g_strdup_printf("gem[%d]", i);

        object_property_set_link(OBJECT(&s->lpd.crl),
                                 name, OBJECT(&s->lpd.iou.gem[i]),
                                 &error_abort);
    }

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
        g_autofree gchar *name = g_strdup_printf("adma[%d]", i);

        object_property_set_link(OBJECT(&s->lpd.crl),
                                 name, OBJECT(&s->lpd.iou.adma[i]),
                                 &error_abort);
    }

    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
        g_autofree gchar *name = g_strdup_printf("uart[%d]", i);

        object_property_set_link(OBJECT(&s->lpd.crl),
                                 name, OBJECT(&s->lpd.iou.uart[i]),
                                 &error_abort);
    }

    object_property_set_link(OBJECT(&s->lpd.crl),
                             "usb", OBJECT(&s->lpd.iou.usb),
                             &error_abort);

    sysbus_realize(sbd, &error_fatal);
    memory_region_add_subregion(&s->mr_ps, MM_CRL,
                                sysbus_mmio_get_region(sbd, 0));
    sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
}

/* This takes the board allocated linear DDR memory and creates aliases
 * for each split DDR range/aperture on the Versal address map.
 */
static void versal_map_ddr(Versal *s)
{
    uint64_t size = memory_region_size(s->cfg.mr_ddr);
    /* Describes the various split DDR access regions.  */
    static const struct {
        uint64_t base;
        uint64_t size;
    } addr_ranges[] = {
        { MM_TOP_DDR, MM_TOP_DDR_SIZE },
        { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE },
        { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE },
        { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE }
    };
    uint64_t offset = 0;
    int i;

    assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges));
    for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) {
        char *name;
        uint64_t mapsize;

        mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size;
        name = g_strdup_printf("noc-ddr-range%d", i);
        /* Create the MR alias.  */
        memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s),
                                 name, s->cfg.mr_ddr,
                                 offset, mapsize);

        /* Map it onto the NoC MR.  */
        memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base,
                                    &s->noc.mr_ddr_ranges[i]);
        offset += mapsize;
        size -= mapsize;
        g_free(name);
    }
}

static void versal_unimp_area(Versal *s, const char *name,
                                MemoryRegion *mr,
                                hwaddr base, hwaddr size)
{
    DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
    MemoryRegion *mr_dev;

    qdev_prop_set_string(dev, "name", name);
    qdev_prop_set_uint64(dev, "size", size);
    object_property_add_child(OBJECT(s), name, OBJECT(dev));
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    mr_dev = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
    memory_region_add_subregion(mr, base, mr_dev);
}

static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level)
{
    qemu_log_mask(LOG_UNIMP,
                  "Selecting between enabling SD mode or eMMC mode on "
                  "controller %d is not yet implemented\n", n);
}

static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level)
{
    qemu_log_mask(LOG_UNIMP,
                  "Selecting between enabling the QSPI or OSPI linear address "
                  "region is not yet implemented\n");
}

static void versal_unimp_irq_parity_imr(void *opaque, int n, int level)
{
    qemu_log_mask(LOG_UNIMP,
                  "PMC SLCR parity interrupt behaviour "
                  "is not yet implemented\n");
}

static void versal_unimp(Versal *s)
{
    qemu_irq gpio_in;

    versal_unimp_area(s, "psm", &s->mr_ps,
                        MM_PSM_START, MM_PSM_END - MM_PSM_START);
    versal_unimp_area(s, "crf", &s->mr_ps,
                        MM_FPD_CRF, MM_FPD_CRF_SIZE);
    versal_unimp_area(s, "apu", &s->mr_ps,
                        MM_FPD_FPD_APU, MM_FPD_FPD_APU_SIZE);
    versal_unimp_area(s, "crp", &s->mr_ps,
                        MM_PMC_CRP, MM_PMC_CRP_SIZE);
    versal_unimp_area(s, "iou-scntr", &s->mr_ps,
                        MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
    versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
                        MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE);

    qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel,
                            "sd-emmc-sel-dummy", 2);
    qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel,
                            "qspi-ospi-mux-sel-dummy", 1);
    qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr,
                            "irq-parity-imr-dummy", 1);

    gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0);
    qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0,
                                gpio_in);

    gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1);
    qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1,
                                gpio_in);

    gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0);
    qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
                                "qspi-ospi-mux-sel", 0,
                                gpio_in);

    gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0);
    qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr),
                                SYSBUS_DEVICE_GPIO_IRQ, 0,
                                gpio_in);
}

static void versal_realize(DeviceState *dev, Error **errp)
{
    Versal *s = XLNX_VERSAL(dev);
    qemu_irq pic[XLNX_VERSAL_NR_IRQS];

    versal_create_apu_cpus(s);
    versal_create_apu_gic(s, pic);
    versal_create_rpu_cpus(s);
    versal_create_uarts(s, pic);
    versal_create_canfds(s, pic);
    versal_create_usbs(s, pic);
    versal_create_gems(s, pic);
    versal_create_admas(s, pic);
    versal_create_sds(s, pic);
    versal_create_pmc_apb_irq_orgate(s, pic);
    versal_create_rtc(s, pic);
    versal_create_xrams(s, pic);
    versal_create_bbram(s, pic);
    versal_create_efuse(s, pic);
    versal_create_pmc_iou_slcr(s, pic);
    versal_create_ospi(s, pic);
    versal_create_crl(s, pic);
    versal_create_cfu(s, pic);
    versal_map_ddr(s);
    versal_unimp(s);

    /* Create the On Chip Memory (OCM).  */
    memory_region_init_ram(&s->lpd.mr_ocm, OBJECT(s), "ocm",
                           MM_OCM_SIZE, &error_fatal);

    memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
    memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
    memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
                                        &s->lpd.rpu.mr_ps_alias, 0);
}

static void versal_init(Object *obj)
{
    Versal *s = XLNX_VERSAL(obj);

    memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
    memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
    memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
    memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
                             "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
}

static Property versal_properties[] = {
    DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
                     MemoryRegion *),
    DEFINE_PROP_LINK("canbus0", Versal, lpd.iou.canbus[0],
                      TYPE_CAN_BUS, CanBusState *),
    DEFINE_PROP_LINK("canbus1", Versal, lpd.iou.canbus[1],
                      TYPE_CAN_BUS, CanBusState *),
    DEFINE_PROP_END_OF_LIST()
};

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

    dc->realize = versal_realize;
    device_class_set_props(dc, versal_properties);
    /* No VMSD since we haven't got any top-level SoC state to save.  */
}

static const TypeInfo versal_info = {
    .name = TYPE_XLNX_VERSAL,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(Versal),
    .instance_init = versal_init,
    .class_init = versal_class_init,
};

static void versal_register_types(void)
{
    type_register_static(&versal_info);
}

type_init(versal_register_types);
