1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
7 */
8
9#include <asm/types.h>
10#include <asm/sn/shub_mmr.h>
11
12#define DEADLOCKBIT	SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
13#define WRITECOUNTMASK	SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK
14#define ALIAS_OFFSET	8
15
16
17	.global	sn2_ptc_deadlock_recovery_core
18	.proc  	sn2_ptc_deadlock_recovery_core
19
20sn2_ptc_deadlock_recovery_core:
21	.regstk 6,0,0,0
22
23	ptc0  	 = in0
24	data0 	 = in1
25	ptc1  	 = in2
26	data1 	 = in3
27	piowc 	 = in4
28	zeroval  = in5
29	piowcphy = r30
30	psrsave  = r2
31	scr1	 = r16
32	scr2	 = r17
33	mask	 = r18
34
35
36	extr.u	piowcphy=piowc,0,61;;	// Convert piowc to uncached physical address
37	dep	piowcphy=-1,piowcphy,63,1
38	movl	mask=WRITECOUNTMASK
39	mov	r8=r0
40
411:
42	cmp.ne  p8,p9=r0,ptc1		// Test for shub type (ptc1 non-null on shub1)
43					// p8 = 1 if shub1, p9 = 1 if shub2
44
45	add	scr2=ALIAS_OFFSET,piowc	// Address of WRITE_STATUS alias register
46	mov	scr1=7;;		// Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR
47(p8)	st8.rel	[scr2]=scr1;;
48(p9)	ld8.acq	scr1=[scr2];;
49
505:	ld8.acq	scr1=[piowc];;		// Wait for PIOs to complete.
51	hint	@pause
52	and	scr2=scr1,mask;;	// mask of writecount bits
53	cmp.ne	p6,p0=zeroval,scr2
54(p6)	br.cond.sptk 5b
55
56
57
58	////////////// BEGIN PHYSICAL MODE ////////////////////
59	mov psrsave=psr			// Disable IC (no PMIs)
60	rsm psr.i | psr.dt | psr.ic;;
61	srlz.i;;
62
63	st8.rel [ptc0]=data0		// Write PTC0 & wait for completion.
64
655:	ld8.acq	scr1=[piowcphy];;	// Wait for PIOs to complete.
66	hint	@pause
67	and	scr2=scr1,mask;;	// mask of writecount bits
68	cmp.ne	p6,p0=zeroval,scr2
69(p6)	br.cond.sptk 5b;;
70
71	tbit.nz	p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
72(p7)	cmp.ne p7,p0=r0,ptc1;;		// Test for non-null ptc1
73
74(p7)	st8.rel [ptc1]=data1;;		// Now write PTC1.
75
765:	ld8.acq	scr1=[piowcphy];;	// Wait for PIOs to complete.
77	hint	@pause
78	and	scr2=scr1,mask;;	// mask of writecount bits
79	cmp.ne	p6,p0=zeroval,scr2
80(p6)	br.cond.sptk 5b
81
82	tbit.nz	p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK
83
84	mov psr.l=psrsave;;		// Reenable IC
85	srlz.i;;
86	////////////// END   PHYSICAL MODE ////////////////////
87
88(p8)	add	r8=1,r8
89(p8)	br.cond.spnt 1b;;		// Repeat if DEADLOCK occurred.
90
91	br.ret.sptk	rp
92	.endp sn2_ptc_deadlock_recovery_core
93