瀏覽代碼

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>
Helge Deller 5 年之前
父節點
當前提交
b28c4a6497
共有 1 個文件被更改,包括 32 次插入0 次删除
  1. 32 0
      hw/hppa/machine.c

+ 32 - 0
hw/hppa/machine.c

@@ -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.  */