1/*
2 * Copyright (c) 2011 Aeroflex Gaisler
3 *
4 * BSD license:
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25
26#include <asm-leon/leonstack.h>
27#include <asm-leon/winmacros.h>
28
29/* Registers to not touch at all. */
30#define t_psr     l0
31#define t_pc      l1
32#define t_npc     l2
33#define t_wim     l3
34#define twin_tmp1 l4
35#define glob_tmp  g4
36#define curptr    g6
37
38	/* Number of register windows */
39	.global _nwindows_min1, _nwindows
40
41        .text
42	.align 4
43	.globl	leonbare_trapreturn_fast, schedule_callback
44
45
46/* rtap return special for irqtrap.S */
47leonbare_trapreturn_fast:
48
49        /* a optional scheduler can be called here */
50        set schedule_callback, %g2
51        ld [%g2], %g2
52        cmp %g2,%g0
53        beq 3f
54         nop
55
56        jmpl %g2,%o7
57#ifndef _SOFT_FLOAT
58	 add	%sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1	! pt_regs ptr
59#else
60	 add	%sp, SF_REGS_SZ , %o1		   ! pt_regs ptr
61#endif
62
633:
64
65#ifndef _SOFT_FLOAT
66	ld [%sp + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 4)],%g2
67	sethi %hi(fpustate_current), %g3
68	st %g2, [%g3+%lo(fpustate_current)]
69	sethi	%hi(fpustate_owner), %g3
70	ld	[%g3+%lo(fpustate_owner)], %g3
71	cmp	%g2, %g3
72	bne	didusefpu
73	 nop
74
75	/* avoid fpu exception */
76	ld 	[%sp + (SF_REGS_SZ + PT_REGS_SZ + FW_REGS_SZ - 8)], %g2
77	set	SPARC_PSR_EF_MASK, %g3
78	and 	%g2, %g3, %g2
79	andn	%t_psr, %g3, %t_psr
80	or	%t_psr, %g2, %t_psr
81	ba,a	1f
82
83didusefpu:
84	add 	%sp,SF_REGS_SZ + PT_REGS_SZ,%g2
85	cmp	%g2, %g3
86	bne	1f
87
88	sethi	%hi(fpustate_owner), %g3
89	st	%g0, [%g3+%lo(fpustate_owner)]
90
911:
92#endif
93
94	wr	%t_psr, 0x0, %psr       ! enable nesting again, clear ET
95
96#ifndef _FLAT
97	/* Will the rett land us in the invalid window? */
98	mov	2, %g1
99	sll	%g1, %t_psr, %g1
100
101	sethi %hi(_nwindows), %g2	!NWINDOWS
102	ld [%g2+%lo(_nwindows)], %g2
103
104       	srl	%g1, %g2, %g2
105	or	%g1, %g2, %g1
106	rd	%wim, %g2
107	andcc	%g2, %g1, %g0
108	be	1f		! Nope, just return from the trap
109	 sll	%g2, 0x1, %g1
110
111        	/* We have to grab a window before returning. */
112		sethi %hi(_nwindows_min1), %g3	!NWINDOWS-1
113		ld [%g3+%lo(_nwindows_min1)], %g3
114
115                srl	%g2, %g3,  %g2
116                or	%g1, %g2, %g1
117                and	%g1, 0xff, %g1
118
119                wr	%g1, 0x0, %wim
120
121        	/* Grrr, make sure we load from the right %sp... */
122                PT_LOAD_ALL_FAST(sp, t_psr, t_pc, t_npc, g1)
123
124        	restore	%g0, %g0, %g0
125                RW_LOAD(sp)
126                b	2f
127                 save	%g0, %g0, %g0
128
129	/* Reload the entire frame in case this is from a
130	 * kernel system call or whatever...
131	 */
1321:
133#endif
134 	PT_LOAD_ALL_FAST(sp, t_psr, t_pc, t_npc, g1)
135
1362:      /*PT_LOAD_GLOBALS(sp)*/
137
138#ifdef _FLAT
139	restore
140	RW_LOAD(sp)
141	save
142#endif
143
144	wr	%t_psr, 0x0, %psr
145	nop; nop; nop
146
147	jmp	%t_pc
148	rett	%t_npc
149
150
151
152
153
154#ifdef _FLAT
155#warning _FLAT not implemented
156#endif
157
158
159