hw/hppa: Add power button emulation

Emulate a power button switch, tell SeaBIOS the address via fw_cfg and
bind the power button to the qemu UI.

Signed-off-by: Helge Deller <deller@gmx.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Helge Deller 2020-08-26 17:45:43 +02:00
parent 245760074a
commit b28c4a6497

View file

@ -12,6 +12,7 @@
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "sysemu/reset.h" #include "sysemu/reset.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/runstate.h"
#include "hw/rtc/mc146818rtc.h" #include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h" #include "hw/timer/i8254.h"
#include "hw/char/serial.h" #include "hw/char/serial.h"
@ -27,6 +28,30 @@
#define MIN_SEABIOS_HPPA_VERSION 1 /* require at least this fw version */ #define MIN_SEABIOS_HPPA_VERSION 1 /* require at least this fw version */
#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
static void hppa_powerdown_req(Notifier *n, void *opaque)
{
hwaddr soft_power_reg = HPA_POWER_BUTTON;
uint32_t val;
val = ldl_be_phys(&address_space_memory, soft_power_reg);
if ((val >> 8) == 0) {
/* immediately shut down when under hardware control */
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
return;
}
/* clear bit 31 to indicate that the power switch was pressed. */
val &= ~1;
stl_be_phys(&address_space_memory, soft_power_reg, val);
}
static Notifier hppa_system_powerdown_notifier = {
.notify = hppa_powerdown_req
};
static ISABus *hppa_isa_bus(void) static ISABus *hppa_isa_bus(void)
{ {
ISABus *isa_bus; ISABus *isa_bus;
@ -86,6 +111,10 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries", fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(HPA_POWER_BUTTON);
fw_cfg_add_file(fw_cfg, "/etc/power-button-addr",
g_memdup(&val, sizeof(val)), sizeof(val));
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_order[0]); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_order[0]);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
@ -177,6 +206,9 @@ static void machine_hppa_init(MachineState *machine)
} }
} }
/* register power switch emulation */
qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
/* Load firmware. Given that this is not "real" firmware, /* Load firmware. Given that this is not "real" firmware,
but one explicitly written for the emulation, we might as but one explicitly written for the emulation, we might as
well load it directly from an ELF image. */ well load it directly from an ELF image. */