/*
 * HP-PARISC Astro/Pluto/Ike/REO system bus adapter (SBA)
 * with Elroy PCI bus (LBA) adapter emulation
 * Found in C3000 and similar machines
 *
 * (C) 2023 by Helge Deller <deller@gmx.de>
 *
 * This work is licensed under the GNU GPL license version 2 or later.
 *
 * Chip documentation is available at:
 * https://parisc.wiki.kernel.org/index.php/Technical_Documentation
 *
 * TODO:
 * - All user-added devices are currently attached to the first
 *   Elroy (PCI bus) only for now. To fix this additional work in
 *   SeaBIOS and this driver is needed. See "user_creatable" flag below.
 * - GMMIO (Greater than 4 GB MMIO) register
 */

#define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region"

#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "hw/irq.h"
#include "hw/pci/pci_device.h"
#include "hw/pci/pci_bus.h"
#include "hw/qdev-properties.h"
#include "hw/pci-host/astro.h"
#include "hw/hppa/hppa_hardware.h"
#include "migration/vmstate.h"
#include "trace.h"
#include "qom/object.h"

/*
 * Helper functions
 */

static uint64_t mask_32bit_val(hwaddr addr, unsigned size, uint64_t val)
{
    if (size == 8) {
        return val;
    }
    if (addr & 4) {
        val >>= 32;
    } else {
        val = (uint32_t) val;
    }
    return val;
}

static void put_val_in_int64(uint64_t *p, hwaddr addr, unsigned size,
                             uint64_t val)
{
    if (size == 8) {
        *p = val;
    } else if (size == 4) {
        if (addr & 4) {
            *p = ((*p << 32) >> 32) | (val << 32);
        } else {
            *p = ((*p >> 32) << 32) | (uint32_t) val;
        }
    }
}

static void put_val_in_arrary(uint64_t *array, hwaddr start_addr,
                              hwaddr addr, unsigned size, uint64_t val)
{
    int index;

    index = (addr - start_addr) / 8;
    put_val_in_int64(&array[index], addr, size, val);
}


/*
 * The Elroy PCI host bridge. We have at least 4 of those under Astro.
 */

static MemTxResult elroy_chip_read_with_attrs(void *opaque, hwaddr addr,
                                             uint64_t *data, unsigned size,
                                             MemTxAttrs attrs)
{
    MemTxResult ret = MEMTX_OK;
    ElroyState *s = opaque;
    uint64_t val = -1;
    int index;

    switch ((addr >> 3) << 3) {
    case 0x0008:
        val = 0x6000005; /* func_class */
        break;
    case 0x0058:
        /*
         * Scratch register, but firmware initializes it with the
         * PCI BUS number and Linux/HP-UX uses it then.
         */
        val = s->pci_bus_num;
        /* Upper byte holds the end of this bus number */
        val |= s->pci_bus_num << 8;
        break;
    case 0x0080:
        val = s->arb_mask; /* set ARB mask */
        break;
    case 0x0108:
        val = s->status_control;
        break;
    case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */
        index = (addr - 0x200) / 8;
        val = s->mmio_base[index];
        break;
    case 0x0680:
        val = s->error_config;
        break;
    case 0x0688:
        val = 0;                /* ERROR_STATUS */
        break;
    case 0x0800:                /* IOSAPIC_REG_SELECT */
        val = s->iosapic_reg_select;
        break;
    case 0x0808:
        val = UINT64_MAX;            /* XXX: tbc. */
        g_assert_not_reached();
        break;
    case 0x0810:                /* IOSAPIC_REG_WINDOW */
        switch (s->iosapic_reg_select) {
        case 0x01:              /* IOSAPIC_REG_VERSION */
            val = (32 << 16) | 1; /* upper 16bit holds max entries */
            break;
        default:
            if (s->iosapic_reg_select < ARRAY_SIZE(s->iosapic_reg)) {
                val = s->iosapic_reg[s->iosapic_reg_select];
            } else {
                trace_iosapic_reg_read(s->iosapic_reg_select, size, val);
                g_assert_not_reached();
            }
        }
        trace_iosapic_reg_read(s->iosapic_reg_select, size, val);
        break;
    default:
        trace_elroy_read(addr, size, val);
        g_assert_not_reached();
    }
    trace_elroy_read(addr, size, val);

    /* for 32-bit accesses mask return value */
    val = mask_32bit_val(addr, size, val);

    trace_astro_chip_read(addr, size, val);
    *data = val;
    return ret;
}


