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

Next file: linux/arch/sparc64/lib/Makefile
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.43/linux/arch/sparc64/kernel/winfixup.S linux/arch/sparc64/kernel/winfixup.S
@@ -1,4 +1,4 @@
-/* $Id: winfixup.S,v 1.8 1997/06/02 06:33:35 davem Exp $
+/* $Id: winfixup.S,v 1.15 1997/07/04 01:41:07 davem Exp $
  *
  * winfixup.S: Handle cases where user stack pointer is found to be bogus.
  *
@@ -31,6 +31,7 @@
 fill_fixup:
 	rdpr		%tstate, %g1
 	andcc		%g1, TSTATE_PRIV, %g0
+	clr		%g4
 	be,pt		%xcc, window_scheisse_from_user_common
 	 and		%g1, TSTATE_CWP, %g1
 
@@ -53,25 +54,26 @@
 	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		%g0, 0x0, %canrestore		! Standard etrap stuff.
+	wr		%g0, 0x0, %fprs			! zap FPU just in case...
 	wrpr		%g2, 0x0, %wstate		! This must be consistant.
 	wrpr		%g0, 0x0, %otherwin		! We know this.
-	sethi		%uhi(KERNBASE), %g2		! Set this up
-	sllx		%g2, 32, %g2			! for the iflush
 	mov		PRIMARY_CONTEXT, %g1		! Change contexts...
 	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.
-	flush		%g2				! Flush instruction buffers
+	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		%g6, %o7			! Get current.
+	mov		%g5, %l5			! Fault address
+	clr		%l4				! It was a load, not a store
 	wrpr		%g0, 0x0, %tl			! Out of trap levels.
 	wrpr		%l1, (PSTATE_IE | PSTATE_AG), %pstate
-	sethi		%uhi(KERNBASE), %g4		! Restore med-any global reg.
-	rd		%pic, %g6			! Get current as well.
+	sethi		%uhi(PAGE_OFFSET), %g4		! Prepare page_offset global reg
+	mov		%o7, %g6
 	b,pt		%xcc, window_scheisse_merge	! And merge.
-	 sllx		%g4, 32, %g4			! Finish med-any reg setup.
+
+	 sllx		%g4, 32, %g4			! and finish it...
 
 	/* Be very careful about usage of the alternate globals here.
 	 * You cannot touch %g4/%g5 as that has the fault information
@@ -82,17 +84,16 @@
 	 * do not touch %g7 or %g2 so we handle the two cases fine.
 	 */
 spill_fixup:
-	rd		%pic, %g1
-	ldx		[%g1 + AOFF_task_tss + AOFF_thread_flags], %g6
-	andcc		%g6, SPARC_FLAG_32BIT, %g0
-	ldx		[%g1 + AOFF_task_tss + AOFF_thread_w_saved], %g6
-	sll		%g6, 3, %g3
-	add		%g1, %g3, %g3
+	ld		[%g6 + AOFF_task_tss + AOFF_thread_flags], %g1
+	andcc		%g1, SPARC_FLAG_32BIT, %g0
+	ldx		[%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		%g6, 7, %g3
+	sll		%g1, 7, %g3
 
 	bne,pt		%xcc, 1f
-	 add		%g1, %g3, %g3
+	 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]
@@ -110,43 +111,45 @@
 	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		%g6, 1, %g6
-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		%g6, 1, %g6
-2:	stx		%g6, [%g1 + AOFF_task_tss + AOFF_thread_w_saved]
+	 stx		%i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x78]
+1:	stw		%l0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x00]
+	stw		%l1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x04]
+	stw		%l2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x08]
+	stw		%l3, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x0c]
+	stw		%l4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x10]
+
+	stw		%l5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x14]
+	stw		%l6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x18]
+	stw		%l7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x1c]
+	stw		%i0, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x20]
+	stw		%i1, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x24]
+	stw		%i2, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x28]
+	stw		%i3, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x2c]
+	stw		%i4, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x30]
+
+	stw		%i5, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x34]
+	stw		%i6, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x38]
+	stw		%i7, [%g3 + AOFF_task_tss + AOFF_thread_reg_window + 0x3c]
+2:	add		%g1, 1, %g1
+	stx		%g1, [%g6 + AOFF_task_tss + AOFF_thread_w_saved]
 	rdpr		%tstate, %g1
