mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	 49fa523046
			
		
	
	
		49fa523046
		
	
	
	
	
		
			
			The system call tracing bug fix mentioned in the Fixes tag
below increased the amount of assembler code in the sequence
of assembler files included by head_64.S
This caused to total set of code to exceed 0x4000 bytes in
size, which overflows the expression in head_64.S that works
to place swapper_tsb at address 0x408000.
When this is violated, the TSB is not properly aligned, and
also the trap table is not aligned properly either.  All of
this together results in failed boots.
So, do two things:
1) Simplify some code by using ba,a instead of ba/nop to get
   those bytes back.
2) Add a linker script assertion to make sure that if this
   happens again the build will fail.
Fixes: 1a40b95374 ("sparc: Fix system call tracing register handling.")
Reported-by: Meelis Roos <mroos@linux.ee>
Reported-by: Joerg Abraham <joerg.abraham@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
		
	
			
		
			
				
	
	
		
			576 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			576 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| 	/* These get patched into the trap table at boot time
 | |
| 	 * once we know we have a cheetah processor.
 | |
| 	 */
 | |
| 	.globl		cheetah_fecc_trap_vector
 | |
| 	.type		cheetah_fecc_trap_vector,#function
 | |
| cheetah_fecc_trap_vector:
 | |
| 	membar		#Sync
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1
 | |
| 	andn		%g1, DCU_DC | DCU_IC, %g1
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG
 | |
| 	membar		#Sync
 | |
| 	sethi		%hi(cheetah_fast_ecc), %g2
 | |
| 	jmpl		%g2 + %lo(cheetah_fast_ecc), %g0
 | |
| 	 mov		0, %g1
 | |
| 	.size		cheetah_fecc_trap_vector,.-cheetah_fecc_trap_vector
 | |
| 
 | |
| 	.globl		cheetah_fecc_trap_vector_tl1
 | |
| 	.type		cheetah_fecc_trap_vector_tl1,#function
 | |
| cheetah_fecc_trap_vector_tl1:
 | |
| 	membar		#Sync
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1
 | |
| 	andn		%g1, DCU_DC | DCU_IC, %g1
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG
 | |
| 	membar		#Sync
 | |
| 	sethi		%hi(cheetah_fast_ecc), %g2
 | |
| 	jmpl		%g2 + %lo(cheetah_fast_ecc), %g0
 | |
| 	 mov		1, %g1
 | |
| 	.size		cheetah_fecc_trap_vector_tl1,.-cheetah_fecc_trap_vector_tl1
 | |
| 
 | |
| 	.globl	cheetah_cee_trap_vector
 | |
| 	.type	cheetah_cee_trap_vector,#function
 | |
| cheetah_cee_trap_vector:
 | |
| 	membar		#Sync
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1
 | |
| 	andn		%g1, DCU_IC, %g1
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG
 | |
| 	membar		#Sync
 | |
| 	sethi		%hi(cheetah_cee), %g2
 | |
| 	jmpl		%g2 + %lo(cheetah_cee), %g0
 | |
| 	 mov		0, %g1
 | |
| 	.size		cheetah_cee_trap_vector,.-cheetah_cee_trap_vector
 | |
| 
 | |
| 	.globl		cheetah_cee_trap_vector_tl1
 | |
| 	.type		cheetah_cee_trap_vector_tl1,#function
 | |
| cheetah_cee_trap_vector_tl1:
 | |
| 	membar		#Sync
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1
 | |
| 	andn		%g1, DCU_IC, %g1
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG
 | |
| 	membar		#Sync
 | |
| 	sethi		%hi(cheetah_cee), %g2
 | |
| 	jmpl		%g2 + %lo(cheetah_cee), %g0
 | |
| 	 mov		1, %g1
 | |
| 	.size		cheetah_cee_trap_vector_tl1,.-cheetah_cee_trap_vector_tl1
 | |
| 
 | |
| 	.globl	cheetah_deferred_trap_vector
 | |
| 	.type	cheetah_deferred_trap_vector,#function
 | |
| cheetah_deferred_trap_vector:
 | |
| 	membar		#Sync
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1;
 | |
| 	andn		%g1, DCU_DC | DCU_IC, %g1;
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG;
 | |
