📄 entry-armv.s
字号:
.macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqstat, #irq_base_addr @ Virt addr IRQ regs add \irqstat, \irqstat, #0x00001000 @ Status reg ldr \irqstat, [\irqstat, #0] @ get interrupts mov \irqnr, #01001: tst \irqstat, #1 addeq \irqnr, \irqnr, #1 moveq \irqstat, \irqstat, lsr #1 tsteq \irqnr, #32 beq 1001b teq \irqnr, #32 .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_INTEGRATOR) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp/* FIXME: should not be using soo many LDRs here */ ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE) ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status ldr \irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE) ldr \irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)] orr \irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0 mov \irqnr, #01001: tst \irqstat, #1 bne 1002f add \irqnr, \irqnr, #1 mov \irqstat, \irqstat, lsr #1 cmp \irqnr, #22 bcc 1001b1002: /* EQ will be set if we reach 22 */ .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_CLPS711X)#include <asm/hardware/clps7111.h> .macro disable_fiq .endm#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)#error INTSR stride != INTMR stride#endif .macro get_irqnr_and_base, irqnr, stat, base, mask mov \base, #CLPS7111_BASE ldr \stat, [\base, #INTSR1] ldr \mask, [\base, #INTMR1] mov \irqnr, #4 mov \mask, \mask, lsl #16 and \stat, \stat, \mask, lsr #16 movs \stat, \stat, lsr #4 bne 1001f add \base, \base, #INTSR2 - INTSR1 ldr \stat, [\base, #INTSR1] ldr \mask, [\base, #INTMR1] mov \irqnr, #16 mov \mask, \mask, lsl #16 and \stat, \stat, \mask, lsr #161001: tst \stat, #255 addeq \irqnr, \irqnr, #8 moveq \stat, \stat, lsr #8 tst \stat, #15 addeq \irqnr, \irqnr, #4 moveq \stat, \stat, lsr #4 tst \stat, #3 addeq \irqnr, \irqnr, #2 moveq \stat, \stat, lsr #2 tst \stat, #1 addeq \irqnr, \irqnr, #1 moveq \stat, \stat, lsr #1 tst \stat, #1 @ bit 0 should be set .endm .macro irq_prio_table .endm #elif defined (CONFIG_ARCH_CAMELOT)#include <asm/arch/platform.h>#undef IRQ_MODE /* same name defined in asm/proc/ptrace.h */#include <asm/arch/int_ctrl00.h> .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =INT_ID(IO_ADDRESS(EXC_INT_CTRL00_BASE)) ldr \irqnr,[\irqstat] cmp \irqnr,#0 subne \irqnr,\irqnr,#1 .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_ANAKIN) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \base, #IO_BASE mov \irqstat, #INTERRUPT_CONTROLLER ldr \tmp, =anakin_irq_mask ldr \irqstat, [\base, \irqstat] ldr \tmp, [\tmp] ands \irqstat, \irqstat, \tmp ldrne \tmp, =anakin_active_irqs strne \irqstat, [\tmp] movne \irqnr, #IRQ_ANAKIN .endm .macro irq_prio_table .ltorg .bssENTRY(anakin_irq_mask) .word 0ENTRY(anakin_active_irqs) .space 4 .text .endm#elif defined(CONFIG_ARCH_IOP310) || defined(CONFIG_ARCH_ADIFCC) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mrc p13, 0, \irqstat, c4, c0, 0 @ get INTSRC mrc p13, 0, \base, c0, c0, 0 @ get INTCTL tst \irqstat, #(1<<29) @ if INTSRC_BI tstne \base, #(1<<3) @ and INTCTL_BM movne \irqnr, #IRQ_XS80200_BCU bne 1001f tst \irqstat, #(1<<28) @ if INTSRC_PI tstne \base, #(1<<2) @ and INTCTL_PM movne \irqnr, #IRQ_XS80200_PMU bne 1001f tst \irqstat, #(1<<31) @ if INTSRC_FI tstne \base, #(1<<0) @ and INTCTL_FM movne \irqnr, #IRQ_XS80200_EXTFIQ bne 1001f tst \irqstat, #(1<<30) @ if INTSRC_II tstne \base, #(1<<1) @ and INTCTL_IM movne \irqnr, #IRQ_XS80200_EXTIRQ1001: .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_PXA) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \base, #0xfc000000 @ IIR Ctl = 0xfcd00000 add \base, \base, #0x00d00000 ldr \irqstat, [\base, #0] @ ICIP ldr \irqnr, [\base, #4] @ ICMR ands \irqstat, \irqstat, \irqnr mov \irqnr, #0 beq 1001f tst \irqstat, #0xff00 moveq \irqstat, \irqstat, lsr #8 addeq \irqnr, \irqnr, #8 tsteq \irqstat, #0xff00 moveq \irqstat, \irqstat, lsr #8 addeq \irqnr, \irqnr, #8 tst \irqstat, #0x0f00 moveq \irqstat, \irqstat, lsr #4 addeq \irqnr, \irqnr, #4 tst \irqstat, #0x0300 moveq \irqstat, \irqstat, lsr #2 addeq \irqnr, \irqnr, #2 tst \irqstat, #0x0100 addeqs \irqnr, \irqnr, #11001: .endm .macro irq_prio_table .endm#else#error Unknown architecture#endif/* * Invalid mode handlers */__pabt_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - lr} @ Save XXX r0 - lr ldr r4, .LCabt mov r1, #BAD_PREFETCH b 1f__dabt_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} @ Save SVC r0 - lr [lr *should* be intact] ldr r4, .LCabt mov r1, #BAD_DATA b 1f__irq_invalid: sub sp, sp, #S_FRAME_SIZE @ Allocate space on stack for frame stmfd sp, {r0 - lr} @ Save r0 - lr ldr r4, .LCirq mov r1, #BAD_IRQ b 1f__und_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} ldr r4, .LCund mov r1, #BAD_UNDEFINSTR @ int reason1: zero_fp ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0 add r4, sp, #S_PC stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 mov r0, sp and r2, r6, #31 @ int mode b SYMBOL_NAME(bad_mode)#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE /* The FPE is always present */ .equ fpe_not_present, 0#elsewfs_mask_data: .word 0x0e200110 @ WFS/RFS .word 0x0fef0fff .word 0x0d000100 @ LDF [sp]/STF [sp] .word 0x0d000100 @ LDF [fp]/STF [fp] .word 0x0f000f00/* 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 mask_pc r10, r10 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 @ +/- ldr r5, [sp, r6, lsr #14] @ Load reg rsbeq r4, r4, #0 add r5, r5, r4, lsl #2 str r5, [sp, r6, lsr #14] @ Save reg mov pc, r9#endif/* * SVC mode handlers */ .align 5__dabt_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r2, .LCabt add r0, sp, #S_FRAME_SIZE ldmia r2, {r2 - r4} @ get pc, cpsr add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro mrs r9, cpsr @ Enable interrupts if they were tst r3, #PSR_I_BIT biceq r9, r9, #PSR_I_BIT @ previously mov r0, r2 @ *** remove once everyones in sync/* * This routine must not corrupt r9 */#ifdef MULTI_ABORT ldr r4, .LCprocfns @ pass r0, r3 to mov lr, pc @ processor code ldr pc, [r4] @ call processor specific code#else bl CPU_ABORT_HANDLER#endif msr cpsr_c, r9 mov r2, sp bl SYMBOL_NAME(do_DataAbort) set_cpsr_c r0, #PSR_I_BIT | MODE_SVC ldr r0, [sp, #S_PSR] msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .align 5__irq_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r7, .LCirq add r5, sp, #S_FRAME_SIZE ldmia r7, {r7 - r9} add r4, sp, #S_SP mov r6, lr stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro#ifdef CONFIG_PREEMPT get_thread_info r8 ldr r9, [r8, #TI_PREEMPT] @ get preempt count add r7, r9, #1 @ increment it str r7, [r8, #TI_PREEMPT]#endif1: get_irqnr_and_base r0, r6, r5, lr movne r1, sp @ @ routine called with r0 = irq number, r1 = struct pt_regs * @ adrsvc ne, lr, 1b bne asm_do_IRQ#ifdef CONFIG_PREEMPT ldr r0, [r8, #TI_FLAGS] @ get flags tst r0, #_TIF_NEED_RESCHED blne svc_preemptpreempt_return: ldr r0, [r8, #TI_PREEMPT] @ read preempt value teq r0, r7 strne r0, [r0, -r0] @ bug() str r9, [r8, #TI_PREEMPT] @ restore preempt count#endif ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr#ifdef CONFIG_PREEMPTsvc_preempt: teq r9, #0 @ was preempt count = 0 ldreq r6, .LCirq_stat movne pc, lr @ no ldr r0, [r6, #4] @ local_irq_count ldr r1, [r6, #8] @ local_bh_count adds r0, r0, r1 movne pc, lr mov r7, #PREEMPT_ACTIVE str r7, [r8, #TI_PREEMPT] @ set PREEMPT_ACTIVE1: set_cpsr_c r2, #MODE_SVC @ enable IRQs bl SYMBOL_NAME(schedule) set_cpsr_c r0, #PSR_I_BIT | MODE_SVC @ disable IRQs ldr r0, [r8, #TI_FLAGS] @ get new tasks TI_FLAGS tst r0, #_TIF_NEED_RESCHED beq preempt_return @ go again b 1b#endif .align 5__und_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r7, .LCund mov r6, lr 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 adrsvc al, r9, 1f @ r9 = normal FP return bl call_fpe @ lr = undefined instr return mov r0, r5 @ unsigned long pc mov r1, sp @ struct pt_regs *regs bl SYMBOL_NAME(do_undefinstr)1: set_cpsr_c r0, #PSR_I_BIT | MODE_SVC ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers .align 5__pabt_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 ldr r2, .LCabt add r0, sp, #S_FRAME_SIZE ldmia r2, {r2 - r4} @ get pc, cpsr add r5, sp, #S_SP mov r1, lr stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro mrs r9, cpsr @ Enable interrupts if they were tst r3, #PSR_I_BIT biceq r9, r9, #PSR_I_BIT @ previously msr cpsr_c, r9 mov r0, r2 @ address (pc) mov r1, sp @ regs bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -