1/* 2 * tbitimer.S 3 * 4 * Copyright (C) 2001, 2002, 2007, 2012 Imagination Technologies. 5 * 6 * This program is free software; you can redistribute it and/or modify it under 7 * the terms of the GNU General Public License version 2 as published by the 8 * Free Software Foundation. 9 * 10 * TBI timer support routines and data values 11 */ 12 13 .file "tbitimer.S" 14/* 15 * Get data structures and defines from the main C header 16 */ 17#include <asm/tbx.h> 18 19 .data 20 .balign 8 21 .global ___TBITimeB 22 .type ___TBITimeB,object 23___TBITimeB: 24 .quad 0 /* Background 'lost' ticks */ 25 .size ___TBITimeB,.-___TBITimeB 26 27 .data 28 .balign 8 29 .global ___TBITimeI 30 .type ___TBITimeI,object 31___TBITimeI: 32 .quad 0 /* Interrupt 'lost' ticks */ 33 .size ___TBITimeI,.-___TBITimeI 34 35 .data 36 .balign 8 37 .global ___TBITimes 38 .type ___TBITimes,object 39___TBITimes: 40 .long ___TBITimeB /* Table of 'lost' tick values */ 41 .long ___TBITimeI 42 .size ___TBITimes,.-___TBITimes 43 44/* 45 * Flag bits for control of ___TBITimeCore 46 */ 47#define TIMER_SET_BIT 1 48#define TIMER_ADD_BIT 2 49 50/* 51 * Initialise or stop timer support 52 * 53 * Register Usage: D1Ar1 holds Id, D1Ar2 is initial delay or 0 54 * D0FrT is used to call ___TBITimeCore 55 * D0Re0 is used for the result which is TXSTAT_TIMER_BIT 56 * D0Ar4, D1Ar5, D0Ar6 are all used as scratch 57 * Other registers are those set by ___TBITimeCore 58 * A0.3 is assumed to point at ___TBITime(I/B) 59 */ 60 .text 61 .balign 4 62 .global ___TBITimerCtrl 63 .type ___TBITimerCtrl,function 64___TBITimerCtrl: 65 MOV D1Ar5,#TIMER_SET_BIT /* Timer SET request */ 66 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */ 67 CALL D0FrT,#LO(___TBITimeCore) /* and perform register update */ 68 NEGS D0Ar6,D0Ar2 /* Set flags from time-stamp */ 69 ASR D1Ar5,D0Ar6,#31 /* Sign extend D0Ar6 into D1Ar5 */ 70 SETLNZ [A0.3],D0Ar6,D1Ar5 /* ___TBITime(B/I)=-Start if enable */ 71 MOV PC,D1RtP /* Return */ 72 .size ___TBITimerCtrl,.-___TBITimerCtrl 73 74/* 75 * Return ___TBITimeStamp value 76 * 77 * Register Usage: D1Ar1 holds Id 78 * D0FrT is used to call ___TBITimeCore 79 * D0Re0, D1Re0 is used for the result 80 * D1Ar3, D0Ar4, D1Ar5 81 * Other registers are those set by ___TBITimeCore 82 * D0Ar6 is assumed to be the timer value read 83 * A0.3 is assumed to point at ___TBITime(I/B) 84 */ 85 .text 86 .balign 4 87 .global ___TBITimeStamp 88 .type ___TBITimeStamp,function 89___TBITimeStamp: 90 MOV D1Ar5,#0 /* Timer GET request */ 91 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */ 92 CALL D0FrT,#LO(___TBITimeCore) /* with no register update */ 93 ADDS D0Re0,D0Ar4,D0Ar6 /* Add current time value */ 94 ADD D1Re0,D1Ar3,D1Ar5 /* to 64-bit signed extend time */ 95 ADDCS D1Re0,D1Re0,#1 /* Support borrow too */ 96 MOV PC,D1RtP /* Return */ 97 .size ___TBITimeStamp,.-___TBITimeStamp 98 99/* 100 * Perform ___TBITimerAdd logic 101 * 102 * Register Usage: D1Ar1 holds Id, D0Ar2 holds value to be added to the timer 103 * D0Re0 is used for the result - new TIMER value 104 * D1Ar5, D0Ar6 are used as scratch 105 * Other registers are those set by ___TBITimeCore 106 * D0Ar6 is assumed to be the timer value read 107 * D0Ar4, D1Ar3 is the current value of ___TBITime(B/I) 108 */ 109 .text 110 .balign 4 111 .global ___TBITimerAdd 112 .type ___TBITimerAdd,function 113___TBITimerAdd: 114 MOV D1Ar5,#TIMER_ADD_BIT /* Timer ADD request */ 115 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */ 116 CALL D0FrT,#LO(___TBITimeCore) /* with no register update */ 117 ADD D0Re0,D0Ar2,D0Ar6 /* Regenerate new value = result */ 118 NEG D0Ar2,D0Ar2 /* Negate delta */ 119 ASR D1Re0,D0Ar2,#31 /* Sign extend negated delta */ 120 ADDS D0Ar4,D0Ar4,D0Ar2 /* Add time added to ... */ 121 ADD D1Ar3,D1Ar3,D1Re0 /* ... real timer ... */ 122 ADDCS D1Ar3,D1Ar3,#1 /* ... with carry */ 123 SETL [A0.3],D0Ar4,D1Ar3 /* Update ___TBITime(B/I) */ 124 MOV PC,D1RtP /* Return */ 125 .size ___TBITimerAdd,.-___TBITimerAdd 126 127#ifdef TBI_1_4 128/* 129 * Perform ___TBITimerDeadline logic 130 * NB: Delays are positive compared to the Wait values which are -ive 131 * 132 * Register Usage: D1Ar1 holds Id 133 * D0Ar2 holds Delay requested 134 * D0Re0 is used for the result - old TIMER Delay value 135 * D1Ar5, D0Ar6 are used as scratch 136 * Other registers are those set by ___TBITimeCore 137 * D0Ar6 is assumed to be the timer value read 138 * D0Ar4, D1Ar3 is the current value of ___TBITime(B/I) 139 * 140 */ 141 .text 142 .type ___TBITimerDeadline,function 143 .global ___TBITimerDeadline 144 .align 2 145___TBITimerDeadline: 146 MOV D1Ar5,#TIMER_SET_BIT /* Timer SET request */ 147 MOVT D0FrT,#HI(___TBITimeCore) /* Get timer core reg values */ 148 CALL D0FrT,#LO(___TBITimeCore) /* with no register update */ 149 MOV D0Re0,D0Ar6 /* Old value read = result */ 150 SUB D0Ar2,D0Ar6,D0Ar2 /* Delta from (old - new) */ 151 ASR D1Re0,D0Ar2,#31 /* Sign extend delta */ 152 ADDS D0Ar4,D0Ar4,D0Ar2 /* Add time added to ... */ 153 ADD D1Ar3,D1Ar3,D1Re0 /* ... real timer ... */ 154 ADDCS D1Ar3,D1Ar3,#1 /* ... with carry */ 155 SETL [A0.3],D0Ar4,D1Ar3 /* Update ___TBITime(B/I) */ 156 MOV PC,D1RtP /* Return */ 157 .size ___TBITimerDeadline,.-___TBITimerDeadline 158#endif /* TBI_1_4 */ 159 160/* 161 * Perform core timer access logic 162 * 163 * Register Usage: D1Ar1 holds Id, D0Ar2 holds input value for SET and 164 * input value for ADD 165 * D1Ar5 controls op as SET or ADD as bit values 166 * On return D0Ar6, D1Ar5 holds the old 64-bit timer value 167 * A0.3 is setup to point at ___TBITime(I/B) 168 * A1.3 is setup to point at ___TBITimes 169 * D0Ar4, D1Ar3 is setup to value of ___TBITime(I/B) 170 */ 171 .text 172 .balign 4 173 .global ___TBITimeCore 174 .type ___TBITimeCore,function 175___TBITimeCore: 176#ifndef METAC_0_1 177 TSTT D1Ar1,#HI(TBID_ISTAT_BIT) /* Interrupt level timer? */ 178#endif 179 MOVT A1LbP,#HI(___TBITimes) 180 ADD A1LbP,A1LbP,#LO(___TBITimes) 181 MOV A1.3,A1LbP /* Get ___TBITimes address */ 182#ifndef METAC_0_1 183 BNZ $LTimeCoreI /* Yes: Service TXTIMERI! */ 184#endif 185 LSRS D1Ar5,D1Ar5,#1 /* Carry = SET, Zero = !ADD */ 186 GETD A0.3,[A1.3+#0] /* A0.3 == &___TBITimeB */ 187 MOV D0Ar6,TXTIMER /* Always GET old value */ 188 MOVCS TXTIMER,D0Ar2 /* Conditional SET operation */ 189 ADDNZ TXTIMER,D0Ar2,D0Ar6 /* Conditional ADD operation */ 190#ifndef METAC_0_1 191 B $LTimeCoreEnd 192$LTimeCoreI: 193 LSRS D1Ar5,D1Ar5,#1 /* Carry = SET, Zero = !ADD */ 194 GETD A0.3,[A1.3+#4] /* A0.3 == &___TBITimeI */ 195 MOV D0Ar6,TXTIMERI /* Always GET old value */ 196 MOVCS TXTIMERI,D0Ar2 /* Conditional SET operation */ 197 ADDNZ TXTIMERI,D0Ar2,D0Ar6 /* Conditional ADD operation */ 198$LTimeCoreEnd: 199#endif 200 ASR D1Ar5,D0Ar6,#31 /* Sign extend D0Ar6 into D1Ar5 */ 201 GETL D0Ar4,D1Ar3,[A0.3] /* Read ___TBITime(B/I) */ 202 MOV PC,D0FrT /* Return quickly */ 203 .size ___TBITimeCore,.-___TBITimeCore 204 205/* 206 * End of tbitimer.S 207 */ 208