VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/libteac.c@ 69498

Last change on this file since 69498 was 53726, checked in by vboxsync, 10 years ago

properties.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.2 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/fcntl.h>
4#include <string.h>
5#include <time.h>
6
7#include "teac.h"
8
9/* Notes-
10 * -Why is elan3_fini dropping core? It's intermittent, and seems to
11 * depend on relative timing of multiple calls.
12 */
13
14#ifdef CHROMIUM
15#include <cr_string.h>
16#include <cr_mem.h>
17#include <cr_error.h>
18#else
19#define crAlloc(sz) malloc(sz)
20#define crStrncpy(out,in,sz) strncpy(out,in,sz)
21#define crMemcpy(out,in,bytes) memcpy(out,in,bytes)
22#define crStrchr(instr,inchr) strchr(instr,inchr)
23#define crFree(ptr) free(ptr)
24#define crRealloc( pp, size ) { \
25 if (!(*pp=realloc(*pp,size))) { \
26 fprintf(stderr,"failed to reallocate %d bytes!\n",size); \
27 abort(); \
28 } \
29}
30#include <stdarg.h>
31static void crDebug( const char* fmt, ... ) {
32 va_list ap;
33 va_start(ap,fmt);
34 vfprintf(stderr, fmt, ap);
35 va_end(ap);
36}
37#endif
38
39#define EADDR_ALLOC_ELAN 0x200000
40#define ALLOC_ELAN_SIZE 0x200000
41#define EADDR_ALLOC_MAIN 0x400000
42#define ALLOC_MAIN_SIZE 0x2000000
43
44/* We need some defs to handle changes in structures between software
45 * revisions.
46 */
47/* Capability shape is the same between KITE and pre-KITE */
48#ifdef ELAN_PRE_KITE
49
50/* software level is PRE_KITE */
51#define TEAC_DEVINFO_TYPE 0
52#define TEAC_CAP_TYPE 0
53
54#else
55#ifdef ELAN_PRE_EAGLE
56
57/* software level is KITE */
58
59#ifdef LINUX
60#define TEAC_DEVINFO_TYPE 1
61#define TEAC_CREATE_TYPE 1
62#else
63#define TEAC_DEVINFO_TYPE 0
64#define TEAC_CREATE_TYPE 0
65#endif
66#define TEAC_CAP_TYPE 1
67
68#else
69/* software level is EAGLE */
70#define TEAC_DEVINFO_TYPE 2
71#define TEAC_CAP_TYPE 2
72#define TEAC_CREATE_TYPE 2
73
74#endif
75#endif
76
77#if (TEAC_CAP_TYPE == 2)
78#define TEAC_CAP_ENTRIES(cap) ELAN_CAP_ENTRIES(cap)
79#else
80#define TEAC_CAP_ENTRIES(cap) (cap->Entries)
81#endif
82
83/* In the future we will use the bitwise AND of the rail masks */
84#define RAIL 0
85
86#ifndef HOST_TABLE_FILENAME
87#define HOST_TABLE_FILENAME "/usr/users/8/welling/elanstuff/teac/teac_host_map.t"
88#endif
89
90#define INITIAL_HOST_TABLE_SIZE 256
91
92static host_t* hosts= NULL; /* this one ends up sorted by host name */
93static int* hostsIndex= NULL; /* this is sorted by node ID */
94static sdramaddr_t* sdramAddrBase= NULL;
95static E3_Addr* elanAddrBase= NULL;
96
97static int nodeTablesInitialized= 0;
98static int nodeTableSize= 0;
99static int nodeCount= 0;
100
101static int read_node_map()
102{
103 FILE* f= NULL;
104 int i;
105 int iLine;
106 char buf[256];
107
108 if (hosts) crFree(hosts);
109 if (!(hosts= (host_t*)crAlloc(INITIAL_HOST_TABLE_SIZE*sizeof(host_t)))) {
110 fprintf(stderr,"libteac: read_node_map: unable to allocate %d bytes!\n",
111 INITIAL_HOST_TABLE_SIZE*sizeof(host_t));
112 abort();
113 }
114 nodeTableSize= INITIAL_HOST_TABLE_SIZE;
115
116 if (!(f=fopen(HOST_TABLE_FILENAME,"r"))) {
117 fprintf(stderr,"libteac: read_node_map: cannot open <%s> for reading!\n",
118 HOST_TABLE_FILENAME);
119 abort();
120 }
121
122 i= 0;
123 iLine= 0;
124 buf[sizeof(buf)-1]= '\0';
125 while (!feof(f) && !ferror(f)) {
126 char* tmp;
127 char* string;
128 if (!fgets(buf, sizeof(buf)-1, f)) break;
129 iLine++;
130 if (buf[0]=='#' || buf[0]=='\n' || buf[0]=='\0') continue;
131 if (i>=nodeTableSize) {
132 /* We need to grow the table */
133 int newSize= 2*nodeTableSize;
134 crRealloc((void**)&hosts,newSize*sizeof(host_t));
135 nodeTableSize= newSize;
136 }
137 if (!(string=strtok_r(buf," ,;\t\n",&tmp))) {
138 fprintf(stderr,"libteac: read_node_map: Bad machine name at line %d of %s!\n",
139 iLine, HOST_TABLE_FILENAME);
140 abort();
141 }
142 if (strlen(string)==0) continue; /* blank line */
143 hosts[i].name= strdup(string);
144
145 if (!(string=strtok_r(NULL," ,;\t\n",&tmp))) {
146 fprintf(stderr,"libteac: read_node_map: bad integer string at line %d of %s!\n",
147 iLine, HOST_TABLE_FILENAME);
148 abort();
149 }
150 errno= 0;
151 hosts[i].railMask= atoi(string);
152 if (errno != 0) {
153 fprintf(stderr,"libteac: read_node_map: bad integer %s at %s line %d!\n",
154 string, HOST_TABLE_FILENAME, iLine);
155 abort();
156 }
157
158 if (!(string=strtok_r(NULL," ,;\t\n",&tmp))) {
159 fprintf(stderr,"libteac: read_node_map: bad integer string at line %d of %s!\n",
160 iLine, HOST_TABLE_FILENAME);
161 abort();
162 }
163 errno= 0;
164 hosts[i].id= atoi(string);
165 if (errno != 0) {
166 fprintf(stderr,"libteac: read_node_map: bad integer %s at %s line %d!\n",
167 string, HOST_TABLE_FILENAME, iLine);
168 abort();
169 }
170
171 if (!(string=strtok_r(NULL," ,;\t\n",&tmp))) {
172 fprintf(stderr,"libteac: read_node_map: bad hex value at line %d of %s!\n",
173 iLine, HOST_TABLE_FILENAME);
174 abort();
175 }
176 errno= 0;
177 hosts[i].sdramAddrBase= (sdramaddr_t)strtol(string, (char**)NULL, 0);
178 if (errno != 0) {
179 fprintf(stderr,"libteac: read_node_map: bad hex address %s at %s line %d!\n",
180 string, HOST_TABLE_FILENAME, iLine);
181 abort();
182 }
183
184 if (!(string=strtok_r(NULL," ,;\t\n",&tmp))) {
185 fprintf(stderr,"libteac: read_node_map: bad hex value at line %d of %s!\n",
186 iLine, HOST_TABLE_FILENAME);
187 abort();
188 }
189 errno= 0;
190 hosts[i].elanAddrBase= (E3_Addr)strtol(string, (char**)NULL, 0);
191 if (errno != 0) {
192 fprintf(stderr,"libteac: read_node_map: bad hex address %s at %s line %d!\n",
193 string, HOST_TABLE_FILENAME, iLine);
194 abort();
195 }
196
197#if 0
198 crDebug("line %d: %d: got <%s> %d %d 0x%x 0x%x\n",
199 iLine, i, hosts[i].name, hosts[i].railMask, hosts[i].id,
200 hosts[i].sdramAddrBase, hosts[i].elanAddrBase);
201#endif
202
203 i++;
204 }
205 if (ferror(f)) {
206 perror("Error reading host table");
207 fprintf(stderr,"libteac: read_node_map: error reading <%s>!\n",
208 HOST_TABLE_FILENAME);
209 abort();
210 }
211
212 (void)fclose(f);
213 return i;
214}
215
216static int hostnameCompare(const void* h1, const void* h2)
217{
218 return strcmp(((host_t*)h1)->name, ((host_t*)h2)->name);
219}
220
221static int hostnameLookup(const void* h1, const void* h2)
222{
223 return strcmp((const char*)h1, ((host_t*)h2)->name);
224}
225
226static void initialize_node_tables()
227{
228 if (!nodeTablesInitialized) {
229 int nodeMin;
230 int nodeMax;
231 int nodeRange;
232 int i;
233
234 crDebug("Loading Quadrics network map from <%s>\n",HOST_TABLE_FILENAME);
235
236 /* Load information about Quadrics network */
237 nodeCount= read_node_map();
238 if (nodeCount==0) {
239 fprintf(stderr,
240 "libteac: initialize_node_tables: no valid nodes in %s!\n",
241 HOST_TABLE_FILENAME);
242 abort();
243 }
244
245 /*
246 * Build the offset tables. Offsets are looked up by node ID, so we
247 * have to avoid redundant IDs and order the tables correctly.
248 */
249 nodeMin= nodeMax= hosts[0].id;
250 for (i=1; i<nodeCount; i++) {
251 if (hosts[i].id<nodeMin) nodeMin= hosts[i].id;
252 if (hosts[i].id>nodeMax) nodeMax= hosts[i].id;
253 }
254 nodeRange= (nodeMax-nodeMin) + 1;
255 if (!(sdramAddrBase=(sdramaddr_t*)crAlloc(nodeRange*sizeof(sdramaddr_t)))) {
256 fprintf(stderr,
257 "libteac: initialize_node_tables: unable to allocate %d bytes!\n",
258 nodeRange*sizeof(sdramaddr_t));
259 abort();
260 }
261 if (!(elanAddrBase=(E3_Addr*)crAlloc(nodeRange*sizeof(E3_Addr)))) {
262 fprintf(stderr,
263 "libteac: initialize_node_tables: unable to allocate %d bytes!\n",
264 nodeRange*sizeof(E3_Addr));
265 abort();
266 }
267 for (i=0; i<nodeRange; i++) {
268 sdramAddrBase[i]= (sdramaddr_t)0;
269 elanAddrBase[i]= (E3_Addr)0;
270 }
271 for (i=0; i<nodeCount; i++) {
272 sdramAddrBase[hosts[i].id]= hosts[i].sdramAddrBase;
273 elanAddrBase[hosts[i].id]= hosts[i].elanAddrBase;
274 }
275
276 /* Sort the host table alphabetically by host name for faster lookup */
277 qsort( hosts, nodeCount, sizeof(host_t), hostnameCompare );
278
279 /* Build an ordered index into the hosts table */
280 if (hostsIndex) crFree(hostsIndex);
281 if (!(hostsIndex= (int*)crAlloc(nodeRange*sizeof(int)))) {
282 fprintf(stderr,"libteac: read_node_map: unable to allocate %d bytes!\n",
283 nodeCount*sizeof(int));
284 abort();
285 }
286 for (i=0; i<nodeRange; i++) hostsIndex[i]= 0;
287 for (i=0; i<nodeCount; i++) hostsIndex[hosts[i].id]= i;
288
289 nodeTablesInitialized= 1;
290 }
291}
292
293static int trans_host(const char *hn) {
294 host_t* h= NULL;
295
296 if (!nodeTablesInitialized) initialize_node_tables();
297
298#if 0
299 char buf[128];
300 int i;
301 i= 0;
302 while (i<sizeof(buf)-1 && hn[i] && hn[i]!='.') { buf[i]= hn[i]; i++; };
303 buf[i]= '\0';
304#endif
305
306 h=(host_t*)bsearch(hn, hosts, nodeCount, sizeof(host_t), hostnameLookup);
307#if 0
308 if (h) {
309 crDebug("Lookup <%s> got <%s> <%d> <%x> <%x>\n",
310 hn,h->name,h->id,(int)h->sdramAddrBase,(int)h->elanAddrBase);
311 }
312 else fprintf(stderr,"Lookup <%s> returned NULL!\n",hn);
313#endif
314 if (h) return h->id;
315 else return -1;
316}
317
318/*
319 * A version of address translation with some safety checks
320 */
321static E3_Addr teac_main2elan( ELAN3_CTX *ctx, void* main_addr )
322{
323 E3_Addr result= elan3_main2elan(ctx,main_addr);
324 /*
325 crDebug("mapping %0lx -> %d; addressable %d\n",
326 main_addr,result,elan3_addressable(ctx,main_addr,64));
327 */
328 if (result==ELAN_BAD_ADDR) {
329 fprintf(stderr,"Address translation error: %0x has no elan equivalent\n",
330 (int)main_addr);
331 abort();
332 }
333 return result;
334}
335
336Tcomm *teac_Init(char *lh, char *hh, int lctx, int hctx, int myrank,
337 const unsigned char key[TEAC_KEY_SIZE])
338{
339#if (TEAC_DEVINFO_TYPE == 2)
340 ELAN_DEVINFO info;
341 ELAN_POSITION position;
342#else
343 ELAN3_DEVINFO info;
344#endif
345 ELAN_CAPABILITY *cap;
346 Tcomm* result= NULL;
347 int i;
348 int j;
349 int a;
350 int b;
351 char buf[256];
352 char* here;
353#if ( TEAC_CREATE_TYPE == 0 )
354 void* control;
355#endif
356
357 if (!nodeTablesInitialized) initialize_node_tables();
358
359 if (!(result= (Tcomm*)crAlloc(sizeof(Tcomm)))) {
360 fprintf(stderr,"teac_Init: unable to allocate %d bytes!\n",
361 sizeof(Tcomm));
362 return(NULL);
363 }
364 result->ctx = NULL;
365 result->dma = NULL;
366 result->e_dma = 0;
367 result->s_event = 0;
368 result->r_event = NULL;
369 for (i=0; i<NUM_SEND_BUFFERS; i++) result->sbuf_pull_event[i] = 0;
370 result->rbuf_pull_event = 0;
371 result->m_snd = NULL;
372 result->m_rcv = NULL;
373 for (i=0; i<NUM_SEND_BUFFERS; i++) result->sbuf_ready[i]= NULL;
374 result->rbuf_ready = NULL;
375 result->mbuff= NULL;
376 for (i=0; i<NUM_SEND_BUFFERS; i++) result->sendWrappers[i]= NULL;
377 result->vp = -1;
378 result->hhost = result->lhost = -1;
379 result->hctx = result->lctx = -1;
380 result->msgnum = 0;
381 result->poll_shift = 0;
382 result->totalSendBufferBytesAllocated= 0;
383 result->totalRecvBufferBytesAllocated= 0;
384
385 a = trans_host(lh);
386 b = trans_host(hh);
387 result->lhost = (a < b)? a : b;
388 result->hhost = (a > b) ? a : b;
389
390 result->lctx = (lctx<hctx) ? lctx : hctx;
391 result->hctx = (hctx>lctx) ? hctx : lctx;
392
393 cap = &(result->cap);
394#if (TEAC_CAP_TYPE == 2)
395 elan_nullcap(cap);
396 /* Initialize the UserKey to the given value */
397 crMemcpy((void*)&(cap->cap_userkey.key_values),key,TEAC_KEY_SIZE);
398 cap->cap_lowcontext = lctx;
399 cap->cap_mycontext = lctx + (myrank%4);
400 cap->cap_highcontext = hctx;
401 cap->cap_lownode = result->lhost;
402 cap->cap_highnode = result->hhost;
403 cap->cap_type =
404 ELAN_CAP_TYPE_BLOCK | ELAN_CAP_TYPE_NO_BITMAP | ELAN_CAP_TYPE_MULTI_RAIL;
405#else
406 elan3_nullcap(cap);
407 /* Initialize the UserKey to the given value */
408 crMemcpy((void*)&(cap->UserKey),key,TEAC_KEY_SIZE);
409 cap->LowContext = lctx;
410 cap->MyContext = lctx + (myrank%4);
411 cap->HighContext = hctx;
412 cap->LowNode = result->lhost;
413 cap->HighNode = result->hhost;
414 cap->Entries = (hctx - lctx + 1) * (cap->HighNode - cap->LowNode + 1);
415 cap->Type =
416 ELAN_CAP_TYPE_BLOCK | ELAN_CAP_TYPE_NO_BITMAP | ELAN_CAP_TYPE_MULTI_RAIL;
417#endif
418
419 if ((result->ctx = elan3_init( 0, EADDR_ALLOC_MAIN, ALLOC_MAIN_SIZE,
420 EADDR_ALLOC_ELAN, ALLOC_ELAN_SIZE))
421 == NULL) {
422 fprintf(stderr, "teac_Init: elan3_init returned NULL context\n");
423 return(NULL);
424 }
425 elan3_block_inputter (result->ctx, 1);
426
427#if ( TEAC_CREATE_TYPE == 0 )
428 if ((control = elan3_control_open (RAIL)) != NULL) {
429 if (elan3_create(control, &(result->cap))) {
430 crDebug("elan3_create failed with <%s>, but that's OK!\n",
431 strerror(errno));
432 errno= 0;
433 }
434 }
435 else {
436 perror("elan3_control_open failed");
437 teac_Close(result);
438 return NULL;
439 }
440#elif ( TEAC_CREATE_TYPE == 1 )
441 if (elan3_create(result->ctx, &(result->cap))) {
442 crDebug("elan3_create failed with <%s>, but that's OK!\n",
443 strerror(errno));
444 errno= 0;
445 }
446#else
447 /* I don't think we have to do anything here! */
448#endif
449
450#if (TEAC_DEVINFO_TYPE == 2)
451 (void)elan3_get_devinfo(result->ctx, &info);
452 (void)elan3_get_position(result->ctx, &position);
453 crDebug("Position mode %d, NodeID %d, NumNodes %d, NumLevels %d\n",
454 position.pos_mode,position.pos_nodeid, position.pos_nodes,
455 position.pos_levels);
456 if (position.pos_mode != ELAN_POS_MODE_SWITCHED)
457 crDebug("WARNING: position mode is not %d!\n",ELAN_POS_MODE_SWITCHED);
458 crDebug("Rail %d\n",info.dev_rail);
459#elif (TEAC_DEVINFO_TYPE == 1)
460 elan3_devinfo(0, &info);
461 crDebug("NodeId: %d, NumNodes: %d, NumLevels: %d, NodeLevel: %d\n",
462 info.Position.NodeId, info.Position.NumNodes,
463 info.Position.NumLevels, info.Position.NodeLevel);
464#else
465 elan3_devinfo(0, &info);
466 crDebug("NodeId: %d, NumLevels: %d, NodeLevel: %d\n",
467 info.NodeId, info.NumLevels, info.NodeLevel);
468#endif
469
470#if 0
471 {
472 static char junkString[256];
473#if (TEAC_CAP_TYPE == 2)
474 crDebug("Capability: <%s>\n",
475 elan_capability_string(&(result->cap),junkString));
476 crDebug("railmask is %d\n",result->cap.cap_railmask);
477 crDebug("bitmap is %x\n",result->cap.cap_bitmap[0]);
478#else
479 crDebug("Capability: <%s>\n",
480 elan3_capability_string(&(result->cap),junkString));
481 crDebug("railmask is %d\n",result->cap.RailMask);
482 crDebug("bitmap is %x\n",result->cap.Bitmap[0]);
483#endif
484 }
485#endif
486
487 /* Reality check. */
488 if (gethostname(buf,sizeof(buf)-1)) {
489 perror("Can't get my own host name");
490 teac_Close(result);
491 return NULL;
492 }
493 if ((here= crStrchr(buf,'.')) != NULL) *here= '\0';
494
495#if (TEAC_DEVINFO_TYPE == 2)
496 if (trans_host(buf) != (int)position.pos_nodeid) {
497 fprintf(stderr,
498 "teac_Init: Expected Quadrics port id %d does not match real value %d!\n",
499 trans_host(buf), position.pos_nodeid);
500 teac_Close(result);
501 return NULL;
502 }
503#elif (TEAC_DEVINFO_TYPE == 1)
504 if (trans_host(buf) != info.Position.NodeId) {
505 fprintf(stderr,
506 "teac_Init: Expected Quadrics port id %d does not match real value %d!\n",
507 trans_host(buf), info.Position.NodeId);
508 teac_Close(result);
509 return NULL;
510 }
511#else
512 if (trans_host(buf) != info.NodeId) {
513 fprintf(stderr,
514 "teac_Init: Expected Quadrics port id %d does not match real value %d!\n",
515 trans_host(buf), info.NodeId);
516 teac_Close(result);
517 return NULL;
518 }
519#endif
520
521 if (elan3_attach(result->ctx, &(result->cap))) {
522 fprintf(stderr, "teac_Init: elan3_attach failed\n");
523 teac_Close(result);
524 return(NULL);
525 }
526
527 if (elan3_addvp(result->ctx, 0, &(result->cap))) {
528 fprintf(stderr, "teac_Init: elan3_addvp failed\n");
529 teac_Close(result);
530 return(NULL);
531 }
532
533 result->vp = elan3_process(result->ctx);
534
535 if (! elan3_set_required_mappings (result->ctx)) {
536 fprintf(stderr, "teac_Init: elan3_set_required_mappings failed\n");
537 teac_Close(result);
538 return(NULL);
539 }
540
541 if (!(result->r_event=
542 (sdramaddr_t**)crAlloc( TEAC_CAP_ENTRIES(cap)*sizeof(sdramaddr_t*) ))) {
543 fprintf(stderr,"teac_Init: unable to allocate %d bytes!\n",
544 TEAC_CAP_ENTRIES(cap)*sizeof(sdramaddr_t*));
545 teac_Close(result);
546 return(NULL);
547 }
548 if (!(result->r_event[0]=
549 (sdramaddr_t*)crAlloc( TEAC_CAP_ENTRIES(cap)*NUM_SEND_BUFFERS
550 * sizeof(sdramaddr_t) ))) {
551 fprintf(stderr,"teac_Init: unable to allocate %d bytes!\n",
552 TEAC_CAP_ENTRIES(cap)*NUM_SEND_BUFFERS*sizeof(sdramaddr_t));
553 teac_Close(result);
554 return(NULL);
555 }
556 if (!(result->r_event[0][0]=
557 elan3_allocElan(result->ctx, E3_EVENT_ALIGN,
558 TEAC_CAP_ENTRIES(cap)*NUM_SEND_BUFFERS*sizeof(E3_BlockCopyEvent)))) {
559 perror("teac_Init: elan3_allocElan failed for r_event block");
560 teac_Close(result);
561 return(NULL);
562 }
563 for (j=1; j<TEAC_CAP_ENTRIES(cap); j++) {
564 result->r_event[j]= result->r_event[0] + j*NUM_SEND_BUFFERS;
565 result->r_event[j][0]=
566 result->r_event[0][0]+j*NUM_SEND_BUFFERS*sizeof(E3_BlockCopyEvent);
567 }
568 for (j=0; j<TEAC_CAP_ENTRIES(cap); j++)
569 for (i=1; i<NUM_SEND_BUFFERS; i++) {
570 result->r_event[j][i]=
571 result->r_event[j][0] + i*sizeof(E3_BlockCopyEvent);
572 }
573#if 0
574 crDebug("r_event[0][0] is %x\n",(int)result->r_event[0][0]);
575#endif
576
577 if (!(result->m_rcv=
578 (volatile E3_uint32**)crAlloc( TEAC_CAP_ENTRIES(cap)*sizeof(E3_uint32*) ))) {
579 fprintf(stderr,"teac_Init: unable to allocate %d bytes!\n",
580 TEAC_CAP_ENTRIES(cap)*sizeof(E3_uint32*));
581 teac_Close(result);
582 return(NULL);
583 }
584 if (!(result->m_rcv[0]= (volatile E3_uint32*)
585 elan3_allocMain(result->ctx, 0,
586 TEAC_CAP_ENTRIES(cap)*NUM_SEND_BUFFERS*sizeof(E3_uint32)))) {
587 perror("teac_Init: elan3_allocMain failed for m_rcv block");
588 teac_Close(result);
589 return(NULL);
590 }
591 for (i=1; i<TEAC_CAP_ENTRIES(cap); i++)
592 result->m_rcv[i]= result->m_rcv[0] + i*NUM_SEND_BUFFERS;
593#if 0
594 crDebug("Base of m_rcv is %lx -> %lx\n",
595 (long)(result->m_rcv[0]),
596 (long)teac_main2elan(result->ctx,(void*)(result->m_rcv[0])));
597#endif
598
599 if (!(result->mbuff= (teacMsg**)crAlloc( TEAC_CAP_ENTRIES(cap)*sizeof(teacMsg*) ))) {
600 fprintf(stderr,"teac_Init: unable to allocate %d bytes!\n",
601 TEAC_CAP_ENTRIES(cap)*sizeof(teacMsg*));
602 teac_Close(result);
603 return(NULL);
604 }
605 if (!(result->mbuff[0]= (teacMsg*)
606 elan3_allocMain(result->ctx, 8,
607 TEAC_CAP_ENTRIES(cap)*NUM_SEND_BUFFERS*sizeof(teacMsg)))) {
608 perror("teac_Init: elan3_allocMain failed for mbuff block");
609 teac_Close(result);
610 return(NULL);
611 }
612 for (i=1; i<TEAC_CAP_ENTRIES(cap); i++)
613 result->mbuff[i]= result->mbuff[0] + i*NUM_SEND_BUFFERS;
614#if 0
615 crDebug("Base of mbuff is %lx -> %lx\n",
616 (long)(result->mbuff[0]),
617 (long)teac_main2elan(result->ctx,result->mbuff[0]));
618#endif
619
620 if (!(result->dma= (E3_DMA_MAIN *)
621 elan3_allocMain(result->ctx,
622 E3_DMA_ALIGN, sizeof(E3_DMA_MAIN)))) {
623 perror("teac_Init: elan3_allocMain failed for dma");
624 teac_Close(result);
625 return(NULL);
626 }
627
628 if (!(result->e_dma=
629 elan3_allocElan(result->ctx, E3_DMA_ALIGN, sizeof(E3_DMA)))) {
630 perror("teac_Init: elan3_allocElan failed for e_dma");
631 teac_Close(result);
632 return(NULL);
633 }
634
635 if (!(result->s_event=
636 elan3_allocElan(result->ctx, E3_EVENT_ALIGN,
637 sizeof(E3_BlockCopyEvent)))) {
638 perror("teac_Init: elan3_allocElan failed for s_event");
639 teac_Close(result);
640 return(NULL);
641 }
642#if 0
643 crDebug("s_event is %x\n",(int)result->s_event);
644#endif
645
646 if (!(result->sbuf_pull_event[0]=
647 elan3_allocElan(result->ctx, E3_EVENT_ALIGN,
648 NUM_SEND_BUFFERS*sizeof(E3_BlockCopyEvent)))) {
649 perror("teac_Init: elan3_allocElan failed for sbuf_pull_event block");
650 teac_Close(result);
651 return(NULL);
652 }
653 for (i=1; i<NUM_SEND_BUFFERS; i++)
654 result->sbuf_pull_event[i]=
655 result->sbuf_pull_event[0]+i*sizeof(E3_BlockCopyEvent);
656
657 if (!(result->rbuf_pull_event=
658 elan3_allocElan(result->ctx, E3_EVENT_ALIGN,
659 sizeof(E3_BlockCopyEvent)))) {
660 perror("teac_Init: elan3_allocElan failed for rbuf_pull_event");
661 teac_Close(result);
662 return(NULL);
663 }
664
665 if (!(result->m_snd= (E3_uint32 *)
666 elan3_allocMain(result->ctx, 0,
667 sizeof(E3_uint32)))) {
668 perror("teac_Init: elan3_allocMain failed for m_snd");
669 teac_Close(result);
670 return(NULL);
671 }
672
673 if (!(result->sbuf_ready[0]= (E3_uint32 *)
674 elan3_allocMain(result->ctx, 0,
675 NUM_SEND_BUFFERS*sizeof(E3_uint32)))) {
676 perror("teac_Init: elan3_allocMain failed for sbuf_ready block");
677 teac_Close(result);
678 return(NULL);
679 }
680 for (i=1; i<NUM_SEND_BUFFERS; i++)
681 result->sbuf_ready[i]= result->sbuf_ready[0] + i;
682
683 if (!(result->sendWrappers[0]=
684 (SBuffer*)crAlloc(NUM_SEND_BUFFERS*sizeof(SBuffer)))) {
685 fprintf(stderr,"teac_Init: unable to allocate %d bytes!\n",
686 NUM_SEND_BUFFERS*sizeof(SBuffer));
687 teac_Close(result);
688 return(NULL);
689 }
690 for (i=1; i<NUM_SEND_BUFFERS; i++)
691 result->sendWrappers[i]= result->sendWrappers[0] + i;
692
693 if (!(result->rbuf_ready= (E3_uint32 *)
694 elan3_allocMain(result->ctx, 0,
695 sizeof(E3_uint32)))) {
696 perror("teac_Init: elan3_allocMain failed for rbuf_ready");
697 teac_Close(result);
698 return(NULL);
699 }
700
701 for (i=0; i<NUM_SEND_BUFFERS; i++) {
702 char* buf;
703 if (!(buf= (char*)elan3_allocMain(result->ctx, 8,
704 E_BUFFER_INITIAL_SIZE))) {
705 perror("teac_Init: elan3_allocMain failed for buffer block");
706 teac_Close(result);
707 return(NULL);
708 }
709 result->sendWrappers[i]->bufId= i;
710 result->sendWrappers[i]->totSize= E_BUFFER_INITIAL_SIZE;
711 result->sendWrappers[i]->validSize= 0;
712 result->sendWrappers[i]->buf= buf;
713 result->totalSendBufferBytesAllocated += result->sendWrappers[i]->totSize;
714 }
715
716 elan3_initevent_word (result->ctx,
717 result->s_event, result->m_snd);
718 elan3_initevent_word (result->ctx,
719 result->rbuf_pull_event, result->rbuf_ready);
720
721 for (i=0; i<NUM_SEND_BUFFERS; i++) {
722 elan3_initevent_word (result->ctx,
723 result->sbuf_pull_event[i], result->sbuf_ready[i]);
724 }
725
726 for (j=0; j<TEAC_CAP_ENTRIES(cap); j++)
727 for (i=0; i<NUM_SEND_BUFFERS; i++) {
728 elan3_initevent_word (result->ctx,
729 result->r_event[j][i], &(result->m_rcv[j][i]));
730 }
731
732 /* Get the message receive events ready to fire, in case something
733 * comes in before receive gets called.
734 */
735 for (j=0; j<TEAC_CAP_ENTRIES(cap); j++)
736 for (i=0; i<NUM_SEND_BUFFERS; i++) {
737 elan3_primeevent(result->ctx, result->r_event[j][i], 1);
738 }
739
740 /* Fire the sbuffer free events, so that the buffers look free when
741 * the first call to send happens.
742 */
743 for (i=0; i<NUM_SEND_BUFFERS; i++) {
744 elan3_primeevent(result->ctx, result->sbuf_pull_event[i], 1);
745 elan3_setevent( result->ctx, result->sbuf_pull_event[i] );
746 }
747
748 /* And now we're ready to face the world. */
749 elan3_block_inputter (result->ctx, 0);
750
751 return(result);
752}
753
754void teac_Close(Tcomm *tcomm)
755{
756 int i;
757
758 if (tcomm) {
759 /* First we have to wait until all pending messages have been
760 * pulled (assuming they got initialized in the first place).
761 */
762 if ((tcomm->sbuf_pull_event[0] != 0) && (tcomm->sbuf_ready[0] != NULL)) {
763 for (i=0; i<NUM_SEND_BUFFERS; i++) {
764 elan3_waitevent_word(tcomm->ctx, tcomm->sbuf_pull_event[i],
765 tcomm->sbuf_ready[i], 10);
766 }
767 crDebug("All TEAC messages have reported home!\n");
768 }
769 elan3_block_inputter (tcomm->ctx, 1);
770
771 if (tcomm->e_dma != 0) elan3_freeElan(tcomm->ctx, tcomm->e_dma);
772 if (tcomm->s_event != 0) elan3_freeElan(tcomm->ctx, tcomm->s_event);
773 if (tcomm->r_event != NULL) {
774 if (tcomm->r_event[0] != NULL) {
775 if (tcomm->r_event[0][0] != 0) elan3_freeElan(tcomm->ctx,
776 tcomm->r_event[0][0]);
777 crFree(tcomm->r_event[0]);
778 }
779 crFree(tcomm->r_event);
780 }
781 if (tcomm->sbuf_pull_event[0] != 0)
782 elan3_freeElan(tcomm->ctx, tcomm->sbuf_pull_event[0]);
783 if (tcomm->sendWrappers[0] != NULL) {
784 for (i=0; i<NUM_SEND_BUFFERS; i++) {
785 if (tcomm->sendWrappers[i]->buf != NULL) {
786 elan3_free(tcomm->ctx, tcomm->sendWrappers[i]->buf);
787 tcomm->totalSendBufferBytesAllocated -=
788 tcomm->sendWrappers[i]->totSize;
789 }
790 }
791 crFree(tcomm->sendWrappers[0]);
792 }
793 if (tcomm->rbuf_pull_event != 0)
794 elan3_freeElan(tcomm->ctx, tcomm->rbuf_pull_event);
795 if (tcomm->m_snd != NULL) elan3_free(tcomm->ctx,
796 (E3_uint32*)tcomm->m_snd);
797 if (tcomm->m_rcv != NULL) {
798 if (tcomm->m_rcv[0] != NULL) elan3_free(tcomm->ctx,
799 (E3_uint32*)tcomm->m_rcv[0]);
800 crFree(tcomm->m_rcv);
801 }
802 if (tcomm->sbuf_ready[0] != NULL)
803 elan3_free(tcomm->ctx, (E3_uint32*)tcomm->sbuf_ready[0]);
804 if (tcomm->rbuf_ready != NULL) elan3_free(tcomm->ctx,
805 (E3_uint32*)tcomm->rbuf_ready);
806 if (tcomm->mbuff != NULL) {
807 if (tcomm->mbuff[0] != NULL) elan3_free(tcomm->ctx, tcomm->mbuff[0]);
808 crFree(tcomm->mbuff);
809 }
810#if (TEAC_CREATE_TYPE==2)
811 elan3_detach(tcomm->ctx);
812 elan3_fini(tcomm->ctx);
813#else
814 /* elan3_detach and elan3_destroy seem to crash sometimes in
815 * these versions.
816 */
817#endif
818 }
819}
820
821int teac_Select(Tcomm* tcomm, int *ids, int num_ids, int timeout)
822{
823 int id;
824 while (timeout-- > 0) {
825 if ((id= teac_Poll(tcomm, ids, num_ids)) >= 0) return id;
826 }
827
828 return -1;
829}
830
831int teac_Poll(Tcomm* tcomm, int *ids, int num_ids)
832{
833 int i;
834 int j;
835
836 for (j=0; j<num_ids; j++) {
837 int index= (j+tcomm->poll_shift) % num_ids;
838 int thisId= ids[index];
839 for (i=0; i<NUM_SEND_BUFFERS; i++) {
840 if (elan3_pollevent_word(tcomm->ctx, &(tcomm->m_rcv[thisId][i]), 1)) {
841#ifdef never
842 tcomm->poll_shift= index;
843#endif
844 return thisId;
845 }
846 }
847 }
848
849 return -1;
850}
851
852int teac_sendBufferAvailable(Tcomm* tcomm)
853{
854 int i;
855 for (i=0; i<NUM_SEND_BUFFERS; i++) {
856 if (elan3_pollevent_word(tcomm->ctx, tcomm->sbuf_ready[i], 1))
857 return 1;
858 }
859 return 0;
860}
861
862SBuffer* teac_getSendBuffer( Tcomm* tcomm, long size )
863{
864 /* Find a free send buffer. We'll busy wait in this poll loop
865 * if necessary.
866 */
867 int i= 0;
868 while (1) {
869 if (elan3_pollevent_word(tcomm->ctx, tcomm->sbuf_ready[i],
870 1)) break;
871 if (++i == NUM_SEND_BUFFERS) i= 0;
872 }
873 /* We will use this buffer! */
874#if 0
875 crDebug("Allocated message buffer %d\n",i);
876#endif
877 *(tcomm->sbuf_ready[i])= 0; /* mark it busy */
878
879 /* If the associated chunk of memory is smaller than that requested,
880 * replace it with something larger.
881 */
882 if (tcomm->sendWrappers[i]->totSize < size) {
883 tcomm->totalSendBufferBytesAllocated -= tcomm->sendWrappers[i]->totSize;
884 elan3_free( tcomm->ctx, tcomm->sendWrappers[i]->buf );
885 if (!(tcomm->sendWrappers[i]->buf=
886 (char*)elan3_allocMain(tcomm->ctx, 8, size))) {
887 perror("teac_getSendBuffer: failed to grow send buffer");
888 exit(-1);
889 }
890 tcomm->totalSendBufferBytesAllocated += size;
891 }
892 tcomm->sendWrappers[i]->totSize= size;
893 tcomm->sendWrappers[i]->validSize= 0;
894 return tcomm->sendWrappers[i];
895}
896
897SBuffer* teac_getUnreadySendBuffer( Tcomm* tcomm, long size )
898{
899 SBuffer* result= NULL;
900 if (!(result= (SBuffer*)crAlloc(sizeof(SBuffer)))) {
901 fprintf(stderr,"libteac: read_node_map: unable to allocate %d bytes!\n",
902 sizeof(SBuffer));
903 abort();
904 }
905 result->bufId= -1; /* this marks it unready */
906#if 0
907 crDebug("Allocated an unready message buffer!\n");
908#endif
909
910 /* Allocate some DMA-able memory */
911 if (!(result->buf= (char*)elan3_allocMain(tcomm->ctx, 8, size))) {
912 perror("teac_getUnreadySendBuffer: failed to allocate elan3 memory");
913 exit(-1);
914 }
915 result->totSize= size;
916 result->validSize= 0;
917 tcomm->totalSendBufferBytesAllocated += result->totSize;
918
919 return result;
920}
921
922SBuffer* teac_makeSendBufferReady( Tcomm* tcomm, SBuffer* buf )
923{
924 int i= 0;
925 /* If the input buffer is already ready, just return it */
926 if (buf->bufId >= 0 && buf->bufId<NUM_SEND_BUFFERS) return buf;
927
928 /* Find a free send buffer. We'll busy wait in this poll loop
929 * if necessary.
930 */
931 while (1) {
932 if (elan3_pollevent_word(tcomm->ctx, tcomm->sbuf_ready[i],
933 1)) break;
934 if (++i == NUM_SEND_BUFFERS) i= 0;
935 }
936 /* We will use this buffer! */
937#if 0
938 crDebug("Allocated message buffer %d in makeSendBufferReady\n",i);
939#endif
940 *(tcomm->sbuf_ready[i])= 0; /* mark it busy */
941
942 /* Substitute the unready payload for the old payload */
943 tcomm->totalSendBufferBytesAllocated -= tcomm->sendWrappers[i]->totSize;
944 elan3_free( tcomm->ctx, tcomm->sendWrappers[i]->buf );
945 tcomm->sendWrappers[i]->buf= buf->buf;
946
947 tcomm->sendWrappers[i]->totSize= buf->totSize;
948 tcomm->sendWrappers[i]->validSize= buf->validSize;
949 crFree(buf);
950 return tcomm->sendWrappers[i];
951
952}
953
954int teac_Send( Tcomm* tcomm, int* ids, int num_ids, SBuffer* buf, void *start )
955{
956 int vp = tcomm->vp;
957 int iBuf;
958 int iDest;
959 teacMsg *msg;
960
961 /* Complain loudly if this is an unready buffer */
962 if (buf->bufId==-1) {
963 fprintf(stderr,"teac_Send: tried to send an unready buffer!\n");
964 return 0;
965 }
966
967 /* Reality check: is this one of my buffers? */
968 if (buf->bufId<0 || buf->bufId>=NUM_SEND_BUFFERS) {
969 fprintf(stderr,"teac_Send: I don't know this buffer!\n");
970 return 0;
971 }
972
973 /* Reality check: did they write too much into the message? */
974 if (buf->validSize > buf->totSize) {
975 fprintf(stderr,"teac_Send: message too large! (%ld vs %ld)\n",
976 buf->validSize, buf->totSize);
977 abort();
978 return 0;
979 }
980
981 iBuf= buf->bufId;
982 msg = &(tcomm->mbuff[vp][iBuf]);
983 msg->msgnum = tcomm->msgnum++;
984 msg->size = buf->validSize;
985 msg->host = vp;
986 if ( start != NULL )
987 msg->mptr = teac_main2elan( tcomm->ctx, start );
988 else
989 msg->mptr = teac_main2elan(tcomm->ctx, buf->buf);
990 msg->clr_event = elan3_sdram2elan(tcomm->ctx, tcomm->ctx->sdram,
991 tcomm->sbuf_pull_event[iBuf]);
992 msg->new= 1;
993
994 /* Set up the parts of the DMA that are not specific to destination */
995 tcomm->dma->dma_type = E3_DMA_TYPE(DMA_BYTE,DMA_WRITE,DMA_NORMAL,0);
996 tcomm->dma->dma_size = sizeof(teacMsg);
997 tcomm->dma->dma_srcEvent =
998 elan3_sdram2elan(tcomm->ctx,tcomm->ctx->sdram,tcomm->s_event);
999 tcomm->dma->dma_source = teac_main2elan(tcomm->ctx, msg);
1000 elan3_primeevent(tcomm->ctx, tcomm->sbuf_pull_event[buf->bufId], num_ids);
1001
1002 /* Send this message off to each destination */
1003 for (iDest=0; iDest<num_ids; iDest++) {
1004 tcomm->dma->dma_srcCookieVProc =
1005 elan3_local_cookie(tcomm->ctx, vp, ids[iDest]);
1006 tcomm->dma->dma_destCookieVProc = ids[iDest];
1007 tcomm->dma->dma_destEvent =
1008 elan3_sdram2elan(tcomm->ctx,tcomm->ctx->sdram,
1009 tcomm->r_event[vp][iBuf])
1010 + sdramAddrBase[(ids[iDest]/NUM_SEND_BUFFERS) + tcomm->lhost]
1011 - sdramAddrBase[(vp/NUM_SEND_BUFFERS) + tcomm->lhost];
1012 tcomm->dma->dma_dest = teac_main2elan(tcomm->ctx, msg)
1013 + elanAddrBase[(ids[iDest]/NUM_SEND_BUFFERS) + tcomm->lhost]
1014 - elanAddrBase[(vp/NUM_SEND_BUFFERS) + tcomm->lhost];
1015 elan3_primeevent(tcomm->ctx, tcomm->s_event, 1);
1016 *(tcomm->m_snd)= 0;
1017 elan3_putdma_main(tcomm->ctx, tcomm->dma, tcomm->e_dma);
1018#if 0
1019 crDebug("DMA dest event %x, dest mem %lx\n",
1020 tcomm->dma->dma_destEvent,
1021 (long)tcomm->dma->dma_dest);
1022 crDebug("Mem shifts are %x %x based on %d %d\n",
1023 elanAddrBase[(ids[iDest]/NUM_SEND_BUFFERS) + tcomm->lhost],
1024 elanAddrBase[(vp/NUM_SEND_BUFFERS) + tcomm->lhost],
1025 ids[iDest],vp);
1026 crDebug("Send msg %d in buffer %d to %d (list index %d)...",
1027 msg->msgnum,iBuf, ids[iDest],iDest);
1028#endif
1029 elan3_waitevent_word(tcomm->ctx,
1030 tcomm->s_event, tcomm->m_snd, ELAN_WAIT_EVENT);
1031#if 0
1032 crDebug("message away!\n");
1033#endif
1034 }
1035 return 1;
1036}
1037
1038RBuffer* teac_Recv(Tcomm* tcomm, int id)
1039{
1040 int vp = tcomm->vp;
1041 RBuffer* result= NULL;
1042 int iEvent= 0;
1043 int iBuf= 0;
1044 int i;
1045 int lowestMsgnum;
1046
1047 /* poll until we get an incoming message from the given sender */
1048 while (1) {
1049 if (elan3_pollevent_word(tcomm->ctx, &(tcomm->m_rcv[id][iEvent]), 1))
1050 break;
1051 if (++iEvent == NUM_SEND_BUFFERS) iEvent= 0;
1052 }
1053
1054 /* This may not be the earliest event, however. */
1055 lowestMsgnum= -1;
1056 for (i=0; i<NUM_SEND_BUFFERS; i++) {
1057#if 0
1058 crDebug("Testing for new msg at %lx -> %lx\n",
1059 (long)&(tcomm->mbuff[id][i]),
1060 (long)teac_main2elan(tcomm->ctx,(void*)(&tcomm->mbuff[id][i])));
1061#endif
1062 if (tcomm->mbuff[id][i].new) {
1063 if ((lowestMsgnum < 0)
1064 || (tcomm->mbuff[id][i].msgnum < (E3_uint32)lowestMsgnum)) {
1065 lowestMsgnum= tcomm->mbuff[id][i].msgnum;
1066 iBuf= i;
1067 }
1068 }
1069 }
1070 if (lowestMsgnum<0) {
1071 fprintf(stderr,
1072 "teac_Recv: internal error: can't find message I just got!\n");
1073 return NULL;
1074 }
1075 tcomm->mbuff[id][iBuf].new= 0;
1076 tcomm->m_rcv[id][iBuf]= 0;
1077 elan3_primeevent(tcomm->ctx, tcomm->r_event[id][iBuf],1);
1078#if 0
1079 crDebug("got msg %d in buffer %d from %d!\n",
1080 tcomm->mbuff[id][iBuf].msgnum, iBuf, id);
1081#endif
1082
1083 /* Make some space to put the message when it arrives */
1084 if (!(result= (RBuffer*)crAlloc(sizeof(RBuffer)))) {
1085 fprintf(stderr,"teac_Recv: unable to allocate %d bytes!\n",
1086 sizeof(RBuffer));
1087 return NULL;
1088 }
1089#if 0
1090 if (!(result->buf= (void*)elan3_allocMain(tcomm->ctx, 8,E_BUFFER_SIZE))) {
1091 perror("teac_Recv: elan3_allocMain failed for buffer");
1092 return(NULL);
1093 }
1094 result->totSize= E_BUFFER_SIZE;
1095#endif
1096 if (!(result->buf= (void*)elan3_allocMain(tcomm->ctx, 8,
1097 tcomm->mbuff[id][iBuf].size))) {
1098 perror("teac_Recv: elan3_allocMain failed for buffer");
1099 return(NULL);
1100 }
1101 result->totSize= tcomm->mbuff[id][iBuf].size;
1102 tcomm->totalRecvBufferBytesAllocated+= result->totSize;
1103 result->validSize= tcomm->mbuff[id][iBuf].size;
1104 result->from= tcomm->mbuff[id][iBuf].host;
1105 result->senderMsgnum= tcomm->mbuff[id][iBuf].msgnum;
1106
1107 /* Set up the DMA to pull the message */
1108 tcomm->dma->dma_type = E3_DMA_TYPE(DMA_BYTE,DMA_READ,DMA_NORMAL,0);
1109 tcomm->dma->dma_size = tcomm->mbuff[id][iBuf].size;
1110 tcomm->dma->dma_source = tcomm->mbuff[id][iBuf].mptr;
1111 tcomm->dma->dma_dest = teac_main2elan(tcomm->ctx,result->buf);
1112 tcomm->dma->dma_srcCookieVProc =
1113 elan3_remote_cookie(tcomm->ctx, vp, tcomm->mbuff[id][iBuf].host);
1114 tcomm->dma->dma_destCookieVProc =
1115 elan3_local_cookie(tcomm->ctx, vp, tcomm->mbuff[id][iBuf].host);
1116 tcomm->dma->dma_srcEvent = tcomm->mbuff[id][iBuf].clr_event;
1117 tcomm->dma->dma_destEvent =
1118 elan3_sdram2elan(tcomm->ctx,tcomm->ctx->sdram,
1119 tcomm->rbuf_pull_event);
1120
1121
1122 elan3_primeevent(tcomm->ctx, tcomm->rbuf_pull_event,1);
1123 *(tcomm->rbuf_ready)= 0;
1124 elan3_getdma_main(tcomm->ctx, tcomm->dma, tcomm->e_dma);
1125 elan3_waitevent_word(tcomm->ctx,
1126 tcomm->rbuf_pull_event,
1127 tcomm->rbuf_ready, ELAN_WAIT_EVENT);
1128
1129 return(result);
1130}
1131
1132int teac_Dispose( Tcomm* tcomm, RBuffer* buf )
1133{
1134 tcomm->totalRecvBufferBytesAllocated -= buf->totSize;
1135 elan3_free(tcomm->ctx, buf->buf);
1136 crFree(buf);
1137 return 0;
1138}
1139
1140char* teac_getTcommString(Tcomm *c, char* buf, int buflen)
1141{
1142 snprintf(buf,buflen-1,
1143 "<vp= %d, host range %d-%d, ctxnum range %d-%d, msg %d>",
1144 c->vp,c->lhost,c->hhost,c->lctx,c->hctx,c->msgnum);
1145 buf[buflen-1]= '\0';
1146 return buf;
1147}
1148
1149char* teac_getConnString(Tcomm *c, int id, char* buf, int buflen)
1150{
1151 int rel_rank= id%4;
1152 int node= ((id-rel_rank)/4) + c->lhost;
1153 snprintf(buf,buflen-1,"vp %d, <%s>:%d",id,
1154 hosts[hostsIndex[node]].name,rel_rank);
1155 buf[buflen-1]= '\0';
1156#if 0
1157 crDebug("getConnString: lookup id %d -> %d %d -> %s\n",id,rel_rank,node,buf);
1158#endif
1159 return buf;
1160}
1161
1162int teac_getConnId(Tcomm *c, const char* host, int rank)
1163{
1164 int node= trans_host(host);
1165#if 0
1166 crDebug("getConnId: <%s> %d %d maps to %d %d\n",
1167 host, rank, c->lhost, node, (4*(node - c->lhost) + (rank%4)));
1168#endif
1169 return (4*(node - c->lhost) + (rank%4));
1170}
1171
1172int teac_getHostInfo(Tcomm *c, char* host, const int hostLength,
1173 int* railMask, int *nodeId,
1174 long* sdramBaseAddr, long* elanBaseAddr)
1175{
1176#if (TEAC_DEVINFO_TYPE == 2)
1177 ELAN_DEVINFO info;
1178 ELAN_POSITION position;
1179#else
1180 ELAN3_DEVINFO info;
1181#endif
1182 char* here;
1183
1184 if (gethostname(host,hostLength-1)) {
1185 perror("Can't get my own host name");
1186 return 0;
1187 }
1188 host[hostLength-1]= '\0';
1189 if ((here= crStrchr(host,'.')) != NULL) *here= '\0';
1190
1191#if (TEAC_DEVINFO_TYPE == 2)
1192 (void)elan3_get_devinfo(c->ctx, &info);
1193 (void)elan3_get_position(c->ctx, &position);
1194 *nodeId= position.pos_nodeid;
1195#elif (TEAC_DEVINFO_TYPE == 1)
1196 elan3_devinfo(0, &info);
1197 *nodeId= info.Position.NodeId;
1198#else
1199 elan3_devinfo(0, &info);
1200 *nodeId= info.NodeId;
1201#endif
1202
1203#if (TEAC_CAP_TYPE == 2)
1204 *railMask= c->cap.cap_railmask;
1205#else
1206 *railMask= c->cap.RailMask;
1207#endif
1208
1209 *sdramBaseAddr= (int)c->r_event[0][0];
1210
1211 *elanBaseAddr= (long)teac_main2elan(c->ctx,(void*)c->m_rcv[0]);
1212 return 1;
1213}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette