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

📄 entry.s

📁 讲述linux的初始化过程
💻 S
📖 第 1 页 / 共 3 页
字号:
/* $Id: entry.S,v 1.168 2001/01/01 01:46:15 davem Exp $ * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1996-1999 Jakub Jelinek   (jj@sunsite.mff.cuni.cz) * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au) */#include <linux/config.h>#include <linux/errno.h>#include <asm/head.h>#include <asm/asi.h>#include <asm/smp.h>#include <asm/kgdb.h>#include <asm/contregs.h>#include <asm/ptrace.h>#include <asm/psr.h>#include <asm/cprefix.h>#include <asm/vaddrs.h>#include <asm/memreg.h>#include <asm/page.h>#ifdef CONFIG_SUN4#include <asm/pgtsun4.h>#else#include <asm/pgtsun4c.h>#endif#include <asm/winmacro.h>#include <asm/signal.h>#include <asm/obio.h>#include <asm/mxcc.h>#include <asm/asmmacro.h>#define curptr      g6#define NR_SYSCALLS 256      /* Each OS is different... *//* First, KGDB low level things.  This is a rewrite * of the routines found in the sparc-stub.c asm() statement * from the gdb distribution.  This is also dual-purpose * as a software trap for userlevel programs. */	.data	.align	4in_trap_handler:	.word	0	.text	.align	4! This function is called when any SPARC trap (except window overflow or! underflow) occurs.  It makes sure that the invalid register window is still! available before jumping into C code.  It will also restore the world if you! return from handle_exception.	.globl	C_LABEL(trap_low)C_LABEL(trap_low):	rd	%wim, %l3	SAVE_ALL	sethi	%hi(in_trap_handler), %l4	ld	[%lo(in_trap_handler) + %l4], %l5	inc	%l5	st	%l5, [%lo(in_trap_handler) + %l4]	/* Make sure kgdb sees the same state we just saved. */	LOAD_PT_GLOBALS(sp)	LOAD_PT_INS(sp)	ld	[%sp + REGWIN_SZ + PT_Y], %l4	ld	[%sp + REGWIN_SZ + PT_WIM], %l3	ld	[%sp + REGWIN_SZ + PT_PSR], %l0	ld	[%sp + REGWIN_SZ + PT_PC], %l1	ld	[%sp + REGWIN_SZ + PT_NPC], %l2	rd	%tbr, %l5	/* Never changes... */	/* Make kgdb exception frame. */		sub	%sp,(16+1+6+1+72)*4,%sp	! Make room for input & locals 					! + hidden arg + arg spill					! + doubleword alignment					! + registers[72] local var	SAVE_KGDB_GLOBALS(sp)	SAVE_KGDB_INS(sp)	SAVE_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)	/* We are increasing PIL, so two writes. */	or	%l0, PSR_PIL, %l0	wr	%l0, 0, %psr	WRITE_PAUSE	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(handle_exception)	 add	%sp, REGWIN_SZ, %o0	! Pass address of registers	/* Load new kgdb register set. */	LOAD_KGDB_GLOBALS(sp)	LOAD_KGDB_INS(sp)	LOAD_KGDB_SREGS(sp, l4, l0, l3, l5, l1, l2)	wr      %l4, 0x0, %y	sethi	%hi(in_trap_handler), %l4	ld	[%lo(in_trap_handler) + %l4], %l5	dec	%l5	st	%l5, [%lo(in_trap_handler) + %l4]	add	%sp,(16+1+6+1+72)*4,%sp	! Undo the kgdb trap frame.	/* Now take what kgdb did and place it into the pt_regs	 * frame which SparcLinux RESTORE_ALL understands.,	 */	STORE_PT_INS(sp)	STORE_PT_GLOBALS(sp)	STORE_PT_YREG(sp, g2)	STORE_PT_PRIV(sp, l0, l1, l2)	RESTORE_ALL#ifdef CONFIG_BLK_DEV_FD	.text	.align	4	.globl	C_LABEL(floppy_hardint)C_LABEL(floppy_hardint):	/*	 * This code cannot touch registers %l0 %l1 and %l2	 * because SAVE_ALL depends on their values. It depends	 * on %l3 also, but we regenerate it before a call.	 * Other registers are:	 * %l3 -- base address of fdc registers	 * %l4 -- pdma_vaddr	 * %l5 -- scratch for ld/st address	 * %l6 -- pdma_size	 * %l7 -- scratch [floppy byte, ld/st address, aux. data]	 */	/* Do we have work to do? */	sethi	%hi(C_LABEL(doing_pdma)), %l7	ld	[%l7 + %lo(C_LABEL(doing_pdma))], %l7	cmp	%l7, 0	be	floppy_dosoftint	 nop	/* Load fdc register base */	sethi	%hi(C_LABEL(fdc_status)), %l3	ld	[%l3 + %lo(C_LABEL(fdc_status))], %l3	/* Setup register addresses */	sethi	%hi(C_LABEL(pdma_vaddr)), %l5	! transfer buffer	ld	[%l5 + %lo(C_LABEL(pdma_vaddr))], %l4	sethi	%hi(C_LABEL(pdma_size)), %l5	! bytes to go	ld	[%l5 + %lo(C_LABEL(pdma_size))], %l6next_byte:  	ldub	[%l3], %l7	andcc	%l7, 0x80, %g0		! Does fifo still have data	bz	floppy_fifo_emptied	! fifo has been emptied...	 andcc	%l7, 0x20, %g0		! in non-dma mode still?	bz	floppy_overrun		! nope, overrun	 andcc	%l7, 0x40, %g0		! 0=write 1=read	bz	floppy_write	 sub	%l6, 0x1, %l6	/* Ok, actually read this byte */	ldub	[%l3 + 1], %l7	orcc	%g0, %l6, %g0	stb	%l7, [%l4]	bne	next_byte	 add	%l4, 0x1, %l4	b	floppy_tdone	 nopfloppy_write:	/* Ok, actually write this byte */	ldub	[%l4], %l7	orcc	%g0, %l6, %g0	stb	%l7, [%l3 + 1]	bne	next_byte	 add	%l4, 0x1, %l4	/* fall through... */floppy_tdone:	sethi	%hi(C_LABEL(pdma_vaddr)), %l5	st	%l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]	sethi	%hi(C_LABEL(pdma_size)), %l5	st	%l6, [%l5 + %lo(C_LABEL(pdma_size))]	/* Flip terminal count pin */	set	C_LABEL(auxio_register), %l7	ld	[%l7], %l7	set	C_LABEL(sparc_cpu_model), %l5	ld	[%l5], %l5	subcc   %l5, 1, %g0		/* enum { sun4c = 1 }; */	be	1f	 ldub	[%l7], %l5	or	%l5, 0xc2, %l5	stb	%l5, [%l7]	andn    %l5, 0x02, %l5	b	2f	 nop1:	or      %l5, 0xf4, %l5	stb     %l5, [%l7]	andn    %l5, 0x04, %l52:	/* Kill some time so the bits set */	WRITE_PAUSE	WRITE_PAUSE	stb     %l5, [%l7]	/* Prevent recursion */	sethi	%hi(C_LABEL(doing_pdma)), %l7	b	floppy_dosoftint	 st	%g0, [%l7 + %lo(C_LABEL(doing_pdma))]	/* We emptied the FIFO, but we haven't read everything	 * as of yet.  Store the current transfer address and	 * bytes left to read so we can continue when the next	 * fast IRQ comes in.	 */floppy_fifo_emptied:	sethi	%hi(C_LABEL(pdma_vaddr)), %l5	st	%l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]	sethi	%hi(C_LABEL(pdma_size)), %l7	st	%l6, [%l7 + %lo(C_LABEL(pdma_size))]	/* Restore condition codes */	wr	%l0, 0x0, %psr	WRITE_PAUSE	jmp	%l1	rett	%l2floppy_overrun:	sethi	%hi(C_LABEL(pdma_vaddr)), %l5	st	%l4, [%l5 + %lo(C_LABEL(pdma_vaddr))]	sethi	%hi(C_LABEL(pdma_size)), %l5	st	%l6, [%l5 + %lo(C_LABEL(pdma_size))]	/* Prevent recursion */	sethi	%hi(C_LABEL(doing_pdma)), %l7	st	%g0, [%l7 + %lo(C_LABEL(doing_pdma))]	/* fall through... */floppy_dosoftint:	rd	%wim, %l3	SAVE_ALL	/* Set all IRQs off. */	or	%l0, PSR_PIL, %l4	wr	%l4, 0x0, %psr	WRITE_PAUSE	wr	%l4, PSR_ET, %psr	WRITE_PAUSE	mov	11, %o0			! floppy irq level (unused anyway)	mov	%g0, %o1		! devid is not used in fast interrupts	call	C_LABEL(sparc_floppy_irq)	 add	%sp, REGWIN_SZ, %o2	! struct pt_regs *regs	RESTORE_ALL	#endif /* (CONFIG_BLK_DEV_FD) */	/* Bad trap handler */	.globl	bad_trap_handlerbad_trap_handler:	SAVE_ALL	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	mov	%l7, %o0		! trap number	mov	%l0, %o1		! psr	call	C_LABEL(do_hw_interrupt)	 mov	%l1, %o2		! pc	RESTORE_ALL	/* For now all IRQ's not registered get sent here. handler_irq() will * see if a routine is registered to handle this interrupt and if not * it will say so on the console. */	.align	4	.globl	real_irq_entry, patch_handler_irqreal_irq_entry:	SAVE_ALL#ifdef CONFIG_SMP	.globl	patchme_maybe_smp_msg	cmp	%l7, 12patchme_maybe_smp_msg:	bgu	maybe_smp4m_msg	 nop#endifreal_irq_continue:	or	%l0, PSR_PIL, %g2	wr	%g2, 0x0, %psr	WRITE_PAUSE	wr	%g2, PSR_ET, %psr	WRITE_PAUSE	mov	%l7, %o0		! irq levelpatch_handler_irq:	call	C_LABEL(handler_irq)	 add	%sp, REGWIN_SZ, %o1	! pt_regs ptr	or	%l0, PSR_PIL, %g2	! restore PIL after handler_irq	wr	%g2, PSR_ET, %psr	! keep ET up	WRITE_PAUSE	RESTORE_ALL#ifdef CONFIG_SMP	/* SMP per-cpu ticker interrupts are handled specially. */smp4m_ticker:	bne	real_irq_continue+4	 or	%l0, PSR_PIL, %g2	wr	%g2, 0x0, %psr	WRITE_PAUSE	wr	%g2, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(smp4m_percpu_timer_interrupt)	 add	%sp, REGWIN_SZ, %o0	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	RESTORE_ALL	/* Here is where we check for possible SMP IPI passed to us	 * on some level other than 15 which is the NMI and only used	 * for cross calls.  That has a separate entry point below.	 */maybe_smp4m_msg:	GET_PROCESSOR_MID(o3, o2)	set	C_LABEL(sun4m_interrupts), %l5	ld	[%l5], %o5	sethi	%hi(0x60000000), %o4	sll	%o3, 12, %o3	ld	[%o5 + %o3], %o1	andcc	%o1, %o4, %g0	be,a	smp4m_ticker	 cmp	%l7, 14	cmp	%l7, 13	add	%o5, %o3, %o5	bne,a	1f	 sethi	%hi(0x40000000), %o2	sethi	%hi(0x20000000), %o21:	st	%o2, [%o5 + 0x4]	WRITE_PAUSE	ld	[%o5], %g0	WRITE_PAUSE	or	%l0, PSR_PIL, %l4	wr	%l4, 0x0, %psr	WRITE_PAUSE	wr	%l4, PSR_ET, %psr	WRITE_PAUSE	cmp	%l7, 13	bne	2f	 nop	call	C_LABEL(smp_reschedule_irq)	 add	%o7, 8, %o72:	call	C_LABEL(smp_stop_cpu_irq)	 nop	RESTORE_ALL	.align	4	.globl	linux_trap_ipi15_sun4mlinux_trap_ipi15_sun4m:	SAVE_ALL	sethi	%hi(0x80000000), %o2	GET_PROCESSOR_MID(o0, o1)	set	C_LABEL(sun4m_interrupts), %l5	ld	[%l5], %o5	sll	%o0, 12, %o0	add	%o5, %o0, %o5	ld	[%o5], %o3	andcc	%o3, %o2, %g0	be	1f			! Must be an NMI async memory error	 st	%o2, [%o5 + 4]	WRITE_PAUSE	ld	[%o5], %g0	WRITE_PAUSE	or	%l0, PSR_PIL, %l4	wr	%l4, 0x0, %psr	WRITE_PAUSE	wr	%l4, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(smp4m_cross_call_irq)	 nop	b	ret_trap_lockless_ipi	 clr	%l61:	/* NMI async memory error handling. */	sethi	%hi(0x80000000), %l4	sethi	%hi(0x4000), %o3	sub	%o5, %o0, %o5	add	%o5, %o3, %l5	st	%l4, [%l5 + 0xc]	WRITE_PAUSE	ld	[%l5], %g0	WRITE_PAUSE	or	%l0, PSR_PIL, %l4	wr	%l4, 0x0, %psr	WRITE_PAUSE	wr	%l4, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(sun4m_nmi)	 nop	st	%l4, [%l5 + 0x8]	WRITE_PAUSE	ld	[%l5], %g0	WRITE_PAUSE	RESTORE_ALL	.globl	smp4d_ticker	/* SMP per-cpu ticker interrupts are handled specially. */smp4d_ticker:	SAVE_ALL	or	%l0, PSR_PIL, %g2	sethi	%hi(CC_ICLR), %o0	sethi	%hi(1 << 14), %o1	or	%o0, %lo(CC_ICLR), %o0	stha	%o1, [%o0] ASI_M_MXCC	/* Clear PIL 14 in MXCC's ICLR */	wr	%g2, 0x0, %psr	WRITE_PAUSE	wr	%g2, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(smp4d_percpu_timer_interrupt)	 add	%sp, REGWIN_SZ, %o0	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	RESTORE_ALL	.align	4	.globl	linux_trap_ipi15_sun4dlinux_trap_ipi15_sun4d:	SAVE_ALL	sethi	%hi(CC_BASE), %o4	sethi	%hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2	or	%o4, (CC_EREG - CC_BASE), %o0	ldda	[%o0] ASI_M_MXCC, %o0	andcc	%o0, %o2, %g0	bne	1f	 sethi	%hi(BB_STAT2), %o2	lduba	[%o2] ASI_M_CTL, %o2	andcc	%o2, BB_STAT2_MASK, %g0	bne	2f	 or	%o4, (CC_ICLR - CC_BASE), %o0	sethi	%hi(1 << 15), %o1	stha	%o1, [%o0] ASI_M_MXCC	/* Clear PIL 15 in MXCC's ICLR */	or	%l0, PSR_PIL, %l4	wr	%l4, 0x0, %psr	WRITE_PAUSE	wr	%l4, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(smp4d_cross_call_irq)	 nop	b	ret_trap_lockless_ipi	 clr	%l61:	/* MXCC error */2:	/* BB error */	/* Disable PIL 15 */	set	CC_IMSK, %l4	lduha	[%l4] ASI_M_MXCC, %l5	sethi	%hi(1 << 15), %l7	or	%l5, %l7, %l5	stha	%l5, [%l4] ASI_M_MXCC	/* FIXME */1:	b,a	1b#endif /* CONFIG_SMP */	/* This routine handles illegal instructions and privileged	 * instruction attempts from user code.	 */	.align	4	.globl	bad_instructionbad_instruction:	sethi	%hi(0xc1f80000), %l4	ld	[%l1], %l5	sethi	%hi(0x81d80000), %l7	and	%l5, %l4, %l5	cmp	%l5, %l7	be	1f	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(do_illegal_instruction)	 mov	%l0, %o3	RESTORE_ALL1:	/* unimplemented flush - just skip */	jmpl	%l2, %g0	 rett	%l2 + 4	.align	4	.globl	priv_instructionpriv_instruction:	SAVE_ALL	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(do_priv_instruction)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles unaligned data accesses. */	.align	4	.globl	mna_handlermna_handler:	andcc	%l0, PSR_PS, %g0	be	mna_fromuser	 nop	SAVE_ALL	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	ld	[%l1], %o1	call	C_LABEL(kernel_unaligned_trap)	 add	%sp, REGWIN_SZ, %o0	RESTORE_ALLmna_fromuser:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	ld	[%l1], %o1	call	C_LABEL(user_unaligned_trap)	 add	%sp, REGWIN_SZ, %o0	RESTORE_ALL	/* This routine handles floating point disabled traps. */	.align	4	.globl	fpd_trap_handlerfpd_trap_handler:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(do_fpd_trap)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Floating Point Exceptions. */	.align	4	.globl	fpe_trap_handlerfpe_trap_handler:	set	fpsave_magic, %l5	cmp	%l1, %l5	be	1f	 sethi	%hi(C_LABEL(fpsave)), %l5	or	%l5, %lo(C_LABEL(fpsave)), %l5	cmp	%l1, %l5	bne	2f	 sethi	%hi(fpsave_catch2), %l5	or	%l5, %lo(fpsave_catch2), %l5	wr	%l0, 0x0, %psr	WRITE_PAUSE	jmp	%l5	 rett	%l5 + 41:		sethi	%hi(fpsave_catch), %l5	or	%l5, %lo(fpsave_catch), %l5	wr	%l0, 0x0, %psr	WRITE_PAUSE	jmp	%l5	 rett	%l5 + 42:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(do_fpe_trap)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Tag Overflow Exceptions. */	.align	4	.globl	do_tag_overflowdo_tag_overflow:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(handle_tag_overflow)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Watchpoint Exceptions. */	.align	4	.globl	do_watchpointdo_watchpoint:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(handle_watchpoint)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Register Access Exceptions. */	.align	4

⌨️ 快捷键说明

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