/*
 * ASPEED PCIe Host Controller
 *
 * Copyright (C) 2025 ASPEED Technology Inc.
 * Copyright (c) 2022 Cédric Le Goater <clg@kaod.org>
 *
 * Authors:
 *   Cédric Le Goater <clg@kaod.org>
 *   Jamin Lin <jamin_lin@aspeedtech.com>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * Based on previous work from Cédric Le Goater.
 * Modifications extend support for the ASPEED AST2600 and AST2700 platforms.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "hw/registerfields.h"
#include "hw/irq.h"
#include "hw/pci/pci_host.h"
#include "hw/pci/pcie_port.h"
#include "hw/pci-host/aspeed_pcie.h"
#include "hw/pci/msi.h"
#include "trace.h"

/*
 * PCIe Root Device
 * This device exists only on AST2600.
 */

static void aspeed_pcie_root_device_class_init(ObjectClass *klass,
                                               const void *data)
{
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);

    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
    dc->desc = "ASPEED PCIe Root Device";
    k->vendor_id = PCI_VENDOR_ID_ASPEED;
    k->device_id = 0x2600;
    k->class_id = PCI_CLASS_BRIDGE_HOST;
    k->subsystem_vendor_id = k->vendor_id;
    k->subsystem_id = k->device_id;
    k->revision = 0;

    /*
     * PCI-facing part of the host bridge,
     * not usable without the host-facing part
     */
    dc->user_creatable = false;
}