static MemTxResult elroy_chip_write_with_attrs(void *opaque, hwaddr addr,
                                              uint64_t val, unsigned size,
                                              MemTxAttrs attrs)
{
    ElroyState *s = opaque;
    int i;

    trace_elroy_write(addr, size, val);

    switch ((addr >> 3) << 3) {
    case 0x080:
        put_val_in_int64(&s->arb_mask, addr, size, val);
        break;
    case 0x0108:
        put_val_in_int64(&s->status_control, addr, size, val);
        break;
    case 0x200 ... 0x250 - 1:   /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */
        put_val_in_arrary(s->mmio_base, 0x200, addr, size, val);
        break;
    case 0x0680:
        put_val_in_int64(&s->error_config, addr, size, val);
        break;
    case 0x0800:                /* IOSAPIC_REG_SELECT */
        s->iosapic_reg_select = val;
        break;
    case 0x0810:                /* IOSAPIC_REG_WINDOW */
        trace_iosapic_reg_write(s->iosapic_reg_select, size, val);
        if (s->iosapic_reg_select < ARRAY_SIZE(s->iosapic_reg)) {
            s->iosapic_reg[s->iosapic_reg_select] = val;
        } else {
            g_assert_not_reached();
        }
        break;
    case 0x0840:                /* IOSAPIC_REG_EOI */
        val = le64_to_cpu(val);
        val &= 63;
        for (i = 0; i < ELROY_IRQS; i++) {
            if ((s->iosapic_reg[0x10 + 2 * i] & 63) == val) {
                s->ilr &= ~(1ull << i);
            }
        }
        break;
    default:
        g_assert_not_reached();
    }
    return MEMTX_OK;
}

static const MemoryRegionOps elroy_chip_ops = {
    .read_with_attrs = elroy_chip_read_with_attrs,
    .write_with_attrs = elroy_chip_write_with_attrs,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
};


/* Unlike pci_config_data_le_ops, no check of high bit set in config_reg.  */

static uint64_t elroy_config_data_read(void *opaque, hwaddr addr, unsigned len)
{
    uint64_t val;

    PCIHostState *s = opaque;
    val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
    trace_elroy_pci_config_data_read(s->config_reg | (addr & 3), len, val);
    return val;
}

static void elroy_config_data_write(void *opaque, hwaddr addr,
                                   uint64_t val, unsigned len)
{
    PCIHostState *s = opaque;
    pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
    trace_elroy_pci_config_data_write(s->config_reg | (addr & 3), len, val);
}

