1 /* arch/arm26/kernel/entry.S
3 * Assembled from chunks of code in arch/arm
5 * Copyright (C) 2003 Ian Molton
6 * Based on the work of RMK.
10 #include <linux/linkage.h>
12 #include <asm/assembler.h>
13 #include <asm/asm_offsets.h>
14 #include <asm/errno.h>
15 #include <asm/hardware.h>
16 #include <asm/sysirq.h>
17 #include <asm/thread_info.h>
19 #include <asm/ptrace.h>
22 #ifndef CONFIG_NO_FRAME_POINTER
32 #define BAD_PREFETCH 0
34 #define BAD_ADDREXCPTN 2
36 #define BAD_UNDEFINSTR 4
38 @ OS version number used in SWIs
43 #define ARMSWI_OFFSET 0x000f0000
46 @ Stack format (ensured by USER_* and SVC_*)
47 @ PSR and PC are comined on arm26
71 str r0, [sp, #-4]! @ Store SVC r0
72 str lr, [sp, #-4]! @ Store user mode PC
74 stmia sp, {r0 - lr}^ @ Store the other user-mode regs
78 .macro slow_restore_user_regs
79 ldmia sp, {r0 - lr}^ @ restore the user regs not including PC
81 ldr lr, [sp, #15*4] @ get user PC
82 add sp, sp, #15*4+8 @ free stack
86 .macro fast_restore_user_regs
101 str r0, [sp, #S_OLD_R0]
105 .macro save_svc_regs_irq
111 stmfd sp!, {r0 - r12}
113 str r0, [sp, #S_OLD_R0]
117 .macro restore_svc_regs
121 .macro mask_pc, rd, rm
122 bic \rd, \rm, #PCMASK
125 .macro disable_irqs, temp
127 orr \temp, \temp, #PSR_I_BIT
131 .macro enable_irqs, temp
133 and \temp, \temp, #~PSR_I_BIT
137 .macro initialise_traps_extra
140 .macro get_thread_info, rd
142 mov \rd, \rd, lsl #13
146 * These are the registers used in the syscall handler, and allow us to
147 * have in theory up to 7 arguments to a function - r0 to r6.
149 * Note that tbl == why is intentional.
151 * We must set at least "tsk" and "why" when calling ret_with_reschedule.
153 scno .req r7 @ syscall number
154 tbl .req r8 @ syscall table pointer
155 why .req r8 @ Linux syscall (!= 0)
156 tsk .req r9 @ current thread_info
159 * Get the system call number.
163 ldr scno, [lr, #-4] @ get SWI instruction
166 * -----------------------------------------------------------------------
170 * We rely on the fact that R0 is at the bottom of the stack (due to
171 * slow/fast restore user regs).
178 * This is the fast syscall return path. We do as little as
179 * possible here, and this includes saving r0 back into the SVC
183 disable_irqs r1 @ disable interrupts
184 ldr r1, [tsk, #TI_FLAGS]
185 tst r1, #_TIF_WORK_MASK
186 bne fast_work_pending
187 fast_restore_user_regs
190 * Ok, we need to do extra processing, enter the slow path.
193 str r0, [sp, #S_R0+S_OFF]! @ returned r0
195 tst r1, #_TIF_NEED_RESCHED
197 tst r1, #_TIF_NOTIFY_RESUME | _TIF_SIGPENDING
200 mov r2, why @ 'syscall'
202 disable_irqs r1 @ disable interrupts
208 * "slow" syscall return path. "why" tells us if this was a real syscall.
212 disable_irqs r1 @ disable interrupts
213 ldr r1, [tsk, #TI_FLAGS]
214 tst r1, #_TIF_WORK_MASK
217 slow_restore_user_regs
220 * This is how we return from a fork.
225 ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing
227 tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
230 mov r0, #1 @ trace exit [IP = 1]
234 // FIXME - is this strictly necessary?
237 /*=============================================================================
239 *-----------------------------------------------------------------------------
248 #ifdef CONFIG_ALIGNMENT_TRAP
249 ldr ip, __cr_alignment
251 mcr p15, 0, ip, c1, c0 @ update control register
255 str r4, [sp, #-S_OFF]! @ push fifth arg
258 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
259 bic scno, scno, #0xff000000 @ mask off SWI op-code
260 eor scno, scno, #OS_NUMBER << 20 @ check OS number
261 adr tbl, sys_call_table @ load syscall table pointer
262 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
265 adral lr, ret_fast_syscall @ set return address
266 orral lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC mode on return
267 cmp scno, #NR_syscalls @ check upper syscall limit
268 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
271 2: mov why, #0 @ no longer a real syscall
272 cmp scno, #ARMSWI_OFFSET
273 eor r0, scno, #OS_NUMBER << 20 @ put OS number back
275 b sys_ni_syscall @ not private func
278 * This is the really slow path. We're going to be doing
279 * context switches, and waiting for our parent to respond.
283 mov r0, #0 @ trace entry [IP = 0]
286 adral lr, __sys_trace_return @ set return address
287 orral lr, lr, #PSR_I_BIT | MODE_SVC26 @ Force SVC mode on return
288 add r1, sp, #S_R0 + S_OFF @ pointer to regs
289 cmp scno, #NR_syscalls @ check upper syscall limit
290 ldmccia r1, {r0 - r3} @ have to reload r0 - r3
291 ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
295 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
297 mov r0, #1 @ trace exit [IP = 1]
302 #ifdef CONFIG_ALIGNMENT_TRAP
303 .type __cr_alignment, #object
308 .type sys_call_table, #object
309 ENTRY(sys_call_table)
312 /*============================================================================
313 * Special system call wrappers
315 @ r0 = syscall number
317 .type sys_syscall, #function
319 eor scno, r0, #OS_NUMBER << 20
320 cmp scno, #NR_syscalls @ check range
321 stmleia sp, {r5, r6} @ shuffle args
326 ldrle pc, [tbl, scno, lsl #2]
345 sys_sigsuspend_wrapper:
349 sys_rt_sigsuspend_wrapper:
353 sys_sigreturn_wrapper:
357 sys_rt_sigreturn_wrapper:
361 sys_sigaltstack_wrapper:
362 ldr r2, [sp, #S_OFF + S_SP]
366 * Note: off_4k (r5) is always units of 4K. If we can't do the requested
367 * offset, we return EINVAL. FIXME - this lost some stuff from arm32 to
368 * ifdefs. check it out.
371 tst r5, #((1 << (PAGE_SHIFT - 12)) - 1)
372 moveq r5, r5, lsr #PAGE_SHIFT - 12
380 * - We have several modes that each vector can be called from,
381 * each with its own set of registers. On entry to any vector,
382 * we *must* save the registers used in *that* mode.
384 * - This code must be as fast as possible.
386 * There are a few restrictions on the vectors:
387 * - the SWI vector cannot be called from *any* non-user mode
389 * - the FP emulator is *never* called from *any* non-user mode undefined
398 ldrb r6, [r4, #0x24] @ get high priority first
401 ldreqb r6, [r4, #0x14] @ get low priority
404 teq r6, #0 @ If an IRQ happened...
405 ldrneb r0, [r5, r6] @ get IRQ number
406 movne r1, sp @ get struct pt_regs
407 adrne lr, 1b @ Set return address to 1b
408 orrne lr, lr, #PSR_I_BIT | MODE_SVC26 @ (and force SVC mode)
409 bne asm_do_IRQ @ process IRQ (if asserted)
414 * Interrupt table (incorporates priority)
416 .macro irq_prio_table
417 irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
418 .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
419 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
420 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
421 .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
422 .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
423 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
424 .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
425 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
426 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
427 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
428 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
429 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
430 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
431 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
432 .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
433 irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
434 .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
435 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
436 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
437 .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
438 .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
439 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
440 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
441 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
442 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
443 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
444 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
445 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
446 .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
447 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
448 .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
453 * Uncomment these if you wish to get more debugging into about data aborts.
454 * FIXME - I bet we can find a way to encode these and keep performance.
456 #define FAULT_CODE_LDRSTRPOST 0x80
457 #define FAULT_CODE_LDRSTRPRE 0x40
458 #define FAULT_CODE_LDRSTRREG 0x20
459 #define FAULT_CODE_LDMSTM 0x10
460 #define FAULT_CODE_LDCSTC 0x08
462 #define FAULT_CODE_PREFETCH 0x04
463 #define FAULT_CODE_WRITE 0x02
464 #define FAULT_CODE_FORCECOW 0x01
466 /*=============================================================================
468 *-----------------------------------------------------------------------------
470 _unexp_fiq: ldr sp, .LCfiq
472 strb r12, [r12, #0x38] @ Disable FIQ register
473 teqp pc, #PSR_I_BIT | PSR_F_BIT | MODE_SVC26
475 stmfd sp!, {r0 - r3, ip, lr}
478 ldmfd sp!, {r0 - r3, ip, lr}
479 teqp pc, #PSR_I_BIT | PSR_F_BIT | MODE_FIQ26
483 Lfiqmsg: .ascii "*** Unexpected FIQ\n\0"
486 .LCfiq: .word __temp_fiq
487 .LCirq: .word __temp_irq
489 /*=============================================================================
490 * Undefined instruction handler
491 *-----------------------------------------------------------------------------
492 * Handles floating point instructions
495 tst lr, #MODE_SVC26 @ did we come from a non-user mode?
496 bne __und_svc @ yes - deal with it.
497 /* Otherwise, fall through for the user-space (common) case. */
499 zero_fp @ zero frame pointer
500 teqp pc, #PSR_I_BIT | MODE_SVC26 @ disable IRQs
503 ldr pc, [r4] @ Call FP module entry point
504 /* FIXME - should we trap for a null pointer here? */
506 /* The SVC mode case */
507 __und_svc: save_svc_regs @ Non-user mode
515 /* We get here if the FP emulator doesnt handle the undef instr.
516 * If the insn WAS handled, the emulator jumps to ret_from_exception by itself/
524 b ret_from_exception @ Normal FP exit
526 #if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE
527 /* The FPE is always present */
528 .equ fpe_not_present, 0
530 /* We get here if an undefined instruction happens and the floating
531 * point emulator is not present. If the offending instruction was
532 * a WFS, we just perform a normal return as if we had emulated the
533 * operation. This is a hack to allow some basic userland binaries
534 * to run so that the emulator module proper can be loaded. --philb
535 * FIXME - probably a broken useless hack...
538 adr r10, wfs_mask_data
539 ldmia r10, {r4, r5, r6, r7, r8}
540 ldr r10, [sp, #S_PC] @ Load PC
543 ldrt r10, [r10] @ get instruction
545 teq r5, r4 @ Is it WFS?
546 beq ret_from_exception
548 teq r5, r6 @ Is it LDF/STF on sp or fp?
551 tst r10, #0x00200000 @ Does it have WB
552 beq ret_from_exception
553 and r4, r10, #255 @ get offset
554 and r6, r10, #0x000f0000
555 tst r10, #0x00800000 @ +/-
556 ldr r5, [sp, r6, lsr #14] @ Load reg
558 add r5, r5, r4, lsl #2
559 str r5, [sp, r6, lsr #14] @ Save reg
562 wfs_mask_data: .word 0x0e200110 @ WFS/RFS
564 .word 0x0d0d0100 @ LDF [sp]/STF [sp]
565 .word 0x0d0b0100 @ LDF [fp]/STF [fp]
571 /*=============================================================================
572 * Prefetch abort handler
573 *-----------------------------------------------------------------------------
576 /* remember: lr = USR pc */
582 teqp pc, #MODE_SVC26 @ Enable IRQs...
583 mask_pc r0, lr @ Address of abort
584 mov r1, sp @ Tasks registers
586 teq r0, #0 @ If non-zero, we believe this abort..
587 bne ret_from_exception
592 ldr lr, [sp,#S_PC] @ FIXME program to test this on. I think its
593 b .Lbug_undef @ broken at the moment though!)
595 __pabt_invalid: save_svc_regs
596 mov r0, sp @ Prefetch aborts are definitely *not*
597 mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant
598 and r2, lr, #3 @ recover from this problem.
602 t: .ascii "*** undef ***\r\n\0"
606 /*=============================================================================
607 * Address exception handler
608 *-----------------------------------------------------------------------------
609 * These aren't too critical.
610 * (they're not supposed to happen).
611 * In order to debug the reason for address exceptions in non-user modes,
612 * we have to obtain all the registers so that we can see what's going on.
618 bne Laddrexcptn_not_user
621 mask_pc r0, lr @ Point to instruction
622 mov r1, sp @ Point to registers
628 Laddrexcptn_not_user:
632 bne Laddrexcptn_illegal_mode
638 ldmia sp, {r0 - lr} @ I cant remember the reason I changed this...
642 Laddrexcptn_illegal_mode:
645 orr r1, r2, #PSR_I_BIT | PSR_F_BIT
646 teqp r1, #0 @ change into mode (wont be user mode)
648 mov r1, r8 @ Any register from r8 - r14 can be banked
655 teqp pc, #PSR_F_BIT | MODE_SVC26 @ back to svc
661 mov r1, #BAD_ADDREXCPTN
664 /*=============================================================================
665 * Interrupt (IRQ) handler
666 *-----------------------------------------------------------------------------
667 * Note: if the IRQ was taken whilst in user mode, then *no* kernel routine
668 * is running, so do not have to save svc lr.
670 * Entered in IRQ mode.
673 vector_IRQ: ldr sp, .LCirq @ Setup some temporary stack
675 str lr, [sp] @ push return address
680 __irq_usr: teqp pc, #PSR_I_BIT | MODE_SVC26 @ Enter SVC mode
684 ldr lr, [lr] @ Restore lr for jump back to USR
694 @ Place the IRQ priority table here so that the handle_irq macros above
695 @ and below here can access it.
699 __irq_non_usr: teqp pc, #PSR_I_BIT | MODE_SVC26 @ Enter SVC mode
706 bne __irq_invalid @ IRQ not from SVC mode
712 __irq_invalid: mov r0, sp
716 /*=============================================================================
717 * Data abort handler code
718 *-----------------------------------------------------------------------------
720 * This handles both exceptions from user and SVC modes, computes the address
721 * range of the problem, and does any correction that is required. It then
722 * calls the kernel data abort routine.
724 * This is where I wish that the ARM would tell you which address aborted.
727 vector_data: sub lr, lr, #8 @ Correct lr
740 bne Ldata_illegal_mode
742 teqeqp pc, #MODE_SVC26
753 ldr r4, [r0] @ Get instruction
755 tst r4, #1 << 20 @ Check to see if it is a write instruction
756 orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction
757 mov r1, r4, lsr #22 @ Now branch to the relevent processing routine
765 b Ldata_ldrstr_post @ ldr rd, [rn], #m
766 b Ldata_ldrstr_numindex @ ldr rd, [rn, #m] @ RegVal
767 b Ldata_ldrstr_post @ ldr rd, [rn], rm
768 b Ldata_ldrstr_regindex @ ldr rd, [rn, rm]
769 b Ldata_ldmstm @ ldm*a rn, <rlist>
770 b Ldata_ldmstm @ ldm*b rn, <rlist>
773 b Ldata_ldrstr_post @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
774 b Ldata_ldcstc_pre @ ldc rd, [rn, #m]
776 Ldata_unknown: @ Part of jumptable
783 mov r0, r4, lsr #14 @ Get Rn
784 and r0, r0, #15 << 2 @ Mask out reg.
786 ldr r0, [r3, r0] @ Get register
787 biceq r0, r0, #PCMASK
789 #ifdef FAULT_CODE_LDRSTRPOST
790 orr r2, r2, #FAULT_CODE_LDRSTRPOST
794 Ldata_ldrstr_numindex:
795 mov r0, r4, lsr #14 @ Get Rn
796 and r0, r0, #15 << 2 @ Mask out reg.
798 ldr r0, [r3, r0] @ Get register
800 biceq r0, r0, #PCMASK
802 addne r0, r0, r1, lsr #20
803 subeq r0, r0, r1, lsr #20
805 #ifdef FAULT_CODE_LDRSTRPRE
806 orr r2, r2, #FAULT_CODE_LDRSTRPRE
810 Ldata_ldrstr_regindex:
811 mov r0, r4, lsr #14 @ Get Rn
812 and r0, r0, #15 << 2 @ Mask out reg.
814 ldr r0, [r3, r0] @ Get register
816 biceq r0, r0, #PCMASK
817 teq r7, #15 @ Check for PC
818 ldr r7, [r3, r7, lsl #2] @ Get Rm
819 and r8, r4, #0x60 @ Get shift types
820 biceq r7, r7, #PCMASK
821 mov r9, r4, lsr #7 @ Get shift amount
825 teq r8, #0x20 @ LSR shift
827 teq r8, #0x40 @ ASR shift
829 teq r8, #0x60 @ ROR shift
833 subeq r0, r0, r7 @ Apply correction
835 #ifdef FAULT_CODE_LDRSTRREG
836 orr r2, r2, #FAULT_CODE_LDRSTRREG
842 orr r7, r7, r7, lsl #8
844 and r1, r4, r7, lsl #1
845 add r0, r0, r1, lsr #1
846 and r1, r4, r7, lsl #2
847 add r0, r0, r1, lsr #2
848 and r1, r4, r7, lsl #3
849 add r0, r0, r1, lsr #3
850 add r0, r0, r0, lsr #8
851 add r0, r0, r0, lsr #4
852 and r7, r0, #15 @ r7 = no. of registers to transfer.
853 mov r5, r4, lsr #14 @ Get Rn
855 ldr r0, [r3, r5] @ Get reg
856 eor r6, r4, r4, lsl #2
857 tst r6, #1 << 23 @ Check inc/dec ^ writeback
859 add r7, r0, r7, lsl #2 @ Do correction (signed)
863 tst r4, #1 << 21 @ Check writeback
865 eor r6, r4, r4, lsl #1
866 tst r6, #1 << 24 @ Check Pre/Post ^ inc/dec
869 teq r5, #15*4 @ CHECK FOR PC
870 biceq r1, r1, #PCMASK
871 biceq r0, r0, #PCMASK
872 #ifdef FAULT_CODE_LDMSTM
873 orr r2, r2, #FAULT_CODE_LDMSTM
878 mov r0, r4, lsr #14 @ Get Rn
879 and r0, r0, #15 << 2 @ Mask out reg.
881 ldr r0, [r3, r0] @ Get register
882 mov r1, r4, lsl #24 @ Get offset
883 biceq r0, r0, #PCMASK
885 addne r0, r0, r1, lsr #24
886 subeq r0, r0, r1, lsr #24
888 #ifdef FAULT_CODE_LDCSTC
889 orr r2, r2, #FAULT_CODE_LDCSTC
895 * This is the return code to user mode for abort handlers
897 ENTRY(ret_from_exception)
904 .word fpe_not_present
907 * Register switch for older 26-bit only ARMs
910 add r0, r0, #TI_CPU_SAVE
911 stmia r0, {r4 - sl, fp, sp, lr}
912 add r1, r1, #TI_CPU_SAVE
913 ldmia r1, {r4 - sl, fp, sp, pc}^
916 *=============================================================================
917 * Low-level interface code
918 *-----------------------------------------------------------------------------
919 * Trap initialisation
920 *-----------------------------------------------------------------------------
922 * Note - FIQ code has changed. The default is a couple of words in 0x1c, 0x20
923 * that call _unexp_fiq. Nowever, we now copy the FIQ routine to 0x1c (removes
924 * some excess cycles).
926 * What we need to put into 0-0x1c are branches to branch to the kernel.
929 .section ".init.text",#alloc,#execinstr
933 .word vector_undefinstr - 12
934 .word vector_swi - 16
935 .word vector_prefetch - 20
936 .word vector_data - 24
937 .word vector_addrexcptn - 28
938 .word vector_IRQ - 32
939 .word _unexp_fiq - 36
942 * initialise the trap system
945 stmfd sp!, {r4 - r7, lr}
946 adr r1, .Ljump_addresses
947 ldmia r1, {r1 - r7, ip, lr}
948 orr r2, lr, r2, lsr #2
949 orr r3, lr, r3, lsr #2
950 orr r4, lr, r4, lsr #2
951 orr r5, lr, r5, lsr #2
952 orr r6, lr, r6, lsr #2
953 orr r7, lr, r7, lsr #2
954 orr ip, lr, ip, lsr #2
956 stmia r0, {r1 - r7, ip}
957 ldmfd sp!, {r4 - r7, pc}^
960 __temp_irq: .space 4 @ saved lr_irq
961 __temp_fiq: .space 128