static const TypeInfo aspeed_pcie_root_device_info = {
    .name = TYPE_ASPEED_PCIE_ROOT_DEVICE,
    .parent = TYPE_PCI_DEVICE,
    .instance_size = sizeof(AspeedPCIERootDeviceState),
    .class_init = aspeed_pcie_root_device_class_init,
    .interfaces = (const InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

/*
 * PCIe Root Port
 */

static void aspeed_pcie_root_port_class_init(ObjectClass *klass,
                                             const void *data)
{
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);

    dc->desc = "ASPEED PCIe Root Port";
    k->vendor_id = PCI_VENDOR_ID_ASPEED;
    k->device_id = 0x1150;
    dc->user_creatable = true;

    rpc->aer_offset = 0x100;
}

static const TypeInfo aspeed_pcie_root_port_info = {
    .name = TYPE_ASPEED_PCIE_ROOT_PORT,
    .parent = TYPE_PCIE_ROOT_PORT,
    .instance_size = sizeof(AspeedPCIERootPortState),
    .class_init = aspeed_pcie_root_port_class_init,
};

/*
 * PCIe Root Complex (RC)
 */

#define ASPEED_PCIE_CFG_RC_MAX_MSI 64

static void aspeed_pcie_rc_set_irq(void *opaque, int irq, int level)
{
    AspeedPCIERcState *rc = (AspeedPCIERcState *) opaque;
    AspeedPCIECfgState *cfg =
        container_of(rc, AspeedPCIECfgState, rc);
    bool intx;

    assert(irq < PCI_NUM_PINS);

    if (level) {
        cfg->regs[cfg->rc_regs->int_sts_reg] |= BIT(irq);
    } else {
        cfg->regs[cfg->rc_regs->int_sts_reg] &= ~BIT(irq);
    }

    intx = !!(cfg->regs[cfg->rc_regs->int_sts_reg] &
              cfg->regs[cfg->rc_regs->int_en_reg]);
    trace_aspeed_pcie_rc_intx_set_irq(cfg->id, irq, intx);
    qemu_set_irq(rc->irq, intx);
}

static int aspeed_pcie_rc_map_irq(PCIDevice *pci_dev, int irq_num)
{
    return irq_num % PCI_NUM_PINS;
}

static void aspeed_pcie_rc_msi_notify(AspeedPCIERcState *rc, uint64_t data)
{
    AspeedPCIECfgState *cfg =
           container_of(rc, AspeedPCIECfgState, rc);
    uint32_t reg;

    /* Written data is the HW IRQ number */
    assert(data < ASPEED_PCIE_CFG_RC_MAX_MSI);

    reg = (data < 32) ?
            cfg->rc_regs->msi_sts0_reg : cfg->rc_regs->msi_sts1_reg;
    cfg->regs[reg] |= BIT(data % 32);

    trace_aspeed_pcie_rc_msi_set_irq(cfg->id, data, 1);
    qemu_set_irq(rc->irq, 1);
}

static void aspeed_pcie_rc_msi_write(void *opaque, hwaddr addr, uint64_t data,
                                     unsigned int size)
{
    AspeedPCIERcState *rc = ASPEED_PCIE_RC(opaque);
    AspeedPCIECfgState *cfg =
           container_of(rc, AspeedPCIECfgState, rc);

    trace_aspeed_pcie_rc_msi_notify(cfg->id, addr + rc->msi_addr, data);
    aspeed_pcie_rc_msi_notify(rc, data);
}

static const MemoryRegionOps aspeed_pcie_rc_msi_ops = {
    .write = aspeed_pcie_rc_msi_write,
    .read = NULL,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

static AddressSpace *aspeed_pcie_rc_get_as(PCIBus *bus, void *opaque, int devfn)
{
    AspeedPCIERcState *rc = ASPEED_PCIE_RC(opaque);
    return &rc->iommu_as;
}

static const PCIIOMMUOps aspeed_pcie_rc_iommu_ops = {
    .get_address_space = aspeed_pcie_rc_get_as,
};

static void aspeed_pcie_rc_realize(DeviceState *dev, Error **errp)
{
    PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
    AspeedPCIERcState *rc = ASPEED_PCIE_RC(dev);
    AspeedPCIECfgState *cfg =
           container_of(rc, AspeedPCIECfgState, rc);
    PCIHostState *pci = PCI_HOST_BRIDGE(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    g_autofree char *ioport_window_name = NULL;
    g_autofree char *mmio_window_name = NULL;
    g_autofree char *iommu_root_name = NULL;
    g_autofree char *dram_alias_name = NULL;
    g_autofree char *root_bus_name = NULL;

    /* PCI configuration space */
    pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
    sysbus_init_mmio(sbd, &pex->mmio);

    /* MMIO and IO region */
    memory_region_init(&rc->mmio, OBJECT(rc), "mmio", UINT64_MAX);
    memory_region_init(&rc->io, OBJECT(rc), "io", 0x10000);

    mmio_window_name = g_strdup_printf("pcie.%d.mmio_window", cfg->id);
    memory_region_init_io(&rc->mmio_window, OBJECT(rc), &unassigned_io_ops,
                          OBJECT(rc), mmio_window_name, UINT64_MAX);
    ioport_window_name = g_strdup_printf("pcie.%d.ioport_window", cfg->id);
    memory_region_init_io(&rc->io_window, OBJECT(rc), &unassigned_io_ops,
                          OBJECT(rc), ioport_window_name, 0x10000);

    memory_region_add_subregion(&rc->mmio_window, 0, &rc->mmio);
    memory_region_add_subregion(&rc->io_window, 0, &rc->io);
    sysbus_init_mmio(sbd, &rc->mmio_window);
    sysbus_init_mmio(sbd, &rc->io_window);

    sysbus_init_irq(sbd, &rc->irq);
    root_bus_name = g_strdup_printf("pcie.rc%d", cfg->id);
    pci->bus = pci_register_root_bus(dev, root_bus_name,
                                     aspeed_pcie_rc_set_irq,
                                     aspeed_pcie_rc_map_irq, rc, &rc->mmio,
                                     &rc->io, 0, 4, TYPE_PCIE_BUS);
    pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;

   /*
    * PCIe memory view setup
    *
    * Background:
    * - On AST2700, all Root Complexes use the same MSI address. This MSI
    *   address is not normal system RAM - it is a PCI system memory address.
    *   If we map the MSI/MSI-X window into real system memory, a write from
    *   one EP can be seen by all RCs and wrongly trigger interrupts on them.
    *
    * Design:
    * - MSI/MSI-X here is just a placeholder address so RC and EP can talk.
    *   We make a separate MMIO space (iommu_root) for the MSI window so the
    *   writes stay local to each RC.
    *
    * DMA:
    * - EPs still need access to real system memory for DMA. We add a DRAM
    *   alias in the PCI space so DMA works as expected.
    */
    iommu_root_name = g_strdup_printf("pcie.%d.iommu_root", cfg->id);
    memory_region_init(&rc->iommu_root, OBJECT(rc), iommu_root_name,
                       UINT64_MAX);
    address_space_init(&rc->iommu_as, &rc->iommu_root, iommu_root_name);
    /* setup MSI */
    memory_region_init_io(&rc->msi_window, OBJECT(rc),
                          &aspeed_pcie_rc_msi_ops, rc,
                          "msi_window", 4);
    memory_region_add_subregion(&rc->iommu_root, rc->msi_addr,
                                &rc->msi_window);
    /* setup DRAM for DMA */
    assert(rc->dram_mr != NULL);
    dram_alias_name = g_strdup_printf("pcie.%d.dram_alias", cfg->id);
    memory_region_init_alias(&rc->dram_alias, OBJECT(rc), dram_alias_name,
                             rc->dram_mr, 0, memory_region_size(rc->dram_mr));
    memory_region_add_subregion(&rc->iommu_root, rc->dram_base,
                                &rc->dram_alias);
    pci_setup_iommu(pci->bus, &aspeed_pcie_rc_iommu_ops, rc);

    /* setup root device */
    if (rc->has_rd) {
        object_initialize_child(OBJECT(rc), "root_device", &rc->root_device,
                                TYPE_ASPEED_PCIE_ROOT_DEVICE);
        qdev_prop_set_int32(DEVICE(&rc->root_device), "addr",
                            PCI_DEVFN(0, 0));
        qdev_prop_set_bit(DEVICE(&rc->root_device), "multifunction", false);
        if (!qdev_realize(DEVICE(&rc->root_device), BUS(pci->bus), errp)) {
            return;
        }
    }

    /* setup root port */
    qdev_prop_set_int32(DEVICE(&rc->root_port), "addr", rc->rp_addr);
    qdev_prop_set_uint16(DEVICE(&rc->root_port), "chassis", cfg->id);
    if (!qdev_realize(DEVICE(&rc->root_port), BUS(pci->bus), errp)) {
        return;
    }
}

static const char *aspeed_pcie_rc_root_bus_path(PCIHostState *host_bridge,
                                                PCIBus *rootbus)
{
    AspeedPCIERcState *rc = ASPEED_PCIE_RC(host_bridge);
    AspeedPCIECfgState *cfg =
           container_of(rc, AspeedPCIECfgState, rc);

    snprintf(rc->name, sizeof(rc->name), "%04x:%02x", cfg->id, rc->bus_nr);

    return rc->name;
}

static void aspeed_pcie_rc_instance_init(Object *obj)
{
    AspeedPCIERcState *rc = ASPEED_PCIE_RC(obj);
    AspeedPCIERootPortState *root_port = &rc->root_port;

    object_initialize_child(obj, "root_port", root_port,
                            TYPE_ASPEED_PCIE_ROOT_PORT);
}

static const Property aspeed_pcie_rc_props[] = {
    DEFINE_PROP_UINT32("bus-nr", AspeedPCIERcState, bus_nr, 0),
    DEFINE_PROP_BOOL("has-rd", AspeedPCIERcState, has_rd, 0),
    DEFINE_PROP_UINT32("rp-addr", AspeedPCIERcState, rp_addr, 0),
    DEFINE_PROP_UINT32("msi-addr", AspeedPCIERcState, msi_addr, 0),
    DEFINE_PROP_UINT64("dram-base", AspeedPCIERcState, dram_base, 0),
    DEFINE_PROP_LINK("dram", AspeedPCIERcState, dram_mr, TYPE_MEMORY_REGION,
                     MemoryRegion *),
};

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

    dc->desc = "ASPEED PCIe RC";
    dc->realize = aspeed_pcie_rc_realize;
    dc->fw_name = "pci";
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);

    hc->root_bus_path = aspeed_pcie_rc_root_bus_path;
    device_class_set_props(dc, aspeed_pcie_rc_props);

    msi_nonbroken = true;
}

static const TypeInfo aspeed_pcie_rc_info = {
    .name = TYPE_ASPEED_PCIE_RC,
    .parent = TYPE_PCIE_HOST_BRIDGE,
    .instance_size = sizeof(AspeedPCIERcState),
    .instance_init = aspeed_pcie_rc_instance_init,
    .class_init = aspeed_pcie_rc_class_init,
};

/*
 * PCIe Config
 *
 * AHB to PCIe Bus Bridge (H2X)
 *
 * On the AST2600:
 * NOTE: rc_l is not supported by this model.
 * - Registers 0x00 - 0x7F are shared by both PCIe0 (rc_l) and PCIe1 (rc_h).
 * - Registers 0x80 - 0xBF are specific to PCIe0.
 * - Registers 0xC0 - 0xFF are specific to PCIe1.
 *
 * On the AST2700:
 * - The register range 0x00 - 0xFF is assigned to a single PCIe configuration.
 * - There are three PCIe Root Complexes (RCs), each with its own dedicated H2X
 *   register set of size 0x100 (covering offsets 0x00 to 0xFF).
 */

/* AST2600 */
REG32(H2X_CTRL,             0x00)
    FIELD(H2X_CTRL, CLEAR_RX, 4, 1)
REG32(H2X_TX_CLEAR,         0x08)
    FIELD(H2X_TX_CLEAR, IDLE, 0, 1)
REG32(H2X_RDATA,            0x0C)
REG32(H2X_TX_DESC0,         0x10)
REG32(H2X_TX_DESC1,         0x14)
REG32(H2X_TX_DESC2,         0x18)
REG32(H2X_TX_DESC3,         0x1C)
REG32(H2X_TX_DATA,          0x20)
REG32(H2X_TX_STS,           0x24)
    FIELD(H2X_TX_STS, IDLE, 31, 1)
    FIELD(H2X_TX_STS, RC_L_TX_COMP, 24, 1)
    FIELD(H2X_TX_STS, RC_H_TX_COMP, 25, 1)
    FIELD(H2X_TX_STS, TRIG, 0, 1)
REG32(H2X_RC_H_CTRL,        0xC0)
REG32(H2X_RC_H_INT_EN,      0xC4)
REG32(H2X_RC_H_INT_STS,     0xC8)
    SHARED_FIELD(H2X_RC_INT_INTDONE, 4, 1)
    SHARED_FIELD(H2X_RC_INT_INTX, 0, 4)
REG32(H2X_RC_H_RDATA,       0xCC)
REG32(H2X_RC_H_MSI_EN0,     0xE0)
REG32(H2X_RC_H_MSI_EN1,     0xE4)
REG32(H2X_RC_H_MSI_STS0,    0xE8)
REG32(H2X_RC_H_MSI_STS1,    0xEC)

/* AST2700 */
REG32(H2X_CFGE_INT_STS,         0x08)
    FIELD(H2X_CFGE_INT_STS, TX_IDEL, 0, 1)
    FIELD(H2X_CFGE_INT_STS, RX_BUSY, 1, 1)
REG32(H2X_CFGI_TLP,         0x20)
    FIELD(H2X_CFGI_TLP, ADDR, 0, 16)
    FIELD(H2X_CFGI_TLP, BEN, 16, 4)
    FIELD(H2X_CFGI_TLP, WR, 20, 1)
REG32(H2X_CFGI_WDATA,       0x24)
REG32(H2X_CFGI_CTRL,        0x28)
    FIELD(H2X_CFGI_CTRL, FIRE, 0, 1)
REG32(H2X_CFGI_RDATA,       0x2C)
REG32(H2X_CFGE_TLP1,        0x30)
REG32(H2X_CFGE_TLPN,        0x34)
REG32(H2X_CFGE_CTRL,        0x38)
    FIELD(H2X_CFGE_CTRL, FIRE, 0, 1)
REG32(H2X_CFGE_RDATA,       0x3C)
REG32(H2X_INT_EN,          0x40)
REG32(H2X_INT_STS,         0x48)
    FIELD(H2X_INT_STS, INTX, 0, 4)
REG32(H2X_MSI_EN0,          0x50)
REG32(H2X_MSI_EN1,          0x54)
REG32(H2X_MSI_STS0,         0x58)
REG32(H2X_MSI_STS1,         0x5C)

#define TLP_FMTTYPE_CFGRD0  0x04 /* Configuration Read  Type 0 */
#define TLP_FMTTYPE_CFGWR0  0x44 /* Configuration Write Type 0 */
#define TLP_FMTTYPE_CFGRD1  0x05 /* Configuration Read  Type 1 */
#define TLP_FMTTYPE_CFGWR1  0x45 /* Configuration Write Type 1 */

#define PCIE_CFG_FMTTYPE_MASK(x) (((x) >> 24) & 0xff)
#define PCIE_CFG_BYTE_EN(x) ((x) & 0xf)

static const AspeedPCIERegMap aspeed_regmap = {
    .rc = {
        .int_en_reg     = R_H2X_RC_H_INT_EN,
        .int_sts_reg    = R_H2X_RC_H_INT_STS,
        .msi_sts0_reg   = R_H2X_RC_H_MSI_STS0,
        .msi_sts1_reg   = R_H2X_RC_H_MSI_STS1,
    },
};

static const AspeedPCIERegMap aspeed_2700_regmap = {
    .rc = {
        .int_en_reg     = R_H2X_INT_EN,
        .int_sts_reg    = R_H2X_INT_STS,
        .msi_sts0_reg   = R_H2X_MSI_STS0,
        .msi_sts1_reg   = R_H2X_MSI_STS1,
    },
};

static uint64_t aspeed_pcie_cfg_read(void *opaque, hwaddr addr,
                                     unsigned int size)
{
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque);
    uint32_t reg = addr >> 2;
    uint32_t value = 0;

    value = s->regs[reg];

    trace_aspeed_pcie_cfg_read(s->id, addr, value);

    return value;
}

