changed reading hint
[gromacs/adressmacs.git] / src / gmxlib / idtio.c
blob0fac7d73c4b35b6307c3b669394f1b0414424257
1 /*
2 * $Id$
3 *
4 * This source code is part of
5 *
6 * G R O M A C S
7 *
8 * GROningen MAchine for Chemical Simulations
9 *
10 * VERSION 2.0
12 * Copyright (c) 1991-1999
13 * BIOSON Research Institute, Dept. of Biophysical Chemistry
14 * University of Groningen, The Netherlands
16 * Please refer to:
17 * GROMACS: A message-passing parallel molecular dynamics implementation
18 * H.J.C. Berendsen, D. van der Spoel and R. van Drunen
19 * Comp. Phys. Comm. 91, 43-56 (1995)
21 * Also check out our WWW page:
22 * http://md.chem.rug.nl/~gmx
23 * or e-mail to:
24 * gromacs@chem.rug.nl
26 * And Hey:
27 * Green Red Orange Magenta Azure Cyan Skyblue
29 static char *SRCID_idtio_c = "$Id$";
32 * This module implements synchronous and asynchronous communication via the
33 * dual ported ram in the SPC-860 system.
35 * Protocol description:
37 * Sender and receiver must complete their previous transfer on the specified
38 * channel first (busy flag must be cleared for the channel) before they can
39 * start a new transfer. A large block of data is split up into a number of
40 * blocks which fit into the i/o buffer. A transfer is finished after all
41 * blocks have been transferred and the receiver has acknowledged the reception
42 * of the last block.
44 * Step Sender Receiver
46 * 1 gmx_tx(),gmx_txs() gmx_rx(),gmx_rxs()
47 * . .
48 * 2 Copy memory to io buffer .
49 * signal buffer filled .
50 * . .
51 * 3 . Wait for buffer filled signal
52 * . .
53 * 4 Wait for buffer empty signal .
54 * . .
55 * 5 . Copy io buffer to memory
56 * . signal buffer empty
57 * . .
58 * 6 Buffer transfer done .
59 * . .
60 * 7 Repeat step 2 & 4 until Repeat step 3 & 5 until
61 * complete transfer done complete transfer done
62 * . .
63 * 8 return return
65 * As is clear from the previous, the sender and the receiver need not to
66 * enter the communication routines at the same time. The sender as well as
67 * the receiver may invoke its routine at every moment. The protocol
68 * guarantuees that no data is lost. The only restriction is that the sender
69 * and receiver have the same transfer length. A message with length 0 (zero)
70 * is also communicated. Although no data transfer is necessary, the protocol
71 * is handled in the same way as a normal message and thus causes the channel
72 * to be used for synchronisation. The synchronous and asynchronous routines
73 * are interchangable between sender and receiver, so a sender may use the
74 * asynchronous version while the receiver uses the synchronous version and
75 * vice versa. Naturally both may use the same type of communication
76 * primitives.
78 * Due to the fact that DMA is not available, all data copying is done by
79 * the processor. Because interrupts aren't used for efficiency reasons,
80 * real asynchronous communication is not possible, messages are copied
81 * from and to the io buffers while within the communication routines. So
82 * an asynchronous communication is implemented by doing the nonblocking
83 * part in the setup and the blocking part in the gmx_wait() routines.
84 * Notice that while another asynchronous transfer is busy on the specified
85 * channel, starting a new one implies waiting for the previous to finish.
87 * IDT layout:
89 * left idt right idt
91 * +----------+ +------+ +----------+
92 * | 3ff 1023 | irq (self) | I860 | irq (other) | 7ff 2047 |
93 * +----------+ | | +----------+
94 * | 3fe 1022 | irq (other) | | irq (self) | 7fe 2046 |
95 * -+----------+-------------- | | --------------+----------+-
96 * | 3fd 1021 | rx cmd | | tx cmd | 7fd 2045 |
97 * +----------+ | | +----------+
98 * | 3fc 1020 | tx cmd | | rx cmd | 7fc 2044 |
99 * -+----------+-------------- | | --------------+----------+-------
100 * | 3fb 1019 | | | | 7fb 2043 | ^
101 * +----------+ | | +----------+ |
102 * . . | | . . BSIZE
103 * +----------+ | | +----------+ |
104 * | 1fe 510 | rx buffer | | tx buffer | 5fe 1534 | v
105 * -+----------+-------------- | | --------------+----------+-------
106 * | 1fd 509 | | | | 5fd 1533 | ^
107 * +----------+ | | +----------+ |
108 * . . | | . . BSIZE
109 * +----------+ | | +----------+ |
110 * | 000 0 | tx buffer | | rx buffer | 400 1024 | v
111 * +----------+ +------+ +----------+-------
113 * Numbers are offsets relative to IDT base address, names like tx and rx are
114 * local for this i860. The actual buffer size may be smaller (aligned for
115 * word size, 4 bytes) for speed, see also module inout.s.
118 #include <stdlib.h>
119 #include <stdio.h>
120 #include <string.h>
121 #include <rdklib.h>
122 #include "fatal.h"
123 #include "delay.h"
124 #include "network.h"
125 #include "inout.h"
126 #include "idtio.h"
127 #include "buffer.h"
128 #include "synclib.h"
129 #include "main.h"
131 #define SERVER_VERSION "SERVER_VERSION"
132 #define USE_VERSION1 "S860.1"
134 #define IDTNR 2 /* Number of available idt's. */
135 #define IDTLEFT 0x0 /* Offset of my idt. */
136 #define IDTRIGHT 0x400 /* Offset of neighbour processors idt. */
137 #define IDTSIZE 0x400 /* Total size of idt. */
138 #define IRQBASE 0x3fe /* Interrupt locations at the top of an idt */
139 #define BSIZE 510 /* Usable buffer size, see comment above */
140 #define TX 0 /* Index of sender status. */
141 #define RX 1 /* Index of receiver status. */
142 #define TXRXNR 2 /* Number of directions (sender & receiver). */
143 #define BUF_DONE 0x55 /* Signals buffer transfer is done. */
144 #define BUF_BUSY ((~(BUF_DONE))&0xff) /* Signals buffer is busy. */
145 #define LINE_WIDTH 16 /* Hex dump bytes per line. */
146 #define MIN(a,b) (((a)>(b))?(b):(a))
147 #define WORK_NAME(work) \
148 (((work)==buf_idle)?"buf_idle": \
149 ((((work)==buf_accept)?"buf_accept": \
150 ((((work)==buf_send)?"buf_send": \
151 ((((work)==buf_avail)?"buf_avail":(NULL))))))))
153 typedef struct t_stat
155 char *name; /* Name of the channel (debugging). */
156 int cmd; /* Offset of command byte in io ram. */
157 int buf; /* Offset of buffer in io ram. */
158 int len; /* Actual number of bytes to transfer. */
159 int bsize; /* Actual usable buffer size */
160 int bcnt; /* Total block count, part of rx/tx. */
161 int tcnt; /* Total transfer count for tx/rx. */
162 int icnt; /* Total idle count, incremented while waiting. */
163 char *data; /* Pointer to data bytes in memory. */
164 void (*work)(struct t_stat* stat); /* State of transfer. */
165 } t_stat;
167 static int idt_id=0;
168 static int idt_busy=0;
169 static char *stat_names[IDTNR][TXRXNR]={{"txl","rxl"},{"txr","rxr"}};
170 static t_stat sys_stat[IDTNR][TXRXNR];
172 static void buf_idle(t_stat *stat);
173 static void buf_accept(t_stat *stat);
174 static void buf_send(t_stat *stat);
175 static void buf_avail(t_stat *stat);
178 * Debug routines start
180 #define COL_WIDTH 19
181 #define line(what) \
182 do \
184 int i,j,len; \
185 for (i=0; i<IDTNR; i++) \
186 for (j=0; j<TXRXNR; j++) \
188 len=what; \
189 (void) fprintf(fp,"%*s",COL_WIDTH-len,""); \
191 (void) fprintf(fp,"\n"); \
193 while (0)
195 static void print_connections(FILE *fp,t_stat stat[IDTNR][TXRXNR])
197 int i,j;
199 for (i=0; i<IDTNR; i++)
200 for (j=0; j<TXRXNR; j++)
201 (void) fprintf(fp,"cmd at %s (0x%x) should be connected to %s (0x%x)\n",
202 stat[i][j].name,stat[i][j].cmd,
203 stat[IDTNR-1-i][TXRXNR-1-j].name,
204 stat[IDTNR-1-i][TXRXNR-1-j].cmd);
205 for (i=0; i<IDTNR; i++)
206 for (j=0; j<TXRXNR; j++)
207 (void) fprintf(fp,"data at %s (0x%x,%d) should be connected to %s "
208 "(0x%x,%d)\n",
209 stat[i][j].name,stat[i][j].buf,stat[i][j].bsize,
210 stat[IDTNR-1-i][TXRXNR-1-j].name,
211 stat[IDTNR-1-i][TXRXNR-1-j].buf,
212 stat[IDTNR-1-i][TXRXNR-1-j].bsize);
215 static void print_chars(FILE *fp,char s[],int len)
217 int i;
219 if (len)
221 for (i=len; i<LINE_WIDTH; i++) (void) fprintf(fp," ");
222 s[len]='\0';
223 (void) fprintf(fp," | %s\n",s);
227 static int ascii(int b)
229 if ((b<' ')||(b>'~')) return ('.'); else return b;
232 static void idt_dump(FILE *fp,char *title,int offset,int len)
234 int i,b,index;
235 char s[LINE_WIDTH+1];
237 index=0;
238 s[0]='\0';
239 if (len) (void) fprintf(fp,"idtdump %s:\n",title);
240 for (i=0; i<len; i++)
242 b=peek_io_buf(IDT7130,offset);
243 if ((index==0)||(index==LINE_WIDTH))
245 print_chars(fp,s,index);
246 (void) fprintf(fp,"%.8X :",offset);
247 index=0;
249 (void) fprintf(fp," %.2X",b);
250 s[index++]=ascii(b);
251 offset++;
253 print_chars(fp,s,index);
256 static int fprintw(FILE *fp,char *title,void (*work)(struct t_stat* stat))
258 char *work_name;
260 if ((work_name=WORK_NAME(work))==NULL)
261 return fprintf(fp,"%s0x%x",title,work);
262 else
263 return fprintf(fp,"%s%s",title,work_name);
266 static void clear_cnt(t_stat stat[IDTNR][TXRXNR])
268 int i,j;
270 for (i=0; i<IDTNR; i++)
271 for (j=0; j<TXRXNR; j++)
273 stat[i][j].bcnt=0;
274 stat[i][j].tcnt=0;
275 stat[i][j].icnt=0;
280 static void print_status(FILE *fp,int pid,char *s,
281 t_stat stat[IDTNR][TXRXNR],t_stat *mark)
283 (void) fprintf(fp,"idt pid: %d, %s\n",pid,s);
284 line(fprintf(fp,"%s%s:",stat[i][j].name,(mark==&stat[i][j])?" (*)":""));
285 line(fprintf(fp,"cmd = 0x%x",stat[i][j].cmd));
286 line(fprintf(fp,"(cmd) = 0x%x",peek_io_buf(IDT7130,stat[i][j].cmd)));
287 line(fprintf(fp,"buf = 0x%x",stat[i][j].buf));
288 line(fprintf(fp,"len = %d",stat[i][j].len));
289 line(fprintf(fp,"bsize = %d",stat[i][j].bsize));
290 line(fprintf(fp,"bcnt = %d",stat[i][j].bcnt));
291 line(fprintf(fp,"tcnt = %d",stat[i][j].tcnt));
292 line(fprintf(fp,"icnt = %d",stat[i][j].icnt));
293 line(fprintf(fp,"data = 0x%x",stat[i][j].data));
294 line(fprintw(fp,"work = ",stat[i][j].work));
295 fflush(fp);
296 clear_cnt(stat);
299 static void init_buf(t_stat *stat,int data)
301 int i;
303 for (i=0; i<stat->bsize; i++) poke_io_buf(IDT7130,stat->buf+i,data);
306 static void init_bufs(t_stat stat[IDTNR][TXRXNR],int data)
308 int i,j;
310 for (i=0; i<IDTNR; i++)
311 for (j=0; j<TXRXNR; j++)
312 init_buf(&stat[i][j],data);
315 static int check_buf(FILE *fp,t_stat *stat,int data)
317 int i,peeked,err;
319 err=0;
320 for (i=0; i<stat->bsize; i++)
321 if ((peeked=peek_io_buf(IDT7130,stat->buf+i))!=data)
323 err++;
324 (void) fprintf(fp,"data at 0x%x in %s is 0x%x, should be 0x%x\n",
325 stat->buf+i,stat->name,peeked,data);
327 return err;
330 static void init_cmd(t_stat stat[IDTNR][TXRXNR],int cmd)
332 int i,j;
334 for (i=0; i<IDTNR; i++)
335 for (j=0; j<TXRXNR; j++)
336 poke_io_buf(IDT7130,stat[i][j].cmd,cmd);
339 static void test_connectivity(FILE *fp,t_stat stat[IDTNR][TXRXNR])
341 int i,j,init,err;
343 err=0;
344 print_connections(fp,stat);
345 (void) fprintf(fp,"short circuit test:\ntesting initialisation ...");
346 fflush(fp);
347 init_cmd(stat,BUF_DONE);
348 for (i=0; i<IDTNR; i++)
349 for (j=0; j<TXRXNR; j++)
350 if ((init=peek_io_buf(IDT7130,stat[i][j].cmd))!=BUF_DONE)
352 if (err++==0) (void) printf("\n");
353 (void) fprintf(fp,"cmd at %s (0x%x) is 0x%x, should be 0x%x\n",
354 stat[i][j].name,stat[i][j].cmd,init,BUF_DONE);
356 (void) fprintf(fp," done\ntesting cmd connectivity ...");
357 fflush(fp);
358 for (i=0; i<IDTNR; i++)
359 for (j=0; j<TXRXNR; j++)
361 init_cmd(stat,BUF_DONE); /* All others should have wrong value */
362 poke_io_buf(IDT7130,stat[i][j].cmd,BUF_BUSY);
363 if ((init=peek_io_buf(IDT7130,stat[IDTNR-1-i][TXRXNR-1-j].cmd))!=
364 BUF_BUSY)
366 if (err++==0) (void) printf("\n");
367 (void) fprintf(fp,"cmd at %s (0x%x) should be connected to"
368 " %s (0x%x)\n",
369 stat[i][j].name,stat[i][j].cmd,
370 stat[IDTNR-1-i][TXRXNR-1-j].name,
371 stat[IDTNR-1-i][TXRXNR-1-j].cmd);
372 (void) fprintf(fp,"cmd at %s (0x%x) is 0x%x, should be 0x%x\n",
373 stat[IDTNR-1-i][TXRXNR-1-j].name,
374 stat[IDTNR-1-i][TXRXNR-1-j].cmd,
375 init,BUF_BUSY);
378 (void) fprintf(fp," done\ntesting data connectivity ...");
379 fflush(fp);
380 for (i=0; i<IDTNR; i++)
381 for (j=0; j<TXRXNR; j++)
383 init_bufs(stat,0); /* All others should have wrong value */
384 init_buf(&stat[i][j],0xff);
385 err+=check_buf(fp,&stat[IDTNR-1-i][TXRXNR-1-j],0xff);
386 init_bufs(stat,0xff); /* All others should have wrong value */
387 init_buf(&stat[i][j],0);
388 err+=check_buf(fp,&stat[IDTNR-1-i][TXRXNR-1-j],0);
390 (void) fprintf(fp," done\n%d error(s) detected\n",err);
391 fflush(fp);
394 #define BUFSIZE 25000
396 static int com_test(FILE *fp,char *title,int src,int dest)
398 int buf[2][BUFSIZE];
400 (void) fprintf(fp,"%s, src=%d, dest=%d\n",title,src,dest);
401 clear_buff(buf[0],BUFSIZE);
402 fill_buff(buf[1],BUFSIZE);
403 gmx_tx(dest,array(buf[1],BUFSIZE));
404 gmx_rx(src,array(buf[0],BUFSIZE));
405 gmx_tx_wait(dest);
406 gmx_rx_wait(src);
407 return check_buff(fp,"com_test",buf[0],BUFSIZE,1);
410 #ifdef USE_MAIN
411 #define i860main_test i860main
412 #endif
414 int i860main_test(int argc,char *argv[],FILE *stdlog,
415 int nprocs,int pid,int left,int right)
417 int err;
419 (void) fprintf(stdlog,"in i860main nprocs=%d, pid=%d, left=%d, right=%d, "
420 "bufsize=%d\n",nprocs,pid,left,right,BUFSIZE*sizeof(int));
421 if (nprocs==1) test_connectivity(stdlog,sys_stat);
422 err=com_test(stdlog,"left to right",left,right);
423 err+=com_test(stdlog,"right to left",right,left);
424 (void) fprintf(stdlog,"%d error(s)\n",err);
425 fflush(stdlog);
426 return 0;
430 * Debug routines end
433 #ifdef DEBUG
435 static void print_stat(FILE *fp,char *title,t_stat *stat)
437 (void) fprintf(fp,"%-35s (%s): cmd=%d, len=%6d, data=0x%x\n",
438 title,stat->name,peek_io_buf(IDT7130,stat->cmd),
439 stat->len,stat->data);
440 fflush(fp);
443 #define ENTER(where,stat) print_stat(stdlog,"enter "#where,stat)
444 #define LEAVE(where,stat) print_stat(stdlog,"leave "#where,stat)
445 #else
446 #define ENTER(where,stat)
447 #define LEAVE(where,stat)
448 #endif
450 static void set_comm_led(int busy)
452 if (busy)
454 if ((idt_busy++)==0) put_led(COMM_LED,1);
456 else
458 if ((--idt_busy)==0) put_led(COMM_LED,0);
462 static int compare_tags(int tag1,int tag2)
464 int i,count;
466 count=0;
467 for (i=-1; i!=0; i<<=1)
469 if ((tag1&1)==(tag2&1)) count++;
470 tag1>>=1;
471 tag2>>=1;
473 return count;
476 void idtio_errstat(FILE *fp,char *msg,t_stat *stat,int dump)
478 print_status(fp,idt_id,msg,sys_stat,stat);
479 if (dump)
481 idt_dump(fp,"idtio_stat left",IDTLEFT,IRQBASE);
482 idt_dump(fp,"idtio_stat right",IDTRIGHT,IRQBASE);
484 fflush(fp);
487 static int repair(FILE *fp,char *where,t_stat *stat,int tag)
489 int out_tag,busy_tag,done_tag;
491 busy_tag=compare_tags(tag,BUF_BUSY);
492 done_tag=compare_tags(tag,BUF_DONE);
493 if (busy_tag>done_tag)
494 out_tag=BUF_BUSY;
495 else
496 if (done_tag>busy_tag)
497 out_tag=BUF_DONE;
498 else
500 out_tag=0;
501 (void) fprintf(fp,"could not repair tag 0x%.2x in %s (%s)\n",tag,where,
502 stat->name);
503 idtio_errstat(fp,where,stat,1);
504 fatal_error(0,"received 0x%x as a tag on processor %d",tag,idt_id);
506 (void) fprintf(fp,"repaired 0x%.2x in %s(%s) -> 0x%.2x\n",
507 tag,where,stat->name,out_tag);
508 return out_tag;
511 static void buf_done(t_stat *stat)
513 ENTER(buf_done,stat);
514 set_comm_led(0);
515 stat->data=NULL;
516 stat->work=buf_idle;
517 LEAVE(buf_done,stat);
520 static void buf_idle(t_stat *stat)
522 ENTER(buf_idle,stat);
523 LEAVE(buf_idle,stat);
526 static void buf_accept(t_stat *stat)
528 int tag,repaired;
529 static void buf_send(t_stat *stat);
531 ENTER(buf_accept,stat);
532 tag=peek_io_buf(IDT7130,stat->cmd);
535 repaired=0;
536 switch(tag)
538 case BUF_BUSY:
539 stat->icnt++;
540 break;
541 case BUF_DONE:
542 if (stat->len!=0) buf_send(stat); else buf_done(stat);
543 break;
544 default:
545 tag=repair(stdlog,"buf_accept",stat,tag);
546 repaired=1;
547 break;
550 while (repaired);
551 LEAVE(buf_accept,stat);
554 static void buf_send(t_stat *stat)
556 int len;
558 ENTER(buf_send,stat);
559 len=MIN(stat->bsize,stat->len);
560 put_io_buf(IDT7130,stat->buf,stat->data,len);
561 poke_io_buf(IDT7130,stat->cmd,BUF_BUSY);
562 stat->bcnt++;
563 stat->len-=len;
564 stat->data+=len;
565 stat->work=buf_accept;
566 LEAVE(buf_send,stat);
569 static void buf_avail(t_stat *stat)
571 int tag,len,repaired;
573 ENTER(buf_avail,stat);
574 tag=peek_io_buf(IDT7130,stat->cmd);
577 repaired=0;
578 switch (tag)
580 case BUF_DONE:
581 stat->icnt++;
582 break;
583 case BUF_BUSY:
584 len=MIN(stat->bsize,stat->len);
585 get_io_buf(IDT7130,stat->buf,stat->data,len);
586 poke_io_buf(IDT7130,stat->cmd,BUF_DONE);
587 stat->bcnt++;
588 stat->len-=len;
589 stat->data+=len;
590 if (stat->len==0) buf_done(stat);
591 break;
592 default:
593 tag=repair(stdlog,"buf_avail",stat,tag);
594 repaired=1;
595 break;
598 while (repaired);
599 LEAVE(buf_avail,stat);
602 static void communicate(t_stat stat[IDTNR][TXRXNR])
604 int i,j;
606 for (i=0; i<IDTNR; i++)
607 for (j=0; j<TXRXNR; j++)
608 stat[i][j].work(&stat[i][j]);
611 static void chan_wait(t_stat stat[IDTNR][TXRXNR],int chan,int txrx)
613 while (stat[chan][txrx].work!=buf_idle) communicate(stat);
616 static void fill_stat(t_stat *stat,void *bufptr,int bufsize,
617 void (*work)(t_stat *stat))
619 ENTER(fill_stat,stat);
620 stat->tcnt++;
621 stat->len=bufsize;
622 stat->data=bufptr;
623 stat->work=work;
624 set_comm_led(1);
625 LEAVE(fill_stat,stat);
628 void idtio_tx(int chan,void *bufptr,int bufsize)
630 ENTER(idtio_tx,&sys_stat[chan][TX]);
631 chan_wait(sys_stat,chan,TX); /* Be sure that this channel is free for use */
632 fill_stat(&sys_stat[chan][TX],bufptr,bufsize,buf_send);
633 LEAVE(idtio_tx,&sys_stat[chan][TX]);
636 void idtio_rx(int chan,void *bufptr,int bufsize)
638 ENTER(idtio_rx,&sys_stat[chan][RX]);
639 chan_wait(sys_stat,chan,RX);
640 fill_stat(&sys_stat[chan][RX],bufptr,bufsize,buf_avail);
641 LEAVE(idtio_rx,&sys_stat[chan][RX]);
644 void idtio_tx_wait(int chan)
646 ENTER(idtio_tx_wait,&sys_stat[chan][TX]);
647 chan_wait(sys_stat,chan,TX);
648 LEAVE(idtio_tx_wait,&sys_stat[chan][TX]);
651 void idtio_rx_wait(int chan)
653 ENTER(idtio_rx_wait,&sys_stat[chan][RX]);
654 chan_wait(sys_stat,chan,RX);
655 LEAVE(idtio_rx_wait,&sys_stat[chan][RX]);
658 void idtio_txs(int chan,void *bufptr,int bufsize)
660 ENTER(idtio_txs,&sys_stat[chan][RX]);
661 idtio_tx(chan,bufptr,bufsize);
662 idtio_tx_wait(chan);
663 LEAVE(idtio_txs,&sys_stat[chan][RX]);
666 void idtio_rxs(int chan,void *bufptr,int bufsize)
668 ENTER(idtio_rxs,&sys_stat[chan][RX]);
669 idtio_rx(chan,bufptr,bufsize);
670 idtio_rx_wait(chan);
671 LEAVE(idtio_rxs,&sys_stat[chan][RX]);
674 static void init_stat(t_stat *stat,char *name,int bsize,int buf,int cmd)
676 stat->name=name;
677 stat->cmd=cmd;
678 stat->buf=buf;
679 stat->len=0;
680 stat->bsize=bsize;
681 stat->bcnt=0;
682 stat->tcnt=0;
683 stat->icnt=0;
684 stat->data=NULL;
685 stat->work=buf_idle;
686 LEAVE(init_stat,stat);
689 static void ring_wait(int pid,int nprocs)
691 * Wait for every processor to execute this function, assume that pid
692 * runs from 0 to nprocs - 1.
695 int i,newserver;
696 char *sv,ch;
698 if ((sv=getenv(SERVER_VERSION))==NULL)
699 newserver=0;
700 else
701 newserver=(strcmp(sv,USE_VERSION1)==0);
702 if (newserver)
703 syncall();
704 else
706 ch=0;
707 if (pid==0)
709 for (i=1; i<nprocs; i++) rdlinda1in(i,-1,&ch);
710 for (i=1; i<nprocs; i++) rdlinda1out(i+nprocs,1,&ch);
712 else
714 rdlinda1out(pid,1,&ch);
715 rdlinda1in(pid+nprocs,-1,&ch);
720 void idtio_init(int pid,int nprocs)
722 int i;
724 idt_id=pid;
725 init_stat(&sys_stat[LEFT] [TX],stat_names[LEFT][TX],
726 BSIZE&~0x3,IDTLEFT, IDTLEFT+2*BSIZE);
727 init_stat(&sys_stat[LEFT] [RX],stat_names[LEFT][RX],
728 BSIZE&~0x3,IDTLEFT+BSIZE, IDTLEFT+2*BSIZE+1);
729 init_stat(&sys_stat[RIGHT][TX],stat_names[RIGHT][TX],
730 BSIZE&~0x3,IDTRIGHT+BSIZE,IDTRIGHT+2*BSIZE+1);
731 init_stat(&sys_stat[RIGHT][RX],stat_names[RIGHT][RX],
732 BSIZE&~0x3,IDTRIGHT ,IDTRIGHT+2*BSIZE);
733 for (i=0; i<IRQBASE; i++) poke_io_buf(IDT7130,IDTLEFT+i,0xff);
735 #ifdef DEBUG
736 print_status(stdlog,pid,"idtio_init (1)",sys_stat,NULL);
737 ring_wait(pid,nprocs);
738 print_status(stdlog,pid,"idtio_init (2)",sys_stat,NULL);
739 #endif
740 ring_wait(pid,nprocs);
742 for (i=0; i<IDTNR; i++) poke_io_buf(IDT7130,sys_stat[i][TX].cmd,BUF_DONE);
743 ring_wait(pid,nprocs);
744 for (i=0; i<IDTNR; i++)
746 if (peek_io_buf(IDT7130,sys_stat[i][RX].cmd)!=BUF_DONE)
748 idtio_errstat(stdlog,"idtio_init",&sys_stat[i][RX],1);
749 fatal_error(0,"idt %s not initialised on processor %d",
750 sys_stat[i][RX].name,idt_id);
753 #ifdef DEBUG
754 print_status(stdlog,pid,"idtio_init(3)",sys_stat,NULL);
755 #endif
756 ring_wait(pid,nprocs);
759 void idtio_stat(FILE *fp,char *msg)
761 fprintf(fp,"idtio_stat message: %s\n",msg);
762 fprintf(fp,"Idle Left Send: %d\n",sys_stat[LEFT][TX].icnt);
763 fprintf(fp,"Idle Left Receive: %d\n",sys_stat[LEFT][TX].icnt);
764 fprintf(fp,"Idle Right Send: %d\n",sys_stat[RIGHT][RX].icnt);
765 fprintf(fp,"Idle Right Receive: %d\n",sys_stat[RIGHT][RX].icnt);
766 #ifdef DEBUG
767 idtio_errstat(fp,msg,NULL,0);
768 #endif
771 void idt_left_right(int nprocs,int pid,int *left,int *right)
773 *left=LEFT;
774 *right=RIGHT;
777 void idt_reset_idle()
779 sys_stat[LEFT][TX].icnt=0;
780 sys_stat[LEFT][TX].icnt=0;
781 sys_stat[RIGHT][RX].icnt=0;
782 sys_stat[RIGHT][RX].icnt=0;