Commit | Line | Data |
---|---|---|
2923f5ea GH |
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> | |
e46bf83c | 10 | #include <asm/fpu.h> |
2923f5ea GH |
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 | |
e46bf83c VC |
19 | .macro skip_save_fucop_ctl |
20 | #if defined(CONFIG_FPU) | |
21 | skip_fucop_ctl: | |
22 | smw.adm $p0, [$sp], $p0, #0x1 | |
23 | j fucop_ctl_done | |
24 | #endif | |
25 | .endm | |
2923f5ea GH |
26 | |
27 | .macro save_user_regs | |
e46bf83c VC |
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 | |
36 | fucop_ctl_done: | |
37 | /* move $SP to the bottom of pt_regs */ | |
38 | addi $sp, $sp, -FUCOP_CTL_OFFSET | |
39 | #else | |
2923f5ea GH |
40 | smw.adm $sp, [$sp], $sp, #0x1 |
41 | /* move $SP to the bottom of pt_regs */ | |
42 | addi $sp, $sp, -OSP_OFFSET | |
e46bf83c | 43 | #endif |
2923f5ea GH |
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 | |
77 | 1: | |
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] | |
82 | 2: | |
83 | .endm | |
84 | ||
85 | .text | |
86 | ||
87 | /* | |
88 | * Exception Vector | |
89 | */ | |
90 | exception_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 | ||
e46bf83c | 102 | skip_save_fucop_ctl |
2923f5ea GH |
103 | common_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 | |
2923f5ea GH |
127 | /* syscall */ |
128 | 1: | |
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 */ | |
139 | 2: | |
140 | #ifdef CONFIG_TRACE_IRQFLAGS | |
0cde56e0 | 141 | jal __trace_hardirqs_off |
2923f5ea GH |
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 | |
167 | exception_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 | |
177 | exception_vector_end: |