| /* |
| * 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 |