patch-2.1.124 linux/arch/sparc64/kernel/winfixup.S

Next file: linux/arch/sparc64/lib/checksum.S
Previous file: linux/arch/sparc64/kernel/unaligned.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.123/linux/arch/sparc64/kernel/winfixup.S linux/arch/sparc64/kernel/winfixup.S
@@ -1,4 +1,4 @@
-/* $Id: winfixup.S,v 1.24 1998/06/12 14:54:19 jj Exp $
+/* $Id: winfixup.S,v 1.27 1998/09/25 01:09:14 davem Exp $
  *
  * winfixup.S: Handle cases where user stack pointer is found to be bogus.
  *
@@ -27,7 +27,7 @@
 	 * These are layed out in a special way for cache reasons,
 	 * don't touch...
 	 */
-	.globl	winfix_trampoline, fill_fixup, spill_fixup
+	.globl	fill_fixup, spill_fixup
 fill_fixup:
 	rdpr		%tstate, %g1
 	andcc		%g1, TSTATE_PRIV, %g0
@@ -192,8 +192,8 @@
 	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.
 	flush		%g6				! Flush instruction buffers
 	rdpr		%pstate, %l1			! Prepare to change globals.
-	mov		%g4, %o5			! Setup args for
-	mov		%g5, %o4			! final call to do_sparc64_fault.
+	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.
@@ -261,7 +261,116 @@
 	sethi		%hi(109f), %g7
 	ba,pt		%xcc, etrap
 109:	 or		%g7, %lo(109b), %g7
+	mov		%l4, %o2
+	mov		%l5, %o1
 	call		mem_address_unaligned
+	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
+	ba,pt		%xcc, rtrap
+	 clr		%l6
+	
+	/* These are only needed for 64-bit mode processes which
+	 * put their stack pointer into the VPTE area and there
+	 * happens to be a VPTE tlb entry mapped there during
+	 * a spill/fill trap to that stack frame.
+	 */
+	.globl		winfix_dax, fill_fixup_dax, spill_fixup_dax
+winfix_dax:
+	andn		%g3, 0x7f, %g3
+	add		%g3, 0x74, %g3
+	wrpr		%g3, %tnpc
+	done
+fill_fixup_dax:
+	rdpr		%tstate, %g1
+	andcc		%g1, TSTATE_PRIV, %g0
+	be,pt		%xcc, window_dax_from_user_common
+	 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 consistant.
+	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, %o1			! Setup args for
+	mov		%g5, %o2			! final call to data_access_exception.
+	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
+	sethi		%uhi(PAGE_OFFSET), %g4		! Set page_offset global reg.
+	mov		%o7, %g6			! Get current back.
+	sllx		%g4, 32, %g4			! Finish it.
+	call		data_access_exception
+	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
+
+	b,pt		%xcc, rtrap
+	 nop						! yes, the nop is correct
+spill_fixup_dax:
+	lduh		[%g6 + AOFF_task_tss + AOFF_thread_flags], %g1
+	andcc		%g1, SPARC_FLAG_32BIT, %g0
+	lduh		[%g6 + AOFF_task_tss + AOFF_thread_w_saved], %g1
+	sll		%g1, 3, %g3
+	add		%g6, %g3, %g3
+	stx		%sp, [%g3 + AOFF_task_tss + AOFF_thread_rwbuf_stkptrs]
+
+	sll		%g1, 7, %g3
+	bne,pt		%xcc, 1f
+	 add		%g6, %g3, %g3
+	stx		%l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
+	stx		%l1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
+	stx		%l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
+	stx		%l3, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x18]
+	stx		%l4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x20]
+
+	stx		%l5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x28]
+	stx		%l6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x30]
+	stx		%l7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x38]
+	stx		%i0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x40]
+	stx		%i1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x48]
+	stx		%i2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x50]
+	stx		%i3, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x58]
+	stx		%i4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x60]
+
+	stx		%i5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x68]
+	stx		%i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x70]
+	stx		%i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x78]
+	b,pt		%xcc, 2f
+	 add		%g1, 1, %g1
+1:	std		%l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
+	std		%l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
+	std		%l4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
+
+	std		%l6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x18]
+	std		%i0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x20]
+	std		%i2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x28]
+	std		%i4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x30]
+	std		%i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x38]
+	add		%g1, 1, %g1
+2:	sth		%g1, [%g6 + AOFF_task_tss + AOFF_thread_w_saved]
+	rdpr		%tstate, %g1
+
+	andcc		%g1, TSTATE_PRIV, %g0
+	saved
+	be,pn		%xcc, window_dax_from_user_common
+	 and		%g1, TSTATE_CWP, %g1
+	retry
+window_dax_from_user_common:
+	wrpr		%g1, %cwp
+	sethi		%hi(109f), %g7
+	ba,pt		%xcc, etrap
+109:	 or		%g7, %lo(109b), %g7
+	mov		%l4, %o1
+	mov		%l5, %o2
+	call		data_access_exception
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
 	ba,pt		%xcc, rtrap
 	 clr		%l6

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov