#include <sys/types.h> #include <sys/mman.h> #include <stdio.h> #include <fcntl.h> #include <getopt.h> #include <errno.h> #include <limits.h> #include <signal.h> int state = 0; #define S_DIR 0x01 #define S_ADAP 0x02 #define S_SPACE 0x04 #define S_ADDR 0x08 #define S_SIZE 0x10 #define S_VAL 0x20 #define D_READ 0x1 #define D_WRITE 0x2 #define READSTATE (S_DIR|S_ADAP|S_SPACE|S_ADDR|S_SIZE) #define WRITESTATE (READSTATE|S_VAL) char *progname; char *spaces[] = { "a16n", "a16s", "a24n", "a24s", "a32n", "a32s" }; #define MAXSPACE (sizeof(spaces)/sizeof(spaces[0])) void usage(void); long ntol(char *); long chkspc(char *); char devnm[PATH_MAX]; static void probe_fail(int); int main(int ac, char *av[]) { int c, errflg = 0; int dir_f; long adap_f; long addr_f; long size_f; long val_f; char *space_f; int fd; char *mapaddr; int pgaddr, pgoff; int pgsz; int rtval; progname = av[0]; while( (c = getopt(ac,av,"rws:a:b:p:v:")) != -1 ) switch( c ) { case 'r': if( state & S_DIR ) { usage(); return 1; } dir_f = D_READ; state |= S_DIR; break; case 'w': if( state & S_DIR ) { usage(); return 1; } dir_f = D_WRITE; state |= S_DIR; break; case 's': if( state & S_SPACE ) { usage(); return 1; } if( chkspc(optarg) ) { usage(); return 1; } state |= S_SPACE; space_f = optarg; break; case 'a': if( ((adap_f = ntol(optarg)) < 0) || (state & S_ADAP) ) { usage(); return 1; } state |= S_ADAP; break; case 'b': if( ((addr_f = ntol(optarg)) < 0) || (state & S_ADDR) ) { usage(); return 1; } state |= S_ADDR; break; case 'p': if( ((size_f = ntol(optarg)) < 0) || (state & S_SIZE) ) { usage(); return 1; } state |= S_SIZE; break; case 'v': if( ((val_f = ntol(optarg)) < 0) || (state & S_VAL) ) { usage(); return 1; } state |= S_VAL; break; case '?': errflg++; break; } if( errflg || !(state & S_DIR) ) { usage(); return 1; } if( (dir_f == D_READ) && (state != READSTATE) ) { usage(); return 1; } if( (dir_f == D_WRITE) && (state != WRITESTATE) ) { usage(); return 1; } /* check the size */ switch( size_f ) { case 1: case 2: case 4: break; default: (void)fprintf(stderr,"invalid size %d\n",size_f); usage(); return 1; } /* create name of device */ sprintf(devnm,"/dev/vme/vme%d%s",adap_f,space_f); /* open the usrvme device */ if( (fd = open(devnm,O_RDWR)) < 0 ) { perror("open"); return 1; } /* we map in memory on page boundaries so figure out * the page and page offset */ pgsz = getpagesize(); pgaddr = (addr_f / pgsz) * pgsz; pgoff = addr_f % pgsz; /* map in the vme space surrounding the address */ if( (mapaddr = mmap( NULL,pgsz,PROT_READ|PROT_WRITE,MAP_PRIVATE, fd,pgaddr)) == (void*)-1 ) { perror("mmap"); return 1; } /* catch bus errors */ signal(SIGBUS,probe_fail); /* do the probe */ if( dir_f & D_READ ) { switch( size_f ) { case 1: rtval = *(char *)&mapaddr[pgoff]; break; case 2: rtval = *(short *)&mapaddr[pgoff]; break; case 4: rtval = *(int *)&mapaddr[pgoff]; break; } printf("read probe of 0x%x\n",rtval); } else { switch( size_f ) { case 1: *(char *)&mapaddr[pgoff] = val_f; break; case 2: *(short *)&mapaddr[pgoff] = val_f; break; case 4: *(int *)&mapaddr[pgoff] = val_f; break; } printf("write probe of 0x%x\n",val_f); /* wait here to catch any bus errors... */ sginap(CLK_TCK/50+1); } return 0; } long ntol(str) char *str; { char *strp; ulong ret; if( *str == '"' ) { str++; return (*str)?*str:-1; } ret = strtoul(str,&strp,0); if( ((ret == 0) && (strp == str)) || ((errno == ERANGE) && (ret = -1)) ) return (long)-1; return (long)ret; } long chkspc(char *nm) { int i; for( i = 0 ; i < MAXSPACE ; i++ ) if( strcmp(nm,spaces[i]) == 0 ) return 0; return 1; } void usage() { (void)fprintf(stderr, "usage: %s -r -a adap -s space -b busaddr -p probesize\n", progname); (void)fprintf(stderr, "usage: %s -w -a adap -s space -b busaddr -p probesize -v val\n", progname); (void)fprintf(stderr, " space is one of a16n, a16s, a24n, a24s, a32n, a32s\n"); (void)fprintf(stderr, " probesize is one of 1 2 or 4\n"); } static void probe_fail(int signo) { fprintf(stderr,"*** probe failed\n"); exit(1); }