source: trunk/libs/newlib/src/libgloss/sparc/traps.S @ 616

Last change on this file since 616 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 18.8 KB
RevLine 
[444]1/*
2 * Copyright (c) 1995, 1996, 1998 Cygnus Support
3 *
4 * The authors hereby grant permission to use, copy, modify, distribute,
5 * and license this software and its documentation for any purpose, provided
6 * that existing copyright notices are retained in all copies and that this
7 * notice is included verbatim in any distributions. No written agreement,
8 * license, or royalty fee is required for any of the authorized uses.
9 * Modifications to this software may be copyrighted by their authors
10 * and need not follow the licensing terms described here, provided that
11 * the new terms are clearly indicated on the first page of each file where
12 * they apply.
13 */
14
15#include "asm.h"
16#include "slite.h"
17
18        .register %g2, #scratch
19        .register %g3, #scratch
20
21        .text
22        .align 4
23
24/*
25 *  The trap table has to be the first code in a boot PROM.  But because
26 *  the Memory Configuration comes up thinking we only have 4K of PROM, we
27 *  cannot have a full trap table and still have room left over to
28 *  reprogram the Memory Configuration register correctly.  This file
29 *  uses an abbreviated trap which has every entry which might be used
30 *  before RTEMS installs its own trap table.
31 */
32        .globl  _trap_table
33_trap_table:
34  TRAP(SYM(ercinit));                           ! 00 reset trap
35  BAD_TRAP;                                     ! 01 instruction access exception
36  TRAP(SYM(no_fpu));                            ! 02 illegal instruction
37  BAD_TRAP;                                     ! 03 privileged instruction
38  BAD_TRAP;                                     ! 04 fp disabled
39  TRAP(SYM(win_overflow));                      ! 05 window overflow
40  TRAP(SYM(win_underflow));                     ! 06 window underflow
41  BAD_TRAP;                                     ! 07 memory address not aligned
42  BAD_TRAP;                                     ! 08 fp exception
43  BAD_TRAP;                                     ! 09 data access exception
44  BAD_TRAP;                                     ! 0A tag overflow
45
46  /* Trap levels from 0B to 0x10 are not defined (used for MEC init) */
47
48SYM(ercinit):
49  sethi         %hi(_ERC32_MEC), %g1            ! 0B
50  sethi         %hi(0x001C1000), %g2
51  or            %g1,%lo(0x001C1000),%g1
52  st            %g2, [%g1 + 0x10]
53  st            %g0, [%g1 + 0x18]                       ! 0C
54  nop
55  nop
56  nop
57
58  TRAP(SYM(hard_reset));                        ! 0D undefined
59  BAD_TRAP;                                     ! 0E undefined
60  BAD_TRAP;                                     ! 0F undefined
61  BAD_TRAP;                                     ! 10 undefined
62
63  /*
64   *  ERC32 defined traps
65   */
66
67  BAD_TRAP;                                     ! 11 masked errors
68  BAD_TRAP;                                     ! 12 external 1
69  BAD_TRAP;                                     ! 13 external 2
70  BAD_TRAP;                                     ! 14 UART A RX/TX
71  BAD_TRAP;                                     ! 15 UART B RX/TX
72  BAD_TRAP;                                     ! 16 correctable memory error
73  BAD_TRAP;                                     ! 17 UART error
74  BAD_TRAP;                                     ! 18 DMA access error
75  BAD_TRAP;                                     ! 19 DMA timeout
76  BAD_TRAP;                                     ! 1A external 3
77  BAD_TRAP;                                     ! 1B external 4
78  BAD_TRAP;                                     ! 1C general purpose timer
79  BAD_TRAP;                                     ! 1D real time clock
80  BAD_TRAP;                                     ! 1E external 5
81  BAD_TRAP;                                     ! 1F watchdog timeout
82
83
84  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 20 - 23 undefined
85  BAD_TRAP;                                     ! 24 cp_disabled
86            BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 25 - 27 undefined
87  BAD_TRAP;                                     ! 28 cp_exception
88            BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 29 - 2B undefined
89  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 2C - 2F undefined
90  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 30 - 33 undefined
91  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 34 - 37 undefined
92  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 38 - 3B undefined
93  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 3C - 3F undefined
94  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 40 - 43 undefined
95  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 44 - 47 undefined
96  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 48 - 4B undefined
97  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 4C - 4F undefined
98  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 50 - 53 undefined
99  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 54 - 57 undefined
100  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 58 - 5B undefined
101  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 5C - 5F undefined
102  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 60 - 63 undefined
103  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 64 - 67 undefined
104  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 68 - 6B undefined
105  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 6C - 6F undefined
106  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 70 - 73 undefined
107  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 74 - 77 undefined
108  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 78 - 7B undefined
109  BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;       ! 7C - 7F undefined
110
111  /*
112   *  Software traps
113   *
114   *  NOTE: At the risk of being redundant... this is not a full
115   *        table.  The setjmp on the SPARC requires a window flush trap
116   *        handler and RTEMS will preserve the entries that were
117   *        installed before.
118   */
119
120  SOFT_TRAP;                                    ! 80
121#if 0
122  SOFT_TRAP;                                    ! 81
123#else
124  TRAP(SYM(trap_low))                           ! 81
125#endif
126  SOFT_TRAP;                                    ! 82
127  TRAP(SYM(win_flush));                         ! 83 flush windows SW trap
128  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 84 - 87
129  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 88 - 8B
130  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 8C - 8F
131  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 90 - 93
132  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 94 - 97
133  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 98 - 9B
134  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! 9C - 9F
135  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! A0 - A3
136  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! A4 - A7
137  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! A8 - AB
138  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! AC - AF
139  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! B0 - B3
140  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! B4 - B7
141  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! B8 - BB
142  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! BC - BF
143  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! C0 - C3
144  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! C4 - C7
145  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! C8 - CB
146  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! CC - CF
147  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! D0 - D3
148  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! D4 - D7
149  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! D8 - DB
150  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! DC - DF
151  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! E0 - E3
152  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! E4 - E7
153  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! E8 - EB
154  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! EC - EF
155  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! F0 - F3
156  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! F4 - F7
157  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! F8 - FB
158  SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;   ! FC - FF
159
160/*
161 * Startup code for standalone system. Wash IU and FPU (if present)
162 * registers. The registers have to be written to initiate the parity
163 * bits.
164 */
165        .globl  SYM(hard_reset)
166SYM(hard_reset):
167
168        sethi   %hi(0x01FE0),%o0
169        or      %o0,%lo(0x01FE0),%o0
170        mov     %o0, %psr               ! Set valid PSR
171        nop
172
173        mov     %g0, %wim               ! Set window invalid mask register
174        mov     %g0, %y                 ! Init Y-register
175        nop
176        sethi   %hi(SYM(hard_reset)), %g1
177
178        mov     %g1, %tbr               ! Set TBR
179        sethi   %hi(SP_INIT),%sp
180        or      %g0, 1, %o0
181        ld      [%g0], %f0              ! Check if FPU is present
182
183        tst     %o0
184        bz      fixiu
185        nop
186        ba      fixfpu
187
188! FPU disabled trap address
189
190        clr     %i0
191        jmpl    %l2, %g0
192        rett    %l2 + 4
193        nop
194       
195
196! Wash register files (fix for 90C601E & 90C602E)
197
198fixfpu:
199
200        ld      [%g0], %f0
201        ld      [%g0], %f1
202        ld      [%g0], %f2
203        ld      [%g0], %f3
204        ld      [%g0], %f4
205        ld      [%g0], %f5
206        ld      [%g0], %f6
207        ld      [%g0], %f7
208        ld      [%g0], %f8
209        ld      [%g0], %f9
210        ld      [%g0], %f10
211        ld      [%g0], %f11
212        ld      [%g0], %f12
213        ld      [%g0], %f13
214        ld      [%g0], %f14
215        ld      [%g0], %f15
216        ld      [%g0], %f16
217        ld      [%g0], %f17
218        ld      [%g0], %f18
219        ld      [%g0], %f19
220        ld      [%g0], %f20
221        ld      [%g0], %f21
222        ld      [%g0], %f22
223        ld      [%g0], %f23
224        ld      [%g0], %f24
225        ld      [%g0], %f25
226        ld      [%g0], %f26
227        ld      [%g0], %f27
228        ld      [%g0], %f28
229        ld      [%g0], %f29
230        ld      [%g0], %f30
231        ld      [%g0], %f31
232
233fixiu:
234        clr     %g1
235        clr     %g2
236        clr     %g3
237        clr     %g4
238        clr     %g5
239        clr     %g6
240        clr     %g7
241        set     8,%g1
242wl0:
243        clr     %i0
244        clr     %i1
245        clr     %i2
246        clr     %i3
247        clr     %i4
248        clr     %i5
249        clr     %i6
250        clr     %i7
251        clr     %l0
252        clr     %l1
253        clr     %l2
254        clr     %l3
255        clr     %l4
256        clr     %l5
257        clr     %l6
258        clr     %l7
259        save
260        subcc   %g1, 1, %g1
261        bne     wl0
262        nop
263
264!
265! Start the real-time clock with a tick of 150 clocks
266!
267
268rtc:
269
270        set     0x1f80000, %l0          ! MEC register base
271        set     149, %l1
272        st      %l1, [%l0 + 0x84]       ! RTC scaler = 149
273        set     0x0d00, %l1
274        st      %l1, [%l0 + 0x98]       ! Start RTC
275
276        st      %g0, [%l0 + 0x64]       ! Disable watchdog for now
277        ld      [%l0], %g1
278        or      %g1, 1, %g1
279        st      %g1, [%l0]              ! Enable power-down mode
280
281_init:
282        set     PSR_INIT, %g1           ! Initialize psr
283        mov     %g1, %psr
284        set     WIM_INIT, %g1           ! Initialize WIM
285        mov     %g1, %wim               
286        set     _trap_table, %g1        ! Initialize TBR
287        mov     %g1, %tbr
288        nop;nop;nop                     
289
290        set     PSR_INIT, %g1
291        wr      %g1, 0x20, %psr         ! enable traps
292        nop; nop; nop;
293
294        call    SYM(start)
295        nop
296       
297/*
298 * Register window overflow handler.  Come here when save would move us
299 * into the invalid window.  This routine runs with traps disabled, and
300 * must be careful not to touch the condition codes, as PSR is never
301 * restored.
302 *
303 * We are called with %l0 = wim, %l1 = pc, %l2 = npc
304 */
305        .globl SYM(win_overflow)
306SYM(win_overflow):
307        mov     %g1, %l3                ! Save g1, we use it to hold the wim
308        srl     %l0, 1, %g1             ! Rotate wim right
309        sll     %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0
310        or      %l0, %g1, %g1
311
312        save    %g0, %g0, %g0           ! Slip into next window
313        mov     %g1, %wim               ! Install the new wim
314        nop
315        nop
316        nop
317
318        std     %l0, [%sp + 0 * 4]      ! save L & I registers
319        std     %l2, [%sp + 2 * 4]
320        std     %l4, [%sp + 4 * 4]
321        std     %l6, [%sp + 6 * 4]
322
323        std     %i0, [%sp + 8 * 4]
324        std     %i2, [%sp + 10 * 4]
325        std     %i4, [%sp + 12 * 4]
326        std     %i6, [%sp + 14 * 4]
327
328        restore                         ! Go back to trap window.
329        mov     %l3, %g1                ! Restore %g1
330
331        jmpl    %l1, %g0
332        rett    %l2
333
334/*
335 * Register window underflow handler.  Come here when restore would move us
336 * into the invalid window.  This routine runs with traps disabled, and
337 * must be careful not to touch the condition codes, as PSR is never
338 * restored.
339 *
340 * We are called with %l0 = wim, %l1 = pc, %l2 = npc
341 */
342        .globl SYM(win_underflow)
343SYM(win_underflow):
344        sll     %l0, 1, %l3             ! Rotate wim left
345        srl     %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0
346        or      %l0, %l3, %l0
347
348        mov     %l0, %wim               ! Install the new wim
349
350        restore                         ! Users window
351        restore                         ! His callers window
352
353        ldd     [%sp + 0 * 4], %l0      ! restore L & I registers
354        ldd     [%sp + 2 * 4], %l2
355        ldd     [%sp + 4 * 4], %l4
356        ldd     [%sp + 6 * 4], %l6
357
358        ldd     [%sp + 8 * 4], %i0
359        ldd     [%sp + 10 * 4], %i2
360        ldd     [%sp + 12 * 4], %i4
361        ldd     [%sp + 14 * 4], %i6
362
363        save    %g0, %g0, %g0           ! Back to trap window
364        save    %g0, %g0, %g0
365
366        jmpl    %l1, %g0
367        rett    %l2
368
369/*
370 * Register window flush handler, triggered by a "ta 3" instruction.
371 * We are called with %l0 = wim, %l1 = pc, %l2 = npc
372 */
373        .globl  SYM(win_flush)
374SYM(win_flush):
375        mov     %psr, %l0
376        or      %l0,0xf00,%l3           ! Disable interrupts
377        mov     %l3,%psr
378        nop
379        nop
380        nop
381        mov     %wim, %l3
382
383        srl     %l3, %l0, %l4           ! wim >> cwp
384        cmp     %l4, 1
385        bne     flush_window_fine       ! Branch if not in the invalid window
386        nop
387
388/* Handle window overflow. We can't trap here. */
389
390        mov     %g1, %l4                ! Save g1, we use it to hold the wim
391        srl     %l3, 1, %g1             ! Rotate wim right
392        sll     %l3, NUMBER_OF_REGISTER_WINDOWS - 1, %l3
393        or      %l3, %g1, %g1
394        mov     %g0, %wim               ! Clear wim so that subsequent save
395        nop                             !  wont trap
396        nop
397        nop
398        save    %g0, %g0, %g0           ! Slip into next window
399        mov     %g1, %wim               ! Install the new wim
400
401        std     %l0, [%sp + 0 * 4]      ! save L & I registers
402        std     %l2, [%sp + 2 * 4]
403        std     %l4, [%sp + 4 * 4]
404        std     %l6, [%sp + 6 * 4]
405
406        std     %i0, [%sp + 8 * 4]
407        std     %i2, [%sp + 10 * 4]
408        std     %i4, [%sp + 12 * 4]
409        std     %i6, [%sp + 14 * 4]
410
411        restore                         ! Go back to trap window.
412        mov     %l4, %g1                ! Restore %g1
413
414flush_window_fine:
415        mov     %psr,%l5                ! enable traps
416        or      %l5,0x20,%l5
417        mov     %l5, %psr
418        nop
419        nop
420        nop
421
422        set     save_buf,%l5
423        st      %l2,[%l5]
424
425        ! The stack pointer currently contains a bogus value [when a trap
426        ! occurs CWP is decremented and points to an unused window].
427        ! Give it something useful before we flush every window.
428        ! This does what a "save %sp,-64,$sp" would, except that CWP has
429        ! already been decremented.
430        add     %fp, -64, %sp
431
432        save %sp, -64, %sp              ! Flush user register window to stack
433        save %sp, -64, %sp
434        save %sp, -64, %sp
435        save %sp, -64, %sp
436        save %sp, -64, %sp
437        save %sp, -64, %sp
438        save %sp, -64, %sp
439        save %sp, -64, %sp
440        restore
441        restore
442        restore
443        restore
444        restore
445        restore
446        restore
447        restore
448
449        restore                         ! Make sure we have a valid window
450        save %g0, %g0, %g0
451
452        set     save_buf, %l2           ! Get our return address back
453        ld      [%l2],%l2
454
455        mov     %psr,%l5                ! disable traps for rett
456        andn    %l5,0x20,%l5
457        mov     %l5,%psr
458        nop
459        nop
460        nop
461
462        jmpl    %l2, %g0
463        rett    %l2+4
464
465/*
466 * Read the TBR.
467 */
468       .globl SYM(rdtbr)
469SYM(rdtbr):
470        mov     %tbr, %o0
471        nop
472        retl
473        nop
474
475/*
476 * Read the psr
477 */
478        .globl  SYM(read_psr)
479SYM(read_psr):
480        mov     %psr, %o0
481        nop
482        retl
483        nop
484
485/*
486 * Write the PSR.
487 */
488
489        .globl  SYM(write_psr)
490SYM(write_psr):
491        mov %i0, %psr
492        nop
493        nop
494        nop
495        retl
496        nop
497/*
498 * Come here when no fpu exists.  This just skips the offending
499 * instruction.
500 */
501        .globl  SYM(no_fpu)
502SYM(no_fpu):
503        jmpl %l2, %g0
504        rett %l2+4
505
506        .globl SYM(fltr_proto)
507        .align 4
508SYM(fltr_proto):                    ! First level trap routine prototype
509        sethi 0, %l0
510        jmpl 0+%l0, %g0
511        nop
512        nop
513
514/*
515 * Trap handler for memory errors.  This just sets mem_err to be
516 * non-zero.  It assumes that l1 is non-zero.  This should be safe,
517 * as it is doubtful that 0 would ever contain code that could mem
518 * fault.  This routine will skip past the faulting instruction after
519 * setting mem_err.
520 */
521        .globl  SYM(fltr_set_mem_err)
522SYM(fltr_set_mem_err):
523        sethi   %hi(SYM(mem_err)), %l0
524        st      %l1, [%l0 + %lo(SYM(mem_err))]
525        jmpl    %l2, %g0
526        rett    %l2+4
527
528        .data
529        .align  4
530        .ascii  "DaTa"
531        .long   SYM(sdata)
532in_trap_handler:
533        .word   0
534save_buf:       
535        .word   0       /* place to save %g1 */
536        .word   0       /* place to save %g2 */
537
538        .text
539        .align 4
540
541/*
542 * This function is called when any SPARC trap (except window overflow
543 * or underflow) occurs.  It makes sure that the invalid register
544 * window is still available before jumping into C code.  It will also
545 * restore the world if you return from handle_exception.
546 */
547        .globl SYM(trap_low)
548SYM(trap_low):
549        mov     %psr, %l0
550        mov     %wim, %l3
551
552        srl     %l3, %l0, %l4           ! wim >> cwp
553        cmp     %l4, 1
554        bne     window_fine             ! Branch if not in the invalid window
555        nop
556
557        mov     %g1, %l4                ! Save g1, we use it to hold the wim
558        srl     %l3, 1, %g1             ! Rotate wim right
559        sll     %l3, 8-1, %l5
560        or      %l5, %g1, %g1
561               
562        save    %g0, %g0, %g0           ! Slip into next window
563        mov     %g1, %wim               ! Install the new wim
564
565        std     %l0, [%sp + 0 * 4]      ! save L & I registers
566        std     %l2, [%sp + 2 * 4]
567        std     %l4, [%sp + 4 * 4]
568        std     %l6, [%sp + 6 * 4]
569
570        std     %i0, [%sp + 8 * 4]
571        std     %i2, [%sp + 10 * 4]
572        std     %i4, [%sp + 12 * 4]
573        std     %i6, [%sp + 14 * 4]
574
575        restore                         ! Go back to trap window.
576        mov     %l4, %g1                ! Restore g1
577
578window_fine:
579        sethi   %hi(in_trap_handler), %l4
580        ld      [%lo(in_trap_handler) + %l4], %l5
581        tst     %l5
582        bg      recursive_trap
583        inc     %l5
584
585        /* use the stack we set in the linker script */
586        sethi   %hi(__trap_stack), %l6
587        or      %l6,%lo(__trap_stack),%l6
588        mov     %l6, %sp                ! set the stack pointer
589
590recursive_trap:
591        st      %l5, [%lo(in_trap_handler) + %l4]
592
593        sub     %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
594                                        ! + hidden arg + arg spill
595                                        ! + doubleword alignment
596                                        ! + registers[72] local var
597
598        std     %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
599        std     %g2, [%sp + (24 + 2) * 4]
600        std     %g4, [%sp + (24 + 4) * 4]
601        std     %g6, [%sp + (24 + 6) * 4]
602
603        std     %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
604        std     %i2, [%sp + (24 + 10) * 4]
605        std     %i4, [%sp + (24 + 12) * 4]
606        std     %i6, [%sp + (24 + 14) * 4]
607                                         ! F0->F31 not implemented
608        mov     %y, %l4
609        mov     %tbr, %l5
610        st      %l4, [%sp + (24 + 64) * 4] ! Y
611        st      %l0, [%sp + (24 + 65) * 4] ! PSR
612        st      %l3, [%sp + (24 + 66) * 4] ! WIM
613        st      %l5, [%sp + (24 + 67) * 4] ! TBR
614        st      %l1, [%sp + (24 + 68) * 4] ! PC
615        st      %l2, [%sp + (24 + 69) * 4] ! NPC
616                                         ! CPSR and FPSR not implemented
617
618        or      %l0, 0xf20, %l4
619        mov     %l4, %psr               ! Turn on traps, disable interrupts
620
621        call    SYM(handle_exception)
622        add     %sp, 24 * 4, %o0        ! Pass address of registers
623
624/* Reload all of the registers that aren't on the stack */
625
626        ld      [%sp + (24 + 1) * 4], %g1  ! registers[Gx]
627        ldd     [%sp + (24 + 2) * 4], %g2
628        ldd     [%sp + (24 + 4) * 4], %g4
629        ldd     [%sp + (24 + 6) * 4], %g6
630
631        ldd     [%sp + (24 + 8) * 4], %i0  ! registers[Ox]
632        ldd     [%sp + (24 + 10) * 4], %i2
633        ldd     [%sp + (24 + 12) * 4], %i4
634        ldd     [%sp + (24 + 14) * 4], %i6
635
636        ldd     [%sp + (24 + 64) * 4], %l0 ! Y & PSR
637        ldd     [%sp + (24 + 68) * 4], %l2 ! PC & NPC
638
639        restore                         ! Ensure that previous window is valid
640        save    %g0, %g0, %g0           !  by causing a window_underflow trap
641
642        mov     %l0, %y
643        mov     %l1, %psr               ! Make sure that traps are disabled
644                                        ! for rett
645
646        sethi   %hi(in_trap_handler), %l4
647        ld      [%lo(in_trap_handler) + %l4], %l5
648        dec     %l5
649        st      %l5, [%lo(in_trap_handler) + %l4]
650
651        jmpl    %l2, %g0                ! Restore old PC
652        rett    %l3                     ! Restore old nPC
653
654
Note: See TracBrowser for help on using the repository browser.