1// SPDX-License-Identifier: GPL-2.0
2// Copyright (C) 2005-2017 Andes Technology Corporation
3
4#include <linux/linkage.h>
5#include <asm/memory.h>
6#include <asm/nds32.h>
7#include <asm/errno.h>
8#include <asm/asm-offsets.h>
9#include <asm/page.h>
10#include <asm/fpu.h>
11
12#ifdef CONFIG_HWZOL
13	.macro push_zol
14	mfusr	$r14, $LB
15	mfusr	$r15, $LE
16	mfusr	$r16, $LC
17	.endm
18#endif
19	.macro  skip_save_fucop_ctl
20#if defined(CONFIG_FPU)
21skip_fucop_ctl:
22	smw.adm $p0, [$sp], $p0, #0x1
23	j fucop_ctl_done
24#endif
25	.endm
26
27	.macro	save_user_regs
28#if defined(CONFIG_FPU)
29	sethi   $p0, hi20(has_fpu)
30	lbsi 	$p0, [$p0+lo12(has_fpu)]
31	beqz	$p0, skip_fucop_ctl
32	mfsr    $p0, $FUCOP_CTL
33	smw.adm $p0, [$sp], $p0, #0x1
34	bclr    $p0, $p0, #FUCOP_CTL_offCP0EN
35	mtsr    $p0, $FUCOP_CTL
36fucop_ctl_done:
37	/* move $SP to the bottom of pt_regs */
38	addi    $sp, $sp, -FUCOP_CTL_OFFSET
39#else
40	smw.adm $sp, [$sp], $sp, #0x1
41	/* move $SP to the bottom of pt_regs */
42	addi    $sp, $sp, -OSP_OFFSET
43#endif
44
45	/* push $r0 ~ $r25 */
46	smw.bim $r0, [$sp], $r25
47	/* push $fp, $gp, $lp */
48	smw.bim $sp, [$sp], $sp, #0xe
49
50	mfsr	$r12, $SP_USR
51	mfsr	$r13, $IPC
52#ifdef CONFIG_HWZOL
53	push_zol
54#endif
55	movi	$r17, -1
56	move	$r18, $r0
57	mfsr	$r19, $PSW
58	mfsr	$r20, $IPSW
59	mfsr	$r21, $P_IPSW
60	mfsr	$r22, $P_IPC
61	mfsr	$r23, $P_P0
62	mfsr	$r24, $P_P1
63	smw.bim $r12, [$sp], $r24, #0
64	addi	$sp, $sp, -FUCOP_CTL_OFFSET
65
66	/* Initialize kernel space $fp */
67	andi    $p0, $r20, #PSW_mskPOM
68	movi    $p1, #0x0
69	cmovz   $fp, $p1, $p0
70
71	andi	$r16, $r19, #PSW_mskINTL
72	slti	$r17, $r16, #4
73	bnez	$r17, 1f
74	addi	$r17, $r19, #-2
75	mtsr	$r17, $PSW
76	isb
771:
78	/* If it was superuser mode, we don't need to update $r25 */
79	bnez	$p0, 2f
80	la	$p0, __entry_task
81	lw	$r25, [$p0]
822:
83	.endm
84
85	.text
86
87/*
88 * Exception Vector
89 */
90exception_handlers:
91	.long	unhandled_exceptions	!Reset/NMI
92	.long	unhandled_exceptions	!TLB fill
93	.long	do_page_fault		!PTE not present
94	.long	do_dispatch_tlb_misc	!TLB misc
95	.long	unhandled_exceptions	!TLB VLPT
96	.long	unhandled_exceptions	!Machine Error
97	.long	do_debug_trap		!Debug related
98	.long	do_dispatch_general	!General exception
99	.long	eh_syscall		!Syscall
100	.long	asm_do_IRQ		!IRQ
101
102	skip_save_fucop_ctl
103common_exception_handler:
104	save_user_regs
105	mfsr	$p0, $ITYPE
106	andi	$p0, $p0, #ITYPE_mskVECTOR
107	srli	$p0, $p0, #ITYPE_offVECTOR
108	andi	$p1, $p0, #NDS32_VECTOR_mskNONEXCEPTION
109	bnez	$p1, 1f
110	sethi	$lp, hi20(ret_from_exception)
111	ori	$lp, $lp, lo12(ret_from_exception)
112	sethi	$p1, hi20(exception_handlers)
113	ori	$p1, $p1, lo12(exception_handlers)
114	lw	$p1, [$p1+$p0<<2]
115	move	$r0, $p0
116	mfsr	$r1, $EVA
117	mfsr	$r2, $ITYPE
118	move	$r3, $sp
119	mfsr    $r4, $OIPC
120	/* enable gie if it is enabled in IPSW. */
121	mfsr	$r21, $PSW
122	andi	$r20, $r20, #PSW_mskGIE	/* r20 is $IPSW*/
123	or	$r21, $r21, $r20
124	mtsr	$r21, $PSW
125	dsb
126	jr	$p1
127	/* syscall */
1281:
129	addi	$p1, $p0, #-NDS32_VECTOR_offEXCEPTION
130	bnez	$p1, 2f
131	sethi	$lp, hi20(ret_from_exception)
132	ori	$lp, $lp, lo12(ret_from_exception)
133	sethi	$p1, hi20(exception_handlers)
134	ori	$p1, $p1, lo12(exception_handlers)
135	lwi	$p1, [$p1+#NDS32_VECTOR_offEXCEPTION<<2]
136	jr	$p1
137
138	/* interrupt */
1392:
140#ifdef CONFIG_TRACE_IRQFLAGS
141	jal     __trace_hardirqs_off
142#endif
143	move	$r0, $sp
144	sethi	$lp, hi20(ret_from_intr)
145	ori	$lp, $lp, lo12(ret_from_intr)
146	sethi	$p0, hi20(exception_handlers)
147	ori	$p0, $p0, lo12(exception_handlers)
148	lwi	$p0, [$p0+#NDS32_VECTOR_offINTERRUPT<<2]
149	jr	$p0
150
151	.macro	EXCEPTION_VECTOR_DEBUG
152	.align 4
153	mfsr     $p0, $EDM_CTL
154	andi     $p0, $p0, EDM_CTL_mskV3_EDM_MODE
155	tnez     $p0, SWID_RAISE_INTERRUPT_LEVEL
156	.endm
157
158	.macro	EXCEPTION_VECTOR
159	.align 4
160	sethi	 $p0, hi20(common_exception_handler)
161	ori	 $p0, $p0, lo12(common_exception_handler)
162	jral.ton $p0, $p0
163	.endm
164
165	.section	".text.init", #alloc, #execinstr
166	.global	exception_vector
167exception_vector:
168.rept 6
169	EXCEPTION_VECTOR
170.endr
171	EXCEPTION_VECTOR_DEBUG
172.rept 121
173	EXCEPTION_VECTOR
174.endr
175	.align 4
176	.global	exception_vector_end
177exception_vector_end:
178