Merge branch 'linus' into cont_syslog
[safe/jmp/linux-2.6] / arch / powerpc / kernel / head_64.S
index 0552f01..844a44b 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/firmware.h>
 #include <asm/page_64.h>
 #include <asm/irqflags.h>
+#include <asm/kvm_book3s_asm.h>
 
 /* The physical memory is layed out such that the secondary processor
  * spin code sits at 0x0000...0x00ff. On server, the vectors follow
@@ -121,10 +122,11 @@ __run_at_load:
  */
        .globl  __secondary_hold
 __secondary_hold:
+#ifndef CONFIG_PPC_BOOK3E
        mfmsr   r24
        ori     r24,r24,MSR_RI
        mtmsrd  r24                     /* RI on */
-
+#endif
        /* Grab our physical cpu number */
        mr      r24,r3
 
@@ -143,6 +145,7 @@ __secondary_hold:
        ld      r4,0(r4)                /* deref function descriptor */
        mtctr   r4
        mr      r3,r24
+       li      r4,0
        bctr
 #else
        BUG_OPCODE
@@ -163,26 +166,61 @@ exception_marker:
 #include "exceptions-64s.S"
 #endif
 
+/* KVM trampoline code needs to be close to the interrupt handlers */
+
+#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
+#include "../kvm/book3s_rmhandlers.S"
+#endif
+
+_GLOBAL(generic_secondary_thread_init)
+       mr      r24,r3
+
+       /* turn on 64-bit mode */
+       bl      .enable_64b_mode
+
+       /* get a valid TOC pointer, wherever we're mapped at */
+       bl      .relative_toc
+
+#ifdef CONFIG_PPC_BOOK3E
+       /* Book3E initialization */
+       mr      r3,r24
+       bl      .book3e_secondary_thread_init
+#endif
+       b       generic_secondary_common_init
 
 /*
  * On pSeries and most other platforms, secondary processors spin
  * in the following code.
  * At entry, r3 = this processor's number (physical cpu id)
+ *
+ * On Book3E, r4 = 1 to indicate that the initial TLB entry for
+ * this core already exists (setup via some other mechanism such
+ * as SCOM before entry).
  */
 _GLOBAL(generic_secondary_smp_init)
        mr      r24,r3
-       
+       mr      r25,r4
+
        /* turn on 64-bit mode */
        bl      .enable_64b_mode
 
-       /* get the TOC pointer (real address) */
+       /* get a valid TOC pointer, wherever we're mapped at */
        bl      .relative_toc
 
+#ifdef CONFIG_PPC_BOOK3E
+       /* Book3E initialization */
+       mr      r3,r24
+       mr      r4,r25
+       bl      .book3e_secondary_core_init
+#endif
+
+generic_secondary_common_init:
        /* Set up a paca value for this processor. Since we have the
         * physical cpu id in r24, we need to search the pacas to find
         * which logical id maps to our physical one.
         */
-       LOAD_REG_ADDR(r13, paca)        /* Get base vaddr of paca array  */
+       LOAD_REG_ADDR(r13, paca)        /* Load paca pointer             */
+       ld      r13,0(r13)              /* Get base vaddr of paca array  */
        li      r5,0                    /* logical cpu id                */
 1:     lhz     r6,PACAHWCPUID(r13)     /* Load HW procid from paca      */
        cmpw    r6,r24                  /* Compare to our id             */
@@ -196,6 +234,11 @@ _GLOBAL(generic_secondary_smp_init)
        b       .kexec_wait             /* next kernel might do better   */
 
 2:     mtspr   SPRN_SPRG_PACA,r13      /* Save vaddr of paca in an SPRG */
+#ifdef CONFIG_PPC_BOOK3E
+       addi    r12,r13,PACA_EXTLB      /* and TLB exc frame in another  */
+       mtspr   SPRN_SPRG_TLB_EXFRAME,r12
+#endif
+
        /* From now on, r24 is expected to be logical cpuid */
        mr      r24,r5
 3:     HMT_LOW
@@ -231,6 +274,7 @@ _GLOBAL(generic_secondary_smp_init)
  * Turn the MMU off.
  * Assumes we're mapped EA == RA if the MMU is on.
  */
+#ifdef CONFIG_PPC_BOOK3S
 _STATIC(__mmu_off)
        mfmsr   r3
        andi.   r0,r3,MSR_IR|MSR_DR
@@ -242,6 +286,7 @@ _STATIC(__mmu_off)
        sync
        rfid
        b       .       /* prevent speculative execution */
