/*
 * microvm device tree support
 *
 * This generates an device tree for microvm and exports it via fw_cfg
 * as "etc/fdt" to the firmware (edk2 specifically).
 *
 * The use case is to allow edk2 find the pcie ecam and the virtio
 * devices, without adding an ACPI parser, reusing the fdt parser
 * which is needed anyway for the arm platform.
 *
 * Note 1: The device tree is incomplete. CPUs and memory is missing
 *         for example, those can be detected using other fw_cfg files.
 *         Also pci ecam irq routing is not there, edk2 doesn't use
 *         interrupts.
 *
 * Note 2: This is for firmware only. OSes should use the more
 *         complete ACPI tables for hardware discovery.
 *
 * ----------------------------------------------------------------------
 *
 * 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 "qemu/cutils.h"
#include "sysemu/device_tree.h"
#include "hw/char/serial.h"
#include "hw/i386/fw_cfg.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/sysbus.h"
#include "hw/virtio/virtio-mmio.h"
#include "hw/usb/xhci.h"

#include "microvm-dt.h"

static bool debug;

static void dt_add_microvm_irq(MicrovmMachineState *mms,
                               const char *nodename, uint32_t irq)
{
    int index = 0;

    if (irq >= IO_APIC_SECONDARY_IRQBASE) {
        irq -= IO_APIC_SECONDARY_IRQBASE;
        index++;
    }

    qemu_fdt_setprop_cell(mms->fdt, nodename, "interrupt-parent",
                          mms->ioapic_phandle[index]);
    qemu_fdt_setprop_cells(mms->fdt, nodename, "interrupts", irq, 0);
}

static void dt_add_virtio(MicrovmMachineState *mms, VirtIOMMIOProxy *mmio)
{
    SysBusDevice *dev = SYS_BUS_DEVICE(mmio);
    VirtioBusState *mmio_virtio_bus = &mmio->bus;
    BusState *mmio_bus = &mmio_virtio_bus->parent_obj;
    char *nodename;

    if (QTAILQ_EMPTY(&mmio_bus->children)) {
        return;
    }

    hwaddr base = dev->mmio[0].addr;
    hwaddr size = 512;
    unsigned index = (base - VIRTIO_MMIO_BASE) / size;
    uint32_t irq = mms->virtio_irq_base + index;

    nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
    qemu_fdt_add_subnode(mms->fdt, nodename);
    qemu_fdt_setprop_string(mms->fdt, nodename, "compatible", "virtio,mmio");
    qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
    qemu_fdt_setprop(mms->fdt, nodename, "dma-coherent", NULL, 0);
    dt_add_microvm_irq(mms, nodename, irq);
    g_free(nodename);
}

static void dt_add_xhci(MicrovmMachineState *mms)
{
    const char compat[] = "generic-xhci";
    uint32_t irq = MICROVM_XHCI_IRQ;
    hwaddr base = MICROVM_XHCI_BASE;
    hwaddr size = XHCI_LEN_REGS;
    char *nodename;

    nodename = g_strdup_printf("/usb@%" PRIx64, base);
    qemu_fdt_add_subnode(mms->fdt, nodename);
    qemu_fdt_setprop(mms->fdt, nodename, "compatible", compat, sizeof(compat));
    qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
    qemu_fdt_setprop(mms->fdt, nodename, "dma-coherent", NULL, 0);
    dt_add_microvm_irq(mms, nodename, irq);
    g_free(nodename);
}

static void dt_add_pcie(MicrovmMachineState *mms)
{
    hwaddr base = PCIE_MMIO_BASE;
    int nr_pcie_buses;
    char *nodename;

    nodename = g_strdup_printf("/pcie@%" PRIx64, base);
    qemu_fdt_add_subnode(mms->fdt, nodename);
    qemu_fdt_setprop_string(mms->fdt, nodename,
                            "compatible", "pci-host-ecam-generic");
    qemu_fdt_setprop_string(mms->fdt, nodename, "device_type", "pci");
    qemu_fdt_setprop_cell(mms->fdt, nodename, "#address-cells", 3);
    qemu_fdt_setprop_cell(mms->fdt, nodename, "#size-cells", 2);
    qemu_fdt_setprop_cell(mms->fdt, nodename, "linux,pci-domain", 0);
    qemu_fdt_setprop(mms->fdt, nodename, "dma-coherent", NULL, 0);

    qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg",
                                 2, PCIE_ECAM_BASE, 2, PCIE_ECAM_SIZE);
    if (mms->gpex.mmio64.size) {
        qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "ranges",

                                     1, FDT_PCI_RANGE_MMIO,
                                     2, mms->gpex.mmio32.base,
                                     2, mms->gpex.mmio32.base,
                                     2, mms->gpex.mmio32.size,

                                     1, FDT_PCI_RANGE_MMIO_64BIT,
                                     2, mms->gpex.mmio64.base,
                                     2, mms->gpex.mmio64.base,
                                     2, mms->gpex.mmio64.size);
    } else {
        qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "ranges",

                                     1, FDT_PCI_RANGE_MMIO,
                                     2, mms->gpex.mmio32.base,
                                     2, mms->gpex.mmio32.base,
                                     2, mms->gpex.mmio32.size);
    }

    nr_pcie_buses = PCIE_ECAM_SIZE / PCIE_MMCFG_SIZE_MIN;
    qemu_fdt_setprop_cells(mms->fdt, nodename, "bus-range", 0,
                           nr_pcie_buses - 1);

    g_free(nodename);
}

static void dt_add_ioapic(MicrovmMachineState *mms, SysBusDevice *dev)
{
    hwaddr base = dev->mmio[0].addr;
    char *nodename;
    uint32_t ph;
    int index;

    switch (base) {
    case IO_APIC_DEFAULT_ADDRESS:
        index = 0;
        break;
    case IO_APIC_SECONDARY_ADDRESS:
        index = 1;
        break;
    default:
        fprintf(stderr, "unknown ioapic @ %" PRIx64 "\n", base);
        return;
    }

    nodename = g_strdup_printf("/ioapic%d@%" PRIx64, index + 1, base);
    qemu_fdt_add_subnode(mms->fdt, nodename);
    qemu_fdt_setprop_string(mms->fdt, nodename,
                            "compatible", "intel,ce4100-ioapic");
    qemu_fdt_setprop(mms->fdt, nodename, "interrupt-controller", NULL, 0);
    qemu_fdt_setprop_cell(mms->fdt, nodename, "#interrupt-cells", 0x2);
    qemu_fdt_setprop_cell(mms->fdt, nodename, "#address-cells", 0x2);
    qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg",
                                 2, base, 2, 0x1000);

    ph = qemu_fdt_alloc_phandle(mms->fdt);
    qemu_fdt_setprop_cell(mms->fdt, nodename, "phandle", ph);
    qemu_fdt_setprop_cell(mms->fdt, nodename, "linux,phandle", ph);
    mms->ioapic_phandle[index] = ph;

    g_free(nodename);
}

static void dt_add_isa_serial(MicrovmMachineState *mms, ISADevice *dev)
{
    const char compat[] = "ns16550";
    uint32_t irq = object_property_get_int(OBJECT(dev), "irq", NULL);
    hwaddr base = object_property_get_int(OBJECT(dev), "iobase", NULL);
    hwaddr size = 8;
    char *nodename;

    nodename = g_strdup_printf("/serial@%" PRIx64, base);
    qemu_fdt_add_subnode(mms->fdt, nodename);
    qemu_fdt_setprop(mms->fdt, nodename, "compatible", compat, sizeof(compat));
    qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
    dt_add_microvm_irq(mms, nodename, irq);

    if (base == 0x3f8 /* com1 */) {
        qemu_fdt_setprop_string(mms->fdt, "/chosen", "stdout-path", nodename);
    }

    g_free(nodename);
}