static void aspeed_pcie_cfg_translate_write(uint8_t byte_en, uint32_t *addr,
                                            uint64_t *val, int *len)
{
    uint64_t packed_val = 0;
    int first_bit = -1;
    int index = 0;
    int i;

    *len = ctpop8(byte_en);

    if (*len == 0 || *len > 4) {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid byte enable: 0x%x\n",
                      __func__, byte_en);
        return;
    }

    /* Special case: full 4-byte write must be 4-byte aligned */
    if (byte_en == 0x0f) {
        if ((*addr & 0x3) != 0) {
            qemu_log_mask(LOG_GUEST_ERROR,
                          "%s: 4-byte write not 4-byte aligned: addr=0x%x\n",
                          __func__, *addr);
            return;
        }
        *val &= 0xffffffffULL;
        return;
    }

    for (i = 0; i < 4; i++) {
        if (byte_en & (1 << i)) {
            if (first_bit < 0) {
                first_bit = i;
            }
            packed_val |= ((*val >> (i * 8)) & 0xff) << (index * 8);
            index++;
        }
    }

    *addr += first_bit;
    *val = packed_val;
}

static void aspeed_pcie_cfg_readwrite(AspeedPCIECfgState *s,
                                      const AspeedPCIECfgTxDesc *desc)
{
    AspeedPCIERcState *rc = &s->rc;
    PCIHostState *pci = NULL;
    PCIDevice *pdev = NULL;
    uint32_t cfg_addr;
    uint32_t offset;
    uint8_t byte_en;
    bool is_write;
    uint8_t devfn;
    uint64_t val;
    uint8_t bus;
    int len;

    val = ~0;
    is_write = !!(desc->desc0 & BIT(30));
    cfg_addr = desc->desc2;

    bus = (cfg_addr >> 24) & 0xff;
    devfn  = (cfg_addr >> 16) & 0xff;
    offset = cfg_addr & 0xffc;

    pci = PCI_HOST_BRIDGE(rc);

    /*
     * On the AST2600, the RC_H bus number range from 0x80 to 0xFF, with the
     * root device and root port assigned to bus 0x80 instead of the standard
     * 0x00. To allow the PCI subsystem to correctly discover devices on the
     * root bus, bus 0x80 is remapped to 0x00.
     */
    if (bus == rc->bus_nr) {
        bus = 0;
    }

    pdev = pci_find_device(pci->bus, bus, devfn);
    if (!pdev) {
        s->regs[desc->rdata_reg] = ~0;
        goto out;
    }

    switch (PCIE_CFG_FMTTYPE_MASK(desc->desc0)) {
    case TLP_FMTTYPE_CFGWR0:
    case TLP_FMTTYPE_CFGWR1:
        byte_en = PCIE_CFG_BYTE_EN(desc->desc1);
        val = desc->wdata;
        aspeed_pcie_cfg_translate_write(byte_en, &offset, &val, &len);
        pci_host_config_write_common(pdev, offset, pci_config_size(pdev),
                                     val, len);
        break;
    case TLP_FMTTYPE_CFGRD0:
    case TLP_FMTTYPE_CFGRD1:
        val = pci_host_config_read_common(pdev, offset,
                                          pci_config_size(pdev), 4);
        s->regs[desc->rdata_reg] = val;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid CFG type. DESC0=0x%x\n",
                      __func__, desc->desc0);
    }

