Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame^] | 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-2004 Silicon Graphics, Inc. All rights reserved. |
| 7 | */ |
| 8 | |
| 9 | #include <asm/sn/shub_mmr.h> |
| 10 | |
| 11 | #define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT |
| 12 | #define WRITECOUNTMASK SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK |
| 13 | #define ALIAS_OFFSET (SH1_PIO_WRITE_STATUS_0_ALIAS-SH1_PIO_WRITE_STATUS_0) |
| 14 | |
| 15 | |
| 16 | .global sn2_ptc_deadlock_recovery_core |
| 17 | .proc sn2_ptc_deadlock_recovery_core |
| 18 | |
| 19 | sn2_ptc_deadlock_recovery_core: |
| 20 | .regstk 6,0,0,0 |
| 21 | |
| 22 | ptc0 = in0 |
| 23 | data0 = in1 |
| 24 | ptc1 = in2 |
| 25 | data1 = in3 |
| 26 | piowc = in4 |
| 27 | zeroval = in5 |
| 28 | piowcphy = r30 |
| 29 | psrsave = r2 |
| 30 | scr1 = r16 |
| 31 | scr2 = r17 |
| 32 | mask = r18 |
| 33 | |
| 34 | |
| 35 | extr.u piowcphy=piowc,0,61;; // Convert piowc to uncached physical address |
| 36 | dep piowcphy=-1,piowcphy,63,1 |
| 37 | movl mask=WRITECOUNTMASK |
| 38 | |
| 39 | 1: |
| 40 | add scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register |
| 41 | mov scr1=7;; // Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR |
| 42 | st8.rel [scr2]=scr1;; |
| 43 | |
| 44 | 5: ld8.acq scr1=[piowc];; // Wait for PIOs to complete. |
| 45 | and scr2=scr1,mask;; // mask of writecount bits |
| 46 | cmp.ne p6,p0=zeroval,scr2 |
| 47 | (p6) br.cond.sptk 5b |
| 48 | |
| 49 | |
| 50 | |
| 51 | ////////////// BEGIN PHYSICAL MODE //////////////////// |
| 52 | mov psrsave=psr // Disable IC (no PMIs) |
| 53 | rsm psr.i | psr.dt | psr.ic;; |
| 54 | srlz.i;; |
| 55 | |
| 56 | st8.rel [ptc0]=data0 // Write PTC0 & wait for completion. |
| 57 | |
| 58 | 5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete. |
| 59 | and scr2=scr1,mask;; // mask of writecount bits |
| 60 | cmp.ne p6,p0=zeroval,scr2 |
| 61 | (p6) br.cond.sptk 5b;; |
| 62 | |
| 63 | tbit.nz p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK |
| 64 | (p7) cmp.ne p7,p0=r0,ptc1;; // Test for non-null ptc1 |
| 65 | |
| 66 | (p7) st8.rel [ptc1]=data1;; // Now write PTC1. |
| 67 | |
| 68 | 5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete. |
| 69 | and scr2=scr1,mask;; // mask of writecount bits |
| 70 | cmp.ne p6,p0=zeroval,scr2 |
| 71 | (p6) br.cond.sptk 5b |
| 72 | |
| 73 | tbit.nz p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK |
| 74 | |
| 75 | mov psr.l=psrsave;; // Reenable IC |
| 76 | srlz.i;; |
| 77 | ////////////// END PHYSICAL MODE //////////////////// |
| 78 | |
| 79 | (p8) br.cond.spnt 1b;; // Repeat if DEADLOCK occurred. |
| 80 | |
| 81 | br.ret.sptk rp |
| 82 | .endp sn2_ptc_deadlock_recovery_core |