@@ -521,6 +521,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)
@@ -628,6 +675,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:
@@ -24,6 +24,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ElroyState, ELROY_PCI_HOST_BRIDGE)
#define LMMIO_DIST_BASE_ADDR 0xf4000000ULL
#define LMMIO_DIST_BASE_SIZE 0x4000000ULL
+#define LMMIO_DIRECT_RANGES 4
+
#define IOS_DIST_BASE_ADDR 0xfffee00000ULL
#define IOS_DIST_BASE_SIZE 0x10000ULL
@@ -83,9 +85,7 @@ struct AstroState {
struct ElroyState *elroy[ELROY_NUM];
MemoryRegion this_mem;
-
- MemoryRegion pci_mmio;
- MemoryRegion pci_io;
+ MemoryRegion lmmio_direct[LMMIO_DIRECT_RANGES];
IOMMUMemoryRegion iommu;
AddressSpace iommu_as;