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-changelog

[Xen-changelog] [xen-unstable] x86: Default ACPI reboot method.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Default ACPI reboot method.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 10 Jun 2008 11:30:11 -0700
Delivery-date: Tue, 10 Jun 2008 11:30:14 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1213105860 -3600
# Node ID c7d361cf579372b7b5e9168892beadc6304bb4c9
# Parent  57b8c74c35ef682838ad3c93974e740bea3ba40d
x86: Default ACPI reboot method.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/shutdown.c   |  219 ++++++++++++++++++++++++----------------------
 xen/drivers/acpi/Makefile |    1 
 xen/drivers/acpi/reboot.c |   37 +++++++
 xen/include/xen/acpi.h    |    2 
 4 files changed, 157 insertions(+), 102 deletions(-)

diff -r 57b8c74c35ef -r c7d361cf5793 xen/arch/x86/shutdown.c
--- a/xen/arch/x86/shutdown.c   Tue Jun 10 14:17:20 2008 +0100
+++ b/xen/arch/x86/shutdown.c   Tue Jun 10 14:51:00 2008 +0100
@@ -14,6 +14,7 @@
 #include <xen/irq.h>
 #include <xen/console.h>
 #include <xen/shutdown.h>
+#include <xen/acpi.h>
 #include <asm/msr.h>
 #include <asm/regs.h>
 #include <asm/mc146818rtc.h>
@@ -23,12 +24,53 @@
 #include <asm/mpspec.h>
 #include <asm/tboot.h>
 
-/* reboot_str: comma-separated list of reboot options. */
-static char __initdata reboot_str[10] = "";
-string_param("reboot", reboot_str);
+enum reboot_type {
+        BOOT_TRIPLE = 't',
+        BOOT_KBD = 'k',
+        BOOT_ACPI = 'a',
+#ifdef CONFIG_X86_32
+        BOOT_BIOS = 'b',
+#endif
+};
 
 static long no_idt[2];
 static int reboot_mode;
+
+/*
+ * reboot=b[ios] | t[riple] | k[bd] | [, [w]arm | [c]old]
+ * warm   Don't set the cold reboot flag
+ * cold   Set the cold reboot flag
+ * bios   Reboot by jumping through the BIOS (only for X86_32)
+ * triple Force a triple fault (init)
+ * kbd    Use the keyboard controller. cold reset (default)
+ * acpi   Use the RESET_REG in the FADT
+ */
+static enum reboot_type reboot_type = BOOT_ACPI;
+static void __init set_reboot_type(char *str)
+{
+    for ( ; ; )
+    {
+        switch ( *str )
+        {
+        case 'w': /* "warm" reboot (no memory testing etc) */
+            reboot_mode = 0x1234;
+            break;
+        case 'c': /* "cold" reboot (with memory testing etc) */
+            reboot_mode = 0x0;
+            break;
+        case 'b':
+        case 'a':
+        case 'k':
+        case 't':
+            reboot_type = *str;
+            break;
+        }
+        if ( (str = strchr(str, ',')) == NULL )
+            break;
+        str++;
+    }
+}
+custom_param("reboot", set_reboot_type);
 
 static inline void kb_wait(void)
 {
@@ -55,8 +97,6 @@ void machine_halt(void)
 }
 
 #ifdef __i386__
-
-static int reboot_thru_bios;
 
 /* The following code and data reboots the machine by switching to real
    mode and jumping to the BIOS reset entry point, as if the CPU has
@@ -192,10 +232,63 @@ static void machine_real_restart(const u
                                           MAX_LENGTH)));
 }
 
+static int __init set_bios_reboot(struct dmi_system_id *d)
+{
+    if ( reboot_type != BOOT_BIOS )
+    {
+        reboot_type = BOOT_BIOS;
+        printk("%s series board detected. "
+               "Selecting BIOS-method for reboots.\n", d->ident);
+    }
+    return 0;
+}
+
+static struct dmi_system_id __initdata reboot_dmi_table[] = {
+    {    /* Handle problems with rebooting on Dell 1300's */
+        .callback = set_bios_reboot,
+        .ident = "Dell PowerEdge 1300",
+        .matches = {
+            DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
+        },
+    },
+    {    /* Handle problems with rebooting on Dell 300's */
+        .callback = set_bios_reboot,
+        .ident = "Dell PowerEdge 300",
+        .matches = {
+            DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
+        },
+    },
+    {    /* Handle problems with rebooting on Dell 2400's */
+        .callback = set_bios_reboot,
+        .ident = "Dell PowerEdge 2400",
+        .matches = {
+            DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
+        },
+    },
+    {    /* Handle problems with rebooting on HP laptops */
+        .callback = set_bios_reboot,
+        .ident = "HP Compaq Laptop",
+        .matches = {
+            DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
+        },
+    },
+    { }
+};
+
+static int __init reboot_init(void)
+{
+    dmi_check_system(reboot_dmi_table);
+    return 0;
+}
+__initcall(reboot_init);
+
 #else /* __x86_64__ */
 
 #define machine_real_restart(x, y)
-#define reboot_thru_bios 0
 
 #endif
 
@@ -226,10 +319,11 @@ void machine_restart(void)
     /* Rebooting needs to touch the page at absolute address 0. */
     *((unsigned short *)__va(0x472)) = reboot_mode;
 
