Commit | Line | Data |
---|---|---|
081860b9 GR |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. | |
3 | ||
4 | #include <linux/linkage.h> | |
5 | #include <abi/entry.h> | |
6 | #include <abi/pgtable-bits.h> | |
7 | #include <asm/errno.h> | |
8 | #include <asm/setup.h> | |
9 | #include <asm/unistd.h> | |
10 | #include <asm/asm-offsets.h> | |
11 | #include <linux/threads.h> | |
081860b9 GR |
12 | #include <asm/page.h> |
13 | #include <asm/thread_info.h> | |
14 | ||
48ede51f GR |
15 | .macro zero_fp |
16 | #ifdef CONFIG_STACKTRACE | |
17 | movi r8, 0 | |
18 | #endif | |
19 | .endm | |
20 | ||
bdcd93ef | 21 | .macro context_tracking |
24a9c541 | 22 | #ifdef CONFIG_CONTEXT_TRACKING_USER |
bdcd93ef GR |
23 | mfcr a0, epsr |
24 | btsti a0, 31 | |
25 | bt 1f | |
f163f030 | 26 | jbsr user_exit_callable |
bdcd93ef GR |
27 | ldw a0, (sp, LSAVE_A0) |
28 | ldw a1, (sp, LSAVE_A1) | |
29 | ldw a2, (sp, LSAVE_A2) | |
30 | ldw a3, (sp, LSAVE_A3) | |
31 | #if defined(__CSKYABIV1__) | |
32 | ldw r6, (sp, LSAVE_A4) | |
33 | ldw r7, (sp, LSAVE_A5) | |
34 | #endif | |
35 | 1: | |
36 | #endif | |
37 | .endm | |
38 | ||
b0ae5e26 GR |
39 | .text |
40 | ENTRY(csky_pagefault) | |
bf241682 | 41 | SAVE_ALL 0 |
48ede51f | 42 | zero_fp |
bdcd93ef | 43 | context_tracking |
0f7e8efa | 44 | psrset ee |
081860b9 | 45 | mov a0, sp |
081860b9 | 46 | jbsr do_page_fault |
081860b9 | 47 | jmpi ret_from_exception |
081860b9 GR |
48 | |
49 | ENTRY(csky_systemcall) | |
bf241682 | 50 | SAVE_ALL TRAP0_SIZE |
48ede51f | 51 | zero_fp |
bdcd93ef | 52 | context_tracking |
081860b9 GR |
53 | psrset ee, ie |
54 | ||
20f69538 GR |
55 | lrw r9, __NR_syscalls |
56 | cmphs syscallid, r9 /* Check nr of syscall */ | |
c5e7ee72 | 57 | bt ret_from_exception |
081860b9 | 58 | |
20f69538 GR |
59 | lrw r9, sys_call_table |
60 | ixw r9, syscallid | |
61 | ldw syscallid, (r9) | |
62 | cmpnei syscallid, 0 | |
081860b9 GR |
63 | bf ret_from_exception |
64 | ||
65 | mov r9, sp | |
66 | bmaski r10, THREAD_SHIFT | |
67 | andn r9, r10 | |
20f69538 GR |
68 | ldw r10, (r9, TINFO_FLAGS) |
69 | lrw r9, _TIF_SYSCALL_WORK | |
70 | and r10, r9 | |
71 | cmpnei r10, 0 | |
2f7932b0 | 72 | bt csky_syscall_trace |
081860b9 GR |
73 | #if defined(__CSKYABIV2__) |
74 | subi sp, 8 | |
75 | stw r5, (sp, 0x4) | |
76 | stw r4, (sp, 0x0) | |
20f69538 | 77 | jsr syscallid /* Do system call */ |
081860b9 GR |
78 | addi sp, 8 |
79 | #else | |
20f69538 | 80 | jsr syscallid |
081860b9 GR |
81 | #endif |
82 | stw a0, (sp, LSAVE_A0) /* Save return value */ | |
83 | jmpi ret_from_exception | |
84 | ||
2f7932b0 GR |
85 | csky_syscall_trace: |
86 | mov a0, sp /* sp = pt_regs pointer */ | |
87 | jbsr syscall_trace_enter | |
e95a4f8c GR |
88 | cmpnei a0, 0 |
89 | bt 1f | |
081860b9 GR |
90 | /* Prepare args before do system call */ |
91 | ldw a0, (sp, LSAVE_A0) | |
92 | ldw a1, (sp, LSAVE_A1) | |
93 | ldw a2, (sp, LSAVE_A2) | |
94 | ldw a3, (sp, LSAVE_A3) | |
95 | #if defined(__CSKYABIV2__) | |
96 | subi sp, 8 | |
e0bbb538 GR |
97 | ldw r9, (sp, LSAVE_A4) |
98 | stw r9, (sp, 0x0) | |
99 | ldw r9, (sp, LSAVE_A5) | |
100 | stw r9, (sp, 0x4) | |
20f69538 GR |
101 | jsr syscallid /* Do system call */ |
102 | addi sp, 8 | |
081860b9 GR |
103 | #else |
104 | ldw r6, (sp, LSAVE_A4) | |
105 | ldw r7, (sp, LSAVE_A5) | |
20f69538 | 106 | jsr syscallid /* Do system call */ |
081860b9 GR |
107 | #endif |
108 | stw a0, (sp, LSAVE_A0) /* Save return value */ | |
109 | ||
e95a4f8c | 110 | 1: |
2f7932b0 GR |
111 | mov a0, sp /* right now, sp --> pt_regs */ |
112 | jbsr syscall_trace_exit | |
31295a72 | 113 | br ret_from_exception |
081860b9 GR |
114 | |
115 | ENTRY(ret_from_kernel_thread) | |
116 | jbsr schedule_tail | |
48ede51f | 117 | mov a0, r10 |
081860b9 GR |
118 | jsr r9 |
119 | jbsr ret_from_exception | |
120 | ||
121 | ENTRY(ret_from_fork) | |
122 | jbsr schedule_tail | |
123 | mov r9, sp | |
124 | bmaski r10, THREAD_SHIFT | |
125 | andn r9, r10 | |
20f69538 GR |
126 | ldw r10, (r9, TINFO_FLAGS) |
127 | lrw r9, _TIF_SYSCALL_WORK | |
128 | and r10, r9 | |
129 | cmpnei r10, 0 | |
bf241682 | 130 | bf ret_from_exception |
2f7932b0 GR |
131 | mov a0, sp /* sp = pt_regs pointer */ |
132 | jbsr syscall_trace_exit | |
081860b9 GR |
133 | |
134 | ret_from_exception: | |
90089759 | 135 | psrclr ie |
20f69538 GR |
136 | ld r9, (sp, LSAVE_PSR) |
137 | btsti r9, 31 | |
081860b9 | 138 | |
20f69538 | 139 | bt 1f |
081860b9 GR |
140 | /* |
141 | * Load address of current->thread_info, Then get address of task_struct | |
142 | * Get task_needreshed in task_struct | |
143 | */ | |
144 | mov r9, sp | |
145 | bmaski r10, THREAD_SHIFT | |
146 | andn r9, r10 | |
147 | ||
20f69538 GR |
148 | ldw r10, (r9, TINFO_FLAGS) |
149 | lrw r9, _TIF_WORK_MASK | |
150 | and r10, r9 | |
151 | cmpnei r10, 0 | |
081860b9 | 152 | bt exit_work |
24a9c541 | 153 | #ifdef CONFIG_CONTEXT_TRACKING_USER |
f163f030 | 154 | jbsr user_enter_callable |
bdcd93ef | 155 | #endif |
bf241682 | 156 | 1: |
90089759 | 157 | #ifdef CONFIG_PREEMPTION |
20f69538 GR |
158 | mov r9, sp |
159 | bmaski r10, THREAD_SHIFT | |
160 | andn r9, r10 | |
161 | ||
162 | ldw r10, (r9, TINFO_PREEMPT) | |
163 | cmpnei r10, 0 | |
90089759 GR |
164 | bt 2f |
165 | jbsr preempt_schedule_irq /* irq en/disable is done inside */ | |
166 | 2: | |
167 | #endif | |
168 | ||
000591f1 GR |
169 | #ifdef CONFIG_TRACE_IRQFLAGS |
170 | ld r10, (sp, LSAVE_PSR) | |
171 | btsti r10, 6 | |
172 | bf 2f | |
173 | jbsr trace_hardirqs_on | |
174 | 2: | |
175 | #endif | |
bf241682 | 176 | RESTORE_ALL |
081860b9 GR |
177 | |
178 | exit_work: | |
20f69538 GR |
179 | lrw r9, ret_from_exception |
180 | mov lr, r9 | |
bf241682 | 181 | |
20f69538 | 182 | btsti r10, TIF_NEED_RESCHED |
081860b9 | 183 | bt work_resched |
bf241682 | 184 | |
90089759 | 185 | psrset ie |
bf241682 | 186 | mov a0, sp |
20f69538 | 187 | mov a1, r10 |
bf241682 | 188 | jmpi do_notify_resume |
081860b9 GR |
189 | |
190 | work_resched: | |
081860b9 GR |
191 | jmpi schedule |
192 | ||
081860b9 | 193 | ENTRY(csky_trap) |
bf241682 | 194 | SAVE_ALL 0 |
48ede51f | 195 | zero_fp |
bdcd93ef | 196 | context_tracking |
081860b9 | 197 | psrset ee |
081860b9 GR |
198 | mov a0, sp /* Push Stack pointer arg */ |
199 | jbsr trap_c /* Call C-level trap handler */ | |
200 | jmpi ret_from_exception | |
201 | ||
202 | /* | |
203 | * Prototype from libc for abiv1: | |
204 | * register unsigned int __result asm("a0"); | |
205 | * asm( "trap 3" :"=r"(__result)::); | |
206 | */ | |
207 | ENTRY(csky_get_tls) | |
208 | USPTOKSP | |
209 | ||
0c8a32ee GR |
210 | RD_MEH a0 |
211 | WR_MEH a0 | |
212 | ||
081860b9 GR |
213 | /* increase epc for continue */ |
214 | mfcr a0, epc | |
bf241682 | 215 | addi a0, TRAP0_SIZE |
081860b9 GR |
216 | mtcr a0, epc |
217 | ||
218 | /* get current task thread_info with kernel 8K stack */ | |
219 | bmaski a0, THREAD_SHIFT | |
220 | not a0 | |
221 | subi sp, 1 | |
222 | and a0, sp | |
223 | addi sp, 1 | |
224 | ||
225 | /* get tls */ | |
226 | ldw a0, (a0, TINFO_TP_VALUE) | |
227 | ||
228 | KSPTOUSP | |
229 | rte | |
230 | ||
231 | ENTRY(csky_irq) | |
bf241682 | 232 | SAVE_ALL 0 |
48ede51f | 233 | zero_fp |
bdcd93ef | 234 | context_tracking |
081860b9 | 235 | psrset ee |
081860b9 | 236 | |
000591f1 GR |
237 | #ifdef CONFIG_TRACE_IRQFLAGS |
238 | jbsr trace_hardirqs_off | |
239 | #endif | |
240 | ||
081860b9 GR |
241 | |
242 | mov a0, sp | |
28723298 | 243 | jbsr generic_handle_arch_irq |
081860b9 | 244 | |
081860b9 GR |
245 | jmpi ret_from_exception |
246 | ||
247 | /* | |
248 | * a0 = prev task_struct * | |
249 | * a1 = next task_struct * | |
250 | * a0 = return next | |
251 | */ | |
252 | ENTRY(__switch_to) | |
253 | lrw a3, TASK_THREAD | |
254 | addu a3, a0 | |
255 | ||
081860b9 GR |
256 | SAVE_SWITCH_STACK |
257 | ||
258 | stw sp, (a3, THREAD_KSP) | |
259 | ||
081860b9 GR |
260 | /* Set up next process to run */ |
261 | lrw a3, TASK_THREAD | |
262 | addu a3, a1 | |
263 | ||
264 | ldw sp, (a3, THREAD_KSP) /* Set next kernel sp */ | |
265 | ||
081860b9 | 266 | #if defined(__CSKYABIV2__) |
9e2ca153 GR |
267 | addi a3, a1, TASK_THREAD_INFO |
268 | ldw tls, (a3, TINFO_TP_VALUE) | |
081860b9 GR |
269 | #endif |
270 | ||
271 | RESTORE_SWITCH_STACK | |
272 | ||
273 | rts | |
274 | ENDPROC(__switch_to) |