| 	membar		#Sync;
 | |
| 	sethi		%hi(cheetah_deferred_trap), %g2
 | |
| 	jmpl		%g2 + %lo(cheetah_deferred_trap), %g0
 | |
| 	 mov		0, %g1
 | |
| 	.size		cheetah_deferred_trap_vector,.-cheetah_deferred_trap_vector
 | |
| 
 | |
| 	.globl		cheetah_deferred_trap_vector_tl1
 | |
| 	.type		cheetah_deferred_trap_vector_tl1,#function
 | |
| cheetah_deferred_trap_vector_tl1:
 | |
| 	membar		#Sync;
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1;
 | |
| 	andn		%g1, DCU_DC | DCU_IC, %g1;
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG;
 | |
| 	membar		#Sync;
 | |
| 	sethi		%hi(cheetah_deferred_trap), %g2
 | |
| 	jmpl		%g2 + %lo(cheetah_deferred_trap), %g0
 | |
| 	 mov		1, %g1
 | |
| 	.size		cheetah_deferred_trap_vector_tl1,.-cheetah_deferred_trap_vector_tl1
 | |
| 
 | |
| 	/* Cheetah+ specific traps. These are for the new I/D cache parity
 | |
| 	 * error traps.  The first argument to cheetah_plus_parity_handler
 | |
| 	 * is encoded as follows:
 | |
| 	 *
 | |
| 	 * Bit0:	0=dcache,1=icache
 | |
| 	 * Bit1:	0=recoverable,1=unrecoverable
 | |
| 	 */
 | |
| 	.globl		cheetah_plus_dcpe_trap_vector
 | |
| 	.type		cheetah_plus_dcpe_trap_vector,#function
 | |
| cheetah_plus_dcpe_trap_vector:
 | |
| 	membar		#Sync
 | |
| 	sethi		%hi(do_cheetah_plus_data_parity), %g7
 | |
| 	jmpl		%g7 + %lo(do_cheetah_plus_data_parity), %g0
 | |
| 	 nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	.size		cheetah_plus_dcpe_trap_vector,.-cheetah_plus_dcpe_trap_vector
 | |
| 
 | |
| 	.type		do_cheetah_plus_data_parity,#function
 | |
| do_cheetah_plus_data_parity:
 | |
| 	rdpr		%pil, %g2
 | |
| 	wrpr		%g0, PIL_NORMAL_MAX, %pil
 | |
| 	ba,pt		%xcc, etrap_irq
 | |
| 	 rd		%pc, %g7
 | |
| #ifdef CONFIG_TRACE_IRQFLAGS
 | |
| 	call		trace_hardirqs_off
 | |
| 	 nop
 | |
| #endif
 | |
| 	mov		0x0, %o0
 | |
| 	call		cheetah_plus_parity_error
 | |
| 	 add		%sp, PTREGS_OFF, %o1
 | |
| 	ba,a,pt		%xcc, rtrap_irq
 | |
| 	.size		do_cheetah_plus_data_parity,.-do_cheetah_plus_data_parity
 | |
| 
 | |
| 	.globl		cheetah_plus_dcpe_trap_vector_tl1
 | |
| 	.type		cheetah_plus_dcpe_trap_vector_tl1,#function
 | |
| cheetah_plus_dcpe_trap_vector_tl1:
 | |
| 	membar		#Sync
 | |
| 	wrpr		PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
 | |
| 	sethi		%hi(do_dcpe_tl1), %g3
 | |
| 	jmpl		%g3 + %lo(do_dcpe_tl1), %g0
 | |
| 	 nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	.size		cheetah_plus_dcpe_trap_vector_tl1,.-cheetah_plus_dcpe_trap_vector_tl1
 | |
| 
 | |
| 	.globl		cheetah_plus_icpe_trap_vector
 | |
| 	.type		cheetah_plus_icpe_trap_vector,#function
 | |
| cheetah_plus_icpe_trap_vector:
 | |
| 	membar		#Sync
 | |
| 	sethi		%hi(do_cheetah_plus_insn_parity), %g7
 | |
| 	jmpl		%g7 + %lo(do_cheetah_plus_insn_parity), %g0
 | |
