source: mainline/kernel/arch/sparc32/src/trap_table.S@ df7f5cea

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since df7f5cea was 208b5f5, checked in by Martin Decky <martin@…>, 12 years ago

cherrypick important fixes and updates from lp:~jceel/helenos/leon3

  • Property mode set to 100644
File size: 21.5 KB
Line 
1#
2# Copyright (c) 2013 Jakub Klama
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#
9# - Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# - Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14# - The name of the author may not be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28
29#include <arch/trap.h>
30#include <arch/regwin.h>
31
32.text
33
34.global trap_table
35.global reset_trap
36.global preemptible_trap
37.global interrupt_trap
38.global syscall_trap
39.global window_overflow_trap
40.global window_underflow_trap
41.global write_to_invalid
42.global read_from_invalid
43.global flush_windows
44
45.macro get_wim_number reg
46 clr \reg
47 mov %wim, %g5
48
49 1:
50 andcc %g5, 1, %g0
51 bne 2f
52 nop
53 srl %g5, 1, %g5
54 inc \reg
55 b 1b
56
57 2:
58 nop
59.endm
60
61.macro get_cwp reg
62 mov %psr, \reg
63 and \reg, 0x7, \reg
64.endm
65
66.macro switch_to_invalid saved_wim, saved_psr
67 get_wim_number %l3
68 mov %wim, \saved_wim ! save WIM
69 mov %g0, %wim ! clear WIM
70 mov %psr, \saved_psr ! read PSR
71 and \saved_psr, 0xfffffff0, %l4
72 or %l4, %l3, %l3 ! set CWP
73 mov %l3, %psr ! write PSR
74 nop
75 nop
76 nop
77 nop ! wait for PSR to be effective
78.endm
79
80.macro switch_back wim, psr
81 mov \wim, %wim ! saved WIM
82 mov \psr, %psr ! saved PSR
83 nop
84 nop
85 nop
86 nop
87.endm
88
89/* Save next window to kernel stack or UWB */
90.macro inline_save_kernel
91 mov %wim, %l3
92 sll %l3, 7, %l4
93 srl %l3, 1, %l3
94 or %l3, %l4, %l3
95 and %l3, 0xff, %l3
96 mov %g0, %wim
97
98 mov %l5, %g5
99 mov %l6, %g6
100 mov %l7, %g7
101
102 save
103 std %l0, [%sp + 0]
104 std %l2, [%sp + 8]
105 std %l4, [%sp + 16]
106 std %l6, [%sp + 24]
107 std %i0, [%sp + 32]
108 std %i2, [%sp + 40]
109 std %i4, [%sp + 48]
110 std %i6, [%sp + 56]
111 mov %g5, %l5
112 mov %g6, %l6
113 mov %g7, %l7
114 restore
115 mov %l3, %wim
116.endm
117
118.macro inline_save_uspace uwb
119 mov %wim, %l3
120 sll %l3, 7, %l4
121 srl %l3, 1, %l3
122 or %l3, %l4, %l3
123 and %l3, 0xff, %l3
124 mov %g0, %wim
125 mov \uwb, %g3
126
127 mov %l5, %g5
128 mov %l6, %g6
129 mov %l7, %g7
130
131 save
132 std %l0, [%g3 + 0]
133 std %l2, [%g3 + 8]
134 std %l4, [%g3 + 16]
135 std %l6, [%g3 + 24]
136 std %i0, [%g3 + 32]
137 std %i2, [%g3 + 40]
138 std %i4, [%g3 + 48]
139 std %i6, [%g3 + 56]
140 mov %g5, %l5
141 mov %g6, %l6
142 mov %g7, %l7
143 add \uwb, 64, \uwb
144 restore
145 mov %l3, %wim
146.endm
147
148/* Restore window from kernel stack or UWB */
149.macro inline_restore_kernel
150 mov %wim, %l3
151 srl %l3, 7, %l4
152 sll %l3, 1, %l3
153 or %l3, %l4, %l3
154 and %l3, 0xff, %l3
155
156 mov %g0, %wim
157 restore
158 mov %l5, %g5
159 mov %l6, %g6
160 mov %l7, %g7
161 restore
162 mov %g5, %l5
163 mov %g6, %l6
164 mov %g7, %l7
165 save
166
167 ldd [%sp + 0], %l0
168 ldd [%sp + 8], %l2
169 ldd [%sp + 16], %l4
170 ldd [%sp + 24], %l6
171 ldd [%sp + 32], %i0
172 ldd [%sp + 40], %i2
173 ldd [%sp + 48], %i4
174 ldd [%sp + 56], %i6
175 save
176
177 mov %l3, %wim
178.endm
179
180.macro inline_restore_uspace uwb
181 mov %wim, %l3
182 srl %l3, 7, %l4
183 sll %l3, 1, %l3
184 or %l3, %l4, %l3
185 and %l3, 0xff, %l3
186
187 mov %g0, %wim
188 restore
189 mov %l5, %g5
190 mov %l6, %g6
191 mov %l7, %g7
192 restore
193 mov %g5, %l5
194 mov %g6, %l6
195 mov %g7, %l7
196 save
197
198 sub \uwb, 64, \uwb
199 ldd [\uwb + 0], %l0
200 ldd [\uwb + 8], %l2
201 ldd [\uwb + 16], %l4
202 ldd [\uwb + 24], %l6
203 ldd [\uwb + 32], %i0
204 ldd [\uwb + 40], %i2
205 ldd [\uwb + 48], %i4
206 ldd [\uwb + 56], %i6
207 save
208
209 mov %l3, %wim
210.endm
211
212.macro if_from_kernel label
213 mov %psr, %l3
214 and %l3, (1 << 6), %l3
215 cmp %l3, 0
216 bne \label
217 nop
218.endm
219
220write_to_invalid:
221 ! Write value 1
222 mov %o0, %g7
223 switch_to_invalid %g3, %g4
224 mov %g7, %l5
225 switch_back %g3, %g4
226 ! Write value 2
227 mov %o1, %g7
228 switch_to_invalid %g3, %g4
229 mov %g7, %l6
230 switch_back %g3, %g4
231 ! Write value 3
232 mov %o2, %g7
233 switch_to_invalid %g3, %g4
234 mov %g7, %l7
235 switch_back %g3, %g4
236 retl
237 nop
238
239read_from_invalid:
240 ! Read value 1
241 mov %o0, %g7
242 switch_to_invalid %g3, %g4
243 st %l5, [%g7]
244 switch_back %g3, %g4
245 ! Write value 2
246 mov %o1, %g7
247 switch_to_invalid %g3, %g4
248 st %l6, [%g7]
249 switch_back %g3, %g4
250 ! Write value 3
251 mov %o2, %g7
252 switch_to_invalid %g3, %g4
253 st %l7, [%g7]
254 switch_back %g3, %g4
255 retl
256 nop
257
258reset_trap:
259 set 0x80000100, %l0
260 set 'r', %l1
261 sta %l1, [%l0] 0x1c
262 rett
263
264window_overflow_trap:
265 mov %g7, %l0
266
267 /* Check whether previous mode was usermode */
268 mov %psr, %l4
269 and %l4, (1 << 6), %l4
270 cmp %l4, 0
271 bne 1f
272 nop
273
274 /* User space: */
275
276 /*
277 * Time to check whether desired stack page is mapped
278 * on the MMU. If so, process with saving window directly.
279 * If not, go to preemptible trap handler.
280 */
281 mov %wim, %g5
282 mov %g0, %wim
283 save
284 mov %sp, %g4
285 restore
286 mov %g5, %wim
287
288 /* Check beginning of %sp */
289 and %g4, 0xfffff000, %l4
290 lda [%l4] 0x18, %l4
291 cmp %l4, 0
292 bne 1f
293 nop
294
295 /* Prepare args for preemptible handler */
296 mov %g4, %o0
297 set preemptible_save_uspace, %o2
298 b preemptible_trap
299 nop
300
301 /* Check end of %sp */
302 add %g4, 56, %g4
303 and %l4, 0xfffff000, %l4
304 lda [%l4] 0x18, %l4
305 cmp %l4, 0
306 bne 1f
307 nop
308
309 /* Prepare args for preemptible handler */
310 mov %g4, %o0
311 set preemptible_save_uspace, %o2
312 b preemptible_trap
313 nop
314
315 /* Kernel: */
316
317 1:
318 /* Rotate WIM on bit right, we have 8 windows */
319 mov %wim, %l3
320 sll %l3, 7, %l4
321 srl %l3, 1, %l3
322 or %l3, %l4, %l3
323 and %l3, 0xff, %l3
324
325 /* Disable WIM traps */
326 mov %g0,%wim
327 nop; nop; nop
328
329 /* Save invalid window data */
330 mov %l5, %g5 ! kernel stack pointer
331 mov %l6, %g6 ! kernel wbuf
332 mov %l7, %g7
333
334 /*
335 * We should check whether window needs to be saved
336 * to kernel stack or uwb.
337 */
338 cmp %g7, 0
339 bne 2f
340 nop
341
342 /* Dump registers to stack */
343 save
344 std %l0, [%sp + 0]
345 std %l2, [%sp + 8]
346 std %l4, [%sp + 16]
347 std %l6, [%sp + 24]
348 std %i0, [%sp + 32]
349 std %i2, [%sp + 40]
350 std %i4, [%sp + 48]
351 std %i6, [%sp + 56]
352 b 3f
353 nop
354
355 /* Dump registers to uwb */
356 2:
357 save
358 std %l0, [%g6 + 0]
359 std %l2, [%g6 + 8]
360 std %l4, [%g6 + 16]
361 std %l6, [%g6 + 24]
362 std %i0, [%g6 + 32]
363 std %i2, [%g6 + 40]
364 std %i4, [%g6 + 48]
365 std %i6, [%g6 + 56]
366 add %g6, 64, %g6
367
368 /* Check whether it's the last user window to be saved */
369 and %g7, 0x7, %l5
370 mov %psr, %l4
371 and %l4, 0x7, %l4
372 cmp %l5, %l4
373 bne 3f
374 nop
375
376 /* Clear uspace window mark */
377 clr %g7
378
379 3:
380 /* Back to where we should be */
381 mov %g5, %l5
382 mov %g6, %l6
383 mov %g7, %l7
384 restore
385
386 /* Set new value of window */
387 mov %l3,%wim
388 nop; nop; nop
389
390 /* Go home */
391 mov %l0, %g7
392 jmp %l1
393 rett %l2
394
395window_underflow_trap:
396 mov %g7, %l0
397
398 /* Check whether previous mode was usermode */
399 mov %psr, %l4
400 and %l4, (1 << 6), %l4
401 cmp %l4, 0
402 bne 1f
403 nop
404
405 /* User space: */
406
407 /*
408 * Time to check whether desired stack page is mapped
409 * on the MMU. If so, process with saving window directly.
410 * If not, go to preemptible trap handler.
411 */
412 mov %wim, %g5
413 mov %g0, %wim
414 restore
415 restore
416 mov %sp, %g4
417 save
418 save
419 mov %g5, %wim
420 and %sp, 0xfffff000, %l4
421 lda [%l4] 0x18, %l4
422 cmp %l4, 0
423 bne 1f
424 nop
425
426 /* Prepare args for preemptible handler */
427 mov %g4, %o0
428 set preemptible_restore_uspace, %o2
429 b preemptible_trap
430 nop
431
432 1:
433 /* Rotate WIM on bit LEFT, we have 8 windows */
434 mov %wim, %l3
435 srl %l3, 7, %l4
436 sll %l3, 1, %l3
437 or %l3, %l4, %l3
438 and %l3, 0xff, %l3
439
440 /* Disable WIM traps */
441 mov %g0, %wim
442 nop; nop; nop
443
444 /* Kernel: */
445 restore
446 restore
447 mov %l5, %g5 ! kernel stack pointer
448 mov %l6, %g6 ! kernel wbuf
449 mov %l7, %g7
450
451 ldd [%sp + 0], %l0
452 ldd [%sp + 8], %l2
453 ldd [%sp + 16], %l4
454 ldd [%sp + 24], %l6
455 ldd [%sp + 32], %i0
456 ldd [%sp + 40], %i2
457 ldd [%sp + 48], %i4
458 ldd [%sp + 56], %i6
459 b 2f
460 nop
461
462 2:
463 /* Restore invalid window data */
464 restore
465 mov %g5, %l5
466 mov %g6, %l6
467 mov %g7, %l7
468 save
469 save
470 save
471
472 /* Set new value of window */
473 mov %l3, %wim
474 nop; nop; nop
475
476 /* Go home */
477 mov %l0, %g7
478 jmp %l1
479 rett %l2
480
481flush_windows:
482 mov 7, %g1
483 1:
484 subcc %g1, 1, %g1
485 bg 1b
486 save %sp, -64, %sp
487
488 mov 7, %g1
489 1:
490 subcc %g1, 1, %g1
491 bg 1b
492 restore
493
494 retl
495 nop
496
497preemptible_trap:
498 /* Save %g7 */
499 mov %g7, %l0
500
501 /* Check whether we landed in invalid window */
502 get_wim_number %g6
503 get_cwp %g7
504 cmp %g6, %g7
505 bne 4f
506 nop
507
508 /* We are in invalid window. Check whether previous mode was usermode. */
509 if_from_kernel 3f
510
511 /* Trap originated from user space */
512 /* Kernel stack pointer is at %l5, uwb is at %l6 */
513 inline_save_uspace %l6
514
515 /* Set uspace window mark */
516 mov %psr, %l7
517 inc %l7
518 and %l7, 0x7, %l7
519 or %l7, 0x10, %l7
520 b 4f
521 nop
522
523 3:
524 /* Trap originated from kernel */
525 inline_save_kernel
526
527 4:
528 /* Check whether previous mode was user mode */
529 if_from_kernel 5f
530
531 /* Load kernel stack pointer from invalid window */
532 switch_to_invalid %g5, %g6
533
534 /* set uspace window mark */
535 mov %g6, %l7
536 inc %l7
537 and %l7, 0x7, %l7
538 or %l7, 0x10, %l7
539
540 /* Save stack pointer */
541 mov %l5, %g7
542 switch_back %g5, %g6
543 mov %g7, %sp
544 ## mov %sp, %fp
545
546 5:
547 /* Set up stack frame */
548 sub %sp, 128, %sp
549
550 /* Save trap data on stack */
551 mov %psr, %l5
552 st %l1, [%sp + 92]
553 st %l2, [%sp + 96]
554 st %l5, [%sp + 100]
555 st %g1, [%sp + 104]
556 st %g2, [%sp + 108]
557 st %g3, [%sp + 112]
558 st %g4, [%sp + 116]
559 st %l0, [%sp + 120]
560
561 /* Enable traps */
562 mov %psr, %l0
563 or %l0, (1 << 5), %l0
564 or %l0, 0xf00, %l0
565 mov %l0, %psr
566 nop
567 nop
568 nop
569 nop
570
571 /* Flush windows to stack */
572 call flush_windows
573 nop
574
575 /* Jump to actual subroutine */
576 call %o2
577 add %sp, 128, %o1
578
579 /* Return from handler (leave PIL disabled) */
580 ld [%sp + 92], %l1
581 ld [%sp + 96], %l2
582 ld [%sp + 100], %l0
583 or %l0, 0xf00, %l0
584 mov %l0, %psr
585 nop
586 nop
587 nop
588 nop
589 nop
590
591 /*
592 * If trap originated from user space, clear user space window mark
593 * and save uwb address for future use.
594 */
595 if_from_kernel 9f
596 switch_to_invalid %g5, %g6
597 clr %l7
598 mov %l5, %g2
599 mov %l6, %g7
600 switch_back %g5, %g6
601 mov %g7, %g1
602
603 /* If trap originated from user space, restore all windows from UWB */
604 /* UWB pointer is at %g1 */
605 0:
606 mov %g0, %wim
607 clr %g5
608 andcc %g1, UWB_ALIGNMENT - 1, %g0
609 bz 0f
610 nop
611
612 restore
613 sub %g1, 64, %g1
614 ldd [%g1 + 0], %l0
615 ldd [%g1 + 8], %l2
616 ldd [%g1 + 16], %l4
617 ldd [%g1 + 24], %l6
618 ldd [%g1 + 32], %i0
619 ldd [%g1 + 40], %i2
620 ldd [%g1 + 48], %i4
621 ldd [%g1 + 56], %i6
622 inc %g5
623 and %g5, 0x7, %g5
624 ba 0b
625 nop
626
627 /*
628 * We've restored all uspace windows. Now time to
629 * fix CWP and WIM.
630 */
631 0:
632 restore
633 get_cwp %g7
634 clr %g5
635 inc %g5
636 sll %g5, %g7, %g5
637
638 /* Write values to invalid window and switch back */
639 mov %g2, %l5
640 mov %g1, %l6
641 clr %l7
642 switch_back %g5, %g6
643
644 mov %sp, %l3
645 sub %g2, 128, %sp
646 ld [%sp + 104], %g1
647 ld [%sp + 108], %g2
648 ld [%sp + 112], %g3
649 ld [%sp + 116], %g4
650 ld [%sp + 120], %g7
651
652 mov %l3, %sp
653 b 10f
654 nop
655
656 9:
657 inline_restore_kernel
658
659 ld [%sp + 104], %g1
660 ld [%sp + 108], %g2
661 ld [%sp + 112], %g3
662 ld [%sp + 116], %g4
663 ld [%sp + 120], %g7
664
665 /* Restore old sp */
666 add %sp, 128, %sp
667
668 10:
669 jmp %l1
670 rett %l2
671
672interrupt_trap:
673 /* Save %g7 */
674 mov %g7, %l0
675
676 /* Check whether we landed in invalid window */
677 get_wim_number %g6
678 get_cwp %g7
679 cmp %g6, %g7
680 bne 4f
681 nop
682
683 /* We are in invalid window. Check whether previous mode was user mode */
684 if_from_kernel 3f
685
686 /* Trap originated from user space */
687 /* Kernel stack pointer is at %l5, uwb is at %l6 */
688 inline_save_uspace %l6
689
690 /* Set uspace window mark */
691 mov %psr, %l7
692 inc %l7
693 and %l7, 0x7, %l7
694 or %l7, 0x10, %l7
695 b 4f
696 nop
697
698 3:
699 /* Trap originated from kernel */
700 inline_save_kernel
701
702 4:
703 /* Check whether previous mode was user mode */
704 if_from_kernel 5f
705
706 /* Load kernel stack pointer from invalid window */
707 switch_to_invalid %g5, %g6
708
709 /* Set user space window mark */
710 mov %g6, %l7
711 inc %l7
712 and %l7, 0x7, %l7
713 or %l7, 0x10, %l7
714
715 /* Save stack pointer */
716 mov %l5, %g7
717 switch_back %g5, %g6
718 mov %g7, %sp
719
720 5:
721 /* Set up stack frame */
722 sub %sp, 128, %sp
723
724 /* Save trap data on stack */
725 mov %psr, %l5
726 st %l1, [%sp + 92]
727 st %l2, [%sp + 96]
728 st %l5, [%sp + 100]
729 st %g1, [%sp + 104]
730 st %g2, [%sp + 108]
731 st %g3, [%sp + 112]
732 st %g4, [%sp + 116]
733 st %l0, [%sp + 120]
734
735 /* Enable traps (without PIL) */
736 mov %psr, %l0
737 or %l0, (1 << 5), %l0
738 or %l0, 0xf00, %l0
739 mov %l0, %psr
740 nop
741 nop
742 nop
743 nop
744
745 /* Flush windows to stack */
746 call flush_windows
747 nop
748
749 /* Jump to actual subroutine */
750 call irq_exception
751 add %sp, 128, %o1
752
753 /* Return from handler (leave PIL disabled) */
754 ld [%sp + 92], %l1
755 ld [%sp + 96], %l2
756 ld [%sp + 100], %l0
757 or %l0, 0xf00, %l0
758 mov %l0, %psr
759 nop
760 nop
761 nop
762 nop
763 nop
764
765 /*
766 * If trap originated from user space, clear user space window mark
767 * and save uwb address for future use.
768 */
769 if_from_kernel 9f
770 switch_to_invalid %g5, %g6
771 clr %l7
772 mov %l5, %g2
773 mov %l6, %g7
774 switch_back %g5, %g6
775 mov %g7, %g1
776
777 /* If trap originated from user space, restore all windows from UWB */
778 /* UWB pointer is at %g1 */
779 0:
780 mov %g0, %wim
781 clr %g5
782 andcc %g1, UWB_ALIGNMENT - 1, %g0
783 bz 0f
784 nop
785
786 restore
787 sub %g1, 64, %g1
788 ldd [%g1 + 0], %l0
789 ldd [%g1 + 8], %l2
790 ldd [%g1 + 16], %l4
791 ldd [%g1 + 24], %l6
792 ldd [%g1 + 32], %i0
793 ldd [%g1 + 40], %i2
794 ldd [%g1 + 48], %i4
795 ldd [%g1 + 56], %i6
796 inc %g5
797 and %g5, 0x7, %g5
798 ba 0b
799 nop
800
801 /*
802 * We've restored all user space windows. Now time to
803 * fix CWP and WIM.
804 */
805 0:
806 restore
807 get_cwp %g7
808 clr %g5
809 inc %g5
810 sll %g5, %g7, %g5
811
812 /* Write values to invalid window and switch back */
813 mov %g2, %l5
814 mov %g1, %l6
815 clr %l7
816 switch_back %g5, %g6
817
818 mov %sp, %l3
819 sub %g2, 128, %sp
820 ld [%sp + 104], %g1
821 ld [%sp + 108], %g2
822 ld [%sp + 112], %g3
823 ld [%sp + 116], %g4
824 ld [%sp + 120], %g7
825
826 mov %l3, %sp
827 b 10f
828 nop
829
830 9:
831 inline_restore_kernel
832
833 ld [%sp + 104], %g1
834 ld [%sp + 108], %g2
835 ld [%sp + 112], %g3
836 ld [%sp + 116], %g4
837 ld [%sp + 120], %g7
838
839 /* Restore old sp */
840 add %sp, 128, %sp
841
842 10:
843 jmp %l1
844 rett %l2
845
846syscall_trap:
847 /* Save %g7 */
848 mov %g7, %l0
849
850 /* Check whether we landed in invalid window */
851 get_wim_number %g6
852 get_cwp %g7
853 cmp %g6, %g7
854 bne 4f
855 nop
856
857 /* We are in invalid window. Check whether previous mode was user mode */
858 if_from_kernel 3f
859
860 /* Trap originated from user space */
861 /* Kernel stack pointer is at %l5, uwb is at %l6 */
862 inline_save_uspace %l6
863
864 /* Set user space window mark */
865 mov %psr, %l7
866 inc %l7
867 and %l7, 0x7, %l7
868 or %l7, 0x10, %l7
869 b 4f
870 nop
871
872 3:
873 /* Trap originated from kernel */
874 inline_save_kernel
875
876 4:
877 /* Check whether previous mode was user mode */
878 if_from_kernel 5f
879
880 /* Load kernel stack pointer from invalid window */
881 switch_to_invalid %g5, %g6
882
883 /* Set user space window mark */
884 mov %g6, %l7
885 inc %l7
886 and %l7, 0x7, %l7
887 or %l7, 0x10, %l7
888
889 /* Save stack pointer */
890 mov %l5, %g7
891 switch_back %g5, %g6
892 mov %g7, %sp
893 ## mov %sp, %fp
894
895 5:
896 /* Set up stack frame */
897 sub %sp, 128, %sp
898
899 /* Save trap data on stack */
900 mov %psr, %l5
901 st %l1, [%sp + 92]
902 st %l2, [%sp + 96]
903 st %l5, [%sp + 100]
904 st %g1, [%sp + 104]
905 st %g2, [%sp + 108]
906 st %g3, [%sp + 112]
907 st %g4, [%sp + 116]
908 st %l0, [%sp + 120]
909
910 /* Enable traps (without PIL) */
911 mov %psr, %l0
912 or %l0, (1 << 5), %l0
913 or %l0, 0xf00, %l0
914 mov %l0, %psr
915 nop
916 nop
917 nop
918 nop
919
920 /* Flush windows */
921 call flush_windows
922 nop
923
924 /* Jump to actual subroutine */
925 sub %o0, 0x80, %o0
926 st %o0, [%sp + 92]
927 mov %i0, %o0
928 mov %i1, %o1
929 mov %i2, %o2
930 mov %i3, %o3
931 mov %i4, %o4
932 call syscall
933 mov %i5, %o5
934
935 /* Return from handler (with PIL disabled) */
936 ld [%sp + 92], %l1
937 ld [%sp + 96], %l2
938 ld [%sp + 100], %l0
939 mov %o0, %i0
940 mov %psr, %l1
941 and %l1, 0xf, %l1
942 or %l1, 0x00000f00, %l1
943 and %l0, 0xfffffff0, %l0
944 or %l0, %l1, %l0
945 mov %l0, %psr
946 nop
947 nop
948 nop
949 nop
950 nop
951
952 /*
953 * If trap originated from user space, clear user space window mark
954 * and save uwb address for future use.
955 */
956 if_from_kernel 8f
957 switch_to_invalid %g5, %g6
958 mov %l5, %g2
959 mov %l6, %g1
960 mov %l7, %g7
961 switch_back %g5, %g6
962
963 /* If trap originated from user space, restore all windows from UWB */
964 /* UWB pointer is at %g1 */
965 0:
966 mov %g0, %wim
967 clr %g5
968 andcc %g1, UWB_ALIGNMENT - 1, %g0
969 bz 0f
970 nop
971
972 restore
973 sub %g1, 64, %g1
974 ldd [%g1 + 0], %l0
975 ldd [%g1 + 8], %l2
976 ldd [%g1 + 16], %l4
977 ldd [%g1 + 24], %l6
978 ldd [%g1 + 32], %i0
979 ldd [%g1 + 40], %i2
980 ldd [%g1 + 48], %i4
981 ldd [%g1 + 56], %i6
982 inc %g5
983 and %g5, 0x7, %g5
984 ba 0b
985 nop
986
987 /*
988 * We've restored all user space windows. Now time to
989 * fix CWP and WIM.
990 */
991 0:
992 restore
993 get_cwp %g7
994 clr %g5
995 inc %g5
996 sll %g5, %g7, %g5
997
998 /* Write values to invalid window and switch back */
999 mov %g2, %l5
1000 mov %g1, %l6
1001 clr %l7
1002 switch_back %g5, %g6
1003
1004 8:
1005 mov %sp, %l1
1006 sub %g2, 128, %sp
1007 ld [%sp + 104], %g1
1008 ld [%sp + 108], %g2
1009 ld [%sp + 112], %g3
1010 ld [%sp + 116], %g4
1011 ld [%sp + 120], %g7
1012
1013 mov %l1, %sp
1014 nop
1015 nop
1016 nop
1017
1018 jmp %l2
1019 rett %l2 + 4
1020
1021#define STRAP(_vector, _handler) \
1022 .org trap_table + _vector * TRAP_ENTRY_SIZE; \
1023 mov %psr, %l0 ; \
1024 sethi %hi(_handler), %l4 ; \
1025 jmp %lo(_handler) + %l4 ; \
1026 nop
1027
1028#define TRAP(_vector, _handler) \
1029 .org trap_table + _vector * TRAP_ENTRY_SIZE; \
1030 set _vector, %o0 ; \
1031 sethi %hi(_handler), %o2 ; \
1032 b preemptible_trap ; \
1033 or %o2, %lo(_handler), %o2 ;
1034
1035#define SYSCALL(_vector) \
1036 .org trap_table + _vector * TRAP_ENTRY_SIZE; \
1037 set _vector, %o0 ; \
1038 b syscall_trap ; \
1039 nop ;
1040
1041#define INTERRUPT(_vector, _priority) \
1042 .org trap_table + _vector * TRAP_ENTRY_SIZE; \
1043 mov _priority, %o0 ; \
1044 b interrupt_trap ; \
1045 nop ;
1046 nop ;
1047
1048#define BADTRAP(_vector) \
1049 .org trap_table + _vector * TRAP_ENTRY_SIZE ; \
1050 ta 0 ;
1051
1052.align TRAP_TABLE_SIZE
1053trap_table:
1054 STRAP(0x0, reset_trap)
1055 TRAP(0x1, instruction_access_exception)
1056 TRAP(0x2, illegal_instruction)
1057 TRAP(0x3, privileged_instruction)
1058 TRAP(0x4, fp_disabled)
1059 STRAP(0x5, window_overflow_trap)
1060 STRAP(0x6, window_underflow_trap)
1061 TRAP(0x7, mem_address_not_aligned)
1062 TRAP(0x8, fp_exception)
1063 TRAP(0x9, data_access_exception)
1064 TRAP(0xa, tag_overflow)
1065 BADTRAP(0xb)
1066 BADTRAP(0xc)
1067 BADTRAP(0xd)
1068 BADTRAP(0xe)
1069 BADTRAP(0xf)
1070 BADTRAP(0x10)
1071 INTERRUPT(0x11, 1)
1072 INTERRUPT(0x12, 2)
1073 INTERRUPT(0x13, 3)
1074 INTERRUPT(0x14, 4)
1075 INTERRUPT(0x15, 5)
1076 INTERRUPT(0x16, 6)
1077 INTERRUPT(0x17, 7)
1078 INTERRUPT(0x18, 8)
1079 INTERRUPT(0x19, 9)
1080 INTERRUPT(0x1a, 10)
1081 INTERRUPT(0x1b, 11)
1082 INTERRUPT(0x1c, 12)
1083 INTERRUPT(0x1d, 13)
1084 INTERRUPT(0x1e, 14)
1085 INTERRUPT(0x1f, 15)
1086 TRAP(0x21, instruction_access_error)
1087 BADTRAP(0x22)
1088 BADTRAP(0x23)
1089 BADTRAP(0x24)
1090 BADTRAP(0x25)
1091 BADTRAP(0x26)
1092 BADTRAP(0x27)
1093 BADTRAP(0x28)
1094 TRAP(0x29, data_access_error)
1095 TRAP(0x2a, division_by_zero)
1096 TRAP(0x2b, data_store_error)
1097 TRAP(0x2c, data_access_mmu_miss)
1098 BADTRAP(0x2d)
1099 BADTRAP(0x2e)
1100 BADTRAP(0x2f)
1101 BADTRAP(0x30)
1102 BADTRAP(0x31)
1103 BADTRAP(0x32)
1104 BADTRAP(0x33)
1105 BADTRAP(0x34)
1106 BADTRAP(0x35)
1107 BADTRAP(0x36)
1108 BADTRAP(0x37)
1109 BADTRAP(0x38)
1110 BADTRAP(0x39)
1111 BADTRAP(0x3a)
1112 BADTRAP(0x3b)
1113 BADTRAP(0x3c)
1114 BADTRAP(0x3d)
1115 BADTRAP(0x3e)
1116 BADTRAP(0x3f)
1117 BADTRAP(0x40)
1118 BADTRAP(0x41)
1119 BADTRAP(0x42)
1120 BADTRAP(0x43)
1121 BADTRAP(0x44)
1122 BADTRAP(0x45)
1123 BADTRAP(0x46)
1124 BADTRAP(0x47)
1125 BADTRAP(0x48)
1126 BADTRAP(0x49)
1127 BADTRAP(0x4a)
1128 BADTRAP(0x4b)
1129 BADTRAP(0x4c)
1130 BADTRAP(0x4d)
1131 BADTRAP(0x4e)
1132 BADTRAP(0x4f)
1133 BADTRAP(0x50)
1134 BADTRAP(0x51)
1135 BADTRAP(0x52)
1136 BADTRAP(0x53)
1137 BADTRAP(0x54)
1138 BADTRAP(0x55)
1139 BADTRAP(0x56)
1140 BADTRAP(0x57)
1141 BADTRAP(0x58)
1142 BADTRAP(0x59)
1143 BADTRAP(0x5a)
1144 BADTRAP(0x5b)
1145 BADTRAP(0x5c)
1146 BADTRAP(0x5d)
1147 BADTRAP(0x5e)
1148 BADTRAP(0x5f)
1149 BADTRAP(0x60)
1150 BADTRAP(0x61)
1151 BADTRAP(0x62)
1152 BADTRAP(0x63)
1153 BADTRAP(0x64)
1154 BADTRAP(0x65)
1155 BADTRAP(0x66)
1156 BADTRAP(0x67)
1157 BADTRAP(0x68)
1158 BADTRAP(0x69)
1159 BADTRAP(0x6a)
1160 BADTRAP(0x6b)
1161 BADTRAP(0x6c)
1162 BADTRAP(0x6d)
1163 BADTRAP(0x6e)
1164 BADTRAP(0x6f)
1165 BADTRAP(0x70)
1166 BADTRAP(0x71)
1167 BADTRAP(0x72)
1168 BADTRAP(0x73)
1169 BADTRAP(0x74)
1170 BADTRAP(0x75)
1171 BADTRAP(0x76)
1172 BADTRAP(0x77)
1173 BADTRAP(0x78)
1174 BADTRAP(0x79)
1175 BADTRAP(0x7a)
1176 BADTRAP(0x7b)
1177 BADTRAP(0x7c)
1178 BADTRAP(0x7d)
1179 BADTRAP(0x7e)
1180 BADTRAP(0x7f)
1181 SYSCALL(0x80)
1182 SYSCALL(0x81)
1183 SYSCALL(0x82)
1184 SYSCALL(0x83)
1185 SYSCALL(0x84)
1186 SYSCALL(0x85)
1187 SYSCALL(0x86)
1188 SYSCALL(0x87)
1189 SYSCALL(0x88)
1190 SYSCALL(0x89)
1191 SYSCALL(0x8a)
1192 SYSCALL(0x8b)
1193 SYSCALL(0x8c)
1194 SYSCALL(0x8d)
1195 SYSCALL(0x8e)
1196 SYSCALL(0x8f)
1197 SYSCALL(0x90)
1198 SYSCALL(0x91)
1199 SYSCALL(0x92)
1200 SYSCALL(0x93)
1201 SYSCALL(0x94)
1202 SYSCALL(0x95)
1203 SYSCALL(0x96)
1204 SYSCALL(0x97)
1205 SYSCALL(0x98)
1206 SYSCALL(0x99)
1207 SYSCALL(0x9a)
1208 SYSCALL(0x9b)
1209 SYSCALL(0x9c)
1210 SYSCALL(0x9d)
1211 SYSCALL(0x9e)
1212 SYSCALL(0x9f)
1213 SYSCALL(0xa0)
1214 SYSCALL(0xa1)
1215 SYSCALL(0xa2)
1216 SYSCALL(0xa3)
1217 SYSCALL(0xa4)
1218 SYSCALL(0xa5)
1219 SYSCALL(0xa6)
1220 SYSCALL(0xa7)
1221 SYSCALL(0xa8)
1222 SYSCALL(0xa9)
1223 SYSCALL(0xaa)
1224 SYSCALL(0xab)
1225 SYSCALL(0xac)
1226 SYSCALL(0xad)
1227 SYSCALL(0xae)
1228 SYSCALL(0xaf)
1229 SYSCALL(0xb0)
1230 SYSCALL(0xb1)
1231 SYSCALL(0xb2)
1232 SYSCALL(0xb3)
1233 SYSCALL(0xb4)
1234 SYSCALL(0xb5)
1235 SYSCALL(0xb6)
1236 SYSCALL(0xb7)
1237 SYSCALL(0xb8)
1238 SYSCALL(0xb9)
1239 SYSCALL(0xba)
1240 SYSCALL(0xbb)
1241 SYSCALL(0xbc)
1242 SYSCALL(0xbd)
1243 SYSCALL(0xbe)
1244 SYSCALL(0xbf)
1245 SYSCALL(0xc0)
1246 SYSCALL(0xc1)
1247 SYSCALL(0xc2)
1248 SYSCALL(0xc3)
1249 SYSCALL(0xc4)
1250 SYSCALL(0xc5)
1251 SYSCALL(0xc6)
1252 SYSCALL(0xc7)
1253 SYSCALL(0xc8)
1254 SYSCALL(0xc9)
1255 SYSCALL(0xca)
1256 SYSCALL(0xcb)
1257 SYSCALL(0xcc)
1258 SYSCALL(0xcd)
1259 SYSCALL(0xce)
1260 SYSCALL(0xcf)
Note: See TracBrowser for help on using the repository browser.