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