-	nop
-
 	andcc		%g1, TSTATE_PRIV, %g0
 	saved
+
 	and		%g1, TSTATE_CWP, %g1
 	be,a,pn		%xcc, window_scheisse_from_user_common
 	 or		%g4, 0x4, %g4			! we know it was a write
 	retry
 window_scheisse_from_user_common:
-	nop
 	wrpr		%g1, %cwp
-
 	ba,pt		%xcc, etrap
 	 rd		%pc, %g7
-	mov		%l5, %o4
-	mov		%l4, %o5
 window_scheisse_merge:
-	srlx		%o4, PAGE_SHIFT, %o3
-	clr		%o1
-	sllx		%o3, PAGE_SHIFT, %o3
-	and		%o5, 0x4, %o2
+	srlx		%l5, PAGE_SHIFT, %o1
 
+	and		%l4, 0x4, %o2
+	sllx		%o1, PAGE_SHIFT, %o1
 	call		do_sparc64_fault
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
 	ba,pt		%xcc, rtrap
@@ -154,6 +157,7 @@
 winfix_trampoline:
 	andn		%g3, 0x7f, %g3
 	add		%g3, 0x7c, %g3
+
 	wrpr		%g3, %tnpc
 	done
 
@@ -174,32 +178,31 @@
 	wrpr		%g0, 0x0, %canrestore		! Standard etrap stuff.
 	wrpr		%g2, 0x0, %wstate		! This must be consistant.
 	wrpr		%g0, 0x0, %otherwin		! We know this.
-	sethi		%uhi(KERNBASE), %g2		! Set this up
-	sllx		%g2, 32, %g2			! for the iflush
 	mov		PRIMARY_CONTEXT, %g1		! Change contexts...
 	stxa		%g0, [%g1] ASI_DMMU		! Back into the nucleus.
-	flush		%g2				! Flush instruction buffers
+	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		%g6, %o7			! Stash away current.
 	wrpr		%g0, 0x0, %tl			! Out of trap levels.
 	wrpr		%l1, (PSTATE_IE | PSTATE_AG), %pstate
-	sethi		%uhi(KERNBASE), %g4		! Restore med-any global reg.
-	rd		%pic, %g6			! Get current as well.
+	sethi		%uhi(PAGE_OFFSET), %g4		! Set page_offset global reg.
+	mov		%o7, %g6			! Get current back.
 	b,pt		%xcc, window_mna_merge		! And merge.
-	 sllx		%g4, 32, %g4			! Finish med-any reg setup.
+	 sllx		%g4, 32, %g4			! Finish it.
+
 spill_fixup_mna:
-	rd		%pic, %g1
-	ldx		[%g1 + AOFF_task_tss + AOFF_thread_flags], %g6
-	andcc		%g6, SPARC_FLAG_32BIT, %g0
-	ldx		[%g1 + AOFF_task_tss + AOFF_thread_w_saved], %g6
-	sll		%g6, 3, %g3
-	add		%g1, %g3, %g3
+	ld		[%g6 + AOFF_task_tss + AOFF_thread_flags], %g1
+	andcc		%g1, SPARC_FLAG_32BIT, %g0
+	ldx		[%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		%g6, 7, %g3
+	sll		%g1, 7, %g3
 
 	bne,pt		%xcc, 1f
-	 add		%g1, %g3, %g3
+	 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]
@@ -219,7 +222,7 @@
 	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		%g6, 1, %g6
+	 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]
@@ -229,8 +232,8 @@
 	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		%g6, 1, %g6
-2:	stx		%g6, [%g1 + AOFF_task_tss + AOFF_thread_w_saved]
+	add		%g1, 1, %g1
+2:	stx		%g1, [%g6 + AOFF_task_tss + AOFF_thread_w_saved]
 	rdpr		%tstate, %g1
 	nop
 

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