-    if ( reboot_thru_bios <= 0 )
-    {
-        for ( ; ; )
+    for ( ; ; )
+    {
+        switch ( reboot_type )
         {
+        case BOOT_KBD:
             /* Pulse the keyboard reset line. */
             for ( i = 0; i < 100; i++ )
             {
@@ -238,100 +332,21 @@ void machine_restart(void)
                 outb(0xfe,0x64); /* pulse reset low */
                 udelay(50);
             }
-
-            /* That didn't work - force a triple fault.. */
-            __asm__ __volatile__("lidt %0": "=m" (no_idt));
-            __asm__ __volatile__("int3");
+            /* fall through */
+        case BOOT_TRIPLE:
+            asm volatile ( "lidt %0 ; int3" : "=m" (no_idt) );
+            break;
+        case BOOT_BIOS:
+            machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
+            break;
+        case BOOT_ACPI:
+            acpi_reboot();
+            break;
         }
-    }
-    machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
-}
-
-#ifndef reboot_thru_bios
-static int __init set_bios_reboot(struct dmi_system_id *d)
-{
-    if ( !reboot_thru_bios )
-    {
-        reboot_thru_bios = 1;
-        printk("%s series board detected. "
-               "Selecting BIOS-method for reboots.\n", d->ident);
-    }
-    return 0;
-}
-
-static struct dmi_system_id __initdata reboot_dmi_table[] = {
-    {    /* Handle problems with rebooting on Dell 1300's */
-        .callback = set_bios_reboot,
-        .ident = "Dell PowerEdge 1300",
-        .matches = {
-            DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
-            DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
-        },
-    },
-    {    /* Handle problems with rebooting on Dell 300's */
-        .callback = set_bios_reboot,
-        .ident = "Dell PowerEdge 300",
-        .matches = {
-            DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
-            DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
-        },
-    },
-    {    /* Handle problems with rebooting on Dell 2400's */
-        .callback = set_bios_reboot,
-        .ident = "Dell PowerEdge 2400",
-        .matches = {
-            DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
-            DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
-        },
-    },
-    {    /* Handle problems with rebooting on HP laptops */
-        .callback = set_bios_reboot,
-        .ident = "HP Compaq Laptop",
-        .matches = {
-            DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-            DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
-        },
-    },
-    { }
-};
-#endif
-
-static int __init reboot_init(void)
-{
-    const char *str;
-
-    for ( str = reboot_str; *str != '\0'; str++ )
-    {
-        switch ( *str )
-        {
-        case 'n': /* no reboot */
-            opt_noreboot = 1;
-            break;
-        case 'w': /* "warm" reboot (no memory testing etc) */
-            reboot_mode = 0x1234;
-            break;
-        case 'c': /* "cold" reboot (with memory testing etc) */
-            reboot_mode = 0x0;
-            break;
-#ifndef reboot_thru_bios
-        case 'b': /* "bios" reboot by jumping through the BIOS */
-            reboot_thru_bios = 1;
-            break;
-        case 'h': /* "hard" reboot by toggling RESET and/or crashing the CPU */
-            reboot_thru_bios = -1;
-            break;
-#endif
-        }
-        if ( (str = strchr(str, ',')) == NULL )
-            break;
-    }
-
-#ifndef reboot_thru_bios
-    dmi_check_system(reboot_dmi_table);
-#endif
-    return 0;
-}
-__initcall(reboot_init);
+
+        reboot_type = BOOT_KBD;
+    }
+}
 
 /*
  * Local variables:
diff -r 57b8c74c35ef -r c7d361cf5793 xen/drivers/acpi/Makefile
--- a/xen/drivers/acpi/Makefile Tue Jun 10 14:17:20 2008 +0100
+++ b/xen/drivers/acpi/Makefile Tue Jun 10 14:51:00 2008 +0100
@@ -6,3 +6,4 @@ obj-y += osl.o
 obj-y += osl.o
 
 obj-$(x86) += hwregs.o
+obj-$(x86) += reboot.o
diff -r 57b8c74c35ef -r c7d361cf5793 xen/drivers/acpi/reboot.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/drivers/acpi/reboot.c Tue Jun 10 14:51:00 2008 +0100
@@ -0,0 +1,37 @@
+#include <xen/config.h>
+#include <xen/pci.h>
+#include <acpi/acpi.h>
+
+void acpi_reboot(void)
+{
+       struct acpi_generic_address *rr;
+       u8 reset_value;
+
+       rr = &acpi_gbl_FADT.reset_register;
+
+       /* Is the reset register supported? */
+       if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+           (rr->bit_width != 8) || (rr->bit_offset != 0))
+               return;
+
+       reset_value = acpi_gbl_FADT.reset_value;
+
+       /* The reset register can only exist in I/O, Memory or PCI config space
+        * on a device on bus 0. */
+       switch (rr->space_id) {
+       case ACPI_ADR_SPACE_PCI_CONFIG:
+               printk("Resetting with ACPI PCI RESET_REG.");
+               /* Write the value that resets us. */
+               pci_conf_write8(0,
+                               (rr->address >> 32) & 31,
+                               (rr->address >> 16) & 7,
+                               (rr->address & 255),
+                               reset_value);
+               break;
+       case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+       case ACPI_ADR_SPACE_SYSTEM_IO:
+               printk("ACPI MEMORY or I/O RESET_REG.");
+               acpi_hw_low_level_write(8, reset_value, rr);
+               break;
+       }
+}
diff -r 57b8c74c35ef -r c7d361cf5793 xen/include/xen/acpi.h
--- a/xen/include/xen/acpi.h    Tue Jun 10 14:17:20 2008 +0100
+++ b/xen/include/xen/acpi.h    Tue Jun 10 14:51:00 2008 +0100
@@ -441,4 +441,6 @@ static inline int acpi_get_pxm(acpi_hand
 
 extern int pnpacpi_disabled;
 
+void acpi_reboot(void);
+
 #endif /*_LINUX_ACPI_H*/

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: Default ACPI reboot method., Xen patchbot-unstable <=