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

📄 entry-armo.s

📁 arm平台上的uclinux系统全部源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* * linux/arch/arm/lib/traps.S * * Copyright (C) 1995, 1996 Russell King. * * Low-level vector interface routines * * Design issues: *  - We have several modes that each vector can be called from, *    each with its own set of registers.  On entry to any vector, *    we *must* save the registers used in *that* mode. * *  - This code must be as fast as possible. * * There are a few restrictions on the vectors: *  - the SWI vector cannot be called from *any* non-user mode * *  - the FP emulator is *never* called from *any* non-user mode undefined *    instruction. * * Ok, so this file may be a mess, but its as efficient as possible while * adhering to the above criteria. */#include <asm/assembler.h>#include <asm/errno.h>#include <asm/hardware.h>#if 0/* * Uncomment these if you wish to get more debugging into about data aborts. */#define FAULT_CODE_LDRSTRPOST	0x80#define FAULT_CODE_LDRSTRPRE	0x40#define FAULT_CODE_LDRSTRREG	0x20#define FAULT_CODE_LDMSTM	0x10#define FAULT_CODE_LDCSTC	0x08#endif#define FAULT_CODE_PREFETCH	0x04#define FAULT_CODE_WRITE	0x02#define FAULT_CODE_USER		0x01		.text/* Offsets into task structure * --------------------------- */#define STATE		0#define COUNTER		4#define PRIORITY	8#define SIGNAL		12#define BLOCKED		16#define FLAGS		20#define ERRNO		24#define PF_TRACESYS	0x20/* Bad Abort numbers * ----------------- */#define BAD_PREFETCH	0#define BAD_DATA	1#define BAD_ADDREXCPTN	2#define BAD_IRQ		3/* OS version number used in SWIs *  RISC OS is 0 *  RISC iX is 8 */#define OS_NUMBER	9/* Stack format (ensured by USER_* and SVC_*) */#define S_OLD_R0	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#include "../lib/constants.h"#define USER_SAVE_ALL				\		str	r0, [sp, #-4]!		;\		str	lr, [sp, #-4]!		;\		sub	sp, sp, #15*4		;\		stmia	sp, {r0 - lr}^		;\		mov	r0, r0			;\		mov	fp, #0#define SVC_SAVE_ALL				\		str	sp, [sp, #-16]!		;\		str	lr, [sp, #8]		;\		str	lr, [sp, #4]		;\		stmfd	sp!, {r0 - r12}		;\		mov	r0, #-1			;\		str	r0, [sp, #S_OLD_R0]	;\		mov	fp, #0#define SVC_IRQ_SAVE_ALL			\		str	sp, [sp, #-16]!		;\		str	lr, [sp, #4]		;\		ldr	lr, [pc, #LC4 - . - 8]	;\		ldr	lr, [lr]		;\		str	lr, [sp, #8]		;\		stmfd	sp!, {r0 - r12}		;\		mov	r0, #-1			;\		str	r0, [sp, #S_OLD_R0]	;\		mov	fp, #0#define USER_RESTORE_ALL			\		ldmia	sp, {r0 - lr}^		;\		mov	r0, r0			;\		add	sp, sp, #15*4		;\		ldr	lr, [sp], #8		;\		movs	pc, lr#define SVC_RESTORE_ALL				\		ldmfd	sp, {r0 - pc}^				.global	_ret_from_sys_call/* * Interrupt table (incorporates priority).  First set is indexed using * IRQSTATB. */Lirq_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,10Lirq_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/************************************************************************** * Interrupt (IRQ) handler (r13 points to irq temp save area) * Note: if in user mode, then *no* kernel routine is running, so dont have *       to save svc lr */LC4:		.word	Lirq_tempLC5:		.word	_irqjumpLvector_IRQ:	ldr	r13, [pc, #LC4 - . - 8]	@ Ill leave this one in just in case...		sub	lr, lr, #4		str	lr, [r13]		tst	lr, #3		bne	LIRQ_not_user		teqp	pc, #0x08000003		mov	r0, r0		ldr	lr, [pc, #LC4 - . - 8]		ldr	lr, [lr]		USER_SAVE_ALL		mov	r4, #IOC_BASE		@ point at IOC		ldrb	r1, [r4, #0x24]		@ get high priority first		adr	r2, Lirq_prio_h		teq	r1, #0		ldreqb	r1, [r4, #0x14]		@ get low priority		adreq	r2, Lirq_prio_l		teq	r1, #0		beq	_ret_from_sys_call		ldrb	r0, [r2, r1]		@ Get IRQ number		ldr	r2, [pc, #LC5 - . - 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		USER_RESTORE_ALLLC65:		.word	_intr_count		@ -8		.word	_bh_mask		@ -4		.word	_bh_active		@ -0Lirq_illegal_mode:		mov	r0, sp		mov	r1, #BAD_IRQ		b	_bad_modeLIRQ_not_user:	teqp	pc, #0x08000003		mov	r0, r0		SVC_IRQ_SAVE_ALL                and	r2, lr, #3		teq	r2, #3		bne	Lirq_illegal_modeLsrepeat:	mov	r4, #IOC_BASE		@ point at IOC		ldrb	r1, [r4, #0x24]		@ get high priority first		adr	r2, Lirq_prio_h		teq	r1, #0		ldreqb	r1, [r4, #0x14]		@ get low priority		adreq	r2, Lirq_prio_l		teq	r1, #0		beq	Lno_irq2		ldrb	r0, [r2, r1]		@ Get IRQ number		ldr	r2, [pc, #LC5 - . - 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, #1		teq	r0, #0			@ Check to see if it is a fast IRQ		bne	Lsrepeat		ldr	r0, [pc, #LC65 - . - 8]		ldr	r1, [r0]		teq	r1, #0		bne	Lsrepeat		mov	r4, r0		mov	r5, r1		ldr	r6, [pc, #LC65 - . - 4]		ldr	r7, [pc, #LC65 - . - 0]Lrecheck_bh2:	ldr	r0, [r6]		ldr	r1, [r7]		tst	r0, r1		beq	Lsrepeat		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_bh2Lno_irq2:	SVC_RESTORE_ALL/************************************************************************** * Trap initialisation * * Note - FIQ code has changed.  The default is a couple of words in 0x1c, * 0x20 that call _unexp_fiq.  Nowever, we now copy the FIQ routine to * 0x1c (removes some excess cycles). */Lswi_reset:	swi	SYS_ERROR0		ldr	pc, . + 4		.long	_unexp_fiqLfiqmsg:	.ascii	"*** Unexpeced FIQ\n\0"		.align_unexp_fiq:	mov	r12, #IOC_BASE		strb	r12, [r12, #0x38]	@ Disable FIQ register		teqp	pc, #0x0c000003		mov	r0, r0		stmfd	sp!, {r0 - r3, ip, lr}		adr	r0, Lfiqmsg		bl	_printk		ldmfd	sp!, {r0 - r3, ip, lr}		teqp	pc, #0x0c000001		mov	r0, r0		movs	pc, lrLvectors:	.long	Lvector_undefinstr - Lvectors - 12		.long	Lvector_swi - Lvectors - 16		.long	Lvector_prefetch - Lvectors - 20		.long	Lvector_data - Lvectors - 24		.long	Lvector_addrexcptn - Lvectors - 28		.long	Lvector_IRQ - Lvectors - 32		.long	0xea000000		.global	_trap_init_trap_init:	stmfd	sp !,{r4 - r9,lr}	@ Save link register		teqp	pc, #0x0c000003		mov	r0, #IOC_BASE		str	r0, [r0, #0x18]		str	r0, [r0, #0x28]		str	r0, [r0, #0x38]		mov	r0, #0			@ Lowest location		adr	r1, Lvectors		ldmia	r1, {r2, r3, r4, r5, r6, r7, ip}		add	r1, ip, r1, asr #2		add	r2, r1, r2, asr #2		add	r3, r1, r3, asr #2		add	r4, r1, r4, asr #2		add	r5, r1, r5, asr #2		add	r6, r1, r6, asr #2		add	r7, r1, r7, asr #2		adr	r1, Lswi_reset		ldmia	r1, {r1, r8, r9}		stmia	r0!, {r1 - r9}		@ Save all into page 0 ram		ldmfd	sp!, {r4 - r9, pc}^/************************************************************************** * Prefetch abort handler */#ifdef DEBUG_UNDEFt:		.ascii "*** undef ***\r\n\0"		.align#endifLvector_prefetch:		sub	lr, lr, #4		tst	lr, #3		bne	Lprefetch_not_user		USER_SAVE_ALL		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode		bic	r0, lr, #0xfc000003	@ Address of abort		mov	r1, #FAULT_CODE_PREFETCH|FAULT_CODE_USER @ Error code		mov	r2, sp			@ Tasks registers		bl	_do_PrefetchAbort		teq	r0, #0			@ If non-zero, we believe this abort..		bne	_ret_from_sys_call#ifdef DEBUG_UNDEF		adr	r0,t			@ Otherwise it was probably an undefined		bl	_printk			@ instruction.  (I do wish that I had a#endif		ldr	lr, [sp,#S_PC]		@ program to test this on.  I think its		b	_undefinstr		@ broken at the moment though!)Lprefetch_not_user:		SVC_SAVE_ALL			@ Prefetch aborts are definitely *not*		mov	r0, sp			@ allowed in non-user modes.  We cant		mov	r1, #BAD_PREFETCH	@ recover from this problem.		and	r2, lr, #3		b	_bad_mode		@ Doesnt return/************************************************************************** * Undefined instruction handler */LC8:		.word	_last_task_used_math		.word	_currentLC9:		.word	_fp_enter		.word	_fp_save		.word	_fp_restoreLundef_not_user:		SVC_SAVE_ALL			@ Non-user mode		bic	r0, lr, #0xfc000003		and	r2, lr, #3		sub	r0, r0, #4		mov	r1, sp		bl	_do_undefinstr		SVC_RESTORE_ALL		.global	_fpreturn		.global	_fpundefinstrLvector_undefinstr:		tst	lr,#3		bne	Lundef_not_user		USER_SAVE_ALL			@ USER mode undefined instructions		teqp	pc, #0x08000003		@ MUST disable interrupts._undefinstr:@@ before calling FP, must call math_state_restore!!!@  something along the lines of:@		adr	r3, LC8		ldmia	r3, {r1, r2, r3}		ldr	r1, [r1]		@ last task used math		ldr	r2, [r2]		@ current task		teq	r1, r2		stmnefd	sp!, {ip, lr}		blne	_math_state_restore		ldmnefd	sp!, {ip, lr}		ldr	r3, [pc, #LC9 - . - 8]		ldr	pc, [r3]		@ Call FP module (when loaded)_fpundefinstr:	mov	r1,sp			@ Called by FP module on undefined instr		teqp	pc, #3			@ Enable interrupts		mov	r2,#0		mov	lr, pc@ Change!!		add	lr, lr, #_ret_from_sys_call - . - 4		b	_do_undefinstr/************************************************************************** * Address exception handler * * These aren't too critical. (they're not supposed to happen). *//* * In order to debug the reason for address exceptions in non-user modes, * we have to obtain all the registers so that we can see what's going on. */Laddrexcptn_illegal_mode:

⌨️ 快捷键说明

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