out:
    trace_aspeed_pcie_cfg_rw(s->id, is_write ?  "write" : "read", bus, devfn,
                             cfg_addr, val);
}

static void aspeed_pcie_cfg_write(void *opaque, hwaddr addr, uint64_t data,
                                  unsigned int size)
{
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque);
    AspeedPCIECfgTxDesc desc;
    uint32_t reg = addr >> 2;
    uint32_t rc_reg;

    trace_aspeed_pcie_cfg_write(s->id, addr, data);

    switch (reg) {
    case R_H2X_CTRL:
        if (data & R_H2X_CTRL_CLEAR_RX_MASK) {
            s->regs[R_H2X_RDATA] = ~0;
        }
        break;
    case R_H2X_TX_CLEAR:
        if (data & R_H2X_TX_CLEAR_IDLE_MASK) {
            s->regs[R_H2X_TX_STS] &= ~R_H2X_TX_STS_IDLE_MASK;
        }
        break;
    case R_H2X_TX_STS:
        if (data & R_H2X_TX_STS_TRIG_MASK) {
            desc.desc0 = s->regs[R_H2X_TX_DESC0];
            desc.desc1 = s->regs[R_H2X_TX_DESC1];
            desc.desc2 = s->regs[R_H2X_TX_DESC2];
            desc.desc3 = s->regs[R_H2X_TX_DESC3];
            desc.wdata = s->regs[R_H2X_TX_DATA];
            desc.rdata_reg = R_H2X_RC_H_RDATA;
            aspeed_pcie_cfg_readwrite(s, &desc);
            rc_reg = s->rc_regs->int_sts_reg;
            s->regs[rc_reg] |= H2X_RC_INT_INTDONE_MASK;
            s->regs[R_H2X_TX_STS] |=
                BIT(R_H2X_TX_STS_RC_H_TX_COMP_SHIFT);
            s->regs[R_H2X_TX_STS] |= R_H2X_TX_STS_IDLE_MASK;
        }
        break;
    /* preserve INTx status */
    case R_H2X_RC_H_INT_STS:
        if (data & H2X_RC_INT_INTDONE_MASK) {
            s->regs[R_H2X_TX_STS] &= ~R_H2X_TX_STS_RC_H_TX_COMP_MASK;
        }
        s->regs[reg] &= ~data | H2X_RC_INT_INTX_MASK;
        break;
    /*
     * These status registers are used for notify sources ISR are executed.
     * If one source ISR is executed, it will clear one bit.
     * If it clear all bits, it means to initialize this register status
     * rather than sources ISR are executed.
     */
    case R_H2X_RC_H_MSI_STS0:
    case R_H2X_RC_H_MSI_STS1:
        if (data == 0) {
            return ;
        }

        s->regs[reg] &= ~data;
        if (data == 0xffffffff) {
            return;
        }

        if (!s->regs[R_H2X_RC_H_MSI_STS0] &&
            !s->regs[R_H2X_RC_H_MSI_STS1]) {
            trace_aspeed_pcie_rc_msi_clear_irq(s->id, 0);
            qemu_set_irq(s->rc.irq, 0);
        }
        break;
    default:
        s->regs[reg] = data;
        break;
    }
}

