⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 entry-armv.s

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* *  linux/arch/arm/kernel/entry-armv.S * *  Copyright (C) 1996,1997,1998 Russell King. *  ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  Low-level vector interface routines * *  Note:  there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes *  it to save wrong values...  Be aware! */#include <linux/config.h> /* for CONFIG_ARCH_xxxx */#include <linux/linkage.h>#include <asm/assembler.h>#include <asm/errno.h>#include <asm/hardware.h>#include <asm/arch/irqs.h>#include <asm/proc-fns.h>#include "../lib/constants.h"#ifndef MODE_SVC#define MODE_SVC 0x13#endif		.macro	zero_fp#ifdef CONFIG_FRAME_POINTER		mov	fp, #0#endif		.endm		.text@ Bad Abort numbers@ -----------------@#define BAD_PREFETCH	0#define BAD_DATA	1#define BAD_ADDREXCPTN	2#define BAD_IRQ		3#define BAD_UNDEFINSTR	4@@ Stack format (ensured by USER_* and SVC_*)@#define S_FRAME_SIZE	72#define S_OLD_R0	68#define S_PSR		64#define S_PC		60#define S_LR		56#define S_SP		52#define S_IP		48#define S_FP		44#define S_R10		40#define S_R9		36#define S_R8		32#define S_R7		28#define S_R6		24#define S_R5		20#define S_R4		16#define S_R3		12#define S_R2		8#define S_R1		4#define S_R0		0#define OFF_CR_ALIGNMENT(x)	cr_alignment - x#ifdef IOC_BASE/* IOC / IOMD based hardware */#include <asm/hardware/iomd.h>		.equ	ioc_base_high, IOC_BASE & 0xff000000		.equ	ioc_base_low, IOC_BASE & 0x00ff0000		.macro	disable_fiq		mov	r12, #ioc_base_high		.if	ioc_base_low		orr	r12, r12, #ioc_base_low		.endif		strb	r12, [r12, #0x38]	@ Disable FIQ register		.endm		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp		mov	r4, #ioc_base_high		@ point at IOC		.if	ioc_base_low		orr	r4, r4, #ioc_base_low		.endif		ldrb	\irqstat, [r4, #0x24]		@ get high priority first		adr	\base, irq_prio_h		teq	\irqstat, #0#ifdef IOMD_BASE		ldreqb	\irqstat, [r4, #0x1f4]		@ get dma		adreq	\base, irq_prio_d		teqeq	\irqstat, #0#endif		ldreqb	\irqstat, [r4, #0x14]		@ get low priority		adreq	\base, irq_prio_l		teq	\irqstat, #0		ldrneb	\irqnr, [\base, \irqstat]	@ get IRQ number		.endm/* * Interrupt table (incorporates priority) */		.macro	irq_prio_tableirq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7#ifdef IOMD_BASEirq_prio_d:	.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16#endifirq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10		.endm#elif defined(CONFIG_ARCH_EBSA110)		.macro	disable_fiq		.endm		.macro	get_irqnr_and_base, irqnr, stat, base, tmp		mov	\base, #IRQ_STAT		ldrb	\stat, [\base]			@ get interrupts		mov	\irqnr, #0		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_SHARK)		.macro	disable_fiq		.endm		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp		mov	r4, #0xe0000000		orr	r4, r4, #0x20		mov	\irqstat, #0x0C		strb	\irqstat, [r4]			@outb(0x0C, 0x20) /* Poll command */		ldrb	\irqnr, [r4]			@irq = inb(0x20) & 7		and	\irqstat, \irqnr, #0x80		teq	\irqstat, #0		beq	43f		and	\irqnr, \irqnr, #7		teq	\irqnr, #2		bne	44f43:		mov	\irqstat, #0x0C		strb	\irqstat, [r4, #0x80]		@outb(0x0C, 0xA0) /* Poll command */		ldrb	\irqnr, [r4, #0x80]		@irq = (inb(0xA0) & 7) + 8		and	\irqstat, \irqnr, #0x80		teq	\irqstat, #0		beq	44f		and	\irqnr, \irqnr, #7		add	\irqnr, \irqnr, #844:		teq	\irqstat, #0		.endm		.macro	irq_prio_table		.endm#elif defined(CONFIG_FOOTBRIDGE)#include <asm/hardware/dec21285.h>		.macro	disable_fiq		.endm		.equ	dc21285_high, ARMCSR_BASE & 0xff000000		.equ	dc21285_low, ARMCSR_BASE & 0x00ffffff		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp		mov	r4, #dc21285_high		.if	dc21285_low		orr	r4, r4, #dc21285_low		.endif		ldr	\irqstat, [r4, #0x180]		@ get interrupts		mov	\irqnr, #IRQ_SDRAMPARITY		tst	\irqstat, #IRQ_MASK_SDRAMPARITY		bne	1001f		tst	\irqstat, #IRQ_MASK_UART_RX		movne	\irqnr, #IRQ_CONRX		bne	1001f		tst	\irqstat, #IRQ_MASK_DMA1		movne	\irqnr, #IRQ_DMA1		bne	1001f		tst	\irqstat, #IRQ_MASK_DMA2		movne	\irqnr, #IRQ_DMA2		bne	1001f		tst	\irqstat, #IRQ_MASK_IN0		movne	\irqnr, #IRQ_IN0		bne	1001f		tst	\irqstat, #IRQ_MASK_IN1		movne	\irqnr, #IRQ_IN1		bne	1001f		tst	\irqstat, #IRQ_MASK_IN2		movne	\irqnr, #IRQ_IN2		bne	1001f		tst	\irqstat, #IRQ_MASK_IN3		movne	\irqnr, #IRQ_IN3		bne	1001f		tst	\irqstat, #IRQ_MASK_PCI		movne	\irqnr, #IRQ_PCI		bne	1001f		tst	\irqstat, #IRQ_MASK_DOORBELLHOST		movne	\irqnr, #IRQ_DOORBELLHOST		bne     1001f			tst	\irqstat, #IRQ_MASK_I2OINPOST		movne	\irqnr, #IRQ_I2OINPOST		bne	1001f		tst	\irqstat, #IRQ_MASK_TIMER1		movne	\irqnr, #IRQ_TIMER1		bne	1001f		tst	\irqstat, #IRQ_MASK_TIMER2		movne	\irqnr, #IRQ_TIMER2		bne	1001f		tst	\irqstat, #IRQ_MASK_TIMER3		movne	\irqnr, #IRQ_TIMER3		bne	1001f		tst	\irqstat, #IRQ_MASK_UART_TX		movne	\irqnr, #IRQ_CONTX		bne	1001f		tst	\irqstat, #IRQ_MASK_PCI_ABORT		movne	\irqnr, #IRQ_PCI_ABORT		bne	1001f		tst	\irqstat, #IRQ_MASK_PCI_SERR		movne	\irqnr, #IRQ_PCI_SERR		bne	1001f		tst	\irqstat, #IRQ_MASK_DISCARD_TIMER		movne	\irqnr, #IRQ_DISCARD_TIMER		bne	1001f		tst	\irqstat, #IRQ_MASK_PCI_DPERR		movne	\irqnr, #IRQ_PCI_DPERR		bne	1001f		tst	\irqstat, #IRQ_MASK_PCI_PERR		movne	\irqnr, #IRQ_PCI_PERR1001:		.endm		.macro	irq_prio_table		.endm#elif defined(CONFIG_ARCH_NEXUSPCI)		.macro	disable_fiq		.endm		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp		ldr	\irqstat, =INTCONT_BASE		ldr	\base, =soft_irq_mask		ldr	\irqstat, [\irqstat]		@ get interrupts		ldr	\base, [\base]		mov	\irqnr, #0		and	\irqstat, \irqstat, \base	@ mask out disabled ones1001:		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		.ltorg		.bssENTRY(soft_irq_mask)		.word	0		.text		.endm#elif defined(CONFIG_ARCH_TBOX)		.macro	disable_fiq		.endm		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp		ldr	\irqstat, =0xffff7000		ldr	\irqstat, [\irqstat]		@ get interrupts		ldr	\base, =soft_irq_mask		ldr	\base, [\base]		mov	\irqnr, #0		and	\irqstat, \irqstat, \base	@ mask out disabled ones1001:		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		.ltorg		.bssENTRY(soft_irq_mask)		.word	0		.text		.endm#elif defined(CONFIG_ARCH_SA1100)		.macro	disable_fiq		.endm		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp		mov	r4, #0xfa000000			@ ICIP = 0xfa050000		add	r4, r4, #0x00050000		ldr	\irqstat, [r4]			@ get irqs		ldr	\irqnr, [r4, #4]		@ ICMR = 0xfa050004		ands	\irqstat, \irqstat, \irqnr		mov	\irqnr, #0		beq	1001f		tst	\irqstat, #0xff		moveq	\irqstat, \irqstat, lsr #8		addeq	\irqnr, \irqnr, #8		tsteq	\irqstat, #0xff		moveq	\irqstat, \irqstat, lsr #8		addeq	\irqnr, \irqnr, #8		tsteq	\irqstat, #0xff		moveq	\irqstat, \irqstat, lsr #8		addeq	\irqnr, \irqnr, #8		tst	\irqstat, #0x0f		moveq	\irqstat, \irqstat, lsr #4		addeq	\irqnr, \irqnr, #4		tst	\irqstat, #0x03		moveq	\irqstat, \irqstat, lsr #2		addeq	\irqnr, \irqnr, #2		tst	\irqstat, #0x01		addeqs	\irqnr, \irqnr, #11001:		.endm		.macro	irq_prio_table		.endm#elif defined(CONFIG_ARCH_L7200)			.equ	irq_base_addr,	IO_BASE_2		.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_P720T)		.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#else#error Unknown architecture#endif/*============================================================================ * For entry-common.S */		.macro	save_user_regs		sub	sp, sp, #S_FRAME_SIZE		stmia	sp, {r0 - r12}			@ Calling r0 - r12		add	r8, sp, #S_PC		stmdb	r8, {sp, lr}^			@ Calling sp, lr		str	lr, [r8, #0]			@ Save calling PC		mrs	r6, spsr		str	r6, [r8, #4]			@ Save CPSR		str	r0, [r8, #8]			@ Save OLD_R0		.endm		.macro	restore_user_regs		ldr	r0, [sp, #S_PSR]		@ Get calling cpsr		mov	ip, #I_BIT | MODE_SVC		msr	cpsr_c, ip			@ disable IRQs		msr	spsr, r0			@ save in spsr_svc		ldmia	sp, {r0 - lr}^			@ Get calling r0 - lr		mov	r0, r0		ldr	lr, [sp, #S_PC]			@ Get PC		add	sp, sp, #S_FRAME_SIZE		movs	pc, lr				@ return & move spsr_svc into cpsr		.endm		.macro	mask_pc, rd, rm		.endm		/* If we're optimising for StrongARM the resulting code won't 		   run on an ARM7 and we can save a couple of instructions.  									--pb */		.macro	arm700_bug_check, instr, temp#ifndef __ARM_ARCH_4__		and	\temp, \instr, #0x0f000000	@ check for SWI		teq	\temp, #0x0f000000		bne	.Larm700bug#endif		.endm		.macro	enable_irqs, temp		mrs	\temp, cpsr		bic	\temp, \temp, #I_BIT		msr	cpsr, \temp		.endm		.macro	get_current_task, rd		mov	\rd, sp, lsr #13		mov	\rd, \rd, lsl #13		.endm		/*		 * Like adr, but force SVC mode (if required)		 */		.macro	adrsvc, cond, reg, label		adr\cond	\reg, \label		.endm		.macro	alignment_trap, rbase, rtemp, sym#ifdef CONFIG_ALIGNMENT_TRAP		ldr	\rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]		mcr	p15, 0, \rtemp, c1, c0#endif		.endm/* * 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -