/* IOBhack.c * Test read Mark-5 I/O card using /dev/mem, change specific parts. * The address information (OFFS and OFFP) is from /sbin/lspci. This * might change if, for example, the I/O card is put into a different * slot. IOBhack needs root priviledges. * Revised: 2004 October 01, JAB */ #include #include /* For strrchr() and strlen() */ #include /* For open() */ #include /* For open() */ #include /* For read() */ #include /* For open() */ #include /* For mmap() */ #include /* For atoi(), atof(), and strtoul() */ #define TRUE 1 #define FALSE 0 #define MEM "/dev/mem" /* System memory */ #define MEMI "/dev/port" /* I/O Ports */ #define OFFS 0xfe102000 /* Offset to Region 2 of PCI board */ #define OFFP 0xec00 /* Offset to Region 1 in PCI board 00:06.0 */ /* (These two defaults will (probably) be incorrect * if the I/O board changes slots) */ #define NUMB 128 /* Number of bytes to process (128 bytes = 64 shorts) */ #define NUMI 128 /* All available bytes in Region 1, I/O ports */ #define DEVICES "/proc/bus/pci/devices" /* For info about I/O board */ #define TAG 0x10b53001 /* PLX + Dan's 3001 */ char * me; /* My name */ int msglev = 0; /* Debug message level */ int main (int argc, char * argv[]) { /* IOBhack */ //unsigned char buff[OFFP+NUMI]; /* To hold all I/O ports */ /* ?? Should be [offp+NUMI]. Fix this ?? */ int memp; //int memi; FILE * devi; int f, i, j, mode, q, r, v, cha, chb; //int k; int found = FALSE; unsigned long offs = OFFS; /* Offset to Region 2 of PCI board */ unsigned long offp = OFFP; /* Offset to Region 1 of PCI board */ unsigned long tag; /* Check: PLX + Dan's 3001 */ //unsigned long cs0, cs1; unsigned short * buf1; /* For memory Region 2 as shorts */ unsigned short * buf2; /* For memory Region 2 offset as shorts */ //unsigned long * ibuf; /* Corrected I/O ports */ double freq; /* MHz */ unsigned long dphase = 0; /* Delta phase, cf. AD9850 writeup, p. 8 */ unsigned char * dp = (char *) &dphase; char line[512]; /* * Initialize * */ me = (me = strrchr(argv[0], '/')) == NULL ? argv[0] : me+1; /* My name */ if (argc > 1) /* Debug level on command line? */ msglev = atoi(argv[1]); /* Yes */ /* * Open file DEVICES (to get offs and offp) * */ if ((devi = fopen(DEVICES, "r")) == NULL) { /* OK? */ (void) fprintf(stderr, /* Nope */ "%s ERROR: \007 Can't fopen() file ", me); perror(DEVICES); return(-1); /* Error */ } /* * Find board TAG (PLX with Dan's 3001) in token 2 * */ while (! found) { /* Loop until found (or end of file) */ if (fgets(line, sizeof(line), devi) == NULL || strlen(line) < 80) { /* Read a line, OK? */ (void) fprintf(stderr, /* Nope */ "%s ERROR: fgets() end of file ", me); perror(DEVICES); break; /* Not found, out of while loop until found */ } /* Decode the needed parts of the line */ (void) sscanf(line, "%x %lx %x %x %lx %lx", &i, &tag, &i, &i, &offp, &offs); if (tag != TAG) /* This one? */ continue; /* Nope. To next while */ /* Else yes, this one */ offp--; /* Why?! */ found = TRUE; } /* End of while loop until found */ (void) fclose(devi); /* We're done with it */ if (! found) /* Did we find the I/O board? */ return(-2); /* Nope, error */ if (msglev < 1) /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s DEBUG: offs %#lx, offp %#lx \n", me, offs, offp); ///* * Open file MEMI, I/O ports * */ //if ((memi = open(MEMI, O_RDWR)) < 0) { /* OK? */ // (void) fprintf(stderr, "%s ERROR: \007 Can't open() file ", me); /* Nope */ // perror(MEMI); // return(-3); /* Error */ } ///* * Read the I/O ports into buff * */ //if ((k = read(memi, buff, sizeof(buff))) != sizeof(buff)) { /* OK? */ // (void) fprintf(stderr, /* Nope */ // "%s ERROR: \007 read() returned %d not %d on file ", // me, k, sizeof(buff)); // perror(MEMI); // return(-4); /* Error */ } //ibuf = (long *) (buff + offp); /* Offset to I/O board */ //(void) close(memi); /* We're done with it */ /* * Open file MEM, system memory * */ if ((memp = open(MEM, O_RDWR)) < 0) { /* OK? */ (void) fprintf(stderr, "%s ERROR: \007 Can't open() file ", me); /* Nope */ perror(MEM); return(-5); /* Error */ } /* * Map board Region 2 to memory * */ if ((buf1 = mmap(0, NUMB, PROT_READ | PROT_WRITE, MAP_SHARED, memp, offs)) == MAP_FAILED) { /* OK? */ (void) fprintf(stderr, /* Nope */ "%s ERROR: \007 Can't mmap() offset %#lx, file ", me, offs); perror(MEM); return(-6); /* Error */ } /* Now buf1[] is Dan's, and ... */ buf2 = buf1 + 32; /* Offset to Will's */ ///* * Chip selects * */ //cs0 = ibuf[0xf]; /* Now use the whole word (0xf = 0x3c/4) */ //(void) printf(" CS0 is 0x%8.8lx \n", cs0); //cs1 = ibuf[0x10]; /* Now use the whole word (0x10 = 0x40/4) */ //(void) printf(" CS1 is 0x%8.8lx \n", cs1); /* * Reset? * */ r = (buf1[0] & 0x200) >> 9; /* Extract R */ (void) printf(" R is %d, change to ", r); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ r = atoi(line); /* Yes */ buf1[0] = 0; buf1[0] = r << 9; /* Pulse R (no check) */ buf1[0] = 0; } /* * Mode * */ mode = buf1[1] & 0xff; /* Extract Mode */ (void) printf(" MODE is %#x, change to ", mode); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ mode = strtol(line, NULL, 0); buf1[1] &= 0xf00; /* Preserve v */ buf1[1] |= mode; /* Set mode (no check) */ } mode = buf2[1] & 0x0f; /* Extract Code */ /* * SF * */ (void) printf(" SF is %d%s \n", (buf2[1] & 0x80) >> 7, buf2[1] & 0x80 ? " (I'm clearing it for next time)" : ""); buf2[1] = buf2[1] & 0xff7f; /* Clear it */ /* * CODE * */ (void) printf(" CODE is %#x, change to ", mode); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ mode = strtol(line, NULL, 0); buf2[1] &= 0xfff0; /* Preserve I and V */ buf2[1] |= mode; /* Set code (no check) */ // buf2[2] = 2; /* Pulse C */ // buf2[2] = 1; /* And set Q */ } /* * Diddle Q? * */ //q = buf2[2] & 1; /* Extract Q */ q = buf2[2]; /* CQ */ (void) printf(" CQ is %d, change to ", q); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ q = atoi(line); /* Yes */ // q = q + ((1-q) << 1); // buf2[2] &= 0xfffe; /* Preserve C */ buf2[2] = q; /* Set CQ (no check) */ } /* * Internal clock? * */ i = (buf2[1] & 0x1000) >> 12; /* Extract I */ (void) printf(" I is %d, change to ", i); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ i = atoi(line); /* Yes */ buf2[1] &= 0x0fff; /* Preserve V and code */ buf2[1] |= i << 12; /* Set I (no check) */ } /* * Set clock frequency? * */ (void) printf(" Clock Generator Frequency is %.3f MHz, change to ", freq); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ freq = atof(line); /* Yes */ dphase = freq/100.0*4294967296.0+0.5; /* cf., AD9850 writeup, p. 8 */ for (j = 0; j < 5; j++) { /* Each Wj */ if (j == 0) /* W0? */ buf1[0] = 0; /* Yes, W0 = phase, cf., AD9850 writeup, p. 10 */ else /* Other j */ buf1[0] = dp[4-j]; /* Wj */ buf1[2] = 1; /* Pulse W = W_CLK */ buf1[2] = 0; } buf1[0] = 0x100; /* Pulse U = FQ_UD */ buf1[0] = 0; /* Reset for next time */ } /* * VLBA mode? * */ v = (buf1[1] & 0x100) >> 8; /* Extract V */ (void) printf(" V is %d, change to ", v); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ v = atoi(line); /* Yes */ buf1[1] &= 0x00ff; /* Preserve Mode */ buf1[1] |= v << 8; /* Set V (no check) */ buf2[1] &= 0xf0ff; /* Preserve I and code */ buf2[1] |= v << 8; /* Set V (no check) */ } /* * Record clock off? * */ f = buf1[4] & 0x1; /* Extract F */ (void) printf(" F is %d, change to ", f); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ f = atoi(line); /* Yes */ buf1[4] = f; /* No check */ } /* * Channels to decoder * */ cha = buf2[0] & 0xff; /* Channel A */ (void) printf(" CHA is %d, change to ", cha); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ cha = atoi(line); /* Yes */ buf2[0] &= 0xff00; /* Preserve CHB */ buf2[0] |= cha; /* (No check) */ } chb = buf2[0] >> 8; /* Channel B */ (void) printf(" CHB is %d, change to ", chb); if (fgets(line, sizeof(line), stdin) != NULL && strlen(line) > 1) { /* Read something, OK? */ chb = atoi(line); /* Yes */ buf2[0] &= 0x00ff; /* Preserve CHA */ buf2[0] |= chb << 8; /* (No check) */ } /* * Debuggery? * */ if (msglev < 1) { /* Debuggery? */ (void) fprintf(stderr, /* Yes */ "%s DEBUG: DPhase %#lx \n", me, dphase); (void) fprintf(stderr, /* Yes */ "%s DEBUG: buf1[0] 0x%4.4x, buf1[1] 0x%4.4x, buf1[2] 0x%4.4x \n", me, buf1[0], buf1[1], buf1[2]); (void) fprintf(stderr, "%s DEBUG: buf1[3] 0x%4.4x, buf1[4] 0x%4.4x, buf1[5] 0x%4.4x \n", me, buf1[3], buf1[4], buf1[5]); (void) fprintf(stderr, "%s DEBUG: buf2[0] 0x%4.4x, buf2[1] 0x%4.4x, buf2[2] 0x%4.4x \n", me, buf2[0], buf2[1], buf2[2]); (void) fprintf(stderr, "%s DEBUG: buf2[3] 0x%4.4x, buf2[4] 0x%4.4x, buf2[5] 0x%4.4x \n", me, buf2[3], buf2[4], buf2[5]); } /* End of if debuggery */ return(0); /* Normal end */ } /* End of main = IOBhack */