diff mbox series

[v3,3/6] hw/loongarch: Refine fwcfg memory map

Message ID 20240515093927.3453674-4-maobibo@loongson.cn (mailing list archive)
State New, archived
Headers show
Series hw/loongarch: Refine numa memory map | expand

Commit Message

Bibo Mao May 15, 2024, 9:39 a.m. UTC
Memory map table for fwcfg is used for UEFI BIOS, UEFI BIOS uses the first
entry from fwcfg memory map as the first memory HOB, the second memory HOB
will be used if the first memory HOB is used up.

Memory map table for fwcfg does not care about numa node, however in
generic the first memory HOB is part of numa node0, so that runtime
memory of UEFI which is allocated from the first memory HOB is located
at numa node0.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 hw/loongarch/virt.c | 60 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 3 deletions(-)

Comments

gaosong May 22, 2024, 7:18 a.m. UTC | #1
在 2024/5/15 下午5:39, Bibo Mao 写道:
> Memory map table for fwcfg is used for UEFI BIOS, UEFI BIOS uses the first
> entry from fwcfg memory map as the first memory HOB, the second memory HOB
> will be used if the first memory HOB is used up.
>
> Memory map table for fwcfg does not care about numa node, however in
> generic the first memory HOB is part of numa node0, so that runtime
> memory of UEFI which is allocated from the first memory HOB is located
> at numa node0.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
Reviewed-by: Song Gao <gaosong@loongson.cn>

Thanks.
Song Gao
>   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;
>       }
diff mbox series

Patch

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;
     }