diff options
Diffstat (limited to 'qemu/hw/arm/highbank.c')
-rw-r--r-- | qemu/hw/arm/highbank.c | 121 |
1 files changed, 73 insertions, 48 deletions
diff --git a/qemu/hw/arm/highbank.c b/qemu/hw/arm/highbank.c index f8353a787..d9930c0d3 100644 --- a/qemu/hw/arm/highbank.c +++ b/qemu/hw/arm/highbank.c @@ -17,11 +17,14 @@ * */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "hw/arm/arm.h" #include "hw/devices.h" #include "hw/loader.h" #include "net/net.h" +#include "sysemu/kvm.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "sysemu/block-backend.h" @@ -32,10 +35,19 @@ #define SMP_BOOT_REG 0x40 #define MPCORE_PERIPHBASE 0xfff10000 +#define MVBAR_ADDR 0x200 +#define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t)) + #define NIRQ_GIC 160 /* Board init. */ +static void hb_write_board_setup(ARMCPU *cpu, + const struct arm_boot_info *info) +{ + arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR); +} + static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info) { int n; @@ -223,52 +235,37 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) MemoryRegion *sysmem; char *sysboot_filename; - if (!cpu_model) { - switch (machine_id) { - case CALXEDA_HIGHBANK: - cpu_model = "cortex-a9"; - break; - case CALXEDA_MIDWAY: - cpu_model = "cortex-a15"; - break; - } + switch (machine_id) { + case CALXEDA_HIGHBANK: + cpu_model = "cortex-a9"; + break; + case CALXEDA_MIDWAY: + cpu_model = "cortex-a15"; + break; } for (n = 0; n < smp_cpus; n++) { ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); Object *cpuobj; ARMCPU *cpu; - Error *err = NULL; - - if (!oc) { - error_report("Unable to find CPU definition"); - exit(1); - } cpuobj = object_new(object_class_get_name(oc)); cpu = ARM_CPU(cpuobj); - /* By default A9 and A15 CPUs have EL3 enabled. This board does not - * currently support EL3 so the CPU EL3 property is disabled before - * realization. - */ - if (object_property_find(cpuobj, "has_el3", NULL)) { - object_property_set_bool(cpuobj, false, "has_el3", &err); - if (err) { - error_report_err(err); - exit(1); - } + object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC, + "psci-conduit", &error_abort); + + if (n) { + /* Secondary CPUs start in PSCI powered-down state */ + object_property_set_bool(cpuobj, true, + "start-powered-off", &error_abort); } if (object_property_find(cpuobj, "reset-cbar", NULL)) { object_property_set_int(cpuobj, MPCORE_PERIPHBASE, "reset-cbar", &error_abort); } - object_property_set_bool(cpuobj, true, "realized", &err); - if (err) { - error_report_err(err); - exit(1); - } + object_property_set_bool(cpuobj, true, "realized", &error_fatal); cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ); } @@ -281,17 +278,19 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) sysram = g_new(MemoryRegion, 1); memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000, - &error_abort); + &error_fatal); memory_region_add_subregion(sysmem, 0xfff88000, sysram); if (bios_name != NULL) { sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (sysboot_filename != NULL) { if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) { - hw_error("Unable to load %s\n", bios_name); + error_report("Unable to load %s", bios_name); + exit(1); } g_free(sysboot_filename); } else { - hw_error("Unable to find %s\n", bios_name); + error_report("Unable to find %s", bios_name); + exit(1); } } @@ -378,6 +377,16 @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) highbank_binfo.loader_start = 0; highbank_binfo.write_secondary_boot = hb_write_secondary; highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary; + if (!kvm_enabled()) { + highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR; + highbank_binfo.write_board_setup = hb_write_board_setup; + highbank_binfo.secure_board_setup = true; + } else { + error_report("WARNING: cannot load built-in Monitor support " + "if KVM is enabled. Some guests (such as Linux) " + "may not boot."); + } + arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo); } @@ -391,26 +400,42 @@ static void midway_init(MachineState *machine) calxeda_init(machine, CALXEDA_MIDWAY); } -static QEMUMachine highbank_machine = { - .name = "highbank", - .desc = "Calxeda Highbank (ECX-1000)", - .init = highbank_init, - .block_default_type = IF_SCSI, - .max_cpus = 4, +static void highbank_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Calxeda Highbank (ECX-1000)"; + mc->init = highbank_init; + mc->block_default_type = IF_SCSI; + mc->max_cpus = 4; +} + +static const TypeInfo highbank_type = { + .name = MACHINE_TYPE_NAME("highbank"), + .parent = TYPE_MACHINE, + .class_init = highbank_class_init, }; -static QEMUMachine midway_machine = { - .name = "midway", - .desc = "Calxeda Midway (ECX-2000)", - .init = midway_init, - .block_default_type = IF_SCSI, - .max_cpus = 4, +static void midway_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "Calxeda Midway (ECX-2000)"; + mc->init = midway_init; + mc->block_default_type = IF_SCSI; + mc->max_cpus = 4; +} + +static const TypeInfo midway_type = { + .name = MACHINE_TYPE_NAME("midway"), + .parent = TYPE_MACHINE, + .class_init = midway_class_init, }; static void calxeda_machines_init(void) { - qemu_register_machine(&highbank_machine); - qemu_register_machine(&midway_machine); + type_register_static(&highbank_type); + type_register_static(&midway_type); } -machine_init(calxeda_machines_init); +type_init(calxeda_machines_init) |