All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Tian, Kevin" <kevin.tian@intel.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH 8/12] Enable ACPI sleep in Linux
Date: Tue, 15 May 2007 22:20:51 +0800	[thread overview]
Message-ID: <D470B4E54465E3469E2ABBC5AFAC390F013B1DF7@pdsmsx412.ccr.corp.intel.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 13450 bytes --]

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@intel.com>
Signed-off-by Kevin Tian <kevin.tian@intel.com>

diff -r ae6a502a5db4 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32	Wed Apr 11 14:09:56 2007
-0400
+++ b/buildconfigs/linux-defconfig_xen_x86_32	Wed Apr 11 14:09:57 2007
-0400
@@ -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 ae6a502a5db4 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64	Wed Apr 11 14:09:56 2007
-0400
+++ b/buildconfigs/linux-defconfig_xen_x86_64	Wed Apr 11 14:09:57 2007
-0400
@@ -167,6 +167,9 @@ CONFIG_PM=y
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig	Wed Apr 11 14:09:56 2007
-0400
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig	Wed Apr 11 14:09:57 2007
-0400
@@ -810,6 +810,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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Apr 11
14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Apr 11
14:09:57 2007 -0400
@@ -849,9 +849,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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/power/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/power/Makefile	Wed Apr 11
14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/power/Makefile	Wed Apr 11
14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c	Wed Apr 11
14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c	Wed Apr 11
14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/arch/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig	Wed Apr 11 14:09:56 2007
-0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig	Wed Apr 11 14:09:57 2007
-0400
@@ -408,6 +408,11 @@ config HOTPLUG_CPU
 		can be controlled through /sys/devices/system/cpu/cpu#.
 		Say N if you want to disable CPU hotplug.
 
+config SUSPEND_SMP
+	bool 
+	depends on HOTPLUG_CPU && X86 && PM
+	default y
+
 config ARCH_ENABLE_MEMORY_HOTPLUG
 	def_bool y
 
diff -r ae6a502a5db4
linux-2.6-xen-sparse/arch/x86_64/kernel/acpi/Makefile
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/acpi/Makefile	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/acpi/Makefile	Wed Apr
11 14:09:57 2007 -0400
@@ -8,3 +8,8 @@ endif
 endif
 
 boot-$(CONFIG_XEN)		:= ../../../i386/kernel/acpi/boot-xen.o
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r ae6a502a5db4 linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Wed Apr
11 14:09:57 2007 -0400
@@ -43,6 +43,13 @@ ENTRY(_start)
 	pushq $0		# fake return address
 	jmp x86_64_start_kernel
 
+#ifdef CONFIG_ACPI_SLEEP
+.org 0xf00
+	.globl pGDT32
+pGDT32:
+	.word	gdt_end-cpu_gdt_table-1
+	.long	cpu_gdt_table-__START_KERNEL_map
+#endif
 ENTRY(stext)
 ENTRY(_stext)
 
@@ -102,6 +109,14 @@ NEXT_PAGE(hypercall_page)
 	CFI_ENDPROC
 
 #undef NEXT_PAGE
+
+	.data
+
+#ifdef CONFIG_ACPI_SLEEP
+	.align PAGE_SIZE
+ENTRY(wakeup_level4_pgt)
+	.fill	512,8,0
+#endif
 
 	.data
 
diff -r ae6a502a5db4
linux-2.6-xen-sparse/arch/x86_64/kernel/suspend-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/suspend-xen.c	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/suspend-xen.c	Wed Apr
11 14:09:57 2007 -0400
@@ -114,12 +114,14 @@ void restore_processor_state(void)
 
 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 neccessary. But... This is neccessary, because 386 hardware has
concept of busy TSS or some similar stupidity. */
 
 	cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
+#endif    
 
 	syscall_init();                         /* This sets MSR_*STAR
and related */
 	load_TR_desc();				/* This does ltr */
diff -r ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/Kconfig
--- a/linux-2.6-xen-sparse/drivers/acpi/Kconfig	Wed Apr 11 14:09:56 2007
-0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/Kconfig	Wed Apr 11 14:09:57 2007
-0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile	Wed Apr
11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4
linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c	Wed Apr
11 14:09:57 2007 -0400
@@ -209,6 +209,37 @@ 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>
+#ifdef CONFIG_X86_64
+#define saved_videomode saved_video_mode
+#endif
+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
@@ -327,6 +358,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 +369,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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile	Wed Apr 11
14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile	Wed Apr 11
14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c	Wed Apr
11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4
linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c	Wed Apr
11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c	Wed Apr
11 14:09:57 2007 -0400
@@ -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();