static const MemoryRegionOps elroy_config_data_ops = {
    .read = elroy_config_data_read,
    .write = elroy_config_data_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static uint64_t elroy_config_addr_read(void *opaque, hwaddr addr, unsigned len)
{
    ElroyState *s = opaque;
    return s->config_reg_elroy;
}

static void elroy_config_addr_write(void *opaque, hwaddr addr,
                                   uint64_t val, unsigned len)
{
    PCIHostState *s = opaque;
    ElroyState *es = opaque;
    es->config_reg_elroy = val; /* keep a copy of original value */
    s->config_reg = val;
}

static const MemoryRegionOps elroy_config_addr_ops = {
    .read = elroy_config_addr_read,
    .write = elroy_config_addr_write,
    .valid.min_access_size = 4,
    .valid.max_access_size = 8,
    .endianness = DEVICE_LITTLE_ENDIAN,
};


/*
 * A subroutine of astro_translate_iommu that builds an IOMMUTLBEntry using the
 * given translated address and mask.
 */
static bool make_iommu_tlbe(hwaddr addr, hwaddr taddr, hwaddr mask,
                            IOMMUTLBEntry *ret)
{
    hwaddr tce_mask = ~((1ull << 12) - 1);
    ret->target_as = &address_space_memory;
    ret->iova = addr & tce_mask;
    ret->translated_addr = taddr & tce_mask;
    ret->addr_mask = ~tce_mask;
    ret->perm = IOMMU_RW;
    return true;
}

/* Handle PCI-to-system address translation.  */
static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu,
                                             hwaddr addr,
                                             IOMMUAccessFlags flag,
                                             int iommu_idx)
{
    AstroState *s = container_of(iommu, AstroState, iommu);
    IOMMUTLBEntry ret = {
        .target_as = &address_space_memory,
        .iova = addr,
        .translated_addr = 0,
        .addr_mask = ~(hwaddr)0,
        .perm = IOMMU_NONE,
    };
    hwaddr pdir_ptr, index, a, ibase;
    hwaddr addr_mask = 0xfff; /* 4k translation */
    uint64_t entry;

#define IOVP_SHIFT              12   /* equals PAGE_SHIFT */
#define PDIR_INDEX(iovp)        ((iovp) >> IOVP_SHIFT)
#define IOVP_MASK               PAGE_MASK
#define SBA_PDIR_VALID_BIT      0x8000000000000000ULL

    /* "range enable" flag cleared? */
    if ((s->tlb_ibase & 1) == 0) {
        make_iommu_tlbe(addr, addr, addr_mask, &ret);
        return ret;
    }

    a = addr;
    ibase = s->tlb_ibase & ~1ULL;
    if ((a & s->tlb_imask) != ibase) {
        /* do not translate this one! */
        make_iommu_tlbe(addr, addr, addr_mask, &ret);
        return ret;
    }
    index = PDIR_INDEX(a);
    pdir_ptr = s->tlb_pdir_base + index * sizeof(entry);
    entry = ldq_le_phys(&address_space_memory, pdir_ptr);
    if (!(entry & SBA_PDIR_VALID_BIT)) { /* I/O PDIR entry valid ? */
        g_assert_not_reached();
        goto failure;
    }
    entry &= ~SBA_PDIR_VALID_BIT;
    entry >>= IOVP_SHIFT;
    entry <<= 12;
    entry |= addr & 0xfff;
    make_iommu_tlbe(addr, entry, addr_mask, &ret);
    goto success;

 failure:
    ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
 success:
    return ret;
}

static AddressSpace *elroy_pcihost_set_iommu(PCIBus *bus, void *opaque,
                                            int devfn)
{
    ElroyState *s = opaque;
    return &s->astro->iommu_as;
}

/*
 * Encoding in IOSAPIC:
 * base_addr == 0xfffa0000, we want to get 0xa0ff0000.
 * eid  0x0ff00000 -> 0x00ff0000
 * id   0x000ff000 -> 0xff000000
 */
#define SWIZZLE_HPA(a) \
        ((((a) & 0x0ff00000) >> 4) | (((a) & 0x000ff000) << 12))
#define UNSWIZZLE_HPA(a) \
        (((((a) << 4) & 0x0ff00000) | (((a) >> 12) & 0x000ff000) | 0xf0000000))

/* bits in the "low" I/O Sapic IRdT entry */
#define IOSAPIC_IRDT_DISABLE      0x10000 /* if bit is set, mask this irq */
#define IOSAPIC_IRDT_PO_LOW       0x02000
#define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
#define IOSAPIC_IRDT_MODE_LPRI    0x00100

#define CPU_IRQ_OFFSET            2

