📄 entry-armo.s
字号:
mov r0, sp str lr, [sp, #-4]! orr r1, r2, #0x0c000000 teqp r1, #0 @ change into mode (wont be user mode) mov r0, r0 mov r1, r8 @ Any register from r8 - r14 can be banked mov r2, r9 mov r3, r10 mov r4, r11 mov r5, r12 mov r6, r13 mov r7, r14 teqp pc, #0x04000003 @ back to svc mov r0, r0 stmfd sp!, {r1-r7} ldmia r0, {r0-r7} stmfd sp!, {r0-r7} mov r0, sp mov r1, #BAD_ADDREXCPTN b _bad_modeLaddrexcptn_not_user: SVC_SAVE_ALL and r2, lr, #3 teq r2, #3 bne Laddrexcptn_illegal_mode teqp pc, #0x00000003 @ NOT a problem - doesnt change mode bic r0, lr, #0xfc000003 mov r1, sp orr r2, r2, #0x400 bl _do_excpt ldmia sp, {r0 - lr} @ I cant remember the reason I changed this... add sp, sp, #15*4 movs pc, lrLvector_addrexcptn: sub lr, lr, #8 tst lr, #3 bne Laddrexcptn_not_user USER_SAVE_ALL teq pc, #0x00000003 bic r0, lr, #0xfc000003 @ Point to instruction mov r1, sp @ Point to registers mov r2, #0x400 mov lr, pc@ Change!! add lr, lr, #_ret_from_sys_call - . - 4 b _do_excpt/************************************************************************** * Data abort handler code */Lvector_data: sub lr, lr, #8 @ Correct lr tst lr, #3 bne Ldata_not_user USER_SAVE_ALL teqp pc, #0x00000003 @ NOT a problem - doesnt change mode bic r0, lr, #0xfc000003 mov r2, #FAULT_CODE_USER mov lr, pc add lr, lr, #_ret_from_sys_call - . - 4 b Ldata_doLdata_not_user: SVC_SAVE_ALL and r2, lr, #3 teq r2, #3 bne Ldata_illegal_mode tst lr, #0x08000000 teqeqp pc, #0x00000003 @ NOT a problem - doesnt change mode bic r0, lr, #0xfc000003 mov r2, #0 bl Ldata_do SVC_RESTORE_ALLLdata_illegal_mode: mov r0, sp mov r1, #BAD_DATA b _bad_mode/************************************************************************** * * All exits to user mode from the kernel go through this code. */LC6: .word _intr_count @ -8 .word _bh_mask @ -4 .word _bh_active @ -0 .word _need_resched @ +4 .word _current @ +8 .word _init_task @ +12Lreschedule: bl _schedule_fpreturn:_ret_from_sys_call: adr r4, LC6 ldmia r4, {r4, r6, r7, r9} ldr r5, [r4] teq r5, #0 bne Lret_no_checkLrecheck_bh: ldr r0, [r6] ldr r1, [r7] tst r0, r1 bne Lhandle_bottom_half ldr r0, [sp, #S_PC] @ Get old PC tst r0, #3 bne Lret_no_check ldr r0, [r9] teq r0, #0 bne Lreschedule ldr r2, [pc, #LC6 - . + 8] ldr r2, [r2] ldr r1, [pc, #LC6 - . + 12] teq r2, r1 beq Lret_no_check ldr r1, [r2, #SIGNAL] ldr r0, [r2, #BLOCKED] bics r1, r1, r0 movne r1, sp blne _do_signalLret_no_check: USER_RESTORE_ALLLhandle_bottom_half: add r0, r5, #1 str r0, [r4] mov r8, pc teqp pc, #0x00000003 bl _do_bottom_half teqp r8, #0 str r5, [r4] b Lrecheck_bh/************************************************************************** * SWI handler * * * We now handle sys-call tracing, and the errno in the task structure. * Still have a problem with >4 arguments for functions. Theres only * a couple of functions in the code that have 5 arguments, so Im not * too worried. */#include "calls.S"LC1: .word _currentLvector_swi: USER_SAVE_ALL bic lr, lr, #0xfc000003 @ get pc value from link register ldr r6, [lr, #-4] @ get swi instruction teqp pc, #0x00000003 @ enable irqs bic r6, r6, #0xff000000 @ mask off swi op code eor r6, r6, #OS_NUMBER << 20 @ check OS numberLretry: cmp r6, #NR_SYSCALLS @ check upper syscall limit bcs Lswi_bad_call ldr r5, [pc, #LC1 - . - 8] ldr r5, [r5] mov ip, #0 @ zero errno str ip, [r5, #ERRNO] ldr ip, [r5, #FLAGS] @ check for syscall tracing tst ip, #PF_TRACESYS bne Ltrace_this_syscall adr ip, _sys_call_table mov r9, sp @ hack for old routines needing '*regs' str r4, [sp, #-4]! @ new-style: (r0 = arg1, r4 = arg5) mov lr, pc ldr pc, [ip, r6, lsl #2] @ call sys routine (r0, r1, r2, r3, r4) add sp, sp, #4 ldr ip, [r5, #ERRNO] @ check errno rsbs ip, ip, #0 movne r0, ip str r0, [sp, #0] @ returned r0 b _ret_from_sys_callLtrace_this_syscall: ldr r7, [sp, #S_IP] mov r0, #0 str r0, [sp, #S_IP] bl _syscall_trace @ trace entry [IP must = 0] str r7, [sp, #S_IP] ldmia sp, {r0 - r3} @ have to reload r0 - r3 adr ip, _sys_call_table mov r9, sp @ hack for routines needing '*regs' str r4, [sp, #-4]! mov lr, pc ldr pc, [ip, r6, lsl #2] @ call sys routine (r0, r1, r2, r3, r4) add sp, sp, #4 ldr ip, [r5, #ERRNO] rsbs ip, ip, #0 movne r0, ip str r0, [sp, #0] @ returned r0 mov r0, #1 str r0, [sp, #S_IP] bl _syscall_trace @ trace exit [IP must != 0] str r7, [sp, #S_IP] b _ret_from_sys_callLswi_bad_call: tst r6, #0x00f00000 bne Lbad cmp r6, #(KSWI_SYS_BASE - KSWI_BASE)@ check for arm private syscalls bcs Larm_sys_call bl _sys_ni_syscall str r0, [sp, #0] @ returned r0 b _ret_from_sys_callLbad: eor r0, r6, #OS_NUMBER << 20 @ check OS number bl _deferred ldmfd sp, {r0 - r3} b LretryLarm_sys_call: bic r0, r6, #0x000f0000 mov r1, sp bl _arm_syscall b _ret_from_sys_call@ r0 = syscall number@ r1 = syscall r0@ r5 = syscall r4@ ip = syscall table_sys_syscall: mov r6, r0 eor r6, r6, #OS_NUMBER << 20 cmp r6, #NR_SYSCALLS @ check range movgt r0, #-ENOSYS movgt pc, lr add sp, sp, #4 @ take of the save of our r4 ldmib sp, {r0 - r4} @ get our args str r4, [sp, #-4]! @ Put our arg on the stack ldr pc, [ip, r6, lsl #2] .global _sys_call_table_sys_call_table:#include "calls.S"/****************************************************************************** * * Data abort handler code. This handles both exceptions from user and SVC * modes, computes the address range of the problem, and does any * correction that is required. It then calls the kernel data abort routine. * * This is where I wish that the ARM would tell you which address aborted. */Ldata_do: mov r3, sp ldr r4, [r0] @ Get instruction tst r4, #1 << 20 @ Check to see if it is a write instruction orreq r2, r2, #FAULT_CODE_WRITE @ Indicate write instruction mov r1, r4, lsr #22 @ Now branch to the relevent processing routine and r1, r1, #15 << 2 add pc, pc, r1 movs pc, lr b Ldata_unknown b Ldata_unknown b Ldata_unknown b Ldata_unknown b Ldata_ldrstr_post @ ldr rd, [rn], #m b Ldata_ldrstr_numindex @ ldr rd, [rn, #m] @ RegVal b Ldata_ldrstr_post @ ldr rd, [rn], rm b Ldata_ldrstr_regindex @ ldr rd, [rn, rm] b Ldata_ldmstm @ ldm*a rn, <rlist> b Ldata_ldmstm @ ldm*b rn, <rlist> b Ldata_unknown b Ldata_unknown b Ldata_ldrstr_post @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m b Ldata_ldcstc_pre @ ldc rd, [rn, #m] b Ldata_unknownLdata_unknown: @ Part of jumptable ldr r3, [sp, #15 * 4] str r3, [sp, #-4]! mov r1, r1, lsr #2 mov r2, r0 mov r3, r4 adr r0, Ltt bl _printkLlpxx: b LlpxxLtt: .ascii "Unknown data abort code %d [pc=%p, *pc=%p]\nLR=%p\0" .alignLdata_ldrstr_post: mov r0, r4, lsr #14 @ Get Rn and r0, r0, #15 << 2 @ Mask out reg. teq r0, #15 << 2 ldr r0, [r3, r0] @ Get register biceq r0, r0, #0xfc000003 mov r1, r0 tst r4, #1 << 21 orrne r2, r2, #FAULT_CODE_USER#ifdef FAULT_CODE_LDRSTRPOST orr r2, r2, #FAULT_CODE_LDRSTRPOST#endif b _do_DataAbortLdata_ldrstr_numindex: mov r0, r4, lsr #14 @ Get Rn and r0, r0, #15 << 2 @ Mask out reg. teq r0, #15 << 2 ldr r0, [r3, r0] @ Get register biceq r0, r0, #0xfc000003 mov r1, r4, lsl #20 tst r4, #1 << 23 addne r0, r0, r1, lsr #20 subeq r0, r0, r1, lsr #20 mov r1, r0#ifdef FAULT_CODE_LDRSTRPRE orr r2, r2, #FAULT_CODE_LDRSTRPRE#endif b _do_DataAbortLdata_ldrstr_regindex: mov r0, r4, lsr #14 @ Get Rn and r0, r0, #15 << 2 @ Mask out reg. teq r0, #15 << 2 ldr r0, [r3, r0] @ Get register biceq r0, r0, #0xfc000003 and r7, r4, #15 teq r7, #15 @ Check for PC ldr r7, [r3, r7, lsl #2] @ Get Rm biceq r7, r7, #0xfc000003 and r8, r4, #0x60 @ Get shift types mov r9, r4, lsr #7 @ Get shift amount and r9, r9, #31 teq r8, #0 moveq r7, r7, lsl r9 teq r8, #0x20 @ LSR shift moveq r7, r7, lsr r9 teq r8, #0x40 @ ASR shift moveq r7, r7, asr r9 teq r8, #0x60 @ ROR shift moveq r7, r7, ror r9 tst r4, #1 << 23 addne r0, r0, r7 subeq r0, r0, r7 @ Apply correction mov r1, r0#ifdef FAULT_CODE_LDRSTRREG orr r2, r2, #FAULT_CODE_LDRSTRREG#endif b _do_DataAbortLdata_ldmstm: mov r7, #0x11 orr r7, r7, r7, lsl #8 and r0, r4, r7 and r1, r4, r7, lsl #1 add r0, r0, r1, lsr #1 and r1, r4, r7, lsl #2 add r0, r0, r1, lsr #2 and r1, r4, r7, lsl #3 add r0, r0, r1, lsr #3 add r0, r0, r0, lsr #8 add r0, r0, r0, lsr #4 and r7, r0, #15 @ r7 = no. of registers to transfer. mov r5, r4, lsr #14 @ Get Rn and r5, r5, #15 << 2 ldr r0, [r3, r5] @ Get reg eor r6, r4, r4, lsl #2 tst r6, #1 << 23 @ Check inc/dec ^ writeback rsbeq r7, r7, #0 add r7, r0, r7, lsl #2 @ Do correction (signed) subne r1, r7, #1 subeq r1, r0, #1 moveq r0, r7 tst r4, #1 << 21 @ Check writeback strne r7, [r3, r5] eor r6, r4, r4, lsl #1 tst r6, #1 << 24 @ Check Pre/Post ^ inc/dec addeq r0, r0, #4 addeq r1, r1, #4 teq r5, #15*4 @ CHECK FOR PC biceq r1, r1, #0xfc000003 biceq r0, r0, #0xfc000003#ifdef FAULT_CODE_LDMSTM orr r2, r2, #FAULT_CODE_LDMSTM#endif b _do_DataAbortLdata_ldcstc_pre: mov r0, r4, lsr #14 @ Get Rn and r0, r0, #15 << 2 @ Mask out reg. teq r0, #15 << 2 ldr r0, [r3, r0] @ Get register biceq r0, r0, #0xfc000003 mov r1, r4, lsl #24 @ Get offset tst r4, #1 << 23 addne r0, r0, r1, lsr #24 subeq r0, r0, r1, lsr #24 mov r1, r0#ifdef FAULT_CODE_LDCSTC orr r2, r2, #FAULT_CODE_LDCSTC#endif b _do_DataAbort .global _fpe_save_fpe_save: ldr r1, [pc, #LC9 - . - 4] ldr pc, [r1] .global _fpe_restore_fpe_restore: ldr r1, [pc, #LC9 - . - 0] ldr pc, [r1]_fpnull: mov pc, lr .data .global _fp_enter .global _fp_save .global _fp_restore_fp_enter: .word _fpundefinstr_fp_save: .word _fpnull_fp_restore: .word _fpnullLirq_temp: .word 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -