diff options
| -rw-r--r-- | hw/arm/xlnx-versal-virt.c | 79 | ||||
| -rw-r--r-- | hw/arm/xlnx-versal.c | 73 | ||||
| -rw-r--r-- | include/hw/arm/xlnx-versal.h | 7 |
3 files changed, 53 insertions, 106 deletions
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index 5958e71251..ad7b3135a6 100644 --- a/hw/arm/xlnx-versal-virt.c +++ b/hw/arm/xlnx-versal-virt.c @@ -106,88 +106,13 @@ static void fdt_nop_memory_nodes(void *fdt, Error **errp) g_strfreev(node_path); } -static void fdt_add_memory_nodes(VersalVirt *s, void *fdt, uint64_t ram_size) -{ - /* Describes the various split DDR access regions. */ - static const struct { - uint64_t base; - uint64_t size; - } addr_ranges[] = { - { MM_TOP_DDR, MM_TOP_DDR_SIZE }, - { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, - { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, - { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } - }; - uint64_t mem_reg_prop[8] = {0}; - uint64_t size = ram_size; - Error *err = NULL; - char *name; - int i; - - fdt_nop_memory_nodes(fdt, &err); - if (err) { - error_report_err(err); - return; - } - - name = g_strdup_printf("/memory@%x", MM_TOP_DDR); - for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { - uint64_t mapsize; - - mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; - - mem_reg_prop[i * 2] = addr_ranges[i].base; - mem_reg_prop[i * 2 + 1] = mapsize; - size -= mapsize; - } - qemu_fdt_add_subnode(fdt, name); - qemu_fdt_setprop_string(fdt, name, "device_type", "memory"); - - switch (i) { - case 1: - qemu_fdt_setprop_sized_cells(fdt, name, "reg", - 2, mem_reg_prop[0], - 2, mem_reg_prop[1]); - break; - case 2: - qemu_fdt_setprop_sized_cells(fdt, name, "reg", - 2, mem_reg_prop[0], - 2, mem_reg_prop[1], - 2, mem_reg_prop[2], - 2, mem_reg_prop[3]); - break; - case 3: - qemu_fdt_setprop_sized_cells(fdt, name, "reg", - 2, mem_reg_prop[0], - 2, mem_reg_prop[1], - 2, mem_reg_prop[2], - 2, mem_reg_prop[3], - 2, mem_reg_prop[4], - 2, mem_reg_prop[5]); - break; - case 4: - qemu_fdt_setprop_sized_cells(fdt, name, "reg", - 2, mem_reg_prop[0], - 2, mem_reg_prop[1], - 2, mem_reg_prop[2], - 2, mem_reg_prop[3], - 2, mem_reg_prop[4], - 2, mem_reg_prop[5], - 2, mem_reg_prop[6], - 2, mem_reg_prop[7]); - break; - default: - g_assert_not_reached(); - } - g_free(name); -} - static void versal_virt_modify_dtb(const struct arm_boot_info *binfo, void *fdt) { VersalVirt *s = container_of(binfo, VersalVirt, binfo); - fdt_add_memory_nodes(s, fdt, binfo->ram_size); + fdt_nop_memory_nodes(s->fdt, &error_abort); + versal_fdt_add_memory_nodes(&s->soc, binfo->ram_size); } static void *versal_virt_get_dtb(const struct arm_boot_info *binfo, diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 8aa82ceb83..f1b704175f 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -115,6 +115,11 @@ typedef struct VersalCpuClusterMap { typedef struct VersalMap { VersalMemMap ocm; + struct VersalDDRMap { + VersalMemMap chan[4]; + size_t num_chan; + } ddr; + VersalCpuClusterMap apu; VersalCpuClusterMap rpu; @@ -219,6 +224,14 @@ static const VersalMap VERSAL_MAP = { .size = 0x40000, }, + .ddr = { + .chan[0] = { .addr = 0x0, .size = 2 * GiB }, + .chan[1] = { .addr = 0x800000000ull, .size = 32 * GiB }, + .chan[2] = { .addr = 0xc00000000ull, .size = 256 * GiB }, + .chan[3] = { .addr = 0x10000000000ull, .size = 734 * GiB }, + .num_chan = 4, + }, + .apu = { .name = "apu", .cpu_model = ARM_CPU_TYPE_NAME("cortex-a72"), @@ -1483,46 +1496,58 @@ static inline void versal_create_crl(Versal *s) versal_sysbus_connect_irq(s, SYS_BUS_DEVICE(dev), 0, map->crl.irq); } -/* This takes the board allocated linear DDR memory and creates aliases +/* + * This takes the board allocated linear DDR memory and creates aliases * for each split DDR range/aperture on the Versal address map. */ -static void versal_map_ddr(Versal *s) +static void versal_map_ddr(Versal *s, const struct VersalDDRMap *map) { uint64_t size = memory_region_size(s->cfg.mr_ddr); - /* Describes the various split DDR access regions. */ - static const struct { - uint64_t base; - uint64_t size; - } addr_ranges[] = { - { MM_TOP_DDR, MM_TOP_DDR_SIZE }, - { MM_TOP_DDR_2, MM_TOP_DDR_2_SIZE }, - { MM_TOP_DDR_3, MM_TOP_DDR_3_SIZE }, - { MM_TOP_DDR_4, MM_TOP_DDR_4_SIZE } - }; uint64_t offset = 0; int i; - assert(ARRAY_SIZE(addr_ranges) == ARRAY_SIZE(s->noc.mr_ddr_ranges)); - for (i = 0; i < ARRAY_SIZE(addr_ranges) && size; i++) { - char *name; + for (i = 0; i < map->num_chan && size; i++) { uint64_t mapsize; + MemoryRegion *alias; + + mapsize = MIN(size, map->chan[i].size); - mapsize = size < addr_ranges[i].size ? size : addr_ranges[i].size; - name = g_strdup_printf("noc-ddr-range%d", i); /* Create the MR alias. */ - memory_region_init_alias(&s->noc.mr_ddr_ranges[i], OBJECT(s), - name, s->cfg.mr_ddr, - offset, mapsize); + alias = g_new(MemoryRegion, 1); + memory_region_init_alias(alias, OBJECT(s), "noc-ddr-range", + s->cfg.mr_ddr, offset, mapsize); /* Map it onto the NoC MR. */ - memory_region_add_subregion(&s->mr_ps, addr_ranges[i].base, - &s->noc.mr_ddr_ranges[i]); + memory_region_add_subregion(&s->mr_ps, map->chan[i].addr, alias); offset += mapsize; size -= mapsize; - g_free(name); } } +void versal_fdt_add_memory_nodes(Versal *s, uint64_t size) +{ + const struct VersalDDRMap *map = &versal_get_map(s)->ddr; + g_autofree char *node; + g_autofree uint64_t *reg; + int i; + + reg = g_new(uint64_t, map->num_chan * 2); + + for (i = 0; i < map->num_chan && size; i++) { + uint64_t mapsize; + + mapsize = MIN(size, map->chan[i].size); + + reg[i * 2] = cpu_to_be64(map->chan[i].addr); + reg[i * 2 + 1] = cpu_to_be64(mapsize); + + size -= mapsize; + } + + node = versal_fdt_add_subnode(s, "/memory", 0, "memory", sizeof("memory")); + qemu_fdt_setprop(s->cfg.fdt, node, "reg", reg, sizeof(uint64_t) * i * 2); +} + static void versal_unimp_area(Versal *s, const char *name, MemoryRegion *mr, hwaddr base, hwaddr size) @@ -1692,7 +1717,7 @@ static void versal_realize(DeviceState *dev, Error **errp) versal_create_cfu(s, &map->cfu); versal_create_crl(s); - versal_map_ddr(s); + versal_map_ddr(s, &map->ddr); versal_unimp(s); /* Create the On Chip Memory (OCM). */ diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index e1d6e54549..39bc414c85 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -44,11 +44,6 @@ struct Versal { MemoryRegion mr_ps; struct { - /* 4 ranges to access DDR. */ - MemoryRegion mr_ddr_ranges[4]; - } noc; - - struct { uint32_t clk_25mhz; uint32_t clk_125mhz; uint32_t gic; @@ -73,6 +68,8 @@ static inline void versal_set_fdt(Versal *s, void *fdt) s->cfg.fdt = fdt; } +void versal_fdt_add_memory_nodes(Versal *s, uint64_t ram_size); + DeviceState *versal_get_boot_cpu(Versal *s); void versal_sdhci_plug_card(Versal *s, int sd_idx, BlockBackend *blk); void versal_efuse_attach_drive(Versal *s, BlockBackend *blk); |