root/arch/powerpc/kernel/fsl_booke_entry_mapping.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 
   3 /* 1. Find the index of the entry we're executing in */
   4         bl      invstr                          /* Find our address */
   5 invstr: mflr    r6                              /* Make it accessible */
   6         mfmsr   r7
   7         rlwinm  r4,r7,27,31,31                  /* extract MSR[IS] */
   8         mfspr   r7, SPRN_PID0
   9         slwi    r7,r7,16
  10         or      r7,r7,r4
  11         mtspr   SPRN_MAS6,r7
  12         tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
  13         mfspr   r7,SPRN_MAS1
  14         andis.  r7,r7,MAS1_VALID@h
  15         bne     match_TLB
  16 
  17         mfspr   r7,SPRN_MMUCFG
  18         rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
  19         cmpwi   r7,3
  20         bne     match_TLB                       /* skip if NPIDS != 3 */
  21 
  22         mfspr   r7,SPRN_PID1
  23         slwi    r7,r7,16
  24         or      r7,r7,r4
  25         mtspr   SPRN_MAS6,r7
  26         tlbsx   0,r6                            /* search MSR[IS], SPID=PID1 */
  27         mfspr   r7,SPRN_MAS1
  28         andis.  r7,r7,MAS1_VALID@h
  29         bne     match_TLB
  30         mfspr   r7, SPRN_PID2
  31         slwi    r7,r7,16
  32         or      r7,r7,r4
  33         mtspr   SPRN_MAS6,r7
  34         tlbsx   0,r6                            /* Fall through, we had to match */
  35 
  36 match_TLB:
  37         mfspr   r7,SPRN_MAS0
  38         rlwinm  r3,r7,16,20,31                  /* Extract MAS0(Entry) */
  39 
  40         mfspr   r7,SPRN_MAS1                    /* Insure IPROT set */
  41         oris    r7,r7,MAS1_IPROT@h
  42         mtspr   SPRN_MAS1,r7
  43         tlbwe
  44 
  45 /* 2. Invalidate all entries except the entry we're executing in */
  46         mfspr   r9,SPRN_TLB1CFG
  47         andi.   r9,r9,0xfff
  48         li      r6,0                            /* Set Entry counter to 0 */
  49 1:      lis     r7,0x1000                       /* Set MAS0(TLBSEL) = 1 */
  50         rlwimi  r7,r6,16,4,15                   /* Setup MAS0 = TLBSEL | ESEL(r6) */
  51         mtspr   SPRN_MAS0,r7
  52         tlbre
  53         mfspr   r7,SPRN_MAS1
  54         rlwinm  r7,r7,0,2,31                    /* Clear MAS1 Valid and IPROT */
  55         cmpw    r3,r6
  56         beq     skpinv                          /* Dont update the current execution TLB */
  57         mtspr   SPRN_MAS1,r7
  58         tlbwe
  59         isync
  60 skpinv: addi    r6,r6,1                         /* Increment */
  61         cmpw    r6,r9                           /* Are we done? */
  62         bne     1b                              /* If not, repeat */
  63 
  64         /* Invalidate TLB0 */
  65         li      r6,0x04
  66         tlbivax 0,r6
  67         TLBSYNC
  68         /* Invalidate TLB1 */
  69         li      r6,0x0c
  70         tlbivax 0,r6
  71         TLBSYNC
  72 
  73 /* 3. Setup a temp mapping and jump to it */
  74         andi.   r5, r3, 0x1     /* Find an entry not used and is non-zero */
  75         addi    r5, r5, 0x1
  76         lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
  77         rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
  78         mtspr   SPRN_MAS0,r7
  79         tlbre
  80 
  81         /* grab and fixup the RPN */
  82         mfspr   r6,SPRN_MAS1    /* extract MAS1[SIZE] */
  83         rlwinm  r6,r6,25,27,31
  84         li      r8,-1
  85         addi    r6,r6,10
  86         slw     r6,r8,r6        /* convert to mask */
  87 
  88         bl      1f              /* Find our address */
  89 1:      mflr    r7
  90 
  91         mfspr   r8,SPRN_MAS3
  92 #ifdef CONFIG_PHYS_64BIT
  93         mfspr   r23,SPRN_MAS7
  94 #endif
  95         and     r8,r6,r8
  96         subfic  r9,r6,-4096
  97         and     r9,r9,r7
  98 
  99         or      r25,r8,r9
 100         ori     r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)
 101 
 102         /* Just modify the entry ID and EPN for the temp mapping */
 103         lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
 104         rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
 105         mtspr   SPRN_MAS0,r7
 106         xori    r6,r4,1         /* Setup TMP mapping in the other Address space */
 107         slwi    r6,r6,12
 108         oris    r6,r6,(MAS1_VALID|MAS1_IPROT)@h
 109         ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
 110         mtspr   SPRN_MAS1,r6
 111         mfspr   r6,SPRN_MAS2
 112         li      r7,0            /* temp EPN = 0 */
 113         rlwimi  r7,r6,0,20,31
 114         mtspr   SPRN_MAS2,r7
 115         mtspr   SPRN_MAS3,r8
 116         tlbwe
 117 
 118         xori    r6,r4,1
 119         slwi    r6,r6,5         /* setup new context with other address space */
 120         bl      1f              /* Find our address */
 121 1:      mflr    r9
 122         rlwimi  r7,r9,0,20,31
 123         addi    r7,r7,(2f - 1b)
 124         mtspr   SPRN_SRR0,r7
 125         mtspr   SPRN_SRR1,r6
 126         rfi
 127 2:
 128 /* 4. Clear out PIDs & Search info */
 129         li      r6,0
 130         mtspr   SPRN_MAS6,r6
 131         mtspr   SPRN_PID0,r6
 132 
 133         mfspr   r7,SPRN_MMUCFG
 134         rlwinm  r7,r7,21,28,31                  /* extract MMUCFG[NPIDS] */
 135         cmpwi   r7,3
 136         bne     2f                              /* skip if NPIDS != 3 */
 137 
 138         mtspr   SPRN_PID1,r6
 139         mtspr   SPRN_PID2,r6
 140 
 141 /* 5. Invalidate mapping we started in */
 142 2:
 143         lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
 144         rlwimi  r7,r3,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r3) */
 145         mtspr   SPRN_MAS0,r7
 146         tlbre
 147         mfspr   r6,SPRN_MAS1
 148         rlwinm  r6,r6,0,2,0     /* clear IPROT */
 149         mtspr   SPRN_MAS1,r6
 150         tlbwe
 151         /* Invalidate TLB1 */
 152         li      r9,0x0c
 153         tlbivax 0,r9
 154         TLBSYNC
 155 
 156 /*
 157  * The mapping only needs to be cache-coherent on SMP, except on
 158  * Freescale e500mc derivatives where it's also needed for coherent DMA.
 159  */
 160 #if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
 161 #define M_IF_NEEDED     MAS2_M
 162 #else
 163 #define M_IF_NEEDED     0
 164 #endif
 165 
 166 #if defined(ENTRY_MAPPING_BOOT_SETUP)
 167 
 168 /* 6. Setup KERNELBASE mapping in TLB1[0] */
 169         lis     r6,0x1000               /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
 170         mtspr   SPRN_MAS0,r6
 171         lis     r6,(MAS1_VALID|MAS1_IPROT)@h
 172         ori     r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
 173         mtspr   SPRN_MAS1,r6
 174         lis     r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@h
 175         ori     r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_NEEDED)@l
 176         mtspr   SPRN_MAS2,r6
 177         mtspr   SPRN_MAS3,r8
 178         tlbwe
 179 
 180 /* 7. Jump to KERNELBASE mapping */
 181         lis     r6,(KERNELBASE & ~0xfff)@h
 182         ori     r6,r6,(KERNELBASE & ~0xfff)@l
 183         rlwinm  r7,r25,0,0x03ffffff
 184         add     r6,r7,r6
 185 
 186 #elif defined(ENTRY_MAPPING_KEXEC_SETUP)
 187 /*
 188  * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp
 189  * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This
 190  * will cover the first 2GiB of memory.
 191  */
 192 
 193         lis r10, (MAS1_VALID|MAS1_IPROT)@h
 194         ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l
 195         li  r11, 0
 196         li  r0, 8
 197         mtctr   r0
 198 
 199 next_tlb_setup:
 200         addi    r0, r11, 3
 201         rlwinm  r0, r0, 16, 4, 15  // Compute esel
 202         rlwinm  r9, r11, 28, 0, 3   // Compute [ER]PN
 203         oris    r0, r0, (MAS0_TLBSEL(1))@h
 204         mtspr   SPRN_MAS0,r0
 205         mtspr   SPRN_MAS1,r10
 206         mtspr   SPRN_MAS2,r9
 207         ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)
 208         mtspr   SPRN_MAS3,r9
 209         tlbwe
 210         addi    r11, r11, 1
 211         bdnz+   next_tlb_setup
 212 
 213 /* 7. Jump to our 1:1 mapping */
 214         mr      r6, r25
 215 #else
 216         #error You need to specify the mapping or not use this at all.
 217 #endif
 218 
 219         lis     r7,MSR_KERNEL@h
 220         ori     r7,r7,MSR_KERNEL@l
 221         bl      1f                      /* Find our address */
 222 1:      mflr    r9
 223         rlwimi  r6,r9,0,20,31
 224         addi    r6,r6,(2f - 1b)
 225         mtspr   SPRN_SRR0,r6
 226         mtspr   SPRN_SRR1,r7
 227         rfi                             /* start execution out of TLB1[0] entry */
 228 
 229 /* 8. Clear out the temp mapping */
 230 2:      lis     r7,0x1000       /* Set MAS0(TLBSEL) = 1 */
 231         rlwimi  r7,r5,16,4,15   /* Setup MAS0 = TLBSEL | ESEL(r5) */
 232         mtspr   SPRN_MAS0,r7
 233         tlbre
 234         mfspr   r8,SPRN_MAS1
 235         rlwinm  r8,r8,0,2,0     /* clear IPROT */
 236         mtspr   SPRN_MAS1,r8
 237         tlbwe
 238         /* Invalidate TLB1 */
 239         li      r9,0x0c
 240         tlbivax 0,r9
 241         TLBSYNC

/* [<][>][^][v][top][bottom][index][help] */