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

📄 entry-armo.s

📁 上传linux-jx2410的源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* *  linux/arch/arm/kernel/entry-armo.S * *  Copyright (C) 1995,1996,1997,1998 Russell King. * * 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 * *  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 <linux/config.h>#include "entry-header.S"		.text#ifdef IOC_BASE/* IOC / IOMD based hardware */		.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, base		mov	r4, #ioc_base_high		@ point at IOC		.if	ioc_base_low		orr	r4, r4, #ioc_base_low		.endif		ldrb	\irqnr, [r4, #0x24]		@ get high priority first		adr	\base, irq_prio_h		teq	\irqnr, #0		ldreqb	\irqnr, [r4, #0x14]		@ get low priority		adreq	\base, irq_prio_l		.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, 7irq_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#else#error Unknown architecture#endif/*============================================================================= * For entry-common.S */#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_FORCECOW	0x01#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]	;\		zero_fp#define SVC_IRQ_SAVE_ALL			\		str	sp, [sp, #-16]!		;\		str	lr, [sp, #4]		;\		ldr	lr, .LCirq		;\		ldr	lr, [lr]		;\		str	lr, [sp, #8]		;\		stmfd	sp!, {r0 - r12}		;\		mov	r0, #-1			;\		str	r0, [sp, #S_OLD_R0]	;\		zero_fp#define SVC_RESTORE_ALL				\		ldmfd	sp, {r0 - pc}^		/*============================================================================= * Undefined FIQs *----------------------------------------------------------------------------- */_unexp_fiq:	ldr	sp, .LCfiq		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	SYMBOL_NAME(printk)		ldmfd	sp!, {r0 - r3, ip, lr}		teqp	pc, #0x0c000001		mov	r0, r0		movs	pc, lrLfiqmsg:	.ascii	"*** Unexpected FIQ\n\0"		.align.LCfiq:		.word	__temp_fiq.LCirq:		.word	__temp_irq/*============================================================================= * Undefined instruction handler *----------------------------------------------------------------------------- * Handles floating point instructions */vector_undefinstr:		tst	lr,#3		bne	__und_svc		save_user_regs		zero_fp		teqp	pc, #I_BIT | MODE_SVC.Lbug_undef:		ldr	r4, .LC2		ldr	pc, [r4]			@ Call FP module USR entry point		.globl	SYMBOL_NAME(fpundefinstr)SYMBOL_NAME(fpundefinstr):				@ Called by FP module on undefined instr		mov	r0, lr		mov	r1, sp		teqp	pc, #MODE_SVC		bl	SYMBOL_NAME(do_undefinstr)		b	ret_from_exception		@ Normal FP exit__und_svc:	SVC_SAVE_ALL				@ Non-user mode		mask_pc	r0, lr		and	r2, lr, #3		sub	r0, r0, #4		mov	r1, sp		bl	SYMBOL_NAME(do_undefinstr)		SVC_RESTORE_ALL#if defined CONFIG_FPE_NWFPE || defined CONFIG_FPE_FASTFPE		/* The FPE is always present */		.equ	fpe_not_present, 0#else/* 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?		beq	ret_from_exception		and	r5, r10, r8		teq	r5, r6				@ Is it LDF/STF on sp or fp?		teqne	r5, r7		bne	fpundefinstr		tst	r10, #0x00200000		@ Does it have WB		beq	ret_from_exception		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		b	ret_from_exceptionwfs_mask_data:	.word	0x0e200110			@ WFS/RFS		.word	0x0fef0fff		.word	0x0d0d0100			@ LDF [sp]/STF [sp]		.word	0x0d0b0100			@ LDF [fp]/STF [fp]		.word	0x0f0f0f00#endif.LC2:		.word	SYMBOL_NAME(fp_enter)/*============================================================================= * Prefetch abort handler *----------------------------------------------------------------------------- */vector_prefetch:		sub	lr, lr, #4		tst	lr, #3		bne	__pabt_invalid		save_user_regs		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode		mask_pc	r0, lr			@ Address of abort		mov	r1, sp			@ Tasks registers		bl	SYMBOL_NAME(do_PrefetchAbort)		teq	r0, #0			@ If non-zero, we believe this abort..		bne	ret_from_exception#ifdef DEBUG_UNDEF		adr	r0, t		bl	SYMBOL_NAME(printk)#endif		ldr	lr, [sp,#S_PC]		@ program to test this on.  I think its		b	.Lbug_undef		@ broken at the moment though!)__pabt_invalid:	SVC_SAVE_ALL		mov	r0, sp				@ Prefetch aborts are definitely *not*		mov	r1, #BAD_PREFETCH		@ allowed in non-user modes.  We cant		and	r2, lr, #3			@ recover from this problem.		b	SYMBOL_NAME(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). * 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. */vector_addrexcptn:		sub	lr, lr, #8		tst	lr, #3		bne	Laddrexcptn_not_user		save_user_regs		teq	pc, #0x00000003		mask_pc	r0, lr			@ Point to instruction		mov	r1, sp			@ Point to registers		mov	r2, #0x400		mov	lr, pc		bl	SYMBOL_NAME(do_excpt)		b	ret_from_exceptionLaddrexcptn_not_user:		SVC_SAVE_ALL		and	r2, lr, #3		teq	r2, #3		bne	Laddrexcptn_illegal_mode		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode		mask_pc	r0, lr		mov	r1, sp		orr	r2, r2, #0x400		bl	SYMBOL_NAME(do_excpt)		ldmia	sp, {r0 - lr}		@ I cant remember the reason I changed this...		add	sp, sp, #15*4		movs	pc, lrLaddrexcptn_illegal_mode:		mov	r0, sp		str	lr, [sp, #-4]!		orr	r1, r2, #0x0c000000		teqp	r1, #0			@ change into mode (wont be user mode)		mov	r0, r0		mov	r1, r8			@ Any register from r8 - r14 can be banked		mov	r2, r9		mov	r3, r10		mov	r4, r11		mov	r5, r12

⌨️ 快捷键说明

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