+#endif
 
 
 /*
@@ -279,6 +324,10 @@ _GLOBAL(__start_initialization_multiplatform)
        mr      r31,r3
        mr      r30,r4
 
+#ifdef CONFIG_PPC_BOOK3E
+       bl      .start_initialization_book3e
+       b       .__after_prom_start
+#else
        /* Setup some critical 970 SPRs before switching MMU off */
        mfspr   r0,SPRN_PVR
        srwi    r0,r0,16
@@ -296,6 +345,7 @@ _GLOBAL(__start_initialization_multiplatform)
        /* Switch off MMU if not already off */
        bl      .__mmu_off
        b       .__after_prom_start
+#endif /* CONFIG_PPC_BOOK3E */
 
 _INIT_STATIC(__boot_from_prom)
 #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
@@ -358,10 +408,16 @@ _STATIC(__after_prom_start)
  * Note: This process overwrites the OF exception vectors.
  */
        li      r3,0                    /* target addr */
+#ifdef CONFIG_PPC_BOOK3E
+       tovirt(r3,r3)                   /* on booke, we already run at PAGE_OFFSET */
+#endif
        mr.     r4,r26                  /* In some cases the loader may  */
        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_CRASH_DUMP
 /*
@@ -481,7 +537,8 @@ _GLOBAL(pmac_secondary_start)
        mtmsrd  r3                      /* RI on */
 
        /* Set up a paca value for this processor. */
-       LOAD_REG_ADDR(r4,paca)          /* Get base vaddr of paca array */
+       LOAD_REG_ADDR(r4,paca)          /* Load paca pointer            */
+       ld      r4,0(r4)                /* Get base vaddr of paca array */
        mulli   r13,r24,PACA_SIZE       /* Calculate vaddr of right paca */
        add     r13,r13,r4              /* for this processor.          */
        mtspr   SPRN_SPRG_PACA,r13      /* Save vaddr of paca in an SPRG*/
@@ -507,6 +564,9 @@ _GLOBAL(pmac_secondary_start)
  *   r13       = paca virtual address
  *   SPRG_PACA = paca virtual address
  */
+       .section ".text";
+       .align 2 ;
+
        .globl  __secondary_start
 __secondary_start:
        /* Set thread priority to MEDIUM */
@@ -543,7 +603,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
        mtspr   SPRN_SRR0,r3
        mtspr   SPRN_SRR1,r4
-       rfid
+       RFI
        b       .       /* prevent speculative execution */
 
 /* 
@@ -557,6 +617,17 @@ _GLOBAL(start_secondary_prolog)
        std     r3,0(r1)                /* Zero the stack frame pointer */
        bl      .start_secondary
        b       .
+/*
+ * Reset stack pointer and call start_secondary
+ * to continue with online operation when woken up
+ * from cede in cpu offline.
+ */
+_GLOBAL(start_secondary_resume)
+       ld      r1,PACAKSAVE(r13)       /* Reload kernel stack pointer */
+       li      r3,0
+       std     r3,0(r1)                /* Zero the stack frame pointer */
+       bl      .start_secondary
+       b       .
 #endif
 
 /*
@@ -564,11 +635,16 @@ _GLOBAL(start_secondary_prolog)
  */
 _GLOBAL(enable_64b_mode)
        mfmsr   r11                     /* grab the current MSR */
+#ifdef CONFIG_PPC_BOOK3E
+       oris    r11,r11,0x8000          /* CM bit set, we'll set ICM later */
+       mtmsr   r11
+#else /* CONFIG_PPC_BOOK3E */
        li      r12,(MSR_SF | MSR_ISF)@highest
        sldi    r12,r12,48
        or      r11,r11,r12
        mtmsrd  r11
        isync
+#endif
        blr
 
 /*
@@ -612,9 +688,11 @@ _INIT_STATIC(start_here_multiplatform)
        bdnz    3b
 4:
 
+#ifndef CONFIG_PPC_BOOK3E
        mfmsr   r6
        ori     r6,r6,MSR_RI
        mtmsrd  r6                      /* RI on */
+#endif
 
 #ifdef CONFIG_RELOCATABLE
        /* Save the physical address we're running at in kernstart_addr */
@@ -647,7 +725,7 @@ _INIT_STATIC(start_here_multiplatform)
        ld      r4,PACAKMSR(r13)
        mtspr   SPRN_SRR0,r3
        mtspr   SPRN_SRR1,r4
-       rfid
+       RFI
        b       .       /* prevent speculative execution */
        
        /* This is where all platforms converge execution */