static void elroy_set_irq(void *opaque, int irq, int level)
{
    ElroyState *s = opaque;
    uint32_t bit;
    uint32_t old_ilr = s->ilr;
    hwaddr cpu_hpa;
    uint32_t val;

    val     = s->iosapic_reg[0x10 + 2 * irq];
    cpu_hpa = s->iosapic_reg[0x11 + 2 * irq];
    /* low nibble of val has value to write into CPU irq reg */
    bit     = 1u << (val & (ELROY_IRQS - 1));
    cpu_hpa = UNSWIZZLE_HPA(cpu_hpa);

    if (level && (!(val & IOSAPIC_IRDT_DISABLE)) && cpu_hpa) {
        uint32_t ena = bit & ~old_ilr;
        s->ilr = old_ilr | bit;
        if (ena != 0) {
            stl_be_phys(&address_space_memory, cpu_hpa, val & 63);
        }
    } else {
        s->ilr = old_ilr & ~bit;
    }
}

static int elroy_pci_map_irq(PCIDevice *d, int irq_num)
{
    int slot = PCI_SLOT(d->devfn);

    assert(irq_num >= 0 && irq_num < ELROY_IRQS);
    return slot & (ELROY_IRQS - 1);
}

static void elroy_reset(DeviceState *dev)
{
    ElroyState *s = ELROY_PCI_HOST_BRIDGE(dev);
    int irq;

    /*
     * Make sure to disable interrupts at reboot, otherwise the Linux kernel
     * serial8250_config_port() in drivers/tty/serial/8250/8250_port.c
     * will hang during autoconfig().
     */
    s->ilr = 0;
    for (irq = 0; irq < ELROY_IRQS; irq++) {
        s->iosapic_reg[0x10 + 2 * irq] = IOSAPIC_IRDT_PO_LOW |
                IOSAPIC_IRDT_LEVEL_TRIG | (irq + CPU_IRQ_OFFSET) |
                IOSAPIC_IRDT_DISABLE;
        s->iosapic_reg[0x11 + 2 * irq] = SWIZZLE_HPA(CPU_HPA);
    }
}

static void elroy_pcihost_init(Object *obj)
{
    ElroyState *s = ELROY_PCI_HOST_BRIDGE(obj);
    PCIHostState *phb = PCI_HOST_BRIDGE(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    /* Elroy config access from CPU.  */
    memory_region_init_io(&s->this_mem, OBJECT(s), &elroy_chip_ops,
                          s, "elroy", 0x2000);

    /* Elroy PCI config. */
    memory_region_init_io(&phb->conf_mem, OBJECT(phb),
                          &elroy_config_addr_ops, DEVICE(s),
                          "pci-conf-idx", 8);
    memory_region_init_io(&phb->data_mem, OBJECT(phb),
                          &elroy_config_data_ops, DEVICE(s),
                          "pci-conf-data", 8);
    memory_region_add_subregion(&s->this_mem, 0x40,
                                &phb->conf_mem);
    memory_region_add_subregion(&s->this_mem, 0x48,
                                &phb->data_mem);

    /* Elroy PCI bus memory.  */
    memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", UINT64_MAX);
    memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj,
                            "pci-isa-mmio",
                            ((uint32_t) IOS_DIST_BASE_SIZE) / ROPES_PER_IOC);

    phb->bus = pci_register_root_bus(DEVICE(s), "pci",
                                     elroy_set_irq, elroy_pci_map_irq, s,
                                     &s->pci_mmio, &s->pci_io,
                                     PCI_DEVFN(0, 0), ELROY_IRQS, TYPE_PCI_BUS);

    sysbus_init_mmio(sbd, &s->this_mem);

    qdev_init_gpio_in(DEVICE(obj), elroy_set_irq, ELROY_IRQS);
}

