6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #if defined(lint)
27 #include <sys/types.h>
28 #include <sys/thread.h>
29 #else /* lint */
30 #include "assym.h"
31 #endif /* lint */
32
33 #include <sys/asm_linkage.h>
34 #include <sys/machthread.h>
35 #include <sys/machcpuvar.h>
36 #include <sys/intreg.h>
37 #include <sys/cmn_err.h>
38 #include <sys/ftrace.h>
39 #include <sys/machasi.h>
40 #include <sys/scb.h>
41 #include <sys/error.h>
42 #include <sys/mmu.h>
43 #include <vm/hat_sfmmu.h>
44 #define INTR_REPORT_SIZE 64
45
46 #ifdef TRAPTRACE
47 #include <sys/traptrace.h>
48 #endif /* TRAPTRACE */
49
50 #if defined(lint)
51
52 void
53 cpu_mondo(void)
54 {}
55
56 #else /* lint */
57
58
59 /*
60 * (TT 0x7c, TL>0) CPU Mondo Queue Handler
61 * Globals are the Interrupt Globals.
62 */
63 ENTRY_NP(cpu_mondo)
64 !
65 ! Register Usage:-
66 ! %g5 PC for fasttrap TL>0 handler
67 ! %g1 arg 1
68 ! %g2 arg 2
69 ! %g3 queue base VA
70 ! %g4 queue size mask
71 ! %g6 head ptr
72 ! %g7 tail ptr
73 mov CPU_MONDO_Q_HD, %g3
74 ldxa [%g3]ASI_QUEUE, %g6 ! %g6 = head ptr
75 mov CPU_MONDO_Q_TL, %g4
76 ldxa [%g4]ASI_QUEUE, %g7 ! %g7 = tail ptr
77 cmp %g6, %g7
78 be,pn %xcc, 3f ! head == tail
178 ta FAST_TRAP ! set TSB info for user process
179 brnz,a,pn %o0, ptl1_panic
180 mov PTL1_BAD_HCALL, %g1
181 mov %g3, %o0 ! restore output regs
182 mov %g4, %o1
183 mov %g6, %o5
184 1:
185 jmp %g5 ! jump to traphandler
186 nop
187 2:
188 ! invalid trap handler, discard it for now
189 set cpu_mondo_inval, %g4
190 ldx [%g4], %g5
191 inc %g5
192 stx %g5, [%g4]
193 3:
194 retry
195 /* Never Reached */
196 SET_SIZE(cpu_mondo)
197
198 #endif /* lint */
199
200 #if defined(lint)
201
202 void
203 dev_mondo(void)
204 {}
205
206 #else /* lint */
207
208
209 /*
210 * (TT 0x7d, TL>0) Dev Mondo Queue Handler
211 * Globals are the Interrupt Globals.
212 * We only process one interrupt at a time causing us to keep
213 * taking this trap till the queue is empty.
214 * We really should drain the whole queue for better performance
215 * but this will do for now.
216 */
217 ENTRY_NP(dev_mondo)
218 !
219 ! Register Usage:-
220 ! %g5 PC for fasttrap TL>0 handler
221 ! %g1 arg 1
222 ! %g2 arg 2
223 ! %g3 queue base PA
224 ! %g4 queue size mask
225 ! %g6 head ptr
226 ! %g7 tail ptr
227 mov DEV_MONDO_Q_HD, %g3
228 ldxa [%g3]ASI_QUEUE, %g6 ! %g6 = head ptr
327 mov DEV_MONDO_Q_HD, %g6
328 ldxa [%g6]ASI_QUEUE, %g6 ! New head offset
329 stna %g6, [%g4 + TRAP_ENT_F1]%asi
330 ldx [%g2 + MCPU_DEV_Q_SIZE], %g6
331 stna %g6, [%g4 + TRAP_ENT_F2]%asi ! Q Size
332 stna %g7, [%g4 + TRAP_ENT_F3]%asi ! tail offset
333 stna %g0, [%g4 + TRAP_ENT_F4]%asi
334 TRACE_NEXT(%g4, %g6, %g3)
335 #endif /* TRAPTRACE */
336
337 !
338 ! setvecint_tl1 will do all the work, and finish with a retry
339 !
340 ba,pt %xcc, setvecint_tl1
341 mov %g5, %g1 ! setvecint_tl1 expects inum in %g1
342
343 0: retry
344
345 /* Never Reached */
346 SET_SIZE(dev_mondo)
347 #endif /* lint */
348
349 #if defined(lint)
350 uint64_t cpu_mondo_inval;
351 #else /* lint */
352 .seg ".data"
353 .global cpu_mondo_inval
354 .align 8
355 cpu_mondo_inval:
356 .skip 8
357
358 .seg ".text"
359 #endif /* lint */
360
361
362 #if defined(lint)
363
364 void
365 resumable_error(void)
366 {}
367
368 #else /* lint */
369
370 /*
371 * (TT 0x7e, TL>0) Resumeable Error Queue Handler
372 * We keep a shadow copy of the queue in kernel buf.
373 * Read the resumable queue head and tail offset
374 * If there are entries on the queue, move them to
375 * the kernel buf, which is next to the resumable
376 * queue in the memory. Call C routine to process.
377 */
378 ENTRY_NP(resumable_error)
379 mov CPU_RQ_HD, %g4
380 ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset
381 mov CPU_RQ_TL, %g4
382 ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset
383 mov %g2, %g6 ! save head in %g2
384
385 cmp %g6, %g3
386 be,pn %xcc, 0f ! head == tail
387 nop
388
389 CPU_ADDR(%g1, %g4) ! %g1 = cpu struct addr
465 stxa %g3, [%g4]ASI_QUEUE ! set head equal to tail
466 membar #Sync
467
468 /*
469 * Set %g2 to %g6, which is current head offset. %g2
470 * is arg2 of the C routine. %g3 is the tail offset,
471 * which is arg3 of the C routine.
472 * Call rq_overflow at PIL 14 unless we're already at PIL 15.
473 */
474 mov %g6, %g2
475 set rq_overflow, %g1
476 rdpr %pil, %g4
477 cmp %g4, PIL_14
478 ba sys_trap
479 movl %icc, PIL_14, %g4
480
481 0: retry
482
483 /*NOTREACHED*/
484 SET_SIZE(resumable_error)
485 #endif /* lint */
486
487 #if defined(lint)
488
489 void
490 nonresumable_error(void)
491 {}
492
493 #else /* lint */
494
495 /*
496 * (TT 0x7f, TL>0) Non-resumeable Error Queue Handler
497 * We keep a shadow copy of the queue in kernel buf.
498 * Read non-resumable queue head and tail offset
499 * If there are entries on the queue, move them to
500 * the kernel buf, which is next to the non-resumable
501 * queue in the memory. Call C routine to process.
502 */
503 ENTRY_NP(nonresumable_error)
504 mov CPU_NRQ_HD, %g4
505 ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset
506 mov CPU_NRQ_TL, %g4
507 ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset
508
509 cmp %g2, %g3
510 be,pn %xcc, 0f ! head == tail
511 nop
512
513 /* force %gl to 1 as sys_trap requires */
514 wrpr %g0, 1, %gl
646 cmp %g4, PIL_14
647 ba sys_trap
648 movl %icc, PIL_14, %g4
649
650 /*
651 * We are here because the C routine is not able to process
652 * errors in time. So the first 8 bytes of ER in buf has not
653 * been cleared. We call sys_trap to panic.
654 * Run at PIL 14 unless we're already at PIL 15.
655 */
656 1: set nrq_overflow, %g1
657 rdpr %pil, %g4
658 cmp %g4, PIL_14
659 ba sys_trap
660 movl %icc, PIL_14, %g4
661
662 0: retry
663
664 /*NOTREACHED*/
665 SET_SIZE(nonresumable_error)
666 #endif /* lint */
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include "assym.h"
27
28 #include <sys/asm_linkage.h>
29 #include <sys/machthread.h>
30 #include <sys/machcpuvar.h>
31 #include <sys/intreg.h>
32 #include <sys/cmn_err.h>
33 #include <sys/ftrace.h>
34 #include <sys/machasi.h>
35 #include <sys/scb.h>
36 #include <sys/error.h>
37 #include <sys/mmu.h>
38 #include <vm/hat_sfmmu.h>
39 #define INTR_REPORT_SIZE 64
40
41 #ifdef TRAPTRACE
42 #include <sys/traptrace.h>
43 #endif /* TRAPTRACE */
44
45
46 /*
47 * (TT 0x7c, TL>0) CPU Mondo Queue Handler
48 * Globals are the Interrupt Globals.
49 */
50 ENTRY_NP(cpu_mondo)
51 !
52 ! Register Usage:-
53 ! %g5 PC for fasttrap TL>0 handler
54 ! %g1 arg 1
55 ! %g2 arg 2
56 ! %g3 queue base VA
57 ! %g4 queue size mask
58 ! %g6 head ptr
59 ! %g7 tail ptr
60 mov CPU_MONDO_Q_HD, %g3
61 ldxa [%g3]ASI_QUEUE, %g6 ! %g6 = head ptr
62 mov CPU_MONDO_Q_TL, %g4
63 ldxa [%g4]ASI_QUEUE, %g7 ! %g7 = tail ptr
64 cmp %g6, %g7
65 be,pn %xcc, 3f ! head == tail
165 ta FAST_TRAP ! set TSB info for user process
166 brnz,a,pn %o0, ptl1_panic
167 mov PTL1_BAD_HCALL, %g1
168 mov %g3, %o0 ! restore output regs
169 mov %g4, %o1
170 mov %g6, %o5
171 1:
172 jmp %g5 ! jump to traphandler
173 nop
174 2:
175 ! invalid trap handler, discard it for now
176 set cpu_mondo_inval, %g4
177 ldx [%g4], %g5
178 inc %g5
179 stx %g5, [%g4]
180 3:
181 retry
182 /* Never Reached */
183 SET_SIZE(cpu_mondo)
184
185
186 /*
187 * (TT 0x7d, TL>0) Dev Mondo Queue Handler
188 * Globals are the Interrupt Globals.
189 * We only process one interrupt at a time causing us to keep
190 * taking this trap till the queue is empty.
191 * We really should drain the whole queue for better performance
192 * but this will do for now.
193 */
194 ENTRY_NP(dev_mondo)
195 !
196 ! Register Usage:-
197 ! %g5 PC for fasttrap TL>0 handler
198 ! %g1 arg 1
199 ! %g2 arg 2
200 ! %g3 queue base PA
201 ! %g4 queue size mask
202 ! %g6 head ptr
203 ! %g7 tail ptr
204 mov DEV_MONDO_Q_HD, %g3
205 ldxa [%g3]ASI_QUEUE, %g6 ! %g6 = head ptr
304 mov DEV_MONDO_Q_HD, %g6
305 ldxa [%g6]ASI_QUEUE, %g6 ! New head offset
306 stna %g6, [%g4 + TRAP_ENT_F1]%asi
307 ldx [%g2 + MCPU_DEV_Q_SIZE], %g6
308 stna %g6, [%g4 + TRAP_ENT_F2]%asi ! Q Size
309 stna %g7, [%g4 + TRAP_ENT_F3]%asi ! tail offset
310 stna %g0, [%g4 + TRAP_ENT_F4]%asi
311 TRACE_NEXT(%g4, %g6, %g3)
312 #endif /* TRAPTRACE */
313
314 !
315 ! setvecint_tl1 will do all the work, and finish with a retry
316 !
317 ba,pt %xcc, setvecint_tl1
318 mov %g5, %g1 ! setvecint_tl1 expects inum in %g1
319
320 0: retry
321
322 /* Never Reached */
323 SET_SIZE(dev_mondo)
324
325 .seg ".data"
326 .global cpu_mondo_inval
327 .align 8
328 cpu_mondo_inval:
329 .skip 8
330
331 .seg ".text"
332
333
334 /*
335 * (TT 0x7e, TL>0) Resumeable Error Queue Handler
336 * We keep a shadow copy of the queue in kernel buf.
337 * Read the resumable queue head and tail offset
338 * If there are entries on the queue, move them to
339 * the kernel buf, which is next to the resumable
340 * queue in the memory. Call C routine to process.
341 */
342 ENTRY_NP(resumable_error)
343 mov CPU_RQ_HD, %g4
344 ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset
345 mov CPU_RQ_TL, %g4
346 ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset
347 mov %g2, %g6 ! save head in %g2
348
349 cmp %g6, %g3
350 be,pn %xcc, 0f ! head == tail
351 nop
352
353 CPU_ADDR(%g1, %g4) ! %g1 = cpu struct addr
429 stxa %g3, [%g4]ASI_QUEUE ! set head equal to tail
430 membar #Sync
431
432 /*
433 * Set %g2 to %g6, which is current head offset. %g2
434 * is arg2 of the C routine. %g3 is the tail offset,
435 * which is arg3 of the C routine.
436 * Call rq_overflow at PIL 14 unless we're already at PIL 15.
437 */
438 mov %g6, %g2
439 set rq_overflow, %g1
440 rdpr %pil, %g4
441 cmp %g4, PIL_14
442 ba sys_trap
443 movl %icc, PIL_14, %g4
444
445 0: retry
446
447 /*NOTREACHED*/
448 SET_SIZE(resumable_error)
449
450 /*
451 * (TT 0x7f, TL>0) Non-resumeable Error Queue Handler
452 * We keep a shadow copy of the queue in kernel buf.
453 * Read non-resumable queue head and tail offset
454 * If there are entries on the queue, move them to
455 * the kernel buf, which is next to the non-resumable
456 * queue in the memory. Call C routine to process.
457 */
458 ENTRY_NP(nonresumable_error)
459 mov CPU_NRQ_HD, %g4
460 ldxa [%g4]ASI_QUEUE, %g2 ! %g2 = Q head offset
461 mov CPU_NRQ_TL, %g4
462 ldxa [%g4]ASI_QUEUE, %g3 ! %g3 = Q tail offset
463
464 cmp %g2, %g3
465 be,pn %xcc, 0f ! head == tail
466 nop
467
468 /* force %gl to 1 as sys_trap requires */
469 wrpr %g0, 1, %gl
601 cmp %g4, PIL_14
602 ba sys_trap
603 movl %icc, PIL_14, %g4
604
605 /*
606 * We are here because the C routine is not able to process
607 * errors in time. So the first 8 bytes of ER in buf has not
608 * been cleared. We call sys_trap to panic.
609 * Run at PIL 14 unless we're already at PIL 15.
610 */
611 1: set nrq_overflow, %g1
612 rdpr %pil, %g4
613 cmp %g4, PIL_14
614 ba sys_trap
615 movl %icc, PIL_14, %g4
616
617 0: retry
618
619 /*NOTREACHED*/
620 SET_SIZE(nonresumable_error)
|