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/asmmacro.h>
28#include <asm-leon/winmacros.h>
29#include <asm-leon/leon.h>
30
31	/* l0: psr
32	   l1: pc
33	   l2: npc
34	   l3: wim
35	   l7: irqnr */
36
37  	.seg    "text"
38
39	/* ------- */
40  	.weak	_leonbare_irq_entry_svt
41	.set	_leonbare_irq_entry_svt,__leonbare_irq_entry_svt
42  	.weak	leonbare_irq_entry
43	.set	leonbare_irq_entry,_leonbare_irq_entry
44	/* ------- */
45        !.global leonbare_irq_entry,_leonbare_irq_entry_svt
46        .global _irqtbl, _irqtrap, handler_irq, fpustate_current
47
48__leonbare_irq_entry_svt:	 /* irq from svt trap dispatcher */
49	sub %l6,0x10, %l7
50	rd %wim, %l3
51
52_leonbare_irq_entry:
53	set	SPARC_PSR_EF_MASK,%l6
54	andn	%l0, %l6, %l0	                   ! fpu off
55
56	SAVE_ALL
57
58	set     nestcount,%o0
59	ld      [%o0],%o1
60	add	%o1,1,%o1
61	st      %o1,[%o0]
62
63#ifdef CONFIG_LEONBARE_NONESTEDIRQ
64        or	%l0, SPARC_PSR_PIL_MASK, %o0       ! no nested irqs
65	wr	%o0, SPARC_PSR_ET_MASK, %psr
66	WRITE_PAUSE
67#else
68	sll     %l7,SPARC_PSR_PIL_SHIFT,%o1
69	andn	%l0,SPARC_PSR_PIL_MASK,%o0
70	or	%l0, %o1, %o1
71	set     nestedirq,%o0
72	ld      [%o0],%o0
73        cmp     %g0,%o0                            ! no nested irqs?
74	beq,a   .L1
75        or	%o1, SPARC_PSR_PIL_MASK, %o1
76.L1:
77	wr	%o1, SPARC_PSR_ET_MASK, %psr
78	WRITE_PAUSE
79#endif
80
81        mov	%l7, %o0                           ! irq level
82        call	handler_irq                        ! void handler_irq (int irq, struct leonbare_pt_regs *pt_regs)
83#ifndef _SOFT_FLOAT
84	 add	%sp, FW_REGS_SZ + 8 + SF_REGS_SZ , %o1	! pt_regs ptr
85#else
86	 add	%sp, SF_REGS_SZ , %o1		   ! pt_regs ptr
87#endif
88
89	or      %l0, SPARC_PSR_PIL_MASK, %o1
90	wr	%o1, SPARC_PSR_ET_MASK, %psr	   ! enable nesting again, keep ET up
91	WRITE_PAUSE
92
93	set     nestcount,%o0
94	ld      [%o0],%o1
95	sub	%o1,1,%o1
96	st      %o1,[%o0]
97
98	RESTORE_ALL
99
100        .seg    "data"
101        .global nestedirq
102	.align  4
103nestedirq:
104        .long   0
105        .global nestcount
106	.align  4
107nestcount:
108        .long   0
109