/*
 * 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"

#define F_EXTEND(addr) ((addr) | MAKE_64BIT_MASK(32, 32))

#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 "target/hppa/cpu.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 0x000: /* PCI_ID & PCI_COMMAND_STATUS_REG */
        break;
    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 0x300: /* ibase */
    case 0x308: /* imask */
        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,
};


/* 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);
    hwaddr pdir_ptr, index, 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 SBA_PDIR_VALID_BIT      0x8000000000000000ULL

    addr &= ~addr_mask;

    /*
     * Default translation: "32-bit PCI Addressing on 40-bit Runway".
     * For addresses in the 32-bit memory address range ... and then
     * language which not-coincidentally matches the PSW.W=0 mapping.
     */
    if (addr <= UINT32_MAX) {
        entry = hppa_abs_to_phys_pa2_w0(addr);
    } else {
        entry = addr;
    }

    /* "range enable" flag cleared? */
    if ((s->tlb_ibase & 1) == 0) {
        goto skip;
    }

    ibase = s->tlb_ibase & ~1ULL;
    if ((addr & s->tlb_imask) != ibase) {
        /* do not translate this one! */
        goto skip;
    }

    index = PDIR_INDEX(addr);
    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 ? */
        /* failure */
        return (IOMMUTLBEntry) { .perm = IOMMU_NONE };
    }

    entry &= ~SBA_PDIR_VALID_BIT;
    entry >>= IOVP_SHIFT;
    entry <<= 12;

 skip:
    return (IOMMUTLBEntry) {
        .target_as = &address_space_memory,
        .iova = addr,
        .translated_addr = entry,
        .addr_mask = addr_mask,
        .perm = IOMMU_RW,
    };
}

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

static const PCIIOMMUOps elroy_pcihost_iommu_ops = {
    .get_address_space = elroy_pcihost_set_iommu,
};

/*
 * 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, F_EXTEND(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 = (const 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 0x0078:        /* NetBSD reads 0x78 ? */
        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 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
        put_val_in_arrary(s->ioc_rope_control, 0x20200, addr, size, val);
        break;
    case 0x20040:        /* IOC Rope config */
    case 0x22040:
        put_val_in_int64(&s->ioc_rope_config, addr, size, val);
        break;
    case 0x20300:
    case 0x22300:
        put_val_in_int64(&s->tlb_ibase, addr, size, val);
        break;
    case 0x20308:
    case 0x22308:
        put_val_in_int64(&s->tlb_imask, addr, size, val);
        break;
    case 0x20310:
    case 0x22310:
        put_val_in_int64(&s->tlb_pcom, addr, size, val);
        /* TODO: flush iommu */
        break;
    case 0x20318:
    case 0x22318:
        put_val_in_int64(&s->tlb_tcnfg, addr, size, val);
        break;
    case 0x20320:
    case 0x22320:
        put_val_in_int64(&s->tlb_pdir_base, addr, size, val);
        break;
    case 0x22000:       /* func_id */
        break;
    case 0x22008:       /* func_class */
        break;
    case 0x22050:       /* rope_debug */
        break;
    case 0x22108:        /* IOC STATUS_CONTROL */
        put_val_in_int64(&s->ioc_status_ctrl, 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 = (const 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 = F_EXTEND(LMMIO_DIST_BASE_ADDR + rope * map_size);
        memory_region_init_alias(&elroy->pci_mmio_alias, OBJECT(elroy),
                                 "pci-mmio-alias",
                                 &elroy->pci_mmio, (uint32_t) map_addr, map_size);
        memory_region_add_subregion(get_system_memory(), map_addr,
                                 &elroy->pci_mmio_alias);

        /* map elroys io */
        map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
        map_addr = F_EXTEND(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_iommu_ops,
                                 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)
