aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/machine_kexec.c
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@xensource.com>2006-11-30 12:38:51 +0000
committerIan Campbell <ian.campbell@xensource.com>2006-11-30 12:38:51 +0000
commit6dd60f6880df6d369385bdac2e41a5b6211423d9 (patch)
tree6d5b586741d303a0a4003648b1a8ed20d559173b /xen/arch/x86/machine_kexec.c
parenta173b7d011523df95259a206a5ff5d6ceeea336b (diff)
downloadxen-6dd60f6880df6d369385bdac2e41a5b6211423d9.tar.gz
xen-6dd60f6880df6d369385bdac2e41a5b6211423d9.tar.bz2
xen-6dd60f6880df6d369385bdac2e41a5b6211423d9.zip
[XEN] Kexec / Kdump: Code shared between x86_32 and x86_64
This patch contains Kexec / Kdump code shared between x86_32 and x86_64. Signed-Off-By: Magnus Damm <magnus@valinux.co.jp> Signed-Off-By: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'xen/arch/x86/machine_kexec.c')
-rw-r--r--xen/arch/x86/machine_kexec.c83
1 files changed, 73 insertions, 10 deletions
diff --git a/xen/arch/x86/machine_kexec.c b/xen/arch/x86/machine_kexec.c
index 639f845ac1..f60296271d 100644
--- a/xen/arch/x86/machine_kexec.c
+++ b/xen/arch/x86/machine_kexec.c
@@ -1,26 +1,89 @@
-#include <xen/lib.h> /* for printk() used in stubs */
+/******************************************************************************
+ * machine_kexec.c
+ *
+ * Xen port written by:
+ * - Simon 'Horms' Horman <horms@verge.net.au>
+ * - Magnus Damm <magnus@valinux.co.jp>
+ */
+
+#include <xen/lib.h>
+#include <asm/irq.h>
+#include <asm/page.h>
+#include <asm/flushtlb.h>
+#include <xen/smp.h>
+#include <xen/nmi.h>
#include <xen/types.h>
-#include <public/kexec.h>
+#include <xen/console.h>
+#include <xen/kexec.h>
+#include <asm/kexec.h>
+#include <xen/domain_page.h>
+#include <asm/fixmap.h>
+#include <asm/hvm/hvm.h>
int machine_kexec_load(int type, int slot, xen_kexec_image_t *image)
{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
- return -1;
+ unsigned long prev_ma = 0;
+ int fix_base = FIX_KEXEC_BASE_0 + (slot * (KEXEC_XEN_NO_PAGES >> 1));
+ int k;
+
+ /* setup fixmap to point to our pages and record the virtual address
+ * in every odd index in page_list[].
+ */
+
+ for (k = 0; k < KEXEC_XEN_NO_PAGES; k++) {
+ if ((k & 1) == 0) { /* even pages: machine address */
+ prev_ma = image->page_list[k];
+ }
+ else { /* odd pages: va for previous ma */
+ set_fixmap(fix_base + (k >> 1), prev_ma);
+ image->page_list[k] = fix_to_virt(fix_base + (k >> 1));
+ }
+ }
+
+ return 0;
}
void machine_kexec_unload(int type, int slot, xen_kexec_image_t *image)
{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
}
-
-void machine_kexec(xen_kexec_image_t *image)
+
+static void __machine_shutdown(void *data)
{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
-}
+ xen_kexec_image_t *image = (xen_kexec_image_t *)data;
+ watchdog_disable();
+ console_start_sync();
+
+ smp_send_stop();
+
+#ifdef CONFIG_X86_IO_APIC
+ disable_IO_APIC();
+#endif
+ hvm_disable();
+
+ machine_kexec(image);
+}
+
void machine_shutdown(xen_kexec_image_t *image)
{
- printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__);
+ int reboot_cpu_id;
+ cpumask_t reboot_cpu;
+
+ reboot_cpu_id = 0;
+
+ if (!cpu_isset(reboot_cpu_id, cpu_online_map))
+ reboot_cpu_id = smp_processor_id();
+
+ if (reboot_cpu_id != smp_processor_id()) {
+ cpus_clear(reboot_cpu);
+ cpu_set(reboot_cpu_id, reboot_cpu);
+ on_selected_cpus(reboot_cpu, __machine_shutdown, image, 1, 0);
+ for (;;)
+ ; /* nothing */
+ }
+ else
+ __machine_shutdown(image);
+ BUG();
}
/*