On Wed, 17 Jun 2026 at 04:31, Kuan-Wei Chiu <[email protected]> wrote:
>
> Add support for the Milk-V Duo development board, which is powered by
> the Sophgo CV1800B SoC.
>
> The implementation includes:
> - Board-level machine initialization with 64mb of default ram.
> - Integration of the CV1800B SoC.
> - Support for loading external FDT, kernel, and initrd images.
> - Proper setup of the reset vector to match the CV1800B's boot flow.
Can you add something to docs/riscv too? A brief description of the
the board as you have here, how to boot it, where to find
firmware/images for it.
> --- /dev/null
> +++ b/hw/riscv/milkv_duo.c
> +static void milkv_duo_init(MachineState *machine)
> +{
> + MilkVDuoState *s = MILK_V_DUO(machine);
> + MemoryRegion *system_memory = get_system_memory();
> + RISCVBootInfo boot_info;
> + hwaddr firmware_load_addr, firmware_end_addr;
> + hwaddr fdt_load_addr = 0;
> + int fdt_size = 0;
> + uint64_t kernel_entry = 0;
> +
> + object_initialize_child(OBJECT(machine), "soc", &s->soc,
> TYPE_CV1800B_SOC);
> + qdev_realize(DEVICE(&s->soc), NULL, &error_fatal);
> +
> + memory_region_add_subregion(system_memory,
> + cv1800b_memmap[CV1800B_DEV_DRAM].base,
> + machine->ram);
> +
> + riscv_boot_info_init(&boot_info, &s->soc.cpus);
> +
> + firmware_load_addr = cv1800b_memmap[CV1800B_DEV_DRAM].base;
> + firmware_end_addr = firmware_load_addr;
> + if (machine->firmware) {
This means the board will not run any firmware unless specified on the
command line. Was this the intent?
If your board can boot with the in-tree opensbi, the usual pattern is:
const char *firmware_name = riscv_default_firmware_name(&s->soc.cpus);
firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
&firmware_load_addr, NULL);
This handles checking if machine->firmware was set, falling back to
the default riscv64 opensbi, and handles `-bios none` and `-bios
default`.
> + firmware_end_addr = riscv_find_and_load_firmware(machine,
> machine->firmware,
> +
> &firmware_load_addr, NULL);
> + }
> +
> + if (machine->dtb) {
> + fdt_load_addr =
> riscv_compute_fdt_addr(cv1800b_memmap[CV1800B_DEV_DRAM].base,
> + machine->ram_size, machine,
> &boot_info);
> + rom_add_blob_fixed_as("fdt", machine->fdt, fdt_size, fdt_load_addr,
> + &address_space_memory);
This can be riscv_load_fdt().
> +
> +static const TypeInfo milkv_duo_machine_type_info = {
> + .name = TYPE_MILK_V_DUO,
> + .parent = TYPE_MACHINE,
> + .instance_size = sizeof(MilkVDuoState),
> + .class_init = milkv_duo_machine_class_init,
> + .interfaces = riscv64_machine_interfaces,
> +};
> +
> +static void milkv_duo_machine_register_types(void)
> +{
> + type_register_static(&milkv_duo_machine_type_info);
> +}
> +
> +type_init(milkv_duo_machine_register_types)
You can avoid some boiler plate by making milkv_duo_machine_type_info
an array and using DEFINE_TYPES()