hw/loongarch/virt.c | 60 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 3 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c996305d87..b67d691fa5 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -912,6 +912,62 @@ static const MemoryRegionOps virt_iocsr_misc_ops = {
},
};
+static void fw_cfg_add_memory(MachineState *ms)
+{
+ hwaddr base, size, ram_size, gap;
+ int nb_numa_nodes, nodes;
+ NodeInfo *numa_info;
+
+ ram_size = ms->ram_size;
+ base = VIRT_LOWMEM_BASE;
+ gap = VIRT_LOWMEM_SIZE;
+ nodes = nb_numa_nodes = ms->numa_state->num_nodes;
+ numa_info = ms->numa_state->nodes;
+ if (!nodes) {
+ nodes = 1;
+ }
+
+ /* add fw_cfg memory map of node0 */
+ if (nb_numa_nodes) {
+ size = numa_info[0].node_mem;
+ } else {
+ size = ram_size;
+ }
+
+ if (size >= gap) {
+ memmap_add_entry(base, gap, 1);
+ size -= gap;
+ base = VIRT_HIGHMEM_BASE;
+ gap = ram_size - VIRT_LOWMEM_SIZE;
+ }
+
+ if (size) {
+ memmap_add_entry(base, size, 1);
+ base += size;
+ }
+
+ if (nodes < 2) {
+ return;
+ }
+
+ /* add fw_cfg memory map of other nodes */
+ size = ram_size - numa_info[0].node_mem;
+ gap = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE;
+ if (base < gap && (base + size) > gap) {
+ /*
+ * memory map for the maining nodes splited into two part
+ * lowram: [base, +(gap - base))
+ * highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base)))
+ */
+ memmap_add_entry(base, gap - base, 1);
+ size -= gap - base;
+ base = VIRT_HIGHMEM_BASE;
+ }
+
+ if (size)
+ memmap_add_entry(base, size, 1);
+}
+
static void virt_init(MachineState *machine)
{
LoongArchCPU *lacpu;
@@ -958,9 +1014,9 @@ static void virt_init(MachineState *machine)
}
fdt_add_cpu_nodes(lvms);
fdt_add_memory_nodes(machine);
+ fw_cfg_add_memory(machine);
/* Node0 memory */
- memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.node0.lowram",
machine->ram, offset, VIRT_LOWMEM_SIZE);
memory_region_add_subregion(address_space_mem, phyAddr, &lvms->lowmem);
@@ -973,7 +1029,6 @@ static void virt_init(MachineState *machine)
highram_size = ram_size - VIRT_LOWMEM_SIZE;
}
phyAddr = VIRT_HIGHMEM_BASE;
- memmap_add_entry(phyAddr, highram_size, 1);
memory_region_init_alias(&lvms->highmem, NULL, "loongarch.node0.highram",
machine->ram, offset, highram_size);
memory_region_add_subregion(address_space_mem, phyAddr, &lvms->highmem);
@@ -988,7 +1043,6 @@ static void virt_init(MachineState *machine)
memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
offset, numa_info[i].node_mem);
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
- memmap_add_entry(phyAddr, numa_info[i].node_mem, 1);
offset += numa_info[i].node_mem;
phyAddr += numa_info[i].node_mem;
}