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