diff options
Diffstat (limited to 'hw/arm/vexpress.c')
-rw-r--r-- | hw/arm/vexpress.c | 141 |
1 files changed, 113 insertions, 28 deletions
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 7cbd13f182..84415c8b0a 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -157,7 +157,27 @@ static hwaddr motherboard_aseries_map[] = { typedef struct VEDBoardInfo VEDBoardInfo; -typedef void DBoardInitFn(const VEDBoardInfo *daughterboard, +typedef struct { + MachineClass parent; + VEDBoardInfo *daughterboard; +} VexpressMachineClass; + +typedef struct { + MachineState parent; + bool secure; +} VexpressMachineState; + +#define TYPE_VEXPRESS_MACHINE "vexpress" +#define TYPE_VEXPRESS_A9_MACHINE "vexpress-a9" +#define TYPE_VEXPRESS_A15_MACHINE "vexpress-a15" +#define VEXPRESS_MACHINE(obj) \ + OBJECT_CHECK(VexpressMachineState, (obj), TYPE_VEXPRESS_MACHINE) +#define VEXPRESS_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VexpressMachineClass, obj, TYPE_VEXPRESS_MACHINE) +#define VEXPRESS_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(VexpressMachineClass, klass, TYPE_VEXPRESS_MACHINE) + +typedef void DBoardInitFn(const VexpressMachineState *machine, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic); @@ -176,7 +196,7 @@ struct VEDBoardInfo { }; static void init_cpus(const char *cpu_model, const char *privdev, - hwaddr periphbase, qemu_irq *pic) + hwaddr periphbase, qemu_irq *pic, bool secure) { ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); DeviceState *dev; @@ -193,6 +213,10 @@ static void init_cpus(const char *cpu_model, const char *privdev, Object *cpuobj = object_new(object_class_get_name(cpu_oc)); Error *err = NULL; + if (!secure) { + object_property_set_bool(cpuobj, false, "has_el3", NULL); + } + if (object_property_find(cpuobj, "reset-cbar", NULL)) { object_property_set_int(cpuobj, periphbase, "reset-cbar", &error_abort); @@ -232,7 +256,7 @@ static void init_cpus(const char *cpu_model, const char *privdev, } } -static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, +static void a9_daughterboard_init(const VexpressMachineState *vms, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic) @@ -268,7 +292,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, memory_region_add_subregion(sysmem, 0x60000000, ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ - init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic); + init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic, vms->secure); /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */ @@ -322,7 +346,7 @@ static VEDBoardInfo a9_daughterboard = { .init = a9_daughterboard_init, }; -static void a15_daughterboard_init(const VEDBoardInfo *daughterboard, +static void a15_daughterboard_init(const VexpressMachineState *vms, ram_addr_t ram_size, const char *cpu_model, qemu_irq *pic) @@ -354,7 +378,7 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard, memory_region_add_subregion(sysmem, 0x80000000, ram); /* 0x2c000000 A15MPCore private memory region (GIC) */ - init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic); + init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic, vms->secure); /* A15 daughterboard peripherals: */ @@ -513,9 +537,11 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name, return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01"); } -static void vexpress_common_init(VEDBoardInfo *daughterboard, - MachineState *machine) +static void vexpress_common_init(MachineState *machine) { + VexpressMachineState *vms = VEXPRESS_MACHINE(machine); + VexpressMachineClass *vmc = VEXPRESS_MACHINE_GET_CLASS(machine); + VEDBoardInfo *daughterboard = vmc->daughterboard;; DeviceState *dev, *sysctl, *pl041; qemu_irq pic[64]; uint32_t sys_id; @@ -530,8 +556,7 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard, const hwaddr *map = daughterboard->motherboard_map; int i; - daughterboard->init(daughterboard, machine->ram_size, machine->cpu_model, - pic); + daughterboard->init(vms, machine->ram_size, machine->cpu_model, pic); /* * If a bios file was provided, attempt to map it into memory @@ -678,39 +703,99 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard, daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30; daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr; daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb; + /* Indicate that when booting Linux we should be in secure state */ + daughterboard->bootinfo.secure_boot = true; arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo); } -static void vexpress_a9_init(MachineState *machine) +static bool vexpress_get_secure(Object *obj, Error **errp) +{ + VexpressMachineState *vms = VEXPRESS_MACHINE(obj); + + return vms->secure; +} + +static void vexpress_set_secure(Object *obj, bool value, Error **errp) { - vexpress_common_init(&a9_daughterboard, machine); + VexpressMachineState *vms = VEXPRESS_MACHINE(obj); + + vms->secure = value; +} + +static void vexpress_instance_init(Object *obj) +{ + VexpressMachineState *vms = VEXPRESS_MACHINE(obj); + + /* EL3 is enabled by default on vexpress */ + vms->secure = true; + object_property_add_bool(obj, "secure", vexpress_get_secure, + vexpress_set_secure, NULL); + object_property_set_description(obj, "secure", + "Set on/off to enable/disable the ARM " + "Security Extensions (TrustZone)", + NULL); } -static void vexpress_a15_init(MachineState *machine) +static void vexpress_class_init(ObjectClass *oc, void *data) { - vexpress_common_init(&a15_daughterboard, machine); + MachineClass *mc = MACHINE_CLASS(oc); + + mc->name = TYPE_VEXPRESS_MACHINE; + mc->desc = "ARM Versatile Express"; + mc->init = vexpress_common_init; + mc->block_default_type = IF_SCSI; + mc->max_cpus = 4; } -static QEMUMachine vexpress_a9_machine = { - .name = "vexpress-a9", - .desc = "ARM Versatile Express for Cortex-A9", - .init = vexpress_a9_init, - .block_default_type = IF_SCSI, - .max_cpus = 4, +static void vexpress_a9_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc); + + mc->name = TYPE_VEXPRESS_A9_MACHINE; + mc->desc = "ARM Versatile Express for Cortex-A9"; + + vmc->daughterboard = &a9_daughterboard;; +} + +static void vexpress_a15_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc); + + mc->name = TYPE_VEXPRESS_A15_MACHINE; + mc->desc = "ARM Versatile Express for Cortex-A15"; + + vmc->daughterboard = &a15_daughterboard; +} + +static const TypeInfo vexpress_info = { + .name = TYPE_VEXPRESS_MACHINE, + .parent = TYPE_MACHINE, + .abstract = true, + .instance_size = sizeof(VexpressMachineState), + .instance_init = vexpress_instance_init, + .class_size = sizeof(VexpressMachineClass), + .class_init = vexpress_class_init, +}; + +static const TypeInfo vexpress_a9_info = { + .name = TYPE_VEXPRESS_A9_MACHINE, + .parent = TYPE_VEXPRESS_MACHINE, + .class_init = vexpress_a9_class_init, }; -static QEMUMachine vexpress_a15_machine = { - .name = "vexpress-a15", - .desc = "ARM Versatile Express for Cortex-A15", - .init = vexpress_a15_init, - .block_default_type = IF_SCSI, - .max_cpus = 4, +static const TypeInfo vexpress_a15_info = { + .name = TYPE_VEXPRESS_A15_MACHINE, + .parent = TYPE_VEXPRESS_MACHINE, + .class_init = vexpress_a15_class_init, }; static void vexpress_machine_init(void) { - qemu_register_machine(&vexpress_a9_machine); - qemu_register_machine(&vexpress_a15_machine); + type_register_static(&vexpress_info); + type_register_static(&vexpress_a9_info); + type_register_static(&vexpress_a15_info); } machine_init(vexpress_machine_init); |