static Property elroy_pcihost_properties[] = {
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_elroy = {
    .name = "Elroy",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(hpa, ElroyState),
        VMSTATE_UINT32(pci_bus_num, ElroyState),
        VMSTATE_UINT64(config_address, ElroyState),
        VMSTATE_UINT64(config_reg_elroy, ElroyState),
        VMSTATE_UINT64(status_control, ElroyState),
        VMSTATE_UINT64(arb_mask, ElroyState),
        VMSTATE_UINT64_ARRAY(mmio_base, ElroyState, (0x0250 - 0x200) / 8),
        VMSTATE_UINT64(error_config, ElroyState),
        VMSTATE_UINT32(iosapic_reg_select, ElroyState),
        VMSTATE_UINT64_ARRAY(iosapic_reg, ElroyState, 0x20),
        VMSTATE_UINT32(ilr, ElroyState),
        VMSTATE_END_OF_LIST()
    }
};

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

    dc->reset = elroy_reset;
    device_class_set_props(dc, elroy_pcihost_properties);
    dc->vmsd = &vmstate_elroy;
    dc->user_creatable = false;
}

static const TypeInfo elroy_pcihost_info = {
    .name          = TYPE_ELROY_PCI_HOST_BRIDGE,
    .parent        = TYPE_PCI_HOST_BRIDGE,
    .instance_init = elroy_pcihost_init,
    .instance_size = sizeof(ElroyState),
    .class_init    = elroy_pcihost_class_init,
};

static void elroy_register_types(void)
{
    type_register_static(&elroy_pcihost_info);
}

type_init(elroy_register_types)


static ElroyState *elroy_init(int num)
{
    DeviceState *dev;

    dev = qdev_new(TYPE_ELROY_PCI_HOST_BRIDGE);
    dev->id = g_strdup_printf("elroy%d", num);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    return ELROY_PCI_HOST_BRIDGE(dev);
}

/*
 * Astro Runway chip.
 */

static MemTxResult astro_chip_read_with_attrs(void *opaque, hwaddr addr,
                                             uint64_t *data, unsigned size,
                                             MemTxAttrs attrs)
{
    AstroState *s = opaque;
    MemTxResult ret = MEMTX_OK;
    uint64_t val = -1;
    int index;

    switch ((addr >> 3) << 3) {
    /* R2I registers */
    case 0x0000:        /* ID */
        val = (0x01 << 3) | 0x01ULL;
        break;
    case 0x0008:        /* IOC_CTRL */
        val = s->ioc_ctrl;
        break;
    case 0x0010:        /* TOC_CLIENT_ID */
        break;
    case 0x0030:        /* HP-UX 10.20 and 11.11 reads it. No idea. */
        val = -1;
        break;
    case 0x0300 ... 0x03d8:     /* LMMIO_DIRECT0_BASE... */
        index = (addr - 0x300) / 8;
        val = s->ioc_ranges[index];
        break;
    case 0x10200:
        val = 0;
        break;
    case 0x10220:
    case 0x10230:        /* HP-UX 11.11 reads it. No idea. */
        val = -1;
        break;
    case 0x22108:        /* IOC STATUS_CONTROL */
        val = s->ioc_status_ctrl;
        break;
    case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
        index = (addr - 0x20200) / 8;
        val = s->ioc_rope_control[index];
        break;
    case 0x20040:        /* IOC Rope config */
        val = s->ioc_rope_config;
        break;
    case 0x20050:        /* IOC Rope debug */
        val = 0;
        break;
    case 0x20108:        /* IOC STATUS_CONTROL */
        val = s->ioc_status_control;
        break;
    case 0x20310:        /* IOC_PCOM */
        val = s->tlb_pcom;
        /* TODO: flush iommu */
        break;
    case 0x20400:
        val = s->ioc_flush_control;
        break;
    /* empty placeholders for non-existent elroys */
#define EMPTY_PORT(x) case x:    case x+8:   val = 0;          break; \
                      case x+40: case x+48:  val = UINT64_MAX; break;
        EMPTY_PORT(0x30000)
        EMPTY_PORT(0x32000)
        EMPTY_PORT(0x34000)
        EMPTY_PORT(0x36000)
        EMPTY_PORT(0x38000)
        EMPTY_PORT(0x3a000)
        EMPTY_PORT(0x3c000)
        EMPTY_PORT(0x3e000)
#undef EMPTY_PORT

    default:
        trace_astro_chip_read(addr, size, val);
        g_assert_not_reached();
    }

    /* for 32-bit accesses mask return value */
    val = mask_32bit_val(addr, size, val);

    trace_astro_chip_read(addr, size, val);
    *data = val;
    return ret;
}

