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

lfn serial ticket/834-toolchain-update topic/fix-logger-deadlock topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f6f22cdb was f7a33de, checked in by Jakub Klama <jakub.klama@…>, 12 years ago

Enable interrupts support.

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