| 	 nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	.size		cheetah_plus_icpe_trap_vector,.-cheetah_plus_icpe_trap_vector
 | |
| 
 | |
| 	.type		do_cheetah_plus_insn_parity,#function
 | |
| do_cheetah_plus_insn_parity:
 | |
| 	rdpr		%pil, %g2
 | |
| 	wrpr		%g0, PIL_NORMAL_MAX, %pil
 | |
| 	ba,pt		%xcc, etrap_irq
 | |
| 	 rd		%pc, %g7
 | |
| #ifdef CONFIG_TRACE_IRQFLAGS
 | |
| 	call		trace_hardirqs_off
 | |
| 	 nop
 | |
| #endif
 | |
| 	mov		0x1, %o0
 | |
| 	call		cheetah_plus_parity_error
 | |
| 	 add		%sp, PTREGS_OFF, %o1
 | |
| 	ba,a,pt		%xcc, rtrap_irq
 | |
| 	.size		do_cheetah_plus_insn_parity,.-do_cheetah_plus_insn_parity
 | |
| 
 | |
| 	.globl		cheetah_plus_icpe_trap_vector_tl1
 | |
| 	.type		cheetah_plus_icpe_trap_vector_tl1,#function
 | |
| cheetah_plus_icpe_trap_vector_tl1:
 | |
| 	membar		#Sync
 | |
| 	wrpr		PSTATE_IG | PSTATE_PEF | PSTATE_PRIV, %pstate
 | |
| 	sethi		%hi(do_icpe_tl1), %g3
 | |
| 	jmpl		%g3 + %lo(do_icpe_tl1), %g0
 | |
| 	 nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	nop
 | |
| 	.size		cheetah_plus_icpe_trap_vector_tl1,.-cheetah_plus_icpe_trap_vector_tl1
 | |
| 
 | |
| 	/* If we take one of these traps when tl >= 1, then we
 | |
| 	 * jump to interrupt globals.  If some trap level above us
 | |
| 	 * was also using interrupt globals, we cannot recover.
 | |
| 	 * We may use all interrupt global registers except %g6.
 | |
| 	 */
 | |
| 	.globl		do_dcpe_tl1
 | |
| 	.type		do_dcpe_tl1,#function
 | |
| do_dcpe_tl1:
 | |
| 	rdpr		%tl, %g1		! Save original trap level
 | |
| 	mov		1, %g2			! Setup TSTATE checking loop
 | |
| 	sethi		%hi(TSTATE_IG), %g3	! TSTATE mask bit
 | |
| 1:	wrpr		%g2, %tl		! Set trap level to check
 | |
| 	rdpr		%tstate, %g4		! Read TSTATE for this level
 | |
| 	andcc		%g4, %g3, %g0		! Interrupt globals in use?
 | |
| 	bne,a,pn	%xcc, do_dcpe_tl1_fatal	! Yep, irrecoverable
 | |
| 	 wrpr		%g1, %tl		! Restore original trap level
 | |
| 	add		%g2, 1, %g2		! Next trap level
 | |
| 	cmp		%g2, %g1		! Hit them all yet?
 | |
| 	ble,pt		%icc, 1b		! Not yet
 | |
| 	 nop
 | |
| 	wrpr		%g1, %tl		! Restore original trap level
 | |
| do_dcpe_tl1_nonfatal:	/* Ok we may use interrupt globals safely. */
 | |
| 	sethi		%hi(dcache_parity_tl1_occurred), %g2
 | |
| 	lduw		[%g2 + %lo(dcache_parity_tl1_occurred)], %g1
 | |
| 	add		%g1, 1, %g1
 | |
| 	stw		%g1, [%g2 + %lo(dcache_parity_tl1_occurred)]
 | |
| 	/* Reset D-cache parity */
 | |
| 	sethi		%hi(1 << 16), %g1	! D-cache size
 | |
| 	mov		(1 << 5), %g2		! D-cache line size
 | |
| 	sub		%g1, %g2, %g1		! Move down 1 cacheline
 | |
| 1:	srl		%g1, 14, %g3		! Compute UTAG
 | |
| 	membar		#Sync
 | |
| 	stxa		%g3, [%g1] ASI_DCACHE_UTAG
 | |
