LLC2_API
llprotocol.cpp
Go to the documentation of this file.
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 }