static void dt_add_isa_rtc(MicrovmMachineState *mms, ISADevice *dev)
{
    const char compat[] = "motorola,mc146818";
    uint32_t irq = RTC_ISA_IRQ;
    hwaddr base = RTC_ISA_BASE;
    hwaddr size = 8;
    char *nodename;

    nodename = g_strdup_printf("/rtc@%" PRIx64, base);
    qemu_fdt_add_subnode(mms->fdt, nodename);
    qemu_fdt_setprop(mms->fdt, nodename, "compatible", compat, sizeof(compat));
    qemu_fdt_setprop_sized_cells(mms->fdt, nodename, "reg", 2, base, 2, size);
    dt_add_microvm_irq(mms, nodename, irq);
    g_free(nodename);
}

static void dt_setup_isa_bus(MicrovmMachineState *mms, DeviceState *bridge)
{
    BusState *bus = qdev_get_child_bus(bridge, "isa.0");
    BusChild *kid;
    Object *obj;

    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        /* serial */
        obj = object_dynamic_cast(OBJECT(dev), TYPE_ISA_SERIAL);
        if (obj) {
            dt_add_isa_serial(mms, ISA_DEVICE(obj));
            continue;
        }

        /* rtc */
        obj = object_dynamic_cast(OBJECT(dev), TYPE_MC146818_RTC);
        if (obj) {
            dt_add_isa_rtc(mms, ISA_DEVICE(obj));
            continue;
        }

        if (debug) {
            fprintf(stderr, "%s: unhandled: %s\n", __func__,
                    object_get_typename(OBJECT(dev)));
        }
    }
}