static const MemoryRegionOps aspeed_pcie_cfg_ops = {
    .read = aspeed_pcie_cfg_read,
    .write = aspeed_pcie_cfg_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void aspeed_pcie_cfg_instance_init(Object *obj)
{
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(obj);

    object_initialize_child(obj, "rc", &s->rc, TYPE_ASPEED_PCIE_RC);
    object_property_add_alias(obj, "dram", OBJECT(&s->rc), "dram");
    object_property_add_alias(obj, "dram-base", OBJECT(&s->rc), "dram-base");

    return;
}

static void aspeed_pcie_cfg_reset(DeviceState *dev)
{
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev);
    AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s);

    memset(s->regs, 0, apc->nr_regs << 2);
    memset(s->tlpn_fifo, 0, sizeof(s->tlpn_fifo));
    s->tlpn_idx = 0;
}

static void aspeed_pcie_cfg_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev);
    AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_GET_CLASS(s);
    g_autofree char *name = NULL;

    s->rc_regs = &apc->reg_map->rc;
    s->regs = g_new(uint32_t, apc->nr_regs);
    name = g_strdup_printf(TYPE_ASPEED_PCIE_CFG ".regs.%d", s->id);
    memory_region_init_io(&s->mmio, OBJECT(s), apc->reg_ops, s, name,
                          apc->nr_regs << 2);
    sysbus_init_mmio(sbd, &s->mmio);

    object_property_set_int(OBJECT(&s->rc), "bus-nr",
                            apc->rc_bus_nr,
                            &error_abort);
    object_property_set_bool(OBJECT(&s->rc), "has-rd",
                            apc->rc_has_rd,
                            &error_abort);
    object_property_set_int(OBJECT(&s->rc), "rp-addr",
                            apc->rc_rp_addr,
                            &error_abort);
    object_property_set_int(OBJECT(&s->rc), "msi-addr",
                            apc->rc_msi_addr,
                            &error_abort);
    if (!sysbus_realize(SYS_BUS_DEVICE(&s->rc), errp)) {
        return;
    }
}

