00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include "local.h"
00051
00052 #include <assert.h>
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055
00056 #include <errno.h>
00057 #include <fcntl.h>
00058 #include <sys/ioctl.h>
00059 #include <sys/mman.h>
00060 #include <sys/stat.h>
00061 #include <sys/time.h>
00062 #include <sys/types.h>
00063 #include <stdio.h>
00064 #include <unistd.h>
00065
00066 #include <popt.h>
00067
00068 #include "acq32ioctl.h"
00069 #include "acq32busprot.h"
00070
00071 #include "llif.h"
00072 #include "llprotocol.h"
00073
00074
00075 #include "llcontrol.h"
00076 #include "x86timer.h"
00077
00078 #define FLAVOR "ACQ196"
00079 #include "llcontrol-core.h"
00080
00081
00082 static void sync_2v_updateTstats(
00083 u32 cmd, struct Card* card, struct TimingStats* tstats)
00084
00085 {
00086 #define SAMPLE_SIZE (96*2)
00087 u32* stats = getVaddr(card->buf, card->sync_2v_offset_status_hsbt);
00088 tstats->tinst = llv2_extend32(stats[LLC_SYNC2V_IN_MBOX2],
00089 stats[LLC_SYNC2V_IN_TINST]);
00090 tstats->tprocess = LLC_GET_TCYCLE(stats[LLC_SYNC2V_IN_MBOX0]);
00091 }
00092
00093 static u32 card_sync_2v_WaitDmaDone(struct Card* card)
00094 {
00095 return card->tlatch = llv2WaitDmaDone_2v(card->mbx,
00096 getVaddr(card->buf, card->sync_2v_offset_status_hsbt),
00097 card->tlatch
00098 );
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 #define BAR_FIFO 3
00114
00115 static u32 getSlavePa(int slot)
00116 {
00117 char fname[128];
00118 char line[80];
00119 FILE *fp;
00120 int bar;
00121 u32 pa = 0;
00122
00123 sprintf(fname, "/dev/ao32cpci/ctrl/ao32cpci.%d/resource", slot);
00124
00125 fp = fopen(fname, "r");
00126 if (!fp){
00127 fprintf(stderr, "ERROR: failed to open \"%s\"\n", fname);
00128 exit(errno);
00129 }
00130
00131 for (bar = 0; fgets(line, 80, fp); ++bar){
00132 if (bar == BAR_FIFO){
00133 long long pa0, pa1, len;
00134 if (sscanf(line,
00135 "%Lx %Lx %Lx", &pa0, &pa1, &len) == 3){
00136 pa = (u32)pa0;
00137 }
00138 }
00139 }
00140 fclose(fp);
00141
00142 if (pa == 0){
00143 fprintf(stderr,
00144 "ERROR: failed to get sensible PA for %d\n", slot);
00145 }
00146 return pa;
00147 }
00148
00149
00150 static void setSlaveData(u32* aovec, void* src)
00151
00152
00153
00154 {
00155 static int ibit;
00156 unsigned long long DO_PAT = 1ULL<<ibit;
00157
00158 if (++ibit > 64){
00159 ibit = 0;
00160 }
00161
00162 memcpy(aovec, src, 16*sizeof(short));
00163 memcpy(aovec+8, src, 16*sizeof(short));
00164 memcpy(aovec+16, &DO_PAT, sizeof(unsigned long long));
00165 }
00166
00167
00168 void appEnterLLC_SYNC_2VAO32(
00169 int icard, struct MU *mu, struct TestDescription *td)
00170
00171
00172
00173
00174 {
00175 u32* init_buf = getVaddr(EACHBUF(td), 0);
00176 u32 target_pa = getBusAddr(EACHBUF(td), 0);
00177 struct Card* card = &td->cards[icard];
00178 int islave = 0;
00179 PRINTF(2)("appEnterLLC_SYNC_2V() va:%p pa:0x%08x %s slaves %d\n",
00180 init_buf, target_pa, MASTER? "MASTER": "",td->ao32_count);
00181
00182
00183
00184 llcv2_hb_offset = 0;
00185 card->sync_2v_offset_status_hsbt =
00186 LLCV2_AI_HSBT + td->channels*sizeof(short);
00187 card->tlatch = 0;
00188
00189
00190 updateTstats = sync_2v_updateTstats;
00191 waitDmaDone = card_sync_2v_WaitDmaDone;
00192
00193 init_buf[LLCV2_INIT_MARKER] = LLCV2_INIT_MAGIC_AO32;
00194 init_buf[LLCV2_INIT_AI_HSBT] = target_pa + LLCV2_AI_HSBT;
00195 init_buf[LLCV2_INIT_AO_HSBS] = target_pa + LLCV2_AO_HSBS;
00196
00197
00198 if (MASTER){
00199 for (islave = 0; islave < td->ao32_count; ++islave){
00200 init_buf[LLCV2_INIT_AO32PA0+islave] =
00201 getSlavePa(td->ao32_ids[islave]);
00202 }
00203 }
00204 init_buf[LLCV2_INIT_AO32PA0+islave] = 0;
00205
00206 enterLLC_SYNC_ECM(
00207 mu, td->clkpos, td->trpos,
00208 td->arg.divisor,td->internal_loopback,
00209 BP_FC_SET_LLCV2_INIT,
00210 target_pa );
00211 }
00212
00213 int runSYNC_2VAO32(struct TestDescription *td, int soft_clock)
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 {
00244 struct TimingStats tstats[MAXCARDS] = {};
00245 struct DacBuf {
00246 MFA mfa;
00247 void* bbb;
00248 } dac_buf[MAXCARDS];
00249 #define EACHBBB (dac_buf[icard].bbb)
00250 #define EACHDAC_BASE (EACHBBB + LLCV2_AO_HSBS)
00251 #define EACHDAC_BASE16 ((u16*)EACHDAC_BASE)
00252 #define BASE_AO32(ic) ((u32*)EACHDAC_BASE+INDEX_OF_LLC_SYNC2V_AO32(ic))
00253 #define V2SETDACS(src, icard) \
00254 memcpy(EACHDAC_BASE, (src)+(icard)*32, DAC_SAMPLE_SIZE)
00255
00256
00257 u32 cmd = LLC_MAKE_DECIM(td->decimation);
00258 #define OFFSET 0
00259
00260 int uses_dacs = td->update_dacs || td->feedback;
00261 void* dac_data;
00262
00263 EACHCARD_INIT;
00264
00265 if (uses_dacs) FOREACHCARD {
00266 EACHBBB = getVaddr(EACHBUF(td), 0);
00267 printf("card %d uses_dacs EACHBBB %p "
00268 "EACHDAC_BASE %p bus 0x%08x\n",
00269 icard, EACHBBB, EACHDAC_BASE,
00270 getBusAddr(EACHBUF(td), LLCV2_AO_HSBS) );
00271 }
00272
00273 FOREACHCARD{
00274 llSetTlatch(EACHMBX(td), tstats[icard].tlatch = 0xffffffff);
00275 llv2InitDmaDone(
00276 getVaddr(EACHBUF(td),
00277 EACHCARD(td)->sync_2v_offset_status_hsbt));
00278 }
00279
00280 FOREACHCARD{
00281 updateTargetAddr(cmd+LLC_CSR_M_ARM, EACHCARD(td), OFFSET);
00282 }
00283
00284 if (td->update_dacs){
00285 dac_data = td_get_next_dac_data(td);
00286 FOREACHCARD{
00287 V2SETDACS(dac_data, icard);
00288 }
00289 }
00290
00291 #if 0
00292
00293
00294 while( !llCounterRunning(FIRSTMBX(td), cmd) ){
00295 POLLALERT(ipoll, "Polling for Counter Running\n");
00296 }
00297 #endif
00298 INIT_TIMER;
00299
00300
00301 for ( td->iter = 0; td->iter != td->iterations; ++td->iter ){
00302 if (soft_clock) FOREACHCARD{
00303 llSetCmd(EACHMBX(td), cmd+LLC_CSR_M_SOFTCLOCK);
00304 }
00305
00306 FOREACHCARD{
00307 MARK_TIME(1, "waitDmaDone() before");
00308 tstats[icard].tlatch = waitDmaDone(EACHCARD(td));
00309 MARK_TIME(2, "waitDmaDone() after");
00310 }
00311
00312 if (!td->min_latency_test) FOREACHCARD{
00313 updateTstats(cmd, EACHCARD(td), &tstats[icard]);
00314 }
00315
00316
00317 if (td->do_work){
00318 doApplicationWork(td, OFFSET);
00319 }
00320
00321 if (td->feedback) {
00322 u16 *pvin = (u16 *)getVaddr(FIRSTBUF(td), OFFSET);
00323 u16 vin = pvin[td->feedback_channel];
00324 u32 feedback = vin << 16 | vin;
00325
00326 PRINTF(1)("feedback 0x%08x\n", feedback);
00327
00328 FOREACHCARD{
00329 MARK_TIME(3, "feedback 1");
00330 memset32(EACHDAC_BASE, feedback, DAC_COUNT/2);
00331
00332 if (td->update_dacs){
00333
00334 u16* excite = td_get_next_dac_data(td);
00335
00336 EACHDAC_BASE16[td->feedback_channel]
00337 = excite[td->feedback_channel];
00338 }
00339 MARK_TIME(4, "feedback 2");
00340 }
00341 }else if (td->update_dacs){
00342 int islave;
00343
00344 dac_data = td_get_next_dac_data(td);
00345 FOREACHCARD{
00346 V2SETDACS(dac_data, icard);
00347 MARK_TIME(5, "update_dacs");
00348 }
00349
00350
00351 for(THIS_CARD = 0, islave = 0;
00352 islave != td->ao32_count; ++islave){
00353 setSlaveData(BASE_AO32(islave), dac_data);
00354 }
00355 }
00356
00357 #if IGNORE_COUNTER_STOP
00358
00359
00360
00361
00362
00363 if (!td->hardware_gate_off &&
00364 !llCounterRunning(FIRSTMBX(td), cmd )){
00365 fprintf( stderr, "Trigger is off - stop\n" );
00366 break;
00367 }
00368 #endif
00369 FOREACHCARD_MARK_TIME(9, "after llCounterRunning check");
00370
00371 if (td->tlog){
00372 FOREACHCARD{
00373 tstats[icard].target_poll =
00374 getMboxPollcount(EACHMBX(td));
00375 MARK_TIME(10, "10");
00376 updateTimingStats(
00377 td->stats_buf[icard],
00378 td->iter,
00379 &tstats[icard]);
00380 }
00381 }
00382 TIMER_CHECK_OVERFLOW;
00383 }
00384
00385 G_quit = 1;
00386 return 0;
00387 #undef EACHMFA
00388 #undef EACHBBB
00389 #undef EACHDAC_BASE
00390 #undef EACHDAC_BASE16
00391 }
00392