static MemTxResult astro_chip_write_with_attrs(void *opaque, hwaddr addr,
                                              uint64_t val, unsigned size,
                                              MemTxAttrs attrs)
{
    AstroState *s = opaque;

    trace_astro_chip_write(addr, size, val);

    switch ((addr >> 3) << 3) {
    case 0x0000:        /* ID */
        break;
    case 0x0008:        /* IOC_CTRL */
        val &= 0x0ffffff;
        put_val_in_int64(&s->ioc_ctrl, addr, size, val);
        break;
    case 0x0010:        /* TOC_CLIENT_ID */
        break;
    case 0x0030:        /* HP-UX 10.20 and 11.11 reads it. No idea. */
        break;
    case 0x0300 ... 0x03d8 - 1: /* LMMIO_DIRECT0_BASE... */
        put_val_in_arrary(s->ioc_ranges, 0x300, addr, size, val);
        break;
    case 0x10200:
    case 0x10220:
    case 0x10230:        /* HP-UX 11.11 reads it. No idea. */
        break;
    case 0x22108:        /* IOC STATUS_CONTROL */
        put_val_in_int64(&s->ioc_status_ctrl, addr, size, val);
        break;
    case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
        put_val_in_arrary(s->ioc_rope_control, 0x20200, addr, size, val);
        break;
    case 0x20040:        /* IOC Rope config */
        put_val_in_int64(&s->ioc_rope_config, addr, size, val);
        break;
    case 0x20300:
        put_val_in_int64(&s->tlb_ibase, addr, size, val);
        break;
    case 0x20308:
        put_val_in_int64(&s->tlb_imask, addr, size, val);
        break;
    case 0x20310:
        put_val_in_int64(&s->tlb_pcom, addr, size, val);
        /* TODO: flush iommu */
        break;
    case 0x20318:
        put_val_in_int64(&s->tlb_tcnfg, addr, size, val);
        break;
    case 0x20320:
        put_val_in_int64(&s->tlb_pdir_base, addr, size, val);
        break;
    /*
     * empty placeholders for non-existent elroys, e.g.
     * func_class, pci config & data
     */
#define EMPTY_PORT(x) case x: case x+8: case x+0x40: case x+0x48:
        EMPTY_PORT(0x30000)
        EMPTY_PORT(0x32000)
        EMPTY_PORT(0x34000)
        EMPTY_PORT(0x36000)
        EMPTY_PORT(0x38000)
        EMPTY_PORT(0x3a000)
        EMPTY_PORT(0x3c000)
        EMPTY_PORT(0x3e000)
        break;
#undef EMPTY_PORT

    default:
        /* Controlled by astro_chip_mem_valid above.  */
        trace_astro_chip_write(addr, size, val);
        g_assert_not_reached();
    }
    return MEMTX_OK;
}

static const MemoryRegionOps astro_chip_ops = {
    .read_with_attrs = astro_chip_read_with_attrs,
    .write_with_attrs = astro_chip_write_with_attrs,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
};

static const VMStateDescription vmstate_astro = {
    .name = "Astro",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(ioc_ctrl, AstroState),
        VMSTATE_UINT64(ioc_status_ctrl, AstroState),
        VMSTATE_UINT64_ARRAY(ioc_ranges, AstroState, (0x03d8 - 0x300) / 8),
        VMSTATE_UINT64(ioc_rope_config, AstroState),
        VMSTATE_UINT64(ioc_status_control, AstroState),
        VMSTATE_UINT64(ioc_flush_control, AstroState),
        VMSTATE_UINT64_ARRAY(ioc_rope_control, AstroState, 8),
        VMSTATE_UINT64(tlb_ibase, AstroState),
        VMSTATE_UINT64(tlb_imask, AstroState),
        VMSTATE_UINT64(tlb_pcom, AstroState),
        VMSTATE_UINT64(tlb_tcnfg, AstroState),
        VMSTATE_UINT64(tlb_pdir_base, AstroState),
        VMSTATE_END_OF_LIST()
    }
};

