1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* sun4v_ivec.S: Sun4v interrupt vector handli 2 /* sun4v_ivec.S: Sun4v interrupt vector handling. 3 * 3 * 4 * Copyright (C) 2006 <davem@davemloft.net> 4 * Copyright (C) 2006 <davem@davemloft.net> 5 */ 5 */ 6 6 7 #include <asm/cpudata.h> 7 #include <asm/cpudata.h> 8 #include <asm/intr_queue.h> 8 #include <asm/intr_queue.h> 9 #include <asm/pil.h> 9 #include <asm/pil.h> 10 10 11 .text 11 .text 12 .align 32 12 .align 32 13 13 14 sun4v_cpu_mondo: 14 sun4v_cpu_mondo: 15 /* Head offset in %g2, tail offset in 15 /* Head offset in %g2, tail offset in %g4. 16 * If they are the same, no work. 16 * If they are the same, no work. 17 */ 17 */ 18 mov INTRQ_CPU_MONDO_HEAD, %g2 18 mov INTRQ_CPU_MONDO_HEAD, %g2 19 ldxa [%g2] ASI_QUEUE, %g2 19 ldxa [%g2] ASI_QUEUE, %g2 20 mov INTRQ_CPU_MONDO_TAIL, %g4 20 mov INTRQ_CPU_MONDO_TAIL, %g4 21 ldxa [%g4] ASI_QUEUE, %g4 21 ldxa [%g4] ASI_QUEUE, %g4 22 cmp %g2, %g4 22 cmp %g2, %g4 23 be,pn %xcc, sun4v_cpu_mondo_queue_em 23 be,pn %xcc, sun4v_cpu_mondo_queue_empty 24 nop 24 nop 25 25 26 /* Get &trap_block[smp_processor_id()] 26 /* Get &trap_block[smp_processor_id()] into %g4. */ 27 ldxa [%g0] ASI_SCRATCHPAD, %g4 27 ldxa [%g0] ASI_SCRATCHPAD, %g4 28 sub %g4, TRAP_PER_CPU_FAULT_INFO, 28 sub %g4, TRAP_PER_CPU_FAULT_INFO, %g4 29 29 30 /* Get smp_processor_id() into %g3 */ 30 /* Get smp_processor_id() into %g3 */ 31 sethi %hi(trap_block), %g5 31 sethi %hi(trap_block), %g5 32 or %g5, %lo(trap_block), %g5 32 or %g5, %lo(trap_block), %g5 33 sub %g4, %g5, %g3 33 sub %g4, %g5, %g3 34 srlx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 34 srlx %g3, TRAP_BLOCK_SZ_SHIFT, %g3 35 35 36 /* Increment cpu_mondo_counter[smp_pro 36 /* Increment cpu_mondo_counter[smp_processor_id()] */ 37 sethi %hi(cpu_mondo_counter), %g5 37 sethi %hi(cpu_mondo_counter), %g5 38 or %g5, %lo(cpu_mondo_counter), % 38 or %g5, %lo(cpu_mondo_counter), %g5 39 sllx %g3, 3, %g3 39 sllx %g3, 3, %g3 40 add %g5, %g3, %g5 40 add %g5, %g3, %g5 41 ldx [%g5], %g3 41 ldx [%g5], %g3 42 add %g3, 1, %g3 42 add %g3, 1, %g3 43 stx %g3, [%g5] 43 stx %g3, [%g5] 44 44 45 /* Get CPU mondo queue base phys addre 45 /* Get CPU mondo queue base phys address into %g7. */ 46 ldx [%g4 + TRAP_PER_CPU_CPU_MONDO_ 46 ldx [%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7 47 47 48 /* Now get the cross-call arguments an 48 /* Now get the cross-call arguments and handler PC, same 49 * layout as sun4u: 49 * layout as sun4u: 50 * 50 * 51 * 1st 64-bit word: low half is 32-bit 51 * 1st 64-bit word: low half is 32-bit PC, put into %g3 and jmpl to it 52 * high half is conte 52 * high half is context arg to MMU flushes, into %g5 53 * 2nd 64-bit word: 64-bit arg, load i 53 * 2nd 64-bit word: 64-bit arg, load into %g1 54 * 3rd 64-bit word: 64-bit arg, load i 54 * 3rd 64-bit word: 64-bit arg, load into %g7 55 */ 55 */ 56 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, % 56 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, %g3 57 add %g2, 0x8, %g2 57 add %g2, 0x8, %g2 58 srlx %g3, 32, %g5 58 srlx %g3, 32, %g5 59 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, % 59 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, %g1 60 add %g2, 0x8, %g2 60 add %g2, 0x8, %g2 61 srl %g3, 0, %g3 61 srl %g3, 0, %g3 62 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, % 62 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, %g7 63 add %g2, 0x40 - 0x8 - 0x8, %g2 63 add %g2, 0x40 - 0x8 - 0x8, %g2 64 64 65 /* Update queue head pointer. */ 65 /* Update queue head pointer. */ 66 lduw [%g4 + TRAP_PER_CPU_CPU_MONDO_ 66 lduw [%g4 + TRAP_PER_CPU_CPU_MONDO_QMASK], %g4 67 and %g2, %g4, %g2 67 and %g2, %g4, %g2 68 68 69 mov INTRQ_CPU_MONDO_HEAD, %g4 69 mov INTRQ_CPU_MONDO_HEAD, %g4 70 stxa %g2, [%g4] ASI_QUEUE 70 stxa %g2, [%g4] ASI_QUEUE 71 membar #Sync 71 membar #Sync 72 72 73 jmpl %g3, %g0 73 jmpl %g3, %g0 74 nop 74 nop 75 75 76 sun4v_cpu_mondo_queue_empty: 76 sun4v_cpu_mondo_queue_empty: 77 retry 77 retry 78 78 79 sun4v_dev_mondo: 79 sun4v_dev_mondo: 80 /* Head offset in %g2, tail offset in 80 /* Head offset in %g2, tail offset in %g4. */ 81 mov INTRQ_DEVICE_MONDO_HEAD, %g2 81 mov INTRQ_DEVICE_MONDO_HEAD, %g2 82 ldxa [%g2] ASI_QUEUE, %g2 82 ldxa [%g2] ASI_QUEUE, %g2 83 mov INTRQ_DEVICE_MONDO_TAIL, %g4 83 mov INTRQ_DEVICE_MONDO_TAIL, %g4 84 ldxa [%g4] ASI_QUEUE, %g4 84 ldxa [%g4] ASI_QUEUE, %g4 85 cmp %g2, %g4 85 cmp %g2, %g4 86 be,pn %xcc, sun4v_dev_mondo_queue_em 86 be,pn %xcc, sun4v_dev_mondo_queue_empty 87 nop 87 nop 88 88 89 /* Get &trap_block[smp_processor_id()] 89 /* Get &trap_block[smp_processor_id()] into %g4. */ 90 ldxa [%g0] ASI_SCRATCHPAD, %g4 90 ldxa [%g0] ASI_SCRATCHPAD, %g4 91 sub %g4, TRAP_PER_CPU_FAULT_INFO, 91 sub %g4, TRAP_PER_CPU_FAULT_INFO, %g4 92 92 93 /* Get DEV mondo queue base phys addre 93 /* Get DEV mondo queue base phys address into %g5. */ 94 ldx [%g4 + TRAP_PER_CPU_DEV_MONDO_ 94 ldx [%g4 + TRAP_PER_CPU_DEV_MONDO_PA], %g5 95 95 96 /* Load IVEC into %g3. */ 96 /* Load IVEC into %g3. */ 97 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 97 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 98 add %g2, 0x40, %g2 98 add %g2, 0x40, %g2 99 99 100 /* XXX There can be a full 64-byte blo 100 /* XXX There can be a full 64-byte block of data here. 101 * XXX This is how we can get at MSI v 101 * XXX This is how we can get at MSI vector data. 102 * XXX Current we do not capture this, 102 * XXX Current we do not capture this, but when we do we'll 103 * XXX need to add a 64-byte storage a 103 * XXX need to add a 64-byte storage area in the struct ino_bucket 104 * XXX or the struct irq_desc. 104 * XXX or the struct irq_desc. 105 */ 105 */ 106 106 107 /* Update queue head pointer, this fre 107 /* Update queue head pointer, this frees up some registers. */ 108 lduw [%g4 + TRAP_PER_CPU_DEV_MONDO_ 108 lduw [%g4 + TRAP_PER_CPU_DEV_MONDO_QMASK], %g4 109 and %g2, %g4, %g2 109 and %g2, %g4, %g2 110 110 111 mov INTRQ_DEVICE_MONDO_HEAD, %g4 111 mov INTRQ_DEVICE_MONDO_HEAD, %g4 112 stxa %g2, [%g4] ASI_QUEUE 112 stxa %g2, [%g4] ASI_QUEUE 113 membar #Sync 113 membar #Sync 114 114 115 TRAP_LOAD_IRQ_WORK_PA(%g1, %g4) 115 TRAP_LOAD_IRQ_WORK_PA(%g1, %g4) 116 116 117 /* For VIRQs, cookie is encoded as ~bu 117 /* For VIRQs, cookie is encoded as ~bucket_phys_addr */ 118 brlz,pt %g3, 1f 118 brlz,pt %g3, 1f 119 xnor %g3, %g0, %g4 119 xnor %g3, %g0, %g4 120 120 121 /* Get __pa(&ivector_table[IVEC]) into 121 /* Get __pa(&ivector_table[IVEC]) into %g4. */ 122 sethi %hi(ivector_table_pa), %g4 122 sethi %hi(ivector_table_pa), %g4 123 ldx [%g4 + %lo(ivector_table_pa)], 123 ldx [%g4 + %lo(ivector_table_pa)], %g4 124 sllx %g3, 4, %g3 124 sllx %g3, 4, %g3 125 add %g4, %g3, %g4 125 add %g4, %g3, %g4 126 126 127 1: ldx [%g1], %g2 127 1: ldx [%g1], %g2 128 stxa %g2, [%g4] ASI_PHYS_USE_EC 128 stxa %g2, [%g4] ASI_PHYS_USE_EC 129 stx %g4, [%g1] 129 stx %g4, [%g1] 130 130 131 /* Signal the interrupt by setting (1 131 /* Signal the interrupt by setting (1 << pil) in %softint. */ 132 wr %g0, 1 << PIL_DEVICE_IRQ, %set 132 wr %g0, 1 << PIL_DEVICE_IRQ, %set_softint 133 133 134 sun4v_dev_mondo_queue_empty: 134 sun4v_dev_mondo_queue_empty: 135 retry 135 retry 136 136 137 sun4v_res_mondo: 137 sun4v_res_mondo: 138 /* Head offset in %g2, tail offset in 138 /* Head offset in %g2, tail offset in %g4. */ 139 mov INTRQ_RESUM_MONDO_HEAD, %g2 139 mov INTRQ_RESUM_MONDO_HEAD, %g2 140 ldxa [%g2] ASI_QUEUE, %g2 140 ldxa [%g2] ASI_QUEUE, %g2 141 mov INTRQ_RESUM_MONDO_TAIL, %g4 141 mov INTRQ_RESUM_MONDO_TAIL, %g4 142 ldxa [%g4] ASI_QUEUE, %g4 142 ldxa [%g4] ASI_QUEUE, %g4 143 cmp %g2, %g4 143 cmp %g2, %g4 144 be,pn %xcc, sun4v_res_mondo_queue_em 144 be,pn %xcc, sun4v_res_mondo_queue_empty 145 nop 145 nop 146 146 147 /* Get &trap_block[smp_processor_id()] 147 /* Get &trap_block[smp_processor_id()] into %g3. */ 148 ldxa [%g0] ASI_SCRATCHPAD, %g3 148 ldxa [%g0] ASI_SCRATCHPAD, %g3 149 sub %g3, TRAP_PER_CPU_FAULT_INFO, 149 sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 150 150 151 /* Get RES mondo queue base phys addre 151 /* Get RES mondo queue base phys address into %g5. */ 152 ldx [%g3 + TRAP_PER_CPU_RESUM_MOND 152 ldx [%g3 + TRAP_PER_CPU_RESUM_MONDO_PA], %g5 153 153 154 /* Get RES kernel buffer base phys add 154 /* Get RES kernel buffer base phys address into %g7. */ 155 ldx [%g3 + TRAP_PER_CPU_RESUM_KBUF 155 ldx [%g3 + TRAP_PER_CPU_RESUM_KBUF_PA], %g7 156 156 157 /* If the first word is non-zero, queu 157 /* If the first word is non-zero, queue is full. */ 158 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, % 158 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, %g1 159 brnz,pn %g1, sun4v_res_mondo_queue_ful 159 brnz,pn %g1, sun4v_res_mondo_queue_full 160 nop 160 nop 161 161 162 lduw [%g3 + TRAP_PER_CPU_RESUM_QMAS 162 lduw [%g3 + TRAP_PER_CPU_RESUM_QMASK], %g4 163 163 164 /* Remember this entry's offset in %g1 164 /* Remember this entry's offset in %g1. */ 165 mov %g2, %g1 165 mov %g2, %g1 166 166 167 /* Copy 64-byte queue entry into kerne 167 /* Copy 64-byte queue entry into kernel buffer. */ 168 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 168 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 169 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 169 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 170 add %g2, 0x08, %g2 170 add %g2, 0x08, %g2 171 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 171 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 172 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 172 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 173 add %g2, 0x08, %g2 173 add %g2, 0x08, %g2 174 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 174 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 175 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 175 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 176 add %g2, 0x08, %g2 176 add %g2, 0x08, %g2 177 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 177 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 178 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 178 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 179 add %g2, 0x08, %g2 179 add %g2, 0x08, %g2 180 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 180 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 181 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 181 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 182 add %g2, 0x08, %g2 182 add %g2, 0x08, %g2 183 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 183 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 184 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 184 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 185 add %g2, 0x08, %g2 185 add %g2, 0x08, %g2 186 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 186 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 187 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 187 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 188 add %g2, 0x08, %g2 188 add %g2, 0x08, %g2 189 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 189 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 190 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 190 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 191 add %g2, 0x08, %g2 191 add %g2, 0x08, %g2 192 192 193 /* Update queue head pointer. */ 193 /* Update queue head pointer. */ 194 and %g2, %g4, %g2 194 and %g2, %g4, %g2 195 195 196 mov INTRQ_RESUM_MONDO_HEAD, %g4 196 mov INTRQ_RESUM_MONDO_HEAD, %g4 197 stxa %g2, [%g4] ASI_QUEUE 197 stxa %g2, [%g4] ASI_QUEUE 198 membar #Sync 198 membar #Sync 199 199 200 /* Disable interrupts and save registe 200 /* Disable interrupts and save register state so we can call 201 * C code. The etrap handling will le 201 * C code. The etrap handling will leave %g4 in %l4 for us 202 * when it's done. 202 * when it's done. 203 */ 203 */ 204 rdpr %pil, %g2 204 rdpr %pil, %g2 205 wrpr %g0, PIL_NORMAL_MAX, %pil 205 wrpr %g0, PIL_NORMAL_MAX, %pil 206 mov %g1, %g4 206 mov %g1, %g4 207 ba,pt %xcc, etrap_irq 207 ba,pt %xcc, etrap_irq 208 rd %pc, %g7 208 rd %pc, %g7 209 #ifdef CONFIG_TRACE_IRQFLAGS 209 #ifdef CONFIG_TRACE_IRQFLAGS 210 call trace_hardirqs_off 210 call trace_hardirqs_off 211 nop 211 nop 212 #endif 212 #endif 213 /* Log the event. */ 213 /* Log the event. */ 214 add %sp, PTREGS_OFF, %o0 214 add %sp, PTREGS_OFF, %o0 215 call sun4v_resum_error 215 call sun4v_resum_error 216 mov %l4, %o1 216 mov %l4, %o1 217 217 218 /* Return from trap. */ 218 /* Return from trap. */ 219 ba,pt %xcc, rtrap_irq 219 ba,pt %xcc, rtrap_irq 220 nop 220 nop 221 221 222 sun4v_res_mondo_queue_empty: 222 sun4v_res_mondo_queue_empty: 223 retry 223 retry 224 224 225 sun4v_res_mondo_queue_full: 225 sun4v_res_mondo_queue_full: 226 /* The queue is full, consolidate our 226 /* The queue is full, consolidate our damage by setting 227 * the head equal to the tail. We'll 227 * the head equal to the tail. We'll just trap again otherwise. 228 * Call C code to log the event. 228 * Call C code to log the event. 229 */ 229 */ 230 mov INTRQ_RESUM_MONDO_HEAD, %g2 230 mov INTRQ_RESUM_MONDO_HEAD, %g2 231 stxa %g4, [%g2] ASI_QUEUE 231 stxa %g4, [%g2] ASI_QUEUE 232 membar #Sync 232 membar #Sync 233 233 234 rdpr %pil, %g2 234 rdpr %pil, %g2 235 wrpr %g0, PIL_NORMAL_MAX, %pil 235 wrpr %g0, PIL_NORMAL_MAX, %pil 236 ba,pt %xcc, etrap_irq 236 ba,pt %xcc, etrap_irq 237 rd %pc, %g7 237 rd %pc, %g7 238 #ifdef CONFIG_TRACE_IRQFLAGS 238 #ifdef CONFIG_TRACE_IRQFLAGS 239 call trace_hardirqs_off 239 call trace_hardirqs_off 240 nop 240 nop 241 #endif 241 #endif 242 call sun4v_resum_overflow 242 call sun4v_resum_overflow 243 add %sp, PTREGS_OFF, %o0 243 add %sp, PTREGS_OFF, %o0 244 244 245 ba,pt %xcc, rtrap_irq 245 ba,pt %xcc, rtrap_irq 246 nop 246 nop 247 247 248 sun4v_nonres_mondo: 248 sun4v_nonres_mondo: 249 /* Head offset in %g2, tail offset in 249 /* Head offset in %g2, tail offset in %g4. */ 250 mov INTRQ_NONRESUM_MONDO_HEAD, %g2 250 mov INTRQ_NONRESUM_MONDO_HEAD, %g2 251 ldxa [%g2] ASI_QUEUE, %g2 251 ldxa [%g2] ASI_QUEUE, %g2 252 mov INTRQ_NONRESUM_MONDO_TAIL, %g4 252 mov INTRQ_NONRESUM_MONDO_TAIL, %g4 253 ldxa [%g4] ASI_QUEUE, %g4 253 ldxa [%g4] ASI_QUEUE, %g4 254 cmp %g2, %g4 254 cmp %g2, %g4 255 be,pn %xcc, sun4v_nonres_mondo_queue 255 be,pn %xcc, sun4v_nonres_mondo_queue_empty 256 nop 256 nop 257 257 258 /* Get &trap_block[smp_processor_id()] 258 /* Get &trap_block[smp_processor_id()] into %g3. */ 259 ldxa [%g0] ASI_SCRATCHPAD, %g3 259 ldxa [%g0] ASI_SCRATCHPAD, %g3 260 sub %g3, TRAP_PER_CPU_FAULT_INFO, 260 sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 261 261 262 /* Get RES mondo queue base phys addre 262 /* Get RES mondo queue base phys address into %g5. */ 263 ldx [%g3 + TRAP_PER_CPU_NONRESUM_M 263 ldx [%g3 + TRAP_PER_CPU_NONRESUM_MONDO_PA], %g5 264 264 265 /* Get RES kernel buffer base phys add 265 /* Get RES kernel buffer base phys address into %g7. */ 266 ldx [%g3 + TRAP_PER_CPU_NONRESUM_K 266 ldx [%g3 + TRAP_PER_CPU_NONRESUM_KBUF_PA], %g7 267 267 268 /* If the first word is non-zero, queu 268 /* If the first word is non-zero, queue is full. */ 269 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, % 269 ldxa [%g7 + %g2] ASI_PHYS_USE_EC, %g1 270 brnz,pn %g1, sun4v_nonres_mondo_queue_ 270 brnz,pn %g1, sun4v_nonres_mondo_queue_full 271 nop 271 nop 272 272 273 lduw [%g3 + TRAP_PER_CPU_NONRESUM_Q 273 lduw [%g3 + TRAP_PER_CPU_NONRESUM_QMASK], %g4 274 274 275 /* Remember this entry's offset in %g1 275 /* Remember this entry's offset in %g1. */ 276 mov %g2, %g1 276 mov %g2, %g1 277 277 278 /* Copy 64-byte queue entry into kerne 278 /* Copy 64-byte queue entry into kernel buffer. */ 279 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 279 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 280 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 280 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 281 add %g2, 0x08, %g2 281 add %g2, 0x08, %g2 282 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 282 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 283 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 283 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 284 add %g2, 0x08, %g2 284 add %g2, 0x08, %g2 285 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 285 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 286 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 286 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 287 add %g2, 0x08, %g2 287 add %g2, 0x08, %g2 288 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 288 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 289 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 289 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 290 add %g2, 0x08, %g2 290 add %g2, 0x08, %g2 291 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 291 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 292 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 292 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 293 add %g2, 0x08, %g2 293 add %g2, 0x08, %g2 294 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 294 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 295 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 295 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 296 add %g2, 0x08, %g2 296 add %g2, 0x08, %g2 297 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 297 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 298 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 298 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 299 add %g2, 0x08, %g2 299 add %g2, 0x08, %g2 300 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, % 300 ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 301 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_ 301 stxa %g3, [%g7 + %g2] ASI_PHYS_USE_EC 302 add %g2, 0x08, %g2 302 add %g2, 0x08, %g2 303 303 304 /* Update queue head pointer. */ 304 /* Update queue head pointer. */ 305 and %g2, %g4, %g2 305 and %g2, %g4, %g2 306 306 307 mov INTRQ_NONRESUM_MONDO_HEAD, %g4 307 mov INTRQ_NONRESUM_MONDO_HEAD, %g4 308 stxa %g2, [%g4] ASI_QUEUE 308 stxa %g2, [%g4] ASI_QUEUE 309 membar #Sync 309 membar #Sync 310 310 311 /* Disable interrupts and save registe 311 /* Disable interrupts and save register state so we can call 312 * C code. The etrap handling will le 312 * C code. The etrap handling will leave %g4 in %l4 for us 313 * when it's done. 313 * when it's done. 314 */ 314 */ 315 rdpr %pil, %g2 315 rdpr %pil, %g2 316 wrpr %g0, PIL_NORMAL_MAX, %pil 316 wrpr %g0, PIL_NORMAL_MAX, %pil 317 mov %g1, %g4 317 mov %g1, %g4 318 ba,pt %xcc, etrap_irq 318 ba,pt %xcc, etrap_irq 319 rd %pc, %g7 319 rd %pc, %g7 320 #ifdef CONFIG_TRACE_IRQFLAGS 320 #ifdef CONFIG_TRACE_IRQFLAGS 321 call trace_hardirqs_off 321 call trace_hardirqs_off 322 nop 322 nop 323 #endif 323 #endif 324 /* Log the event. */ 324 /* Log the event. */ 325 add %sp, PTREGS_OFF, %o0 325 add %sp, PTREGS_OFF, %o0 326 call sun4v_nonresum_error 326 call sun4v_nonresum_error 327 mov %l4, %o1 327 mov %l4, %o1 328 328 329 /* Return from trap. */ 329 /* Return from trap. */ 330 ba,pt %xcc, rtrap_irq 330 ba,pt %xcc, rtrap_irq 331 nop 331 nop 332 332 333 sun4v_nonres_mondo_queue_empty: 333 sun4v_nonres_mondo_queue_empty: 334 retry 334 retry 335 335 336 sun4v_nonres_mondo_queue_full: 336 sun4v_nonres_mondo_queue_full: 337 /* The queue is full, consolidate our 337 /* The queue is full, consolidate our damage by setting 338 * the head equal to the tail. We'll 338 * the head equal to the tail. We'll just trap again otherwise. 339 * Call C code to log the event. 339 * Call C code to log the event. 340 */ 340 */ 341 mov INTRQ_NONRESUM_MONDO_HEAD, %g2 341 mov INTRQ_NONRESUM_MONDO_HEAD, %g2 342 stxa %g4, [%g2] ASI_QUEUE 342 stxa %g4, [%g2] ASI_QUEUE 343 membar #Sync 343 membar #Sync 344 344 345 rdpr %pil, %g2 345 rdpr %pil, %g2 346 wrpr %g0, PIL_NORMAL_MAX, %pil 346 wrpr %g0, PIL_NORMAL_MAX, %pil 347 ba,pt %xcc, etrap_irq 347 ba,pt %xcc, etrap_irq 348 rd %pc, %g7 348 rd %pc, %g7 349 #ifdef CONFIG_TRACE_IRQFLAGS 349 #ifdef CONFIG_TRACE_IRQFLAGS 350 call trace_hardirqs_off 350 call trace_hardirqs_off 351 nop 351 nop 352 #endif 352 #endif 353 call sun4v_nonresum_overflow 353 call sun4v_nonresum_overflow 354 add %sp, PTREGS_OFF, %o0 354 add %sp, PTREGS_OFF, %o0 355 355 356 ba,pt %xcc, rtrap_irq 356 ba,pt %xcc, rtrap_irq 357 nop 357 nop
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.