From ffb07b043894ced11b591efdc6db34b12424d552 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Mon, 14 Dec 2020 10:17:44 +0000 Subject: [PATCH] plat/qemu: trigger reboot with secure pl061 Secure pl061 qemu driver allows to rize the GPIO pin from the secure world to reboot and power down virtual machine. Do not define secure-gpio for sbsa-ref platform due to reboot is done via sbsa-ec watchdog. Signed-off-by: Maxim Uvarov Change-Id: I508d7c5cf4c75cb169b34b00682a76f6761d3869 --- plat/qemu/common/qemu_bl31_setup.c | 10 ++++++++++ plat/qemu/common/qemu_pm.c | 16 ++++++++++++++++ plat/qemu/qemu/include/platform_def.h | 7 ++++++- plat/qemu/qemu/platform.mk | 2 ++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c index 4d36b0391..4f60eb163 100644 --- a/plat/qemu/common/qemu_bl31_setup.c +++ b/plat/qemu/common/qemu_bl31_setup.c @@ -7,6 +7,7 @@ #include #include +#include #include #include "qemu_private.h" @@ -69,9 +70,18 @@ void bl31_plat_arch_setup(void) BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); } +static void qemu_gpio_init(void) +{ +#ifdef SECURE_GPIO_BASE + pl061_gpio_init(); + pl061_gpio_register(SECURE_GPIO_BASE, 0); +#endif +} + void bl31_platform_setup(void) { plat_qemu_gic_init(); + qemu_gpio_init(); } unsigned int plat_get_syscnt_freq2(void) diff --git a/plat/qemu/common/qemu_pm.c b/plat/qemu/common/qemu_pm.c index cf800096f..c4ffcf922 100644 --- a/plat/qemu/common/qemu_pm.c +++ b/plat/qemu/common/qemu_pm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "qemu_private.h" @@ -201,16 +202,31 @@ void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state) /******************************************************************************* * Platform handlers to shutdown/reboot the system ******************************************************************************/ + static void __dead2 qemu_system_off(void) { +#ifdef SECURE_GPIO_BASE + ERROR("QEMU System Power off: with GPIO.\n"); + gpio_set_direction(SECURE_GPIO_POWEROFF, GPIO_DIR_OUT); + gpio_set_value(SECURE_GPIO_POWEROFF, GPIO_LEVEL_HIGH); + gpio_set_value(SECURE_GPIO_POWEROFF, GPIO_LEVEL_LOW); +#else semihosting_exit(ADP_STOPPED_APPLICATION_EXIT, 0); ERROR("QEMU System Off: semihosting call unexpectedly returned.\n"); +#endif panic(); } static void __dead2 qemu_system_reset(void) { + ERROR("QEMU System Reset: with GPIO.\n"); +#ifdef SECURE_GPIO_BASE + gpio_set_direction(SECURE_GPIO_RESET, GPIO_DIR_OUT); + gpio_set_value(SECURE_GPIO_RESET, GPIO_LEVEL_HIGH); + gpio_set_value(SECURE_GPIO_RESET, GPIO_LEVEL_LOW); +#else ERROR("QEMU System Reset: operation not handled.\n"); +#endif panic(); } diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index ed4b748af..9a85685b4 100644 --- a/plat/qemu/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -81,6 +81,11 @@ #define SEC_DRAM_BASE 0x0e100000 #define SEC_DRAM_SIZE 0x00f00000 +#define SECURE_GPIO_BASE 0x090b0000 +#define SECURE_GPIO_SIZE 0x00001000 +#define SECURE_GPIO_POWEROFF 0 +#define SECURE_GPIO_RESET 1 + /* Load pageable part of OP-TEE 2MB above secure DRAM base */ #define QEMU_OPTEE_PAGEABLE_LOAD_BASE (SEC_DRAM_BASE + 0x00200000) #define QEMU_OPTEE_PAGEABLE_LOAD_SIZE 0x00400000 @@ -202,7 +207,7 @@ #define DEVICE0_BASE 0x08000000 #define DEVICE0_SIZE 0x01000000 #define DEVICE1_BASE 0x09000000 -#define DEVICE1_SIZE 0x00041000 +#define DEVICE1_SIZE 0x00c00000 /* * GIC related constants diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 14bf049be..88a95c800 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -163,6 +163,8 @@ BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ plat/common/plat_psci_common.c \ + drivers/arm/pl061/pl061_gpio.c \ + drivers/gpio/gpio.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \ ${PLAT_QEMU_COMMON_PATH}/topology.c \ ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \