This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ppc64 / kernel / head.S
index a5d67f5..647b239 100644 (file)
@@ -200,7 +200,6 @@ exception_marker:
 #define EX_R13         32
 #define EX_SRR0                40
 #define EX_DAR         48
-#define EX_LR          48      /* SLB miss saves LR, but not DAR */
 #define EX_DSISR       56
 #define EX_CCR         60
 
@@ -221,8 +220,7 @@ exception_marker:
        mtspr   SRR0,r12;                                               \
        mfspr   r12,SRR1;               /* and SRR1 */                  \
        mtspr   SRR1,r10;                                               \
-       rfid;                                                           \
-       b       .       /* prevent speculative execution */
+       rfid
 
 /*
  * This is the start of the interrupt handlers for iSeries
@@ -303,14 +301,12 @@ exception_marker:
        . = n;                                          \
        .globl label##_Pseries;                         \
 label##_Pseries:                                       \
-       HMT_MEDIUM;                                     \
        mtspr   SPRG1,r13;              /* save r13 */  \
        EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
 
 #define STD_EXCEPTION_ISERIES(n, label, area)          \
        .globl label##_Iseries;                         \
 label##_Iseries:                                       \
-       HMT_MEDIUM;                                     \
        mtspr   SPRG1,r13;              /* save r13 */  \
        EXCEPTION_PROLOG_ISERIES_1(area);               \
        EXCEPTION_PROLOG_ISERIES_2;                     \
@@ -319,7 +315,6 @@ label##_Iseries:                                    \
 #define MASKABLE_EXCEPTION_ISERIES(n, label)                           \
        .globl label##_Iseries;                                         \
 label##_Iseries:                                                       \
-       HMT_MEDIUM;                                                     \
        mtspr   SPRG1,r13;              /* save r13 */                  \
        EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);                         \
        lbz     r10,PACAPROFENABLED(r13);                               \
@@ -413,14 +408,12 @@ __start_interrupts:
 
        . = 0x200
 _MachineCheckPseries:
-       HMT_MEDIUM
        mtspr   SPRG1,r13               /* save r13 */
        EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
 
        . = 0x300
        .globl DataAccess_Pseries
 DataAccess_Pseries:
-       HMT_MEDIUM
        mtspr   SPRG1,r13
 BEGIN_FTR_SECTION
        mtspr   SPRG2,r12
@@ -439,57 +432,19 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        . = 0x380
        .globl DataAccessSLB_Pseries
 DataAccessSLB_Pseries:
-       HMT_MEDIUM
        mtspr   SPRG1,r13
-       mfspr   r13,SPRG3               /* get paca address into r13 */
-       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
-       std     r10,PACA_EXSLB+EX_R10(r13)
-       std     r11,PACA_EXSLB+EX_R11(r13)
-       std     r12,PACA_EXSLB+EX_R12(r13)
-       std     r3,PACASLBR3(r13)
-       mfspr   r9,SPRG1
-       std     r9,PACA_EXSLB+EX_R13(r13)
-       mfcr    r9
-       clrrdi  r12,r13,32              /* get high part of &label */
-       mfmsr   r10
-       mfspr   r11,SRR0                /* save SRR0 */
-       ori     r12,r12,(.do_slb_miss)@l
-       ori     r10,r10,MSR_IR|MSR_DR   /* DON'T set RI for SLB miss */
-       mtspr   SRR0,r12
-       mfspr   r12,SRR1                /* and SRR1 */
-       mtspr   SRR1,r10
-       mfspr   r3,DAR
-       rfid
-       b       .       /* prevent speculative execution */
+       mtspr   SPRG2,r12
+       mfspr   r13,DAR
+       mfcr    r12
+       srdi    r13,r13,60
+       cmpdi   r13,0xc
+       beq     .do_slb_bolted_Pseries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, DataAccessSLB_common)
 
        STD_EXCEPTION_PSERIES(0x400, InstructionAccess)
