WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 8/12] Enable ACPI sleep in Linux

To: "Keir Fraser" <Keir.Fraser@xxxxxxxxxxxx>, "Ian Pratt" <m+Ian.Pratt@xxxxxxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 8/12] Enable ACPI sleep in Linux
From: "Tian, Kevin" <kevin.tian@xxxxxxxxx>
Date: Wed, 14 Feb 2007 17:17:12 +0800
Cc: "Yu, Ke" <ke.yu@xxxxxxxxx>
Delivery-date: Wed, 14 Feb 2007 01:17:28 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcdQGOkJ8KWFRpHBQX24yid+5KyMgQ==
Thread-topic: [PATCH 8/12] Enable ACPI sleep in Linux
Open CONFIG_ACPI_SLEEP in xenlinux, to enable ACPI based
power management. Basically, user can trigger power event
now by "echo *** > /sys/power/state". Also gear to pm
interface defined between xenlinux and Xen.

Signed-off-by Ke Yu <ke.yu@xxxxxxxxx>
Signed-off-by Kevin Tian <kevin.tian@xxxxxxxxx>

diff -r 0d3d91f87abd buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32   Tue Feb 13 16:40:58 2007
+0800
+++ b/buildconfigs/linux-defconfig_xen_x86_32   Tue Feb 13 16:40:59 2007
+0800
@@ -205,6 +205,9 @@ CONFIG_PM=y
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_SLEEP_PROC_SLEEP=y
 CONFIG_ACPI_AC=m
 CONFIG_ACPI_BATTERY=m
 CONFIG_ACPI_BUTTON=m
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig    Tue Feb 13 16:40:58 2007
+0800
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig    Tue Feb 13 16:40:59 2007
+0800
@@ -816,6 +816,11 @@ config HOTPLUG_CPU
          Say Y here to experiment with turning CPUs off and on, and to
          enable suspend on SMP systems. CPUs can be controlled through
          /sys/devices/system/cpu.
+
+config SUSPEND_SMP
+       bool
+       depends on HOTPLUG_CPU && X86 && PM
+       default y
 
 config COMPAT_VDSO
        bool "Compat VDSO support"
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c  Tue Feb 13
16:40:59 2007 +0800
@@ -851,9 +851,9 @@ static int timer_resume(struct sys_devic
        return 0;
 }
 
+void time_resume(void);
 static struct sysdev_class timer_sysclass = {
-       .resume = timer_resume,
-       .suspend = timer_suspend,
+       .resume = time_resume,
        set_kset_name("timer"),
 };
 
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/power/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/power/Makefile     Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/arch/i386/power/Makefile     Tue Feb 13
16:40:59 2007 +0800
@@ -2,3 +2,8 @@ obj-$(CONFIG_SOFTWARE_SUSPEND)  += cpu.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += cpu.o
 obj-$(CONFIG_ACPI_SLEEP)       += cpu.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r 0d3d91f87abd linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c    Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c    Tue Feb 13
