diff --git a/hw/omap.h b/hw/omap.h index d12f4027a2..367ba11baa 100644 --- a/hw/omap.h +++ b/hw/omap.h @@ -84,7 +84,8 @@ struct omap_target_agent_s { uint32_t control; uint32_t status; }; -struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num); +struct omap_l4_s *omap_l4_init(MemoryRegion *address_space, + target_phys_addr_t base, int ta_num); struct omap_target_agent_s; struct omap_target_agent_s *omap_l4ta_get( @@ -94,8 +95,12 @@ struct omap_target_agent_s *omap_l4ta_get( int cs); target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region, int iotype); +target_phys_addr_t omap_l4_attach_region(struct omap_target_agent_s *ta, + int region, MemoryRegion *mr); target_phys_addr_t omap_l4_region_base(struct omap_target_agent_s *ta, int region); +target_phys_addr_t omap_l4_region_size(struct omap_target_agent_s *ta, + int region); /* OMAP2 SDRAM controller */ struct omap_sdrc_s; diff --git a/hw/omap2.c b/hw/omap2.c index 8a0fa73191..5fc3fcf6fb 100644 --- a/hw/omap2.c +++ b/hw/omap2.c @@ -2260,7 +2260,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem, (sram_base = qemu_ram_alloc(NULL, "omap2.sram", s->sram_size)) | IO_MEM_RAM); - s->l4 = omap_l4_init(OMAP2_L4_BASE, 54); + s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54); /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */ cpu_irq = arm_pic_init_cpu(s->env); diff --git a/hw/omap_l4.c b/hw/omap_l4.c index a19ea702d6..a0bed5cdbc 100644 --- a/hw/omap_l4.c +++ b/hw/omap_l4.c @@ -21,16 +21,19 @@ #include "omap.h" struct omap_l4_s { + MemoryRegion *address_space; target_phys_addr_t base; int ta_num; struct omap_target_agent_s ta[0]; }; -struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num) +struct omap_l4_s *omap_l4_init(MemoryRegion *address_space, + target_phys_addr_t base, int ta_num) { struct omap_l4_s *bus = g_malloc0( sizeof(*bus) + ta_num * sizeof(*bus->ta)); + bus->address_space = address_space; bus->ta_num = ta_num; bus->base = base; @@ -43,6 +46,12 @@ target_phys_addr_t omap_l4_region_base(struct omap_target_agent_s *ta, return ta->bus->base + ta->start[region].offset; } +target_phys_addr_t omap_l4_region_size(struct omap_target_agent_s *ta, + int region) +{ + return ta->start[region].size; +} + static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr) { struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque; @@ -150,3 +159,21 @@ target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region, return base; } + +target_phys_addr_t omap_l4_attach_region(struct omap_target_agent_s *ta, + int region, MemoryRegion *mr) +{ + target_phys_addr_t base; + + if (region < 0 || region >= ta->regions) { + fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region); + exit(-1); + } + + base = ta->bus->base + ta->start[region].offset; + if (mr) { + memory_region_add_subregion(ta->bus->address_space, base, mr); + } + + return base; +}