These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / powerpc / kernel / head_64.S
index d48125d..1b77956 100644 (file)
@@ -182,6 +182,8 @@ exception_marker:
 
 #ifdef CONFIG_PPC_BOOK3E
 _GLOBAL(fsl_secondary_thread_init)
+       mfspr   r4,SPRN_BUCSR
+
        /* Enable branch prediction */
        lis     r3,BUCSR_INIT@h
        ori     r3,r3,BUCSR_INIT@l
@@ -196,10 +198,24 @@ _GLOBAL(fsl_secondary_thread_init)
         * number.  There are two threads per core, so shift everything
         * but the low bit right by two bits so that the cpu numbering is
         * continuous.
+        *
+        * If the old value of BUCSR is non-zero, this thread has run
+        * before.  Thus, we assume we are coming from kexec or a similar
+        * scenario, and PIR is already set to the correct value.  This
+        * is a bit of a hack, but there are limited opportunities for
+        * getting information into the thread and the alternatives
+        * seemed like they'd be overkill.  We can't tell just by looking
+        * at the old PIR value which state it's in, since the same value
+        * could be valid for one thread out of reset and for a different
+        * thread in Linux.
         */
+
        mfspr   r3, SPRN_PIR
+       cmpwi   r4,0
+       bne     1f
        rlwimi  r3, r3, 30, 2, 30
        mtspr   SPRN_PIR, r3
+1:
 #endif
 
 _GLOBAL(generic_secondary_thread_init)
@@ -441,12 +457,22 @@ __after_prom_start:
        /* process relocations for the final address of the kernel */
        lis     r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
        sldi    r25,r25,32
+#if defined(CONFIG_PPC_BOOK3E)
+       tovirt(r26,r26)         /* on booke, we already run at PAGE_OFFSET */
+#endif
        lwz     r7,__run_at_load-_stext(r26)
+#if defined(CONFIG_PPC_BOOK3E)
+       tophys(r26,r26)
+#endif
        cmplwi  cr0,r7,1        /* flagged to stay where we are ? */
        bne     1f
        add     r25,r25,r26
 1:     mr      r3,r25
        bl      relocate
+#if defined(CONFIG_PPC_BOOK3E)
+       /* IVPR needs to be set after relocation. */
+       bl      init_core_book3e
+#endif
 #endif
 
 /*
@@ -458,15 +484,15 @@ __after_prom_start:
  */
        li      r3,0                    /* target addr */
 #ifdef CONFIG_PPC_BOOK3E
-       tovirt(r3,r3)                   /* on booke, we already run at PAGE_OFFSET */
+       tovirt(r3,r3)           /* on booke, we already run at PAGE_OFFSET */
 #endif
        mr.     r4,r26                  /* In some cases the loader may  */
+#if defined(CONFIG_PPC_BOOK3E)
+       tovirt(r4,r4)
+#endif
        beq     9f                      /* have already put us at zero */
        li      r6,0x100                /* Start offset, the first 0x100 */
                                        /* bytes were copied earlier.    */
-#ifdef CONFIG_PPC_BOOK3E
-       tovirt(r6,r6)                   /* on booke, we already run at PAGE_OFFSET */
-#endif
 
 #ifdef CONFIG_RELOCATABLE
 /*
@@ -474,12 +500,21 @@ __after_prom_start:
  * variable __run_at_load, if it is set the kernel is treated as relocatable
  * kernel, otherwise it will be moved to PHYSICAL_START
  */
+#if defined(CONFIG_PPC_BOOK3E)
+       tovirt(r26,r26)         /* on booke, we already run at PAGE_OFFSET */
+#endif
        lwz     r7,__run_at_load-_stext(r26)
        cmplwi  cr0,r7,1
        bne     3f
 
+#ifdef CONFIG_PPC_BOOK3E
+       LOAD_REG_ADDR(r5, __end_interrupts)
+       LOAD_REG_ADDR(r11, _stext)
+       sub     r5,r5,r11
+#else
        /* just copy interrupts */
        LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext)
+#endif
        b       5f
 3:
 #endif