| 	membar		#Sync
 | |
| 	sub		%g2, 8, %g3		! 64-bit data word within line
 | |
| 2:	membar		#Sync
 | |
| 	stxa		%g0, [%g1 + %g3] ASI_DCACHE_DATA
 | |
| 	membar		#Sync
 | |
| 	subcc		%g3, 8, %g3		! Next 64-bit data word
 | |
| 	bge,pt		%icc, 2b
 | |
| 	 nop
 | |
| 	subcc		%g1, %g2, %g1		! Next cacheline
 | |
| 	bge,pt		%icc, 1b
 | |
| 	 nop
 | |
| 	ba,a,pt		%xcc, dcpe_icpe_tl1_common
 | |
| 
 | |
| do_dcpe_tl1_fatal:
 | |
| 	sethi		%hi(1f), %g7
 | |
| 	ba,pt		%xcc, etraptl1
 | |
| 1:	or		%g7, %lo(1b), %g7
 | |
| 	mov		0x2, %o0
 | |
| 	call		cheetah_plus_parity_error
 | |
| 	 add		%sp, PTREGS_OFF, %o1
 | |
| 	ba,a,pt		%xcc, rtrap
 | |
| 	.size		do_dcpe_tl1,.-do_dcpe_tl1
 | |
| 
 | |
| 	.globl		do_icpe_tl1
 | |
| 	.type		do_icpe_tl1,#function
 | |
| do_icpe_tl1:
 | |
| 	rdpr		%tl, %g1		! Save original trap level
 | |
| 	mov		1, %g2			! Setup TSTATE checking loop
 | |
| 	sethi		%hi(TSTATE_IG), %g3	! TSTATE mask bit
 | |
| 1:	wrpr		%g2, %tl		! Set trap level to check
 | |
| 	rdpr		%tstate, %g4		! Read TSTATE for this level
 | |
| 	andcc		%g4, %g3, %g0		! Interrupt globals in use?
 | |
| 	bne,a,pn	%xcc, do_icpe_tl1_fatal	! Yep, irrecoverable
 | |
| 	 wrpr		%g1, %tl		! Restore original trap level
 | |
| 	add		%g2, 1, %g2		! Next trap level
 | |
| 	cmp		%g2, %g1		! Hit them all yet?
 | |
| 	ble,pt		%icc, 1b		! Not yet
 | |
| 	 nop
 | |
| 	wrpr		%g1, %tl		! Restore original trap level
 | |
| do_icpe_tl1_nonfatal:	/* Ok we may use interrupt globals safely. */
 | |
| 	sethi		%hi(icache_parity_tl1_occurred), %g2
 | |
| 	lduw		[%g2 + %lo(icache_parity_tl1_occurred)], %g1
 | |
| 	add		%g1, 1, %g1
 | |
| 	stw		%g1, [%g2 + %lo(icache_parity_tl1_occurred)]
 | |
| 	/* Flush I-cache */
 | |
| 	sethi		%hi(1 << 15), %g1	! I-cache size
 | |
| 	mov		(1 << 5), %g2		! I-cache line size
 | |
| 	sub		%g1, %g2, %g1
 | |
| 1:	or		%g1, (2 << 3), %g3
 | |
| 	stxa		%g0, [%g3] ASI_IC_TAG
 | |
| 	membar		#Sync
 | |
| 	subcc		%g1, %g2, %g1
 | |
| 	bge,pt		%icc, 1b
 | |
| 	 nop
 | |
| 	ba,a,pt		%xcc, dcpe_icpe_tl1_common
 | |
| 
 | |
| do_icpe_tl1_fatal:
 | |
| 	sethi		%hi(1f), %g7
 | |
| 	ba,pt		%xcc, etraptl1
 | |
| 1:	or		%g7, %lo(1b), %g7
 | |
| 	mov		0x3, %o0
 | |
| 	call		cheetah_plus_parity_error
 | |
| 	 add		%sp, PTREGS_OFF, %o1
 | |
| 	ba,a,pt		%xcc, rtrap
 | |
| 	.size		do_icpe_tl1,.-do_icpe_tl1
 | |
| 	
 | |
| 	.type		dcpe_icpe_tl1_common,#function
 | |
| dcpe_icpe_tl1_common:
 | |
| 	/* Flush D-cache, re-enable D/I caches in DCU and finally
 | |
| 	 * retry the trapping instruction.
 | |
| 	 */
 | |
| 	sethi		%hi(1 << 16), %g1	! D-cache size
 | |
| 	mov		(1 << 5), %g2		! D-cache line size
 | |
| 	sub		%g1, %g2, %g1
 | |
| 1:	stxa		%g0, [%g1] ASI_DCACHE_TAG
 | |
| 	membar		#Sync
 | |
| 	subcc		%g1, %g2, %g1
 | |
| 	bge,pt		%icc, 1b
 | |
| 	 nop
 | |
| 	ldxa		[%g0] ASI_DCU_CONTROL_REG, %g1
 | |
| 	or		%g1, (DCU_DC | DCU_IC), %g1
 | |
| 	stxa		%g1, [%g0] ASI_DCU_CONTROL_REG
 | |
| 	membar		#Sync
 | |
| 	retry
 | |
| 	.size		dcpe_icpe_tl1_common,.-dcpe_icpe_tl1_common
 | |
| 
 | |
| 	/* Capture I/D/E-cache state into per-cpu error scoreboard.
 | |
| 	 *
 | |
| 	 * %g1:		(TL>=0) ? 1 : 0
 | |
| 	 * %g2:		scratch
 | |
| 	 * %g3:		scratch
 | |
| 	 * %g4:		AFSR
 | |
| 	 * %g5:		AFAR
 | |
| 	 * %g6:		unused, will have current thread ptr after etrap
 | |
| 	 * %g7:		scratch
 | |
| 	 */
 | |
| 	.type		__cheetah_log_error,#function
 | |
| __cheetah_log_error:
 | |
| 	/* Put "TL1" software bit into AFSR. */
 | |
| 	and		%g1, 0x1, %g1
 | |
| 	sllx		%g1, 63, %g2
 | |
| 	or		%g4, %g2, %g4
 | |
| 
 | |
| 	/* Get log entry pointer for this cpu at this trap level. */
 | |
| 	BRANCH_IF_JALAPENO(g2,g3,50f)
 | |
| 	ldxa		[%g0] ASI_SAFARI_CONFIG, %g2
 | |
| 	srlx		%g2, 17, %g2
 | |
| 	ba,pt		%xcc, 60f
 | |
| 	 and		%g2, 0x3ff, %g2
 | |
| 
 | |
| 50:	ldxa		[%g0] ASI_JBUS_CONFIG, %g2
 | |
| 	srlx		%g2, 17, %g2
 | |
| 	and		%g2, 0x1f, %g2
 | |
| 
 | |
| 60:	sllx		%g2, 9, %g2
 | |
| 	sethi		%hi(cheetah_error_log), %g3
 | |
| 	ldx		[%g3 + %lo(cheetah_error_log)], %g3
 | |
| 	brz,pn		%g3, 80f
 | |
| 	 nop
 | |
| 
 | |
| 	add		%g3, %g2, %g3
 | |
| 	sllx		%g1, 8, %g1
 | |
| 	add		%g3, %g1, %g1
 | |
| 
 | |
| 	/* %g1 holds pointer to the top of the logging scoreboard */
 | |
| 	ldx		[%g1 + 0x0], %g7
 | |
| 	cmp		%g7, -1
 | |
| 	bne,pn		%xcc, 80f
 | |
| 	 nop
 | |
| 
 | |
| 	stx		%g4, [%g1 + 0x0]
 | |
| 	stx		%g5, [%g1 + 0x8]
 | |
| 	add		%g1, 0x10, %g1
 | |
| 
 | |
| 	/* %g1 now points to D-cache logging area */
 | |
| 	set		0x3ff8, %g2	/* DC_addr mask		*/
 | |
| 	and		%g5, %g2, %g2	/* DC_addr bits of AFAR	*/
 | |
| 	srlx		%g5, 12, %g3
 | |
| 	or		%g3, 1, %g3	/* PHYS tag + valid	*/
 | |
| 
 | |
| 10:	ldxa		[%g2] ASI_DCACHE_TAG, %g7
 | |
