#define I_AM_HOST #include "hostspec.h" #include "sys_pub.h" #include "sys_priv.h" #include "sys_gen.h" /* Still to be done: Fix abort code on vme side. */ /* Get a better user interface for message composing */ /* Test flag stuff */ /* Fix big_mess stuff */ /* ********************************************************************* */ int sys_set(int dest, int signal) /* sets a bit in signal word */ { extern dpr *io_base[]; int x = 1; if ((signal < 0) || (signal > NUM_FLAGS)) return(ENOSIG); io_base[dest]->signals |= (x << signal); return ( SUCCESS ); } /***********************************************************************/ int sys_clear(int dest, int signal) { extern dpr *io_base[]; int x = 1; if((signal < 0) || (signal > NUM_FLAGS)) return(ENOSIG); io_base[dest]->signals &= ~(x << signal); return(SUCCESS); } /***********************************************************************/ int sys_wait(int dest, int signal) { while(!(look(dest, signal))) { if(look(dest, ABORT)) return(EABORT); } return(SUCCESS); } /***********************************************************************/ int sys_nwait(int dest, int signal) { while(look(dest, signal)) { if(look(dest, ABORT)) return(EABORT); } return(SUCCESS); } /***********************************************************************/ /***********************************************************************/ int look(int dest, int sig) { int32 a[LOOKUPS]; int n; extern dpr *io_base[]; for(n = 0;n < LOOKUPS; n++) { a[n] = (io_base[dest]->signals) & (1 << sig); if(n != 0) { if(a[n] != a[n-1]) return ECONFLICT; } } if(a[0]) return(1); return(0); } /***********************************************************************/ /***********************************************************************/ int get_sigs( int dest ) { extern dpr *io_base[]; return io_base[dest]->signals; } /**********************************************************************/ int send_mess( int32 *pmess ) { int remain; int32 *from, *to; int dest, time; static int mess_id = 0; static int num_sent = 0; static int num_err = 0; static int iam = 0; extern dpr *io_base[]; m_generic *message; message = (m_generic *) pmess; dest = MDEST(message); remain = MSIZE(message); if ( 0 ) /* FIXME - do some sanity checking here*/ return EMESSINVAL; if(look(dest, EXPORT)) return ECONFLICT; sys_set(dest, IMPORT); if(look(dest, EXPORT)) return ECONFLICT; mess_id++; time = 0; DO_T_HEAD( dest ); from = (int32 *) message; to = io_base[dest]->packet.message; while( remain > MTU ) { copy(from, to, MTU); sys_set(dest, DAV); remain -= MTU; from += MTU; if ( sys_wait(dest, ACK) == EABORT ) return EABORT; sys_clear(dest, DAV); if ( sys_nwait(dest, ACK) == EABORT ) return EABORT; } copy (from, to, remain); to += remain; zero (to, (MTU - remain)); sys_set (dest, EOM); sys_set (dest, DAV); sys_wait (dest, ACK); sys_clear (dest, EOM); sys_clear (dest, IMPORT); sys_clear (dest, DAV); sys_nwait (dest, ACK); return (SUCCESS); } int get_mess( int dest ) { int32 *to, *from; int32 remain; int32 timestamp, mess_id; //int32 maxtsize = 0x2000; /* FIXME was 10000 t.d. */ int32 maxtsize = 0x10000; extern int32 *message_base; extern dpr *io_base[]; // printf (" get_mess %lx %lx\n", message_base, io_base[0]); from = io_base[dest]->packet.message; to = message_base; if(!look( dest, EXPORT )) return ENOMESS; if(sys_wait( dest, DAV ) == EABORT) return EABORT; if((remain = TSIZE( dest )) > maxtsize) return ETOOBIG; timestamp = TTIME ( dest ); mess_id = TMESSID ( dest ); while(remain > MTU) { copy( from, to, MTU ); sys_set( dest, ACK ); to += MTU; remain -= MTU; if(sys_nwait( dest, DAV ) == EABORT) return EABORT; sys_clear( dest, ACK ); if(sys_wait( dest, DAV ) == EABORT) return EABORT; } copy( from, to, remain ); sys_set( dest, ACK ); if(sys_nwait( dest, DAV ) == EABORT) return EABORT; sys_clear( dest, ACK ); return SUCCESS; } void copy( int32 *from, int32 *to, int32 n ) { int32 c; if((!from) || (!to)) return; if(n == 0) return; for( c = n; c != 0; c--) *to++ = *from++; } void zero( int32 *to, int32 n) { int32 c; if((!to) || !(n > 0)) return; for( c = n; c != 0; c--) *to++ = 0; } int get_flag( int dest, int flag ) { int val; extern dpr *io_base[]; if((dest > (NUM_CHAN - 1)) || (flag > (NUM_FLAGS - 1))) return ENOSIG; val = FLAG (dest, flag); printf (" flag %d %d\n", flag, val); return val; } int set_flag( int dest, int flag, int val ) { extern dpr *io_base[]; if((dest > (NUM_CHAN - 1)) || (flag > (NUM_FLAGS - 1))) return ENOSIG; FLAG(dest, flag) = val; } /***********************************************************************/ int message_status(void) { int stat = 0; int n; for(n = NUM_CHAN - 1; n >= 0; n--) { if( __check_mess(n) == 0) { stat <<= 1; continue; } stat <<= 1; stat += 1; } return stat; } int __check_mess(int dest) { extern dpr *io_base[]; if(io_base[dest]->signals & (1 << EXPORT)) return 1; return 0; } int check_mess(int dest) { int val; val = __check_mess(dest); return val; } int m_wait(int dest) { int n; while(!(n = look(0, EXPORT))) { if(n == ECONFLICT) return ECONFLICT; } return SUCCESS; } int32 * dsp_base( int dsp ) { extern dpr *io_base[]; return (int32 *) io_base[dsp]; } void dsp_led( int dsp_no, int on ) /* turns red LED on DSP's VME card on or off */ { int i; i = get_port( dsp_no ); /* get theoretical current value in port */ i &= ~0x80; /* clear bit 7 = turn LED on */ if ( ! on ) i |= 0x80; /* set bit 7 = turn LED off */ set_port( dsp_no, i ); /* write new value to port */ } void interrupt_dsp( int dsp_no ) /* interrupts DSP */ { int i; i = get_port( dsp_no ); /* get theoretical current value in port */ i |= 0x2; /* set bit 1 */ set_port( dsp_no, i ); i &= ~0x2; /* clear bit 1 */ set_port( dsp_no, i ); i |= 0x2; /* set bit 1 */ set_port( dsp_no, i ); } int port_image[ NUM_CHAN ]; /* image of VME cards' host ports */ int get_port( int dsp_no ) /* returns image of port */ { return( port_image[ dsp_no ] ); /* return image of port */ } void set_port( int dsp_no, int value ) /* writes value to port */ { * ( dsp_base( dsp_no ) + PORT_OFFSET ) = value; /* write to hardware */ port_image[ dsp_no ] = value; /* write to image */ }