diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-12-23 15:05:22 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-12-23 15:05:22 +0000 |
commit | ab0302ee764fd702465aef6d88612cdff4302809 (patch) | |
tree | 4f7ba47706d9e60c5dc731159030280c2cd7b5a9 /hw/arm/vexpress.c | |
parent | 03de06dde54df1f64bb099efe22edfa773b16e8e (diff) | |
parent | aa351061dbb0e3054db11c00a69395785c4186c8 (diff) |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20141223' into staging
target-arm queue:
* enable 32-bit EL3 (TrustZone) for vexpress and virt boards
* add fw_cfg device to virt board for UEFI firmware config
* support passing commandline kernel/initrd to firmware
# gpg: Signature made Tue 23 Dec 2014 13:50:33 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
* remotes/pmaydell/tags/pull-target-arm-20141223: (31 commits)
hw/arm/virt: enable passing of EFI-stubbed kernel to guest UEFI firmware
hw/arm: pass pristine kernel image to guest firmware over fw_cfg
hw/loader: split out load_image_gzipped_buffer()
arm: add fw_cfg to "virt" board
fw_cfg_mem: expose the "data_width" property with fw_cfg_init_mem_wide()
fw_cfg_mem: introduce the "data_width" property
exec: allows 8-byte accesses in subpage_ops
fw_cfg_mem: flip ctl_mem_ops and data_mem_ops to DEVICE_BIG_ENDIAN
fw_cfg_mem: max access size and region size are the same for data register
fw_cfg: move boards to fw_cfg_init_io() / fw_cfg_init_mem()
fw_cfg: hard separation between the MMIO and I/O port mappings
target-arm: add cpu feature EL3 to CPUs with Security Extensions
target-arm: Disable EL3 on unsupported machines
target-arm: Breakout integratorcp and versatilepb cpu init
target-arm: Set CPU has_el3 prop during virt init
target-arm: Enable CPU has_el3 prop during VE init
target-arm: Add arm_boot_info secure_boot control
target-arm: Add ARMCPU secure property
target-arm: Add feature unset function
target-arm: Add virt machine secure property
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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); |