| 	cmp		%g3, %g7	/* TAG match?		*/
 | |
| 	bne,pt		%xcc, 13f
 | |
| 	 nop
 | |
| 
 | |
| 	/* Yep, what we want, capture state. */
 | |
| 	stx		%g2, [%g1 + 0x20]
 | |
| 	stx		%g7, [%g1 + 0x28]
 | |
| 
 | |
| 	/* A membar Sync is required before and after utag access. */
 | |
| 	membar		#Sync
 | |
| 	ldxa		[%g2] ASI_DCACHE_UTAG, %g7
 | |
| 	membar		#Sync
 | |
| 	stx		%g7, [%g1 + 0x30]
 | |
| 	ldxa		[%g2] ASI_DCACHE_SNOOP_TAG, %g7
 | |
| 	stx		%g7, [%g1 + 0x38]
 | |
| 	clr		%g3
 | |
| 
 | |
| 12:	ldxa		[%g2 + %g3] ASI_DCACHE_DATA, %g7
 | |
| 	stx		%g7, [%g1]
 | |
| 	add		%g3, (1 << 5), %g3
 | |
| 	cmp		%g3, (4 << 5)
 | |
| 	bl,pt		%xcc, 12b
 | |
| 	 add		%g1, 0x8, %g1
 | |
| 
 | |
| 	ba,pt		%xcc, 20f
 | |
| 	 add		%g1, 0x20, %g1
 | |
| 
 | |
| 13:	sethi		%hi(1 << 14), %g7
 | |
| 	add		%g2, %g7, %g2
 | |
| 	srlx		%g2, 14, %g7
 | |
| 	cmp		%g7, 4
 | |
| 	bl,pt		%xcc, 10b
 | |
| 	 nop
 | |
| 
 | |
| 	add		%g1, 0x40, %g1
 | |
| 
 | |
| 	/* %g1 now points to I-cache logging area */
 | |
| 20:	set		0x1fe0, %g2	/* IC_addr mask		*/
 | |
| 	and		%g5, %g2, %g2	/* IC_addr bits of AFAR	*/
 | |
| 	sllx		%g2, 1, %g2	/* IC_addr[13:6]==VA[12:5] */
 | |
| 	srlx		%g5, (13 - 8), %g3 /* Make PTAG */
 | |
| 	andn		%g3, 0xff, %g3	/* Mask off undefined bits */
 | |
| 
 | |
| 21:	ldxa		[%g2] ASI_IC_TAG, %g7
 | |
| 	andn		%g7, 0xff, %g7
 | |
| 	cmp		%g3, %g7
 | |
| 	bne,pt		%xcc, 23f
 | |
| 	 nop
 | |
| 
 | |
| 	/* Yep, what we want, capture state. */
 | |
| 	stx		%g2, [%g1 + 0x40]
 | |
| 	stx		%g7, [%g1 + 0x48]
 | |
| 	add		%g2, (1 << 3), %g2
 | |
| 	ldxa		[%g2] ASI_IC_TAG, %g7
 | |
| 	add		%g2, (1 << 3), %g2
 | |
| 	stx		%g7, [%g1 + 0x50]
 | |
| 	ldxa		[%g2] ASI_IC_TAG, %g7
 | |
| 	add		%g2, (1 << 3), %g2
 | |
| 	stx		%g7, [%g1 + 0x60]
 | |
| 	ldxa		[%g2] ASI_IC_TAG, %g7
 | |
| 	stx		%g7, [%g1 + 0x68]
 | |
| 	sub		%g2, (3 << 3), %g2
 | |
| 	ldxa		[%g2] ASI_IC_STAG, %g7
 | |
| 	stx		%g7, [%g1 + 0x58]
 | |
| 	clr		%g3
 | |
| 	srlx		%g2, 2, %g2
 | |
| 
 | |
| 22:	ldxa		[%g2 + %g3] ASI_IC_INSTR, %g7
 | |
| 	stx		%g7, [%g1]
 | |
| 	add		%g3, (1 << 3), %g3
 | |
| 	cmp		%g3, (8 << 3)
 | |
| 	bl,pt		%xcc, 22b
 | |
| 	 add		%g1, 0x8, %g1
 | |