static void aspeed_pcie_cfg_unrealize(DeviceState *dev)
{
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(dev);

    g_free(s->regs);
    s->regs = NULL;
}

static const Property aspeed_pcie_cfg_props[] = {
    DEFINE_PROP_UINT32("id", AspeedPCIECfgState, id, 0),
};

static void aspeed_pcie_cfg_class_init(ObjectClass *klass, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_CLASS(klass);

    dc->desc = "ASPEED PCIe Config";
    dc->realize = aspeed_pcie_cfg_realize;
    dc->unrealize = aspeed_pcie_cfg_unrealize;
    device_class_set_legacy_reset(dc, aspeed_pcie_cfg_reset);
    device_class_set_props(dc, aspeed_pcie_cfg_props);

    apc->reg_ops = &aspeed_pcie_cfg_ops;
    apc->reg_map = &aspeed_regmap;
    apc->nr_regs = 0x100 >> 2;
    apc->rc_msi_addr = 0x1e77005C;
    apc->rc_bus_nr = 0x80;
    apc->rc_has_rd = true;
    apc->rc_rp_addr = PCI_DEVFN(8, 0);
}

static const TypeInfo aspeed_pcie_cfg_info = {
    .name       = TYPE_ASPEED_PCIE_CFG,
    .parent     = TYPE_SYS_BUS_DEVICE,
    .instance_init = aspeed_pcie_cfg_instance_init,
    .instance_size = sizeof(AspeedPCIECfgState),
    .class_init = aspeed_pcie_cfg_class_init,
    .class_size = sizeof(AspeedPCIECfgClass),
};

