]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/sparc/cpu/leon3/start.S
1e393a56e6ae51e335e654f717eedadef3916a2f
[karo-tx-uboot.git] / arch / sparc / cpu / leon3 / start.S
1 /* This is where the SPARC/LEON3 starts
2  * Copyright (C) 2007,
3  * Daniel Hellstrom, daniel@gaisler.com
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <asm-offsets.h>
25 #include <config.h>
26 #include <asm/asmmacro.h>
27 #include <asm/winmacro.h>
28 #include <asm/psr.h>
29 #include <asm/stack.h>
30 #include <asm/leon.h>
31 #include <version.h>
32
33 /* Entry for traps which jump to a programmer-specified trap handler.  */
34 #define TRAPR(H)  \
35         wr      %g0, 0xfe0, %psr; \
36         mov     %g0, %tbr; \
37         ba      (H); \
38         mov     %g0, %wim;
39
40 #define TRAP(H) \
41         mov     %psr, %l0; \
42         ba      (H); \
43         nop; nop;
44
45 #define TRAPI(ilevel) \
46         mov     ilevel, %l7; \
47         mov     %psr, %l0; \
48         b       _irq_entry; \
49         mov     %wim, %l3
50
51 /* Unexcpected trap will halt the processor by forcing it to error state */
52 #undef BAD_TRAP
53 #define BAD_TRAP ta 0; nop; nop; nop;
54
55 /* Software trap. Treat as BAD_TRAP for the time being... */
56 #define SOFT_TRAP TRAP(_hwerr)
57
58 #define PSR_INIT   0x1FC0       /* Disable traps, set s and ps */
59 #define WIM_INIT   2
60
61 /* All traps low-level code here must end with this macro. */
62 #define RESTORE_ALL b ret_trap_entry; clr %l6;
63
64 #define WRITE_PAUSE nop;nop;nop
65
66 WINDOWSIZE = (16 * 4)
67 ARGPUSHSIZE = (6 * 4)
68 ARGPUSH = (WINDOWSIZE + 4)
69 MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
70
71 /* Number of register windows */
72 #ifndef CONFIG_SYS_SPARC_NWINDOWS
73 #error Must define number of SPARC register windows, default is 8
74 #endif
75
76 #define STACK_ALIGN     8
77 #define SA(X)   (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
78
79         .section ".start", "ax"
80         .globl  _start, start, _trap_table
81         .globl  _irq_entry, nmi_trap
82         .globl  _reset_reloc
83
84 /* at address 0
85  * Hardware traps
86  */
87 start:
88 _start:
89 _trap_table:
90         TRAPR(_hardreset);              ! 00 reset trap
91         BAD_TRAP;                       ! 01 instruction_access_exception
92         BAD_TRAP;                       ! 02 illegal_instruction
93         BAD_TRAP;                       ! 03 priveleged_instruction
94         BAD_TRAP;                       ! 04 fp_disabled
95         TRAP(_window_overflow);         ! 05 window_overflow
96         TRAP(_window_underflow);        ! 06 window_underflow
97         BAD_TRAP;                       ! 07 Memory Address Not Aligned
98         BAD_TRAP;                       ! 08 Floating Point Exception
99         BAD_TRAP;                       ! 09 Data Miss Exception
100         BAD_TRAP;                       ! 0a Tagged Instruction Ovrflw
101         BAD_TRAP;                       ! 0b Watchpoint Detected
102         BAD_TRAP;                       ! 0c
103         BAD_TRAP;                       ! 0d
104         BAD_TRAP;                       ! 0e
105         BAD_TRAP;                       ! 0f
106         BAD_TRAP;                       ! 10
107         TRAPI(1);                       ! 11 IRQ level 1
108         TRAPI(2);                       ! 12 IRQ level 2
109         TRAPI(3);                       ! 13 IRQ level 3
110         TRAPI(4);                       ! 14 IRQ level 4
111         TRAPI(5);                       ! 15 IRQ level 5
112         TRAPI(6);                       ! 16 IRQ level 6
113         TRAPI(7);                       ! 17 IRQ level 7
114         TRAPI(8);                       ! 18 IRQ level 8
115         TRAPI(9);                       ! 19 IRQ level 9
116         TRAPI(10);                      ! 1a IRQ level 10
117         TRAPI(11);                      ! 1b IRQ level 11
118         TRAPI(12);                      ! 1c IRQ level 12
119         TRAPI(13);                      ! 1d IRQ level 13
120         TRAPI(14);                      ! 1e IRQ level 14
121         TRAP(_nmi_trap);                ! 1f IRQ level 15 /
122                                         ! NMI (non maskable interrupt)
123         BAD_TRAP;                       ! 20 r_register_access_error
124         BAD_TRAP;                       ! 21 instruction access error
125         BAD_TRAP;                       ! 22
126         BAD_TRAP;                       ! 23
127         BAD_TRAP;                       ! 24 co-processor disabled
128         BAD_TRAP;                       ! 25 uniplemented FLUSH
129         BAD_TRAP;                       ! 26
130         BAD_TRAP;                       ! 27
131         BAD_TRAP;                       ! 28 co-processor exception
132         BAD_TRAP;                       ! 29 data access error
133         BAD_TRAP;                       ! 2a division by zero
134         BAD_TRAP;                       ! 2b data store error
135         BAD_TRAP;                       ! 2c data access MMU miss
136         BAD_TRAP;                       ! 2d
137         BAD_TRAP;                       ! 2e
138         BAD_TRAP;                       ! 2f
139         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30-33
140         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34-37
141         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38-3b
142         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3c-3f
143         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40-43
144         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44-47
145         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48-4b
146         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4c-4f
147         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50-53
148         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54-57
149         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58-5b
150         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5c-5f
151
152         /* implementaion dependent */
153         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60-63
154         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64-67
155         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68-6b
156         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6c-6f
157         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70-73
158         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74-77
159         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78-7b
160         BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7c-7f
161
162         /* Software traps, not handled */
163         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 80-83
164         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 84-87
165         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 88-8b
166         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 8c-8f
167         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 90-93
168         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 94-97
169         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 98-9b
170         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! 9c-9f
171         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! a0-a3
172         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! a4-a7
173         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! a8-ab
174         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! ac-af
175         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! b0-b3
176         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! b4-b7
177         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! b8-bb
178         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! bc-bf
179         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! c0-c3
180         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! c4-c7
181         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! c8-cb
182         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! cc-cf
183         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! d0-d3
184         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! d4-d7
185         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! d8-db
186         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! dc-df
187         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! e0-e3
188         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! e4-e7
189         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! e8-eb
190         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! ec-ef
191         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! f0-f3
192         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! f4-f7
193         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! f8-fb
194         SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;     ! fc-ff
195 /*
196  * Version string
197  */
198
199         .data
200         .extern leon3_snooping_avail
201         .globl  version_string
202 version_string:
203         .ascii U_BOOT_VERSION_STRING, "\0"
204
205         .section        ".text"
206         .align 4
207
208 _hardreset:
209 1000:
210         flush
211
212         /* Enable I/D-Cache and Snooping */
213         set     0x0081000f, %g2
214         sta     %g2, [%g0] 2
215
216         mov     %g0, %y
217         clr     %g1
218         clr     %g2
219         clr     %g3
220         clr     %g4
221         clr     %g5
222         clr     %g6
223         clr     %g7
224
225         mov     %asr17, %g3
226         and     %g3, 0x1f, %g3
227 clear_window:
228         mov     %g0, %l0
229         mov     %g0, %l1
230         mov     %g0, %l2
231         mov     %g0, %l3
232         mov     %g0, %l4
233         mov     %g0, %l5
234         mov     %g0, %l6
235         mov     %g0, %l7
236         mov     %g0, %o0
237         mov     %g0, %o1
238         mov     %g0, %o2
239         mov     %g0, %o3
240         mov     %g0, %o4
241         mov     %g0, %o5
242         mov     %g0, %o6
243         mov     %g0, %o7
244         subcc   %g3, 1, %g3
245         bge     clear_window
246         save
247
248 wininit:
249         set     WIM_INIT, %g3
250         mov     %g3, %wim
251
252 stackp:
253         set     CONFIG_SYS_INIT_SP_OFFSET, %fp
254         andn    %fp, 0x0f, %fp
255         sub     %fp, 64, %sp
256
257 cpu_init_unreloc:
258         call    cpu_init_f
259         nop
260
261 /* un relocated start address of monitor */
262 #define TEXT_START _text
263
264 /* un relocated end address of monitor */
265 #define DATA_END __init_end
266
267 reloc:
268         set     TEXT_START,%g2
269         set     DATA_END,%g3
270         set     CONFIG_SYS_RELOC_MONITOR_BASE,%g4
271 reloc_loop:
272         ldd     [%g2],%l0
273         ldd     [%g2+8],%l2
274         std     %l0,[%g4]
275         std     %l2,[%g4+8]
276         inc     16,%g2
277         subcc   %g3,%g2,%g0
278         bne     reloc_loop
279         inc     16,%g4
280
281         clr     %l0
282         clr     %l1
283         clr     %l2
284         clr     %l3
285         clr     %g2
286
287 /* register g4 contain address to start
288  * This means that BSS must be directly after data and code segments
289  *
290  * g3 is length of bss = (__bss_end-__bss_start)
291  *
292  */
293
294 clr_bss:
295 /* clear bss area (the relocated) */
296         set     __bss_start,%g2
297         set     __bss_end,%g3
298         sub     %g3,%g2,%g3
299         add     %g3,%g4,%g3
300         clr     %g1     /* std %g0 uses g0 and g1 */
301 /* clearing 16byte a time ==> linker script need to align to 16 byte offset */
302 clr_bss_16:
303         std     %g0,[%g4]
304         std     %g0,[%g4+8]
305         inc     16,%g4
306         cmp     %g3,%g4
307         bne     clr_bss_16
308         nop
309
310 /* add offsets to GOT table */
311 fixup_got:
312         set     __got_start,%g4
313         set     __got_end,%g3
314 /*
315  * new got offset = (old GOT-PTR (read with ld) -
316  *   CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
317  *   Destination Address (from define)
318  */
319         set     CONFIG_SYS_RELOC_MONITOR_BASE,%g2
320         set     TEXT_START, %g1
321         add     %g4,%g2,%g4
322         sub     %g4,%g1,%g4
323         add     %g3,%g2,%g3
324         sub     %g3,%g1,%g3
325         sub     %g2,%g1,%g2     ! prepare register with (new base address) -
326                                 !  (old base address)
327 got_loop:
328         ld      [%g4],%l0       ! load old GOT-PTR
329         add     %l0,%g2,%l0     ! increase with (new base address) -
330                                 !  (old base)
331         st      %l0,[%g4]
332         inc     4,%g4
333         cmp     %g3,%g4
334         bne     got_loop
335         nop
336
337 prom_relocate:
338         set     __prom_start, %g2
339         set     __prom_end, %g3
340         set     CONFIG_SYS_PROM_OFFSET, %g4
341
342 prom_relocate_loop:
343         ldd     [%g2],%l0
344         ldd     [%g2+8],%l2
345         std     %l0,[%g4]
346         std     %l2,[%g4+8]
347         inc     16,%g2
348         subcc   %g3,%g2,%g0
349         bne     prom_relocate_loop
350         inc     16,%g4
351
352 /* Trap table has been moved, lets tell CPU about
353  * the new trap table address
354  */
355
356         set     CONFIG_SYS_RELOC_MONITOR_BASE, %g2
357         wr      %g0, %g2, %tbr
358         nop
359         nop
360         nop
361
362 /* If CACHE snooping is available in hardware the
363  * variable leon3_snooping_avail will be set to
364  * 0x800000 else 0.
365  */
366 snoop_detect:
367         sethi   %hi(0x00800000), %o0
368         lda     [%g0] 2, %o1
369         and     %o0, %o1, %o0
370         sethi   %hi(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE), %o1
371         st      %o0, [%lo(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE)+%o1]
372
373 /*      call    relocate*/
374         nop
375 /* Call relocated init functions */
376 jump:
377         set     cpu_init_f2,%o1
378         set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
379         add     %o1,%o2,%o1
380         sub     %o1,%g1,%o1
381         call    %o1
382         clr     %o0
383
384         set     board_init_f,%o1
385         set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
386         add     %o1,%o2,%o1
387         sub     %o1,%g1,%o1
388         call    %o1
389         clr     %o0
390
391 dead:   ta 0                            ! if call returns...
392         nop
393
394 /* Interrupt handler caller,
395  * reg L7: interrupt number
396  * reg L0: psr after interrupt
397  * reg L1: PC
398  * reg L2: next PC
399  * reg L3: wim
400  */
401 _irq_entry:
402         SAVE_ALL
403
404         or      %l0, PSR_PIL, %g2
405         wr      %g2, 0x0, %psr
406         WRITE_PAUSE
407         wr      %g2, PSR_ET, %psr
408         WRITE_PAUSE
409         mov     %l7, %o0                ! irq level
410         set     handler_irq, %o1
411         set     (CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE), %o2
412         add     %o1, %o2, %o1
413         call    %o1
414         add     %sp, SF_REGS_SZ, %o1    ! pt_regs ptr
415         or      %l0, PSR_PIL, %g2       ! restore PIL after handler_irq
416         wr      %g2, PSR_ET, %psr       ! keep ET up
417         WRITE_PAUSE
418
419         RESTORE_ALL
420
421 !Window overflow trap handler.
422         .global _window_overflow
423
424 _window_overflow:
425
426         mov     %wim, %l3               ! Calculate next WIM
427         mov     %g1, %l7
428         srl     %l3, 1, %g1
429         sll     %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4
430         or      %l4, %g1, %g1
431
432         save                            ! Get into window to be saved.
433         mov     %g1, %wim
434         nop;
435         nop;
436         nop
437         st      %l0, [%sp + 0];
438         st      %l1, [%sp + 4];
439         st      %l2, [%sp + 8];
440         st      %l3, [%sp + 12];
441         st      %l4, [%sp + 16];
442         st      %l5, [%sp + 20];
443         st      %l6, [%sp + 24];
444         st      %l7, [%sp + 28];
445         st      %i0, [%sp + 32];
446         st      %i1, [%sp + 36];
447         st      %i2, [%sp + 40];
448         st      %i3, [%sp + 44];
449         st      %i4, [%sp + 48];
450         st      %i5, [%sp + 52];
451         st      %i6, [%sp + 56];
452         st      %i7, [%sp + 60];
453         restore                         ! Go back to trap window.
454         mov     %l7, %g1
455         jmp     %l1                     ! Re-execute save.
456         rett    %l2
457
458 /* Window underflow trap handler.  */
459
460         .global  _window_underflow
461
462 _window_underflow:
463
464         mov  %wim, %l3                  ! Calculate next WIM
465         sll  %l3, 1, %l4
466         srl  %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5
467         or   %l5, %l4, %l5
468         mov  %l5, %wim
469         nop; nop; nop
470         restore                         ! Two restores to get into the
471         restore                         ! window to restore
472         ld      [%sp + 0], %l0;         ! Restore window from the stack
473         ld      [%sp + 4], %l1;
474         ld      [%sp + 8], %l2;
475         ld      [%sp + 12], %l3;
476         ld      [%sp + 16], %l4;
477         ld      [%sp + 20], %l5;
478         ld      [%sp + 24], %l6;
479         ld      [%sp + 28], %l7;
480         ld      [%sp + 32], %i0;
481         ld      [%sp + 36], %i1;
482         ld      [%sp + 40], %i2;
483         ld      [%sp + 44], %i3;
484         ld      [%sp + 48], %i4;
485         ld      [%sp + 52], %i5;
486         ld      [%sp + 56], %i6;
487         ld      [%sp + 60], %i7;
488         save                            ! Get back to the trap window.
489         save
490         jmp     %l1                     ! Re-execute restore.
491         rett    %l2
492
493         retl
494
495 _nmi_trap:
496         nop
497         jmp %l1
498         rett %l2
499
500 _hwerr:
501         ta 0
502         nop
503         nop
504         b _hwerr                        ! loop infinite
505         nop
506
507 /* Registers to not touch at all. */
508 #define t_psr      l0 /* Set by caller */
509 #define t_pc       l1 /* Set by caller */
510 #define t_npc      l2 /* Set by caller */
511 #define t_wim      l3 /* Set by caller */
512 #define t_twinmask l4 /* Set at beginning of this entry routine. */
513 #define t_kstack   l5 /* Set right before pt_regs frame is built */
514 #define t_retpc    l6 /* If you change this, change winmacro.h header file */
515 #define t_systable l7 /* Never touch this, could be the syscall table ptr. */
516 #define curptr     g6 /* Set after pt_regs frame is built */
517
518 trap_setup:
519 /* build a pt_regs trap frame. */
520         sub     %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
521         PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
522
523         /* See if we are in the trap window. */
524         mov     1, %t_twinmask
525         sll     %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
526         andcc   %t_twinmask, %t_wim, %g0
527         beq     1f              ! in trap window, clean up
528         nop
529
530         /*-------------------------------------------------
531          * Spill , adjust %wim and go.
532          */
533         srl     %t_wim, 0x1, %g2                ! begin computation of new %wim
534
535         set     (CONFIG_SYS_SPARC_NWINDOWS-1), %g3      !NWINDOWS-1
536
537         sll     %t_wim, %g3, %t_wim     ! NWINDOWS-1
538         or      %t_wim, %g2, %g2
539         and     %g2, 0xff, %g2
540
541         save    %g0, %g0, %g0           ! get in window to be saved
542
543         /* Set new %wim value */
544         wr      %g2, 0x0, %wim
545
546         /* Save the kernel window onto the corresponding stack. */
547         RW_STORE(sp)
548
549         restore %g0, %g0, %g0
550         /*-------------------------------------------------*/
551
552 1:
553         /* Trap from kernel with a window available.
554          * Just do it...
555          */
556         jmpl    %t_retpc + 0x8, %g0     ! return to caller
557          mov    %t_kstack, %sp          ! jump onto new stack
558
559 #define twin_tmp1 l4
560 #define glob_tmp  g4
561 #define curptr    g6
562 ret_trap_entry:
563         wr      %t_psr, 0x0, %psr       ! enable nesting again, clear ET
564
565         /* Will the rett land us in the invalid window? */
566         mov     2, %g1
567         sll     %g1, %t_psr, %g1
568
569         set     CONFIG_SYS_SPARC_NWINDOWS, %g2  !NWINDOWS
570
571         srl     %g1, %g2, %g2
572         or      %g1, %g2, %g1
573         rd      %wim, %g2
574         andcc   %g2, %g1, %g0
575         be      1f              ! Nope, just return from the trap
576          sll    %g2, 0x1, %g1
577
578         /* We have to grab a window before returning. */
579         set     (CONFIG_SYS_SPARC_NWINDOWS-1), %g3      !NWINDOWS-1
580
581         srl     %g2, %g3,  %g2
582         or      %g1, %g2, %g1
583         and     %g1, 0xff, %g1
584
585         wr      %g1, 0x0, %wim
586
587         /* Grrr, make sure we load from the right %sp... */
588         PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
589
590         restore %g0, %g0, %g0
591         RW_LOAD(sp)
592         b       2f
593         save    %g0, %g0, %g0
594
595         /* Reload the entire frame in case this is from a
596          * kernel system call or whatever...
597          */
598 1:
599         PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
600 2:
601         wr      %t_psr, 0x0, %psr
602         nop;
603         nop;
604         nop
605
606         jmp     %t_pc
607         rett    %t_npc
608
609 /* This is called from relocated C-code.
610  * It resets the system by jumping to _start
611  */
612 _reset_reloc:
613         set     start, %l0
614         call    %l0
615         nop