ioemu: HVM virtual S3
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 20 May 2008 13:28:19 +0000 (14:28 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 20 May 2008 13:28:19 +0000 (14:28 +0100)
  - add S3 suspend logic in PM1A control register. when guest write
    specific value to this register,
    QEMU will trigger S3 sleep by
    * reset all qemu device
    * set CMOS shutdown status as S3 resume, so that rombios will do
      S3 resume later
    * request Xen to S3-suspend the guest

Signed-off-by: Yu Ke <ke.yu@intel.com>
Signed-off-by: Liping Ke <liping.ke@intel.com?
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/ioemu/hw/pc.c
tools/ioemu/hw/piix4acpi.c
tools/ioemu/target-i386-dm/helper2.c
tools/ioemu/vl.h

index 9731ef0aacb7ccd8e0c79e06f8c64a4af2b0690d..3835191ac100c0409c41da588f541e78847d509b 100644 (file)
@@ -1121,6 +1121,14 @@ static void pc_init_isa(uint64_t ram_size, int vga_ram_size, char *boot_device,
              initrd_filename, 0, NULL);
 }
 
+/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
+   BIOS will read it and start S3 resume at POST Entry*/
+void cmos_set_s3_resume(void)
+{
+    if (rtc_state)
+        rtc_set_memory(rtc_state, 0xF, 0xFE);
+}
+
 QEMUMachine pc_machine = {
     "pc",
     "Standard PC",
index a4ebfc4163f6b495c3573766a89555000ff4d39b..f084c8ec6528f5bfbc2cc49253c7be320838fe84 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "vl.h"
 #include <xen/hvm/ioreq.h>
+#include <xen/hvm/params.h>
 
 /* PM1a_CNT bits, as defined in the ACPI specification. */
 #define SCI_EN            (1 <<  0)
@@ -35,6 +36,7 @@
 /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */
 /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */
 #define SLP_TYP_S4        (6 << 10)
+#define SLP_TYP_S3        (5 << 10)
 #define SLP_TYP_S5        (7 << 10)
 
 #define ACPI_DBG_IO_ADDR  0xb044
@@ -79,6 +81,8 @@ typedef struct PHPSlots {
 
 PHPSlots php_slots;
 
+int s3_shutdown_flag;
+
 static void piix4acpi_save(QEMUFile *f, void *opaque)
 {
     PCIAcpiState *s = opaque;
@@ -118,6 +122,13 @@ static void acpi_shutdown(uint32_t val)
         return;
 
     switch (val & SLP_TYP_Sx) {
+    case SLP_TYP_S3:
+        s3_shutdown_flag = 1;
+        qemu_system_reset();
+        s3_shutdown_flag = 0;
+        cmos_set_s3_resume();
+        xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3);
+        break;
     case SLP_TYP_S4:
     case SLP_TYP_S5:
         qemu_system_shutdown_request();
index 16623e90b3cc44b0866e633448fabe46ad280d63..c7b0820ed8d703129e874061e35373e39f7c4ced 100644 (file)
@@ -133,8 +133,12 @@ CPUX86State *cpu_x86_init(void)
 /* called from main_cpu_reset */
 void cpu_reset(CPUX86State *env)
 {
+    extern int s3_shutdown_flag;
     int xcHandle;
     int sts;
+    if (s3_shutdown_flag)
+        return;
 
     xcHandle = xc_interface_open();
     if (xcHandle < 0)
index 705878cba2132c7a19f2dd3e323bd8e3bbcb0a50..1c7ff42fc60ce441c44177b988ca611455022ec5 100644 (file)
@@ -1181,6 +1181,7 @@ extern int fd_bootchk;
 
 void ioport_set_a20(int enable);
 int ioport_get_a20(void);
+void cmos_set_s3_resume(void);
 
 /* ppc.c */
 extern QEMUMachine prep_machine;