[-- Attachment #2: enable_linux_acpi_sleep.patch --]
[-- Type: application/octet-stream, Size: 13412 bytes --]

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@intel.com>
Signed-off-by Kevin Tian <kevin.tian@intel.com>

diff -r ae6a502a5db4 buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32	Wed Apr 11 14:09:56 2007 -0400
+++ b/buildconfigs/linux-defconfig_xen_x86_32	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64	Wed Apr 11 14:09:56 2007 -0400
+++ b/buildconfigs/linux-defconfig_xen_x86_64	Wed Apr 11 14:09:57 2007 -0400
@@ -167,6 +167,9 @@ CONFIG_PM=y
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig	Wed Apr 11 14:09:57 2007 -0400
@@ -810,6 +810,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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/time-xen.c	Wed Apr 11 14:09:57 2007 -0400
@@ -849,9 +849,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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/power/Makefile
--- a/linux-2.6-xen-sparse/arch/i386/power/Makefile	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/power/Makefile	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/i386/power/cpu-xen.c	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/arch/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig	Wed Apr 11 14:09:57 2007 -0400
@@ -408,6 +408,11 @@ config HOTPLUG_CPU
 		can be controlled through /sys/devices/system/cpu/cpu#.
 		Say N if you want to disable CPU hotplug.
 
+config SUSPEND_SMP
+	bool 
+	depends on HOTPLUG_CPU && X86 && PM
+	default y
+
 config ARCH_ENABLE_MEMORY_HOTPLUG
 	def_bool y
 
diff -r ae6a502a5db4 linux-2.6-xen-sparse/arch/x86_64/kernel/acpi/Makefile
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/acpi/Makefile	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/acpi/Makefile	Wed Apr 11 14:09:57 2007 -0400
@@ -8,3 +8,8 @@ endif
 endif
 
 boot-$(CONFIG_XEN)		:= ../../../i386/kernel/acpi/boot-xen.o
+
+ifdef CONFIG_XEN
+include $(srctree)/scripts/Makefile.xen
+obj-y := $(call cherrypickxen, $(obj-y))
+endif
diff -r ae6a502a5db4 linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S	Wed Apr 11 14:09:57 2007 -0400
@@ -43,6 +43,13 @@ ENTRY(_start)
 	pushq $0		# fake return address
 	jmp x86_64_start_kernel
 
+#ifdef CONFIG_ACPI_SLEEP
+.org 0xf00
+	.globl pGDT32
+pGDT32:
+	.word	gdt_end-cpu_gdt_table-1
+	.long	cpu_gdt_table-__START_KERNEL_map
+#endif
 ENTRY(stext)
 ENTRY(_stext)
 
@@ -102,6 +109,14 @@ NEXT_PAGE(hypercall_page)
 	CFI_ENDPROC
 
 #undef NEXT_PAGE
+
+	.data
+
+#ifdef CONFIG_ACPI_SLEEP
+	.align PAGE_SIZE
+ENTRY(wakeup_level4_pgt)
+	.fill	512,8,0
+#endif
 
 	.data
 
diff -r ae6a502a5db4 linux-2.6-xen-sparse/arch/x86_64/kernel/suspend-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/suspend-xen.c	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/suspend-xen.c	Wed Apr 11 14:09:57 2007 -0400
@@ -114,12 +114,14 @@ void restore_processor_state(void)
 
 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 neccessary. But... This is neccessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
 
 	cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
+#endif    
 
 	syscall_init();                         /* This sets MSR_*STAR and related */
 	load_TR_desc();				/* This does ltr */
diff -r ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/Kconfig
--- a/linux-2.6-xen-sparse/drivers/acpi/Kconfig	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/Kconfig	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/Makefile	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/hardware/hwsleep-xen.c	Wed Apr 11 14:09:57 2007 -0400
@@ -209,6 +209,37 @@ 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>
+#ifdef CONFIG_X86_64
+#define saved_videomode saved_video_mode
+#endif
+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
@@ -327,6 +358,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 +369,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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/Makefile	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/main-xen.c	Wed Apr 11 14:09:57 2007 -0400
@@ -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 ae6a502a5db4 linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c
--- a/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c	Wed Apr 11 14:09:56 2007 -0400
+++ b/linux-2.6-xen-sparse/drivers/acpi/sleep/poweroff-xen.c	Wed Apr 11 14:09:57 2007 -0400
@@ -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();

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

             reply	other threads:[~2007-05-15 14:20 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-15 14:20 Tian, Kevin [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-02-14  9:17 [PATCH 8/12] Enable ACPI sleep in Linux Tian, Kevin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=D470B4E54465E3469E2ABBC5AFAC390F013B1DF7@pdsmsx412.ccr.corp.intel.com \
    --to=kevin.tian@intel.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.