From: Horms <horms@verge.net.au>
Date: Wed, 13 Dec 2006 12:01:12 +0900
Subject: [PATCH] [IA64] kexec/kdump: Pass in physical addresses to purgatory
To: fastboot@lists.osdl.org, linux-ia64@vger.kernel.org
Cc: "Luck, Tony" <tony.luck@intel.com>, Khalid Aziz <khalid_aziz@hp.com>, Zou Nan hai <nanhai.zou@intel.com>, Magnus Damm <magnus.damm@gmail.com>

Index: linux-2.6/arch/ia64/kernel/machine_kexec.c
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/machine_kexec.c	2007-06-08 12:40:09.000000000 +0900
+++ linux-2.6/arch/ia64/kernel/machine_kexec.c	2007-06-08 14:07:27.000000000 +0900
@@ -19,11 +19,12 @@
 #include <asm/setup.h>
 #include <asm/delay.h>
 #include <asm/meminit.h>
+#include <asm/page.h>
 
 typedef NORET_TYPE void (*relocate_new_kernel_t)(
 					unsigned long indirection_page,
 					unsigned long start_address,
-					struct ia64_boot_param *boot_param,
+					unsigned long boot_param,
 					unsigned long pal_addr) ATTRIB_NORET;
 
 struct kimage *ia64_kimage;
@@ -70,6 +71,23 @@ void machine_kexec_cleanup(struct kimage
 }
 
 /*
+ * boot_param is used inside purgatory and purgatory runs
+ * in physical mode, so translate the addresses that purgatory
+ * accesses from virtual to physical.
+ */
+static unsigned long machine_kexec_prepare_boot_param (void)
+{
+	efi_system_table_t *systab;
+
+	systab = (efi_system_table_t *)__va(ia64_boot_param->efi_systab);
+	systab->runtime->set_virtual_address_map =
+				__pa(systab->runtime->set_virtual_address_map);
+	systab->runtime = (efi_runtime_services_t *)__pa(systab->runtime);
+
+	return __pa(ia64_boot_param);
+}
+
+/*
  * Do not allocate memory (or fail in any way) in machine_kexec().
  * We are past the point of no return, committed to rebooting now.
  */
@@ -114,7 +132,7 @@ static void ia64_machine_kexec(struct un
 	}
 	platform_kernel_launch_event();
 	rnk = (relocate_new_kernel_t)&code_addr;
-	(*rnk)(image->head, image->start, ia64_boot_param,
+	(*rnk)(image->head, image->start, machine_kexec_prepare_boot_param(),
 		     GRANULEROUNDDOWN((unsigned long) pal_addr));
 	BUG();
 }
Index: linux-2.6/arch/ia64/kernel/relocate_kernel.S
===================================================================
--- linux-2.6.orig/arch/ia64/kernel/relocate_kernel.S	2007-06-08 12:40:09.000000000 +0900
+++ linux-2.6/arch/ia64/kernel/relocate_kernel.S	2007-06-08 14:07:36.000000000 +0900
@@ -57,7 +57,7 @@ GLOBAL_ENTRY(relocate_new_kernel)
 1:
 	//physical mode code begin
 	mov b6=in1
-	dep r28=0,in2,61,3	//to physical address
+	mov r28=in2
 
 	// purge all TC entries
 #define O(member)       IA64_CPUINFO_##member##_OFFSET
