linux/arch/sparc/kernel/sun4v_tlb_miss.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/* sun4v_tlb_miss.S: Sun4v TLB miss handlers.
   3 *
   4 * Copyright (C) 2006 <davem@davemloft.net>
   5 */
   6
   7        .text
   8        .align  32
   9
  10        /* Load ITLB fault information into VADDR and CTX, using BASE.  */
  11#define LOAD_ITLB_INFO(BASE, VADDR, CTX) \
  12        ldx     [BASE + HV_FAULT_I_ADDR_OFFSET], VADDR; \
  13        ldx     [BASE + HV_FAULT_I_CTX_OFFSET], CTX;
  14
  15        /* Load DTLB fault information into VADDR and CTX, using BASE.  */
  16#define LOAD_DTLB_INFO(BASE, VADDR, CTX) \
  17        ldx     [BASE + HV_FAULT_D_ADDR_OFFSET], VADDR; \
  18        ldx     [BASE + HV_FAULT_D_CTX_OFFSET], CTX;
  19
  20        /* DEST = (VADDR >> 22)
  21         *
  22         * Branch to ZERO_CTX_LABEL if context is zero.
  23         */
  24#define COMPUTE_TAG_TARGET(DEST, VADDR, CTX, ZERO_CTX_LABEL) \
  25        srlx    VADDR, 22, DEST; \
  26        brz,pn  CTX, ZERO_CTX_LABEL; \
  27         nop;
  28
  29        /* Create TSB pointer.  This is something like:
  30         *
  31         * index_mask = (512 << (tsb_reg & 0x7UL)) - 1UL;
  32         * tsb_base = tsb_reg & ~0x7UL;
  33         * tsb_index = ((vaddr >> HASH_SHIFT) & tsb_mask);
  34         * tsb_ptr = tsb_base + (tsb_index * 16);
  35         */
  36#define COMPUTE_TSB_PTR(TSB_PTR, VADDR, HASH_SHIFT, TMP1, TMP2) \
  37        and     TSB_PTR, 0x7, TMP1;                     \
  38        mov     512, TMP2;                              \
  39        andn    TSB_PTR, 0x7, TSB_PTR;                  \
  40        sllx    TMP2, TMP1, TMP2;                       \
  41        srlx    VADDR, HASH_SHIFT, TMP1;                \
  42        sub     TMP2, 1, TMP2;                          \
  43        and     TMP1, TMP2, TMP1;                       \
  44        sllx    TMP1, 4, TMP1;                          \
  45        add     TSB_PTR, TMP1, TSB_PTR;
  46
  47sun4v_itlb_miss:
  48        /* Load MMU Miss base into %g2.  */
  49        ldxa    [%g0] ASI_SCRATCHPAD, %g2
  50        
  51        /* Load UTSB reg into %g1.  */
  52        mov     SCRATCHPAD_UTSBREG1, %g1
  53        ldxa    [%g1] ASI_SCRATCHPAD, %g1
  54
  55        LOAD_ITLB_INFO(%g2, %g4, %g5)
  56        COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_itlb_4v)
  57        COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
  58
  59        /* Load TSB tag/pte into %g2/%g3 and compare the tag.  */
  60        ldda    [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
  61        cmp     %g2, %g6
  62        bne,a,pn %xcc, tsb_miss_page_table_walk
  63         mov    FAULT_CODE_ITLB, %g3
  64        andcc   %g3, _PAGE_EXEC_4V, %g0
  65        be,a,pn %xcc, tsb_do_fault
  66         mov    FAULT_CODE_ITLB, %g3
  67
  68        /* We have a valid entry, make hypervisor call to load
  69         * I-TLB and return from trap.
  70         *
  71         * %g3: PTE
  72         * %g4: vaddr
  73         */
  74sun4v_itlb_load:
  75        ldxa    [%g0] ASI_SCRATCHPAD, %g6
  76        mov     %o0, %g1                ! save %o0
  77        mov     %o1, %g2                ! save %o1
  78        mov     %o2, %g5                ! save %o2
  79        mov     %o3, %g7                ! save %o3
  80        mov     %g4, %o0                ! vaddr
  81        ldx     [%g6 + HV_FAULT_I_CTX_OFFSET], %o1      ! ctx
  82        mov     %g3, %o2                ! PTE
  83        mov     HV_MMU_IMMU, %o3        ! flags
  84        ta      HV_MMU_MAP_ADDR_TRAP
  85        brnz,pn %o0, sun4v_itlb_error
  86         mov    %g2, %o1                ! restore %o1
  87        mov     %g1, %o0                ! restore %o0
  88        mov     %g5, %o2                ! restore %o2
  89        mov     %g7, %o3                ! restore %o3
  90
  91        retry
  92
  93sun4v_dtlb_miss:
  94        /* Load MMU Miss base into %g2.  */
  95        ldxa    [%g0] ASI_SCRATCHPAD, %g2
  96        
  97        /* Load UTSB reg into %g1.  */
  98        mov     SCRATCHPAD_UTSBREG1, %g1
  99        ldxa    [%g1] ASI_SCRATCHPAD, %g1
 100
 101        LOAD_DTLB_INFO(%g2, %g4, %g5)
 102        COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_dtlb_4v)
 103        COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
 104
 105        /* Load TSB tag/pte into %g2/%g3 and compare the tag.  */
 106        ldda    [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
 107        cmp     %g2, %g6
 108        bne,a,pn %xcc, tsb_miss_page_table_walk
 109         mov    FAULT_CODE_DTLB, %g3
 110
 111        /* We have a valid entry, make hypervisor call to load
 112         * D-TLB and return from trap.
 113         *
 114         * %g3: PTE
 115         * %g4: vaddr
 116         */
 117sun4v_dtlb_load:
 118        ldxa    [%g0] ASI_SCRATCHPAD, %g6
 119        mov     %o0, %g1                ! save %o0
 120        mov     %o1, %g2                ! save %o1
 121        mov     %o2, %g5                ! save %o2
 122        mov     %o3, %g7                ! save %o3
 123        mov     %g4, %o0                ! vaddr
 124        ldx     [%g6 + HV_FAULT_D_CTX_OFFSET], %o1      ! ctx
 125        mov     %g3, %o2                ! PTE
 126        mov     HV_MMU_DMMU, %o3        ! flags
 127        ta      HV_MMU_MAP_ADDR_TRAP
 128        brnz,pn %o0, sun4v_dtlb_error
 129         mov    %g2, %o1                ! restore %o1
 130        mov     %g1, %o0                ! restore %o0
 131        mov     %g5, %o2                ! restore %o2
 132        mov     %g7, %o3                ! restore %o3
 133
 134        retry
 135
 136sun4v_dtlb_prot:
 137        SET_GL(1)
 138
 139        /* Load MMU Miss base into %g5.  */
 140        ldxa    [%g0] ASI_SCRATCHPAD, %g5
 141        
 142        ldx     [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
 143        rdpr    %tl, %g1
 144        cmp     %g1, 1
 145        bgu,pn  %xcc, winfix_trampoline
 146         mov    FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4
 147        ba,pt   %xcc, sparc64_realfault_common
 148         nop
 149
 150        /* Called from trap table:
 151         * %g4: vaddr
 152         * %g5: context
 153         * %g6: TAG TARGET
 154         */
 155sun4v_itsb_miss:
 156        mov     SCRATCHPAD_UTSBREG1, %g1
 157        ldxa    [%g1] ASI_SCRATCHPAD, %g1
 158        brz,pn  %g5, kvmap_itlb_4v
 159         mov    FAULT_CODE_ITLB, %g3
 160        ba,a,pt %xcc, sun4v_tsb_miss_common
 161
 162        /* Called from trap table:
 163         * %g4: vaddr
 164         * %g5: context
 165         * %g6: TAG TARGET
 166         */
 167sun4v_dtsb_miss:
 168        mov     SCRATCHPAD_UTSBREG1, %g1
 169        ldxa    [%g1] ASI_SCRATCHPAD, %g1
 170        brz,pn  %g5, kvmap_dtlb_4v
 171         mov    FAULT_CODE_DTLB, %g3
 172
 173        /* fallthrough */
 174
 175sun4v_tsb_miss_common:
 176        COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g5, %g7)
 177
 178        sub     %g2, TRAP_PER_CPU_FAULT_INFO, %g2
 179
 180#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 181        mov     SCRATCHPAD_UTSBREG2, %g5
 182        ldxa    [%g5] ASI_SCRATCHPAD, %g5
 183        cmp     %g5, -1
 184        be,pt   %xcc, 80f
 185         nop
 186        COMPUTE_TSB_PTR(%g5, %g4, REAL_HPAGE_SHIFT, %g2, %g7)
 187
 188        /* That clobbered %g2, reload it.  */
 189        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 190        sub     %g2, TRAP_PER_CPU_FAULT_INFO, %g2
 191
 19280:     stx     %g5, [%g2 + TRAP_PER_CPU_TSB_HUGE_TEMP]
 193#endif
 194
 195        ba,pt   %xcc, tsb_miss_page_table_walk_sun4v_fastpath
 196         ldx    [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7
 197
 198sun4v_itlb_error:
 199        rdpr    %tl, %g1
 200        cmp     %g1, 1
 201        ble,pt  %icc, sun4v_bad_ra
 202         or     %g0, FAULT_CODE_BAD_RA | FAULT_CODE_ITLB, %g1
 203
 204        sethi   %hi(sun4v_err_itlb_vaddr), %g1
 205        stx     %g4, [%g1 + %lo(sun4v_err_itlb_vaddr)]
 206        sethi   %hi(sun4v_err_itlb_ctx), %g1
 207        ldxa    [%g0] ASI_SCRATCHPAD, %g6
 208        ldx     [%g6 + HV_FAULT_I_CTX_OFFSET], %o1
 209        stx     %o1, [%g1 + %lo(sun4v_err_itlb_ctx)]
 210        sethi   %hi(sun4v_err_itlb_pte), %g1
 211        stx     %g3, [%g1 + %lo(sun4v_err_itlb_pte)]
 212        sethi   %hi(sun4v_err_itlb_error), %g1
 213        stx     %o0, [%g1 + %lo(sun4v_err_itlb_error)]
 214
 215        sethi   %hi(1f), %g7
 216        rdpr    %tl, %g4
 217        ba,pt   %xcc, etraptl1
 2181:       or     %g7, %lo(1f), %g7
 219        mov     %l4, %o1
 220        call    sun4v_itlb_error_report
 221         add    %sp, PTREGS_OFF, %o0
 222
 223        /* NOTREACHED */
 224
 225sun4v_dtlb_error:
 226        rdpr    %tl, %g1
 227        cmp     %g1, 1
 228        ble,pt  %icc, sun4v_bad_ra
 229         or     %g0, FAULT_CODE_BAD_RA | FAULT_CODE_DTLB, %g1
 230
 231        sethi   %hi(sun4v_err_dtlb_vaddr), %g1
 232        stx     %g4, [%g1 + %lo(sun4v_err_dtlb_vaddr)]
 233        sethi   %hi(sun4v_err_dtlb_ctx), %g1
 234        ldxa    [%g0] ASI_SCRATCHPAD, %g6
 235        ldx     [%g6 + HV_FAULT_D_CTX_OFFSET], %o1
 236        stx     %o1, [%g1 + %lo(sun4v_err_dtlb_ctx)]
 237        sethi   %hi(sun4v_err_dtlb_pte), %g1
 238        stx     %g3, [%g1 + %lo(sun4v_err_dtlb_pte)]
 239        sethi   %hi(sun4v_err_dtlb_error), %g1
 240        stx     %o0, [%g1 + %lo(sun4v_err_dtlb_error)]
 241
 242        sethi   %hi(1f), %g7
 243        rdpr    %tl, %g4
 244        ba,pt   %xcc, etraptl1
 2451:       or     %g7, %lo(1f), %g7
 246        mov     %l4, %o1
 247        call    sun4v_dtlb_error_report
 248         add    %sp, PTREGS_OFF, %o0
 249
 250        /* NOTREACHED */
 251
 252sun4v_bad_ra:
 253        or      %g0, %g4, %g5
 254        ba,pt   %xcc, sparc64_realfault_common
 255         or     %g1, %g0, %g4
 256
 257        /* NOTREACHED */
 258
 259        /* Instruction Access Exception, tl0. */
 260sun4v_iacc:
 261        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 262        ldx     [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3
 263        ldx     [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4
 264        ldx     [%g2 + HV_FAULT_I_CTX_OFFSET], %g5
 265        sllx    %g3, 16, %g3
 266        or      %g5, %g3, %g5
 267        ba,pt   %xcc, etrap
 268         rd     %pc, %g7
 269        mov     %l4, %o1
 270        mov     %l5, %o2
 271        call    sun4v_insn_access_exception
 272         add    %sp, PTREGS_OFF, %o0
 273        ba,a,pt %xcc, rtrap
 274
 275        /* Instruction Access Exception, tl1. */
 276sun4v_iacc_tl1:
 277        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 278        ldx     [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3
 279        ldx     [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4
 280        ldx     [%g2 + HV_FAULT_I_CTX_OFFSET], %g5
 281        sllx    %g3, 16, %g3
 282        or      %g5, %g3, %g5
 283        ba,pt   %xcc, etraptl1
 284         rd     %pc, %g7
 285        mov     %l4, %o1
 286        mov     %l5, %o2
 287        call    sun4v_insn_access_exception_tl1
 288         add    %sp, PTREGS_OFF, %o0
 289        ba,a,pt %xcc, rtrap
 290
 291        /* Data Access Exception, tl0. */
 292sun4v_dacc:
 293        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 294        ldx     [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
 295        ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
 296        ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
 297        sllx    %g3, 16, %g3
 298        or      %g5, %g3, %g5
 299        ba,pt   %xcc, etrap
 300         rd     %pc, %g7
 301        mov     %l4, %o1
 302        mov     %l5, %o2
 303        call    sun4v_data_access_exception
 304         add    %sp, PTREGS_OFF, %o0
 305        ba,a,pt %xcc, rtrap
 306
 307        /* Data Access Exception, tl1. */
 308sun4v_dacc_tl1:
 309        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 310        ldx     [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
 311        ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
 312        ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
 313        sllx    %g3, 16, %g3
 314        or      %g5, %g3, %g5
 315        ba,pt   %xcc, etraptl1
 316         rd     %pc, %g7
 317        mov     %l4, %o1
 318        mov     %l5, %o2
 319        call    sun4v_data_access_exception_tl1
 320         add    %sp, PTREGS_OFF, %o0
 321        ba,a,pt %xcc, rtrap
 322
 323        /* Memory Address Unaligned.  */
 324sun4v_mna:
 325        /* Window fixup? */
 326        rdpr    %tl, %g2
 327        cmp     %g2, 1
 328        ble,pt  %icc, 1f
 329         nop
 330
 331        SET_GL(1)
 332        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 333        ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5
 334        mov     HV_FAULT_TYPE_UNALIGNED, %g3
 335        ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g4
 336        sllx    %g3, 16, %g3
 337        or      %g4, %g3, %g4
 338        ba,pt   %xcc, winfix_mna
 339         rdpr   %tpc, %g3
 340        /* not reached */
 341
 3421:      ldxa    [%g0] ASI_SCRATCHPAD, %g2
 343        mov     HV_FAULT_TYPE_UNALIGNED, %g3
 344        ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
 345        ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
 346        sllx    %g3, 16, %g3
 347        or      %g5, %g3, %g5
 348
 349        ba,pt   %xcc, etrap
 350         rd     %pc, %g7
 351        mov     %l4, %o1
 352        mov     %l5, %o2
 353        call    sun4v_do_mna
 354         add    %sp, PTREGS_OFF, %o0
 355        ba,a,pt %xcc, rtrap
 356         nop
 357
 358        /* Privileged Action.  */
 359sun4v_privact:
 360        ba,pt   %xcc, etrap
 361         rd     %pc, %g7
 362        call    do_privact
 363         add    %sp, PTREGS_OFF, %o0
 364        ba,a,pt %xcc, rtrap
 365
 366        /* Unaligned ldd float, tl0. */
 367sun4v_lddfmna:
 368        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 369        ldx     [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
 370        ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
 371        ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
 372        sllx    %g3, 16, %g3
 373        or      %g5, %g3, %g5
 374        ba,pt   %xcc, etrap
 375         rd     %pc, %g7
 376        mov     %l4, %o1
 377        mov     %l5, %o2
 378        call    handle_lddfmna
 379         add    %sp, PTREGS_OFF, %o0
 380        ba,a,pt %xcc, rtrap
 381
 382        /* Unaligned std float, tl0. */
 383sun4v_stdfmna:
 384        ldxa    [%g0] ASI_SCRATCHPAD, %g2
 385        ldx     [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
 386        ldx     [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
 387        ldx     [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
 388        sllx    %g3, 16, %g3
 389        or      %g5, %g3, %g5
 390        ba,pt   %xcc, etrap
 391         rd     %pc, %g7
 392        mov     %l4, %o1
 393        mov     %l5, %o2
 394        call    handle_stdfmna
 395         add    %sp, PTREGS_OFF, %o0
 396        ba,a,pt %xcc, rtrap
 397
 398#define BRANCH_ALWAYS   0x10680000
 399#define NOP             0x01000000
 400#define SUN4V_DO_PATCH(OLD, NEW)        \
 401        sethi   %hi(NEW), %g1; \
 402        or      %g1, %lo(NEW), %g1; \
 403        sethi   %hi(OLD), %g2; \
 404        or      %g2, %lo(OLD), %g2; \
 405        sub     %g1, %g2, %g1; \
 406        sethi   %hi(BRANCH_ALWAYS), %g3; \
 407        sll     %g1, 11, %g1; \
 408        srl     %g1, 11 + 2, %g1; \
 409        or      %g3, %lo(BRANCH_ALWAYS), %g3; \
 410        or      %g3, %g1, %g3; \
 411        stw     %g3, [%g2]; \
 412        sethi   %hi(NOP), %g3; \
 413        or      %g3, %lo(NOP), %g3; \
 414        stw     %g3, [%g2 + 0x4]; \
 415        flush   %g2;
 416
 417        .globl  sun4v_patch_tlb_handlers
 418        .type   sun4v_patch_tlb_handlers,#function
 419sun4v_patch_tlb_handlers:
 420        SUN4V_DO_PATCH(tl0_iamiss, sun4v_itlb_miss)
 421        SUN4V_DO_PATCH(tl1_iamiss, sun4v_itlb_miss)
 422        SUN4V_DO_PATCH(tl0_damiss, sun4v_dtlb_miss)
 423        SUN4V_DO_PATCH(tl1_damiss, sun4v_dtlb_miss)
 424        SUN4V_DO_PATCH(tl0_daprot, sun4v_dtlb_prot)
 425        SUN4V_DO_PATCH(tl1_daprot, sun4v_dtlb_prot)
 426        SUN4V_DO_PATCH(tl0_iax, sun4v_iacc)
 427        SUN4V_DO_PATCH(tl1_iax, sun4v_iacc_tl1)
 428        SUN4V_DO_PATCH(tl0_dax, sun4v_dacc)
 429        SUN4V_DO_PATCH(tl1_dax, sun4v_dacc_tl1)
 430        SUN4V_DO_PATCH(tl0_mna, sun4v_mna)
 431        SUN4V_DO_PATCH(tl1_mna, sun4v_mna)
 432        SUN4V_DO_PATCH(tl0_lddfmna, sun4v_lddfmna)
 433        SUN4V_DO_PATCH(tl0_stdfmna, sun4v_stdfmna)
 434        SUN4V_DO_PATCH(tl0_privact, sun4v_privact)
 435        retl
 436         nop
 437        .size   sun4v_patch_tlb_handlers,.-sun4v_patch_tlb_handlers
 438