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

📄 winfixup.s

📁 open source bios with linux platform, very good and can be reused.
💻 S
字号:
/* $Id: winfixup.S,v 1.30 2002/02/09 19:49:30 davem Exp $ * * winfixup.S: Handle cases where user stack pointer is found to be bogus. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) */#include "asi.h"#include "spitfire.h"#if 0#include <asm/head.h>#include <asm/page.h>#include <asm/ptrace.h>#include <asm/processor.h>#include <asm/thread_info.h>#else#define FAULT_CODE_WRITE        0x01    /* Write access, implies D-TLB     */#define FAULT_CODE_DTLB         0x02    /* Miss happened in D-TLB          */#define FAULT_CODE_ITLB         0x04    /* Miss happened in I-TLB          */#define FAULT_CODE_WINFIXUP     0x08    /* Miss happened during spill/fill */#define FAULT_CODE_BLKCOMMIT    0x10    /* Use blk-commit ASI in copy_page */#endif	.text	.align	32	/* Here are the rules, pay attention.	 *	 * The kernel is disallowed from touching user space while	 * the trap level is greater than zero, except for from within	 * the window spill/fill handlers.  This must be followed	 * so that we can easily detect the case where we tried to	 * spill/fill with a bogus (or unmapped) user stack pointer.	 *	 * These are layed out in a special way for cache reasons,	 * don't touch...	 */	.globl	fill_fixup, spill_fixupfill_fixup:	rdpr		%tstate, %g1	or		%g4, FAULT_CODE_WINFIXUP, %g4	and		%g1, TSTATE_CWP, %g1	/* This is the extremely complex case, but it does happen from	 * time to time if things are just right.  Essentially the restore	 * done in rtrap right before going back to user mode, with tl=1	 * and that levels trap stack registers all setup, took a fill trap,	 * the user stack was not mapped in the tlb, and tlb miss occurred,	 * the pte found was not valid, and a simple ref bit watch update	 * could not satisfy the miss, so we got here.	 *	 * We must carefully unwind the state so we get back to tl=0, preserve	 * all the register values we were going to give to the user.  Luckily	 * most things are where they need to be, we also have the address	 * which triggered the fault handy as well.	 *	 * Also note that we must preserve %l5 and %l6.  If the user was	 * returning from a system call, we must make it look this way	 * after we process the fill fault on the users stack.	 *	 * First, get into the window where the original restore was executed.	 */	rdpr		%wstate, %g2			! Grab user mode wstate.	wrpr		%g1, %cwp			! Get into the right window.	sll		%g2, 3, %g2			! NORMAL-->OTHER	wrpr		%g0, 0x0, %canrestore		! Standard etrap stuff.	wrpr		%g2, 0x0, %wstate		! This must be consistent.	wrpr		%g0, 0x0, %otherwin		! We know this.	mov		PRIMARY_CONTEXT, %g1		! Change contexts...	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.	flush		%g6				! Flush instruction buffers	rdpr		%pstate, %l1			! Prepare to change globals.	mov		%g6, %o7			! Get current.	andn		%l1, PSTATE_MM, %l1		! We want to be in RMO	stb		%g4, [%g6 + TI_FAULT_CODE]	stx		%g5, [%g6 + TI_FAULT_ADDR]	wrpr		%g0, 0x0, %tl			! Out of trap levels.	wrpr		%l1, (PSTATE_IE | PSTATE_AG | PSTATE_RMO), %pstate	mov		%o7, %g6	ldx		[%g6 + TI_TASK], %g4	/* This is the same as below, except we handle this a bit special	 * since we must preserve %l5 and %l6, see comment above.	 */	call		do_sparc64_fault	 add		%sp, PTREGS_OFF, %o0	ba,pt		%xcc, rtrap	 nop						! yes, nop is correct	/* Be very careful about usage of the alternate globals here.	 * You cannot touch %g4/%g5 as that has the fault information	 * should this be from usermode.  Also be careful for the case	 * where we get here from the save instruction in etrap.S when	 * coming from either user or kernel (does not matter which, it	 * is the same problem in both cases).  Essentially this means	 * do not touch %g7 or %g2 so we handle the two cases fine.	 */spill_fixup:	ldx		[%g6 + TI_FLAGS], %g1	andcc		%g1, _TIF_32BIT, %g0	ldub		[%g6 + TI_WSAVED], %g1	sll		%g1, 3, %g3	add		%g6, %g3, %g3	stx		%sp, [%g3 + TI_RWIN_SPTRS]	sll		%g1, 7, %g3	bne,pt		%xcc, 1f	 add		%g6, %g3, %g3	stx		%l0, [%g3 + TI_REG_WINDOW + 0x00]	stx		%l1, [%g3 + TI_REG_WINDOW + 0x08]	stx		%l2, [%g3 + TI_REG_WINDOW + 0x10]	stx		%l3, [%g3 + TI_REG_WINDOW + 0x18]	stx		%l4, [%g3 + TI_REG_WINDOW + 0x20]	stx		%l5, [%g3 + TI_REG_WINDOW + 0x28]	stx		%l6, [%g3 + TI_REG_WINDOW + 0x30]	stx		%l7, [%g3 + TI_REG_WINDOW + 0x38]	stx		%i0, [%g3 + TI_REG_WINDOW + 0x40]	stx		%i1, [%g3 + TI_REG_WINDOW + 0x48]	stx		%i2, [%g3 + TI_REG_WINDOW + 0x50]	stx		%i3, [%g3 + TI_REG_WINDOW + 0x58]	stx		%i4, [%g3 + TI_REG_WINDOW + 0x60]	stx		%i5, [%g3 + TI_REG_WINDOW + 0x68]	stx		%i6, [%g3 + TI_REG_WINDOW + 0x70]	b,pt		%xcc, 2f	 stx		%i7, [%g3 + TI_REG_WINDOW + 0x78]1:	stw		%l0, [%g3 + TI_REG_WINDOW + 0x00]	stw		%l1, [%g3 + TI_REG_WINDOW + 0x04]	stw		%l2, [%g3 + TI_REG_WINDOW + 0x08]	stw		%l3, [%g3 + TI_REG_WINDOW + 0x0c]	stw		%l4, [%g3 + TI_REG_WINDOW + 0x10]	stw		%l5, [%g3 + TI_REG_WINDOW + 0x14]	stw		%l6, [%g3 + TI_REG_WINDOW + 0x18]	stw		%l7, [%g3 + TI_REG_WINDOW + 0x1c]	stw		%i0, [%g3 + TI_REG_WINDOW + 0x20]	stw		%i1, [%g3 + TI_REG_WINDOW + 0x24]	stw		%i2, [%g3 + TI_REG_WINDOW + 0x28]	stw		%i3, [%g3 + TI_REG_WINDOW + 0x2c]	stw		%i4, [%g3 + TI_REG_WINDOW + 0x30]	stw		%i5, [%g3 + TI_REG_WINDOW + 0x34]	stw		%i6, [%g3 + TI_REG_WINDOW + 0x38]	stw		%i7, [%g3 + TI_REG_WINDOW + 0x3c]2:	add		%g1, 1, %g1	stb		%g1, [%g6 + TI_WSAVED]	rdpr		%tstate, %g1	saved	and		%g1, TSTATE_CWP, %g1	mov		FAULT_CODE_WRITE | FAULT_CODE_DTLB | FAULT_CODE_WINFIXUP, %g4	retry	.globl		winfix_mna, fill_fixup_mna, spill_fixup_mnawinfix_mna:	andn		%g3, 0x7f, %g3	add		%g3, 0x78, %g3	wrpr		%g3, %tnpc	donefill_fixup_mna:	rdpr		%tstate, %g1	and		%g1, TSTATE_CWP, %g1	/* Please, see fill_fixup commentary about why we must preserve	 * %l5 and %l6 to preserve absolute correct semantics.	 */	rdpr		%wstate, %g2			! Grab user mode wstate.	wrpr		%g1, %cwp			! Get into the right window.	sll		%g2, 3, %g2			! NORMAL-->OTHER	wrpr		%g0, 0x0, %canrestore		! Standard etrap stuff.	wrpr		%g2, 0x0, %wstate		! This must be consistent.	wrpr		%g0, 0x0, %otherwin		! We know this.	mov		PRIMARY_CONTEXT, %g1		! Change contexts...	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.	flush		%g6				! Flush instruction buffers	rdpr		%pstate, %l1			! Prepare to change globals.	mov		%g4, %o2			! Setup args for	mov		%g5, %o1			! final call to mem_address_unaligned.	andn		%l1, PSTATE_MM, %l1		! We want to be in RMO	mov		%g6, %o7			! Stash away current.	wrpr		%g0, 0x0, %tl			! Out of trap levels.	wrpr		%l1, (PSTATE_IE | PSTATE_AG | PSTATE_RMO), %pstate	mov		%o7, %g6			! Get current back.	ldx		[%g6 + TI_TASK], %g4		! Finish it.	call		mem_address_unaligned	 add		%sp, PTREGS_OFF, %o0	b,pt		%xcc, rtrap	 nop						! yes, the nop is correctspill_fixup_mna:	ldx		[%g6 + TI_FLAGS], %g1	andcc		%g1, _TIF_32BIT, %g0	ldub		[%g6 + TI_WSAVED], %g1	sll		%g1, 3, %g3	add		%g6, %g3, %g3	stx		%sp, [%g3 + TI_RWIN_SPTRS]	sll		%g1, 7, %g3	bne,pt		%xcc, 1f	 add		%g6, %g3, %g3	stx		%l0, [%g3 + TI_REG_WINDOW + 0x00]	stx		%l1, [%g3 + TI_REG_WINDOW + 0x08]	stx		%l2, [%g3 + TI_REG_WINDOW + 0x10]	stx		%l3, [%g3 + TI_REG_WINDOW + 0x18]	stx		%l4, [%g3 + TI_REG_WINDOW + 0x20]	stx		%l5, [%g3 + TI_REG_WINDOW + 0x28]	stx		%l6, [%g3 + TI_REG_WINDOW + 0x30]	stx		%l7, [%g3 + TI_REG_WINDOW + 0x38]	stx		%i0, [%g3 + TI_REG_WINDOW + 0x40]	stx		%i1, [%g3 + TI_REG_WINDOW + 0x48]	stx		%i2, [%g3 + TI_REG_WINDOW + 0x50]	stx		%i3, [%g3 + TI_REG_WINDOW + 0x58]	stx		%i4, [%g3 + TI_REG_WINDOW + 0x60]	stx		%i5, [%g3 + TI_REG_WINDOW + 0x68]	stx		%i6, [%g3 + TI_REG_WINDOW + 0x70]	stx		%i7, [%g3 + TI_REG_WINDOW + 0x78]	b,pt		%xcc, 2f	 add		%g1, 1, %g11:	std		%l0, [%g3 + TI_REG_WINDOW + 0x00]	std		%l2, [%g3 + TI_REG_WINDOW + 0x08]	std		%l4, [%g3 + TI_REG_WINDOW + 0x10]	std		%l6, [%g3 + TI_REG_WINDOW + 0x18]	std		%i0, [%g3 + TI_REG_WINDOW + 0x20]	std		%i2, [%g3 + TI_REG_WINDOW + 0x28]	std		%i4, [%g3 + TI_REG_WINDOW + 0x30]	std		%i6, [%g3 + TI_REG_WINDOW + 0x38]	add		%g1, 1, %g12:	stb		%g1, [%g6 + TI_WSAVED]	saved	retry	

⌨️ 快捷键说明

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