/*
 * QEMU PowerPC PowerNV Proxy PHB model
 *
 * Copyright (c) 2022, IBM Corporation.
 *
 * This code is licensed under the GPL version 2 or later. See the
 * COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/visitor.h"
#include "qapi/error.h"
#include "hw/pci-host/pnv_phb.h"
#include "hw/pci-host/pnv_phb3.h"
#include "hw/pci-host/pnv_phb4.h"
#include "hw/ppc/pnv.h"
#include "hw/qdev-properties.h"
#include "qom/object.h"
#include "sysemu/sysemu.h"


/*
 * Set the QOM parent and parent bus of an object child. If the device
 * state associated with the child has an id, use it as QOM id.
 * Otherwise use object_typename[index] as QOM id.
 *
 * This helper does both operations at the same time because setting
 * a new QOM child will erase the bus parent of the device. This happens
 * because object_unparent() will call object_property_del_child(),
 * which in turn calls the property release callback prop->release if
 * it's defined. In our case this callback is set to
 * object_finalize_child_property(), which was assigned during the
 * first object_property_add_child() call. This callback will end up
 * calling device_unparent(), and this function removes the device
 * from its parent bus.
 *
 * The QOM and parent bus to be set aren´t necessarily related, so
 * let's receive both as arguments.
 */
static bool pnv_parent_fixup(Object *parent, BusState *parent_bus,
                             Object *child, int index,
                             Error **errp)
{
    g_autofree char *default_id =
        g_strdup_printf("%s[%d]", object_get_typename(child), index);
    const char *dev_id = DEVICE(child)->id;

    if (child->parent == parent) {
        return true;
    }

    object_ref(child);
    object_unparent(child);
    object_property_add_child(parent, dev_id ? dev_id : default_id, child);
    object_unref(child);

    if (!qdev_set_parent_bus(DEVICE(child), parent_bus, errp)) {
        return false;
    }

    return true;
}

static Object *pnv_phb_user_get_parent(PnvChip *chip, PnvPHB *phb, Error **errp)
{
    if (phb->version == 3) {
        return OBJECT(pnv_chip_add_phb(chip, phb));
    } else {
        return OBJECT(pnv_pec_add_phb(chip, phb, errp));
    }
}

/*
 * User created devices won't have the initial setup that default
 * devices have. This setup consists of assigning a parent device
 * (chip for PHB3, PEC for PHB4/5) that will be the QOM/bus parent
 * of the PHB.
 */
static bool pnv_phb_user_device_init(PnvPHB *phb, Error **errp)
{
    PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
    PnvChip *chip = pnv_get_chip(pnv, phb->chip_id);
    Object *parent = NULL;

    if (!chip) {
        error_setg(errp, "invalid chip id: %d", phb->chip_id);
        return false;
    }

    parent = pnv_phb_user_get_parent(chip, phb, errp);
    if (!parent) {
        return false;
    }

    /*
     * Reparent user created devices to the chip to build
     * correctly the device tree. pnv_xscom_dt() needs every
     * PHB to be a child of the chip to build the DT correctly.
     */
    if (!pnv_parent_fixup(parent, qdev_get_parent_bus(DEVICE(chip)),
                          OBJECT(phb), phb->phb_id, errp)) {
        return false;
    }

    return true;
}

static void pnv_phb_realize(DeviceState *dev, Error **errp)
{
    PnvPHB *phb = PNV_PHB(dev);
    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
    g_autofree char *phb_typename = NULL;

    if (!phb->version) {
        error_setg(errp, "version not specified");
        return;
    }

    switch (phb->version) {
    case 3:
        phb_typename = g_strdup(TYPE_PNV_PHB3);
        break;
    case 4:
        phb_typename = g_strdup(TYPE_PNV_PHB4);
        break;
    case 5:
        phb_typename = g_strdup(TYPE_PNV_PHB5);
        break;
    default:
        g_assert_not_reached();
    }

    phb->backend = object_new(phb_typename);
    object_property_add_child(OBJECT(dev), "phb-backend", phb->backend);

    /* Passthrough child device properties to the proxy device */
    object_property_set_uint(phb->backend, "index", phb->phb_id, errp);
    object_property_set_uint(phb->backend, "chip-id", phb->chip_id, errp);
    object_property_set_link(phb->backend, "phb-base", OBJECT(phb), errp);

    /*
     * Handle user created devices. User devices will not have a
     * pointer to a chip (PHB3) and a PEC (PHB4/5).
     */
    if (!phb->chip && !phb->pec) {
        if (!pnv_phb_user_device_init(phb, errp)) {
            return;
        }
    }

    if (phb->version == 3) {
        object_property_set_link(phb->backend, "chip",
                                 OBJECT(phb->chip), errp);
    } else {
        object_property_set_link(phb->backend, "pec", OBJECT(phb->pec), errp);
    }

    if (!qdev_realize(DEVICE(phb->backend), NULL, errp)) {
        return;
    }

    if (phb->version == 3) {
        pnv_phb3_bus_init(dev, PNV_PHB3(phb->backend));
    } else {
        pnv_phb4_bus_init(dev, PNV_PHB4(phb->backend));
    }

    if (defaults_enabled()) {
        PCIDevice *root = pci_new(PCI_DEVFN(0, 0), TYPE_PNV_PHB_ROOT_PORT);

        pci_realize_and_unref(root, pci->bus, errp);
    }
}

static const char *pnv_phb_root_bus_path(PCIHostState *host_bridge,
                                         PCIBus *rootbus)
{
    PnvPHB *phb = PNV_PHB(host_bridge);

    snprintf(phb->bus_path, sizeof(phb->bus_path), "00%02x:%02x",
             phb->chip_id, phb->phb_id);
    return phb->bus_path;
}

static Property pnv_phb_properties[] = {
    DEFINE_PROP_UINT32("index", PnvPHB, phb_id, 0),
    DEFINE_PROP_UINT32("chip-id", PnvPHB, chip_id, 0),
    DEFINE_PROP_UINT32("version", PnvPHB, version, 0),

    DEFINE_PROP_LINK("chip", PnvPHB, chip, TYPE_PNV_CHIP, PnvChip *),

    DEFINE_PROP_LINK("pec", PnvPHB, pec, TYPE_PNV_PHB4_PEC,
                     PnvPhb4PecState *),

    DEFINE_PROP_END_OF_LIST(),
};

static void pnv_phb_class_init(ObjectClass *klass, void *data)
{
    PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    hc->root_bus_path = pnv_phb_root_bus_path;
    dc->realize = pnv_phb_realize;
    device_class_set_props(dc, pnv_phb_properties);
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    dc->user_creatable = true;
}

static void pnv_phb_root_port_reset_hold(Object *obj, ResetType type)
{
    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(obj);
    PnvPHBRootPort *phb_rp = PNV_PHB_ROOT_PORT(obj);
    PCIDevice *d = PCI_DEVICE(obj);
    uint8_t *conf = d->config;

    if (rpc->parent_phases.hold) {
        rpc->parent_phases.hold(obj, type);
    }

    if (phb_rp->version == 3) {
        return;
    }

    /* PHB4 and later requires these extra reset steps */
    pci_byte_test_and_set_mask(conf + PCI_IO_BASE,
                               PCI_IO_RANGE_MASK & 0xff);
    pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
                                 PCI_IO_RANGE_MASK & 0xff);
    pci_set_word(conf + PCI_MEMORY_BASE, 0);
    pci_set_word(conf + PCI_MEMORY_LIMIT, 0xfff0);
    pci_set_word(conf + PCI_PREF_MEMORY_BASE, 0x1);
    pci_set_word(conf + PCI_PREF_MEMORY_LIMIT, 0xfff1);
    pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0x1); /* Hack */
    pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0xffffffff);
    pci_config_set_interrupt_pin(conf, 0);
}

static void pnv_phb_root_port_realize(DeviceState *dev, Error **errp)
{
    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
    PnvPHBRootPort *phb_rp = PNV_PHB_ROOT_PORT(dev);
    PCIBus *bus = PCI_BUS(qdev_get_parent_bus(dev));
    PCIDevice *pci = PCI_DEVICE(dev);
    uint16_t device_id = 0;
    Error *local_err = NULL;
    int chip_id, index;

    /*
     * 'index' will be used both as a PCIE slot value and to calculate
     * QOM id. 'chip_id' is going to be used as PCIE chassis for the
     * root port.
     */
    chip_id = object_property_get_int(OBJECT(bus), "chip-id", &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }
    index = object_property_get_int(OBJECT(bus), "phb-id", &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    /* Set unique chassis/slot values for the root port */
    qdev_prop_set_uint8(dev, "chassis", chip_id);
    qdev_prop_set_uint16(dev, "slot", index);

    /*
     * User created root ports are QOM parented to one of
     * the peripheral containers but it's already at the right
     * parent bus. Change the QOM parent to be the same as the
     * parent bus it's already assigned to.
     */
    if (!pnv_parent_fixup(OBJECT(bus), BUS(bus), OBJECT(dev),
                          index, errp)) {
        return;
    }

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

    switch (phb_rp->version) {
    case 3:
        device_id = PNV_PHB3_DEVICE_ID;
        break;
    case 4:
        device_id = PNV_PHB4_DEVICE_ID;
        break;
    case 5:
        device_id = PNV_PHB5_DEVICE_ID;
        break;
    default:
        g_assert_not_reached();
    }

    pci_config_set_device_id(pci->config, device_id);
    pci_config_set_interrupt_pin(pci->config, 0);
}

static Property pnv_phb_root_port_properties[] = {
    DEFINE_PROP_UINT32("version", PnvPHBRootPort, version, 0),

    DEFINE_PROP_END_OF_LIST(),
};

static void pnv_phb_root_port_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ResettableClass *rc = RESETTABLE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);

    dc->desc     = "IBM PHB PCIE Root Port";

    device_class_set_props(dc, pnv_phb_root_port_properties);
    device_class_set_parent_realize(dc, pnv_phb_root_port_realize,
                                    &rpc->parent_realize);
    resettable_class_set_parent_phases(rc, NULL, pnv_phb_root_port_reset_hold,
                                       NULL, &rpc->parent_phases);
    dc->user_creatable = true;

    k->vendor_id = PCI_VENDOR_ID_IBM;
    /* device_id will be written during realize() */
    k->device_id = 0;
    k->revision  = 0;

    rpc->exp_offset = 0x48;
    rpc->aer_offset = 0x100;
}

static const TypeInfo pnv_phb_type_info = {
    .name          = TYPE_PNV_PHB,
    .parent        = TYPE_PCIE_HOST_BRIDGE,
    .instance_size = sizeof(PnvPHB),
    .class_init    = pnv_phb_class_init,
};

static const TypeInfo pnv_phb_root_port_info = {
    .name          = TYPE_PNV_PHB_ROOT_PORT,
    .parent        = TYPE_PCIE_ROOT_PORT,
    .instance_size = sizeof(PnvPHBRootPort),
    .class_init    = pnv_phb_root_port_class_init,
};

static void pnv_phb_register_types(void)
{
    type_register_static(&pnv_phb_type_info);
    type_register_static(&pnv_phb_root_port_info);
}

type_init(pnv_phb_register_types)
