]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/leon3/start.S
imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
[karo-tx-uboot.git] / 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 <config.h>
25 #include <asm/asmmacro.h>
26 #include <asm/winmacro.h>
27 #include <asm/psr.h>
28 #include <asm/stack.h>
29 #include <asm/leon.h>
30 #include <timestamp.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
204         .ascii " (", U_BOOT_DATE, " - ", U_BOOT_TIME, ")"
205         .ascii CONFIG_IDENT_STRING, "\0"
206
207         .section        ".text"
208         .align 4
209
210 _hardreset:
211 1000:
212         flush
213
214         /* Enable I/D-Cache and Snooping */
215         set     0x0081000f, %g2
216         sta     %g2, [%g0] 2
217
218         mov     %g0, %y
219         clr     %g1
220         clr     %g2
221         clr     %g3
222         clr     %g4
223         clr     %g5
224         clr     %g6
225         clr     %g7
226
227         mov     %asr17, %g3
228         and     %g3, 0x1f, %g3
229 clear_window:
230         mov     %g0, %l0
231         mov     %g0, %l1
232         mov     %g0, %l2
233         mov     %g0, %l3
234         mov     %g0, %l4
235         mov     %g0, %l5
236         mov     %g0, %l6
237         mov     %g0, %l7
238         mov     %g0, %o0
239         mov     %g0, %o1
240         mov     %g0, %o2
241         mov     %g0, %o3
242         mov     %g0, %o4
243         mov     %g0, %o5
244         mov     %g0, %o6
245         mov     %g0, %o7
246         subcc   %g3, 1, %g3
247         bge     clear_window
248         save
249
250 wininit:
251         set     WIM_INIT, %g3
252         mov     %g3, %wim
253
254 stackp:
255         set     CONFIG_SYS_INIT_SP_OFFSET, %fp
256         andn    %fp, 0x0f, %fp
257         sub     %fp, 64, %sp
258
259 cpu_init_unreloc:
260         call    cpu_init_f
261         nop
262
263 /* un relocated start address of monitor */
264 #define TEXT_START _text
265
266 /* un relocated end address of monitor */
267 #define DATA_END __init_end
268
269 reloc:
270         set     TEXT_START,%g2
271         set     DATA_END,%g3
272         set     CONFIG_SYS_RELOC_MONITOR_BASE,%g4
273 reloc_loop:
274         ldd     [%g2],%l0
275         ldd     [%g2+8],%l2
276         std     %l0,[%g4]
277         std     %l2,[%g4+8]
278         inc     16,%g2
279         subcc   %g3,%g2,%g0
280         bne     reloc_loop
281         inc     16,%g4
282
283         clr     %l0
284         clr     %l1
285         clr     %l2
286         clr     %l3
287         clr     %g2
288
289 /* register g4 contain address to start
290  * This means that BSS must be directly after data and code segments
291  *
292  * g3 is length of bss = (__bss_end-__bss_start)
293  *
294  */
295
296 clr_bss:
297 /* clear bss area (the relocated) */
298         set     __bss_start,%g2
299         set     __bss_end,%g3
300         sub     %g3,%g2,%g3
301         add     %g3,%g4,%g3
302         clr     %g1     /* std %g0 uses g0 and g1 */
303 /* clearing 16byte a time ==> linker script need to align to 16 byte offset */
304 clr_bss_16:
305         std     %g0,[%g4]
306         std     %g0,[%g4+8]
307         inc     16,%g4
308         cmp     %g3,%g4
309         bne     clr_bss_16
310         nop
311
312 /* add offsets to GOT table */
313 fixup_got:
314         set     __got_start,%g4
315         set     __got_end,%g3
316 /*
317  * new got offset = (old GOT-PTR (read with ld) -
318  *   CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
319  *   Destination Address (from define)
320  */
321         set     CONFIG_SYS_RELOC_MONITOR_BASE,%g2
322         set     TEXT_START, %g1
323         add     %g4,%g2,%g4
324         sub     %g4,%g1,%g4
325         add     %g3,%g2,%g3
326         sub     %g3,%g1,%g3
327         sub     %g2,%g1,%g2     ! prepare register with (new base address) -
328                                 !  (old base address)
329 got_loop:
330         ld      [%g4],%l0       ! load old GOT-PTR
331         add     %l0,%g2,%l0     ! increase with (new base address) -
332                                 !  (old base)
333         st      %l0,[%g4]
334         inc     4,%g4
335         cmp     %g3,%g4
336         bne     got_loop
337         nop
338
339 prom_relocate:
340         set     __prom_start, %g2
341         set     __prom_end, %g3
342         set     CONFIG_SYS_PROM_OFFSET, %g4
343
344 prom_relocate_loop:
345         ldd     [%g2],%l0
346         ldd     [%g2+8],%l2
347         std     %l0,[%g4]
348         std     %l2,[%g4+8]
349         inc     16,%g2
350         subcc   %g3,%g2,%g0
351         bne     prom_relocate_loop
352         inc     16,%g4
353
354 /* Trap table has been moved, lets tell CPU about
355  * the new trap table address
356  */
357
358         set     CONFIG_SYS_RELOC_MONITOR_BASE, %g2
359         wr      %g0, %g2, %tbr
360         nop
361         nop
362         nop
363
364 /* If CACHE snooping is available in hardware the
365  * variable leon3_snooping_avail will be set to
366  * 0x800000 else 0.
367  */
368 snoop_detect:
369         sethi   %hi(0x00800000), %o0
370         lda     [%g0] 2, %o1
371         and     %o0, %o1, %o0
372         sethi   %hi(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-TEXT_BASE), %o1
373         st      %o0, [%lo(leon3_snooping_avail+CONFIG_SYS_RELOC_MONITOR_BASE-TEXT_BASE)+%o1]
374
375 /*      call    relocate*/
376         nop
377 /* Call relocated init functions */
378 jump:
379         set     cpu_init_f2,%o1
380         set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
381         add     %o1,%o2,%o1
382         sub     %o1,%g1,%o1
383         call    %o1
384         clr     %o0
385
386         set     board_init_f,%o1
387         set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
388         add     %o1,%o2,%o1
389         sub     %o1,%g1,%o1
390         call    %o1
391         clr     %o0
392
393 dead:   ta 0                            ! if call returns...
394         nop
395
396 /* Interrupt handler caller,
397  * reg L7: interrupt number
398  * reg L0: psr after interrupt
399  * reg L1: PC
400  * reg L2: next PC
401  * reg L3: wim
402  */
403 _irq_entry:
404         SAVE_ALL
405
406         or      %l0, PSR_PIL, %g2
407         wr      %g2, 0x0, %psr
408         WRITE_PAUSE
409         wr      %g2, PSR_ET, %psr
410         WRITE_PAUSE
411         mov     %l7, %o0                ! irq level
412         set     handler_irq, %o1
413         set     (CONFIG_SYS_RELOC_MONITOR_BASE-TEXT_BASE), %o2
414         add     %o1, %o2, %o1
415         call    %o1
416         add     %sp, SF_REGS_SZ, %o1    ! pt_regs ptr
417         or      %l0, PSR_PIL, %g2       ! restore PIL after handler_irq
418         wr      %g2, PSR_ET, %psr       ! keep ET up
419         WRITE_PAUSE
420
421         RESTORE_ALL
422
423 !Window overflow trap handler.
424         .global _window_overflow
425
426 _window_overflow:
427
428         mov     %wim, %l3               ! Calculate next WIM
429         mov     %g1, %l7
430         srl     %l3, 1, %g1
431         sll     %l3, (CONFIG_SYS_SPARC_NWINDOWS-1) , %l4
432         or      %l4, %g1, %g1
433
434         save                            ! Get into window to be saved.
435         mov     %g1, %wim
436         nop;
437         nop;
438         nop
439         st      %l0, [%sp + 0];
440         st      %l1, [%sp + 4];
441         st      %l2, [%sp + 8];
442         st      %l3, [%sp + 12];
443         st      %l4, [%sp + 16];
444         st      %l5, [%sp + 20];
445         st      %l6, [%sp + 24];
446         st      %l7, [%sp + 28];
447         st      %i0, [%sp + 32];
448         st      %i1, [%sp + 36];
449         st      %i2, [%sp + 40];
450         st      %i3, [%sp + 44];
451         st      %i4, [%sp + 48];
452         st      %i5, [%sp + 52];
453         st      %i6, [%sp + 56];
454         st      %i7, [%sp + 60];
455         restore                         ! Go back to trap window.
456         mov     %l7, %g1
457         jmp     %l1                     ! Re-execute save.
458         rett    %l2
459
460 /* Window underflow trap handler.  */
461
462         .global  _window_underflow
463
464 _window_underflow:
465
466         mov  %wim, %l3                  ! Calculate next WIM
467         sll  %l3, 1, %l4
468         srl  %l3, (CONFIG_SYS_SPARC_NWINDOWS-1), %l5
469         or   %l5, %l4, %l5
470         mov  %l5, %wim
471         nop; nop; nop
472         restore                         ! Two restores to get into the
473         restore                         ! window to restore
474         ld      [%sp + 0], %l0;         ! Restore window from the stack
475         ld      [%sp + 4], %l1;
476         ld      [%sp + 8], %l2;
477         ld      [%sp + 12], %l3;
478         ld      [%sp + 16], %l4;
479         ld      [%sp + 20], %l5;
480         ld      [%sp + 24], %l6;
481         ld      [%sp + 28], %l7;
482         ld      [%sp + 32], %i0;
483         ld      [%sp + 36], %i1;
484         ld      [%sp + 40], %i2;
485         ld      [%sp + 44], %i3;
486         ld      [%sp + 48], %i4;
487         ld      [%sp + 52], %i5;
488         ld      [%sp + 56], %i6;
489         ld      [%sp + 60], %i7;
490         save                            ! Get back to the trap window.
491         save
492         jmp     %l1                     ! Re-execute restore.
493         rett    %l2
494
495         retl
496
497 _nmi_trap:
498         nop
499         jmp %l1
500         rett %l2
501
502 _hwerr:
503         ta 0
504         nop
505         nop
506         b _hwerr                        ! loop infinite
507         nop
508
509 /* Registers to not touch at all. */
510 #define t_psr      l0 /* Set by caller */
511 #define t_pc       l1 /* Set by caller */
512 #define t_npc      l2 /* Set by caller */
513 #define t_wim      l3 /* Set by caller */
514 #define t_twinmask l4 /* Set at beginning of this entry routine. */
515 #define t_kstack   l5 /* Set right before pt_regs frame is built */
516 #define t_retpc    l6 /* If you change this, change winmacro.h header file */
517 #define t_systable l7 /* Never touch this, could be the syscall table ptr. */
518 #define curptr     g6 /* Set after pt_regs frame is built */
519
520 trap_setup:
521 /* build a pt_regs trap frame. */
522         sub     %fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
523         PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
524
525         /* See if we are in the trap window. */
526         mov     1, %t_twinmask
527         sll     %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
528         andcc   %t_twinmask, %t_wim, %g0
529         beq     1f              ! in trap window, clean up
530         nop
531
532         /*-------------------------------------------------
533          * Spill , adjust %wim and go.
534          */
535         srl     %t_wim, 0x1, %g2                ! begin computation of new %wim
536
537         set     (CONFIG_SYS_SPARC_NWINDOWS-1), %g3      !NWINDOWS-1
538
539         sll     %t_wim, %g3, %t_wim     ! NWINDOWS-1
540         or      %t_wim, %g2, %g2
541         and     %g2, 0xff, %g2
542
543         save    %g0, %g0, %g0           ! get in window to be saved
544
545         /* Set new %wim value */
546         wr      %g2, 0x0, %wim
547
548         /* Save the kernel window onto the corresponding stack. */
549         RW_STORE(sp)
550
551         restore %g0, %g0, %g0
552         /*-------------------------------------------------*/
553
554 1:
555         /* Trap from kernel with a window available.
556          * Just do it...
557          */
558         jmpl    %t_retpc + 0x8, %g0     ! return to caller
559          mov    %t_kstack, %sp          ! jump onto new stack
560
561 #define twin_tmp1 l4
562 #define glob_tmp  g4
563 #define curptr    g6
564 ret_trap_entry:
565         wr      %t_psr, 0x0, %psr       ! enable nesting again, clear ET
566
567         /* Will the rett land us in the invalid window? */
568         mov     2, %g1
569         sll     %g1, %t_psr, %g1
570
571         set     CONFIG_SYS_SPARC_NWINDOWS, %g2  !NWINDOWS
572
573         srl     %g1, %g2, %g2
574         or      %g1, %g2, %g1
575         rd      %wim, %g2
576         andcc   %g2, %g1, %g0
577         be      1f              ! Nope, just return from the trap
578          sll    %g2, 0x1, %g1
579
580         /* We have to grab a window before returning. */
581         set     (CONFIG_SYS_SPARC_NWINDOWS-1), %g3      !NWINDOWS-1
582
583         srl     %g2, %g3,  %g2
584         or      %g1, %g2, %g1
585         and     %g1, 0xff, %g1
586
587         wr      %g1, 0x0, %wim
588
589         /* Grrr, make sure we load from the right %sp... */
590         PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
591
592         restore %g0, %g0, %g0
593         RW_LOAD(sp)
594         b       2f
595         save    %g0, %g0, %g0
596
597         /* Reload the entire frame in case this is from a
598          * kernel system call or whatever...
599          */
600 1:
601         PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
602 2:
603         wr      %t_psr, 0x0, %psr
604         nop;
605         nop;
606         nop
607
608         jmp     %t_pc
609         rett    %t_npc
610
611 /* This is called from relocated C-code.
612  * It resets the system by jumping to _start
613  */
614 _reset_reloc:
615         set     start, %l0
616         call    %l0
617         nop