OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [newlib/] [newlib/] [libgloss/] [sparc/] [traps.S] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.