static void astro_reset(DeviceState *dev)
{
    AstroState *s = ASTRO_CHIP(dev);
    int i;

    s->ioc_ctrl = 0x29cf;
    s->ioc_rope_config = 0xc5f;
    s->ioc_flush_control = 0xb03;
    s->ioc_status_control = 0;
    memset(&s->ioc_rope_control, 0, sizeof(s->ioc_rope_control));

    /*
     * The SBA BASE/MASK registers control CPU -> IO routing.
     * The LBA BASE/MASK registers control IO -> System routing (in Elroy)
     */
    memset(&s->ioc_ranges, 0, sizeof(s->ioc_ranges));
    s->ioc_ranges[(0x360 - 0x300) / 8] = LMMIO_DIST_BASE_ADDR | 0x01; /* LMMIO_DIST_BASE (SBA) */
    s->ioc_ranges[(0x368 - 0x300) / 8] = 0xfc000000;          /* LMMIO_DIST_MASK */
    s->ioc_ranges[(0x370 - 0x300) / 8] = 0;                   /* LMMIO_DIST_ROUTE */
    s->ioc_ranges[(0x390 - 0x300) / 8] = IOS_DIST_BASE_ADDR | 0x01; /* IOS_DIST_BASE */
    s->ioc_ranges[(0x398 - 0x300) / 8] = 0xffffff0000;        /* IOS_DIST_MASK    */
    s->ioc_ranges[(0x3a0 - 0x300) / 8] = 0x3400000000000000ULL; /* IOS_DIST_ROUTE */
    s->ioc_ranges[(0x3c0 - 0x300) / 8] = 0xfffee00000;        /* IOS_DIRECT_BASE  */
    s->ioc_ranges[(0x3c8 - 0x300) / 8] = 0xffffff0000;        /* IOS_DIRECT_MASK  */
    s->ioc_ranges[(0x3d0 - 0x300) / 8] = 0x0;                 /* IOS_DIRECT_ROUTE */

    s->tlb_ibase = 0;
    s->tlb_imask = 0;
    s->tlb_pcom = 0;
    s->tlb_tcnfg = 0;
    s->tlb_pdir_base = 0;

    for (i = 0; i < ELROY_NUM; i++) {
        elroy_reset(DEVICE(s->elroy[i]));
    }
}

static void astro_init(Object *obj)
{
}

