Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / ia64 / sn / kernel / sn2 / ptc_deadlock.S
diff --git a/kernel/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/kernel/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
new file mode 100644 (file)
index 0000000..bebbcc4
--- /dev/null
@@ -0,0 +1,92 @@
+/* 
+ * 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