diff options
Diffstat (limited to 'hw/pci-host/astro.c')
-rw-r--r-- | hw/pci-host/astro.c | 68 |
1 files changed, 58 insertions, 10 deletions
diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c index e3e589c..859e308 100644 --- a/hw/pci-host/astro.c +++ b/hw/pci-host/astro.c @@ -35,6 +35,7 @@ #include "target/hppa/cpu.h" #include "trace.h" #include "qom/object.h" +#include "exec/target_page.h" /* * Helper functions @@ -461,10 +462,6 @@ static void elroy_pcihost_init(Object *obj) 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, @@ -485,12 +482,11 @@ static const VMStateDescription vmstate_elroy = { } }; -static void elroy_pcihost_class_init(ObjectClass *klass, void *data) +static void elroy_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->reset = elroy_reset; - device_class_set_props(dc, elroy_pcihost_properties); + device_class_set_legacy_reset(dc, elroy_reset); dc->vmsd = &vmstate_elroy; dc->user_creatable = false; } @@ -526,6 +522,53 @@ static ElroyState *elroy_init(int num) * Astro Runway chip. */ +static void adjust_LMMIO_DIRECT_mapping(AstroState *s, unsigned int reg_index) +{ + MemoryRegion *lmmio_alias; + unsigned int lmmio_index, map_route; + hwaddr map_addr; + uint32_t map_size; + struct ElroyState *elroy; + + /* pointer to LMMIO_DIRECT entry */ + lmmio_index = reg_index / 3; + lmmio_alias = &s->lmmio_direct[lmmio_index]; + + map_addr = s->ioc_ranges[3 * lmmio_index + 0]; + map_size = s->ioc_ranges[3 * lmmio_index + 1]; + map_route = s->ioc_ranges[3 * lmmio_index + 2]; + + /* find elroy to which this address is routed */ + map_route &= (ELROY_NUM - 1); + elroy = s->elroy[map_route]; + + if (lmmio_alias->enabled) { + memory_region_set_enabled(lmmio_alias, false); + } + + map_addr = F_EXTEND(map_addr); + map_addr &= TARGET_PAGE_MASK; + map_size = (~map_size) + 1; + map_size &= TARGET_PAGE_MASK; + + /* exit if disabled or zero map size */ + if (!(map_addr & 1) || !map_size) { + return; + } + + if (!memory_region_size(lmmio_alias)) { + memory_region_init_alias(lmmio_alias, OBJECT(elroy), + "pci-lmmmio-alias", &elroy->pci_mmio, + (uint32_t) map_addr, map_size); + memory_region_add_subregion(get_system_memory(), map_addr, + lmmio_alias); + } else { + memory_region_set_alias_offset(lmmio_alias, map_addr); + memory_region_set_size(lmmio_alias, map_size); + memory_region_set_enabled(lmmio_alias, true); + } +} + static MemTxResult astro_chip_read_with_attrs(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) @@ -633,6 +676,11 @@ static MemTxResult astro_chip_write_with_attrs(void *opaque, hwaddr addr, break; case 0x0300 ... 0x03d8 - 1: /* LMMIO_DIRECT0_BASE... */ put_val_in_arrary(s->ioc_ranges, 0x300, addr, size, val); + unsigned int index = (addr - 0x300) / 8; + /* check if one of the 4 LMMIO_DIRECT regs, each using 3 entries. */ + if (index < LMMIO_DIRECT_RANGES * 3) { + adjust_LMMIO_DIRECT_mapping(s, index); + } break; case 0x10200: case 0x10220: @@ -861,11 +909,11 @@ static void astro_realize(DeviceState *obj, Error **errp) } } -static void astro_class_init(ObjectClass *klass, void *data) +static void astro_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->reset = astro_reset; + device_class_set_legacy_reset(dc, astro_reset); dc->vmsd = &vmstate_astro; dc->realize = astro_realize; /* @@ -884,7 +932,7 @@ static const TypeInfo astro_chip_info = { }; static void astro_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); |