static void aspeed_2700_pcie_cfg_write(void *opaque, hwaddr addr,
                                       uint64_t data, unsigned int size)
{
    AspeedPCIECfgState *s = ASPEED_PCIE_CFG(opaque);
    AspeedPCIECfgTxDesc desc;
    uint32_t reg = addr >> 2;

    trace_aspeed_pcie_cfg_write(s->id, addr, data);

    switch (reg) {
    case R_H2X_CFGE_INT_STS:
        if (data & R_H2X_CFGE_INT_STS_TX_IDEL_MASK) {
            s->regs[R_H2X_CFGE_INT_STS] &= ~R_H2X_CFGE_INT_STS_TX_IDEL_MASK;
        }

        if (data & R_H2X_CFGE_INT_STS_RX_BUSY_MASK) {
            s->regs[R_H2X_CFGE_INT_STS] &= ~R_H2X_CFGE_INT_STS_RX_BUSY_MASK;
        }
        break;
    case R_H2X_CFGI_CTRL:
        if (data & R_H2X_CFGI_CTRL_FIRE_MASK) {
            /*
             * Internal access to bridge
             * Type and BDF are 0
             */
            desc.desc0 = 0x04000001 |
                (ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, WR) << 30);
            desc.desc1 = 0x00401000 |
                ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, BEN);
            desc.desc2 = 0x00000000 |
                ARRAY_FIELD_EX32(s->regs, H2X_CFGI_TLP, ADDR);
            desc.wdata = s->regs[R_H2X_CFGI_WDATA];
            desc.rdata_reg = R_H2X_CFGI_RDATA;
            aspeed_pcie_cfg_readwrite(s, &desc);
        }
        break;
    case R_H2X_CFGE_TLPN:
        s->tlpn_fifo[s->tlpn_idx] = data;
        s->tlpn_idx = (s->tlpn_idx + 1) % ARRAY_SIZE(s->tlpn_fifo);
        break;
    case R_H2X_CFGE_CTRL:
        if (data & R_H2X_CFGE_CTRL_FIRE_MASK) {
            desc.desc0 = s->regs[R_H2X_CFGE_TLP1];
            desc.desc1 = s->tlpn_fifo[0];
            desc.desc2 = s->tlpn_fifo[1];
            desc.wdata = s->tlpn_fifo[2];
            desc.rdata_reg = R_H2X_CFGE_RDATA;
            aspeed_pcie_cfg_readwrite(s, &desc);
            s->regs[R_H2X_CFGE_INT_STS] |= R_H2X_CFGE_INT_STS_TX_IDEL_MASK;
            s->regs[R_H2X_CFGE_INT_STS] |= R_H2X_CFGE_INT_STS_RX_BUSY_MASK;
            s->tlpn_idx = 0;
        }
        break;

    case R_H2X_INT_STS:
        s->regs[reg] &= ~data | R_H2X_INT_STS_INTX_MASK;
        break;
    /*
     * These status registers are used for notify sources ISR are executed.
     * If one source ISR is executed, it will clear one bit.
     * If it clear all bits, it means to initialize this register status
     * rather than sources ISR are executed.
     */
    case R_H2X_MSI_STS0:
    case R_H2X_MSI_STS1:
        if (data == 0) {
            return ;
        }

        s->regs[reg] &= ~data;
        if (data == 0xffffffff) {
            return;
        }

        if (!s->regs[R_H2X_MSI_STS0] &&
            !s->regs[R_H2X_MSI_STS1]) {
            trace_aspeed_pcie_rc_msi_clear_irq(s->id, 0);
            qemu_set_irq(s->rc.irq, 0);
        }
        break;
    default:
        s->regs[reg] = data;
        break;
    }
}

static const MemoryRegionOps aspeed_2700_pcie_cfg_ops = {
    .read = aspeed_pcie_cfg_read,
    .write = aspeed_2700_pcie_cfg_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void aspeed_2700_pcie_cfg_class_init(ObjectClass *klass,
                                            const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedPCIECfgClass *apc = ASPEED_PCIE_CFG_CLASS(klass);

    dc->desc = "ASPEED 2700 PCIe Config";
    apc->reg_ops = &aspeed_2700_pcie_cfg_ops;
    apc->reg_map = &aspeed_2700_regmap;
    apc->nr_regs = 0x100 >> 2;
    apc->rc_msi_addr = 0x000000F0;
    apc->rc_bus_nr = 0;
    apc->rc_has_rd = false;
    apc->rc_rp_addr = PCI_DEVFN(0, 0);
}

static const TypeInfo aspeed_2700_pcie_cfg_info = {
    .name = TYPE_ASPEED_2700_PCIE_CFG,
    .parent = TYPE_ASPEED_PCIE_CFG,
    .class_init = aspeed_2700_pcie_cfg_class_init,
};

/*
 * PCIe PHY
 *
 * PCIe Host Controller (PCIEH)
 */

/* AST2600 */
REG32(PEHR_ID,     0x00)
    FIELD(PEHR_ID, DEV, 16, 16)
REG32(PEHR_CLASS_CODE,  0x04)
REG32(PEHR_DATALINK,    0x10)
REG32(PEHR_PROTECT,     0x7C)
    FIELD(PEHR_PROTECT, LOCK, 0, 8)
REG32(PEHR_LINK,        0xC0)
    FIELD(PEHR_LINK, STS, 5, 1)

/* AST2700 */
REG32(PEHR_2700_LINK_GEN2,  0x344)
    FIELD(PEHR_2700_LINK_GEN2, STS, 18, 1)
REG32(PEHR_2700_LINK_GEN4,  0x358)
    FIELD(PEHR_2700_LINK_GEN4, STS, 8, 1)

#define ASPEED_PCIE_PHY_UNLOCK  0xA8

static uint64_t aspeed_pcie_phy_read(void *opaque, hwaddr addr,
                                     unsigned int size)
{
    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(opaque);
    uint32_t reg = addr >> 2;
    uint32_t value = 0;

    value = s->regs[reg];

    trace_aspeed_pcie_phy_read(s->id, addr, value);

    return value;
}

static void aspeed_pcie_phy_write(void *opaque, hwaddr addr, uint64_t data,
                                  unsigned int size)
{
    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(opaque);
    uint32_t reg = addr >> 2;

    trace_aspeed_pcie_phy_write(s->id, addr, data);

    switch (reg) {
    case R_PEHR_PROTECT:
        data &= R_PEHR_PROTECT_LOCK_MASK;
        s->regs[reg] = !!(data == ASPEED_PCIE_PHY_UNLOCK);
        break;
    default:
        s->regs[reg] = data;
        break;
    }
}

static const MemoryRegionOps aspeed_pcie_phy_ops = {
    .read = aspeed_pcie_phy_read,
    .write = aspeed_pcie_phy_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
};

static void aspeed_pcie_phy_reset(DeviceState *dev)
{
    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);

    memset(s->regs, 0, apc->nr_regs << 2);

    s->regs[R_PEHR_ID] =
        (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED;
    s->regs[R_PEHR_CLASS_CODE] = 0x06040006;
    s->regs[R_PEHR_DATALINK] = 0xD7040022;
    s->regs[R_PEHR_LINK] = R_PEHR_LINK_STS_MASK;
}

static void aspeed_pcie_phy_realize(DeviceState *dev, Error **errp)
{
    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    g_autofree char *name = NULL;

    s->regs = g_new(uint32_t, apc->nr_regs);
    name = g_strdup_printf(TYPE_ASPEED_PCIE_PHY ".regs.%d", s->id);
    memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_pcie_phy_ops, s, name,
                          apc->nr_regs << 2);
    sysbus_init_mmio(sbd, &s->mmio);
}

