Introduce an abstract E2000 machine class and keep the Phytium Pi board strap fixed to SD0. Pass the selected backend and boot-mode property to the PBR device so firmware-visible boot-media state is owned by PBR rather than a user-settable machine option.
The class-level selection also provides the board-specific hook required by a later E2000Q COMe machine without allowing either board to change its physical boot strap. Signed-off-by: Bin Meng <[email protected]> --- hw/arm/phytium_e2000.c | 84 +++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c index 1f2642df13..fe362dd4bd 100644 --- a/hw/arm/phytium_e2000.c +++ b/hw/arm/phytium_e2000.c @@ -44,8 +44,12 @@ #include "target/arm/cpu-qom.h" #include "target/arm/gtimer.h" +#define TYPE_PHYTIUM_E2000_MACHINE \ + MACHINE_TYPE_NAME("phytium-e2000-base") +OBJECT_DECLARE_TYPE(PhytiumE2000State, PhytiumE2000MachineClass, + PHYTIUM_E2000_MACHINE) + #define TYPE_PHYTIUM_PI MACHINE_TYPE_NAME("phytium-pi") -OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000State, PHYTIUM_PI) #define PHYTIUM_E2000_NUM_CPUS 4 #define PHYTIUM_E2000_NUM_IRQS 256 @@ -100,7 +104,7 @@ enum { }; struct PhytiumE2000State { - MachineState parent; + MachineState parent_obj; struct arm_boot_info bootinfo; DeviceState *gic; DeviceState *qspi; @@ -113,6 +117,13 @@ struct PhytiumE2000State { MemoryRegion ram_high; }; +struct PhytiumE2000MachineClass { + MachineClass parent_class; + + const char *machine_name; + const char *pbr_boot_mode; +}; + /* * Keep the physical addresses used by the vendor firmware even before every * device behind them is modeled. In particular, boot SRAM carries PBR/PBF @@ -436,11 +447,16 @@ static void phytium_e2000_create_pcie(PhytiumE2000State *s) } } -static void phytium_e2000_reject_legacy_firmware(MachineState *ms) +static void phytium_e2000_reject_legacy_firmware( + MachineState *ms, PhytiumE2000MachineClass *pemc) { if (ms->firmware || drive_get(IF_PFLASH, 0, 0)) { - error_report("phytium-pi: -bios and pflash firmware are not " - "supported; use an if=sd,index=0 image"); + error_report("%s: -bios and pflash firmware are not supported; " + "use an if=%s,index=0 image", + pemc->machine_name, + !strcmp(pemc->pbr_boot_mode, + PHYTIUM_E2000_PBR_BOOT_MODE_QSPI) ? + "mtd" : "sd"); exit(1); } } @@ -509,13 +525,17 @@ static void phytium_e2000_create_qspi(PhytiumE2000State *s) static bool phytium_e2000_create_pbr(PhytiumE2000State *s) { MachineState *ms = MACHINE(s); + PhytiumE2000MachineClass *pemc = + PHYTIUM_E2000_MACHINE_GET_CLASS(s); DeviceState *dev = qdev_new(TYPE_PHYTIUM_E2000_PBR); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); BlockBackend *boot_blk = NULL; uint64_t cpu_mpidrs[PHYTIUM_E2000_NUM_CPUS]; int i; - if (!ms->kernel_filename) { + if (!ms->kernel_filename && + !strcmp(pemc->pbr_boot_mode, + PHYTIUM_E2000_PBR_BOOT_MODE_SD0)) { boot_blk = phytium_e2000_sd_blk(0); } @@ -523,8 +543,7 @@ static bool phytium_e2000_create_pbr(PhytiumE2000State *s) cpu_mpidrs[i] = phytium_e2000_cpu_mp_affinity(i); } - qdev_prop_set_string(dev, "boot-mode", - PHYTIUM_E2000_PBR_BOOT_MODE_SD0); + qdev_prop_set_string(dev, "boot-mode", pemc->pbr_boot_mode); phytium_e2000_pbr_configure(PHYTIUM_E2000_PBR(dev), boot_blk, phytium_e2000_memmap[ PHYTIUM_E2000_RAM].base, @@ -735,19 +754,21 @@ static void phytium_e2000_create_cpus(PhytiumE2000State *s, } } -static void phytium_pi_init(MachineState *ms) +static void phytium_e2000_init(MachineState *ms) { - PhytiumE2000State *s = PHYTIUM_PI(ms); + PhytiumE2000State *s = PHYTIUM_E2000_MACHINE(ms); + PhytiumE2000MachineClass *pemc = + PHYTIUM_E2000_MACHINE_GET_CLASS(ms); bool firmware_loaded; int i; if (kvm_enabled()) { - error_report("phytium-pi: KVM is not supported"); + error_report("%s: KVM is not supported", pemc->machine_name); exit(1); } if (ms->smp.cpus > PHYTIUM_E2000_NUM_CPUS) { - error_report("phytium-pi supports at most %d CPUs", + error_report("%s supports at most %d CPUs", pemc->machine_name, PHYTIUM_E2000_NUM_CPUS); exit(1); } @@ -755,11 +776,11 @@ static void phytium_pi_init(MachineState *ms) if (ms->ram_size > phytium_e2000_memmap[PHYTIUM_E2000_RAM].size + phytium_e2000_memmap[PHYTIUM_E2000_RAM_HIGH].size) { - error_report("phytium-pi supports at most 8 GiB RAM"); + error_report("%s supports at most 8 GiB RAM", pemc->machine_name); exit(1); } - phytium_e2000_reject_legacy_firmware(ms); + phytium_e2000_reject_legacy_firmware(ms, pemc); phytium_e2000_create_ram(s); phytium_e2000_create_unimplemented(); @@ -822,7 +843,7 @@ static const CPUArchIdList *phytium_e2000_possible_cpu_arch_ids(MachineState *ms return ms->possible_cpus; } -static void phytium_pi_class_init(ObjectClass *oc, const void *data) +static void phytium_e2000_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char * const valid_cpu_types[] = { @@ -831,8 +852,7 @@ static void phytium_pi_class_init(ObjectClass *oc, const void *data) NULL, }; - mc->init = phytium_pi_init; - mc->desc = "Phytium Pi board (Phytium E2000Q)"; + mc->init = phytium_e2000_init; mc->default_cpu_type = ARM_CPU_TYPE_NAME("phytium-ftc664"); mc->valid_cpu_types = valid_cpu_types; mc->max_cpus = PHYTIUM_E2000_NUM_CPUS; @@ -844,22 +864,42 @@ static void phytium_pi_class_init(ObjectClass *oc, const void *data) mc->default_ram_size = 2 * GiB; mc->default_ram_id = "phytium-e2000.ram"; mc->minimum_page_bits = 12; - mc->block_default_type = IF_SD; mc->no_cdrom = 1; mc->possible_cpu_arch_ids = phytium_e2000_possible_cpu_arch_ids; } +static void phytium_pi_class_init(ObjectClass *oc, const void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + PhytiumE2000MachineClass *pemc = + PHYTIUM_E2000_MACHINE_CLASS(oc); + + mc->desc = "Phytium Pi board (Phytium E2000Q)"; + mc->block_default_type = IF_SD; + pemc->machine_name = "phytium-pi"; + pemc->pbr_boot_mode = PHYTIUM_E2000_PBR_BOOT_MODE_SD0; +} + +static const TypeInfo phytium_e2000_base_info = { + .name = TYPE_PHYTIUM_E2000_MACHINE, + .parent = TYPE_MACHINE, + .abstract = true, + .class_init = phytium_e2000_class_init, + .class_size = sizeof(PhytiumE2000MachineClass), + .instance_size = sizeof(PhytiumE2000State), +}; + static const TypeInfo phytium_pi_info = { .name = TYPE_PHYTIUM_PI, - .parent = TYPE_MACHINE, + .parent = TYPE_PHYTIUM_E2000_MACHINE, .class_init = phytium_pi_class_init, - .instance_size = sizeof(PhytiumE2000State), .interfaces = aarch64_machine_interfaces, }; -static void phytium_pi_machine_init(void) +static void phytium_e2000_machine_init(void) { + type_register_static(&phytium_e2000_base_info); type_register_static(&phytium_pi_info); } -type_init(phytium_pi_machine_init); +type_init(phytium_e2000_machine_init); -- 2.53.0
