2 * arch/score/kernel/entry.S
4 * Score Processor version.
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <linux/err.h>
27 #include <linux/init.h>
28 #include <linux/linkage.h>
30 #include <asm/asmmacro.h>
31 #include <asm/thread_info.h>
32 #include <asm/unistd.h>
64 ENTRY(debug_exception_vector)
74 ENTRY(general_exception_vector) # should move to addr 0x200
83 ENTRY(interrupt_exception_vector) # should move to addr 0x210
92 .section ".text", "ax"
97 la r30, exception_handlers
98 andi r31, 0x1f # get ecr.exc_code
108 lw r16, [r28, TI_REGS]
109 sw r0, [r28, TI_REGS]
111 srli r4, r4, 18 # get ecr.ip[7:2], interrupt No.
115 ENTRY(handle_nmi) # NMI #1
118 la r8, nmi_exception_handler
122 ENTRY(handle_adelinsn) # AdEL-instruction #2
135 ENTRY(handle_ibe) # BusEL-instruction #5
144 ENTRY(handle_pel) # P-EL #6
153 ENTRY(handle_ccu) # CCU #8
162 ENTRY(handle_ri) # RI #9
171 ENTRY(handle_tr) # Trap #10
180 ENTRY(handle_adedata) # AdES-instruction #12
193 ENTRY(handle_cee) # CeE #16
202 ENTRY(handle_cpe) # CpE #17
211 ENTRY(handle_dbe) # BusEL-data #18
220 ENTRY(handle_reserved) # others
229 #ifndef CONFIG_PREEMPT
230 #define resume_kernel restore_all
232 #define __ret_from_irq ret_from_exception
236 #ifndef CONFIG_PREEMPT
237 ENTRY(ret_from_exception)
238 disable_irq # preempt stop
245 sw r16, [r28, TI_REGS]
247 ENTRY(__ret_from_irq)
248 lw r8, [r0, PT_PSR] # returning to kernel mode?
249 andri.c r8, r8, KU_USER
254 lw r6, [r28, TI_FLAGS] # current->work
255 li r8, _TIF_WORK_MASK
256 and.c r8, r8, r6 # ignoring syscall_trace
262 #ifdef CONFIG_PREEMPT
265 lw r8, [r28, TI_PRE_COUNT]
269 lw r8, [r28, TI_FLAGS]
270 andri.c r9, r8, _TIF_NEED_RESCHED
272 lw r8, [r28, PT_PSR] # Interrupts off?
275 bl preempt_schedule_irq
282 bl schedule_tail # r4=struct task_struct *prev
287 lw r6, [r28, TI_FLAGS] # current->work
288 li r8, _TIF_WORK_MASK
290 bne syscall_exit_work
292 ENTRY(restore_all) # restore full frame
296 andri.c r8, r6, _TIF_NEED_RESCHED # r6 is preloaded with TI_FLAGS
302 lw r6, [r28, TI_FLAGS]
303 li r8, _TIF_WORK_MASK
304 and.c r8, r6, r8 # is there any work to be done
305 # other than syscall tracing?
307 andri.c r8, r6, _TIF_NEED_RESCHED
313 bl do_notify_resume # r6 already loaded
318 ENTRY(syscall_exit_work)
319 li r8, _TIF_SYSCALL_TRACE
320 and.c r8, r8, r6 # r6 is preloaded with TI_FLAGS
321 beq work_pending # trace bit set?
331 .macro save_context reg
332 sw r12, [\reg, THREAD_REG12];
333 sw r13, [\reg, THREAD_REG13];
334 sw r14, [\reg, THREAD_REG14];
335 sw r15, [\reg, THREAD_REG15];
336 sw r16, [\reg, THREAD_REG16];
337 sw r17, [\reg, THREAD_REG17];
338 sw r18, [\reg, THREAD_REG18];
339 sw r19, [\reg, THREAD_REG19];
340 sw r20, [\reg, THREAD_REG20];
341 sw r21, [\reg, THREAD_REG21];
342 sw r29, [\reg, THREAD_REG29];
343 sw r2, [\reg, THREAD_REG2];
344 sw r0, [\reg, THREAD_REG0]
347 .macro restore_context reg
348 lw r12, [\reg, THREAD_REG12];
349 lw r13, [\reg, THREAD_REG13];
350 lw r14, [\reg, THREAD_REG14];
351 lw r15, [\reg, THREAD_REG15];
352 lw r16, [\reg, THREAD_REG16];
353 lw r17, [\reg, THREAD_REG17];
354 lw r18, [\reg, THREAD_REG18];
355 lw r19, [\reg, THREAD_REG19];
356 lw r20, [\reg, THREAD_REG20];
357 lw r21, [\reg, THREAD_REG21];
358 lw r29, [\reg, THREAD_REG29];
359 lw r0, [\reg, THREAD_REG0];
360 lw r2, [\reg, THREAD_REG2];
361 lw r3, [\reg, THREAD_REG3]
365 * task_struct *resume(task_struct *prev, task_struct *next,
366 * struct thread_info *next_ti)
372 sw r9, [r4, THREAD_PSR]
374 sw r3, [r4, THREAD_REG3]
379 addi r8, KERNEL_STACK_SIZE
388 lw r6, [r5, THREAD_PSR]
393 nop; nop; nop; nop; nop
398 sw r8, [r0, 16] # argument 5 from user r8
399 sw r9, [r0, 20] # argument 6 from user r9
402 sw r4, [r0, PT_ORIG_R4] #for restart syscall
403 sw r7, [r0, PT_ORIG_R7] #for restart syscall
404 sw r27, [r0, PT_IS_SYSCALL] # it from syscall
406 lw r9, [r0, PT_EPC] # skip syscall on return
410 cmpi.c r27, __NR_syscalls # check syscall number
413 slli r8, r27, 2 # get syscall routine
414 la r11, sys_call_table
416 lw r10, [r11] # get syscall entry
421 lw r8, [r28, TI_FLAGS]
422 li r9, _TIF_SYSCALL_TRACE
424 bne syscall_trace_entry
426 brl r10 # Do The Real system call
434 cmpi.c r4, -MAX_ERRNO - 1
440 sw r4, [r0, PT_R4] # save result
444 lw r6, [r28, TI_FLAGS] # current->work
445 li r8, _TIF_WORK_MASK
447 bne syscall_return_work
460 lw r4, [r0, PT_R4] # Restore argument registers
466 li r8, -MAX_ERRNO - 1
467 sw r8, [r0, PT_R7] # set error flag
470 sw r4, [r0, PT_R0] # set flag for syscall
472 1: sw r4, [r0, PT_R2] # result
476 ldi r4, -ENOSYS # error
477 sw r4, [r0, PT_ORIG_R4]
479 ldi r9, 1 # set error flag
493 ENTRY(sys_rt_sigreturn)
495 la r8, score_rt_sigreturn
498 ENTRY(sys_sigaltstack)
500 la r8, score_sigaltstack
503 #ifdef __ARCH_WANT_SYSCALL_DEPRECATED
513 #endif /* __ARCH_WANT_SYSCALL_DEPRECATED */