diff options
author | Michal Simek <monstr@monstr.eu> | 2009-03-27 09:25:20 -0400 |
---|---|---|
committer | Michal Simek <monstr@monstr.eu> | 2009-03-27 09:25:20 -0400 |
commit | 6d5af1a35f363d3bca7ecb4560102ff94f792186 (patch) | |
tree | 2f29b58ede496174da801b2d5d522f506814f98d /arch/microblaze/kernel/entry-nommu.S | |
parent | 2d43dab99a5387c9bac22fc92e88ae3754672e19 (diff) |
microblaze_v8: assembler files head.S, entry-nommu.S, syscall_table.S
Reviewed-by: Ingo Molnar <mingo@elte.hu>
Acked-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
Acked-by: John Linn <john.linn@xilinx.com>
Acked-by: John Williams <john.williams@petalogix.com>
Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/kernel/entry-nommu.S')
-rw-r--r-- | arch/microblaze/kernel/entry-nommu.S | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S new file mode 100644 index 000000000000..f24b1268baaf --- /dev/null +++ b/arch/microblaze/kernel/entry-nommu.S | |||
@@ -0,0 +1,596 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
4 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <asm/thread_info.h> | ||
13 | #include <asm/errno.h> | ||
14 | #include <asm/entry.h> | ||
15 | #include <asm/asm-offsets.h> | ||
16 | #include <asm/registers.h> | ||
17 | #include <asm/unistd.h> | ||
18 | #include <asm/percpu.h> | ||
19 | #include <asm/signal.h> | ||
20 | |||
21 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
22 | .macro disable_irq | ||
23 | msrclr r0, MSR_IE | ||
24 | .endm | ||
25 | |||
26 | .macro enable_irq | ||
27 | msrset r0, MSR_IE | ||
28 | .endm | ||
29 | |||
30 | .macro clear_bip | ||
31 | msrclr r0, MSR_BIP | ||
32 | .endm | ||
33 | #else | ||
34 | .macro disable_irq | ||
35 | mfs r11, rmsr | ||
36 | andi r11, r11, ~MSR_IE | ||
37 | mts rmsr, r11 | ||
38 | .endm | ||
39 | |||
40 | .macro enable_irq | ||
41 | mfs r11, rmsr | ||
42 | ori r11, r11, MSR_IE | ||
43 | mts rmsr, r11 | ||
44 | .endm | ||
45 | |||
46 | .macro clear_bip | ||
47 | mfs r11, rmsr | ||
48 | andi r11, r11, ~MSR_BIP | ||
49 | mts rmsr, r11 | ||
50 | .endm | ||
51 | #endif | ||
52 | |||
53 | ENTRY(_interrupt) | ||
54 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | ||
55 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
56 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
57 | beqid r11, 1f | ||
58 | nop | ||
59 | brid 2f /* jump over */ | ||
60 | addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */ | ||
61 | 1: /* switch to kernel stack */ | ||
62 | lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | ||
63 | lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | ||
64 | /* calculate kernel stack pointer */ | ||
65 | addik r1, r1, THREAD_SIZE - PT_SIZE | ||
66 | 2: | ||
67 | swi r11, r1, PT_MODE /* store the mode */ | ||
68 | lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | ||
69 | swi r2, r1, PT_R2 | ||
70 | swi r3, r1, PT_R3 | ||
71 | swi r4, r1, PT_R4 | ||
72 | swi r5, r1, PT_R5 | ||
73 | swi r6, r1, PT_R6 | ||
74 | swi r7, r1, PT_R7 | ||
75 | swi r8, r1, PT_R8 | ||
76 | swi r9, r1, PT_R9 | ||
77 | swi r10, r1, PT_R10 | ||
78 | swi r11, r1, PT_R11 | ||
79 | swi r12, r1, PT_R12 | ||
80 | swi r13, r1, PT_R13 | ||
81 | swi r14, r1, PT_R14 | ||
82 | swi r14, r1, PT_PC | ||
83 | swi r15, r1, PT_R15 | ||
84 | swi r16, r1, PT_R16 | ||
85 | swi r17, r1, PT_R17 | ||
86 | swi r18, r1, PT_R18 | ||
87 | swi r19, r1, PT_R19 | ||
88 | swi r20, r1, PT_R20 | ||
89 | swi r21, r1, PT_R21 | ||
90 | swi r22, r1, PT_R22 | ||
91 | swi r23, r1, PT_R23 | ||
92 | swi r24, r1, PT_R24 | ||
93 | swi r25, r1, PT_R25 | ||
94 | swi r26, r1, PT_R26 | ||
95 | swi r27, r1, PT_R27 | ||
96 | swi r28, r1, PT_R28 | ||
97 | swi r29, r1, PT_R29 | ||
98 | swi r30, r1, PT_R30 | ||
99 | swi r31, r1, PT_R31 | ||
100 | /* special purpose registers */ | ||
101 | mfs r11, rmsr | ||
102 | swi r11, r1, PT_MSR | ||
103 | mfs r11, rear | ||
104 | swi r11, r1, PT_EAR | ||
105 | mfs r11, resr | ||
106 | swi r11, r1, PT_ESR | ||
107 | mfs r11, rfsr | ||
108 | swi r11, r1, PT_FSR | ||
109 | /* reload original stack pointer and save it */ | ||
110 | lwi r11, r0, PER_CPU(ENTRY_SP) | ||
111 | swi r11, r1, PT_R1 | ||
112 | /* update mode indicator we are in kernel mode */ | ||
113 | addik r11, r0, 1 | ||
114 | swi r11, r0, PER_CPU(KM) | ||
115 | /* restore r31 */ | ||
116 | lwi r31, r0, PER_CPU(CURRENT_SAVE) | ||
117 | /* prepare the link register, the argument and jump */ | ||
118 | la r15, r0, ret_from_intr - 8 | ||
119 | addk r6, r0, r15 | ||
120 | braid do_IRQ | ||
121 | add r5, r0, r1 | ||
122 | |||
123 | ret_from_intr: | ||
124 | lwi r11, r1, PT_MODE | ||
125 | bneid r11, 3f | ||
126 | |||
127 | lwi r6, r31, TS_THREAD_INFO /* get thread info */ | ||
128 | lwi r19, r6, TI_FLAGS /* get flags in thread info */ | ||
129 | /* do an extra work if any bits are set */ | ||
130 | |||
131 | andi r11, r19, _TIF_NEED_RESCHED | ||
132 | beqi r11, 1f | ||
133 | bralid r15, schedule | ||
134 | nop | ||
135 | 1: andi r11, r19, _TIF_SIGPENDING | ||
136 | beqid r11, no_intr_reshed | ||
137 | addk r5, r1, r0 | ||
138 | addk r7, r0, r0 | ||
139 | bralid r15, do_signal | ||
140 | addk r6, r0, r0 | ||
141 | |||
142 | no_intr_reshed: | ||
143 | /* save mode indicator */ | ||
144 | lwi r11, r1, PT_MODE | ||
145 | 3: | ||
146 | swi r11, r0, PER_CPU(KM) | ||
147 | |||
148 | /* save r31 */ | ||
149 | swi r31, r0, PER_CPU(CURRENT_SAVE) | ||
150 | restore_context: | ||
151 | /* special purpose registers */ | ||
152 | lwi r11, r1, PT_FSR | ||
153 | mts rfsr, r11 | ||
154 | lwi r11, r1, PT_ESR | ||
155 | mts resr, r11 | ||
156 | lwi r11, r1, PT_EAR | ||
157 | mts rear, r11 | ||
158 | lwi r11, r1, PT_MSR | ||
159 | mts rmsr, r11 | ||
160 | |||
161 | lwi r31, r1, PT_R31 | ||
162 | lwi r30, r1, PT_R30 | ||
163 | lwi r29, r1, PT_R29 | ||
164 | lwi r28, r1, PT_R28 | ||
165 | lwi r27, r1, PT_R27 | ||
166 | lwi r26, r1, PT_R26 | ||
167 | lwi r25, r1, PT_R25 | ||
168 | lwi r24, r1, PT_R24 | ||
169 | lwi r23, r1, PT_R23 | ||
170 | lwi r22, r1, PT_R22 | ||
171 | lwi r21, r1, PT_R21 | ||
172 | lwi r20, r1, PT_R20 | ||
173 | lwi r19, r1, PT_R19 | ||
174 | lwi r18, r1, PT_R18 | ||
175 | lwi r17, r1, PT_R17 | ||
176 | lwi r16, r1, PT_R16 | ||
177 | lwi r15, r1, PT_R15 | ||
178 | lwi r14, r1, PT_PC | ||
179 | lwi r13, r1, PT_R13 | ||
180 | lwi r12, r1, PT_R12 | ||
181 | lwi r11, r1, PT_R11 | ||
182 | lwi r10, r1, PT_R10 | ||
183 | lwi r9, r1, PT_R9 | ||
184 | lwi r8, r1, PT_R8 | ||
185 | lwi r7, r1, PT_R7 | ||
186 | lwi r6, r1, PT_R6 | ||
187 | lwi r5, r1, PT_R5 | ||
188 | lwi r4, r1, PT_R4 | ||
189 | lwi r3, r1, PT_R3 | ||
190 | lwi r2, r1, PT_R2 | ||
191 | lwi r1, r1, PT_R1 | ||
192 | rtid r14, 0 | ||
193 | nop | ||
194 | |||
195 | ENTRY(_reset) | ||
196 | brai 0; | ||
197 | |||
198 | ENTRY(_user_exception) | ||
199 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | ||
200 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
201 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
202 | beqid r11, 1f /* Already in kernel mode? */ | ||
203 | nop | ||
204 | brid 2f /* jump over */ | ||
205 | addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */ | ||
206 | 1: /* Switch to kernel stack */ | ||
207 | lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | ||
208 | lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | ||
209 | /* calculate kernel stack pointer */ | ||
210 | addik r1, r1, THREAD_SIZE - PT_SIZE | ||
211 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
212 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
213 | 2: | ||
214 | swi r11, r1, PT_MODE /* store the mode */ | ||
215 | lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | ||
216 | /* save them on stack */ | ||
217 | swi r2, r1, PT_R2 | ||
218 | swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ | ||
219 | swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ | ||
220 | swi r5, r1, PT_R5 | ||
221 | swi r6, r1, PT_R6 | ||
222 | swi r7, r1, PT_R7 | ||
223 | swi r8, r1, PT_R8 | ||
224 | swi r9, r1, PT_R9 | ||
225 | swi r10, r1, PT_R10 | ||
226 | swi r11, r1, PT_R11 | ||
227 | /* r12: _always_ in clobber list; see unistd.h */ | ||
228 | swi r12, r1, PT_R12 | ||
229 | swi r13, r1, PT_R13 | ||
230 | /* r14: _always_ in clobber list; see unistd.h */ | ||
231 | swi r14, r1, PT_R14 | ||
232 | /* but we want to return to the next inst. */ | ||
233 | addik r14, r14, 0x4 | ||
234 | swi r14, r1, PT_PC /* increment by 4 and store in pc */ | ||
235 | swi r15, r1, PT_R15 | ||
236 | swi r16, r1, PT_R16 | ||
237 | swi r17, r1, PT_R17 | ||
238 | swi r18, r1, PT_R18 | ||
239 | swi r19, r1, PT_R19 | ||
240 | swi r20, r1, PT_R20 | ||
241 | swi r21, r1, PT_R21 | ||
242 | swi r22, r1, PT_R22 | ||
243 | swi r23, r1, PT_R23 | ||
244 | swi r24, r1, PT_R24 | ||
245 | swi r25, r1, PT_R25 | ||
246 | swi r26, r1, PT_R26 | ||
247 | swi r27, r1, PT_R27 | ||
248 | swi r28, r1, PT_R28 | ||
249 | swi r29, r1, PT_R29 | ||
250 | swi r30, r1, PT_R30 | ||
251 | swi r31, r1, PT_R31 | ||
252 | |||
253 | disable_irq | ||
254 | nop /* make sure IE bit is in effect */ | ||
255 | clear_bip /* once IE is in effect it is safe to clear BIP */ | ||
256 | nop | ||
257 | |||
258 | /* special purpose registers */ | ||
259 | mfs r11, rmsr | ||
260 | swi r11, r1, PT_MSR | ||
261 | mfs r11, rear | ||
262 | swi r11, r1, PT_EAR | ||
263 | mfs r11, resr | ||
264 | swi r11, r1, PT_ESR | ||
265 | mfs r11, rfsr | ||
266 | swi r11, r1, PT_FSR | ||
267 | /* reload original stack pointer and save it */ | ||
268 | lwi r11, r0, PER_CPU(ENTRY_SP) | ||
269 | swi r11, r1, PT_R1 | ||
270 | /* update mode indicator we are in kernel mode */ | ||
271 | addik r11, r0, 1 | ||
272 | swi r11, r0, PER_CPU(KM) | ||
273 | /* restore r31 */ | ||
274 | lwi r31, r0, PER_CPU(CURRENT_SAVE) | ||
275 | /* re-enable interrupts now we are in kernel mode */ | ||
276 | enable_irq | ||
277 | |||
278 | /* See if the system call number is valid. */ | ||
279 | addi r11, r12, -__NR_syscalls | ||
280 | bgei r11, 1f /* return to user if not valid */ | ||
281 | /* Figure out which function to use for this system call. */ | ||
282 | /* Note Microblaze barrel shift is optional, so don't rely on it */ | ||
283 | add r12, r12, r12 /* convert num -> ptr */ | ||
284 | add r12, r12, r12 | ||
285 | lwi r12, r12, sys_call_table /* Get function pointer */ | ||
286 | la r15, r0, ret_to_user-8 /* set return address */ | ||
287 | bra r12 /* Make the system call. */ | ||
288 | bri 0 /* won't reach here */ | ||
289 | 1: | ||
290 | brid ret_to_user /* jump to syscall epilogue */ | ||
291 | addi r3, r0, -ENOSYS /* set errno in delay slot */ | ||
292 | |||
293 | /* | ||
294 | * Debug traps are like a system call, but entered via brki r14, 0x60 | ||
295 | * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal | ||
296 | * will handle the rest | ||
297 | */ | ||
298 | ENTRY(_debug_exception) | ||
299 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | ||
300 | lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | ||
301 | lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | ||
302 | addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */ | ||
303 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
304 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
305 | //save_context: | ||
306 | swi r11, r1, PT_MODE /* store the mode */ | ||
307 | lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | ||
308 | /* save them on stack */ | ||
309 | swi r2, r1, PT_R2 | ||
310 | swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ | ||
311 | swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ | ||
312 | swi r5, r1, PT_R5 | ||
313 | swi r6, r1, PT_R6 | ||
314 | swi r7, r1, PT_R7 | ||
315 | swi r8, r1, PT_R8 | ||
316 | swi r9, r1, PT_R9 | ||
317 | swi r10, r1, PT_R10 | ||
318 | swi r11, r1, PT_R11 | ||
319 | /* r12: _always_ in clobber list; see unistd.h */ | ||
320 | swi r12, r1, PT_R12 | ||
321 | swi r13, r1, PT_R13 | ||
322 | /* r14: _always_ in clobber list; see unistd.h */ | ||
323 | swi r14, r1, PT_R14 | ||
324 | swi r14, r1, PT_PC /* Will return to interrupted instruction */ | ||
325 | swi r15, r1, PT_R15 | ||
326 | swi r16, r1, PT_R16 | ||
327 | swi r17, r1, PT_R17 | ||
328 | swi r18, r1, PT_R18 | ||
329 | swi r19, r1, PT_R19 | ||
330 | swi r20, r1, PT_R20 | ||
331 | swi r21, r1, PT_R21 | ||
332 | swi r22, r1, PT_R22 | ||
333 | swi r23, r1, PT_R23 | ||
334 | swi r24, r1, PT_R24 | ||
335 | swi r25, r1, PT_R25 | ||
336 | swi r26, r1, PT_R26 | ||
337 | swi r27, r1, PT_R27 | ||
338 | swi r28, r1, PT_R28 | ||
339 | swi r29, r1, PT_R29 | ||
340 | swi r30, r1, PT_R30 | ||
341 | swi r31, r1, PT_R31 | ||
342 | |||
343 | disable_irq | ||
344 | nop /* make sure IE bit is in effect */ | ||
345 | clear_bip /* once IE is in effect it is safe to clear BIP */ | ||
346 | nop | ||
347 | |||
348 | /* special purpose registers */ | ||
349 | mfs r11, rmsr | ||
350 | swi r11, r1, PT_MSR | ||
351 | mfs r11, rear | ||
352 | swi r11, r1, PT_EAR | ||
353 | mfs r11, resr | ||
354 | swi r11, r1, PT_ESR | ||
355 | mfs r11, rfsr | ||
356 | swi r11, r1, PT_FSR | ||
357 | /* reload original stack pointer and save it */ | ||
358 | lwi r11, r0, PER_CPU(ENTRY_SP) | ||
359 | swi r11, r1, PT_R1 | ||
360 | /* update mode indicator we are in kernel mode */ | ||
361 | addik r11, r0, 1 | ||
362 | swi r11, r0, PER_CPU(KM) | ||
363 | /* restore r31 */ | ||
364 | lwi r31, r0, PER_CPU(CURRENT_SAVE) | ||
365 | /* re-enable interrupts now we are in kernel mode */ | ||
366 | enable_irq | ||
367 | |||
368 | addi r5, r0, SIGTRAP /* sending the trap signal */ | ||
369 | add r6, r0, r31 /* to current */ | ||
370 | bralid r15, send_sig | ||
371 | add r7, r0, r0 /* 3rd param zero */ | ||
372 | |||
373 | /* Restore r3/r4 to work around how ret_to_user works */ | ||
374 | lwi r3, r1, PT_R3 | ||
375 | lwi r4, r1, PT_R4 | ||
376 | bri ret_to_user | ||
377 | |||
378 | ENTRY(_break) | ||
379 | bri 0 | ||
380 | |||
381 | /* struct task_struct *_switch_to(struct thread_info *prev, | ||
382 | struct thread_info *next); */ | ||
383 | ENTRY(_switch_to) | ||
384 | /* prepare return value */ | ||
385 | addk r3, r0, r31 | ||
386 | |||
387 | /* save registers in cpu_context */ | ||
388 | /* use r11 and r12, volatile registers, as temp register */ | ||
389 | addik r11, r5, TI_CPU_CONTEXT | ||
390 | swi r1, r11, CC_R1 | ||
391 | swi r2, r11, CC_R2 | ||
392 | /* skip volatile registers. | ||
393 | * they are saved on stack when we jumped to _switch_to() */ | ||
394 | /* dedicated registers */ | ||
395 | swi r13, r11, CC_R13 | ||
396 | swi r14, r11, CC_R14 | ||
397 | swi r15, r11, CC_R15 | ||
398 | swi r16, r11, CC_R16 | ||
399 | swi r17, r11, CC_R17 | ||
400 | swi r18, r11, CC_R18 | ||
401 | /* save non-volatile registers */ | ||
402 | swi r19, r11, CC_R19 | ||
403 | swi r20, r11, CC_R20 | ||
404 | swi r21, r11, CC_R21 | ||
405 | swi r22, r11, CC_R22 | ||
406 | swi r23, r11, CC_R23 | ||
407 | swi r24, r11, CC_R24 | ||
408 | swi r25, r11, CC_R25 | ||
409 | swi r26, r11, CC_R26 | ||
410 | swi r27, r11, CC_R27 | ||
411 | swi r28, r11, CC_R28 | ||
412 | swi r29, r11, CC_R29 | ||
413 | swi r30, r11, CC_R30 | ||
414 | /* special purpose registers */ | ||
415 | mfs r12, rmsr | ||
416 | swi r12, r11, CC_MSR | ||
417 | mfs r12, rear | ||
418 | swi r12, r11, CC_EAR | ||
419 | mfs r12, resr | ||
420 | swi r12, r11, CC_ESR | ||
421 | mfs r12, rfsr | ||
422 | swi r12, r11, CC_FSR | ||
423 | |||
424 | /* update r31, the current */ | ||
425 | lwi r31, r6, TI_TASK | ||
426 | swi r31, r0, PER_CPU(CURRENT_SAVE) | ||
427 | |||
428 | /* get new process' cpu context and restore */ | ||
429 | addik r11, r6, TI_CPU_CONTEXT | ||
430 | |||
431 | /* special purpose registers */ | ||
432 | lwi r12, r11, CC_FSR | ||
433 | mts rfsr, r12 | ||
434 | lwi r12, r11, CC_ESR | ||
435 | mts resr, r12 | ||
436 | lwi r12, r11, CC_EAR | ||
437 | mts rear, r12 | ||
438 | lwi r12, r11, CC_MSR | ||
439 | mts rmsr, r12 | ||
440 | /* non-volatile registers */ | ||
441 | lwi r30, r11, CC_R30 | ||
442 | lwi r29, r11, CC_R29 | ||
443 | lwi r28, r11, CC_R28 | ||
444 | lwi r27, r11, CC_R27 | ||
445 | lwi r26, r11, CC_R26 | ||
446 | lwi r25, r11, CC_R25 | ||
447 | lwi r24, r11, CC_R24 | ||
448 | lwi r23, r11, CC_R23 | ||
449 | lwi r22, r11, CC_R22 | ||
450 | lwi r21, r11, CC_R21 | ||
451 | lwi r20, r11, CC_R20 | ||
452 | lwi r19, r11, CC_R19 | ||
453 | /* dedicated registers */ | ||
454 | lwi r18, r11, CC_R18 | ||
455 | lwi r17, r11, CC_R17 | ||
456 | lwi r16, r11, CC_R16 | ||
457 | lwi r15, r11, CC_R15 | ||
458 | lwi r14, r11, CC_R14 | ||
459 | lwi r13, r11, CC_R13 | ||
460 | /* skip volatile registers */ | ||
461 | lwi r2, r11, CC_R2 | ||
462 | lwi r1, r11, CC_R1 | ||
463 | |||
464 | rtsd r15, 8 | ||
465 | nop | ||
466 | |||
467 | ENTRY(ret_from_fork) | ||
468 | addk r5, r0, r3 | ||
469 | addk r6, r0, r1 | ||
470 | brlid r15, schedule_tail | ||
471 | nop | ||
472 | swi r31, r1, PT_R31 /* save r31 in user context. */ | ||
473 | /* will soon be restored to r31 in ret_to_user */ | ||
474 | addk r3, r0, r0 | ||
475 | brid ret_to_user | ||
476 | nop | ||
477 | |||
478 | work_pending: | ||
479 | andi r11, r19, _TIF_NEED_RESCHED | ||
480 | beqi r11, 1f | ||
481 | bralid r15, schedule | ||
482 | nop | ||
483 | 1: andi r11, r19, _TIF_SIGPENDING | ||
484 | beqi r11, no_work_pending | ||
485 | addk r5, r1, r0 | ||
486 | addik r7, r0, 1 | ||
487 | bralid r15, do_signal | ||
488 | addk r6, r0, r0 | ||
489 | bri no_work_pending | ||
490 | |||
491 | ENTRY(ret_to_user) | ||
492 | disable_irq | ||
493 | |||
494 | swi r4, r1, PT_R4 /* return val */ | ||
495 | swi r3, r1, PT_R3 /* return val */ | ||
496 | |||
497 | lwi r6, r31, TS_THREAD_INFO /* get thread info */ | ||
498 | lwi r19, r6, TI_FLAGS /* get flags in thread info */ | ||
499 | bnei r19, work_pending /* do an extra work if any bits are set */ | ||
500 | no_work_pending: | ||
501 | disable_irq | ||
502 | |||
503 | /* save r31 */ | ||
504 | swi r31, r0, PER_CPU(CURRENT_SAVE) | ||
505 | /* save mode indicator */ | ||
506 | lwi r18, r1, PT_MODE | ||
507 | swi r18, r0, PER_CPU(KM) | ||
508 | //restore_context: | ||
509 | /* special purpose registers */ | ||
510 | lwi r18, r1, PT_FSR | ||
511 | mts rfsr, r18 | ||
512 | lwi r18, r1, PT_ESR | ||
513 | mts resr, r18 | ||
514 | lwi r18, r1, PT_EAR | ||
515 | mts rear, r18 | ||
516 | lwi r18, r1, PT_MSR | ||
517 | mts rmsr, r18 | ||
518 | |||
519 | lwi r31, r1, PT_R31 | ||
520 | lwi r30, r1, PT_R30 | ||
521 | lwi r29, r1, PT_R29 | ||
522 | lwi r28, r1, PT_R28 | ||
523 | lwi r27, r1, PT_R27 | ||
524 | lwi r26, r1, PT_R26 | ||
525 | lwi r25, r1, PT_R25 | ||
526 | lwi r24, r1, PT_R24 | ||
527 | lwi r23, r1, PT_R23 | ||
528 | lwi r22, r1, PT_R22 | ||
529 | lwi r21, r1, PT_R21 | ||
530 | lwi r20, r1, PT_R20 | ||
531 | lwi r19, r1, PT_R19 | ||
532 | lwi r18, r1, PT_R18 | ||
533 | lwi r17, r1, PT_R17 | ||
534 | lwi r16, r1, PT_R16 | ||
535 | lwi r15, r1, PT_R15 | ||
536 | lwi r14, r1, PT_PC | ||
537 | lwi r13, r1, PT_R13 | ||
538 | lwi r12, r1, PT_R12 | ||
539 | lwi r11, r1, PT_R11 | ||
540 | lwi r10, r1, PT_R10 | ||
541 | lwi r9, r1, PT_R9 | ||
542 | lwi r8, r1, PT_R8 | ||
543 | lwi r7, r1, PT_R7 | ||
544 | lwi r6, r1, PT_R6 | ||
545 | lwi r5, r1, PT_R5 | ||
546 | lwi r4, r1, PT_R4 /* return val */ | ||
547 | lwi r3, r1, PT_R3 /* return val */ | ||
548 | lwi r2, r1, PT_R2 | ||
549 | lwi r1, r1, PT_R1 | ||
550 | |||
551 | rtid r14, 0 | ||
552 | nop | ||
553 | |||
554 | sys_vfork_wrapper: | ||
555 | brid sys_vfork | ||
556 | addk r5, r1, r0 | ||
557 | |||
558 | sys_clone_wrapper: | ||
559 | brid sys_clone | ||
560 | addk r7, r1, r0 | ||
561 | |||
562 | sys_execve_wrapper: | ||
563 | brid sys_execve | ||
564 | addk r8, r1, r0 | ||
565 | |||
566 | sys_sigreturn_wrapper: | ||
567 | brid sys_sigreturn | ||
568 | addk r5, r1, r0 | ||
569 | |||
570 | sys_rt_sigreturn_wrapper: | ||
571 | brid sys_rt_sigreturn | ||
572 | addk r5, r1, r0 | ||
573 | |||
574 | sys_sigsuspend_wrapper: | ||
575 | brid sys_rt_sigsuspend | ||
576 | addk r6, r1, r0 | ||
577 | |||
578 | sys_rt_sigsuspend_wrapper: | ||
579 | brid sys_rt_sigsuspend | ||
580 | addk r7, r1, r0 | ||
581 | |||
582 | /* Interrupt vector table */ | ||
583 | .section .init.ivt, "ax" | ||
584 | .org 0x0 | ||
585 | brai _reset | ||
586 | brai _user_exception | ||
587 | brai _interrupt | ||
588 | brai _break | ||
589 | brai _hw_exception_handler | ||
590 | .org 0x60 | ||
591 | brai _debug_exception | ||
592 | |||
593 | .section .rodata,"a" | ||
594 | #include "syscall_table.S" | ||
595 | |||
596 | syscall_table_size=(.-sys_call_table) | ||