If we're emulating EL3 then the EL3 guest firmware is responsible for providing the PSCI ABI, including reboot, core power down, etc. sbsa-ref machine has an embedded controller to do reboot, poweroff. Machine virt,secure=on can reuse this code to do reboot inside ATF.
Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org --- Hello,
This patch implements reboot for the secure machine inside ATF firmware. I.e. current qemu patch should be used with [1] ATF patch. It looks like that Embedded Controller qemu driver (sbsa-ec) can be common and widely used for other emulated machines. While if there are plans to extend sbsa-ec then we might find some other solution.
So for the long term it looks like machine virt was used as an initial playground for secure firmware. While the original intent was a runner for kvm guests. Relation between kvm guest and firmware is not very clear now. If everyone agree it might be good solution to move secure firmware things from virt machine to bsa-ref and make this machine reference for secure boot, firmware updates etc.
[1] https://github.com/muvarov/arm-trusted-firmware/commit/6d3339a0081f6f2b45d99...
Best regards, Maxim.
hw/arm/virt.c | 9 +++++++++ include/hw/arm/virt.h | 2 ++ 2 files changed, 11 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e465a988d6..6b77912f02 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -152,6 +152,7 @@ static const MemMapEntry base_memmap[] = { [VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN }, [VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN}, [VIRT_PVTIME] = { 0x090a0000, 0x00010000 }, + [VIRT_EC] = { 0x090c0000, 0x00001000 }, [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 }, @@ -1729,6 +1730,13 @@ static void virt_cpu_post_init(VirtMachineState *vms, int max_cpus, } }
+static void init_ec_controller(VirtMachineState *vms) +{ + vms->ec = qdev_new("sbsa-ec"); + + sysbus_mmio_map(SYS_BUS_DEVICE(vms->ec), 0, vms->memmap[VIRT_EC].base); +} + static void machvirt_init(MachineState *machine) { VirtMachineState *vms = VIRT_MACHINE(machine); @@ -1797,6 +1805,7 @@ static void machvirt_init(MachineState *machine) */ if (vms->secure && firmware_loaded) { vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED; + init_ec_controller(vms); } else if (vms->virt) { vms->psci_conduit = QEMU_PSCI_CONDUIT_SMC; } else { diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index aad6d69841..6f2ce4e4ff 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -85,6 +85,7 @@ enum { VIRT_ACPI_GED, VIRT_NVDIMM_ACPI, VIRT_PVTIME, + VIRT_EC, VIRT_LOWMEMMAP_LAST, };
@@ -163,6 +164,7 @@ struct VirtMachineState { DeviceState *gic; DeviceState *acpi_dev; Notifier powerdown_notifier; + DeviceState *ec; };
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)