static void aspeed_pcie_phy_unrealize(DeviceState *dev)
{
    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);

    g_free(s->regs);
    s->regs = NULL;
}

static const Property aspeed_pcie_phy_props[] = {
    DEFINE_PROP_UINT32("id", AspeedPCIEPhyState, id, 0),
};

static void aspeed_pcie_phy_class_init(ObjectClass *klass, const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass);

    dc->desc = "ASPEED PCIe Phy";
    dc->realize = aspeed_pcie_phy_realize;
    dc->unrealize = aspeed_pcie_phy_unrealize;
    device_class_set_legacy_reset(dc, aspeed_pcie_phy_reset);
    device_class_set_props(dc, aspeed_pcie_phy_props);

    apc->nr_regs = 0x100 >> 2;
}

static const TypeInfo aspeed_pcie_phy_info = {
    .name       = TYPE_ASPEED_PCIE_PHY,
    .parent     = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(AspeedPCIEPhyState),
    .class_init = aspeed_pcie_phy_class_init,
    .class_size = sizeof(AspeedPCIEPhyClass),
};

static void aspeed_2700_pcie_phy_reset(DeviceState *dev)
{
    AspeedPCIEPhyState *s = ASPEED_PCIE_PHY(dev);
    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_GET_CLASS(s);

    memset(s->regs, 0, apc->nr_regs << 2);

    s->regs[R_PEHR_ID] =
        (0x1150 << R_PEHR_ID_DEV_SHIFT) | PCI_VENDOR_ID_ASPEED;
    s->regs[R_PEHR_CLASS_CODE] = 0x06040011;
    s->regs[R_PEHR_2700_LINK_GEN2] = R_PEHR_2700_LINK_GEN2_STS_MASK;
    s->regs[R_PEHR_2700_LINK_GEN4] = R_PEHR_2700_LINK_GEN4_STS_MASK;
}

static void aspeed_2700_pcie_phy_class_init(ObjectClass *klass,
                                            const void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    AspeedPCIEPhyClass *apc = ASPEED_PCIE_PHY_CLASS(klass);

    dc->desc = "ASPEED AST2700 PCIe Phy";
    device_class_set_legacy_reset(dc, aspeed_2700_pcie_phy_reset);

    apc->nr_regs = 0x800 >> 2;
}

static const TypeInfo aspeed_2700_pcie_phy_info = {
    .name       = TYPE_ASPEED_2700_PCIE_PHY,
    .parent     = TYPE_ASPEED_PCIE_PHY,
    .class_init = aspeed_2700_pcie_phy_class_init,
};

static void aspeed_pcie_register_types(void)
{
    type_register_static(&aspeed_pcie_rc_info);
    type_register_static(&aspeed_pcie_root_device_info);
    type_register_static(&aspeed_pcie_root_port_info);
    type_register_static(&aspeed_pcie_cfg_info);
    type_register_static(&aspeed_2700_pcie_cfg_info);
    type_register_static(&aspeed_pcie_phy_info);
    type_register_static(&aspeed_2700_pcie_phy_info);
}

type_init(aspeed_pcie_register_types);