-
-       . = 0x480
-       .globl InstructionAccessSLB_Pseries
-InstructionAccessSLB_Pseries:
-       HMT_MEDIUM
-       mtspr   SPRG1,r13
-       mfspr   r13,SPRG3               /* get paca address into r13 */
-       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
-       std     r10,PACA_EXSLB+EX_R10(r13)
-       std     r11,PACA_EXSLB+EX_R11(r13)
-       std     r12,PACA_EXSLB+EX_R12(r13)
-       std     r3,PACASLBR3(r13)
-       mfspr   r9,SPRG1
-       std     r9,PACA_EXSLB+EX_R13(r13)
-       mfcr    r9
-       clrrdi  r12,r13,32              /* get high part of &label */
-       mfmsr   r10
-       mfspr   r11,SRR0                /* save SRR0 */
-       ori     r12,r12,(.do_slb_miss)@l
-       ori     r10,r10,MSR_IR|MSR_DR   /* DON'T set RI for SLB miss */
-       mtspr   SRR0,r12
-       mfspr   r12,SRR1                /* and SRR1 */
-       mtspr   SRR1,r10
-       mr      r3,r11                  /* SRR0 is faulting address */
-       rfid
-       b       .       /* prevent speculative execution */
-
+       STD_EXCEPTION_PSERIES(0x480, InstructionAccessSLB)
        STD_EXCEPTION_PSERIES(0x500, HardwareInterrupt)
        STD_EXCEPTION_PSERIES(0x600, Alignment)
        STD_EXCEPTION_PSERIES(0x700, ProgramCheck)
@@ -501,7 +456,6 @@ InstructionAccessSLB_Pseries:
        . = 0xc00
        .globl  SystemCall_Pseries
 SystemCall_Pseries:
-       HMT_MEDIUM
        mr      r9,r13
        mfmsr   r10
        mfspr   r13,SPRG3
@@ -514,7 +468,6 @@ SystemCall_Pseries:
        mfspr   r12,SRR1
        mtspr   SRR1,r10
        rfid
-       b       .       /* prevent speculative execution */
 
        STD_EXCEPTION_PSERIES(0xd00, SingleStep)
        STD_EXCEPTION_PSERIES(0xe00, Trap_0e)
@@ -541,6 +494,11 @@ _GLOBAL(do_stab_bolted_Pseries)
        mfspr   r12,SPRG2
        EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
 
+_GLOBAL(do_slb_bolted_Pseries)
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_slb_bolted)
+
        
        /* Space for the naca.  Architected to be located at real address
         * NACA_PHYS_ADDR.  Various tools rely on this location being fixed.
@@ -629,25 +587,27 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        .globl  DataAccessSLB_Iseries
 DataAccessSLB_Iseries:
        mtspr   SPRG1,r13               /* save r13 */
-       EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
-       std     r3,PACASLBR3(r13)
-       ld      r11,PACALPPACA+LPPACASRR0(r13)
-       ld      r12,PACALPPACA+LPPACASRR1(r13)
-       mfspr   r3,DAR
-       b       .do_slb_miss
-
-       STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN)
+       mtspr   SPRG2,r12
+       mfspr   r13,DAR
+       mfcr    r12
+       srdi    r13,r13,60
+       cmpdi   r13,0xc
+       beq     .do_slb_bolted_Iseries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
+       EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
+       EXCEPTION_PROLOG_ISERIES_2
+       b       DataAccessSLB_common
 
-       .globl  InstructionAccessSLB_Iseries
-InstructionAccessSLB_Iseries:
-       mtspr   SPRG1,r13               /* save r13 */
+.do_slb_bolted_Iseries:
+       mtcrf   0x80,r12
+       mfspr   r12,SPRG2
        EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
-       std     r3,PACASLBR3(r13)
-       ld      r11,PACALPPACA+LPPACASRR0(r13)
-       ld      r12,PACALPPACA+LPPACASRR1(r13)
-       mr      r3,r11
-       b       .do_slb_miss
+       EXCEPTION_PROLOG_ISERIES_2
+       b       .do_slb_bolted
 
+       STD_EXCEPTION_ISERIES(0x400, InstructionAccess, PACA_EXGEN)
+       STD_EXCEPTION_ISERIES(0x480, InstructionAccessSLB, PACA_EXGEN)
        MASKABLE_EXCEPTION_ISERIES(0x500, HardwareInterrupt)
        STD_EXCEPTION_ISERIES(0x600, Alignment, PACA_EXGEN)
        STD_EXCEPTION_ISERIES(0x700, ProgramCheck, PACA_EXGEN)
@@ -723,7 +683,7 @@ Decrementer_Iseries_masked:
        li      r11,1
        stb     r11,PACALPPACA+LPPACADECRINT(r13)
        lwz     r12,PACADEFAULTDECR(r13)
-       mtspr   SPRN_DEC,r12
+       mtspr   DEC,r12
        /* fall through */
 
        .globl HardwareInterrupt_Iseries_masked
