These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / powerpc / kernel / misc_64.S
index 8a7238d..96b7ef8 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/thread_info.h>
 #include <asm/kexec.h>
 #include <asm/ptrace.h>
+#include <asm/mmu.h>
 
        .text
 
@@ -477,9 +478,20 @@ _GLOBAL(kexec_wait)
 #ifdef CONFIG_KEXEC            /* use no memory without kexec */
        lwz     r4,0(r5)
        cmpwi   0,r4,0
-       bnea    0x60
+       beq     99b
+#ifdef CONFIG_PPC_BOOK3S_64
+       li      r10,0x60
+       mfmsr   r11
+       clrrdi  r11,r11,1       /* Clear MSR_LE */
+       mtsrr0  r10
+       mtsrr1  r11
+       rfid
+#else
+       /* Create TLB entry in book3e_secondary_core_init */
+       li      r4,0
+       ba      0x60
+#endif
 #endif
-       b       99b
 
 /* this can be in text because we won't change it until we are
  * running in real anyways
@@ -489,6 +501,51 @@ kexec_flag:
 
 
 #ifdef CONFIG_KEXEC
+#ifdef CONFIG_PPC_BOOK3E
+/*
+ * BOOK3E has no real MMU mode, so we have to setup the initial TLB
+ * for a core to identity map v:0 to p:0.  This current implementation
+ * assumes that 1G is enough for kexec.
+ */
+kexec_create_tlb:
+       /*
+        * Invalidate all non-IPROT TLB entries to avoid any TLB conflict.
+        * IPROT TLB entries should be >= PAGE_OFFSET and thus not conflict.
+        */
+       PPC_TLBILX_ALL(0,R0)
+       sync
+       isync
+
+       mfspr   r10,SPRN_TLB1CFG
+       andi.   r10,r10,TLBnCFG_N_ENTRY /* Extract # entries */
+       subi    r10,r10,1       /* Last entry: no conflict with kernel text */
+       lis     r9,MAS0_TLBSEL(1)@h
+       rlwimi  r9,r10,16,4,15          /* Setup MAS0 = TLBSEL | ESEL(r9) */
+
+/* Set up a temp identity mapping v:0 to p:0 and return to it. */
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
+#define M_IF_NEEDED    MAS2_M
+#else
+#define M_IF_NEEDED    0
+#endif
+       mtspr   SPRN_MAS0,r9
+
+       lis     r9,(MAS1_VALID|MAS1_IPROT)@h
+       ori     r9,r9,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
+       mtspr   SPRN_MAS1,r9
+
+       LOAD_REG_IMMEDIATE(r9, 0x0 | M_IF_NEEDED)
+       mtspr   SPRN_MAS2,r9
+
+       LOAD_REG_IMMEDIATE(r9, 0x0 | MAS3_SR | MAS3_SW | MAS3_SX)
+       mtspr   SPRN_MAS3,r9
+       li      r9,0
+       mtspr   SPRN_MAS7,r9
+
+       tlbwe
+       isync
+       blr
+#endif
 
 /* kexec_smp_wait(void)
  *
@@ -518,6 +575,10 @@ _GLOBAL(kexec_smp_wait)
  * don't overwrite r3 here, it is live for kexec_wait above.
  */
 real_mode:     /* assume normal blr return */
+#ifdef CONFIG_PPC_BOOK3E
+       /* Create an identity mapping. */
+       b       kexec_create_tlb
+#else
 1:     li      r9,MSR_RI
        li      r10,MSR_DR|MSR_IR
        mflr    r11             /* return address to SRR0 */
@@ -529,7 +590,7 @@ real_mode:  /* assume normal blr return */
        mtspr   SPRN_SRR1,r10
        mtspr   SPRN_SRR0,r11
        rfid
-
+#endif
 
 /*
  * kexec_sequence(newstack, start, image, control, clear_all())
@@ -572,9 +633,13 @@ _GLOBAL(kexec_sequence)
        lhz     r25,PACAHWCPUID(r13)    /* get our phys cpu from paca */
 
        /* disable interrupts, we are overwriting kernel data next */
+#ifdef CONFIG_PPC_BOOK3E
+       wrteei  0
+#else
        mfmsr   r3
        rlwinm  r3,r3,0,17,15
        mtmsrd  r3,1
+#endif
 
        /* copy dest pages, flush whole dest image */
        mr      r3,r29
@@ -596,6 +661,7 @@ _GLOBAL(kexec_sequence)
        li      r6,1
        stw     r6,kexec_flag-1b(5)
 
+#ifndef CONFIG_PPC_BOOK3E
        /* clear out hardware hash page table and tlb */
 #if !defined(_CALL_ELF) || _CALL_ELF != 2
        ld      r12,0(r27)              /* deref function descriptor */
@@ -604,6 +670,7 @@ _GLOBAL(kexec_sequence)
 #endif
        mtctr   r12
        bctrl                           /* ppc_md.hpte_clear_all(void); */
+#endif /* !CONFIG_PPC_BOOK3E */
 
 /*
  *   kexec image calling is: