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

📄 entry.s

📁 microwindows移植到S3C44B0的源码
💻 S
📖 第 1 页 / 共 2 页
字号:
/* -*- mode: asm -*- * *  linux/arch/m68knommu/platform/5307/entry.S * *  Copyright (C) 1999  Greg Ungerer (gerg@snapgear.com) *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>, *                      Kenneth Albanowski <kjahds@kjahds.com>, *  Copyright (C) 2000  Lineo Inc. (www.lineo.com)  * * Based on: * *  linux/arch/m68k/kernel/entry.S * *  Copyright (C) 1991, 1992  Linus Torvalds * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file README.legal in the main directory of this archive * for more details. * * Linux/m68k support by Hamish Macdonald * * 68060 fixes by Jesper Skov * ColdFire support by Greg Ungerer (gerg@snapgear.com) * 5307 fixes by David W. Miller * linux 2.4 support David McCullough <davidm@lineo.com> *//* * entry.S  contains the system-call and fault low-level handling routines. * This also contains the timer-interrupt handler, as well as all interrupts * and faults that can result in a task-switch. * * NOTE: This code handles signal-recognition, which happens every time * after a timer-interrupt and after each system call. * * Stack layout in 'ret_from_exception': * *	This allows access to the syscall arguments in registers d1-d5 * *	 0(sp) - d1 *	 4(sp) - d2 *	 8(sp) - d3 *	 C(sp) - d4 *	10(sp) - d5 *	14(sp) - a0 *	18(sp) - a1 *	1C(sp) - a2 *	20(sp) - d0 *	24(sp) - orig_d0 *	28(sp) - stack adjustment *	2C(sp) - format & vector      } *	2E(sp) - sr                   } different to m68k *	30(sp) - pc                   } */#include <linux/sys.h>#include <linux/config.h>#include <linux/linkage.h>#include <asm/setup.h>#include <asm/segment.h>#include "m68k_defs.h"LENOSYS = 38/* the following macro is used when enabling interrupts */#define ALLOWINT 0xf8ff#define	MAX_NOINT_IPL	0LD0			= 0x20LORIG_D0	= 0x24LFORMATVEC	= 0x2cLSR			= 0x2eLPC			= 0x30/* * This defines the normal kernel pt-regs layout. * * regs are a2-a6 and d6-d7 preserved by C code * the kernel doesn't mess with usp unless it needs to * *	This is made a little more tricky on the ColdFire. There is no *	separate kernel and user stack pointers. Need to artificially *	construct a usp in software... When doing this we need to disable *	interrupts, otherwise bad things could happen. */#define SAVE_ALL						\	move	#0x2700,%sr;		/* disable intrs */	\	btst	#5,%sp@(2);		/* from user? */	\	bnes	6f;			/* no, skip */		\	movel	%sp,sw_usp;		/* save user sp */	\	addql	#8,sw_usp;		/* remove exception */	\	movel	sw_ksp,%sp;		/* kernel sp */		\	subql	#8,%sp;			/* room for exception */\	clrl	%sp@-;			/* stk_adj */		\	movel	%d0,%sp@-;		/* orig d0 */		\	movel	%d0,%sp@-;		/* d0 */		\	subl	#32,%sp;		/* space for 8 regs */	\	moveml	%d1-%d5/%a0-%a2,%sp@;				\	movel	sw_usp,%a0;		/* get usp */		\	moveml	%a0@(-8),%d1-%d2;	/* get exception */	\	moveml	%d1-%d2,%sp@(LFORMATVEC); /* copy exception */	\	bra	7f;						\	6:							\	clrl	%sp@-;			/* stk_adj */		\	movel	%d0,%sp@-;		/* orig d0 */		\	movel	%d0,%sp@-;		/* d0 */		\	subl	#32,%sp;		/* space for 7 regs */	\	moveml	%d1-%d5/%a0-%a2,%sp@;				\	7:#define RESTORE_ALL						\	btst	#5,%sp@(LSR);		/* going user? */	\	bnes	8f;			/* no, skip */		\	move	#0x2700,%sr;		/* disable intrs */	\	movel	sw_usp,%a0;		/* get usp */		\	moveml	%sp@(LFORMATVEC),%d1-%d2; /* copy exception */	\	moveml	%d1-%d2,%a0@(-8);				\	moveml	%sp@,%d1-%d5/%a0-%a2;				\	addl	#32,%sp;		/* space for 8 regs */	\	movel	%sp@+,%d0;					\	addql	#4,%sp;			/* orig d0 */		\	addl	%sp@+,%sp;		/* stk adj */		\	addql	#8,%sp;			/* remove exception */	\	movel	%sp,sw_ksp;		/* save ksp */		\	subql	#8,sw_usp;		/* set exception */	\	movel	sw_usp,%sp;		/* restore usp */	\	rte;							\	8:							\	moveml	%sp@,%d1-%d5/%a0-%a2;				\	addl	#32,%sp;		/* space for 8 regs */	\	movel	%sp@+,%d0;					\	addql	#4,%sp;			/* orig d0 */		\	addl	%sp@+,%sp;		/* stk adj */		\	rte/* *	Quick exception save, use current stack only. */#define SAVE_LOCAL						\	move	#0x2700,%sr;		/* disable intrs */	\	clrl	%sp@-;			/* stk_adj */		\	movel	%d0,%sp@-;		/* orig d0 */		\	movel	%d0,%sp@-;		/* d0 */		\	subl	#32,%sp;		/* space for 8 regs */	\	moveml	%d1-%d5/%a0-%a2,%sp@;#define RESTORE_LOCAL						\	moveml	%sp@,%d1-%d5/%a0-%a2;				\	addl	#32,%sp;		/* space for 8 regs */	\	movel	%sp@+,%d0;					\	addql	#4,%sp;			/* orig d0 */		\	addl	%sp@+,%sp;		/* stk adj */		\	rte#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */#define SAVE_SWITCH_STACK		\	subl    #24,%sp; /* 6 regs */	\	moveml	%a3-%a6/%d6-%d7,%sp@#define RESTORE_SWITCH_STACK		\	moveml	%sp@,%a3-%a6/%d6-%d7;	\	addl	#24,%sp /* 6 regs *//* *	Software copy of the user and kernel stack pointers... Ugh... *	Need these to get around ColdFire not having separate kernel *	and user stack pointers. */.globl SYMBOL_NAME(sw_usp).globl SYMBOL_NAME(sw_ksp).datasw_ksp:.long	0sw_usp:.long	0.text.globl SYMBOL_NAME(buserr).globl SYMBOL_NAME(trap).globl SYMBOL_NAME(system_call).globl SYMBOL_NAME(resume), SYMBOL_NAME(ret_from_exception).globl SYMBOL_NAME(ret_from_signal).globl SYMBOL_NAME(sys_call_table).globl SYMBOL_NAME(sys_fork), SYMBOL_NAME(sys_clone), SYMBOL_NAME(sys_vfork).globl SYMBOL_NAME(ret_from_interrupt).globl SYMBOL_NAME(inthandler).globl SYMBOL_NAME(fasthandler)#ifdef TRAP_DBG_INTERRUPT.globl SYMBOL_NAME(dbginterrupt)#endif.textENTRY(buserr)	SAVE_ALL	moveq	#-1,%d0	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field								| signifies that the stack frame								| is NOT for syscall	movel	%sp,%sp@- 			| stack frame pointer argument	jsr	SYMBOL_NAME(buserr_c)	addql	#4,%sp	jra	SYMBOL_NAME(ret_from_exception)#ifdef TRAP_DBG_INTERRUPTENTRY(dbginterrupt)	SAVE_ALL	moveq	#-1,%d0	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field								| signifies that the stack frame								| is NOT for syscall	movel	%sp,%sp@- 			| stack frame pointer argument	jsr	SYMBOL_NAME(dbginterrupt_c)	addql	#4,%sp	jra	SYMBOL_NAME(ret_from_exception)#endifENTRY(reschedule)	| save top of frame	pea	%sp@	jbsr	SYMBOL_NAME(set_esp0)	addql	#4,%sp	pea	SYMBOL_NAME(ret_from_exception)	jmp	SYMBOL_NAME(schedule)	| After a fork we jump here directly from resume,	| so that %d1 contains the previous task	| Theoretically only needed on SMP, but lets watch	| what happens in schedule_tail() in future...ENTRY(ret_from_fork)	movel	%d1,%sp@-	jsr	SYMBOL_NAME(schedule_tail)	addql	#4,%sp	jra	SYMBOL_NAME(ret_from_exception)ENTRY(system_call)	SAVE_ALL	move	#0x2000,%sr;		| enable intrs again	movel	#-LENOSYS,%d2	movel	%d2,LD0(%sp)		| default return value in d0					| original D0 is in orig_d0	movel	%d0,%d2	| save top of frame	pea	%sp@	jbsr	SYMBOL_NAME(set_esp0)	addql	#4,%sp	cmpl	#NR_syscalls,%d2	jcc	SYMBOL_NAME(ret_from_exception)	lea	SYMBOL_NAME(sys_call_table),%a0	lsll	#2,%d2		| movel	%a0@(%d2:l:4),%d3	movel	%a0@(%d2),%d3	jeq	SYMBOL_NAME(ret_from_exception)	lsrl	#2,%d2	movel	SYMBOL_NAME(_current_task),%a0	btst	#1,%a0@(TASK_PTRACE+3)	| PT_TRACESYS	bnes	1f	movel	%d3,%a0	jbsr	%a0@	movel	%d0,%sp@(LD0)		| save the return value	jra	SYMBOL_NAME(ret_from_exception)1:	subql	#4,%sp	SAVE_SWITCH_STACK	jbsr	SYMBOL_NAME(syscall_trace)	RESTORE_SWITCH_STACK	addql	#4,%sp	movel	%d3,%a0	jbsr	%a0@	movel	%d0,%sp@(LD0)		| save the return value	subql	#4,%sp			| dummy return address	SAVE_SWITCH_STACK	jbsr	SYMBOL_NAME(syscall_trace)SYMBOL_NAME_LABEL(ret_from_signal)	RESTORE_SWITCH_STACK	addql	#4,%spSYMBOL_NAME_LABEL(ret_from_exception)	btst	#5,%sp@(LSR)		| check if returning to kernel	bnes	2f			| if so, skip resched, signals	| tstl	SYMBOL_NAME(need_resched)	| jne	SYMBOL_NAME(reschedule)	movel	SYMBOL_NAME(_current_task),%a0	tstl	%a0@(TASK_NEEDRESCHED)	jne	SYMBOL_NAME(reschedule)#if 0 /* as per m68k */	cmpl	#SYMBOL_NAME(task),%a0	| task[0] cannot have signals	jeq	2f#endif	bclr	#2,%a0@(TASK_PTRACE+3)	| check for delayed trace	jeq	1f	bclr	#7,%sp@(LSR)		| clear trace bit in SR	pea	1			| send SIGTRAP	movel	%a0,%sp@-	pea	5	jbsr	SYMBOL_NAME(send_sig)	addql	#8,%sp	addql	#4,%sp	movel	SYMBOL_NAME(_current_task),%a01:	tstl	%a0@(TASK_STATE)	| state	jne	SYMBOL_NAME(reschedule)	tstl	%a0@(TASK_COUNTER)	| counter	jeq	SYMBOL_NAME(reschedule)	movel	%a0@(TASK_BLOCKED),%d0	notl	%d0	btst	#0,%a0@(TASK_PTRACE+3)	| PT_PTRACED	jeq	1f	moveq	#-1,%d0			| let the debugger see all signals1:	andl	%a0@(TASK_SIGPENDING),%d0	jne	Lsignal_return2:	RESTORE_ALL			| Does RTELsignal_return:	subql	#4,%sp			| dummy return address	SAVE_SWITCH_STACK	pea	%sp@(SWITCH_STACK_SIZE)	clrl	%sp@-	jsr	SYMBOL_NAME(do_signal)	addql	#8,%sp	RESTORE_SWITCH_STACK	addql	#4,%sp	btst    #5,%sp@(LSR);	/* going user? */   	bnes    not_user;	/* no, skip */      	move    #0x2700,%sr;	/* disable intrs */ 	movel   sw_usp,%a0;	/* get usp */       	moveml  %sp@(LFORMATVEC),%d1-%d2; /* copy exception */  	moveml  %d1-%d2,%a0@(-8);               	bclr    #5,%a0@(-8);  /* clear format byte, bit 5 to make stack appear modulo 4 which it WILL be when we do the rte because it was generated in setup_frame */	bclr    #4,%a0@(-8);  /* clear format byte, bit 4 to make stack appear modulo 4 which it WILL be when we do the rte because it was generated in setup_frame */	/*	 * if an app is getting tricky and using "a5",  the signal handler	 * may trigger while "a5" is invalid,  so we have to set it here	 */	jsr 	SYMBOL_NAME(get_pic_a5)	movel	%d0, %a5	moveml  %sp@,%d1-%d5/%a0-%a2;               	addl    #32,%sp;        /* space for 8 regs */  	movel   %sp@+,%d0;                  	addql   #4,%sp;         /* orig d0 */       	addl    %sp@+,%sp;      /* stk adj */       	addql   #8,%sp;         /* remove exception */  	movel   %sp,sw_ksp;     /* save ksp */      	movel   sw_usp,%sp;     /* restore usp */   	subql   #8,%sp;         /* set exception */ 	rte;                            not_user:                          	moveml  %sp@,%d1-%d5/%a0-%a2;               	addl    #32,%sp;        /* space for 8 regs */  	movel   %sp@+,%d0;                  	addql   #4,%sp;         /* orig d0 */       	addl    %sp@+,%sp;      /* stk adj */       	rte/*--------------------------------------------------------------------------*//* *	Common ColdFire trap handler. Most traps come through here first. */ENTRY(trap)	SAVE_ALL	moveq	#-1,%d0	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field					| signifies that the stack frame					| is NOT for syscall	movel	%sp,%sp@- 		| stack frame pointer argument	jsr	SYMBOL_NAME(trap_c)	addql	#4,%sp	jra	SYMBOL_NAME(ret_from_exception)/* *	This is the generic interrupt handler (for all hardware interrupt *	sources). It figures out the vector number and calls the appropriate *	interrupt service routine directly. */SYMBOL_NAME_LABEL(inthandler)	SAVE_ALL	moveq	#-1,%d0	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field					| signifies that the stack frame					| is NOT for syscall	addql	#1,SYMBOL_NAME(local_irq_count)					| put exception # in d0	movew   %sp@(LFORMATVEC),%d0	andl	#0x03fc,%d0		| mask out vector only	movel	SYMBOL_NAME(mach_kstat_irqs),%a0					| get addr of kstat struct	addql	#1,%a0@(%d0)		| incr irq intr count	lsrl	#2,%d0			| calculate real vector #	movel	%d0,%d1			| calculate array offset	lsll	#4,%d1	lea	SYMBOL_NAME(irq_list),%a0	addl	%d1,%a0			| pointer to array struct	movel	%sp,%sp@-		| push regs arg onto stack	movel	%a0@(8),%sp@-		| push devid arg	movel	%d0,%sp@- 		| push vector # on stack

⌨️ 快捷键说明

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