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