| 
 | |
| 	ba,pt		%xcc, 30f
 | |
| 	 add		%g1, 0x30, %g1
 | |
| 
 | |
| 23:	sethi		%hi(1 << 14), %g7
 | |
| 	add		%g2, %g7, %g2
 | |
| 	srlx		%g2, 14, %g7
 | |
| 	cmp		%g7, 4
 | |
| 	bl,pt		%xcc, 21b
 | |
| 	 nop
 | |
| 
 | |
| 	add		%g1, 0x70, %g1
 | |
| 
 | |
| 	/* %g1 now points to E-cache logging area */
 | |
| 30:	andn		%g5, (32 - 1), %g2
 | |
| 	stx		%g2, [%g1 + 0x20]
 | |
| 	ldxa		[%g2] ASI_EC_TAG_DATA, %g7
 | |
| 	stx		%g7, [%g1 + 0x28]
 | |
| 	ldxa		[%g2] ASI_EC_R, %g0
 | |
| 	clr		%g3
 | |
| 
 | |
| 31:	ldxa		[%g3] ASI_EC_DATA, %g7
 | |
| 	stx		%g7, [%g1 + %g3]
 | |
| 	add		%g3, 0x8, %g3
 | |
| 	cmp		%g3, 0x20
 | |
| 
 | |
| 	bl,pt		%xcc, 31b
 | |
| 	 nop
 | |
| 80:
 | |
| 	rdpr		%tt, %g2
 | |
| 	cmp		%g2, 0x70
 | |
| 	be		c_fast_ecc
 | |
| 	 cmp		%g2, 0x63
 | |
| 	be		c_cee
 | |
| 	 nop
 | |
| 	ba,a,pt		%xcc, c_deferred
 | |
| 	.size		__cheetah_log_error,.-__cheetah_log_error
 | |
| 
 | |
| 	/* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
 | |
| 	 * in the trap table.  That code has done a memory barrier
 | |
| 	 * and has disabled both the I-cache and D-cache in the DCU
 | |
| 	 * control register.  The I-cache is disabled so that we may
 | |
| 	 * capture the corrupted cache line, and the D-cache is disabled
 | |
| 	 * because corrupt data may have been placed there and we don't
 | |
| 	 * want to reference it.
 | |
| 	 *
 | |
| 	 * %g1 is one if this trap occurred at %tl >= 1.
 | |
| 	 *
 | |
| 	 * Next, we turn off error reporting so that we don't recurse.
 | |
| 	 */
 | |
| 	.globl		cheetah_fast_ecc
 | |
| 	.type		cheetah_fast_ecc,#function
 | |
| cheetah_fast_ecc:
 | |
| 	ldxa		[%g0] ASI_ESTATE_ERROR_EN, %g2
 | |
| 	andn		%g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
 | |
| 	stxa		%g2, [%g0] ASI_ESTATE_ERROR_EN
 | |
| 	membar		#Sync
 | |
| 
 | |
| 	/* Fetch and clear AFSR/AFAR */
 | |
| 	ldxa		[%g0] ASI_AFSR, %g4
 | |
| 	ldxa		[%g0] ASI_AFAR, %g5
 | |
| 	stxa		%g4, [%g0] ASI_AFSR
 | |
| 	membar		#Sync
 | |
| 
 | |
| 	ba,pt		%xcc, __cheetah_log_error
 | |
| 	 nop
 | |
| 	.size		cheetah_fast_ecc,.-cheetah_fast_ecc
 | |
| 
 | |
| 	.type		c_fast_ecc,#function
 | |
| c_fast_ecc:
 | |
| 	rdpr		%pil, %g2
 | |
| 	wrpr		%g0, PIL_NORMAL_MAX, %pil
 | |
| 	ba,pt		%xcc, etrap_irq
 | |
| 	 rd		%pc, %g7
 | |
| #ifdef CONFIG_TRACE_IRQFLAGS
 | |
| 	call		trace_hardirqs_off
 | |
| 	 nop
 | |
| #endif
 | |
| 	mov		%l4, %o1
 | |
| 	mov		%l5, %o2
 | |
| 	call		cheetah_fecc_handler
 | |
