@samitouri / QOSamiQemu / commits / 896c1f3d4b

hw/riscv/boot: Describe discontiguous memory in boot_info

Machines that have discontiguous memory may need to adjust where firmware and images are loaded at boot. Provide an interface for machines to describe a discontiguous low/high RAM scheme for this purpose. Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Joel Stanley <joel@jms.id.au> Message-ID: <20260630024952.1520546-2-joel@jms.id.au> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Nicholas Piggin committed Jun 30, 2026 at 12:19 UTC 896c1f3d4b33b5597b4cb1a1d99ee00909ee539f
2 files changed +23
hw/riscv/boot.c
+16
@@ -70,11 +70,27 @@ char *riscv_plic_hart_config_string(int hart_count)
70
71 void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts)
72 {
73 + info->ram_low_start = 0;
74 + info->ram_low_size = 0;
75 info->kernel_size = 0;
76 info->initrd_size = 0;
77 info->is_32bit = riscv_is_32bit(harts);
78 }
79
80 +/*
81 + * This can be used instead of riscv_boot_info_init() if the machine has
82 + * discontiguous physical memory. The low memory range specified will be
83 + * used to place firmware images.
84 + */
85 +void riscv_boot_info_init_discontig_mem(RISCVBootInfo *info,
86 + RISCVHartArrayState *harts,
87 + hwaddr low_start, hwaddr low_size)
88 +{
89 + riscv_boot_info_init(info, harts);
90 + info->ram_low_start = low_start;
91 + info->ram_low_size = low_size;
92 +}
93 +
94 vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info,
95 hwaddr firmware_end_addr) {
96 if (info->is_32bit) {
include/hw/riscv/boot.h
+7
@@ -28,6 +28,10 @@
28 #define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin"
29
30 typedef struct RISCVBootInfo {
31 + /* First contiguous RAM region. If size is zero then assume entire RAM */
32 + hwaddr ram_low_start;
33 + hwaddr ram_low_size;
34 +
35 ssize_t kernel_size;
36 hwaddr image_low_addr;
37 hwaddr image_high_addr;
@@ -43,6 +47,9 @@ bool riscv_is_32bit(RISCVHartArrayState *harts);
47 char *riscv_plic_hart_config_string(int hart_count);
48
49 void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts);
50 +void riscv_boot_info_init_discontig_mem(RISCVBootInfo *info,
51 + RISCVHartArrayState *harts,
52 + hwaddr low_start, hwaddr low_size);
53 vaddr riscv_calc_kernel_start_addr(RISCVBootInfo *info,
54 hwaddr firmware_end_addr);
55 hwaddr riscv_find_and_load_firmware(MachineState *machine,