@@ -739,7 +699,6 @@ HardwareInterrupt_Iseries_masked:
        ld      r12,PACA_EXGEN+EX_R12(r13)
        ld      r13,PACA_EXGEN+EX_R13(r13)
        rfid
-       b       .       /* prevent speculative execution */
 #endif
 
 /*
@@ -755,12 +714,10 @@ fwnmi_data_area:
        . = 0x8000
        .globl SystemReset_FWNMI
 SystemReset_FWNMI:
-       HMT_MEDIUM
        mtspr   SPRG1,r13               /* save r13 */
        EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, SystemReset_common)
        .globl MachineCheck_FWNMI
 MachineCheck_FWNMI:
-       HMT_MEDIUM
        mtspr   SPRG1,r13               /* save r13 */
        EXCEPTION_PROLOG_PSERIES(PACA_EXMC, MachineCheck_common)
 
@@ -882,7 +839,6 @@ fast_exception_return:
        REST_4GPRS(10, r1)
        ld      r1,GPR1(r1)
        rfid
-       b       .       /* prevent speculative execution */
 
 unrecov_fer:
        bl      .save_nvgprs
@@ -908,6 +864,21 @@ DataAccess_common:
        li      r5,0x300
        b       .do_hash_page           /* Try to handle as hpte fault */
 
+       .align  7
+       .globl DataAccessSLB_common
+DataAccessSLB_common:
+       mfspr   r10,DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       std     r3,_DAR(r1)
+       bl      .slb_allocate
+       cmpdi   r3,0                    /* Check return code */
+       beq     fast_exception_return   /* Return if we succeeded */
+       li      r5,0
+       std     r5,_DSISR(r1)
+       b       .handle_page_fault
+
        .align  7
        .globl InstructionAccess_common
 InstructionAccess_common:
@@ -917,6 +888,21 @@ InstructionAccess_common:
        li      r5,0x400
        b       .do_hash_page           /* Try to handle as hpte fault */
 
+       .align  7
+       .globl InstructionAccessSLB_common
+InstructionAccessSLB_common:
+       EXCEPTION_PROLOG_COMMON(0x480, PACA_EXGEN)
+       ld      r3,_NIP(r1)             /* SRR0 = NIA   */
+       bl      .slb_allocate
+       or.     r3,r3,r3                /* Check return code */
+       beq+    fast_exception_return   /* Return if we succeeded */
+
+       ld      r4,_NIP(r1)
+       li      r5,0
+       std     r4,_DAR(r1)
+       std     r5,_DSISR(r1)
+       b      .handle_page_fault
+
        .align  7
        .globl HardwareInterrupt_common
        .globl HardwareInterrupt_entry
@@ -1042,7 +1028,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
        bl      .local_irq_restore
        b       11f
 #else
-       beq     fast_exception_return   /* Return from exception on success */
+       beq+    fast_exception_return   /* Return from exception on success */
        /* fall through */
 #endif
 
@@ -1162,42 +1148,134 @@ _GLOBAL(do_stab_bolted)
        ld      r12,PACA_EXSLB+EX_R12(r13)
        ld      r13,PACA_EXSLB+EX_R13(r13)
        rfid
-       b       .       /* prevent speculative execution */
 
 /*
  * r13 points to the PACA, r9 contains the saved CR,
  * r11 and r12 contain the saved SRR0 and SRR1.
- * r3 has the faulting address
  * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
  * We assume we aren't going to take any exceptions during this procedure.
  */
-_GLOBAL(do_slb_miss)
-       mflr    r10
-
+/* XXX note fix masking in get_kernel_vsid to match */
+_GLOBAL(do_slb_bolted)
        stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
        std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
-       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
 
-       bl      .slb_allocate                   /* handle it */
+       /*
+        * We take the next entry, round robin. Previously we tried
+        * to find a free slot first but that took too long. Unfortunately
+        * we dont have any LRU information to help us choose a slot.
+        */
 