16:40:59 2007 +0800
@@ -62,11 +62,12 @@ static void do_fpu_end(void)
 
 static void fix_processor_context(void)
 {
+#ifndef CONFIG_X86_NO_TSS
        int cpu = smp_processor_id();
        struct tss_struct * t = &per_cpu(init_tss, cpu);
 
        set_tss_desc(cpu,t);    /* This just modifies memory; should not
be necessary. But... This is necessary, because 386 hardware has concept
of busy TSS or some similar stupidity. */
-
+#endif
        load_TR_desc();                         /* This does ltr */
        load_LDT(&current->active_mm->context); /* This does lldt */
 
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/Kconfig
--- a/linux-2.6-xen-sparse/drivers/acpi/Kconfig Tue Feb 13 16:40:58 2007
+0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/Kconfig Tue Feb 13 16:40:59 2007
+0800
@@ -45,7 +45,7 @@ if ACPI
 
 config ACPI_SLEEP
        bool "Sleep States"
-       depends on X86 && (!SMP || SUSPEND_SMP) && !XEN
+       depends on X86 && (!SMP || SUSPEND_SMP)
        depends on PM
        default y
        ---help---
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile       Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile       Tue Feb
13 16:40:59 2007 +0800
@@ -7,3 +7,8 @@ obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
 obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r 0d3d91f87abd
linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c  Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c  Tue Feb
13 16:49:22 2007 +0800
@@ -209,6 +209,34 @@ acpi_status acpi_enter_sleep_state_prep(
 
 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
 
+#ifdef CONFIG_XEN
+#include <asm/hypervisor.h>
+#include <xen/interface/platform.h>
+extern unsigned long acpi_video_flags;
+extern unsigned long saved_videomode;
+static acpi_status acpi_notify_xen_state(u8 sleep_state,
+       u32 pm1a_cnt, u32 pm1b_cnt)
+{
+       struct xen_platform_op op = {
+               .cmd = XENPF_enter_acpi_sleep,
+               .interface_version = XENPF_INTERFACE_VERSION,
+               .u = {
+                       .enter_acpi_sleep = {
+                               .pm1a_cnt_val = (u16)pm1a_cnt,
+                               .pm1b_cnt_val = (u16)pm1b_cnt,
+                               .sleep_state = sleep_state,
+                       },
+               },
+       };
+
+#ifdef CONFIG_X86
+       op.u.enter_acpi_sleep.video_flags = acpi_video_flags;
+       op.u.enter_acpi_sleep.video_mode = saved_videomode;
+#endif
+
+       return HYPERVISOR_platform_op(&op);
+}
+#endif
 
/***********************************************************************
********
  *
  * FUNCTION:    acpi_enter_sleep_state
@@ -304,6 +332,7 @@ acpi_status asmlinkage acpi_enter_sleep_
 
        /* Write #1: fill in SLP_TYP data */
 
+#ifndef CONFIG_XEN
        status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
                                        ACPI_REGISTER_PM1A_CONTROL,
                                        PM1Acontrol);
@@ -314,6 +343,10 @@ acpi_status asmlinkage acpi_enter_sleep_
        status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
                                        ACPI_REGISTER_PM1B_CONTROL,
                                        PM1Bcontrol);
+#else
+       status = acpi_notify_xen_state(sleep_state,
+                       PM1Acontrol, PM1Bcontrol);
+#endif
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -327,6 +360,7 @@ acpi_status asmlinkage acpi_enter_sleep_
 
        ACPI_FLUSH_CPU_CACHE();
 
+#ifndef CONFIG_XEN
        status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
                                        ACPI_REGISTER_PM1A_CONTROL,
                                        PM1Acontrol);
@@ -337,6 +371,10 @@ acpi_status asmlinkage acpi_enter_sleep_
        status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
                                        ACPI_REGISTER_PM1B_CONTROL,
                                        PM1Bcontrol);
+#else
+       status = acpi_notify_xen_state(sleep_state,
+                       PM1Acontrol, PM1Bcontrol);
+#endif
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile  Tue Feb 13
16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile  Tue Feb 13
16:40:59 2007 +0800
@@ -3,3 +3,8 @@ obj-$(CONFIG_ACPI_SLEEP_PROC_FS)        += proc
 obj-$(CONFIG_ACPI_SLEEP_PROC_FS)       += proc.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r 0d3d91f87abd linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c        Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c        Tue Feb
