📄 entry-armv.s
字号:
mov r1, sp bl deferred ldmfd sp, {r0 - r3} b _ret_from_sys_callLarm_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 tablesys_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]Larm700bug: str lr, [r8] ldr r0, [sp, #S_PSR] @ Get calling cpsr msr spsr, r0 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr mov r0, r0 add sp, sp, #S_PC ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and jump over PC, PSR, OLD_R0 movs pc, lr .globl _sys_call_table,sys_call_tablesys_call_table:_sys_call_table:#include "calls.S"/* *================================================================================================ * Undefined instruction handler *------------------------------------------------------------------------------------------------ */LC2: .word last_task_used_math .word current .word fp_enter__und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ Save r0 - r12 add r8, sp, #S_PC stmdb r8, {sp, lr}^ @ Save user r0 - r12 ldr r4, [pc, #LCund - . - 8] ldmia r4, {r5 - r7} stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 adr r1, LC2 ldmia r1, {r1, r2, r4} ldr r1, [r1] ldr r2, [r2] teq r1, r2 blne math_state_restore adr r9, _fpreturn adr lr, _fpundefinstr ldr pc, [r4] @ Call FP module USR entry point .global _fpreturn,fpreturn .global _fpundefinstr,fpundefinstrfpundefinstr:_fpundefinstr: mov r0, lr @ Called by FP module on undefined instr mov r1, sp mrs r4, cpsr @ Enable interrupts bic r4, r4, #I_BIT msr cpsr, r4 bl do_undefinstrfpreturn:_fpreturn: b _ret_from_sys_call @ Normal FP exit__und_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 mov r6, lr mov fp, #0 ldr r7, [pc, #LCund - . - 8] ldmia r7, {r7 - r9} add r5, sp, #S_FRAME_SIZE add r4, sp, #S_SP stmia r4, {r5 - r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro adr r1, LC2 ldmia r1, {r1, r2, r4} ldr r1, [r1] ldr r2, [r2] teq r1, r2 blne math_state_restore adr r9, _fpreturnsvc adr lr, _fpundefinstrsvc ldr pc, [r4] @ Call FP module SVC entry point .globl _fpreturnsvc,fpreturnsvc .globl _fpundefinstrsvc,fpundefinstrsvcfpundefinstrsvc:_fpundefinstrsvc: mov r0, r5 @ unsigned long pc mov r1, sp @ struct pt_regs *regs bl do_undefinstrfpreturnsvc:_fpreturnsvc: ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers/* We get here if an undefined instruction happens and the floating * point emulator is not present. If the offending instruction was * a WFS, we just perform a normal return as if we had emulated the * operation. This is a hack to allow some basic userland binaries * to run so that the emulator module proper can be loaded. --philb */fpe_not_present: adr r10, wfs_mask_data ldmia r10, {r4, r5, r6, r7, r8} ldr r10, [sp, #S_PC] @ Load PC sub r10, r10, #4 ldrt r10, [r10] @ get instruction and r5, r10, r5 teq r5, r4 @ Is it WFS? moveq pc, r9 and r5, r10, r8 teq r5, r6 @ Is it LDF/STF on sp or fp? teqne r5, r7 movne pc, lr tst r10, #0x00200000 @ Does it have WB moveq pc, r9 and r4, r10, #255 @ get offset and r6, r10, #0x000f0000 tst r10, #0x00800000 @ +/- rsbeq r4, r4, #0 ldr r5, [sp, r6, lsr #14] @ Load reg add r5, r5, r4, lsl #2 str r5, [sp, r6, lsr #14] @ Save reg mov pc, r9wfs_mask_data: .word 0x0e200110 @ WFS .word 0x0fff0fff .word 0x0d0d0100 @ LDF [sp]/STF [sp] .word 0x0d0b0100 @ LDF [fp]/STF [fp] .word 0x0f0f0f00LC3: .word _fp_save .word _fp_restore/* * Function to call when switching tasks to save FP state */ .global _fpe_save,fpe_savefpe_save:_fpe_save: ldr r1, [pc, #LC3 - . - 8] ldr pc, [r1]/* * Function to call when switching tasks to restore FP state */ .global _fpe_restore,fpe_restorefpe_restore:_fpe_restore: ldr r1, [pc, #LC3 - . - 4] ldr pc, [r1]__und_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} mov r7, r0 ldr r4, [pc, #LCund - . - 8] ldmia r4, {r5, r6} @ Get UND/IRQ/FIQ/ABT pc, cpsr add r4, sp, #S_PC stmia r4, {r5, r6, r7} @ Save UND/IRQ/FIQ/ABT pc, cpsr, old_r0 mov r0, sp @ struct pt_regs *regs mov r1, #BAD_UNDEFINSTR @ int reason and r2, r6, #31 @ int mode b bad_mode @ Does not ever return.../* *================================================================================================ * Prefetch abort handler *------------------------------------------------------------------------------------------------ */pabtmsg: .ascii "Pabt: %08lX\n\0" .align__pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ Save r0 - r12 add r8, sp, #S_PC stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr ldr r4, [pc, #LCabt - . - 8] ldmia r4, {r5 - r7} @ Get USR pc, cpsr stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 mrs r7, cpsr @ Enable interrupts if they were bic r7, r7, #I_BIT @ previously msr cpsr, r7 mov r0, r5 @ address (pc) mov r1, sp @ regs bl do_PrefetchAbort @ call abort handler teq r0, #0 @ Does this still apply??? bne _ret_from_sys_call @ Return from sys call#ifdef DEBUG_UNDEF adr r0, t bl _printk#endif mov r0, r5 mov r1, sp and r2, r6, #31 bl do_undefinstr ldr lr, [sp, #S_PSR] @ Get USR cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore USR registers__pabt_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - lr} @ Save XXX r0 - lr mov r7, r0 @ OLD R0 ldr r4, [pc, #LCabt - . - 8] ldmia r4, {r5 - r7} @ Get XXX pc, cpsr add r4, sp, #S_PC stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 mov r0, sp @ Prefetch aborts are definitely *not* mov r1, #BAD_PREFETCH @ allowed in non-user modes. We cant and r2, r6, #31 @ recover from this problem. b bad_mode#ifdef DEBUG_UNDEFt: .ascii "*** undef ***\r\n\0" .align#endif/* *================================================================================================ * Address exception handler *------------------------------------------------------------------------------------------------ * These aren't too critical. (they're not supposed to happen, and won't happen in 32-bit mode). */vector_addrexcptn: b vector_addrexcptn/* *================================================================================================ * Interrupt (IRQ) handler (r13 points to irq temp save area) * MOD: if in user mode, then *no* kernel routine is running, so dont have to * save svc lr *------------------------------------------------------------------------------------------------ */LC4: .word irqjump__irq_usr: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 add r8, sp, #S_PC stmdb r8, {sp, lr}^ ldr r4, [pc, #LCirq - . - 8] ldmia r4, {r5 - r7} @ get saved PC, SPSR stmia r8, {r5 - r7} @ save pc, psr, old_r0urepeat: get_irqnr_and_base r6, r5#if defined(CONFIG_ARCH_TRIO) teq r6, #0x1f bne has_irq_usr ldr r4,=AIC_EOICR eor r6,r6,r6 str r6,[r4]#else teq r6, #0 bne has_irq_usr#endif b _ret_from_sys_callhas_irq_usr: ldrb r0, [r5, r6] @ Get IRQ number ldr r2, [pc, #LC4 - . - 8] mov r1, sp mov lr, pc @ @ routine gets called with r0 = interrupt number, r1 = struct pt_regs * @ ldr pc, [r2, r0, lsl#2] mov r2, #0 teq r0, #0 @ Check to see if it is a fast IRQ beq _ret_from_sys_call ldr r0, [sp, #S_PSR] @ Get saved SPSR msr spsr, r0 @ restore SPSR ldmia sp, {r0 - lr}^ @ Get calling r0 - lr mov r0, r0 add sp, sp, #S_PC ldr lr, [sp], #S_FRAME_SIZE - S_PC movs pc, lr irq_prio_tableLC5: .word intr_count @ -8 .word bh_mask @ -4 .word bh_active @ -0__irq_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 mov r6, lr mov fp, #0 ldr r7, [pc, #LCirq - . - 8] ldmia r7, {r7 - r9} add r5, sp, #S_FRAME_SIZE add r4, sp, #S_SP stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_rosrepeat: get_irqnr_and_base r6, r5#if defined(CONFIG_ARCH_TRIO) teq r6, #0x1f#else teq r6, #0#endif beq no_irq2 ldrb r0, [r5, r6] @ Get IRQ number ldr r2, [pc, #LC4 - . - 8] mov r1, sp mov lr, pc @ @ routine gets called with r0 = interrupt number, r1 = struct pt_regs * @ ldr pc, [r2, r0, lsl #2] teq r0, #0 @ Check to see if it was a fast IRQ bne srepeat ldr r4, [pc, #LC5 - . - 8] ldr r5, [r4] teq r5, #0 bne srepeat ldr r6, [pc, #LC5 - . - 4] ldr r7, [pc, #LC5 - . - 0]recheck_bh2: ldr r0, [r6] ldr r1, [r7] tst r0, r1 beq srepeat add r0, r5, #1 str r0, [r4] mrs r8, cpsr @ Enable interrupts bic lr, r8, #I_BIT msr cpsr, lr bl do_bottom_half msr cpsr, r8 @ Restore interrupt state str r5, [r4] b recheck_bh2no_irq2:#if defined(CONFIG_ARCH_TRIO) ldr r4, =AIC_EOICR eor r6,r6,r6 str r6,[r4]#endif ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr__irq_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate space on stack for frame stmfd sp, {r0 - lr} @ Save r0 - lr mov r7, #-1 ldr r4, [pc, #LCirq - . - 8] ldmia r4, {r5, r6} @ get saved pc, psr add r4, sp, #S_PC stmia r4, {r5, r6, r7} mov fp, #0 mov r0, sp mov r1, #BAD_IRQ b bad_mode/* *================================================================================================ * Data abort handler code *------------------------------------------------------------------------------------------------ */LCprocfns: .word processor__dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ save r0 - r12 add r3, sp, #S_PC stmdb r3, {sp, lr}^ ldr r0, [pc, #LCabt - . - 8] ldmia r0, {r0 - r2} @ Get USR pc, cpsr stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0 mov fp, #0 mrs r2, cpsr @ Enable interrupts if they were bic r2, r2, #I_BIT @ previously msr cpsr, r2 ldr r2, LCprocfns mov lr, pc ldr pc, [r2, #8] @ call processor specific code mov r3, sp bl do_DataAbort b _ret_from_sys_call__dabt_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r2, [pc, #LCabt - . - 8] add r0, sp, #S_FRAME_SIZE add r5, sp, #S_SP mov r1, lr ldmia r2, {r2 - r4} @ get pc, cpsr stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro tst r3, #I_BIT mrseq r0, cpsr @ Enable interrupts if they were biceq r0, r0, #I_BIT @ previously msreq cpsr, r0 mov r0, r2 ldr r2, LCprocfns mov lr, pc ldr pc, [r2, #8] @ call processor specific code mov r3, sp bl do_DataAbort ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr__dabt_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} @ Save SVC r0 - lr [lr *should* be intact] mov r7, r0 ldr r4, [pc, #LCabt - . - 8] ldmia r4, {r5, r6} @ Get SVC pc, cpsr add r4, sp, #S_PC stmia r4, {r5, r6, r7} @ Save SVC pc, cpsr, old_r0 mov r0, sp mov r1, #BAD_DATA and r2, r6, #31 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 scheduleret_from_sys_call:_ret_from_sys_call: adr r9, LC6 ldmia r9!, {r4, r6, r7} 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_PSR] tst r0, #3 bne Lret_no_check ldmia r9, {r5, r6, r7} ldr r0, [r5] teq r0, #0 bne Lreschedule ldr r0, [r6] teq r0, r7 beq Lret_no_check ldr r1, [r0, #SIGNAL] ldr r0, [r0, #BLOCKED] bics r1, r1, r0 movne r1, sp blne do_signalLret_no_check: mrs r0, cpsr @ disable IRQs orr r0, r0, #I_BIT msr cpsr, r0 ldr r0, [sp, #S_PSR] @ Get calling cpsr msr spsr, r0 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr mov r0, r0 add sp, sp, #S_PC ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and jump over PC, PSR, OLD_R0 movs pc, lrLhandle_bottom_half: add r0, r5, #1 str r0, [r4] mrs r8, cpsr bic lr, r8, #I_BIT msr cpsr, lr bl do_bottom_half msr cpsr, r8 str r5, [r4] b Lrecheck_bh_fpnull: mov pc, lr .data .global _fp_enter,fp_enter .global _fp_save,fp_save .global _fp_restore,fp_restorefp_enter:_fp_enter: .word fpe_not_present .word fpe_not_presentfp_save:_fp_save: .word _fpnullfp_restore:_fp_restore: .word _fpnull__temp_irq: .word 0 @ saved lr_irq .word 0 @ saved spsr_irq .word -1 @ old_r0__temp_und: .word 0 @ Saved lr_und .word 0 @ Saved spsr_und .word -1 @ old_r0__temp_abt: .word 0 @ Saved lr_abt .word 0 @ Saved spsr_abt .word -1 @ old_r0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -