config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on PPC_BOOK3S && EXPERIMENTAL
+       depends on (PPC_BOOK3S || (FSL_BOOKE && !SMP)) && EXPERIMENTAL
        help
          kexec is a system call that implements the ability to shutdown your
          current kernel, and to start another kernel.  It is like a reboot
 
 #define _ASM_POWERPC_KEXEC_H
 #ifdef __KERNEL__
 
+#ifdef CONFIG_FSL_BOOKE
+
+/*
+ * On FSL-BookE we setup a 1:1 mapping which covers the first 2GiB of memory
+ * and therefore we can only deal with memory within this range
+ */
+#define KEXEC_SOURCE_MEMORY_LIMIT      (2 * 1024 * 1024 * 1024UL)
+#define KEXEC_DESTINATION_MEMORY_LIMIT (2 * 1024 * 1024 * 1024UL)
+#define KEXEC_CONTROL_MEMORY_LIMIT     (2 * 1024 * 1024 * 1024UL)
+
+#else
+
 /*
  * Maximum page that is mapped directly into kernel memory.
  * XXX: Since we copy virt we can use any page we allocate
 /* TASK_SIZE, probably left over from use_mm ?? */
 #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
 #endif
+#endif
 
 #define KEXEC_CONTROL_PAGE_SIZE 4096
 
 
 }
 
 /* wait for all the CPUs to hit real mode but timeout if they don't come in */
+#ifdef CONFIG_PPC_STD_MMU_64
 static void crash_kexec_wait_realmode(int cpu)
 {
        unsigned int msecs;
        }
        mb();
 }
+#endif
 
 /*
  * This function will be called by secondary cpus or by kexec cpu
        crash_kexec_prepare_cpus(crashing_cpu);
        cpu_set(crashing_cpu, cpus_in_crash);
        crash_kexec_stop_spus();
+#ifdef CONFIG_PPC_STD_MMU_64
        crash_kexec_wait_realmode(crashing_cpu);
+#endif
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(1, 0);
 }
 
 #define M_IF_SMP       0
 #endif
 
+#if defined(ENTRY_MAPPING_BOOT_SETUP)
+
 /* 6. Setup KERNELBASE mapping in TLB1[0] */
        lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
        mtspr   SPRN_MAS0,r6
 /* 7. Jump to KERNELBASE mapping */
        lis     r6,(KERNELBASE & ~0xfff)@h
        ori     r6,r6,(KERNELBASE & ~0xfff)@l
+
+#elif defined(ENTRY_MAPPING_KEXEC_SETUP)
+/*
+ * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp
+ * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This
+ * will cover the first 2GiB of memory.
+ */
+
+       lis r10, (MAS1_VALID|MAS1_IPROT)@h
+       ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l
+       li  r11, 0
+       li  r0, 8
+       mtctr   r0
+
+next_tlb_setup:
+       addi    r0, r11, 3
+       rlwinm  r0, r0, 16, 4, 15  // Compute esel
+       rlwinm  r9, r11, 28, 0, 3   // Compute [ER]PN
+       oris    r0, r0, (MAS0_TLBSEL(1))@h
+       mtspr   SPRN_MAS0,r0
+       mtspr   SPRN_MAS1,r10
+       mtspr   SPRN_MAS2,r9
+       ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)
+       mtspr   SPRN_MAS3,r9
+       tlbwe
+       addi    r11, r11, 1
+       bdnz+   next_tlb_setup
+
+/* 7. Jump to our 1:1 mapping */
+       li      r6, 0
+
+#else
+       #error You need to specify the mapping or not use this at all.
+#endif
+
        lis     r7,MSR_KERNEL@h
        ori     r7,r7,MSR_KERNEL@l
        bl      1f                      /* Find our address */
 
 
 _ENTRY(__early_start)
 
+#define ENTRY_MAPPING_BOOT_SETUP
 #include "fsl_booke_entry_mapping.S"
+#undef ENTRY_MAPPING_BOOT_SETUP
 
        /* Establish the interrupt vector offsets */
        SET_IVOR(0,  CriticalInput);
 
        /* r4 = reboot_code_buffer */
        /* r5 = start_address      */
 
+#ifdef CONFIG_FSL_BOOKE
+
+       mr      r29, r3
+       mr      r30, r4
+       mr      r31, r5
+
+#define ENTRY_MAPPING_KEXEC_SETUP
+#include "fsl_booke_entry_mapping.S"
+#undef ENTRY_MAPPING_KEXEC_SETUP
+
+       mr      r3, r29
+       mr      r4, r30
+       mr      r5, r31
+
+       li      r0, 0
+#else
        li      r0, 0
 
        /*
        rfi
 
 1:
+#endif
        /* from this point address translation is turned off */
        /* and interrupts are disabled */