0001
0002
0003
0004
0005
0006
0007 .text
0008 .align 32
0009
0010
0011 #define LOAD_ITLB_INFO(BASE, VADDR, CTX) \
0012 ldx [BASE + HV_FAULT_I_ADDR_OFFSET], VADDR; \
0013 ldx [BASE + HV_FAULT_I_CTX_OFFSET], CTX;
0014
0015
0016 #define LOAD_DTLB_INFO(BASE, VADDR, CTX) \
0017 ldx [BASE + HV_FAULT_D_ADDR_OFFSET], VADDR; \
0018 ldx [BASE + HV_FAULT_D_CTX_OFFSET], CTX;
0019
0020
0021
0022
0023
0024 #define COMPUTE_TAG_TARGET(DEST, VADDR, CTX, ZERO_CTX_LABEL) \
0025 srlx VADDR, 22, DEST; \
0026 brz,pn CTX, ZERO_CTX_LABEL; \
0027 nop;
0028
0029
0030
0031
0032
0033
0034
0035
0036 #define COMPUTE_TSB_PTR(TSB_PTR, VADDR, HASH_SHIFT, TMP1, TMP2) \
0037 and TSB_PTR, 0x7, TMP1; \
0038 mov 512, TMP2; \
0039 andn TSB_PTR, 0x7, TSB_PTR; \
0040 sllx TMP2, TMP1, TMP2; \
0041 srlx VADDR, HASH_SHIFT, TMP1; \
0042 sub TMP2, 1, TMP2; \
0043 and TMP1, TMP2, TMP1; \
0044 sllx TMP1, 4, TMP1; \
0045 add TSB_PTR, TMP1, TSB_PTR;
0046
0047 sun4v_itlb_miss:
0048
0049 ldxa [%g0] ASI_SCRATCHPAD, %g2
0050
0051
0052 mov SCRATCHPAD_UTSBREG1, %g1
0053 ldxa [%g1] ASI_SCRATCHPAD, %g1
0054
0055 LOAD_ITLB_INFO(%g2, %g4, %g5)
0056 COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_itlb_4v)
0057 COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
0058
0059
0060 ldda [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
0061 cmp %g2, %g6
0062 bne,a,pn %xcc, tsb_miss_page_table_walk
0063 mov FAULT_CODE_ITLB, %g3
0064 andcc %g3, _PAGE_EXEC_4V, %g0
0065 be,a,pn %xcc, tsb_do_fault
0066 mov FAULT_CODE_ITLB, %g3
0067
0068
0069
0070
0071
0072
0073
0074 sun4v_itlb_load:
0075 ldxa [%g0] ASI_SCRATCHPAD, %g6
0076 mov %o0, %g1 ! save %o0
0077 mov %o1, %g2 ! save %o1
0078 mov %o2, %g5 ! save %o2
0079 mov %o3, %g7 ! save %o3
0080 mov %g4, %o0 ! vaddr
0081 ldx [%g6 + HV_FAULT_I_CTX_OFFSET], %o1 ! ctx
0082 mov %g3, %o2 ! PTE
0083 mov HV_MMU_IMMU, %o3 ! flags
0084 ta HV_MMU_MAP_ADDR_TRAP
0085 brnz,pn %o0, sun4v_itlb_error
0086 mov %g2, %o1 ! restore %o1
0087 mov %g1, %o0 ! restore %o0
0088 mov %g5, %o2 ! restore %o2
0089 mov %g7, %o3 ! restore %o3
0090
0091 retry
0092
0093 sun4v_dtlb_miss:
0094
0095 ldxa [%g0] ASI_SCRATCHPAD, %g2
0096
0097
0098 mov SCRATCHPAD_UTSBREG1, %g1
0099 ldxa [%g1] ASI_SCRATCHPAD, %g1
0100
0101 LOAD_DTLB_INFO(%g2, %g4, %g5)
0102 COMPUTE_TAG_TARGET(%g6, %g4, %g5, kvmap_dtlb_4v)
0103 COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g3, %g7)
0104
0105
0106 ldda [%g1] ASI_QUAD_LDD_PHYS_4V, %g2
0107 cmp %g2, %g6
0108 bne,a,pn %xcc, tsb_miss_page_table_walk
0109 mov FAULT_CODE_DTLB, %g3
0110
0111
0112
0113
0114
0115
0116
0117 sun4v_dtlb_load:
0118 ldxa [%g0] ASI_SCRATCHPAD, %g6
0119 mov %o0, %g1 ! save %o0
0120 mov %o1, %g2 ! save %o1
0121 mov %o2, %g5 ! save %o2
0122 mov %o3, %g7 ! save %o3
0123 mov %g4, %o0 ! vaddr
0124 ldx [%g6 + HV_FAULT_D_CTX_OFFSET], %o1 ! ctx
0125 mov %g3, %o2 ! PTE
0126 mov HV_MMU_DMMU, %o3 ! flags
0127 ta HV_MMU_MAP_ADDR_TRAP
0128 brnz,pn %o0, sun4v_dtlb_error
0129 mov %g2, %o1 ! restore %o1
0130 mov %g1, %o0 ! restore %o0
0131 mov %g5, %o2 ! restore %o2
0132 mov %g7, %o3 ! restore %o3
0133
0134 retry
0135
0136 sun4v_dtlb_prot:
0137 SET_GL(1)
0138
0139
0140 ldxa [%g0] ASI_SCRATCHPAD, %g5
0141
0142 ldx [%g5 + HV_FAULT_D_ADDR_OFFSET], %g5
0143 rdpr %tl, %g1
0144 cmp %g1, 1
0145 bgu,pn %xcc, winfix_trampoline
0146 mov FAULT_CODE_DTLB | FAULT_CODE_WRITE, %g4
0147 ba,pt %xcc, sparc64_realfault_common
0148 nop
0149
0150
0151
0152
0153
0154
0155 sun4v_itsb_miss:
0156 mov SCRATCHPAD_UTSBREG1, %g1
0157 ldxa [%g1] ASI_SCRATCHPAD, %g1
0158 brz,pn %g5, kvmap_itlb_4v
0159 mov FAULT_CODE_ITLB, %g3
0160 ba,a,pt %xcc, sun4v_tsb_miss_common
0161
0162
0163
0164
0165
0166
0167 sun4v_dtsb_miss:
0168 mov SCRATCHPAD_UTSBREG1, %g1
0169 ldxa [%g1] ASI_SCRATCHPAD, %g1
0170 brz,pn %g5, kvmap_dtlb_4v
0171 mov FAULT_CODE_DTLB, %g3
0172
0173
0174
0175 sun4v_tsb_miss_common:
0176 COMPUTE_TSB_PTR(%g1, %g4, PAGE_SHIFT, %g5, %g7)
0177
0178 sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
0179
0180 #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
0181 mov SCRATCHPAD_UTSBREG2, %g5
0182 ldxa [%g5] ASI_SCRATCHPAD, %g5
0183 cmp %g5, -1
0184 be,pt %xcc, 80f
0185 nop
0186 COMPUTE_TSB_PTR(%g5, %g4, REAL_HPAGE_SHIFT, %g2, %g7)
0187
0188
0189 ldxa [%g0] ASI_SCRATCHPAD, %g2
0190 sub %g2, TRAP_PER_CPU_FAULT_INFO, %g2
0191
0192 80: stx %g5, [%g2 + TRAP_PER_CPU_TSB_HUGE_TEMP]
0193 #endif
0194
0195 ba,pt %xcc, tsb_miss_page_table_walk_sun4v_fastpath
0196 ldx [%g2 + TRAP_PER_CPU_PGD_PADDR], %g7
0197
0198 sun4v_itlb_error:
0199 rdpr %tl, %g1
0200 cmp %g1, 1
0201 ble,pt %icc, sun4v_bad_ra
0202 or %g0, FAULT_CODE_BAD_RA | FAULT_CODE_ITLB, %g1
0203
0204 sethi %hi(sun4v_err_itlb_vaddr), %g1
0205 stx %g4, [%g1 + %lo(sun4v_err_itlb_vaddr)]
0206 sethi %hi(sun4v_err_itlb_ctx), %g1
0207 ldxa [%g0] ASI_SCRATCHPAD, %g6
0208 ldx [%g6 + HV_FAULT_I_CTX_OFFSET], %o1
0209 stx %o1, [%g1 + %lo(sun4v_err_itlb_ctx)]
0210 sethi %hi(sun4v_err_itlb_pte), %g1
0211 stx %g3, [%g1 + %lo(sun4v_err_itlb_pte)]
0212 sethi %hi(sun4v_err_itlb_error), %g1
0213 stx %o0, [%g1 + %lo(sun4v_err_itlb_error)]
0214
0215 sethi %hi(1f), %g7
0216 rdpr %tl, %g4
0217 ba,pt %xcc, etraptl1
0218 1: or %g7, %lo(1f), %g7
0219 mov %l4, %o1
0220 call sun4v_itlb_error_report
0221 add %sp, PTREGS_OFF, %o0
0222
0223
0224
0225 sun4v_dtlb_error:
0226 rdpr %tl, %g1
0227 cmp %g1, 1
0228 ble,pt %icc, sun4v_bad_ra
0229 or %g0, FAULT_CODE_BAD_RA | FAULT_CODE_DTLB, %g1
0230
0231 sethi %hi(sun4v_err_dtlb_vaddr), %g1
0232 stx %g4, [%g1 + %lo(sun4v_err_dtlb_vaddr)]
0233 sethi %hi(sun4v_err_dtlb_ctx), %g1
0234 ldxa [%g0] ASI_SCRATCHPAD, %g6
0235 ldx [%g6 + HV_FAULT_D_CTX_OFFSET], %o1
0236 stx %o1, [%g1 + %lo(sun4v_err_dtlb_ctx)]
0237 sethi %hi(sun4v_err_dtlb_pte), %g1
0238 stx %g3, [%g1 + %lo(sun4v_err_dtlb_pte)]
0239 sethi %hi(sun4v_err_dtlb_error), %g1
0240 stx %o0, [%g1 + %lo(sun4v_err_dtlb_error)]
0241
0242 sethi %hi(1f), %g7
0243 rdpr %tl, %g4
0244 ba,pt %xcc, etraptl1
0245 1: or %g7, %lo(1f), %g7
0246 mov %l4, %o1
0247 call sun4v_dtlb_error_report
0248 add %sp, PTREGS_OFF, %o0
0249
0250
0251
0252 sun4v_bad_ra:
0253 or %g0, %g4, %g5
0254 ba,pt %xcc, sparc64_realfault_common
0255 or %g1, %g0, %g4
0256
0257
0258
0259
0260 sun4v_iacc:
0261 ldxa [%g0] ASI_SCRATCHPAD, %g2
0262 ldx [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3
0263 ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4
0264 ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5
0265 sllx %g3, 16, %g3
0266 or %g5, %g3, %g5
0267 ba,pt %xcc, etrap
0268 rd %pc, %g7
0269 mov %l4, %o1
0270 mov %l5, %o2
0271 call sun4v_insn_access_exception
0272 add %sp, PTREGS_OFF, %o0
0273 ba,a,pt %xcc, rtrap
0274
0275
0276 sun4v_iacc_tl1:
0277 ldxa [%g0] ASI_SCRATCHPAD, %g2
0278 ldx [%g2 + HV_FAULT_I_TYPE_OFFSET], %g3
0279 ldx [%g2 + HV_FAULT_I_ADDR_OFFSET], %g4
0280 ldx [%g2 + HV_FAULT_I_CTX_OFFSET], %g5
0281 sllx %g3, 16, %g3
0282 or %g5, %g3, %g5
0283 ba,pt %xcc, etraptl1
0284 rd %pc, %g7
0285 mov %l4, %o1
0286 mov %l5, %o2
0287 call sun4v_insn_access_exception_tl1
0288 add %sp, PTREGS_OFF, %o0
0289 ba,a,pt %xcc, rtrap
0290
0291
0292 sun4v_dacc:
0293 ldxa [%g0] ASI_SCRATCHPAD, %g2
0294 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
0295 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
0296 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
0297 sllx %g3, 16, %g3
0298 or %g5, %g3, %g5
0299 ba,pt %xcc, etrap
0300 rd %pc, %g7
0301 mov %l4, %o1
0302 mov %l5, %o2
0303 call sun4v_data_access_exception
0304 add %sp, PTREGS_OFF, %o0
0305 ba,a,pt %xcc, rtrap
0306
0307
0308 sun4v_dacc_tl1:
0309 ldxa [%g0] ASI_SCRATCHPAD, %g2
0310 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
0311 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
0312 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
0313 sllx %g3, 16, %g3
0314 or %g5, %g3, %g5
0315 ba,pt %xcc, etraptl1
0316 rd %pc, %g7
0317 mov %l4, %o1
0318 mov %l5, %o2
0319 call sun4v_data_access_exception_tl1
0320 add %sp, PTREGS_OFF, %o0
0321 ba,a,pt %xcc, rtrap
0322
0323
0324 sun4v_mna:
0325
0326 rdpr %tl, %g2
0327 cmp %g2, 1
0328 ble,pt %icc, 1f
0329 nop
0330
0331 SET_GL(1)
0332 ldxa [%g0] ASI_SCRATCHPAD, %g2
0333 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g5
0334 mov HV_FAULT_TYPE_UNALIGNED, %g3
0335 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g4
0336 sllx %g3, 16, %g3
0337 or %g4, %g3, %g4
0338 ba,pt %xcc, winfix_mna
0339 rdpr %tpc, %g3
0340
0341
0342 1: ldxa [%g0] ASI_SCRATCHPAD, %g2
0343 mov HV_FAULT_TYPE_UNALIGNED, %g3
0344 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
0345 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
0346 sllx %g3, 16, %g3
0347 or %g5, %g3, %g5
0348
0349 ba,pt %xcc, etrap
0350 rd %pc, %g7
0351 mov %l4, %o1
0352 mov %l5, %o2
0353 call sun4v_do_mna
0354 add %sp, PTREGS_OFF, %o0
0355 ba,a,pt %xcc, rtrap
0356 nop
0357
0358
0359 sun4v_privact:
0360 ba,pt %xcc, etrap
0361 rd %pc, %g7
0362 call do_privact
0363 add %sp, PTREGS_OFF, %o0
0364 ba,a,pt %xcc, rtrap
0365
0366
0367 sun4v_lddfmna:
0368 ldxa [%g0] ASI_SCRATCHPAD, %g2
0369 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
0370 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
0371 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
0372 sllx %g3, 16, %g3
0373 or %g5, %g3, %g5
0374 ba,pt %xcc, etrap
0375 rd %pc, %g7
0376 mov %l4, %o1
0377 mov %l5, %o2
0378 call handle_lddfmna
0379 add %sp, PTREGS_OFF, %o0
0380 ba,a,pt %xcc, rtrap
0381
0382
0383 sun4v_stdfmna:
0384 ldxa [%g0] ASI_SCRATCHPAD, %g2
0385 ldx [%g2 + HV_FAULT_D_TYPE_OFFSET], %g3
0386 ldx [%g2 + HV_FAULT_D_ADDR_OFFSET], %g4
0387 ldx [%g2 + HV_FAULT_D_CTX_OFFSET], %g5
0388 sllx %g3, 16, %g3
0389 or %g5, %g3, %g5
0390 ba,pt %xcc, etrap
0391 rd %pc, %g7
0392 mov %l4, %o1
0393 mov %l5, %o2
0394 call handle_stdfmna
0395 add %sp, PTREGS_OFF, %o0
0396 ba,a,pt %xcc, rtrap
0397
0398 #define BRANCH_ALWAYS 0x10680000
0399 #define NOP 0x01000000
0400 #define SUN4V_DO_PATCH(OLD, NEW) \
0401 sethi %hi(NEW), %g1; \
0402 or %g1, %lo(NEW), %g1; \
0403 sethi %hi(OLD), %g2; \
0404 or %g2, %lo(OLD), %g2; \
0405 sub %g1, %g2, %g1; \
0406 sethi %hi(BRANCH_ALWAYS), %g3; \
0407 sll %g1, 11, %g1; \
0408 srl %g1, 11 + 2, %g1; \
0409 or %g3, %lo(BRANCH_ALWAYS), %g3; \
0410 or %g3, %g1, %g3; \
0411 stw %g3, [%g2]; \
0412 sethi %hi(NOP), %g3; \
0413 or %g3, %lo(NOP), %g3; \
0414 stw %g3, [%g2 + 0x4]; \
0415 flush %g2;
0416
0417 .globl sun4v_patch_tlb_handlers
0418 .type sun4v_patch_tlb_handlers,#function
0419 sun4v_patch_tlb_handlers:
0420 SUN4V_DO_PATCH(tl0_iamiss, sun4v_itlb_miss)
0421 SUN4V_DO_PATCH(tl1_iamiss, sun4v_itlb_miss)
0422 SUN4V_DO_PATCH(tl0_damiss, sun4v_dtlb_miss)
0423 SUN4V_DO_PATCH(tl1_damiss, sun4v_dtlb_miss)
0424 SUN4V_DO_PATCH(tl0_daprot, sun4v_dtlb_prot)
0425 SUN4V_DO_PATCH(tl1_daprot, sun4v_dtlb_prot)
0426 SUN4V_DO_PATCH(tl0_iax, sun4v_iacc)
0427 SUN4V_DO_PATCH(tl1_iax, sun4v_iacc_tl1)
0428 SUN4V_DO_PATCH(tl0_dax, sun4v_dacc)
0429 SUN4V_DO_PATCH(tl1_dax, sun4v_dacc_tl1)
0430 SUN4V_DO_PATCH(tl0_mna, sun4v_mna)
0431 SUN4V_DO_PATCH(tl1_mna, sun4v_mna)
0432 SUN4V_DO_PATCH(tl0_lddfmna, sun4v_lddfmna)
0433 SUN4V_DO_PATCH(tl0_stdfmna, sun4v_stdfmna)
0434 SUN4V_DO_PATCH(tl0_privact, sun4v_privact)
0435 retl
0436 nop
0437 .size sun4v_patch_tlb_handlers,.-sun4v_patch_tlb_handlers