| 	 add		%sp, PTREGS_OFF, %o0
 | |
| 	ba,a,pt		%xcc, rtrap_irq
 | |
| 	.size		c_fast_ecc,.-c_fast_ecc
 | |
| 
 | |
| 	/* Our caller has disabled I-cache and performed membar Sync. */
 | |
| 	.globl		cheetah_cee
 | |
| 	.type		cheetah_cee,#function
 | |
| cheetah_cee:
 | |
| 	ldxa		[%g0] ASI_ESTATE_ERROR_EN, %g2
 | |
| 	andn		%g2, ESTATE_ERROR_CEEN, %g2
 | |
| 	stxa		%g2, [%g0] ASI_ESTATE_ERROR_EN
 | |
| 	membar		#Sync
 | |
| 
 | |
| 	/* Fetch and clear AFSR/AFAR */
 | |
| 	ldxa		[%g0] ASI_AFSR, %g4
 | |
| 	ldxa		[%g0] ASI_AFAR, %g5
 | |
| 	stxa		%g4, [%g0] ASI_AFSR
 | |
| 	membar		#Sync
 | |
| 
 | |
| 	ba,pt		%xcc, __cheetah_log_error
 | |
| 	 nop
 | |
| 	.size		cheetah_cee,.-cheetah_cee
 | |
| 
 | |
| 	.type		c_cee,#function
 | |
| c_cee:
 | |
| 	rdpr		%pil, %g2
 | |
| 	wrpr		%g0, PIL_NORMAL_MAX, %pil
 | |
| 	ba,pt		%xcc, etrap_irq
 | |
| 	 rd		%pc, %g7
 | |
| #ifdef CONFIG_TRACE_IRQFLAGS
 | |
| 	call		trace_hardirqs_off
 | |
| 	 nop
 | |
| #endif
 | |
| 	mov		%l4, %o1
 | |
| 	mov		%l5, %o2
 | |
| 	call		cheetah_cee_handler
 | |
| 	 add		%sp, PTREGS_OFF, %o0
 | |
| 	ba,a,pt		%xcc, rtrap_irq
 | |
| 	.size		c_cee,.-c_cee
 | |
| 
 | |
| 	/* Our caller has disabled I-cache+D-cache and performed membar Sync. */
 | |
| 	.globl		cheetah_deferred_trap
 | |
| 	.type		cheetah_deferred_trap,#function
 | |
| cheetah_deferred_trap:
 | |
| 	ldxa		[%g0] ASI_ESTATE_ERROR_EN, %g2
 | |
| 	andn		%g2, ESTATE_ERROR_NCEEN | ESTATE_ERROR_CEEN, %g2
 | |
| 	stxa		%g2, [%g0] ASI_ESTATE_ERROR_EN
 | |
| 	membar		#Sync
 | |
| 
 | |
| 	/* Fetch and clear AFSR/AFAR */
 | |
| 	ldxa		[%g0] ASI_AFSR, %g4
 | |
| 	ldxa		[%g0] ASI_AFAR, %g5
 | |
| 	stxa		%g4, [%g0] ASI_AFSR
 | |
| 	membar		#Sync
 | |
| 
 | |
| 	ba,pt		%xcc, __cheetah_log_error
 | |
| 	 nop
 | |
| 	.size		cheetah_deferred_trap,.-cheetah_deferred_trap
 | |
| 
 | |
| 	.type		c_deferred,#function
 | |
| c_deferred:
 | |
| 	rdpr		%pil, %g2
 | |
| 	wrpr		%g0, PIL_NORMAL_MAX, %pil
 | |
| 	ba,pt		%xcc, etrap_irq
 | |
| 	 rd		%pc, %g7
 | |
| #ifdef CONFIG_TRACE_IRQFLAGS
 | |
| 	call		trace_hardirqs_off
 | |
| 	 nop
 | |
| #endif
 | |
| 	mov		%l4, %o1
 | |
| 	mov		%l5, %o2
 | |
| 	call		cheetah_deferred_handler
 | |
| 	 add		%sp, PTREGS_OFF, %o0
 | |
| 	ba,a,pt		%xcc, rtrap_irq
 | |
| 	.size		c_deferred,.-c_deferred
 |