entry-armv.s
来自「优龙2410linux2.6.8内核源代码」· S 代码 · 共 1,572 行 · 第 1/3 页
S
1,572 行
1001: 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_IOP310) .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_IOP321) .macro disable_fiq .endm /* * Note: only deal with normal interrupts, not FIQ */ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqnr, #0 mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC cmp \irqstat, #0 beq 1001f clz \irqnr, \irqstat mov \base, #31 subs \irqnr,\base,\irqnr add \irqnr,\irqnr,#IRQ_IOP321_DMA0_EOT1001: .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_PXA) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp#ifdef CONFIG_PXA27x mrc p6, 0, \irqstat, c0, c0, 0 @ ICIP mrc p6, 0, \irqnr, c1, c0, 0 @ ICMR#else mov \base, #io_p2v(0x40000000) @ IIR Ctl = 0x40d00000 add \base, \base, #0x00d00000 ldr \irqstat, [\base, #0] @ ICIP ldr \irqnr, [\base, #4] @ ICMR#endif ands \irqnr, \irqstat, \irqnr beq 1001f rsb \irqstat, \irqnr, #0 and \irqstat, \irqstat, \irqnr clz \irqnr, \irqstat rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)1001: .endm .macro irq_prio_table .endm#elif defined (CONFIG_ARCH_IXP4XX) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET) ldr \irqstat, [\irqstat] @ get interrupts cmp \irqstat, #0 beq 1002f clz \irqnr, \irqstat mov \base, #31 subs \irqnr, \base, \irqnr /*1001: tst \irqstat, #1 addeq \irqnr, \irqnr, #1 moveq \irqstat, \irqstat, lsr #1 tsteq \irqnr, #32 beq 1001b teq \irqnr, #32*/1002: .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_OMAP) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \base, =IO_ADDRESS(OMAP_IH1_BASE) ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET] ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET] mov \irqstat, #0xffffffff bic \tmp, \irqstat, \tmp tst \irqnr, \tmp beq 1510f ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET] cmp \irqnr, #0 ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET] cmpeq \irqnr, #INT_IH2_IRQ ldreq \base, =IO_ADDRESS(OMAP_IH2_BASE) ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET] addeqs \irqnr, \irqnr, #321510: .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_S3C2410) /* S3C2410X IRQ Handler, <ben@simtec.co.uk> */ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp30000: mov \tmp, #S3C2410_VA_IRQ ldr \irqnr, [ \tmp, #0x14 ] @ get irq no teq \irqnr, #4 teqne \irqnr, #5 beq 1002f @ external irq reg teq \irqnr, #16 beq 1003f @ lcd controller @ debug check to see if interrupt reported is the same @ as the offset.... teq \irqnr, #0 beq 20002f ldr \irqstat, [ \tmp, #0x10 ] @ INTPND mov \irqstat, \irqstat, lsr \irqnr tst \irqstat, #1 bne 20002f#if 1 stmfd r13!, { r0 - r4 , r14 } ldr r1, [ \tmp, #0x14 ] @ intoffset ldr r2, [ \tmp, #0x10 ] @ INTPND ldr r3, [ \tmp, #0x00 ] @ SRCPND adr r0, 20003f bl printk b 20004f#endif20003: .ascii "<7>irq: err - bad offset %d, intpnd=%08x, srcpnd=%08x\n" .byte 0 .align 420004: mov r1, #1 mov \tmp, #S3C2410_VA_IRQ ldmfd r13!, { r0 - r4 , r14 } @ try working out interript number for ourselves mov \irqnr, #0 ldr \irqstat, [ \tmp, #0x10 ] @ INTPND10021: movs \irqstat, \irqstat, lsr#1 bcs 30000b @ try and re-start the proccess add \irqnr, \irqnr, #1 cmp \irqnr, #32 ble 10021b @ found no interrupt, set Z flag and leave movs \irqnr, #0 b 1001f20005:20002: @ exit @ we base the s3c2410x interrupts at 16 and above to allow @ isa peripherals to have their standard interrupts, also @ ensure that Z flag is un-set on exit @ note, we cannot be sure if we get IRQ_EINT0 (0) that @ there is simply no interrupt pending, so in all other @ cases we jump to say we have found something, otherwise @ we check to see if the interrupt really is assrted adds \irqnr, \irqnr, #IRQ_EINT0 teq \irqnr, #IRQ_EINT0 bne 1001f @ exit ldr \irqstat, [ \tmp, #0x10 ] @ INTPND teq \irqstat, #0 moveq \irqnr, #0 b 1001f @ we get here from no main or external interrupts pending1002: add \tmp, \tmp, #S3C2410_VA_GPIO - S3C2410_VA_IRQ ldr \irqstat, [ \tmp, # 0xa8 ] @ EXTINTPEND ldr \irqnr, [ \tmp, # 0xa4 ] @ EXTINTMASK bic \irqstat, \irqstat, \irqnr @ clear masked irqs mov \irqnr, #IRQ_EINT4 @ start extint nos mov \irqstat, \irqstat, lsr#4 @ ignore bottom 4 bits10021: movs \irqstat, \irqstat, lsr#1 bcs 1004f add \irqnr, \irqnr, #1 cmp \irqnr, #IRQ_EINT23 ble 10021b @ found no interrupt, set Z flag and leave movs \irqnr, #0 b 1001f1003: @ lcd interrupt has been asserted... add \tmp, \tmp, #S3C2410_VA_LCD - S3C2410_VA_IRQ ldr \irqstat, [ \tmp, # 0x54 ] @ lcd int pending tst \irqstat, #2 movne \irqnr, #IRQ_LCD_FRAME tst \irqstat, #1 movne \irqnr, #IRQ_LCD_FIFO @ fall through to exit with flags updated1004: @ ensure Z flag clear in case our MOVS shifted out the last bit teq \irqnr, #01001: @ exit irq routine .endm /* currently don't need an disable_fiq macro */ .macro disable_fiq .endm /* we don't have an irq priority table */ .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_LH7A400)# if defined (CONFIG_ARCH_LH7A404)# error "LH7A400 and LH7A404 are mutually exclusive"# endif .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqnr, #0 mov \base, #io_p2v(0x80000000) @ APB registers ldr \irqstat, [\base, #0x500] @ PIC INTSR1001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry bcs 1008f @ Bit set; irq found add \irqnr, \irqnr, #1 bne 1001b @ Until no bits b 1009f @ Nothing? Hmm.1008: movs \irqstat, #1 @ Force !Z1009: .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_LH7A404) .macro disable_fiq .endm .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqnr, #0 @ VIC1 irq base mov \base, #io_p2v(0x80000000) @ APB registers add \base, \base, #0x8000 ldr \tmp, [\base, #0x0030] @ VIC1_VECTADDR tst \tmp, #VA_VECTORED @ Direct vectored bne 1002f tst \tmp, #VA_VIC1DEFAULT @ Default vectored VIC1 ldrne \irqstat, [\base, #0] @ VIC1_IRQSTATUS bne 1001f add \base, \base, #(0xa000 - 0x8000) ldr \tmp, [\base, #0x0030] @ VIC2_VECTADDR tst \tmp, #VA_VECTORED @ Direct vectored bne 1002f ldr \irqstat, [\base, #0] @ VIC2_IRQSTATUS mov \irqnr, #32 @ VIC2 irq base1001: movs \irqstat, \irqstat, lsr #1 @ Shift into carry bcs 1008f @ Bit set; irq found add \irqnr, \irqnr, #1 bne 1001b @ Until no bits b 1009f @ Nothing? Hmm.1002: and \irqnr, \tmp, #0x3f @ Mask for valid bits1008: movs \irqstat, #1 @ Force !Z str \tmp, [\base, #0x0030] @ Clear vector1009: .endm .macro irq_prio_table .endm#elif defined(CONFIG_ARCH_IMX) .macro disable_fiq .endm#define AITC_NIVECSR 0x40 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \irqstat, =IO_ADDRESS(IMX_AITC_BASE) @ Load offset & priority of the highest priority @ interrupt pending. ldr \irqnr, [\irqstat, #AITC_NIVECSR] @ Shift off the priority leaving the offset or @ "interrupt number" mov \irqnr, \irqnr, lsr #16 ldr \irqstat, =1 @ dummy compare ldr \base, =0xFFFF // invalid interrupt cmp \irqnr, \base bne 1001f ldr \irqstat, =01001: tst \irqstat, #1 @ to make the condition code = TRUE .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 bad_mode/* * 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/* * This routine must not corrupt r9 */#ifdef MULTI_ABORT ldr r4, .LCprocfns @ pass r2, 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 do_DataAbort disable_irq r0 ldr r0, [sp, #S_PSR] msr spsr_cxsf, 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 str r9, [r8, #TI_PREEMPT] @ restore preempt count strne r0, [r0, -r0] @ bug()#endif ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr_cxsf, r0 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .ltorg#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: enable_irq r2 @ enable IRQs bl schedule disable_irq r0 @ 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 r3, .LCund mov r4, lr ldmia r3, {r5 - r7} add r3, sp, #S_FRAME_SIZE add r2, sp, #S_SP stmia r2, {r3 - r7} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?