forked from Minki/linux
590711b7dd
The patch that added support for a new platform chipset (shub2) broke PTC deadlock recovery on older versions of the chipset. (PTCs are the SN platform-specific method for doing a global TLB purge). This patch fixes deadlock recovery so that it works on both the old & new chipsets. Signed-off-by: Jack Steiner <steiner@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
93 lines
2.3 KiB
ArmAsm
93 lines
2.3 KiB
ArmAsm
/*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
|
|
*/
|
|
|
|
#include <asm/types.h>
|
|
#include <asm/sn/shub_mmr.h>
|
|
|
|
#define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
|
|
#define WRITECOUNTMASK SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK
|
|
#define ALIAS_OFFSET 8
|
|
|
|
|
|
.global sn2_ptc_deadlock_recovery_core
|
|
.proc sn2_ptc_deadlock_recovery_core
|
|
|
|
sn2_ptc_deadlock_recovery_core:
|
|
.regstk 6,0,0,0
|
|
|
|
ptc0 = in0
|
|
data0 = in1
|
|
ptc1 = in2
|
|
data1 = in3
|
|
piowc = in4
|
|
zeroval = in5
|
|
piowcphy = r30
|
|
psrsave = r2
|
|
scr1 = r16
|
|
scr2 = r17
|
|
mask = r18
|
|
|
|
|
|
extr.u piowcphy=piowc,0,61;; // Convert piowc to uncached physical address
|
|
dep piowcphy=-1,piowcphy,63,1
|
|
movl mask=WRITECOUNTMASK
|
|
mov r8=r0
|
|
|
|
1:
|
|
cmp.ne p8,p9=r0,ptc1 // Test for shub type (ptc1 non-null on shub1)
|
|
// p8 = 1 if shub1, p9 = 1 if shub2
|
|
|
|
add scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register
|
|
mov scr1=7;; // Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR
|
|
(p8) st8.rel [scr2]=scr1;;
|
|
(p9) ld8.acq scr1=[scr2];;
|
|
|
|
5: ld8.acq scr1=[piowc];; // Wait for PIOs to complete.
|
|
hint @pause
|
|
and scr2=scr1,mask;; // mask of writecount bits
|
|
cmp.ne p6,p0=zeroval,scr2
|
|
(p6) br.cond.sptk 5b
|
|
|
|
|
|
|
|
////////////// BEGIN PHYSICAL MODE ////////////////////
|
|
mov psrsave=psr // Disable IC (no PMIs)
|
|
rsm psr.i | psr.dt | psr.ic;;
|
|
srlz.i;;
|
|
|
|
st8.rel [ptc0]=data0 // Write PTC0 & wait for completion.
|
|
|
|
5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete.
|
|
hint @pause
|
|
and scr2=scr1,mask;; // mask of writecount bits
|
|
cmp.ne p6,p0=zeroval,scr2
|
|
(p6) br.cond.sptk 5b;;
|
|
|
|
tbit.nz p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
|
|
(p7) cmp.ne p7,p0=r0,ptc1;; // Test for non-null ptc1
|
|
|
|
(p7) st8.rel [ptc1]=data1;; // Now write PTC1.
|
|
|
|
5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete.
|
|
hint @pause
|
|
and scr2=scr1,mask;; // mask of writecount bits
|
|
cmp.ne p6,p0=zeroval,scr2
|
|
(p6) br.cond.sptk 5b
|
|
|
|
tbit.nz p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK
|
|
|
|
mov psr.l=psrsave;; // Reenable IC
|
|
srlz.i;;
|
|
////////////// END PHYSICAL MODE ////////////////////
|
|
|
|
(p8) add r8=1,r8
|
|
(p8) br.cond.spnt 1b;; // Repeat if DEADLOCK occurred.
|
|
|
|
br.ret.sptk rp
|
|
.endp sn2_ptc_deadlock_recovery_core
|