-       /* All done -- return from exception. */
+       /* r13 = paca */
+1:     ld      r10,PACASTABRR(r13)
+       addi    r9,r10,1
+       cmpdi   r9,SLB_NUM_ENTRIES
+       blt+    2f
+       li      r9,2                    /* dont touch slot 0 or 1 */
+2:     std     r9,PACASTABRR(r13)
+
+       /* r13 = paca, r10 = entry */
+
+       /* 
+        * Never cast out the segment for our kernel stack. Since we
+        * dont invalidate the ERAT we could have a valid translation
+        * for the kernel stack during the first part of exception exit 
+        * which gets invalidated due to a tlbie from another cpu at a
+        * non recoverable point (after setting srr0/1) - Anton
+        */
+       slbmfee r9,r10
+       srdi    r9,r9,27
+       /*
+        * Use paca->ksave as the value of the kernel stack pointer,
+        * because this is valid at all times.
+        * The >> 27 (rather than >> 28) is so that the LSB is the
+        * valid bit - this way we check valid and ESID in one compare.
+        * In order to completely close the tiny race in the context
+        * switch (between updating r1 and updating paca->ksave),
+        * we check against both r1 and paca->ksave.
+        */
+       srdi    r11,r1,27
+       ori     r11,r11,1
+       cmpd    r11,r9
+       beq-    1b
+       ld      r11,PACAKSAVE(r13)
+       srdi    r11,r11,27
+       ori     r11,r11,1
+       cmpd    r11,r9
+       beq-    1b
+
+       /* r13 = paca, r10 = entry */
+
+       /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
+       mfspr   r9,DAR
+       rldicl  r11,r9,36,51
+       sldi    r11,r11,15
+       srdi    r9,r9,60
+       or      r11,r11,r9
 
-       ld      r10,PACA_EXSLB+EX_LR(r13)
-       ld      r3,PACASLBR3(r13)
+       /* VSID_RANDOMIZER */
+       li      r9,9
+       sldi    r9,r9,32
+       oris    r9,r9,58231
+       ori     r9,r9,39831
+
+       /* vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK */
+       mulld   r11,r11,r9
+       clrldi  r11,r11,28
+
+       /* r13 = paca, r10 = entry, r11 = vsid */
+
+       /* Put together slb word1 */
+       sldi    r11,r11,12
+
+BEGIN_FTR_SECTION
+       /* set kp and c bits */
+       ori     r11,r11,0x480
+END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
+BEGIN_FTR_SECTION
+       /* set kp, l and c bits */
+       ori     r11,r11,0x580
+END_FTR_SECTION_IFSET(CPU_FTR_16M_PAGE)
+
+       /* r13 = paca, r10 = entry, r11 = slb word1 */
+
+       /* Put together slb word0 */
+       mfspr   r9,DAR
+       clrrdi  r9,r9,28        /* get the new esid */
+       oris    r9,r9,0x800     /* set valid bit */
+       rldimi  r9,r10,0,52     /* insert entry */
+
+       /* r13 = paca, r9 = slb word0, r11 = slb word1 */
+
+       /* 
+        * No need for an isync before or after this slbmte. The exception
+        * we enter with and the rfid we exit with are context synchronizing .
+        */
+       slbmte  r11,r9
+
+       /* All done -- return from exception. */
        lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
        ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
 
-       mtlr    r10
-
        andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
        beq-    unrecov_slb
 
-.machine       push
-.machine       "power4"
+       /*
+        * Until everyone updates binutils hardwire the POWER4 optimised
+        * single field mtcrf
+        */
+#if 0
+       .machine        push
+       .machine        "power4"
        mtcrf   0x80,r9
-       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
-.machine       pop
+       .machine        pop
+#else
+       .long 0x7d380120
+#endif
+
+       mfmsr   r10
+       clrrdi  r10,r10,2
+       mtmsrd  r10,1
 
        mtspr   SRR0,r11
        mtspr   SRR1,r12
@@ -1207,7 +1285,6 @@ _GLOBAL(do_slb_miss)
        ld      r12,PACA_EXSLB+EX_R12(r13)
        ld      r13,PACA_EXSLB+EX_R13(r13)
        rfid
-       b       .       /* prevent speculative execution */
 
 unrecov_slb:
        EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
@@ -1313,7 +1390,6 @@ _STATIC(mmu_off)
        mtspr   SRR1,r3
        sync
        rfid
-       b       .       /* prevent speculative execution */
 _GLOBAL(__start_initialization_pSeries)
        mr      r31,r3                  /* save parameters */
        mr      r30,r4
@@ -1796,7 +1872,6 @@ _GLOBAL(__secondary_start)
        mtspr   SRR0,r3
        mtspr   SRR1,r4
        rfid
-       b       .       /* prevent speculative execution */
 
 /* 
  * Running with relocation on at this point.  All we want to do is
@@ -1960,7 +2035,6 @@ _STATIC(start_here_pSeries)
        mtspr   SRR0,r3
        mtspr   SRR1,r4
        rfid
-       b       .       /* prevent speculative execution */
 #endif /* CONFIG_PPC_PSERIES */
        
        /* This is where all platforms converge execution */