13 16:50:03 2007 +0800
@@ -75,12 +75,15 @@ static int acpi_pm_enter(suspend_state_t
 
        ACPI_FLUSH_CPU_CACHE();
 
+#ifndef CONFIG_XEN
+       /* Covered by Xen */
        /* Do arch specific saving of state. */
        if (pm_state > PM_SUSPEND_STANDBY) {
                int error = acpi_save_state_mem();
                if (error)
                        return error;
        }
+#endif
 
        local_irq_save(flags);
        acpi_enable_wakeup_device(acpi_state);
@@ -91,7 +94,14 @@ static int acpi_pm_enter(suspend_state_t
                break;
 
        case PM_SUSPEND_MEM:
+#ifdef CONFIG_XEN
+               /* XEN hyperviosr will save and restore CPU context
+                * and then we can skip low level housekeeping here.
+                */
+               acpi_enter_sleep_state(acpi_state);
+#else
                do_suspend_lowlevel();
+#endif
                break;
 
        case PM_SUSPEND_DISK:
@@ -121,8 +131,10 @@ static int acpi_pm_enter(suspend_state_t
         * And, in the case of the latter, the memory image should have
already
         * been loaded from disk.
         */
+#ifndef CONFIG_XEN
        if (pm_state > PM_SUSPEND_STANDBY)
                acpi_restore_state_mem();
+#endif
 
        return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
@@ -145,10 +157,12 @@ static int acpi_pm_finish(suspend_state_
        /* reset firmware waking vector */
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
 
+#ifndef CONFIG_XEN
        if (init_8259A_after_S1) {
                printk("Broken toshiba laptop -> kicking interrupts\n");
                init_8259A(0);
        }
+#endif
        return 0;
 }
 
@@ -199,6 +213,46 @@ static struct dmi_system_id __initdata a
         },
        {},
 };
+
+#ifdef CONFIG_XEN
+#include <asm/hypervisor.h>
+#include <xen/interface/platform.h>
+/* Register sleep info to xen hypervisor which does real work later */
+static acpi_status acpi_register_sleep_info(void)
+{
+       struct xen_platform_op op;
+       acpi_status status;
+
+       if (acpi_gbl_FADT == NULL) {
+               printk(KERN_WARNING "%s: ACPI FADT not existed\n",
+                               __FUNCTION__);
+               return AE_NO_ACPI_TABLES;
+       }
+
+       op.cmd = XENPF_set_acpi_sleep;
+       op.interface_version = XENPF_INTERFACE_VERSION;
+       op.u.set_acpi_sleep.pm1a_cnt_port =
+               (u16)acpi_gbl_FADT->xpm1a_cnt_blk.address;
+       op.u.set_acpi_sleep.pm1b_cnt_port =
+               (u16)acpi_gbl_FADT->xpm1b_cnt_blk.address;
+       op.u.set_acpi_sleep.pm1a_evt_port =
+               (u16)acpi_gbl_FADT->xpm1a_evt_blk.address;
+       op.u.set_acpi_sleep.pm1b_evt_port =
+               (u16)acpi_gbl_FADT->xpm1b_evt_blk.address;
+
+       status  = HYPERVISOR_platform_op(&op);
+
+       if (ACPI_FAILURE(status)){
+               printk(KERN_WARNING "%s: Fail to register acpi sleep
info,"
+                               "Xen sleep will not work\n",
__FUNCTION__);
+               return (status);
+       }
+
+       acpi_wakeup_address = (unsigned long)
+               op.u.set_acpi_sleep.xen_waking_vec;
+       return status;
+}
+#endif /* CONFIG_XEN */
 
 static int __init acpi_sleep_init(void)
 {
@@ -226,6 +280,10 @@ static int __init acpi_sleep_init(void)
        printk(")\n");
 
        pm_set_ops(&acpi_pm_ops);
+
+#ifdef CONFIG_XEN
+       acpi_register_sleep_info();
+#endif
        return 0;
 }
 
diff -r 0d3d91f87abd
linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c    Tue Feb
13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c    Tue Feb
13 16:40:59 2007 +0800
@@ -25,9 +25,14 @@ int acpi_sleep_prepare(u32 acpi_state)
                if (!acpi_wakeup_address) {
                        return -EFAULT;
                }
+#ifndef CONFIG_XEN
                acpi_set_firmware_waking_vector((acpi_physical_address)
                                                virt_to_phys((void *)
 
acpi_wakeup_address));
+#else
+               acpi_set_firmware_waking_vector((acpi_physical_address)
+                                               acpi_wakeup_address);
+#endif
 
        }
        ACPI_FLUSH_CPU_CACHE();
diff -r 0d3d91f87abd
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
Tue Feb 13 16:40:58 2007 +0800
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
Tue Feb 13 16:40:59 2007 +0800
@@ -402,6 +402,12 @@ HYPERVISOR_kexec_op(
        return _hypercall2(int, kexec_op, op, args);
 }
 
+static inline long
+HYPERVISOR_platform_op(
+       void* arg)
+{
+       return _hypercall1(long, platform_op, arg);
+}
 
 
 #endif /* __HYPERCALL_H__ */

Attachment: enable_linux_acpi_sleep.patch
Description: enable_linux_acpi_sleep.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 8/12] Enable ACPI sleep in Linux, Tian, Kevin <=