Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
[powerpc.git] / arch / powerpc / kernel / head_64.S
index 16ab40d..1c066d1 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/reg.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
-#include <asm/systemcfg.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/bug.h>
@@ -155,11 +154,15 @@ _GLOBAL(__secondary_hold)
        bne     100b
 
 #ifdef CONFIG_HMT
-       b       .hmt_init
+       LOADADDR(r4, .hmt_init)
+       mtctr   r4
+       bctr
 #else
 #ifdef CONFIG_SMP
+       LOADADDR(r4, .pSeries_secondary_smp_init)
+       mtctr   r4
        mr      r3,r24
-       b       .pSeries_secondary_smp_init
+       bctr
 #else
        BUG_OPCODE
 #endif
@@ -201,6 +204,20 @@ exception_marker:
 #define EX_R3          64
 #define EX_LR          72
 
+/*
+ * We're short on space and time in the exception prolog, so we can't use
+ * the normal LOADADDR macro. Normally we just need the low halfword of the
+ * address, but for Kdump we need the whole low word.
+ */
+#ifdef CONFIG_CRASH_DUMP
+#define LOAD_HANDLER(reg, label)                                       \
+       oris    reg,reg,(label)@h;      /* virt addr of handler ... */  \
+       ori     reg,reg,(label)@l;      /* .. and the rest */
+#else
+#define LOAD_HANDLER(reg, label)                                       \
+       ori     reg,reg,(label)@l;      /* virt addr of handler ... */
+#endif
+
 #define EXCEPTION_PROLOG_PSERIES(area, label)                          \
        mfspr   r13,SPRN_SPRG3;         /* get paca address into r13 */ \
        std     r9,area+EX_R9(r13);     /* save r9 - r12 */             \
@@ -213,7 +230,7 @@ exception_marker:
        clrrdi  r12,r13,32;             /* get high part of &label */   \
        mfmsr   r10;                                                    \
        mfspr   r11,SPRN_SRR0;          /* save SRR0 */                 \
-       ori     r12,r12,(label)@l;      /* virt addr of handler */      \
+       LOAD_HANDLER(r12,label)                                         \
        ori     r10,r10,MSR_IR|MSR_DR|MSR_RI;                           \
        mtspr   SPRN_SRR0,r12;                                          \
        mfspr   r12,SPRN_SRR1;          /* and SRR1 */                  \
@@ -554,6 +571,7 @@ slb_miss_user_pseries:
  * Vectors for the FWNMI option.  Share common code.
  */
        .globl system_reset_fwnmi
+      .align 7
 system_reset_fwnmi:
        HMT_MEDIUM
        mtspr   SPRN_SPRG1,r13          /* save r13 */
@@ -561,6 +579,7 @@ system_reset_fwnmi:
        EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
 
        .globl machine_check_fwnmi
+      .align 7
 machine_check_fwnmi:
        HMT_MEDIUM
        mtspr   SPRN_SPRG1,r13          /* save r13 */
@@ -727,7 +746,8 @@ iSeries_secondary_smp_loop:
 decrementer_iSeries_masked:
        li      r11,1
        stb     r11,PACALPPACA+LPPACADECRINT(r13)
-       lwz     r12,PACADEFAULTDECR(r13)
+       LOADBASE(r12,tb_ticks_per_jiffy)
+       lwz     r12,OFF(tb_ticks_per_jiffy)(r12)
        mtspr   SPRN_DEC,r12
        /* fall through */
 
@@ -1346,7 +1366,7 @@ _GLOBAL(do_stab_bolted)
  * fixed address (the linker can't compute (u64)&initial_stab >>
  * PAGE_SHIFT).
  */
-       . = STAB0_PHYS_ADDR     /* 0x6000 */
+       . = STAB0_OFFSET        /* 0x6000 */
        .globl initial_stab
 initial_stab:
        .space  4096
@@ -1486,11 +1506,13 @@ _STATIC(__mmu_off)
  *
  */
 _GLOBAL(__start_initialization_multiplatform)
+#ifdef CONFIG_PPC_MULTIPLATFORM
        /*
         * Are we booted from a PROM Of-type client-interface ?
         */
        cmpldi  cr0,r5,0
        bne     .__boot_from_prom               /* yes -> prom */
+#endif
 
        /* Save parameters */
        mr      r31,r3
@@ -1511,6 +1533,7 @@ _GLOBAL(__start_initialization_multiplatform)
        bl      .__mmu_off
        b       .__after_prom_start
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
 _STATIC(__boot_from_prom)
        /* Save parameters */
        mr      r31,r3
@@ -1543,6 +1566,7 @@ _STATIC(__boot_from_prom)
        bl      .prom_init
        /* We never return */
        trap
+#endif
 
 /*
  * At this point, r3 contains the physical address we are running at,
@@ -1551,7 +1575,7 @@ _STATIC(__boot_from_prom)
 _STATIC(__after_prom_start)
 
 /*
- * We need to run with __start at physical address 0.
+ * We need to run with __start at physical address PHYSICAL_START.
  * This will leave some code in the first 256B of
  * real memory, which are reserved for software use.
  * The remainder of the first page is loaded with the fixed
@@ -1566,7 +1590,7 @@ _STATIC(__after_prom_start)
        mr      r26,r3
        SET_REG_TO_CONST(r27,KERNELBASE)
 
-       li      r3,0                    /* target addr */
+       LOADADDR(r3, PHYSICAL_START)    /* target addr */
 
        // XXX FIXME: Use phys returned by OF (r30)
        add     r4,r27,r26              /* source addr                   */