static void dt_setup_sys_bus(MicrovmMachineState *mms)
{
    BusState *bus;
    BusChild *kid;
    Object *obj;

    /* sysbus devices */
    bus = sysbus_get_default();
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        /* ioapic */
        obj = object_dynamic_cast(OBJECT(dev), TYPE_IOAPIC);
        if (obj) {
            dt_add_ioapic(mms, SYS_BUS_DEVICE(obj));
            continue;
        }
    }

    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;

        /* virtio */
        obj = object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MMIO);
        if (obj) {
            dt_add_virtio(mms, VIRTIO_MMIO(obj));
            continue;
        }

        /* xhci */
        obj = object_dynamic_cast(OBJECT(dev), TYPE_XHCI_SYSBUS);
        if (obj) {
            dt_add_xhci(mms);
            continue;
        }

        /* pcie */
        obj = object_dynamic_cast(OBJECT(dev), TYPE_GPEX_HOST);
        if (obj) {
            dt_add_pcie(mms);
            continue;
        }

        /* isa */
        obj = object_dynamic_cast(OBJECT(dev), "isabus-bridge");
        if (obj) {
            dt_setup_isa_bus(mms, DEVICE(obj));
            continue;
        }

        if (debug) {
            obj = object_dynamic_cast(OBJECT(dev), TYPE_IOAPIC);
            if (obj) {
                /* ioapic already added in first pass */
                continue;
            }
            fprintf(stderr, "%s: unhandled: %s\n", __func__,
                    object_get_typename(OBJECT(dev)));
        }
    }
}

void dt_setup_microvm(MicrovmMachineState *mms)
{
    X86MachineState *x86ms = X86_MACHINE(mms);
    int size = 0;

    mms->fdt = create_device_tree(&size);

    /* root node */
    qemu_fdt_setprop_string(mms->fdt, "/", "compatible", "linux,microvm");
    qemu_fdt_setprop_cell(mms->fdt, "/", "#address-cells", 0x2);
    qemu_fdt_setprop_cell(mms->fdt, "/", "#size-cells", 0x2);

    qemu_fdt_add_subnode(mms->fdt, "/chosen");
    dt_setup_sys_bus(mms);

    /* add to fw_cfg */
    if (debug) {
        fprintf(stderr, "%s: add etc/fdt to fw_cfg\n", __func__);
    }
    fw_cfg_add_file(x86ms->fw_cfg, "etc/fdt", mms->fdt, size);

    if (debug) {
        fprintf(stderr, "%s: writing microvm.fdt\n", __func__);
        if (!g_file_set_contents("microvm.fdt", mms->fdt, size, NULL)) {
            fprintf(stderr, "%s: writing microvm.fdt failed\n", __func__);
            return;
        }
        int ret = system("dtc -I dtb -O dts microvm.fdt");
        if (ret != 0) {
            fprintf(stderr, "%s: oops, dtc not installed?\n", __func__);
        }
    }
}