static void astro_realize(DeviceState *obj, Error **errp)
{
    AstroState *s = ASTRO_CHIP(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    int i;

    memory_region_init_io(&s->this_mem, OBJECT(s), &astro_chip_ops,
                          s, "astro", 0x40000);
    sysbus_init_mmio(sbd, &s->this_mem);

    /* Host memory as seen from Elroys PCI side, via the IOMMU.  */
    memory_region_init_iommu(&s->iommu, sizeof(s->iommu),
                             TYPE_ASTRO_IOMMU_MEMORY_REGION, OBJECT(s),
                             "iommu-astro", UINT64_MAX);
    address_space_init(&s->iommu_as, MEMORY_REGION(&s->iommu),
                       "bm-pci");

    /* Create Elroys (PCI host bus chips).  */
    for (i = 0; i < ELROY_NUM; i++) {
        static const int elroy_hpa_offsets[ELROY_NUM] = {
                    0x30000, 0x32000, 0x38000, 0x3c000 };
        static const char elroy_rope_nr[ELROY_NUM] = {
                    0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */
        int addr_offset;
        ElroyState *elroy;
        hwaddr map_addr;
        uint64_t map_size;
        int rope;

        addr_offset = elroy_hpa_offsets[i];
        rope = elroy_rope_nr[i];

        elroy = elroy_init(i);
        s->elroy[i] = elroy;
        elroy->hpa = ASTRO_HPA + addr_offset;
        elroy->pci_bus_num = i;
        elroy->astro = s;

        /*
         * NOTE: we only allow PCI devices on first Elroy for now.
         * SeaBIOS will not find devices on the other busses.
         */
        if (i > 0) {
            qbus_mark_full(&PCI_HOST_BRIDGE(elroy)->bus->qbus);
        }

        /* map elroy config addresses into Astro space */
        memory_region_add_subregion(&s->this_mem, addr_offset,
                                    &elroy->this_mem);

        /* LMMIO */
        elroy->mmio_base[(0x0200 - 0x200) / 8] = 0xf0000001;
        elroy->mmio_base[(0x0208 - 0x200) / 8] = 0xf8000000;
        /* GMMIO */
        elroy->mmio_base[(0x0210 - 0x200) / 8] = 0x000000f800000001;
        elroy->mmio_base[(0x0218 - 0x200) / 8] = 0x000000ff80000000;
        /* WLMMIO */
        elroy->mmio_base[(0x0220 - 0x200) / 8] = 0xf0000001;
        elroy->mmio_base[(0x0228 - 0x200) / 8] = 0xf0000000;
        /* WGMMIO */
        elroy->mmio_base[(0x0230 - 0x200) / 8] = 0x000000f800000001;
        elroy->mmio_base[(0x0238 - 0x200) / 8] = 0x000000fc00000000;
        /* IOS_BASE */
        map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
        elroy->mmio_base[(0x0240 - 0x200) / 8] = rope * map_size | 0x01;
        elroy->mmio_base[(0x0248 - 0x200) / 8] = 0x0000e000;

        /* map elroys mmio */
        map_size = LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC;
        map_addr = (uint32_t) (LMMIO_DIST_BASE_ADDR + rope * map_size);
        memory_region_init_alias(&elroy->pci_mmio_alias, OBJECT(elroy),
                                 "pci-mmio-alias",
                                 &elroy->pci_mmio, map_addr, map_size);
        memory_region_add_subregion(get_system_memory(), map_addr,
                                 &elroy->pci_mmio_alias);

        map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
        map_addr = (uint32_t) (IOS_DIST_BASE_ADDR + rope * map_size);
        memory_region_add_subregion(get_system_memory(), map_addr,
                                 &elroy->pci_io);

        /* Host memory as seen from the PCI side, via the IOMMU.  */
        pci_setup_iommu(PCI_HOST_BRIDGE(elroy)->bus, elroy_pcihost_set_iommu,
                                 elroy);
    }
}

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

    dc->reset = astro_reset;
    dc->vmsd = &vmstate_astro;
    dc->realize = astro_realize;
    /*
     * astro with elroys are hard part of the newer PA2.0 machines and can not
     * be created without that hardware
     */
    dc->user_creatable = false;
}

static const TypeInfo astro_chip_info = {
    .name          = TYPE_ASTRO_CHIP,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_init = astro_init,
    .instance_size = sizeof(AstroState),
    .class_init    = astro_class_init,
};

static void astro_iommu_memory_region_class_init(ObjectClass *klass,
                                                   void *data)
{
    IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);

    imrc->translate = astro_translate_iommu;
}

static const TypeInfo astro_iommu_memory_region_info = {
    .parent = TYPE_IOMMU_MEMORY_REGION,
    .name = TYPE_ASTRO_IOMMU_MEMORY_REGION,
    .class_init = astro_iommu_memory_region_class_init,
};


static void astro_register_types(void)
{
    type_register_static(&astro_chip_info);
    type_register_static(&astro_iommu_memory_region_info);
}

type_init(astro_register_types)