@@ -1697,25 +1721,14 @@ _GLOBAL(pmac_secondary_start)
  *   SPRG3 = paca virtual address
  */
 _GLOBAL(__secondary_start)
+       /* Set thread priority to MEDIUM */
+       HMT_MEDIUM
 
-       HMT_MEDIUM                      /* Set thread priority to MEDIUM */
-
+       /* Load TOC */
        ld      r2,PACATOC(r13)
-       li      r6,0
-       stb     r6,PACAPROCENABLED(r13)
-
-#ifndef CONFIG_PPC_ISERIES
-       /* Initialize the page table pointer register. */
-       LOADADDR(r6,_SDR1)
-       ld      r6,0(r6)                /* get the value of _SDR1        */
-       mtspr   SPRN_SDR1,r6                    /* set the htab location         */
-#endif
-       /* Initialize the first segment table (or SLB) entry             */
-       ld      r3,PACASTABVIRT(r13)    /* get addr of segment table     */
-BEGIN_FTR_SECTION
-       bl      .stab_initialize
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-       bl      .slb_initialize
+
+       /* Do early setup for that CPU (stab, slb, hash table pointer) */
+       bl      .early_setup_secondary
 
        /* Initialize the kernel stack.  Just a repeat for iSeries.      */
        LOADADDR(r3,current_set)
@@ -1724,37 +1737,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
        std     r1,PACAKSAVE(r13)
 
-       ld      r3,PACASTABREAL(r13)    /* get raddr of segment table    */
-       ori     r4,r3,1                 /* turn on valid bit             */
-
-#ifdef CONFIG_PPC_ISERIES
-       li      r0,-1                   /* hypervisor call */
-       li      r3,1
-       sldi    r3,r3,63                /* 0x8000000000000000 */
-       ori     r3,r3,4                 /* 0x8000000000000004 */
-       sc                              /* HvCall_setASR */
-#else
-       /* set the ASR */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg         */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags           */
-       andi.   r3,r3,PLATFORM_LPAR     /* Test if bit 0 is set (LPAR bit) */
-       beq     98f                     /* branch if result is 0  */
-       mfspr   r3,SPRN_PVR
-       srwi    r3,r3,16
-       cmpwi   r3,0x37                 /* SStar  */
-       beq     97f
-       cmpwi   r3,0x36                 /* IStar  */
-       beq     97f
-       cmpwi   r3,0x34                 /* Pulsar */
-       bne     98f
-97:    li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
-       HVSC                            /* Invoking hcall */
-       b       99f
-98:                                    /* !(rpa hypervisor) || !(star)  */
-       mtasr   r4                      /* set the stab location         */
-99:
-#endif
+       /* Clear backchain so we get nice backtraces */
        li      r7,0
        mtlr    r7
 
@@ -1777,6 +1760,7 @@ _GLOBAL(start_secondary_prolog)
        li      r3,0
        std     r3,0(r1)                /* Zero the stack frame pointer */
        bl      .start_secondary
+       b       .
 #endif
 
 /*
@@ -1887,7 +1871,7 @@ _STATIC(start_here_multiplatform)
        mulli   r13,r27,PACA_SIZE       /* Calculate vaddr of right paca */
        add     r13,r13,r24             /* for this processor.           */
        add     r13,r13,r26             /* convert to physical addr      */
-       mtspr   SPRN_SPRG3,r13          /* PPPBBB: Temp... -Peter */
+       mtspr   SPRN_SPRG3,r13
        
        /* Do very early kernel initializations, including initial hash table,
         * stab and slb setup before we turn on relocation.     */
@@ -1896,40 +1880,6 @@ _STATIC(start_here_multiplatform)
        mr      r3,r31
        bl      .early_setup
 
-       /* set the ASR */
-       ld      r3,PACASTABREAL(r13)
-       ori     r4,r3,1                 /* turn on valid bit             */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
-       andi.   r3,r3,PLATFORM_LPAR     /* Test if bit 0 is set (LPAR bit) */
-       beq     98f                     /* branch if result is 0  */
-       mfspr   r3,SPRN_PVR
-       srwi    r3,r3,16
-       cmpwi   r3,0x37                 /* SStar */
-       beq     97f
-       cmpwi   r3,0x36                 /* IStar  */
-       beq     97f
-       cmpwi   r3,0x34                 /* Pulsar */
-       bne     98f
-97:    li      r3,H_SET_ASR            /* hcall = H_SET_ASR */
-       HVSC                            /* Invoking hcall */
-       b       99f
-98:                                    /* !(rpa hypervisor) || !(star) */
-       mtasr   r4                      /* set the stab location        */
-99:
-       /* Set SDR1 (hash table pointer) */
-       ld      r3,systemcfg@got(r2)    /* r3 = ptr to systemcfg */
-       ld      r3,0(r3)
-       lwz     r3,PLATFORM(r3)         /* r3 = platform flags */
-       /* Test if bit 0 is set (LPAR bit) */
-       andi.   r3,r3,PLATFORM_LPAR
-       bne     98f                     /* branch if result is !0  */
-       LOADADDR(r6,_SDR1)              /* Only if NOT LPAR */
-       add     r6,r6,r26
-       ld      r6,0(r6)                /* get the value of _SDR1 */
-       mtspr   SPRN_SDR1,r6                    /* set the htab location  */
-98: 
        LOADADDR(r3,.start_here_common)
        SET_REG_TO_CONST(r4, MSR_KERNEL)
        mtspr   SPRN_SRR0,r3