Book E processors need some extra setup in relocate_new_kernel,
because the MMU can't be turned off.  Add the code to create
the required one-to-one memory map.

Signed-off-by: Dale Farnsworth <[EMAIL PROTECTED]>
---
 arch/powerpc/Kconfig                      |    2 +-
 arch/powerpc/kernel/misc_32.S             |   69 +++++++++++++++++++++++++++++
 arch/powerpc/platforms/85xx/mpc85xx_ads.c |    6 +++
 arch/powerpc/platforms/85xx/mpc85xx_cds.c |    6 +++
 arch/powerpc/platforms/85xx/mpc85xx_ds.c  |    6 +++
 arch/powerpc/platforms/85xx/mpc85xx_mds.c |    6 +++
 6 files changed, 94 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 191cc2c..9e9581a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -236,7 +236,7 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
 
 config KEXEC
        bool "kexec system call (EXPERIMENTAL)"
-       depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+       depends on (PPC_MULTIPLATFORM || PPC_85xx) && 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
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 8b642ab..db0e749 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -816,6 +816,75 @@ relocate_new_kernel:
        /* r4 = reboot_code_buffer */
        /* r5 = start_address      */
 
+#ifdef CONFIG_E500
+       /*
+        * Since we can't turn off the MMU, we must create an identity
+        * map for kernel low memory.  We start by invalidating the
+        * TLB entries we don't need.
+        *
+        * First, invalidate the TLB0 entries
+        */
+       li      r6, 0x04
+       tlbivax 0, r6
+#ifdef CONFIG_SMP
+       tlbsync
+#endif
+       msync
+
+       /*
+        * Kernel low memory is mapped by TLB1 entries 0, 1, and 2.
+        * Preserve these, but invalidate all other TLB1 entries.
+        */
+       li      r7, 3                   /* first TLB1 entry */
+       mfspr   r6, SPRN_TLB1CFG
+       andi.   r6, r6, 0xfff
+       mr      r8, r6
+       subf    r6, r7, r6
+       mtctr   r6
+1:
+       rlwinm  r6, r7, 16, 12, 15
+       oris    r6, r6, 0x1000
+       mtspr   SPRN_MAS0, r6
+       tlbre
+       mfspr   r6, SPRN_MAS1
+       rlwinm  r6, r6, 0, 2, 31        /* Clear MAS1 Valid and IPROT */
+       mtspr   SPRN_MAS1, r6
+       tlbwe
+       isync
+       addi    r7, r7, 1
+       bdnz    1b
+
+       /*
+        * Using TLB1 entries 3, 4, and 5, identity-map kernel low
+        * memory by copying and modifying the contents of TLB1
+        * entries 0, 1 and 2, respectively.
+        */
+       li      r7, 0                   /* source TLB entry */
+       li      r8, 3                   /* destination TLB entry */
+       li      r6, 3                   /* number of TLBs to copy */
+       mtctr   r6
+1:
+       rlwinm  r6, r7, 16, 12, 15
+       oris    r6, r6, 0x1000
+       mtspr   SPRN_MAS0, r6
+       tlbre
+
+       mfspr   r6, SPRN_MAS2
+       lis     r0, [EMAIL PROTECTED]
+       subf    r6, r0, r6              /* identity map */
+       mtspr   SPRN_MAS2, r6
+
+       rlwinm  r6, r8, 16, 12, 15
+       oris    r6, r6, 0x1000
+       mtspr   SPRN_MAS0, r6
+       tlbwe
+       sync
+       isync
+       addi    r7, r7, 1
+       addi    r8, r8, 1
+       bdnz    1b
+#endif /* CONFIG_E500 */
+
        li      r0, 0
 
        /*
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c 
b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index bccdc25..1ade3dd 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/of_platform.h>
+#include <linux/kexec.h>
 
 #include <asm/system.h>
 #include <asm/time.h>
@@ -259,6 +260,11 @@ define_machine(mpc85xx_ads) {
        .show_cpuinfo           = mpc85xx_ads_show_cpuinfo,
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
+#ifdef CONFIG_KEXEC
+       .machine_kexec_prepare = default_machine_kexec_prepare,
+       .machine_kexec = default_machine_kexec,
+       .machine_crash_shutdown = default_machine_crash_shutdown,
+#endif
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
 };
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c 
b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 4d063ee..b8a5ed2 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
+#include <linux/kexec.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -352,6 +353,11 @@ define_machine(mpc85xx_cds) {
 #else
        .restart        = fsl_rstcr_restart,
 #endif
+#ifdef CONFIG_KEXEC
+       .machine_kexec_prepare = default_machine_kexec_prepare,
+       .machine_kexec = default_machine_kexec,
+       .machine_crash_shutdown = default_machine_crash_shutdown,
+#endif
        .calibrate_decr = generic_calibrate_decr,
        .progress       = udbg_progress,
 };
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c 
b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 59c121a..4c106b6 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
+#include <linux/kexec.h>
 
 #include <asm/system.h>
 #include <asm/time.h>
@@ -224,6 +225,11 @@ define_machine(mpc8572_ds) {
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
+#ifdef CONFIG_KEXEC
+       .machine_kexec_prepare = default_machine_kexec_prepare,
+       .machine_kexec = default_machine_kexec,
+       .machine_crash_shutdown = default_machine_crash_shutdown,
+#endif
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
 };
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c 
b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 61b3eed..49f55c1 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -30,6 +30,7 @@
 #include <linux/initrd.h>
 #include <linux/module.h>
 #include <linux/fsl_devices.h>
+#include <linux/kexec.h>
 
 #include <asm/of_device.h>
 #include <asm/of_platform.h>
@@ -202,6 +203,11 @@ define_machine(mpc85xx_mds) {
        .init_IRQ       = mpc85xx_mds_pic_init,
        .get_irq        = mpic_get_irq,
        .restart        = fsl_rstcr_restart,
+#ifdef CONFIG_KEXEC
+       .machine_kexec_prepare = default_machine_kexec_prepare,
+       .machine_kexec = default_machine_kexec,
+       .machine_crash_shutdown = default_machine_crash_shutdown,
+#endif
        .calibrate_decr = generic_calibrate_decr,
        .progress       = udbg_progress,
 #ifdef CONFIG_PCI
-- 
1.5.3.4

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to