LLC2_API
|
00001 /***************************************************************************** 00002 * 00003 * File: 00004 * 00005 * $RCSfile: llprotocol.c,v $ 00006 * 00007 * Copyright (C) 2001 D-TACQ Solutions Ltd 00008 * not to be used without owner's permission 00009 * 00010 * Description: implementation of app side bus protocol 00011 * 00012 * $Id: llprotocol.c,v 1.7.4.14 2010/08/26 16:25:52 pgm Exp $ 00013 * $Log: llprotocol.c,v $ 00014 * Revision 1.7.4.14 2010/08/26 16:25:52 pgm 00015 * more switchable instrumentation 00016 * 00017 * Revision 1.7.4.13 2009/04/02 13:19:01 pgm 00018 * docs away 00019 * 00020 * Revision 1.7.4.12 2006/02/24 17:32:37 pgm 00021 * seed V2 correctly 00022 * 00023 * Revision 1.7.4.11 2006/02/23 21:56:40 pgm 00024 * remove unwanted statics 00025 * 00026 * Revision 1.7.4.10 2006/01/15 14:30:17 pgm 00027 * *** empty log message *** 00028 * 00029 * Revision 1.7.4.9 2006/01/15 11:18:18 pgm 00030 * SYNC_2V 00031 * 00032 * Revision 1.7.4.8 2005/11/04 17:26:18 pgm 00033 * *** empty log message *** 00034 * 00035 * Revision 1.7.4.7 2005/09/25 20:32:34 pgm 00036 * LLCV2 initial poll corrected 00037 * 00038 * Revision 1.7.4.6 2005/08/11 10:02:24 pgm 00039 * SYNC_ECM - init host side slave memory areas 00040 * 00041 * Revision 1.7.4.5 2005/08/01 11:10:24 pgm 00042 * V2 part 1 running - local status, no hbpoll - ECM 100 acheived 00043 * 00044 * Revision 1.7.4.4 2004/09/25 08:31:37 pgm 00045 * *** empty log message *** 00046 * 00047 * Revision 1.7.4.3 2004/08/10 07:35:46 pgm 00048 * works with ACQ196 00049 * 00050 * Revision 1.7.4.2 2004/07/27 20:49:06 pgm 00051 * llcontrol 2G with AO - in debug 00052 * 00053 * Revision 1.7.4.1 2004/07/25 20:39:38 pgm 00054 * hbpolling, 96 channels 00055 * 00056 * Revision 1.7 2002/09/02 11:01:18 pgm 00057 * revised debug levels 00058 * 00059 * Revision 1.6 2002/04/02 10:15:38 pgm 00060 * emacs indent, untabify 00061 * 00062 * Revision 1.5 2002/03/12 15:37:52 pgm 00063 * emacs format rools OK 00064 * 00065 * Revision 1.4 2001/08/17 07:25:38 pgm 00066 * ll, aync update, has race 00067 * 00068 * Revision 1.3 2001/05/25 12:05:15 pgm 00069 * its a runner - shippit quick 00070 * 00071 * Revision 1.2 2001/05/23 19:16:21 pgm 00072 * doc 00073 * 00074 * Revision 1.1 2001/05/21 17:42:38 pgm 00075 * reformed 00076 * 00077 * Revision 1.5 2001/05/20 21:24:10 pgm 00078 * ll WIP - almost works 00079 * 00080 * Revision 1.4 2001/05/19 19:46:15 pgm 00081 * enters LL mode with good bufs, mboxes 00082 * 00083 * Revision 1.3 2001/05/19 07:03:40 pgm 00084 * LL done for SOFT CLOCK, compiles 00085 * 00086 * Revision 1.2 2001/05/18 20:21:13 pgm 00087 * compiles. needs algorithms 00088 * 00089 * Revision 1.1 2001/05/18 07:09:37 pgm 00090 * first cut - wont compile :-( 00091 * 00092 * Revision 1.2 2000/12/28 11:03:00 pgm 00093 * *** empty log message *** 00094 * 00095 * Revision 1.1 1999/10/22 16:26:49 pgm 00096 * first entry to cvs 00097 * 00098 * 00099 \*****************************************************************************/ 00100 00101 /** @file llprotocol.c implementation of bus level protocol. */ 00102 00103 00104 #include "local.h" 00105 00106 00107 #include <assert.h> 00108 #include "llif.h" 00109 00110 #include <stdio.h> 00111 #include <stdlib.h> 00112 00113 #include <errno.h> 00114 #include <fcntl.h> 00115 #include <signal.h> 00116 #include <sys/ioctl.h> 00117 #include <sys/mman.h> 00118 #include <sys/stat.h> 00119 #include <sys/types.h> 00120 #include <stdio.h> 00121 #include <unistd.h> 00122 00123 00124 #include "acq32busprot.h" 00125 //#include "platform.h" 00126 00127 #include "llprotocol.h" 00128 00129 00130 int pollAck( struct MU* m ) 00131 // polls regular ack from acq32 00132 { 00133 int ipoll = 0; 00134 00135 while( (getMbox( m, BP_MB_COMMAND )&MASK(BP_CI_ACK_BIT) ) == 0 ){ 00136 if ( (++ipoll&0xfffff) == 0 ){ 00137 fprintf( stderr, "pollAck %6d looking for 0x%08x got 0x%08x\n", 00138 ipoll, MASK(BP_CI_ACK_BIT), getMbox(m,BP_MB_COMMAND) ); 00139 } 00140 } 00141 00142 PRINTF(4)( "pollAck() done 0x%08x\n", getMbox(m,BP_MB_COMMAND) ); 00143 00144 return 0; 00145 } 00146 00147 00148 static int enterLLC( 00149 struct MU* m, 00150 unsigned mode, 00151 unsigned a3, 00152 int clkpos, 00153 int trpos 00154 ) 00155 { 00156 u32 command = MASK(BP_CI_DONE_BIT)+ 00157 MASK(BP_CI_COMMAND_BIT)+ 00158 BP_SET_FUNCODE(BP_FC_SET_MODE_LLC)+ 00159 mode; 00160 00161 if ( clkpos ){ 00162 command |= BP_SET_A1(BP_FC_SET_MODE_LLC_CLKPOL_POS); 00163 } 00164 if ( trpos ) { 00165 command |= BP_SET_A1(BP_FC_SET_MODE_LLC_TRPOL_POS); 00166 } 00167 00168 PRINTF(1)("enterLLC()\n"); 00169 00170 setMbox( m, BP_MB_A3, a3 ); 00171 setMbox( m, BP_MB_COMMAND, command ); 00172 pollAck( m ); 00173 pollMboxBits( m, BP_MB_COMMAND, LLC_CSR_READY, LLC_CSR_READY ); 00174 00175 setPathCleanup(m, LLC_CSR_M_ESC); 00176 return 0; 00177 } 00178 00179 int enterLLCSoftClock( 00180 struct MU* m, int clkpos, int trpos, int internal_loopback, 00181 u32 command_mods) 00182 { 00183 u32 command = BP_FC_SET_MODE_LLC_SOFTCLOCK; 00184 00185 command |= command_mods; 00186 00187 if ( internal_loopback ){ 00188 command += BP_FC_SET_MODE_LLC_INTSOFT_CLK; 00189 } 00190 return enterLLC( 00191 m, 00192 BP_SET_A1(command), 00193 0, 00194 clkpos, 00195 trpos 00196 ); 00197 } 00198 00199 int enterLLCExtClock( 00200 struct MU* m, int clkpos, int trpos, 00201 unsigned short divisor, 00202 int internal_loopback, 00203 u32 command_mods 00204 ) 00205 { 00206 unsigned command = BP_FC_SET_MODE_LLC_EXTCLOCK; 00207 00208 command |= command_mods; 00209 00210 if ( internal_loopback ){ 00211 command += BP_FC_SET_MODE_LLC_INTDIV_CLK; 00212 } 00213 return enterLLC( 00214 m, 00215 BP_SET_A1(command), 00216 divisor, 00217 clkpos, 00218 trpos 00219 ); 00220 } 00221 00222 int enterLLC_SYNC_ECM( 00223 struct MU* m, int clkpos, int trpos, 00224 unsigned short divisor, 00225 int internal_loopback, 00226 u32 command_mods, 00227 u32 init_buf_baddr 00228 ) 00229 { 00230 setMbox( m, BP_MB_A4, init_buf_baddr); 00231 return enterLLCExtClock(m, clkpos, trpos, 00232 divisor, internal_loopback, 00233 command_mods|BP_FC_SET_LLCV2_INIT); 00234 } 00235 00236 int leaveLLC( struct MU* m ) 00237 { 00238 setPathCleanup(m, 0); 00239 llSetCmd( m,LLC_CSR_M_ESC ); 00240 fprintf( stderr, "leave LLC\n" ); 00241 return 0; 00242 } 00243 00244 00245 u32 llWaitDmaDone(struct MU* m) 00246 /** polls until DMA has completed. 00247 *Returns tlatch 00248 * guaranteed DMA done when tlatch updated 00249 */ 00250 { 00251 u32 old_tlatch = getMboxShadow(m, BP_MB_LLC_TADC); 00252 u32 tlatch; 00253 int ipoll = 0; 00254 00255 do { 00256 tlatch = llGetTlatch( m ); 00257 ++ipoll; 00258 } 00259 while (tlatch == old_tlatch); 00260 00261 setMboxPollcount(m, ipoll); 00262 return tlatch; 00263 } 00264 00265 /* 00266 * WARNING: SERVICE_ macros snipped from llc.ko 00267 * duplicate assignment statement adds a conditional bitop, but loses 00268 * an expensive str/ldr. Way to go! 00269 */ 00270 00271 #define ACQ196_TCR_MASK 0xfff 00272 00273 #define SERVICE_ROLLOVER(tim, reg, mask, temp) \ 00274 temp = (reg) & (mask); \ 00275 if (((tim) & (mask)) > (temp)){ \ 00276 (tim) = (((tim) & ~(mask)) | (temp)) + ((mask)+1); \ 00277 }else{ \ 00278 (tim) = (((tim) & ~(mask)) | (temp)); \ 00279 } 00280 00281 00282 00283 u32 llv2_extend32(u32 old32, u32 new12) 00284 /** return 32 bit count as function of old32, new12. */ 00285 { 00286 u32 y = old32; 00287 u32 t; 00288 00289 SERVICE_ROLLOVER(y, new12, ACQ196_TCR_MASK, t); 00290 return y; 00291 } 00292 00293 #define LLCV2_POISON 0xf0000001 00294 00295 u32 llv2WaitDmaDone(struct MU *m, volatile u32* hstats) 00296 /** polls until DMA has completed. 00297 * Returns tlatch 00298 * guaranteed DMA done when tlatch updated 00299 * V2 method does NOT poll PCI 00300 */ 00301 { 00302 unsigned pollcat = 0; 00303 unsigned mask = 0xffffff; 00304 00305 while (hstats[LLCV2_STATUS_BDR] == LLCV2_POISON){ 00306 if ((++pollcat&mask) == 0){ 00307 fprintf(stderr, 00308 "polling[%08x] %p current 0x%08x wait poison\n", 00309 pollcat, 00310 &hstats[LLCV2_STATUS_BDR], 00311 hstats[LLCV2_STATUS_BDR]); 00312 mask = (mask << 1) | 1; 00313 } 00314 } 00315 while (hstats[LLCV2_STATUS_BDR] != 0xdeadbeef){ 00316 if ((++pollcat&mask) == 0){ 00317 fprintf(stderr, "polling[%08x] %p current 0x%08x\n", 00318 pollcat, 00319 &hstats[LLCV2_STATUS_BDR], 00320 hstats[LLCV2_STATUS_BDR]); 00321 mask = (mask << 1) | 1; 00322 } 00323 } 00324 hstats[LLCV2_STATUS_BDR] = LLCV2_POISON; 00325 00326 setMboxPollcount(m, pollcat); 00327 return llv2_extend32( 00328 hstats[BP_MB_LLC_TADC], hstats[LLCV2_STATUS_TLATCH]); 00329 } 00330 00331 00332 u32 llv2WaitDmaDone_2v(struct MU *m, volatile u32* hstats, unsigned tlatch) 00333 /** polls until DMA has completed. 00334 * Returns tlatch 00335 * guaranteed DMA done when tlatch updated 00336 * V2 method does NOT poll PCI 00337 */ 00338 { 00339 unsigned pollcat = 0; 00340 unsigned mask = tlatch==0? 0x3fffffff: 0xffffff; 00341 00342 while (hstats[LLC_SYNC2V_IN_LAST] == LLCV2_POISON){ 00343 if ((++pollcat&mask) == 0){ 00344 fprintf(stderr, 00345 "polling[%08x] %p current 0x%08x\n", 00346 pollcat, 00347 &hstats[LLC_SYNC2V_IN_LAST], 00348 hstats[LLC_SYNC2V_IN_LAST]); 00349 mask = (mask << 1) | 1; 00350 } 00351 if (tlatch != 0 && pollcat > 0x7fffffff){ 00352 fprintf(stderr, "ERROR: timeout\n"); 00353 kill(getpid(), 1); 00354 return 0; 00355 } 00356 } 00357 hstats[LLC_SYNC2V_IN_LAST] = LLCV2_POISON; 00358 00359 setMboxPollcount(m, pollcat); 00360 return llv2_extend32(tlatch, hstats[LLCV2_STATUS_TLATCH]); 00361 } 00362 00363 00364 void llv2InitDmaDone(volatile u32* hstats) { 00365 hstats[LLCV2_STATUS_BDR] = LLCV2_POISON; 00366 hstats[LLC_SYNC2V_IN_LAST] = LLCV2_POISON; 00367 }