diff --git a/distrib/sets/lists/minix-base/md.i386 b/distrib/sets/lists/minix-base/md.i386 index bf2d1f477..f5090563a 100644 --- a/distrib/sets/lists/minix-base/md.i386 +++ b/distrib/sets/lists/minix-base/md.i386 @@ -9,6 +9,7 @@ ./etc/system.conf.d/als4000 minix-base ./etc/system.conf.d/amddev minix-base ./etc/system.conf.d/atl2 minix-base +./etc/system.conf.d/b004 minix-base ./etc/system.conf.d/cmi8738 minix-base ./etc/system.conf.d/cs4281 minix-base ./etc/system.conf.d/dec21140A minix-base @@ -36,6 +37,7 @@ ./service/amddev minix-base ./service/at_wini minix-base ./service/atl2 minix-base +./service/b004 minix-base ./service/cmi8738 minix-base ./service/cs4281 minix-base ./service/dec21140A minix-base @@ -65,6 +67,9 @@ ./service/virtio_blk minix-base ./service/virtio_net minix-base ./service/vt6105 minix-base +./usr/bin/iserver minix-base +./usr/bin/ispy minix-base +./usr/bin/mtest minix-base ./usr/lib/libacpi.a minix-base ./usr/lib/libacpi_pic.a minix-base ./usr/lib/libhgfs.a minix-base diff --git a/distrib/sets/lists/minix-comp/md.i386 b/distrib/sets/lists/minix-comp/md.i386 index 458ec5777..859026fad 100644 --- a/distrib/sets/lists/minix-comp/md.i386 +++ b/distrib/sets/lists/minix-comp/md.i386 @@ -191,6 +191,7 @@ ./usr/include/i386/vmparam.h minix-comp ./usr/include/i386/wchar_limits.h minix-comp ./usr/include/minix/vassert.h minix-comp +./usr/include/sys/ioc_b004.h minix-comp ./usr/include/x86 minix-comp ./usr/include/x86/aout_machdep.h minix-comp ./usr/include/x86/bootinfo.h minix-comp diff --git a/distrib/sets/lists/minix-man/md.i386 b/distrib/sets/lists/minix-man/md.i386 index fc6f9f57d..5018df40f 100644 --- a/distrib/sets/lists/minix-man/md.i386 +++ b/distrib/sets/lists/minix-man/md.i386 @@ -5,5 +5,9 @@ # ../../../../releasetools/sort_set.pl < mi > out # mv out mi # +./usr/man/man1/iserver.1 minix-man +./usr/man/man1/ispy.1 minix-man +./usr/man/man1/mtest.1 minix-man +./usr/man/man4/b004.4 minix-man ./usr/man/man8/hgfs.8 minix-man ./usr/man/man8/vbfs.8 minix-man diff --git a/minix/commands/Makefile b/minix/commands/Makefile index 8aca55470..229cfafd1 100644 --- a/minix/commands/Makefile +++ b/minix/commands/Makefile @@ -33,4 +33,8 @@ SUBDIR= at backup \ autopart part partition playwave \ recwave repartition screendump +.if ${MACHINE_ARCH} == "i386" +SUBDIR+= inmos +.endif # ${MACHINE_ARCH} == "i386" + .include diff --git a/minix/commands/inmos/Makefile b/minix/commands/inmos/Makefile new file mode 100644 index 000000000..3135d1978 --- /dev/null +++ b/minix/commands/inmos/Makefile @@ -0,0 +1,10 @@ +DEFS= -DMINIX -DDEFAULTLINK=\"/dev/link0\" -DBOARD_ID=B008 +CPPFLAGS+= ${DEFS} + +PROGS= ispy mtest iserver + +SRCS.ispy= check.c cklib.c b004link.c +SRCS.mtest= mtest.c cklib.c b004link.c +SRCS.iserver= iserver.c filec.c hostc.c serverc.c b004link.c + +.include diff --git a/minix/commands/inmos/b004link.c b/minix/commands/inmos/b004link.c new file mode 100644 index 000000000..934d97bf0 --- /dev/null +++ b/minix/commands/inmos/b004link.c @@ -0,0 +1,292 @@ + +/* + -- --------------------------------------------------------------------------- + -- + -- b004link.c - INMOS standard link interface for the MINIX B004 driver + -- + -- --------------------------------------------------------------------------- +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "iserver.h" + +#define NULL_LINK -1 + +extern int errno; + +static int ActiveLink = NULL_LINK; +static int TheCurrentTimeout = -1; + +/* + * + * OpenLink + * + * Ready the link associated with `Name'. + * If `Name' is NULL or "" then any free link can be used. + * Returns any positive integer as a link id or + * a negative value if the open fails. + * + */ + +int OpenLink ( Name ) + char *Name; +{ + static char DefaultDevice[] = "/dev/link0"; + + /* Already open ? */ + if (ActiveLink != NULL_LINK) + return ER_LINK_CANT; + + /* Use default name ? */ + if ((Name == NULL) || (*Name == '\0')) { + if ((ActiveLink = open(DefaultDevice, O_RDWR)) >= 0) + return ActiveLink; + } + else { + if ((ActiveLink = open(Name, O_RDWR)) >= 0) + return ActiveLink; + } + + return ER_LINK_CANT; +} + + + +/* + * + * CloseLink + * + * Close the active link `LinkId'. + * Returns 1 on success or negative if the close failed. + * + */ + +int CloseLink ( LinkId ) + int LinkId; +{ + if (LinkId != ActiveLink) + return -1; + + close(ActiveLink); + ActiveLink = NULL_LINK; + + return SUCCEEDED; +} + + + +/* + * + * ReadLink + * + * Read `Count' chars into `Buffer' from the specified link. + * LinkId is a vaild link identifier, opened with OpenLink. + * `Timeout' is a non negative integer representing tenths + * of a second. A `Timeout' of zero is an infinite timeout. + * The timeout is for the complete operation. + * If `Timeout' is positive then ReadLink may return having + * read less that the number of chars asked for. + * Returns the number of chars placed in `Buffer' (which may + * be zero) or negative to indicate an error. + * + */ + +int ReadLink ( LinkId, Buffer, Count, Timeout ) + int LinkId; + char *Buffer; + unsigned int Count; + int Timeout; +{ + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (Count < 1) + return ER_LINK_CANT; + + if (Timeout && (Timeout != TheCurrentTimeout)) { + if (ioctl(LinkId, B004SETTIMEOUT, &Timeout) != 0) + return ER_LINK_BAD; + + TheCurrentTimeout = Timeout; + } + + return read(LinkId, Buffer, Count); +} + + + +/* + * + * WriteLink + * + * Write `Count' chars from `Buffer' to the specified link. + * LinkId is a vaild link identifier, opened with OpenLink. + * `Timeout' is a non negative integer representing tenths + * of a second. A `Timeout' of zero is an infinite timeout. + * The timeout is for the complete operation. + * If `Timeout' is positive then WriteLink may return having + * written less that the number of chars asked for. + * Returns the number of chars actually written (which may + * be zero) or negative to indicate an error. + * + */ + +int WriteLink ( LinkId, Buffer, Count, Timeout ) + int LinkId; + char *Buffer; + unsigned int Count; + int Timeout; +{ + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (Count < 1) + return ER_LINK_BAD; + + if (Timeout && (Timeout != TheCurrentTimeout)) { + if (ioctl(LinkId, B004SETTIMEOUT, &Timeout) != 0) + return ER_LINK_BAD; + + TheCurrentTimeout = Timeout; + } + + return write(LinkId, Buffer, Count); +} + + + +/* + * + * ResetLink + * + * Reset the subsystem associated with the specified link. + * Returns 1 if the reset is successful, negative otherwise. + * + */ + +int ResetLink ( LinkId ) + int LinkId; +{ + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (ioctl(LinkId, B004RESET) != 0) + return ER_LINK_BAD; + + return SUCCEEDED; +} + + + +/* + * + * AnalyseLink + * + * Analyse the subsystem associated with the specified link. + * Returns 1 if the analyse is successful, negative otherwise. + * + */ + +int AnalyseLink ( LinkId ) + int LinkId; +{ + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (ioctl(LinkId, B004ANALYSE) != 0) + return ER_LINK_BAD; + + return SUCCEEDED; +} + + + +/* + * + * TestError + * + * Test the error status associated with the specified link. + * Returns 1 if error is set, 0 if it is not and + * negative to indicate an error. + * + */ + +int TestError ( LinkId ) + int LinkId; +{ + struct b004_flags flag; + + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (ioctl(LinkId, B004GETFLAGS, &flag) != 0) + return ER_LINK_BAD; + + return flag.b004_error; +} + + + +/* + * + * TestRead + * + * Test input status of the link. + * Returns 1 if ReadLink will return one byte without timeout, + * 0 if it may not and negative to indicate an error. + * + */ + +int TestRead ( LinkId ) + int LinkId; +{ + struct b004_flags flag; + + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (ioctl(LinkId, B004GETFLAGS, &flag) != 0) + return ER_LINK_BAD; + + return flag.b004_readable; +} + + + +/* + * + * TestWrite + * + * Test output status of the link. + * Returns 1 if WriteLink can write one byte without timeout, + * 0 if it may not and negative to indicate an error. + * + */ + +int TestWrite ( LinkId ) + int LinkId; +{ + struct b004_flags flag; + + if (LinkId != ActiveLink) + return ER_LINK_BAD; + + if (ioctl(LinkId, B004GETFLAGS, &flag) != 0) + return ER_LINK_BAD; + + return flag.b004_writeable; +} + + + +/* + * Eof + */ diff --git a/minix/commands/inmos/boot.h b/minix/commands/inmos/boot.h new file mode 100644 index 000000000..a55fb715d --- /dev/null +++ b/minix/commands/inmos/boot.h @@ -0,0 +1,141 @@ + +/* -------------------------------------------------- + * + * boot.h -- boot code for check + * + * Copyright andyr@wizzy.com (Andy Rabagliati) 30 August 1994 + * + * This code may be freely used, provided credits remain intact + * + * -------------------------------------------------- + */ + + + +static unsigned char boot[] = +{0x8B, /* BYTE END-START */ + /* ORG 0 */ + /* START */ + 0x25, 0x0A, /* J INIT-$ ; bootchan in C */ + 0x21, 0xF5, /* STOP STOPP */ + /* */ + /* EPILOG ; index in AREG */ + 0x71, /* LDL WS */ + 0x60, 0xEE, /* STNL -2 ; BOOTCHAN */ + 0x72, /* LDL VEC */ + 0x71, /* LDL WS */ + 0x60, 0xEF, /* STNL -1 ; VEC space pointer */ + 0x60, 0x43, /* LDC STOP-$-2 */ + 0x21, 0xFB, /* LDPI */ + 0x71, /* LDL WS */ + 0x60, 0xED, /* STNL -3 ; Clean stop on ret */ + 0x71, /* LDL WS */ + 0x70, /* LDL BOOTCHAN */ + 0x73, /* LDL LENGTH */ + 0xF7, /* IN ; read code */ + 0x71, /* LDL WS */ + 0x60, 0x5D, /* LDNLP -3 */ + 0x23, 0xFC, /* GAJW */ + 0x34, /* LDNL ENTRY */ + 0xF6, /* GCALL */ + /* */ + /* READCODE */ + /* WS EQC 1 */ + /* VEC EQC 2 */ + /* LENGTH EQC 3 */ + /* ENTRY EQC 4 ; byte offset */ + /* */ + 0x11, /* LDLP WS */ + 0x70, /* LDL 0 ; bootchan */ + 0x44, /* LDC 4 */ + 0x23, 0xF4, /* BCNT */ + 0xF7, /* IN */ + /* ; read WS, VEC slots, code length, entry */ + /* ; space is used as follows:- */ + /* ; WS from MEMSTART+4 to MEMSTART+4+((WS+3)*bpw) */ + /* ; VEC from WS end to MEMSTART+4+((WS+VEC+3)*bpw) */ + /* ; CODE */ + /* ; Param 1 Of called PROC is VEC space Ptr */ + 0x71, /* LDL WS */ + 0x83, /* ADC 3 ; RETptr, BOOT, Vec */ + 0x62, 0x47, /* LDC START-$-2 ; MEMSTART */ + 0x21, 0xFB, /* LDPI ; MEMSTART */ + 0x84, /* ADC 4 ; room for STOPP */ + 0xFA, /* WSUB */ + 0xD1, /* STL WS ; Wrksp/Code start */ + 0x61, 0x4D, /* LDC READCODE-$-2 */ + 0x21, 0xFB, /* LDPI ; code after EPILOG */ + 0x71, /* LDL WS ; check overwrite */ + 0x60, 0x5D, /* LDNLP -3 ; start of params */ + 0xF9, /* GT */ + 0xA6, /* CJ ENOUGH-$ */ + 0x61, 0x44, /* LDC READCODE-$-2 */ + 0x21, 0xFB, /* LDPI ; code after EPILOG */ + 0x53, /* LDNLP 3 */ + 0xD1, /* STL WS ; Fix it */ + 0x71, /* ENOUGH LDL WS */ + 0x73, /* LDL LENGTH */ + 0xF2, /* BSUB ; space after code */ + 0x41, /* LDC 1 */ + 0x23, 0xF4, /* BCNT */ + 0x60, 0x8F, /* ADC -1 ; Bytes per word -1 */ + 0xF5, /* ADD */ + 0x41, /* LDC 1 */ + 0x23, 0xF4, /* BCNT */ + 0x23, 0xF2, /* NOT */ + 0x81, /* ADC 1 ; Word mask */ + 0x24, 0xF6, /* AND ; round up to word */ + 0xD2, /* STL VEC ; VEC space start */ + 0x74, /* LDL ENTRY */ + 0x71, /* LDL WS */ + 0xF2, /* BSUB */ + 0xD4, /* STL ENTRY */ + 0x70, /* LDL BOOTCHAN */ + 0x41, /* LDC 1 */ + 0x23, 0xF4, /* BCNT ; bpw independent */ + 0x22, 0xFC, /* DIV ; Bytes Per Word */ + 0x43, /* LDC 3 ; leave last 2 bits */ + 0x24, 0xF6, /* AND ; Index of boot chan*/ + 0x65, 0x08, /* J EPILOG-$ */ + /* ALIGN 4 ; INIT might be WPTR*/ + /* MINT EQC 1 */ + /* BOOTCHAN EQC 0 */ + 0xD0, /* INIT STL 0 */ + 0xD0, /* STL 0 */ + 0x66, 0x4E, /* LDC START-$-2 */ + 0x21, 0xFB, /* LDPI */ + 0x60, 0x5B, /* LDNLP -5 */ + 0x23, 0xFC, /* GAJW */ + 0xD0, /* STL 0 */ + 0xD0, /* STL BOOTCHAN */ + 0x24, 0xF2, /* MINT */ + 0xD1, /* STL MINT */ + 0x71, /* LDL MINT */ + 0x21, 0xFC, /* STLF ; lo priority Q */ + 0x71, /* LDL MINT */ + 0x21, 0xF8, /* STHF ; hi */ + 0x22, 0xF9, /* TESTERR */ + 0x25, 0xF7, /* CLRHALTERR */ + 0x40, /* LDC 0 */ + 0x25, 0xF4, /* STTIMER ; clock */ + 0x40, /* LDC 0 ; loop to init Links,Timers*/ + 0xD2, /* STL 2 */ + 0x4B, /* LDC 11 */ + 0xD3, /* STL 3 */ + 0x71, /* L101A LDL MINT */ + 0x72, /* LDL 2 */ + 0x71, /* LDL MINT */ + 0xFA, /* WSUB */ + 0xE0, /* STNL 0 */ + 0x12, /* LDLP 2 */ + 0x49, /* LDC LXXX-L101A */ + 0x22, 0xF1, /* LEND ; end */ + 0x66, 0x06, /* LXXX J READCODE-$ */ + /* ; padding for timeslice to tread on*/ + 0,0,0,0 /* BYTE 0,0,0,0 */ + /* END */ }; + + +/* + * eof + */ diff --git a/minix/commands/inmos/check.c b/minix/commands/inmos/check.c new file mode 100644 index 000000000..5ad516156 --- /dev/null +++ b/minix/commands/inmos/check.c @@ -0,0 +1,1408 @@ +/*{{{ header */ +/* + * -------------------------------------------------- + * + * check.c -- check program + * + * renamed to ispy - cos its a better name + * + * Andy Rabagliati INMOS + * + * Modified by Jeremy Thorp + * + * Adapted for Autronica, TRONDHEIM, Norway, under contract to + * 0yvind Teig for link on their boards. + * + * + * Copyright andyr@wizzy.com (Andy Rabagliati) 30 August 1994 + * 18 January 1995 + * + * This code may be freely used, provided above credits remain intact + * the CREDITS #define below is kept. Any modifications must be + * distributed in source. + * + * -------------------------------------------------- + */ +/*}}} */ +/*{{{ includes, defines */ +char *PROGRAM_NAME = "ispy"; + +#define VERSION_NUMBER "3.23" +#define VERSION_DATE "2nd Feb 1995" +#define CREDITS "by Andy Rabagliati " +#define WWW "" +#define AUTRONICA "for AUTRONICA, Trondheim, Norway" +#include +#include +#include + +#include "linkio.h" + +/* for isatty */ +#ifdef MSDOS +#include +#else +#ifndef isatty +#include +#endif +#endif +#include +#include +#include + +#include "inmos.h" +#include "checklib.h" +#include "cklib.h" + +#include "type16.h" +#include "type32.h" +#include "check16.h" +#include "check32.h" +/* #include "c00416.h" */ +/* #include "c00432.h" */ + +/* always use "-" */ + +#define SWITCHAR '-' + +#define SEGSIZE 511 + +#define TIMEOUT 10 +#define EMPTY (-1) +#define MAXLENGTH 1024 /* maximum route length */ +#define PERLINE 9 + +#define CocoPops 0 +#define VerboseSwitch 1 + +#define DEBUG(x) { if (CocoPops) { fputs("(", stdout); printf x; fputs(")", stdout); fputc((VerboseSwitch ? '\n' : ' '), stdout); fflush(stdout); } } +#define INFO(x) { if (VerboseSwitch) printf x ; fflush(stdout); } + + +/*}}} */ +/*{{{ Usage */ +void Usage(void) +{ + printf("\nUsage: %s [%coption...] [ < file ] -- version %s of %s.\n\n", + PROGRAM_NAME, SWITCHAR, VERSION_NUMBER, VERSION_DATE); + printf(" This tests the network connectivity\n"); + printf(" and can compare this to a file from a previous run\n\n"); + printf("Options:\n"); + printf(" %cn : do not reset the root transputer\n", SWITCHAR); + printf(" %cr : reset the root transputer subsystem\n", SWITCHAR); + printf(" %cc4 : read the state of all C004s found\n", SWITCHAR); + printf(" %ccl : read the state of C004s, long form\n", SWITCHAR); + printf(" %ccr : reset all C004s found\n", SWITCHAR); + printf(" %ccs : set all C004s in filename\n", SWITCHAR); + printf(" %cl : use this link, else TRANSPUTER envr. var, else %s\n", + SWITCHAR, DEFAULTLINK); + printf(" %cx : Ignores any file piped in to %s\n", SWITCHAR, + PROGRAM_NAME); + printf(" %ci : Information - gives progress reports\n", SWITCHAR); + printf(" %ch : This help page\n\n", SWITCHAR); + printf( " %s\n", AUTRONICA); + printf( "%s %s\n", CREDITS, WWW); + + exit(0); +} +/*}}} */ +/*{{{ statics */ +static unsigned char SSRESETHI[] = +{0, /* poke */ + 0, 0, 0, 0, /* reset */ + 1, 0, 0, 0}; /* asserted */ +static unsigned char SSRESETLO[] = +{0, /* poke */ + 0, 0, 0, 0, /* reset */ + 0, 0, 0, 0}; /* de-asserted */ + +#if 0 +static unsigned char SSANALYSEHI[] = +{0, /* poke */ + 1, 0, 0, 0, /* analyse */ + 1, 0, 0, 0}; /* asserted */ +static unsigned char SSANALYSELO[] = +{0, /* poke */ + 1, 0, 0, 0, /* analyse */ + 0, 0, 0, 0}; /* de-asserted */ +#endif + +static unsigned char BOOTSTRING[] = +{23, /* length of bootstrap * ls 2 bits + * 1, so its a data * packet for 1/2 + * speed links */ + 0xB1, /* AJW 1, allow for Iptr store */ + 0xD1, /* STL 1 */ + 0x24, 0xF2, /* MINT */ + 0x21, 0xFC, /* STHF */ + 0x24, 0xF2, /* MINT */ + 0x21, 0xF8, /* STLF */ + 0xF0, /* REV */ + 0x60, 0x5C, /* LDNLP -4 */ + 0x2A, 0x2A, 0x2A, 0x4A, /* LDC #AAAA */ + 0xFF, /* OUTWORD */ + 0x21, 0x2F, 0xFF, /* START */ + 0x02, 0x00}; /* C004 read link */ +/*}}} */ +/*{{{ globals */ +int kong = TRUE, c4read = 0; +struct tpstats *root; +LINK TheLink; +char LinkName[64]; +char FileName[256]; +/*}}} */ + +/*{{{ readC004 */ +void readC004(struct c4stats * q) +{ + unsigned int length; + unsigned char query[2]; + int i; + query[0] = 8; + query[1] = (char) q->route; + setroute(TheLink, q->parent, 4); + if (!sendiserver(TheLink, 2, query)) + AbortExit(PROGRAM_NAME, "Failed to ask for C004 %d type", q->tpid); + if (!getiserver(TheLink, &length, query, 2)) + AbortExit(PROGRAM_NAME, "Failed to read C004 %d type", q->tpid); + if (length == 1) + q->tptype = C4 + query[0] - 'a'; + query[0] = 2; + query[1] = (unsigned char) q->route; + if (!sendiserver(TheLink, (unsigned int) 2, query)) + AbortExit(PROGRAM_NAME, "Failed to query C004 %d", q->tpid); + if (!getiserver(TheLink, &length, (unsigned char *) q->config, 32)) + AbortExit(PROGRAM_NAME, "C004 %d failed to respond to query", q->tpid); + for (i = 0; i < 32; i++) + { + if (q->tptype == C4) /* C004a */ + q->config[i] = (char) ((int) q->config[i] & 0x1F); + else /* C004b */ + q->config[i] = (char) (((int) q->config[i] & 0x9F) ^ 0x80); + if (q->config[i] < 0) + q->config[i] = EMPTY; + } +} +/*}}} */ +/*{{{ check */ +/*{{{ subordinate fns */ +/*{{{ writeresults */ +void writeresults(struct tpstats * root, char *LinkName, int c4read, + int kong) +#define MyBanner " # Part rate Link# [ Link0 Link1 Link2 Link3 ]" +{ + struct tpstats *p; + int error = FALSE; + if (LinkName[0]) + printf("Using %s ", LinkName); + printf("%s %s\n%s", PROGRAM_NAME, VERSION_NUMBER, MyBanner); + if (kong) + printf(" CHANGES \n"); + else + printf(" by Andy!\n"); + for (p = root; p != NULL; p = p->next) + { + if (class(p->tptype) != C4) + { + error = writeup(p, c4read, 0); + putchar('\n'); + } else + if (c4read == 1) + { + writeC4((struct c4stats *) p); + putchar('\n'); + } else + if (c4read == 2) + { + writeCl((struct c4stats *) p); + putchar('\n'); + } + } +} +/*}}} */ +/*{{{ test_root_int_mem */ +void test_root_int_mem(const unsigned int bpw, const unsigned char byte_value) +{ +/* buffer 0 1 2 3 4 5 6 7 8 9 10 11 12 + 32 bit PP < addr > < data > + 16 bit PP
*/ + + unsigned char buffer[30]; + int i, j; + + buffer[3] = 0; + buffer[4] = buffer[5] = buffer[6] = 0; + i = 3 + bpw; + buffer[i++] = 0x80; + for (j = 0; j < bpw; j++) + buffer[i++] = byte_value; + for (i = 0; i < 2048; i += bpw) + { + WriteLink(TheLink, &buffer[3], (2 * bpw) + 1, TIMEOUT); + if (!(buffer[4] += bpw)) + buffer[5]++; + } + buffer[3] = 1; + buffer[4] = buffer[5] = buffer[6] = 0; + i = 3 + bpw; + buffer[i] = 0x80; + for (i = 0; i < 2048; i += bpw) + { + unsigned int byte_count; + unsigned char mem_value[4]; + + WriteLink(TheLink, &buffer[3], bpw + 1, TIMEOUT); + readbytes(TheLink, mem_value, bpw); + if (!(buffer[4] += bpw)) + buffer[5]++; + for (byte_count = 0; byte_count < bpw; byte_count++) + if (mem_value[byte_count] != byte_value) + AbortExit(PROGRAM_NAME, "Root processor internal RAM failure"); + } +} +/*}}} */ +/*{{{ findtype */ +int findtype(void) +{ + unsigned char buffer[30]; + int bytes, read_result, going; + int type = 0; + char bpw; + bytes = WriteLink(TheLink, BOOTSTRING, sizeof(BOOTSTRING), TIMEOUT); + if (bytes == sizeof(BOOTSTRING)) + { + /*{{{ read bytes */ + int count = 0; + bytes = 0; + going = TRUE; + while (going) + { + read_result = ReadLink(TheLink, &buffer[bytes], 1, 1); + count++; + if (count >= 30) + going = FALSE; + else if (read_result == 1) + bytes++; + else if (read_result != ER_LINK_NOSYNC) + going = FALSE; + } + /*}}} */ + + if (read_result < 0 && read_result != ER_LINK_NOSYNC) + AbortExit(PROGRAM_NAME, "Failed to determine Root Transputer type (result %d)", + read_result); + + switch (bytes) + { + case 1: + return (C4); + break; + case 2: + if ((buffer[0] == 0xAA) && (buffer[1] == 0xAA)) + { + type = T16; + bpw = 2; + } else + AbortExit(PROGRAM_NAME, "Failed to determine Root Transputer type, received %d bytes", + bytes); + break; + case 4: + if ((buffer[0] == 0xAA) && (buffer[1] == 0xAA)) + { + type = T32; + bpw = 4; + } else + AbortExit(PROGRAM_NAME, "Failed to determine Root Transputer type, received %d bytes", + bytes); + break; + default: + AbortExit(PROGRAM_NAME, "Failed to determine Root Transputer type, received %d bytes", + bytes); + } + } else + AbortExit(PROGRAM_NAME, "Failed to boot Root Transputer, only took %d byte(s)", + bytes); + /* test_root_int_mem((int) bpw, (unsigned char) 0x55); + test_root_int_mem((int) bpw, (unsigned char) 0xAA); */ + + return (type); +} + +/*}}} */ +/*{{{ ramtest */ + +void ramtest(struct tpstats * p, int link) +{ + unsigned char testcommand[3]; + setroute(TheLink, p, link); + testcommand[0] = 0xFF; + testcommand[1] = 0xFF; + switch (p->linkno[link]) + { + case T16: + testcommand[2] = TAG_TEST16; + break; + case T32: + testcommand[2] = TAG_TEST32; + break; + } + if (WriteLink(TheLink, testcommand, 3, TIMEOUT) != 3) + { + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Timed out sending RAMTEST to processor %d", p->tpid); + } +} /* ramtest */ +/*}}} */ +/*{{{ linkspeed */ +void linkspeed(struct tpstats * p) +{ + static unsigned char LINKSPEED[] = {0xFF, 0xFF, TAG_LSPEED}; + setroute(TheLink, p->parent, p->route); + if (WriteLink(TheLink, LINKSPEED, 3, TIMEOUT) == 3); + else + { + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Timed out testing link speed for processor %d", p->tpid); + } +} /* linkspeed */ +/*}}} */ +/*{{{ sendid */ +void sendid(struct tpstats * p) +{ + unsigned char int16[2]; + int16[0] = (unsigned char) p->tpid & 0xFF; + int16[1] = (unsigned char) p->tpid >> 8; + setroute(TheLink, p->parent, p->route); + if (!sendiserver(TheLink, 2, int16)) + { + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Failed to send Transputer id to processor %d", p->tpid); + } +} +/*}}} */ +/*{{{ create */ +struct tpstats *create(struct tpstats * parent, int link) +{ + struct tpstats *p; + int i; + + for (p = root; p->next != NULL; p = p->next); + if (parent->linkno[link] == C4) + { + p->next = (struct tpstats *) Malloc(sizeof(struct c4stats)); + p->next->tpid = p->tpid + 1; + p = p->next; + } else + { + p->next = (struct tpstats *) Malloc(sizeof(struct tpstats)); + p->next->tpid = p->tpid + 1; + p = p->next; + p->procspeed = 0; + p->bootlink = 255; + p->linkspeed = 0.0f; + for (i = 0; i < 4; i++) + { + p->links[i] = NULL; + p->linkno[i] = UNKNOWN; + } + } + p->next = NULL; + parent->links[link] = p; + p->routelen = parent->routelen + 1; + p->tptype = parent->linkno[link]; + p->parent = parent; + p->route = link; + p->info[0] = '\0'; + return (p); +} /* create */ +/*}}} */ +/*{{{ getstats */ +void getstats(struct tpstats * p) +{ + unsigned char string[6]; + unsigned int i = 0; + int tptype; + if ((getiserver(TheLink, &i, string, sizeof(string))) && (i == 6)) + { + tptype = string[0] + ((char) string[1] << 8); + if (p->tptype == T32) + p->tptype = tptype; + else + if ((p->tptype == T16) && (class(tptype) == T_414)) + p->tptype = T_212; + p->bootlink = string[3]; + p->links[p->bootlink] = p->parent; + if (p->parent != NULL) + { + p->linkno[p->bootlink] = p->route; + p->parent->linkno[p->route] = p->bootlink; + } else + p->linkno[p->bootlink] = HOST_TAG; + p->procspeed = string[2]; + p->linkspeed = (float) (string[4] + (string[5] << 8)); + if (p->linkspeed != 0.0f) + p->linkspeed = (float) (256.0E6 / p->linkspeed); + } else + { + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "%d Partial results : Error reading Transputer %d type information", i, p->tpid); + } +} +/*}}} */ +/*{{{ checksum */ +int checksum(struct tpstats * p, int link) +{ + while (p->parent != NULL) + { + link = (link << 2) + p->route; + p = p->parent; + } + return (link); +} +/*}}} */ +/*{{{ nextcandidate */ +int nextcandidate(struct tpstats ** child, struct tpstats ** parent) +{ + int success; + unsigned char i; + for (*parent = root, success = FALSE; + (!success) && (*parent != NULL); + *parent = (*parent)->next) + if (class((*parent)->tptype) != C4) + for (i = 0; (!success) && (i < 4); i++) + switch ((*parent)->linkno[i]) + { + case T16: + case T32: + success = TRUE; + *child = create(*parent, i); + break; + default: + success = FALSE; + break; + } + return (success); +} /* nextcandidate */ +/*}}} */ +/*{{{ solve */ +void solve(struct tpstats * current, int length, + unsigned char *buffer) +{ + struct tpstats *p; + int id; +/* + printf("solve: processor %d [", current->tpid); + for (id=0; idlinkno[buffer[1]] = HALF; + break; + case qTXXX: + switch (length) + { + case 2: + current->linkno[buffer[1]] = TXXX; + break; + case 3: /* myself booting myself */ + current->linkno[buffer[1]] = buffer[2]; + current->linkno[buffer[2]] = buffer[1]; + current->links[buffer[1]] = current; + current->links[buffer[2]] = current; + break; + case 5: /* another booted transputer */ + id = ((int) buffer[2] << 8) + (int) buffer[1]; + for (p = root; (p != NULL) && (p->tpid != id); p = p->next); + if (p == NULL) + { + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, " (%d:%d-%d:%d) : Check link connections", + current->tpid, buffer[4], id, buffer[3]); + } + current->links[buffer[4]] = p; + current->linkno[buffer[4]] = buffer[3]; + p->links[buffer[3]] = current; + p->linkno[buffer[3]] = buffer[4]; + break; + } + break; + case qDISK: + if ((current->tptype == T_212) && (buffer[1] == 2)) + { + current->tptype = M212; + current->linkno[2] = DISK; + break; + } else + { + current->linkno[buffer[1]] = UNKNOWN; + break; + } + /* first look says T16, T32, C4 */ + case qT32: + current->linkno[buffer[1]] = T32; + break; + case qT16: + current->linkno[buffer[1]] = T16; + break; + case qC4: + current->linkno[buffer[1]] = C4; + break; + } +} /* solve */ +/*}}} */ +/*}}} */ +void check(int subsys, int c4read, int c4reset, int information, int do_reset) + +{ + /* int c004count = 0, c004s[100]; */ + do + { + int i, success; + struct tpstats *parent, *p; + if (do_reset) + /*{{{ */ + { + if (information) + INFO((", Reset root")); + success = ResetLink(TheLink); + + if (success < 0) + AbortExit(PROGRAM_NAME, "reset link failed (result = %d)", success); + } + /*}}} */ + + if (subsys) + /*{{{ */ + { + long delay; + if (information) + INFO((", re")); + if (WriteLink(TheLink, SSRESETLO, sizeof(SSRESETLO), TIMEOUT) != + sizeof(SSRESETLO)) + AbortExit(PROGRAM_NAME, "Failed to reset Subsystem port"); + for (delay = 0; delay < 100000; delay++); + if (information) + INFO(("set")); + if (WriteLink(TheLink, SSRESETHI, sizeof(SSRESETHI), TIMEOUT) != + sizeof(SSRESETHI)) + AbortExit(PROGRAM_NAME, "Failed to reset Subsystem port"); + for (delay = 0; delay < 1000000; delay++); + if (information) + INFO((" subsystem")); + if (WriteLink(TheLink, SSRESETLO, sizeof(SSRESETLO), TIMEOUT) != + sizeof(SSRESETLO)) + AbortExit(PROGRAM_NAME, "Failed to reset Subsystem port"); + for (delay = 0; delay < 100000; delay++); + } + /*}}} */ + /*{{{ init*/ + root = (struct tpstats *) Malloc(sizeof(struct tpstats)); + p = root; + parent = NULL; + p->tpid = 0; + p->procspeed = 0; + p->bootlink = 255; + p->linkspeed = 0.0f; + for (i = 0; i < 4; i++) + { + p->links[i] = NULL; + p->linkno[i] = UNKNOWN; + } + p->routelen = 0; + p->parent = NULL; + p->next = NULL; + p->info[0] = '\0'; + + if (information) + INFO((", CPU type\n")); + + p->tptype = findtype(); + if (information) { + writeup(p, 0, information); + putchar ('\n'); + } + success = TRUE; + /*}}} */ + while (success) + { + /* int c4 = FALSE; */ + + if (information) + INFO(("# CPU")); + + switch (p->tptype) + { + /*{{{ case T32:*/ + case T32: + if (!load(TheLink, p, + type32_code.CodeSize, + type32_code.Offset, + type32_code.WorkSpace, + type32_code.VectorSpace, + type32_code.BytesPerWord, + type32_code.Code)) + { + if (information) INFO(("\n")); + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Failed to load TYPE32 code on Transputer %d", + p->tpid); + } + break; + /*}}} */ + /*{{{ case T16:*/ + case T16: + if (!load(TheLink, p, + type16_code.CodeSize, + type16_code.Offset, + type16_code.WorkSpace, + type16_code.VectorSpace, + type16_code.BytesPerWord, + type16_code.Code)) + { + if (information) INFO(("\n")); + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Failed to load TYPE16 code on Transputer %d", + p->tpid); + } + break; + /*}}} */ + } + if (information) + INFO((", link")); + + if (p->routelen == 0) + { + unsigned char *buffer; + unsigned int tmp; + buffer = (unsigned char *) Malloc(257); + tmp = WriteLink(TheLink, buffer, 257, TIMEOUT); + if (tmp != 257) /* for link speed */ + { + if (information) INFO(("\n")); + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Only wrote %d bytes to Transputer %d boot link\n", tmp, p->tpid); + } + free(buffer); + } else + linkspeed(p); + if (information) + INFO((" speed\n")); + getstats(p); + if (information) { + writeup(p, 0, information); + printf("\n"); + } + if (information) + INFO(("# Loading ispy")); + + if (p->tptype != T_414) /* T414A */ + { + int j; + switch (bpw(p->tptype)) + { + /*{{{ case 2:*/ + case 2: + if (!load(TheLink, p, + check16_code.CodeSize, + check16_code.Offset, + check16_code.WorkSpace, + check16_code.VectorSpace, + check16_code.BytesPerWord, + check16_code.Code)) + { + if (information) INFO(("\n")); + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Failed to load CHECK16 code on Transputer %d", + p->tpid); + } + break; + /*}}} */ + /*{{{ case 4:*/ + case 4: + if (!load(TheLink, p, + check32_code.CodeSize, + check32_code.Offset, + check32_code.WorkSpace, + check32_code.VectorSpace, + check32_code.BytesPerWord, + check32_code.Code)) + { + if (information) INFO(("\n")); + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Failed to load CHECK32 code on Transputer %d", + p->tpid); + } + break; + /*}}} */ + } + sendid(p); + if (information) + INFO((", id %d, probe\n", p->tpid)); + + success = TRUE; + j = 0; + while ((j < 3) && success) + { + unsigned int length; + unsigned char buffer[8]; + success = getiserver(TheLink, &length, + buffer, (unsigned) sizeof(buffer)); + if (success) + { + if (buffer[0] == qHALF) /* this always precedes qC4 */ + j--; + solve(p, length, buffer); + if (information) { + writeup(p, 0, information); + printf("\n"); + } + } + j++; + } + if (!success) + { + writeresults(root, LinkName, c4read, kong); + AbortExit(PROGRAM_NAME, "Partial results : Failed to probe links on Transputer %d", + p->tpid); + } + for (j = 0; j < 4; j++) + switch (p->linkno[j]) { + case C4: + { + struct tpstats *q; + q = create(p, j); + /* c4 = TRUE; */ + } + break; + } + } +#if 0 /* cannot test this */ + if (c4) + { + if (information) + INFO(("# C004s ")); + stop(p); + switch (bpw(p->tptype)) + { + case 2: + load(TheLink, p, + c00416_code.CodeSize, + c00416_code.Offset, + c00416_code.WorkSpace, + c00416_code.VectorSpace, + c00416_code.BytesPerWord, + c00416_code.Code); + break; + case 4: + load(TheLink, p, + c00432_code.CodeSize, + c00432_code.Offset, + c00432_code.WorkSpace, + c00432_code.VectorSpace, + c00432_code.BytesPerWord, + c00432_code.Code); + break; + } + sendid(p); + if (c4reset) + { + int reset; + unsigned char command[2]; + int i, j, sum = 0; + for (i = 0, reset = FALSE; (!reset) && (i < 4); i++) + { + if (p->linkno[i] == C4) + { + sum = checksum(p, i); + for (j = 0; (sum != c004s[j]) && (j < c004count); j++); + if (j == c004count) + reset = TRUE; + } + } + if (reset) + { + i--; /* undo 'for' increment */ + if (information) + INFO(("# Reset C004 %d\n", p->links[i]->tpid)); + setroute(TheLink, p, 4); /* application */ + command[1] = (unsigned char) i; + command[0] = '\4'; + sendiserver(TheLink, 2, command); /* reset */ + c004s[c004count++] = sum; + while (root->next != NULL) + { + for (p = root; + (p->next != NULL) && (p->next->next != NULL); + p = p->next); + free(p->next); + p->next = NULL; + } + free(root); + } + success = !reset; + } + } else +#endif + success = TRUE; + if (success) + { + success = nextcandidate(&p, &parent); + if (!success) { + c4reset = FALSE; + } + } + } /* while */ + } while (c4reset); +} +/*}}} */ +/*{{{ compare */ +/* +* Strategy :- For each Transputer on the reference tree, see if we can find +* a match on the real tree. +* +* First:- mark them all as not found, ref->routelen = -1. +* +* For each ref Transputer, +* +* mark all real transputers as not yet scanned, real->extra = NULL. trace a +* path from ref TP to its root - follow same path back from real root to see +* if TPs match. +* +* skip search if we encounter unfound transputers on the way. repeat while +* there is progress +* + */ +/*{{{ subordinate fns */ +/*{{{ int tpcompare(int tp1, int tp2) */ +int tpcompare(int tp1, int tp2) +{ + int res; + int ctp1 = class(tp1); + int ctp2 = class(tp2); + char nametp1[8]; + char nametp2[8]; + + strcpy(nametp1, tptostr(tp1)); + strcpy(nametp2, tptostr(tp2)); + + res = (ctp1==ctp2); + + DEBUG(("tp1 = %d, \"%s\", tp2 = %d, \"%s\", ctp1 = %d, ctp2 = %d, res = %d", + tp1, nametp1, tp2, nametp2, ctp1, ctp2, res)); + + return(res); +} +/*}}} */ +/*{{{ getparams */ +void getparams(int argc, char *argv[], + char *LinkName, char *FileName, + int *mapfile, + int *subsys, int *c4read, int *c4reset, + int *c4set, int *kong, int *do_reset, + int *information) +{ + char *c; + c = getenv("TRANSPUTER"); + if (c != NULL) + strcpy(LinkName, c); + else strcpy(LinkName, DEFAULTLINK); + while (--argc > 0) + { + argv++; + c = *argv; +#ifdef MSDOS + if ((*c != '-') && (*c != '/')) + Usage(); +#else + if (*c != SWITCHAR) + Usage(); +#endif + ++c; + switch (*c) + { + case '?': + case 'h': + case 'H': + Usage(); + break; + case 'l': + case 'L': + if (argc-- == 1) + AbortExit(PROGRAM_NAME, "name or hex address missing after the L option"); + ++argv; + strcpy(LinkName, *argv); + break; + case 'x': + case 'X': + *kong = FALSE; + break; + case 'i': + case 'I': + *information = TRUE; + break; + case 'n': + case 'N': + *do_reset = FALSE; + break; + case 'r': + case 'R': + *subsys = TRUE; + break; + case 'm': + case 'M': + if (argc-- == 1) + AbortExit(PROGRAM_NAME, + "file name missing after the M option"); + ++argv; + strcpy(FileName, *argv); + *mapfile = TRUE; + break; + case 'c': + case 'C': + c++; + switch (*c) + { + case 'r': + case 'R': + *c4reset = TRUE; + break; + case '4': + *c4read = 1; + break; + case 'L': + case 'l': + *c4read = 2; + break; + case 'S': + case 's': + *c4set = TRUE; + break; + default: + Usage(); + break; + } + break; + default: + Usage(); + break; + } + } +} +/*}}} */ +/*{{{ sort */ +struct tpstats *sort(struct tpstats * root) +{ + struct tpstats **p; + int sorted; + sorted = FALSE; + while (!sorted) + { + sorted = TRUE; + for (p = (&root); ((*p) != NULL) && ((*p)->next != NULL); p = (&((*p)->next))) + if ((*p)->tpid > (*p)->next->tpid) + { + struct tpstats *temp; + temp = *p; + *p = temp->next; + temp->next = temp->next->next; + (*p)->next = temp; + sorted = FALSE; + } + } + return (root); +} +/*}}} */ +/*{{{ follow */ +struct tpstats *follow(struct tpstats * p, struct tpstats * q, int fromroot) +{ + DEBUG(("starting follow()")); + + if ((!fromroot) && (p->routelen == (-1))) /* not located yet */ + return (p); + if (!fromroot && class(p->tptype) == C4) + return (NULL); + if (p->extra != NULL) + return (NULL); /* been here already */ + if (p->parent == NULL) + return (q); + else + { + int i, lno, unfound = FALSE; + struct tpstats *r = NULL; + if (class(p->tptype) == C4) + { + for (lno = 0; (lno < 4) && p->parent->links[lno] != p; lno++); + if (lno > 3) + AbortExit(PROGRAM_NAME, "Internal error in follow"); + p->extra = p; /* mark this one as searched */ + r = follow(p->parent, q, FALSE); + p->extra = NULL; /* done with this tree search */ + r = r->links[lno]; /* back-tracing */ + } else + for (i = 0; (i < 4) && (r == NULL); i++) + if ((fromroot) || (i == (int) p->bootlink)) + { + struct tpstats *temp = p->links[i]; + lno = p->linkno[i]; + if (temp != NULL) + { + p->extra = p; /* mark this one as searched */ + r = follow(temp, q, FALSE); + p->extra = NULL; /* done with this tree search */ + if (r == temp) + { + unfound = TRUE; + r = NULL; /* encountered unfound transputer */ + } else + { + if ((r == NULL) || /* cant find it */ + (r->links[lno] == NULL) || /* bad connection */ + ((int) r->linkno[lno] != i) || /* ditto */ + (!tpcompare(r->links[lno]->tptype, p->tptype))) + r = NULL; /* keep searching */ + if (r != NULL) + { + p->bootlink = (char) i; + r = r->links[lno]; + } + } + } + } + if ((r == NULL) && unfound) + return (p); + else + return (r); + } +} +/*}}} */ +/*}}} */ + +int compare(struct tpstats * root, struct tpstats * reference) +{ + int progress = TRUE; + int same = 0, i, refmax, max = 0; + struct tpstats *p, *q; + + DEBUG(("starting same()")); + + for (p = reference; p != NULL; p = p->next) + { + if (p->tpid > max) + max = p->tpid; + p->routelen = (-1); /* mark them as not found */ + } + refmax = max; + for (p = root; p != NULL; p = p->next) + { + p->extra = NULL; /* not allocated yet */ + for (i = 0; (p->info[i + 1]) && (p->info[i] != ']'); i++); + strcpy(p->info, &p->info[i + 1]); + } + for (p = root; p != NULL; p = p->next) + p->tpid = ++max; /* renumber them out of the way */ + + /* no match if the root tp is different in root & reference */ + progress = tpcompare(root->tptype, reference->tptype); + + while (progress) + { + progress = 0; + for (p = reference; p != NULL; p = p->next) + if (p->routelen) + { + q = follow(p, root, TRUE); + if ((q != NULL) && (q != p) && (q->extra == NULL)) + { + q->tpid = p->tpid; + p->routelen = 0; /* found */ + q->extra = q; /* allocated */ + if (class(p->tptype) == C4) + memcpy(((struct c4stats *) q)->config, + ((struct c4stats *) p)->config, 32); + progress++; + } + } + } + for (p = reference; p != NULL; p = p->next) + if (p->routelen == -1) + { + struct tpstats *r; + r = (struct tpstats *) Malloc(sizeof(struct tpstats)); + r->next = root->next; + root->next = r; /* stuff it in somewhere, it'll be sorted */ + r->tpid = p->tpid; + r->routelen = -1; /* route length from host */ + r->tptype = p->tptype; /* Transputer type */ + r->procspeed = p->procspeed; /* processor speed */ + r->route = 0; /* incremental route here */ + r->bootlink = p->bootlink; + r->linkspeed = 0.0f;/* Mbytes/sec down boot link set to zero to + * mark it as not present */ + for (i = 0; i < 4; i++) + { + r->links[i] = p->links[i]; /* pointers to other + * Transputers */ + r->linkno[i] = p->linkno[i]; /* link numbers, or + * non-transputer type */ + } + r->parent = NULL; + strcpy(r->info, " MISSING "); + r->extra = NULL; + same = -1; + } + for (p = reference; p != NULL; p = p->next) + { + q = find(root, p->tpid); + if ((q != NULL) && (q->routelen != -1) && (class(p->tptype) != C4)) + /* a match */ + { + q->info[0] = ' '; + q->info[1] = '\0'; + for (i = 0; i < 4; i++) + { + if ((p->links[i] != NULL) && (q->links[i] == NULL)) + { + sprintf(&(q->info[strlen(q->info)]), "%d-", i); + same = -1; + } + if ((p->links[i] == NULL) && (q->links[i] == NULL)) + sprintf(&(q->info[strlen(q->info)]), " "); + if ((p->links[i] == NULL) && (q->links[i] != NULL)) + { + sprintf(&(q->info[strlen(q->info)]), "%d+", i); + if (!same) + same = 1; + } + if ((p->links[i] != NULL) && (q->links[i] != NULL)) + { + if ((p->links[i]->tpid != q->links[i]->tpid) || + (p->linkno[i] != q->linkno[i])) + { + sprintf(&(q->info[strlen(q->info)]), "%d?", i); + same = -1; + } else + sprintf(&(q->info[strlen(q->info)]), " "); + } + } + } + } + max = refmax; + for (p = root; p != NULL; p = p->next) + if (p->tpid > refmax) + { /* an extra transputer */ + p->tpid = ++max; /* renumber it */ + strcpy(p->info, " -EXTRA- \0"); + } + + DEBUG(("ending same()")); + + return (same); +} +/*}}} */ +/*{{{ setC004 */ +void setC004(struct c4stats * p) +{ + unsigned char command[100]; + int i, length; + setroute(TheLink, p->parent, 4); /* application */ + command[1] = (unsigned char) p->route; + command[0] = '\4'; + sendiserver(TheLink, 2, command); /* reset */ + for (i = 0, length = 0; i < 32; i++) + if (p->config[i] != EMPTY) + { + command[length++] = '\0'; + command[length++] = p->config[i]; + command[length++] = (unsigned char) i; + } + if (length > 0) + { + tpboot(TheLink, (struct tpstats *) p); /* raw mode */ + sendiserver(TheLink, length, command); /* config */ + } +} +/*}}} */ +/*{{{ main */ +int main(int argc, char *argv[]) +{ + struct tpstats *reference = NULL; + char Pipe[128]; + char Banner[128]; + int transputers = 0; + int same = 0, subsys = FALSE, information = FALSE; + int c4reset = FALSE, c4set = FALSE, mapfile = FALSE; + int do_reset = TRUE; + + FileName[0] = '\0'; + LinkName[0] = '\0'; + getparams(argc, argv, LinkName, FileName, &mapfile, + &subsys, &c4read, &c4reset, &c4set, + &kong, &do_reset, &information); + + if (kong) + /*{{{ read template (if there is one) */ + { + if (!isatty(fileno(stdin))) /* file piped in */ + { + if (information) + INFO(("# Reading input template\n")); + transputers = lex(stdin, &reference, Pipe, LinkName, Banner); + } + else + { + kong = FALSE; + c4set = FALSE; + } + } + /*}}} */ + else + c4set = FALSE; + + /*{{{ try to open link */ + TheLink = OpenLink(LinkName); + + if (TheLink < 0) + switch (TheLink) + { + case ER_LINK_BAD: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - Transputer no longer available"); + case ER_LINK_CANT: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - No response from transputer"); + case ER_LINK_SOFT: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - Comms software failure"); + case ER_LINK_NODATA: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - Empty data packet received"); + case ER_LINK_NOSYNC: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - Link syncronisation lost"); + case ER_LINK_BUSY: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - Link Hardware already in use"); + case ER_NO_LINK: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - No link interface hardware"); + case ER_LINK_SYNTAX: + AbortExit(PROGRAM_NAME, + "cannot access root transputer - Bad link specifier"); + default: + AbortExit(PROGRAM_NAME, + "cannot access root transputer (result = %d)", TheLink); + }; + /*}}} */ + /*{{{ map network */ + if (information) + INFO(("# Test")); + check(subsys, c4read, c4reset, information, do_reset); + /*}}} */ + if (kong) + /*{{{ try to match network to template */ + { + if (information) + { + INFO(("Matching network to template\n")); + /* + writeresults(root, LinkName, c4read, kong); + writeresults(reference, LinkName, c4read, kong); + */ + } + + same = compare(root, reference); + + if (!transputers) + AbortExit(PROGRAM_NAME, "No Transputers found"); + root = sort(root); + } + /*}}} */ + + if (c4set || c4read) + /*{{{ do C004 stuff */ + { + struct tpstats *p; + struct c4stats *q; + if (c4set) + { + if (information) + INFO(("Setting C004s ")); + for (q = (struct c4stats *) root; q != NULL; + q = (struct c4stats *) q->next) + if ((class(q->tptype) == C4) && (q->extra != NULL)) + { + if (information) + INFO(("%d ", q->tpid)); + setC004(q); + } + if (information) + INFO(("\n")); + while (root->next != NULL) + { + for (p = root; (p->next != NULL) && (p->next->next != NULL); + p = p->next); + if (class(p->tptype) == C4) + { + q = (struct c4stats *) p->next; + free(q); + } else + free(p->next); + p->next = NULL; + } + free(root); + if (information) + INFO(("Re-testing network after C004s set\n")); + + if (do_reset) + check(subsys, c4read, FALSE, information, do_reset); + else + AbortExit(PROGRAM_NAME, + "Unable to reset network due to N option"); + + if (information) + INFO(("Matching network to template\n")); + + same = compare(root, reference); + + if (!transputers) + AbortExit(PROGRAM_NAME, "No Transputers found"); + root = sort(root); + } + if (information) + INFO(("Reading C004 settings\n")); + for (q = (struct c4stats *) root; q != NULL; + q = (struct c4stats *) q->next) + if (class(q->tptype) == C4) + readC004(q); + } + /*}}} */ + if (!c4read && c4set) + c4read = 1; + + writeresults(root, LinkName, c4read, kong); + + CloseLink(TheLink); + /*{{{ display result info and return() */ + switch (same) + { + case -1: + if (information) + INFO(("Input Template will not load onto network\n")); + return (-1); + case 0: + if (information && kong) + INFO(("Network is identical to input template\n")); + return (0); + case 1: + if (information) + INFO(("Network is a superset of input template\n")); + return (0); + } + return (0); + /*}}} */ +} +/*}}} */ diff --git a/minix/commands/inmos/check16.h b/minix/commands/inmos/check16.h new file mode 100644 index 000000000..685e4242c --- /dev/null +++ b/minix/commands/inmos/check16.h @@ -0,0 +1,106 @@ +/* automatically generated code - basename check16 */ + + +struct check16_struct { + unsigned char Code[914]; + char Target[10]; + char Mode[10]; + long CodeSize; + long Offset; + long WorkSpace; + long VectorSpace; + int BytesPerWord; + int TotalSpace; +}; + +struct check16_struct check16_code = { + + { /* code */ + 0x20,0x61,0xBE,0x24, 0xF2,0xD4,0x24,0xF2, 0x51,0xD5,0x24,0xF2, + 0x52,0xD6,0x24,0xF2, 0x53,0xD7,0x24,0xF2, 0x54,0xDE,0x24,0xF2, + 0x55,0xDF,0x24,0xF2, 0x56,0x21,0xD0,0x24, 0xF2,0x57,0x21,0xD1, + 0x21,0x73,0x1E,0xFA, 0xD2,0x72,0x30,0xD0, 0x13,0x70,0x42,0xF7, + 0x13,0x70,0x42,0xF7, 0x1B,0xD8,0x1C,0xD9, 0x1D,0xDA,0x24,0xF2, + 0xDB,0x24,0xF2,0xDC, 0x24,0xF2,0xDD,0x43, 0xD1,0x21,0x2E,0x44, + 0x21,0xFB,0xD0,0x2C, 0x4E,0x62,0x1C,0xFD, 0x21,0x29,0x40,0x6A, + 0x13,0xFD,0x60,0xB7, 0x40,0x11,0x81,0x23, 0xFB,0x11,0x51,0xF1, + 0x1D,0xFA,0xD8,0x14, 0x7B,0x30,0x42,0xF7, 0x74,0x60,0xCF,0x2A, + 0xA3,0x11,0x7B,0x30, 0x41,0xF7,0x11,0xF1, 0xC0,0x26,0xAC,0x7B, + 0x30,0xD3,0x14,0x73, 0x42,0xF7,0x11,0x51, 0x73,0x41,0xF7,0x74, + 0x60,0x8F,0xD4,0x40, 0x11,0x81,0x23,0xFB, 0x74,0xC0,0x23,0xA2, + 0x11,0x51,0xF1,0x2F, 0xCF,0x22,0xA4,0x41, 0xD5,0x43,0xD6,0x75, + 0x21,0x7C,0xF5,0x44, 0x21,0xFF,0xD0,0x70, 0x21,0x17,0xFA,0xD7, + 0x70,0x1D,0xFA,0xD3, 0x77,0x21,0xF2,0x73, 0x21,0xF2,0x15,0x21, + 0x4C,0x22,0xF1,0x21, 0x2F,0xFF,0x05,0x41, 0x11,0x83,0x23,0xFB, + 0x21,0x0F,0x11,0x51, 0xF1,0x1D,0xFA,0xD5, 0x40,0x11,0x83,0x23, + 0xFB,0x75,0x30,0xD3, 0x73,0x60,0x4F,0xFF, 0x73,0x40,0xFE,0x40, + 0xD0,0x14,0x75,0x30, 0x7B,0x30,0x22,0x26, 0x94,0x22,0x0C,0x41, + 0x11,0x83,0xF1,0xF4, 0xAD,0x78,0x30,0xD3, 0x73,0x60,0x4F,0xFF, + 0x73,0x11,0xF1,0xFE, 0x21,0x09,0x11,0xF1, 0xC2,0xA6,0x41,0x11, + 0x81,0x23,0xFB,0x0F, 0x11,0xF1,0xC9,0xA9, 0x24,0xF2,0x78,0x30, + 0x21,0x20,0x41,0xFB, 0x02,0x21,0xF0,0x0C, 0x11,0x81,0xF1,0xD0, + 0x14,0x78,0x30,0x7B, 0x30,0x22,0x22,0x99, 0x6C,0x0F,0x44,0xD1, + 0x2B,0x4F,0x21,0xFB, 0xD0,0x60,0x1C,0xD2, 0x41,0xD3,0x43,0xD4, + 0x10,0x72,0xE1,0x73, 0x72,0xE0,0x4B,0x72, 0x60,0x5C,0xFD,0x72, + 0x62,0x55,0xD2,0x13, 0x21,0x44,0x22,0xF1, 0x10,0xF3,0x75,0x23, + 0x37,0x74,0xF5,0x44, 0x21,0xFF,0xD3,0x24, 0xF2,0xD2,0x42,0xD1, + 0x28,0x4D,0x21,0xFB, 0xD0,0x24,0x47,0x60, 0x11,0xFD,0x60,0xBC, + 0x77,0x79,0x22,0x58, 0xFA,0xD3,0x40,0xD2, 0x73,0x30,0xD1,0x21, + 0x2C,0x42,0x21,0xFB, 0x71,0x21,0x47,0xFB, 0x71,0x77,0x21,0x20, + 0x40,0x21,0xF3,0xFE, 0x12,0x16,0x41,0xF7, 0x72,0xC0,0x21,0xA1, + 0x73,0x30,0xD1,0x71, 0x79,0x22,0x37,0xFF, 0x71,0x77,0x21,0x20, + 0x40,0x21,0xF3,0xFE, 0x0E,0x72,0xC1,0xA9, 0x29,0x4A,0x21,0xFB, + 0x73,0x30,0x42,0xFB, 0x02,0x21,0xF0,0x62, 0x07,0x21,0x73,0x60, + 0x8F,0x21,0x74,0x22, 0x5C,0xFA,0xD7,0x21, 0x72,0x21,0x74,0x23, + 0x52,0xFA,0xD1,0x1F, 0x27,0x9F,0x16,0x71, 0x30,0x42,0xF7,0x76, + 0x64,0x21,0x21,0xC7, 0x21,0xA3,0x40,0xD4, 0x21,0x46,0xD5,0x12, + 0x71,0x30,0x41,0xF7, 0x14,0x49,0x22,0xF1, 0x21,0x11,0x40,0xFE, + 0x0A,0x40,0xD0,0x16, 0x77,0x30,0x71,0x30, 0x21,0x26,0x96,0x62, + 0x05,0x75,0xF3,0x22, 0x14,0xF3,0x24,0xF3, 0x40,0xD1,0x43,0xD2, + 0x71,0x2B,0x15,0xFA, 0x30,0x41,0x24,0xF8, 0x11,0x4C,0x22,0xF1, + 0x24,0xF4,0x40,0xD1, 0x43,0xD2,0x71,0x2B, 0x15,0xFA,0x30,0x41, + 0x40,0x22,0xFF,0xA2, 0x71,0xD3,0x11,0x21, 0x41,0x22,0xF1,0x24, + 0xF5,0x15,0x73,0x2B, 0x15,0xFA,0x30,0x42, 0xF7,0x40,0xD0,0x73, + 0x2B,0x15,0xFA,0x30, 0xD4,0x15,0x2C,0x70, 0x2B,0x11,0xFA,0x30, + 0x74,0x21,0x21,0x99, 0x64,0x08,0x21,0xB2, 0x22,0xF0,0x02,0x00, + 0x00,0x60,0xB7,0x40, 0xD1,0x41,0xD2,0x22, 0xF2,0xD3,0x72,0x23, + 0xAC,0x24,0xFE,0x7A, 0x60,0x32,0x30,0x41, 0x24,0xF8,0x73,0x2F, + 0x2A,0x40,0xF2,0x41, 0x24,0xF7,0x25,0xF1, 0x7A,0x60,0x32,0x30, + 0x41,0x40,0x22,0xFF, 0x73,0x2F,0x2A,0x40, 0xF2,0x41,0x21,0x41, + 0x22,0xFE,0x24,0xF5, 0x71,0x84,0x48,0x21, 0xFF,0x15,0xF2,0x7A, + 0x60,0x32,0x30,0x41, 0xF7,0x71,0x81,0xD1, 0x02,0x40,0xD2,0x63, + 0x01,0x71,0xC3,0x21, 0xAF,0x40,0x15,0x83, 0x23,0xFB,0x7A,0x33, + 0x21,0x20,0x40,0x21, 0xF3,0x15,0x87,0x23, 0xFB,0x7A,0x60,0x38, + 0x30,0xD4,0x74,0x45, 0xFF,0x15,0x83,0x74, 0x45,0xFB,0x28,0x05, + 0x71,0x21,0xC8,0x21, 0xAF,0x40,0x15,0x51, 0x23,0xFB,0x7A,0x33, + 0x21,0x20,0x40,0x21, 0xF3,0x15,0x52,0x23, 0xFB,0x7A,0x60,0x38, + 0x30,0xD4,0x74,0x43, 0xFF,0x15,0x51,0x74, 0x43,0xFB,0x26,0x01, + 0x71,0xC1,0x22,0xAD, 0x15,0x52,0xF1,0xC0, 0x21,0xAB,0x7A,0x60, + 0x38,0x30,0xD4,0x74, 0x42,0xFF,0x44,0x10, 0x23,0xFB,0x7A,0x33, + 0x21,0x20,0x40,0x21, 0xF3,0x10,0x81,0x23, 0xFB,0x10,0x74,0x42, + 0xFB,0x7A,0x52,0x41, 0xFE,0x15,0x7A,0x60, 0x32,0x30,0x41,0xF7, + 0x0F,0x15,0x52,0xF1, 0x2A,0xCA,0xA7,0x2A, 0x4A,0x15,0x85,0xF1, + 0xF4,0xA2,0x40,0xD1, 0x71,0x21,0x4F,0x21, 0xFB,0xF2,0xF1,0x15, + 0x23,0xFB,0x7A,0x33, 0x21,0x20,0x40,0x21, 0xF3,0x15,0x81,0x23, + 0xFB,0x7A,0x60,0x38, 0x30,0xD4,0x74,0x42, 0xFF,0x15,0x74,0x42, + 0xFB,0xB9,0x22,0xF0, 0x00,0x01,0x02,0x00, 0x03,0x00,0x17,0xB1, + 0xD1,0x24,0xF2,0x21, 0xFC,0x24,0xF2,0x21, 0xF8,0xF0,0x60,0x5C, + 0x2A,0x2A,0x2A,0x4A, 0xFF,0x21,0x2F,0xFF, 0x02,0x60,0xB1,0x41, + 0x21,0x73,0xF4,0xA6, 0x21,0x71,0x21,0x72, 0x30,0xFF,0x21,0x72, + 0x30,0x40,0xF9,0x23, 0xA6,0x21,0x72,0x30, 0x21,0x4C,0xF9,0x21, + 0xA6,0x11,0x21,0x70, 0x21,0x4C,0xF7,0x11, 0x21,0x71,0x21,0x4C, + 0xFB,0x21,0x72,0x30, 0x61,0x84,0x21,0x72, 0xE0,0x21,0x06,0x21, + 0x72,0x30,0xD0,0x11, 0x21,0x70,0x70,0xF7, 0x21,0x72,0x30,0xD0, + 0x11,0x21,0x71,0x70, 0xFB,0x40,0x21,0x72, 0xE0,0x63,0x03,0xBF, + 0x22,0xF0 }, + + "TA", /* target */ + "Undefined", /* mode */ + 914, /* code size */ + 1, /* offset */ + 213, /* workspace */ + 0, /* vectorspace */ + 2, /* bytes per word */ + 1340 /* total code requirement not including parameter space */ + +}; /* end of generated code */ diff --git a/minix/commands/inmos/check32.h b/minix/commands/inmos/check32.h new file mode 100644 index 000000000..d896483df --- /dev/null +++ b/minix/commands/inmos/check32.h @@ -0,0 +1,111 @@ +/* automatically generated code - basename check32 */ + + +struct check32_struct { + unsigned char Code[976]; + char Target[10]; + char Mode[10]; + long CodeSize; + long Offset; + long WorkSpace; + long VectorSpace; + int BytesPerWord; + int TotalSpace; +}; + +struct check32_struct check32_code = { + + { /* code */ + 0x20,0x20,0x20,0x61, 0xBD,0x22,0x26,0x4E, 0x21,0xFB,0xD4,0x24, + 0xF2,0xD5,0x24,0xF2, 0x51,0xD6,0x24,0xF2, 0x52,0xD7,0x24,0xF2, + 0x53,0xD8,0x24,0xF2, 0x54,0xDF,0x24,0xF2, 0x55,0x21,0xD0,0x24, + 0xF2,0x56,0x21,0xD1, 0x24,0xF2,0x57,0x21, 0xD2,0x21,0x74,0x1F, + 0xFA,0xD2,0x72,0x30, 0xD0,0x13,0x70,0x42, 0xF7,0x13,0x70,0x42, + 0xF7,0x1C,0xD9,0x1D, 0xDA,0x1E,0xDB,0x24, 0xF2,0xDC,0x24,0xF2, + 0xDD,0x24,0xF2,0xDE, 0x43,0xD1,0x22,0x21, 0x4D,0x21,0xFB,0xD0, + 0x2E,0x48,0x61,0x12, 0xFD,0x21,0x2B,0x4B, 0x69,0x1D,0xFD,0x60, + 0xB7,0x40,0x11,0x81, 0x23,0xFB,0x11,0x82, 0xF1,0x1E,0xFA,0xD8, + 0x15,0x7B,0x30,0x42, 0xF7,0x75,0x2F,0x2F, 0x2F,0x4F,0x24,0xF6, + 0x28,0x20,0x20,0x40, 0x23,0xFA,0xD4,0x74, 0x60,0xCF,0x2A,0xAF, + 0x11,0x7B,0x30,0x41, 0xF7,0x11,0xF1,0xC0, 0x27,0xA8,0x7B,0x30, + 0xD2,0x15,0x72,0x42, 0xF7,0x11,0x82,0x72, 0x41,0xF7,0x75,0x2F, + 0x2F,0x2F,0x4F,0x24, 0xF6,0x28,0x20,0x20, 0x40,0x23,0xFA,0x60, + 0x8F,0xD4,0x40,0x11, 0x81,0x23,0xFB,0x74, 0xC0,0x23,0xA2,0x11, + 0x82,0xF1,0x2F,0xCF, 0x22,0xA4,0x41,0xD2, 0x43,0xD3,0x72,0x21, + 0x7D,0xF5,0x44,0x21, 0xFF,0xD0,0x70,0x21, 0x18,0xFA,0xD7,0x70, + 0x1E,0xFA,0xD6,0x77, 0x21,0xF2,0x76,0x21, 0xF2,0x12,0x21,0x4C, + 0x22,0xF1,0x21,0x2F, 0xFF,0x05,0x41,0x11, 0x83,0x23,0xFB,0x21, + 0x0F,0x11,0x82,0xF1, 0x1E,0xFA,0xD3,0x40, 0x11,0x83,0x23,0xFB, + 0x73,0x30,0xD2,0x7D, 0x72,0x42,0xFB,0x72, 0x40,0xFE,0x40,0xD0, + 0x14,0x73,0x30,0x7B, 0x30,0x22,0x28,0x94, 0x22,0x0C,0x41,0x11, + 0x83,0xF1,0xF4,0xAD, 0x78,0x30,0xD2,0x7D, 0x72,0x42,0xFB,0x72, + 0x11,0xF1,0xFE,0x21, 0x09,0x11,0xF1,0xC2, 0xA6,0x41,0x11,0x81, + 0x23,0xFB,0x0F,0x11, 0xF1,0xC9,0xA9,0x24, 0xF2,0x78,0x30,0x21, + 0x20,0x41,0xFB,0x02, 0x21,0xF0,0x0C,0x11, 0x81,0xF1,0xD0,0x14, + 0x78,0x30,0x7B,0x30, 0x22,0x24,0x99,0x6D, 0x05,0x44,0xD1,0x2D, + 0x40,0x21,0xFB,0xD0, 0x60,0x1C,0xD2,0x41, 0xD3,0x43,0xD4,0x10, + 0x72,0xE1,0x73,0x72, 0xE0,0x4B,0x72,0x60, 0x5C,0xFD,0x72,0x62, + 0x5C,0xD2,0x13,0x21, 0x44,0x22,0xF1,0x10, 0xF3,0x75,0x23,0x32, + 0x74,0xF5,0x44,0x21, 0xFF,0xD3,0x24,0xF2, 0xD2,0x42,0xD1,0x29, + 0x4E,0x21,0xFB,0xD0, 0x24,0x48,0x60,0x12, 0xFD,0x60,0xBC,0x77, + 0x79,0x22,0x53,0xFA, 0xD3,0x40,0xD2,0x73, 0x30,0xD1,0x21,0x2E, + 0x41,0x21,0xFB,0x71, 0x21,0x47,0xFB,0x71, 0x77,0x21,0x20,0x40, + 0x21,0xF3,0xFE,0x12, 0x16,0x41,0xF7,0x72, 0xC0,0x21,0xA2,0x73, + 0x30,0xD1,0x79,0x22, 0x51,0x71,0x42,0xFB, 0x71,0x77,0x21,0x20, + 0x40,0x21,0xF3,0xFE, 0x0E,0x72,0xC1,0xA9, 0x2B,0x48,0x21,0xFB, + 0x73,0x30,0x42,0xFB, 0x02,0x21,0xF0,0x62, 0x06,0x21,0x72,0x60, + 0x8F,0x21,0x73,0x22, 0x57,0xFA,0xD6,0x21, 0x71,0x21,0x73,0x22, + 0x5D,0xFA,0xD1,0x1E, 0x2A,0x95,0x40,0xD5, 0x15,0x71,0x30,0x41, + 0xF7,0x75,0xD4,0x15, 0x71,0x30,0x41,0xF7, 0x75,0x48,0x24,0xF1, + 0x74,0xF5,0xD4,0x74, 0x2B,0x21,0x21,0xC7, 0x21,0xA3,0x40,0xD2, + 0x21,0x46,0xD3,0x10, 0x71,0x30,0x41,0xF7, 0x12,0x49,0x22,0xF1, + 0x21,0x10,0x40,0xFE, 0x0A,0x40,0xD0,0x14, 0x76,0x30,0x71,0x30, + 0x21,0x27,0x95,0x63, 0x05,0x75,0xF3,0x21, 0x1E,0xF3,0x24,0xF3, + 0x40,0xD1,0x43,0xD2, 0x71,0x29,0x1C,0xFA, 0x30,0x41,0x24,0xF8, + 0x11,0x4C,0x22,0xF1, 0x24,0xF4,0x40,0xD1, 0x43,0xD2,0x71,0x29, + 0x1C,0xFA,0x30,0x41, 0x40,0x22,0xFF,0xA2, 0x71,0xD3,0x11,0x21, + 0x41,0x22,0xF1,0x24, 0xF5,0x16,0x73,0x29, 0x1C,0xFA,0x30,0x42, + 0xF7,0x76,0x2F,0x2F, 0x2F,0x4F,0x24,0xF6, 0x28,0x20,0x20,0x40, + 0x23,0xFA,0xD5,0x40, 0xD0,0x73,0x29,0x1C, 0xFA,0x30,0xD4,0x15, + 0x2A,0x77,0x29,0x18, 0xFA,0x30,0x74,0x21, 0x21,0x9A,0x65,0x0A, + 0x21,0xB3,0x22,0xF0, 0x02,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, + 0x00,0x00,0x00,0x60, 0xB9,0x2D,0x4F,0x21, 0xFB,0xD6,0x40,0xD1, + 0x41,0xD4,0x22,0xF2, 0xD5,0x74,0x23,0xAC, 0x24,0xFE,0x78,0x60, + 0x33,0x30,0x41,0x24, 0xF8,0x75,0x2F,0x2A, 0x40,0xF2,0x41,0x24, + 0xF7,0x25,0xF1,0x78, 0x60,0x33,0x30,0x41, 0x40,0x22,0xFF,0x75, + 0x2F,0x2A,0x40,0xF2, 0x41,0x21,0x41,0x22, 0xFE,0x24,0xF5,0x71, + 0x84,0x48,0x21,0xFF, 0x12,0xF2,0x78,0x60, 0x33,0x30,0x41,0xF7, + 0x71,0x81,0xD1,0x02, 0x40,0xD4,0x63,0x01, 0x71,0xC3,0x22,0xA1, + 0x40,0x12,0x83,0x23, 0xFB,0x78,0x33,0x21, 0x20,0x40,0x21,0xF3, + 0x12,0x87,0x23,0xFB, 0x78,0x60,0x38,0x30, 0xD0,0x76,0x52,0x70, + 0x42,0xFB,0x12,0x83, 0x70,0x45,0xFB,0x26, 0x08,0x71,0x21,0xC8, + 0x22,0xA1,0x40,0x12, 0x82,0x23,0xFB,0x78, 0x33,0x21,0x20,0x40, + 0x21,0xF3,0x12,0x51, 0x23,0xFB,0x78,0x60, 0x38,0x30,0xD0,0x76, + 0x51,0x70,0x42,0xFB, 0x12,0x82,0x70,0x43, 0xFB,0x24,0x02,0x71, + 0xC1,0xAE,0x60,0x0E, 0x78,0x52,0x41,0xFE, 0x12,0x78,0x60,0x33, + 0x30,0x41,0xF7,0x0F, 0x12,0x51,0xF1,0x2A, 0xCA,0xA7,0x2A,0x4A, + 0x12,0x85,0xF1,0xF4, 0xA2,0x40,0xD1,0x71, 0x22,0x40,0x21,0xFB, + 0xF2,0xF1,0x12,0x23, 0xFB,0x78,0x33,0x21, 0x20,0x40,0x21,0xF3, + 0x12,0x81,0x23,0xFB, 0x78,0x60,0x38,0x30, 0xD0,0x76,0x70,0x42, + 0xFB,0x12,0x70,0x42, 0xFB,0xB7,0x22,0xF0, 0x00,0x01,0x02,0x00, + 0x03,0x00,0x00,0x00, 0x02,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, + 0x05,0x00,0x00,0x00, 0x17,0xB1,0xD1,0x24, 0xF2,0x21,0xFC,0x24, + 0xF2,0x21,0xF8,0xF0, 0x60,0x5C,0x2A,0x2A, 0x2A,0x4A,0xFF,0x21, + 0x2F,0xFF,0x02,0x00, 0x60,0xB7,0x41,0x7D, 0xF4,0xAD,0x7C,0x30, + 0x28,0x20,0x20,0x40, 0x25,0xF6,0xD0,0x10, 0x7B,0x42,0xFB,0x7C, + 0x30,0x40,0xF9,0x22, 0xAC,0x7C,0x30,0x22, 0x40,0xF9,0x21,0xA2, + 0x11,0x7A,0x22,0x40, 0xF7,0x11,0x7B,0x22, 0x40,0xFB,0x7C,0x30, + 0x61,0x80,0x7C,0xE0, 0x21,0x01,0x7C,0x30, 0xD0,0x11,0x7A,0x70, + 0xF7,0x7C,0x30,0xD0, 0x11,0x7B,0x70,0xFB, 0x40,0x7C,0xE0,0x63, + 0x0E,0xB9,0x22,0xF0 }, + + "TA", /* target */ + "Undefined", /* mode */ + 976, /* code size */ + 3, /* offset */ + 182, /* workspace */ + 0, /* vectorspace */ + 4, /* bytes per word */ + 1704 /* total code requirement not including parameter space */ + +}; /* end of generated code */ diff --git a/minix/commands/inmos/checklib.h b/minix/commands/inmos/checklib.h new file mode 100644 index 000000000..804a8831b --- /dev/null +++ b/minix/commands/inmos/checklib.h @@ -0,0 +1,47 @@ +/* + * Copyright andyr@wizzy.com (Andy Rabagliati) 30 August 1994 + * + * This code may be freely used, provided credits remain intact + * + */ + +#define tint_from_link tint32_from_link +#define UNKNOWN -140 +#define HALF -130 +#define DISK -120 +#define HOST_TAG -110 +#define TXXX -100 +#define BAD16 -90 +#define BAD32 -80 +#define T16 -70 +#define T32 -60 +#define C4 -50 +#define M212 -40 +#define T_212 -30 +#define T_414 -20 +#define T414A -20 +#define T414B -19 +#define T_800 -10 +#define T800C -8 +#define T800D -7 +#define T_425 0 +#define T_805 10 +#define T_801 20 +#define T_225 40 +#define T_400 50 +#define qTXXX ((unsigned char)0) +#define qC4 ((unsigned char)1) +#define qT16 ((unsigned char)2) +#define qT32 ((unsigned char)3) +#define qHALF ((unsigned char)4) +#define qM212 ((unsigned char)5) +#define qDISK ((unsigned char)6) +#define TAG_SETPATH ((unsigned char)0) +#define TAG_LSPEED ((unsigned char)9) +#define TAG_BOOT ((unsigned char)2) +#define TAG_TEST16 ((unsigned char)3) +#define TAG_TEST32 ((unsigned char)4) +#define TAG_HALT ((unsigned char)255) +#define ESCAPE ((short)-1) + + diff --git a/minix/commands/inmos/cklib.c b/minix/commands/inmos/cklib.c new file mode 100644 index 000000000..c9b6c02d4 --- /dev/null +++ b/minix/commands/inmos/cklib.c @@ -0,0 +1,864 @@ + +/* + * -------------------------------------------------- + * + * cklib.c -- check library routines + * + * Copyright andyr@wizzy.com (Andy Rabagliati) 30 August 1994 + * + * This code may be freely used, provided credits remain intact + * + * -------------------------------------------------- + */ + +#define CocoPops FALSE +#define VerboseSwitch FALSE + +#define DEBUG(x) { if (CocoPops) { fputs("(", stderr); fprintf x; fputs(")", stderr); fputc((VerboseSwitch ? '\n' : ' '), stderr); fflush(stderr); } } +#define INFO(x) { if (VerboseSwitch) printf x ; fflush(stderr); } + + +/*{{{ include & statics */ +#include +#include +#include +#include +#ifndef atoi +#include +#endif +#include + +#include "linkio.h" +#include "inmos.h" +#include "checklib.h" +#include "cklib.h" + +#define TIMEOUT 40 +#define SEGSIZE 511 +#define MAXINT ((unsigned)-1) +#define EMPTY ' ' + +#define SWITCHAR '-' + +static char *TPIDS[] = {"???", "?1/2?", "DISK", "HOST", "T???", + "?T16", "?T32", "T16", "T32", "C004", "M212", "T2", "T414", "T800", + "T425", "T805", "T801", "", "T225", "T400"}; +static char LETTER[32] = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; +/*}}} */ +/*{{{ externs */ +extern char *PROGRAM_NAME; +/*}}} */ +/*{{{ int bpw(int tptype) */ +int bpw(int tptype) +{ + switch (class(tptype)) { + case T16: + case M212: + case T_212: + case T_225: + return (2); + case T32: + case T_414: /* same as case T414A: */ + case T414B: + case T_800: + case T800C: + case T800D: + case T_425: + case T_805: + case T_801: + case T_400: + return (4); + default: + return (0); + } +} +/*}}} */ +/*{{{ void AbortExit(char *String,...) */ +void AbortExit(char *String,...) +{ + va_list ArgPtr; + char *p; + int AnInt; + char *AString; + char *ControlString; + + fprintf(stderr, "\nError - %s - ", String); + va_start(ArgPtr, String); + + ControlString = va_arg(ArgPtr, char *); + for (p = ControlString; *p; p++) + if (*p != '%') + { + putc(*p, stderr); + continue; + } else + { + switch (*++p) + { + case 'd': + AnInt = va_arg(ArgPtr, int); + fprintf(stderr, "%d", AnInt); + break; + case 's': + AString = va_arg(ArgPtr, char *); + fprintf(stderr, "%s", AString); + break; + default: + putc(*p, stderr); + break; + } + } + + va_end(ArgPtr); + + fprintf(stderr, ".\n\007"); + + exit(1); +} +/*}}} */ +/*{{{ void *Malloc(int size) */ +void *Malloc(int size) +{ + void *ptr; + + ptr = (void *) calloc(1, size); + + if (ptr == NULL) + AbortExit(PROGRAM_NAME, "Ran out of memory"); + + return(ptr); +} +/*}}} */ + +/* + * -------------------------------------------------- + * + * routines to lex check output + * + * -------------------------------------------------- + */ + +/*{{{ void tidy(struct tpstats * root) */ +void tidy(struct tpstats * root) +{ + struct tpstats *p, *next; + int i, j, progress = TRUE, tidied = FALSE; + while (!tidied) + { + while (progress && (!tidied)) + { + tidied = TRUE; + progress = FALSE; + for (p = root; p != NULL; p = p->next) + if (p->routelen == (-1)) + { /* not tidied yet */ + if (class(p->tptype) != C4) + { + for (i = 0; i < 4; i++) + if ((p->linkno[i] >= 0) && (p->linkno[i] <= 3)) + { /* valid link no */ + for (next = root; (next != NULL) && + (next->tpid != p->tpno[i]); + next = next->next); + if (next != NULL) + p->links[i] = next; + else + AbortExit("lex", "unable to find Transputer %d", p->tpno[i]); + } else + if ((class(p->linkno[i]) == C4) && (p->links[i] != NULL)) + { + next = find(root, p->tpno[i]); + if (next == NULL) + AbortExit("lex", "unable to find C004 %d", p->tpno[i]); + p->links[i] = next; + next->parent = p; + next->route = i; + } else + p->links[i] = NULL; + p->parent = p->links[p->bootlink]; + if (p->parent == NULL) + { + if ((class(p->tptype) != C4) && (p->linkno[p->bootlink] == HOST_TAG)) + p->routelen = 0; + else + tidied = FALSE; + } else + { + if (p->parent->routelen >= 0) + { + /* parent tidied already */ + p->routelen = p->parent->routelen + 1; + if (class(p->tptype) != C4) + { + for (j = 0; (j < 4) && + ((p->parent->linkno[j] != p->bootlink) || + (p->parent->links[j] != p)); + j++); + if (j < 4) + { + p->route = j; + progress = TRUE; + } else + tidied = FALSE; + } + } else + tidied = FALSE; + } + } else + if (p->parent == NULL) + tidied = FALSE; + else + p->routelen = p->parent->routelen + 1; + } + } + if (!tidied) + { + progress = TRUE; + for (p = root; progress && p != NULL; p = p->next) + { + progress = FALSE; + if ((class(p->tptype) == C4) && p->parent == NULL) + AbortExit("lex", "cannot find parent of C004 %d", p->tpid); + else + if (p->routelen == (-1)) + { + /* not tidied yet */ + for (j = 0; j < 4; j++) + if ((p->links[j] != NULL) && + (p->links[j]->routelen >= 0)) + { + fprintf(stderr, "lex - Warning - Processor %d boot link changed from %d to %d\n", + p->tpid, p->bootlink, j); + p->bootlink = j; + p->route = p->linkno[j]; + p->parent = p->links[p->bootlink]; + progress = TRUE; + } + } + } + } + if (!tidied && !progress) + { + for (p = root; p->routelen != (-1); p = p->next); + AbortExit("lex", "Unable to find path to part %d", p->tpid); + } + } +} +/*}}} */ +/*{{{ int readtp(char *tputer) */ +int readtp(char *tputer) +{ + int i, type = 0; + char revision; + tputer[5] = '\0'; + for (i = 4; tputer[i] == ' '; i--) + tputer[i] = '\0'; + for (i = 0; (i < NUMTPIDS + TPOFFSET) && (strcmp(TPIDS[i], tputer)); i++); + if (i < NUMTPIDS + TPOFFSET)/* found it there */ + type = (i - TPOFFSET) * 10; + else + { + revision = toupper((int) tputer[4]); + tputer[4] = (char) 0; + for (i = 0; + (i < NUMTPIDS + TPOFFSET) && (strcmp(TPIDS[i], tputer)); i++); + if (i < NUMTPIDS + TPOFFSET) + { /* found it there */ + type = (i - TPOFFSET) * 10; + if ((revision >= 'A') && (revision <= 'J')) + type += revision - 'A'; + } + } + return (type); +} +/*}}} */ +/*{{{ int lex(....) */ +int lex(FILE * stream, struct tpstats ** root, + char *Pipe, char *LinkName, char *Banner) +{ + struct tpstats *curr, *next; + char line[LINESIZE]; + int i,j; + curr = *root = NULL; + *LinkName = '\0'; + while (fgets(line, LINESIZE, stream) != NULL) { + for (i = 0; (line[i]) && (line[i] != '\n'); i++); + line[i] = '\0'; + if (line[0] == '#') + printf("#%s\n", line); + else if (!strncmp(line, "Using ", 6)) { + strcpy(Pipe, line); + for (i=6; line[i] == ' '; i++); + for (j=0; line[i] != ' '; i++, j++) + LinkName[j] = line[i]; + LinkName[j] = '\0'; + fgets(Banner, LINESIZE, stream); /* next line, regardless */ + for (i = 0; (Banner[i]) && (Banner[i] != '\n'); i++); + Banner[i] = '\0'; + { + char *c; + c = strstr(Banner, " by Andy"); + c && (*c = '\0'); + } + + } else { + int procspeed, bootlink, tpid; + char bootspeed[6]; + char tputer[6]; + char linkinfo[4][10]; + char delimiter, c; + i = sscanf(line, "%d %5c-%2d %s %d [ %s %s %s %s ]", + &tpid, tputer, &procspeed, + bootspeed, &bootlink, + linkinfo[0], linkinfo[1], linkinfo[2], linkinfo[3]); + if (i == 9) + { + next = (struct tpstats *) Malloc(sizeof(struct tpstats)); + if (curr != NULL) + curr->next = next; + else + *root = next; + curr = next; + strcpy(curr->info, line); + curr->next = NULL; + curr->extra = NULL; + curr->parent = NULL; + curr->routelen = -1; + curr->tpid = tpid; + curr->procspeed = procspeed; + curr->bootlink = bootlink; + if (sscanf(bootspeed, "%fM", &curr->linkspeed)) + curr->linkspeed = curr->linkspeed * 1.0E6; + else if (sscanf(bootspeed, "%fk", &curr->linkspeed)) + curr->linkspeed = curr->linkspeed * 1.0E3; + else curr->linkspeed = 0.0; + tputer[5] = '\0'; + curr->tptype = readtp(tputer); + for (i = 0; i < 4; i++) + { + if ((linkinfo[i][0] == '.') || (linkinfo[i][0] == '?')) + curr->linkno[i] = TXXX; + else + { + int tpno; + if (sscanf(linkinfo[i], "%d:%c", &tpno, &c) == 2) + { + curr->tpno[i] = tpno; + if (c == 'C') + curr->linkno[i] = C4; + else + curr->linkno[i] = c - '0'; + curr->links[i] = curr; /* for benefit of C004 */ + } else + { + curr->linkno[i] = readtp(linkinfo[i]); + curr->links[i] = NULL; /* for benefit of C004 */ + } + } + } + } else if (i > 0) + { + struct c4stats *q; + int from = 0, to; + char bracket, *c; + i = sscanf(line, "%d %s", &tpid, tputer); + if ((i == 2) && (tputer[0] == 'C')) + { + q = (struct c4stats *) Malloc(sizeof(struct c4stats)); + if (curr != NULL) + curr->next = (struct tpstats *) q; + else + *root = (struct tpstats *) q; + curr = curr->next; + strcpy(q->info, line); + q->next = NULL; + q->extra = NULL; + q->parent = NULL; + q->routelen = -1; + q->tpid = tpid; + q->tptype = readtp(tputer); + if (class(q->tptype) != C4) + AbortExit("lex", "%s ???", line); + strcpy(q->config, " "); + for (i = 0; (line[i] != '[') && (line[i] != '(') && line[i]; i++); + bracket = line[i++]; + switch (bracket) + { + case '[': + for (to = 0; (line[i] != 0) && (line[i] != ']'); i++) + switch (line[i]) + { + case '-': + to++; + case ' ': + break; + default: + for (from = 0; LETTER[from] != line[i]; from++); + q->config[to] = (char) from; + to++; + break; + } + break; + case '(': + c = &line[i]; + while (*c!=')' && (*c)) + { + while (*c && ((*c<'0') || (*c>'9'))) + c++; + if (*c) + from = atoi(c); + while (*c && (*c!='-') && (*c!='>')) + c++; + delimiter = *c; + while (*c && ((*c<'0') || (*c>'9'))) + c++; + if (*c) + to = atoi(c); + while (*c && (*c>='0') && (*c<='9')) + c++; + if (!*c) + continue; + while (*c && ((*c<'0') || (*c>'9'))) + c++; + switch (delimiter) + { + case '-': + if (q->config[from] == EMPTY) + q->config[from] = (char) to; + else + AbortExit("lex", "C004 %d: link %d connected to %d and %d", + tpid, from, to, q->config[from]); + if ((q->config[to] == EMPTY) || (to == from)) + q->config[to] = (char) from; + else + AbortExit("lex", "C004 %d: link %d connected to %d and %d", + tpid, to, from, q->config[to]); + break; + case '>': + if (q->config[from] == EMPTY) + q->config[from] = (char) to; + else + AbortExit("lex", "C004 %d: link %d connected twice", + tpid, from); + break; + } + } + } + } + } else + fprintf(stderr, "%s ???\n", line); + } + } + if (*root != NULL) { + tidy(*root); + for (curr = (*root), i = 0; curr != NULL; curr = curr->next) + i++; + return (i); + } else + return (0); +} +/*}}} */ +/*{{{ struct tpstats *find(struct tpstats * root, int id) */ +struct tpstats *find(struct tpstats * root, int id) +{ + struct tpstats *p; + for (p = root; (p != NULL) && (p->tpid != id); p = p->next); + return (p); +} +/*}}} */ +/*{{{ char *tptostr(int tp) */ +char *tptostr(int tp) +{ + static char buffer[8]; + if ((tp / 10) < NUMTPIDS) + strcpy(buffer, (TPIDS[(class(tp) / 10) + TPOFFSET])); + else + sprintf(buffer, "T#%-2d", tp / 10); + if (tp >= (-50)) + { + buffer[4] = (char) 'a' + (tp - class(tp)); + buffer[5] = (char) 0; + } + return (buffer); +} +/*}}} */ +/*{{{ int writeup(struct tpstats * p, int c4read) */ +int writeup(struct tpstats * p, int c4read, int comment) +{ + int i; + int errfound = FALSE; + + if (p != NULL) + if (class(p->tptype) != C4) + { + if (comment) + printf("#%3d %-5s-%2d ", p->tpid, tptostr(p->tptype), p->procspeed); + else + printf("%4d %-5s-%2d ", p->tpid, tptostr(p->tptype), p->procspeed); + if (p->linkspeed > 1.0E6) + printf("%3.1fM", p->linkspeed/1.0E6); + else + printf("%3.0fk", p->linkspeed/1.0E3); + if (p->bootlink < 4) + printf("%2d [", p->bootlink); + else + printf(" - ["); + for (i = 0; i < 4; i++) + { + if (p->links[i] == NULL) + switch (class(p->linkno[i])) + { + case UNKNOWN: + case HALF: + case DISK: + case HOST_TAG: + case BAD16: + case BAD32: + case T16: + case T32: + case T414A: + printf("%7s", tptostr(p->linkno[i])); + break; + case C4: + printf(" C004"); + break; + default: + if (p->links[i] == NULL) + printf(" ..."); + break; + } + else + switch (p->linkno[i]) + { + case 0: + case 1: + case 2: + case 3: + printf(" %4d:%1d", p->links[i]->tpid, p->linkno[i]); + break; + case C4: + case C4 + 1: + if (c4read) + printf(" %4d:C", p->links[i]->tpid); + else + printf(" C004"); + break; + default: + printf(" %4d:?", p->links[i]->tpid); + break; + } + } + printf(" ]%s", p->info); + for (i = 0; i < 4; i++) + if (p->links[i] == NULL) + switch (p->linkno[i]) + { + case BAD16: + case BAD32: + break; + case T16: + case T32: + errfound = TRUE; + break; + case T414A: + break; + } + } + return (errfound); +} +/*}}} */ +/*{{{ void writeC4(struct c4stats * q) */ +void writeC4(struct c4stats * q) +{ + char inputs[32]; + int i, error = FALSE; + for (i = 0; i < 32; i++) + inputs[i] = EMPTY; + for (i = 0; i < 32; i++) + if (q->config[i] != EMPTY) + { + int j; + j = q->config[i]; + if (inputs[j] != EMPTY) + error = TRUE; + } + printf("%4d %-5s [", q->tpid, tptostr(q->tptype)); + for (i = 0; i < 32; i++) + { + int j = q->config[i]; + if (!(i % 8)) + putchar(' '); + if (j == EMPTY) + putchar('-'); + else + putchar(j>9 ? j+'A'-10 : j+'0'); + } + + if (error) + printf(" ]?"); + else + printf(" ]"); +} +/*}}} */ +/*{{{ void writeCl(struct c4stats * q) */ +void writeCl(struct c4stats * q) +{ + char inputs[32]; + int i, error = FALSE; + for (i = 0; i < 32; i++) + inputs[i] = EMPTY; + for (i = 0; i < 32; i++) + if (q->config[i] != EMPTY) + { + int j; + j = q->config[i]; + if (inputs[j] != EMPTY) + error = TRUE; + } + printf("%4d %-5s (", q->tpid, tptostr(q->tptype)); + for (i = 0; i < 32; i++) + { + int j; + if (q->config[i] != EMPTY) + { + j = q->config[i]; + if (q->config[j] == (char) i) + { + if (j >= i) + printf("%d-%d ", i, j); + } else + printf("%d>%d ", i, j); + } + } + + if (error) + printf(")?"); + else + printf(")"); +} +/*}}} */ + +/* + * -------------------------------------------------- + * + * fns to talk to check network + * + * -------------------------------------------------- + */ + +/*{{{ int readbytes(....) */ +int readbytes(LINK TheLink, + unsigned char *string, unsigned int maxlength) +{ + unsigned int bytes_to_go = maxlength; + unsigned char *read_point = string; + int bytesread = 0; + int count = 10; + + while ((bytes_to_go > 0) && (count > 0)) + { + bytesread = ReadLink(TheLink, read_point, bytes_to_go, TIMEOUT); + DEBUG((stderr, "readbytes(bytesread = %d)", bytesread)); + bytes_to_go -= bytesread; + read_point += bytesread; + count--; + } + + if (bytesread < 0) + { + fprintf(stderr, "Read from link failed - result = %d\n", bytesread); + bytesread = 0; + } else { + if (count == 0) + fprintf(stderr, "Read from link failed (Timeout)\n"); + else + bytesread = maxlength - bytes_to_go; + } + + DEBUG((stderr, "readbytes(bytesread = %d)", bytesread)); + if (CocoPops) + { + int i; + + fputs("(", stderr); + + for (i = 0; i < bytesread; i++) + fprintf (stderr, "%0X ", (int) *(string + i) ); + + fputs(")", stderr); + fputc('\n', stderr); + fflush(stderr); + } + + return (bytesread); +} +/*}}} */ +/*{{{ int getiserver(....) */ +int getiserver(LINK TheLink, unsigned int *length, + unsigned char *string, unsigned int maxlength) +{ + if (readbytes(TheLink, string, 2) == 2) + { + *length = (string[1] << 8) + string[0]; + if + ((*length <= maxlength) && (length) && + (readbytes(TheLink, string, *length) == *length)) + return (TRUE); + else + if (length) + return (FALSE); + else /* length of zero */ + return (TRUE); + } else + return (FALSE); +} +/*}}} */ +/*{{{ int sendiserver(....) */ +int sendiserver(LINK TheLink, unsigned int length, unsigned char *buffer) +{ + unsigned char int16[2]; + + int16[0] = (unsigned char) (length & 0xFF); + int16[1] = (unsigned char) (length >> 8); + + if ((WriteLink(TheLink, int16, 2, TIMEOUT) == 2) && length) + { + unsigned int start=0, written=0; /* , writing=64; */ + do { + /* if ((length-written) < writing) + writing = length-written; */ + start += written; + written = WriteLink(TheLink, &buffer[start], + (length-written), TIMEOUT); + } while (written && ((start+written) < length)); + if ((start+written) == length) + return (TRUE); + else + return (FALSE); + } + else + return (FALSE); +} +/*}}} */ +/*{{{ void setroute(LINK TheLink, struct tpstats * p, int lastlink) */ +void setroute(LINK TheLink, struct tpstats * p, int lastlink) +{ + unsigned char *route; + struct tpstats *q; + unsigned int i; + static unsigned char ROUTE[] = {0xFF, 0xFF, TAG_SETPATH}; + if (p != NULL) + { + route = (unsigned char *) Malloc((p->routelen) + 1); + if (route == NULL) + AbortExit("loader", "out of memory in setroute, route length %d", + (p->routelen) + 1); + route[p->routelen] = (unsigned char) lastlink; + for (i = p->routelen, q = p; + (i > 0) && (q != NULL); + i--, q = q->parent) + route[i - 1] = (unsigned char) q->route; + if ((i != 0) || (q->parent != NULL)) + AbortExit("loader", "Error finding route thread, processor %d", p->tpid); + if ((WriteLink(TheLink, ROUTE, sizeof(ROUTE), TIMEOUT) == + sizeof(ROUTE)) && sendiserver(TheLink, (p->routelen) + 1, route)); + else + { + if (lastlink == (-1)) + AbortExit("loader", "Timed out stopping processor %d", p->tpid); + else + if (lastlink < 4) + AbortExit("loader", "Timed out setting route to processor %d", + p->links[lastlink]->tpid); + else + if (lastlink == 4) + AbortExit("loader", "Timed out talking to application on processor %d", + p->tpid); + } + free(route); + } +} /* setroute */ +/*}}} */ +/*{{{ void tpboot(LINK TheLink, struct tpstats * p) */ +void tpboot(LINK TheLink, struct tpstats * p) +{ + static unsigned char TPBOOT[] = {0xFF, 0xFF, TAG_BOOT}; + if (p->parent != NULL) + { + setroute(TheLink, p->parent, p->route); + if (WriteLink(TheLink, TPBOOT, 3, TIMEOUT) == 3); + else + AbortExit("loader", "Timed out preparing to boot processor %d", + p->tpid); + } +} /* TPboot */ +/*}}} */ +/*{{{ int load(....) */ +int load(LINK TheLink, struct tpstats * p, + long CodeSize, + long Offset, + long WorkSpace, + long VectorSpace, + int BytesPerWord, + unsigned char *Code) +{ +#include "boot.h" + long count, i, length; + int flag, j, k; + unsigned char params[16]; + tpboot(TheLink, p); + length = CodeSize; + if (p->parent != NULL) + flag = sendiserver(TheLink, sizeof(boot), boot); + else + flag = WriteLink(TheLink, boot, + sizeof(boot), TIMEOUT) == sizeof(boot); + if (flag) + { + j = 0; + for (k = 0; k < BytesPerWord; k++) + { + params[j++] = (unsigned char) (WorkSpace & 0xFF); + WorkSpace = WorkSpace >> 8; + } + for (k = 0; k < BytesPerWord; k++) + { + params[j++] = (unsigned char) (VectorSpace & 0xFF); + VectorSpace = VectorSpace >> 8; + } + + for (k = 0; k < BytesPerWord; k++) + { + params[j++] = (unsigned char) (CodeSize & 0xFF); + CodeSize = CodeSize >> 8; + } + for (k = 0; k < BytesPerWord; k++) + { + params[j++] = (unsigned char) (Offset & 0xFF); + Offset = Offset >> 8; + } + + if (p->parent != NULL) + flag = sendiserver(TheLink, 4 * BytesPerWord, params); + else + flag = (WriteLink(TheLink, params, 4 * BytesPerWord, + TIMEOUT) == (4 * BytesPerWord)); +/* if (p->tpid == 6) { + exit(0); + } +*/ for (i = 0; (i < length) && flag; i += count) + { + count = length - i; + if (count > SEGSIZE) + count = SEGSIZE; + if (p->parent != NULL) + flag = sendiserver(TheLink, (int) count, &Code[i]); + else + flag = WriteLink(TheLink, &Code[i], + (int) count, TIMEOUT) == (int) count; + } + } + return (flag); + +} +/*}}} */ diff --git a/minix/commands/inmos/cklib.h b/minix/commands/inmos/cklib.h new file mode 100644 index 000000000..0d04e2be5 --- /dev/null +++ b/minix/commands/inmos/cklib.h @@ -0,0 +1,96 @@ +/* + * -------------------------------------------------- + * + * lex.h -- interface to lex.c + * + * andyr@wizzy.com (Andy Rabagliati) 30 August 1994 + * + * This code may be freely used, provided credits remain intact + * + * -------------------------------------------------- + */ + +#define LINESIZE 200 +#define NUMTPIDS 6 +#define TPOFFSET 14 +#define class(tptype) ((((tptype+(TPOFFSET*10))/10)-TPOFFSET)*10) + +struct tpstats +{ + struct tpstats *parent, /* where I was born */ + *next; /* sequential list, handy to have */ + void *extra; /* used by other programs to extend struct */ + char info[LINESIZE]; /* original line */ + int tpid, /* number assigned by CHECKOUT */ + tptype, /* Transputer type */ + route, /* incremental route here */ + routelen, /* route length from host */ + bootlink, /* link CHECKOUT is using for lifeline */ + procspeed; /* processor speed */ + float linkspeed; /* Mbytes/sec down boot link */ + struct tpstats *links[4]; /* pointers to other Transputers */ + int tpno[4]; /* temporary - other transputer number */ + int linkno[4]; /* link numbers, or non-transputer type */ +}; + +struct c4stats +{ + struct tpstats *parent, /* where I was born */ + *next; /* sequential list, handy to have */ + void *extra; /* used by other programs to extend struct */ + char info[LINESIZE]; /* original line */ + int tpid, /* number assigned by CHECKOUT */ + tptype, /* Transputer type */ + route, /* incremental route here */ + routelen; /* route length from host */ + char config[32]; /* state */ +}; + +int bpw(int tptype); +void AbortExit(char *String,...); +void *Malloc(int size); + +int lex(FILE * stream, struct tpstats ** root, + char *Pipe, char *LinkName, char *Banner); +struct tpstats *find(struct tpstats * root, int id); +int readtp(char *tputer); +EXTERN char *tptostr(int tp); +int writeup(struct tpstats * p, int c4read, int comment); + /* writes one line */ +void writeC4(struct c4stats * q); /* C004 shorthand */ +void writeCl(struct c4stats * q); /* C004 longhand */ + +/*********************************************************** + * definitions for loader fns + ***********************************************************/ + +EXTERN LINK OpenLink(char *Name); +EXTERN int CloseLink(LINK LinkId); +EXTERN int ReadLink(LINK LinkId, unsigned char *Buffer, unsigned int Count, int Timeout); +EXTERN int WriteLink(LINK LinkId, unsigned char *Buffer, unsigned int Count, int Timeout); +EXTERN int ResetLink(LINK LinkId); +EXTERN int AnalyseLink(LINK LinkId); +EXTERN int TestError(LINK LinkId); + +int readbytes(LINK TheLink, + unsigned char *string, unsigned int maxlength); +int getiserver(LINK TheLink, unsigned int *length, + unsigned char *string, unsigned int maxlength); +int sendiserver(LINK TheLink, unsigned int length, + unsigned char *buffer); +void setroute(LINK TheLink, struct tpstats * p, int lastlink); +void tpboot(LINK TheLink, struct tpstats * p); +int load(LINK TheLink, struct tpstats * p, + long CodeSize, + long Offset, + long WorkSpace, + long VectorSpace, + int BytesPerWord, + unsigned char *Code); + +#define stop(p) setroute(TheLink, p, TAG_HALT) + + +/* + * eof + */ diff --git a/minix/commands/inmos/filec.c b/minix/commands/inmos/filec.c new file mode 100644 index 000000000..6352b392e --- /dev/null +++ b/minix/commands/inmos/filec.c @@ -0,0 +1,794 @@ + +/* + -- --------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- filec.c + -- + -- Primary file operations + -- + -- Copyright (c) INMOS Ltd., 1988. + -- All Rights Reserved. + -- + -- --------------------------------------------------------------------------- +*/ + + + +#include +#include +#include + +#ifdef MINIX +#include +#endif + +#ifdef VMS +#include +#endif + +#include "inmos.h" +#include "iserver.h" +#include "pack.h" + +#if defined(SUN) || defined(MINIX) +EXTERN VOID ResetTerminal(); +#endif + +EXTERN BOOL CocoPops; /* for DEBUG */ +EXTERN BOOL VerboseSwitch; + +EXTERN int errno; + +EXTERN BYTE Tbuf[TRANSACTION_BUFFER_SIZE]; + +PRIVATE BYTE DataBuffer[MAX_SLICE_LENGTH+1]; +PRIVATE int Size; + + + + +/* + * SpOpen + */ + +PUBLIC VOID SpOpen() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Name, Type, Mode; + + DEBUG(( "SP.OPEN" )); + INIT_BUFFERS; + + Name = &DataBuffer[0]; + GET_SLICE( Size, Name ); *(Name+Size)=0; DEBUG(( "\"%s\"", Name )); + + GET_BYTE( Type ); DEBUG(( "type %d", Type )); + GET_BYTE( Mode ); DEBUG(( "mode %d", Mode )); + + if ( strlen( (char *)Name ) == 0 ) + { + PUT_BYTE( SP_ERROR ); + REPLY; + } + + if ( ( Type != 1 ) && ( Type !=2 ) ) + { + PUT_BYTE( SP_ERROR ); + REPLY; + } + + if( ( Mode < 0 ) || ( Mode > 6 )) + { + PUT_BYTE( SP_ERROR ); + REPLY; + } + +#ifdef SUN /* fopen file modes */ +#define BINARY_1 "r" +#define BINARY_2 "w" +#define BINARY_3 "a" +#define BINARY_4 "r+" +#define BINARY_5 "w+" +#define BINARY_6 "a+" +#define TEXT_1 BINARY_1 +#define TEXT_2 BINARY_2 +#define TEXT_3 BINARY_3 +#define TEXT_4 BINARY_4 +#define TEXT_5 BINARY_5 +#define TEXT_6 BINARY_6 +#endif + +#ifdef MSC +#define BINARY_1 "rb" +#define BINARY_2 "wb" +#define BINARY_3 "ab" +#define BINARY_4 "r+b" +#define BINARY_5 "w+b" +#define BINARY_6 "a+b" +#define TEXT_1 "rt" +#define TEXT_2 "wt" +#define TEXT_3 "at" +#define TEXT_4 "r+t" +#define TEXT_5 "w+t" +#define TEXT_6 "a+t" +#endif + +#ifdef HELIOS +#define BINARY_1 "rb" +#define BINARY_2 "wb" +#define BINARY_3 "ab" +#define BINARY_4 "r+b" +#define BINARY_5 "w+b" +#define BINARY_6 "a+b" +#define TEXT_1 "r" +#define TEXT_2 "w" +#define TEXT_3 "a" +#define TEXT_4 "r+" +#define TEXT_5 "w+" +#define TEXT_6 "a+" +#endif + +#ifdef MINIX +#define BINARY_1 "r" +#define BINARY_2 "w" +#define BINARY_3 "a" +#define BINARY_4 "r+" +#define BINARY_5 "w+" +#define BINARY_6 "a+" +#define TEXT_1 BINARY_1 +#define TEXT_2 BINARY_2 +#define TEXT_3 BINARY_3 +#define TEXT_4 BINARY_4 +#define TEXT_5 BINARY_5 +#define TEXT_6 BINARY_6 +#endif + +#ifdef VMS +#define BINARY_1 "rb" +#define BINARY_2 "wb" +#define BINARY_3 "ab" +#define BINARY_4 "r+b" +#define BINARY_5 "w+b" +#define BINARY_6 "a+b" +#define TEXT_1 "rt" +#define TEXT_2 "wt" +#define TEXT_3 "at" +#define TEXT_4 "r+t" +#define TEXT_5 "w+t" +#define TEXT_6 "a+t" +#endif + + if( Type == 1 ) + switch( Mode ) + { + case 1 : Fd = fopen( (char *)Name, BINARY_1 ); break; + case 2 : Fd = fopen( (char *)Name, BINARY_2 ); break; + case 3 : Fd = fopen( (char *)Name, BINARY_3 ); break; + case 4 : Fd = fopen( (char *)Name, BINARY_4 ); break; + case 5 : Fd = fopen( (char *)Name, BINARY_5 ); break; + case 6 : Fd = fopen( (char *)Name, BINARY_6 ); break; + } + else + switch( Mode ) + { + case 1 : Fd = fopen( (char *)Name, TEXT_1 ); break; + case 2 : Fd = fopen( (char *)Name, TEXT_2 ); break; + case 3 : Fd = fopen( (char *)Name, TEXT_3 ); break; + case 4 : Fd = fopen( (char *)Name, TEXT_4 ); break; + case 5 : Fd = fopen( (char *)Name, TEXT_5 ); break; + case 6 : Fd = fopen( (char *)Name, TEXT_6 ); break; + } + + if( Fd == NULL ) + { + PUT_BYTE( SP_ERROR ); + REPLY; + } + + PUT_BYTE( SP_SUCCESS ); + PUT_FD( Fd ) + DEBUG(( "fd %0X", (int)Fd )); + REPLY; +} + + + + +/* + * SpClose + */ + +PUBLIC VOID SpClose() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + + DEBUG(( "SP.CLOSE" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + if ( fclose( Fd ) == EOF ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + } + REPLY; +} + + + + +/* + * SpRead + */ + +PUBLIC VOID SpRead() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Data; + int Read; + + DEBUG(( "SP.READ" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; +#if defined(SUN) || defined(MINIX) + ResetTerminal(); +#endif + break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + GET_INT16( Size ); DEBUG(( "request %d", Size )); + + Data = &DataBuffer[0]; + Read = fread( Data, 1, Size, Fd ); + DEBUG(( "read %d", Read )); + PUT_BYTE( SP_SUCCESS ); + PUT_SLICE( Read, Data ); + + REPLY; +} + + + +/* + * SpWrite + */ + +PUBLIC VOID SpWrite() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Data; + int Written; + + DEBUG(( "SP.WRITE" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + Data = &DataBuffer[0]; + GET_SLICE( Size, Data ); DEBUG(( "%d bytes", Size )); + +#ifdef VMS + /* VMS RMS generates a record for *each* item */ + if ( fwrite( Data, Size, 1, Fd ) != 1 ) + Written = 0; + else + Written = Size; +#else + Written = fwrite( Data, 1, Size, Fd ); +#endif + if ( Fd == stdout ) + fflush( stdout ); + DEBUG(( "wrote %d", Written )); + PUT_BYTE( SP_SUCCESS ); + PUT_INT16( Written ); + REPLY; +} + + + + +/* + * SpGetBlock + */ + +PUBLIC VOID SpGetBlock() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Data; + int Read; + + DEBUG(( "SP.GETBLOCK" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; +#if defined(SUN) || defined(MINIX) + ResetTerminal(); +#endif + break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + GET_INT16( Size ); DEBUG(( "request %d", Size )); + + Data = &DataBuffer[0]; + Read = fread( Data, 1, Size, Fd ); + DEBUG(( "read %d", Read )); + PUT_BYTE( (Read == 0) ? SP_ERROR : SP_SUCCESS ); + PUT_SLICE( Read, Data ); + + REPLY; +} + + + +/* + * SpPutBlock + */ + +PUBLIC VOID SpPutBlock() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Data; + int Written; + + DEBUG(( "SP.PUTBLOCK" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + Data = &DataBuffer[0]; + GET_SLICE( Size, Data ); DEBUG(( "%d bytes", Size )); + +#ifdef VMS + /* VMS RMS generates a record for *each* item */ + if ( fwrite( Data, Size, 1, Fd ) != 1 ) + Written = 0; + else + Written = Size; +#else + Written = fwrite( Data, 1, Size, Fd ); +#endif + if ( Fd == stdout ) + fflush( stdout ); + DEBUG(( "wrote %d", Written )); + PUT_BYTE( (Written == 0) ? SP_ERROR : SP_SUCCESS ); + PUT_INT16( Written ); + REPLY; +} + + + + +/* + * SpGets + */ + +PUBLIC VOID SpGets() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Data; + + DEBUG(( "SP.GETS" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; +#if defined(SUN) || defined(MINIX) + ResetTerminal(); +#endif + break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + GET_INT16( Size ); DEBUG(( "limit %d", Size )); + + Data = &DataBuffer[0]; + if ( fgets( (char *)Data, Size, Fd ) == NULL ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + Size = strlen( (char *)Data ); + if( *(Data+Size-1) == '\n') + { + *(Data+Size) = 0; + --Size; + } + DEBUG(( "got %d", Size )); + PUT_BYTE( SP_SUCCESS ); + PUT_SLICE( Size, Data ); + } + REPLY; +} + + + + +/* + * SpPuts + */ + +PUBLIC VOID SpPuts() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + BYTE *Data; + + DEBUG(( "SP.PUTS" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + Data = &DataBuffer[0]; + GET_SLICE( Size, Data ); DEBUG(( "%d bytes", Size )); + + *(Data+Size)=0; + if ( fputs( (char *)Data, Fd ) == EOF ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + if( fputs( "\n", Fd ) == EOF ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + } + } + REPLY; +} + + + + +/* + * SpFlush + */ + +PUBLIC VOID SpFlush() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + + DEBUG(( "SP.FLUSH" )); + INIT_BUFFERS; + + GET_FD( Fd ); DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + if( fflush( Fd ) == EOF ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + } + REPLY; +} + + + + +/* + * SpSeek + */ + +PUBLIC VOID SpSeek() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + INT32 Offset, Origin; + int origin; + + DEBUG(( "SP.SEEK" )); + INIT_BUFFERS; + + GET_FD( Fd ); + DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + GET_INT32( Offset ); DEBUG(( "offset %ld", (long)Offset )); + GET_INT32( Origin ); DEBUG(( "origin %ld", (long)Origin )); + +#ifdef SUN + origin = (int)--Origin; +#endif +#ifdef MINIX + origin = (int)--Origin; +#endif +#ifdef VMS + origin = (int)--Origin; +#endif +#ifdef MSC + switch( (int)Origin ) + { + case 1 : origin = SEEK_SET; break; + case 2 : origin = SEEK_CUR; break; + case 3 : origin = SEEK_END; break; + } +#endif + if ( fseek( Fd, Offset, origin ) ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + } + REPLY; + +} + + + + +/* + * SpTell + */ + +PUBLIC VOID SpTell() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + long Position; + + DEBUG(( "SP.TELL" )); + INIT_BUFFERS; + + GET_FD( Fd ); + DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + Position = ftell( Fd ); + if( Position == -1L ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + PUT_INT32( Position ); + } + REPLY; +} + + + + +/* + * SpEof + */ + +PUBLIC VOID SpEof() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + + DEBUG(( "SP.EOF" )); + INIT_BUFFERS; + + GET_FD( Fd ); + DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + if( feof( Fd ) ) + { + PUT_BYTE( SP_SUCCESS ); + } + else + { + PUT_BYTE( SP_ERROR ); + } + REPLY; +} + + + + +/* + * SpError + */ + +PUBLIC VOID SpError() +{ + BUFFER_DECLARATIONS; + FILE *Fd; + INT32 Errno; + BYTE String[128]; + + DEBUG(( "SP.ERROR" )); + INIT_BUFFERS; + + GET_FD( Fd ); + DEBUG(( "fd %0X", (int)Fd )); + switch( (int)Fd ) + { + case 0 : Fd = stdin; break; + case 1 : Fd = stdout; break; + case 2 : Fd = stderr; break; + } + + if( ferror(Fd) ) + { + PUT_BYTE( SP_SUCCESS ); + Errno = errno; + DEBUG(( "errno %d", Errno )); + PUT_INT32( Errno ); +#ifdef SUN + String[0] = 0; +#else + strcpy( (char *)String, strerror(errno)); +#endif + DEBUG(( "error \"%s\"", String)); + Size = strlen((char *)String); + PUT_SLICE( Size, (char *)String ); + REPLY; + } + else + { + PUT_BYTE( SP_ERROR ); + REPLY; + } +} + + + + +/* + * SpRemove + */ + +PUBLIC VOID SpRemove() +{ + BUFFER_DECLARATIONS; + BYTE *Name; + + DEBUG(( "SP.REMOVE" )); + INIT_BUFFERS; + + Name = &DataBuffer[0]; + GET_SLICE( Size, Name ); DataBuffer[Size] = 0; DEBUG(( "\"%s\"", Name )); + if ( *Name == 0 ) + { + PUT_BYTE( SP_ERROR ); + } + else + { +#if defined(SUN) || defined(MINIX) + if( unlink( (char *)Name ) ) +#else + if( remove( Name ) ) +#endif + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + } + } + REPLY; +} + + + +/* + * SpRename + */ + +PUBLIC VOID SpRename() +{ + BUFFER_DECLARATIONS; + BYTE *Oldname, *Newname; + + DEBUG(( "SP.RENAME" )); + INIT_BUFFERS; + Oldname = &DataBuffer[0]; + GET_SLICE( Size, Oldname ); *(Oldname+Size)=0; DEBUG(( "old \"%s\"", Oldname )); + + Newname = Oldname+Size+1; + GET_SLICE( Size, Newname ); *(Newname+Size)=0; DEBUG(( "new \"%s\"", Newname )); + + if ( *Oldname == 0 ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + if ( *Newname == 0 ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + if( rename( (char *)Oldname, (char *)Newname ) ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + } + } + } + REPLY; + +} + + + +/* + * Eof + */ + diff --git a/minix/commands/inmos/hostc.c b/minix/commands/inmos/hostc.c new file mode 100644 index 000000000..64a8cb250 --- /dev/null +++ b/minix/commands/inmos/hostc.c @@ -0,0 +1,616 @@ + +/* + -- --------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- hostc.c + -- + -- Primary environment operations + -- + -- Copyright (c) INMOS Ltd., 1988. + -- All Rights Reserved. + -- + -- --------------------------------------------------------------------------- +*/ + + + +#include +#include +#include + +#if (BOARD_ID == UDP) +#include "udplink.h" +#endif + +#ifdef SUN +#include +#endif + +#ifdef MINIX +#include +#include +#include +#endif + +#ifdef VMS +#include +#include +#include +#include +#include +#endif + +#ifdef HELIOS +#include +#include +#include +#endif + +#include "inmos.h" +#include "iserver.h" +#include "pack.h" + + +EXTERN BOOL CocoPops; /* for DEBUG */ +EXTERN BOOL VerboseSwitch; + +EXTERN BYTE Tbuf[TRANSACTION_BUFFER_SIZE]; + +EXTERN int TheLink; + +PRIVATE BYTE DataBuffer[MAX_SLICE_LENGTH+1]; +PRIVATE int Size; + +#define ORG_MODE 0 +#define GET_MODE 1 +#define POLL_MODE 2 + +PRIVATE BOOL TermMode = ORG_MODE; + +#if defined(SUN) || defined(MINIX) +PRIVATE struct termios OrgMode, CurMode; +#endif + +#ifdef HELIOS +PRIVATE Attributes CurAttributes, OrgAttributes; +PRIVATE Stream *InputStream; +#endif + +#ifdef VMS +PRIVATE short int InputChan; /* declare channel */ +$DESCRIPTOR( InputDescriptor, "TT:" ); /* and descriptor for input */ + +PRIVATE struct IOSB_DESC { + short int Status; + short int Count; + int DeviceInfo; + } iosb_desc; +#endif + + + + +PUBLIC VOID HostEnd() +{ +#ifdef SUN + ioctl(0,TCSETS,&OrgMode); +#endif +#ifdef MINIX + tcsetattr(0, TCSANOW, &OrgMode); +#endif +#ifdef HELIOS + SetAttributes( InputStream, &CurAttributes ); +#endif +} + + +PUBLIC VOID ResetTerminal() +{ +#ifdef SUN + if ( TermMode != ORG_MODE ) + { + ioctl(0, TCSETS, &OrgMode); + TermMode = ORG_MODE; + } +#endif +#ifdef MINIX + if ( TermMode != ORG_MODE ) + { + tcsetattr(0, TCSANOW, &OrgMode); + TermMode = ORG_MODE; + } +#endif +#ifdef HELIOS + if ( TermMode != ORG_MODE ) + { + SetAttributes( InputStream, &OrgAttributes ); + TermMode = ORG_MODE; + } +#endif +} + + +PUBLIC VOID HostBegin() +{ +#ifdef SUN + ioctl(0,TCGETS,&OrgMode); + ioctl(0,TCGETS,&CurMode); +#endif +#ifdef MINIX + tcgetattr(0, &OrgMode); + tcgetattr(0, &CurMode); +#endif +#ifdef HELIOS + InputStream = fdstream(0); + GetAttributes( InputStream, &OrgAttributes ); + GetAttributes( InputStream, &CurAttributes ); +#endif +#ifdef VMS + if ( sys$assign(&InputDescriptor, &InputChan, PSL$C_USER, 0 ) != SS$_NORMAL ) + { + DEBUG((SE, "cannot sys$assign TT:")); + } +#endif + +} + + + + +/* + * GetAKey + */ + +PUBLIC BYTE GetAKey() +{ + BYTE c; + +#if defined(SUN) || defined(MINIX) + if ( TermMode == ORG_MODE ) + { + CurMode.c_iflag &= ~ICRNL; + CurMode.c_lflag &= ~(ICANON | ECHO); + CurMode.c_cc[VTIME] = 0; + CurMode.c_cc[VMIN] = 1; +#ifdef MINIX + tcsetattr(0, TCSANOW, &CurMode); +#else + ioctl( 0, TCSETS, &CurMode ); +#endif + TermMode = GET_MODE; + } + else + if ( TermMode == POLL_MODE ) + { + CurMode.c_cc[VTIME] = 0; + CurMode.c_cc[VMIN] = 1; +#ifdef MINIX + tcsetattr(0, TCSANOW, &CurMode); +#else + ioctl( 0, TCSETS, &CurMode ); +#endif + TermMode = GET_MODE; + } + (void)read(0, &c, 1); +#endif +#ifdef MSC + c = getch(); +#endif +#ifdef HELIOS + if ( TermMode == ORG_MODE ) + { + RemoveAttribute(&CurAttributes,ConsoleEcho); + AddAttribute(&CurAttributes,ConsoleRawInput); + SetAttributes(InputStream,&CurAttributes); + TermMode = GET_MODE; + } + (void)Read(InputStream, &c, 1, -1); +#endif +#ifdef VMS + (void)SYS$QIOW(0, InputChan, (IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR ), &iosb_desc, 0, 0, &c, 1, 0, 0L, 0, 0); +#endif + + return(c); +} + + + + +/* + * SpGetKey + */ + +PUBLIC VOID SpGetkey() +{ +#if (BOARD_ID == UDP) +/* the udp version of iserver requires that the link is kept active, + if it is inactive for X seconds the transputer will reset itself. + Therefore this function polls the keyboard & sends an ACTIVE frame + every X seconds to keep the transputer alive. */ + BUFFER_DECLARATIONS; + BYTE c; + int timeval1,timeval2,finished; + +#ifdef VMS + struct CHARACTERISTICS { + short Count; + char ch; + char res1; + long res2; + } Chars; +#endif + + DEBUG(( "SP.GETKEY {udp}" )); + INIT_BUFFERS; + finished = FALSE; + time (&timeval1); + + while (!finished) { + time (&timeval2); + /* if 10 seconds elapsed, check link still active */ + if ((timeval2-timeval1) >= QUIETTIMEOUT) { + if (TestLink(TheLink) != SUCCEEDED) { + finished = TRUE; + PUT_BYTE( SP_ERROR ); + break; + } else { + time (&timeval1); + }; + }; + +#ifdef MSC + if (kbhit()) { + c = getch(); + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + finished = TRUE; + }; +#endif + +#if defined(SUN) || defined(MINIX) + if ( TermMode == ORG_MODE ) { + CurMode.c_iflag &= ~ICRNL; + CurMode.c_lflag &= ~(ICANON | ECHO); + CurMode.c_cc[VTIME] = 1; + CurMode.c_cc[VMIN] = 0; +#ifdef MINIX + tcsetattr(0, TCSANOW, &CurMode); +#else + ioctl( 0, TCSETS, &CurMode ); +#endif + TermMode = POLL_MODE; + } else { + if ( TermMode == GET_MODE ) { + CurMode.c_cc[VTIME] = 1; + CurMode.c_cc[VMIN] = 0; +#ifdef MINIX + tcsetattr(0, TCSANOW, &CurMode); +#else + ioctl( 0, TCSETS, &CurMode ); +#endif + TermMode = POLL_MODE; + }; + }; + if (read(0, &c, 1) != 0) { + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + finished = TRUE; + }; +#endif + +#ifdef VMS + (void)SYS$QIOW( 0, InputChan, (IO$_SENSEMODE | IO$M_TYPEAHDCNT ), &iosb_desc, 0, 0, &Chars, sizeof(struct CHARACTERISTICS), 0, 0, 0, 0 ) ; + if (Chars.Count > 0) { + (void)SYS$QIOW( 0, InputChan, (IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR ), &iosb_desc, 0, 0, &c, 1, 0, 0L, 0, 0 ); + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + finished = TRUE; + }; +#endif + +#ifdef HELIOS + if ( TermMode == ORG_MODE ) { + RemoveAttribute(&CurAttributes,ConsoleEcho); + AddAttribute(&CurAttributes,ConsoleRawInput); + AddAttribute(&CurAttributes,ConsoleBreakInterrupt); + SetAttributes(InputStream,&CurAttributes); + TermMode = POLL_MODE; + } + if ( Read( InputStream, &c, 1, OneSec/10 ) == 1 ) { + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + finished = TRUE; + }; +#endif + }; /* end of while */ + + DEBUG(("key was %c",c)); + REPLY; +#else + BUFFER_DECLARATIONS; + BYTE c; + + DEBUG(( "SP.GETKEY {non-udp}" )); + INIT_BUFFERS; + + c = GetAKey(); + + DEBUG(("key was %c",c)); + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + REPLY; +#endif +} + +/* + * SpPollkey + */ + +PUBLIC VOID SpPollkey() +{ + BUFFER_DECLARATIONS; + char c; +#ifdef VMS + struct CHARACTERISTICS { + short Count; + char ch; + char res1; + long res2; + } Chars; +#endif + + DEBUG(( "SP.POLLKEY" )); + INIT_BUFFERS; + +#ifdef MSC + if ( kbhit() ) + { + c = getch(); + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + } + else + { + PUT_BYTE( SP_ERROR ); + } +#endif +#if defined(SUN) || defined(MINIX) + if ( TermMode == ORG_MODE ) + { + CurMode.c_iflag &= ~ICRNL; + CurMode.c_lflag &= ~(ICANON | ECHO); + CurMode.c_cc[VTIME] = 1; + CurMode.c_cc[VMIN] = 0; +#ifdef MINIX + tcsetattr(0, TCSANOW, &CurMode); +#else + ioctl( 0, TCSETS, &CurMode ); +#endif + TermMode = POLL_MODE; + } + else + if ( TermMode == GET_MODE ) + { + CurMode.c_cc[VTIME] = 1; + CurMode.c_cc[VMIN] = 0; +#ifdef MINIX + tcsetattr(0, TCSANOW, &CurMode); +#else + ioctl( 0, TCSETS, &CurMode ); +#endif + TermMode = POLL_MODE; + } + + if ( read(0, &c, 1) == 0 ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + } +#endif + +#ifdef VMS + (void)SYS$QIOW( 0, InputChan, (IO$_SENSEMODE | IO$M_TYPEAHDCNT ), &iosb_desc, 0, 0, &Chars, sizeof(struct CHARACTERISTICS), 0, 0, 0, 0 ) ; + if ( Chars.Count > 0 ) + { + (void)SYS$QIOW( 0, InputChan, (IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR ), &iosb_desc, 0, 0, &c, 1, 0, 0L, 0, 0 ); + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + } + else + { + PUT_BYTE( SP_ERROR ); + } +#endif +#ifdef HELIOS + if ( TermMode == ORG_MODE ) + { + RemoveAttribute(&CurAttributes,ConsoleEcho); + AddAttribute(&CurAttributes,ConsoleRawInput); + AddAttribute(&CurAttributes,ConsoleBreakInterrupt); + SetAttributes(InputStream,&CurAttributes); + TermMode = POLL_MODE; + } + if ( Read( InputStream, &c, 1, OneSec/10 ) == 1 ) + { + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( c ); + } + else + { + PUT_BYTE( SP_ERROR ); + } +#endif + REPLY; + +} + + + + +/* + * SpGetenv + */ + +PUBLIC VOID SpGetenv() +{ + BUFFER_DECLARATIONS; + BYTE *Name; + + DEBUG(( "SP.GETENV" )); + INIT_BUFFERS; + + Name = &DataBuffer[0]; + GET_SLICE( Size, Name ); *(Name+Size)=0; DEBUG(( "\"%s\"", Name )); + + if( *Name == 0 ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + if( ( Name=(BYTE *)getenv( (char *)Name ) ) == NULL ) + { + PUT_BYTE( SP_ERROR ); + } + else + { + DEBUG(( "\"%s\"", Name )); + PUT_BYTE( SP_SUCCESS ); + Size = strlen( (char *)Name ); + PUT_SLICE( Size, Name ); + } + } + REPLY; +} + + + +/* + * SpTime + */ + +PUBLIC VOID SpTime() +{ + BUFFER_DECLARATIONS; +#ifdef MINIX + time_t Time, UTCTime; +#else + long Time, UTCTime; +#endif + + DEBUG(( "SP.TIME" )); + INIT_BUFFERS; + +#ifdef MSC + tzset(); + time( &UTCTime ); + Time = UTCTime - timezone; + PUT_BYTE( SP_SUCCESS ); + PUT_INT32( Time ); + PUT_INT32( UTCTime ); + REPLY; +#endif + +#if defined(SUN) || defined(MINIX) + UTCTime = time(NULL); + Time = UTCTime + (localtime(&UTCTime))->tm_gmtoff; + PUT_BYTE( SP_SUCCESS ); + PUT_INT32( Time ); + PUT_INT32( UTCTime ); + REPLY; +#endif + +#ifdef HELIOS + time( &Time ); + UTCTime = 0L; + PUT_BYTE( SP_SUCCESS ); + PUT_INT32( Time ); + PUT_INT32( UTCTime ); + REPLY; +#endif + +#ifdef VMS + time( &Time ); + UTCTime = 0L; + PUT_BYTE( SP_SUCCESS ); + PUT_INT32( Time ); + PUT_INT32( UTCTime ); + REPLY; +#endif + +} + + + + +/* + * SpSystem + */ + +PUBLIC VOID SpSystem() +{ + BUFFER_DECLARATIONS; + BYTE *Command; + INT32 Status; + + DEBUG(( "SP.SYSTEM" )); + INIT_BUFFERS; + +#ifndef UNKNOWN_HOST + Command = &DataBuffer[0]; + GET_SLICE( Size, Command ); *(Command+Size)=0; DEBUG(( "\"%s\"", Command )); + Status = system( (char *)Command ); + DEBUG(( "status %ld", (long)Status )); + PUT_BYTE( SP_SUCCESS ); + PUT_INT32( Status ); + REPLY; +#else + PUT_BYTE( SP_UNIMPLEMENTED ); + REPLY; +#endif + +} + + + + +/* + * SpExit + */ + +PUBLIC int SpExit() +{ + BUFFER_DECLARATIONS; + long Status; + + DEBUG(( "SP.EXIT" )); + INIT_BUFFERS; + + GET_INT32( Status ); + DEBUG(( "%ld", Status )); + + if( Status == 999999999 ) + Status = TERMINATE_OK_EXIT; + else if( Status == -999999999 ) + Status = TERMINATE_FAIL_EXIT; + else + Status = TERMINATE_OTHER_STATUS; + + DEBUG(( "exit with %d", (int)Status )); + + PUT_BYTE( SP_SUCCESS ); + REPLY ( (int)Status ); +} + + + +/* + * Eof + */ + diff --git a/minix/commands/inmos/inmos.h b/minix/commands/inmos/inmos.h new file mode 100644 index 000000000..4242192aa --- /dev/null +++ b/minix/commands/inmos/inmos.h @@ -0,0 +1,77 @@ + +/* + -- --------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- inmos.h + -- + -- Some global definitions + -- + -- Copyright (c) INMOS Ltd., 1988. + -- All Rights Reserved. + -- + -- --------------------------------------------------------------------------- +*/ + + + +#ifndef _INMOS_H +#define _INMOS_H +#endif + +#ifndef BYTE +#define BYTE unsigned char +#endif +#define BOOL int + +#ifdef MSC +#define INT32 long +#else +#define INT32 int +#endif + +#ifdef MINIX +#include +#if BYTE_ORDER == BIG_ENDIAN +#undef LITTLE_ENDIAN +#else +#undef BIG_ENDIAN +#endif +#else +#ifdef sun3 +#define BIG_ENDIAN +#else +#ifdef sun4 +#define BIG_ENDIAN +#else +#define LITTLE_ENDIAN +#endif +#endif +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef PUBLIC +#define PUBLIC +#endif +#ifndef PRIVATE +#define PRIVATE static +#endif +#define VOID void +#define EXTERN extern + +#define LINK int + +static char Copyright[] = "Copyright (c) INMOS Ltd, 1988. All Rights Reserved.\n"; + + +/* + * Eof + */ + diff --git a/minix/commands/inmos/iserver.1 b/minix/commands/inmos/iserver.1 new file mode 100644 index 000000000..692b6ae82 --- /dev/null +++ b/minix/commands/inmos/iserver.1 @@ -0,0 +1,56 @@ +.TH ISERVER 1 +.SH NAME +iserver \- Inmos host file server for Transputer networks +.SH SYNOPSIS +\fBiserver [\fB\-sb \fIfilename\fR] [\fB\-si\fR] [\fB\-se\fR] [\fB\-sl \fIlinkname\fR] [\fB\-sr\fR] [\fB\-sa\fR] [\fB\-sc \fIfilename\fR] [\fB\-sp \fIKiB\fR] [\fB\-ss\fR] +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.TP 5 +.B \-sb +# boot the named file (same as \-sr \-ss \-si \-sc filename) +.TP 5 +.B \-si +# verbose mode +.TP 5 +.B \-se +# test the error flag +.TP 5 +.B \-sl +# use the named link (else TRANSPUTER env var, else /dev/link0) +.TP 5 +.B \-sr +# reset the root transputer +.TP 5 +.B \-sa +# analyze and peek the root transputer +.TP 5 +.B \-sc +# copy the named file to the link +.TP 5 +.B \-sp +# set peek size to the specified number of kilobytes +.TP 5 +.B \-ss +# serve the link +.SH DESCRIPTION +.PP +iserver is the Inmos host system server for Transputer networks, booting +them, and giving them access to console and storage resources on the host. +.PP +The b004 service must be loaded, and Inmos B004 compatible hardware present. +.SH "SEE ALSO" +.BR ispy (1), +.BR mtest (1), +.BR b004 (4) +.SH AUTHOR +INMOS Ltd diff --git a/minix/commands/inmos/iserver.c b/minix/commands/inmos/iserver.c new file mode 100644 index 000000000..357334d09 --- /dev/null +++ b/minix/commands/inmos/iserver.c @@ -0,0 +1,869 @@ +/* + -- --------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- iserver.c + -- + -- The main body + -- + -- Copyright (c) INMOS Ltd., 1988. + -- All Rights Reserved. + -- + -- --------------------------------------------------------------------------- +*/ + + +#include +#include +#include +#ifdef MSC +#include +#include +#endif + +#ifdef VMS +#include +#include +#endif + +#ifdef HELIOS +#include +#include +#endif + +#ifdef MINIX +#include +#include +#endif + +#include "inmos.h" +#include "iserver.h" + + + + +EXTERN VOID SpOpen(); +EXTERN VOID SpClose(); +EXTERN VOID SpRead(); +EXTERN VOID SpWrite(); +EXTERN VOID SpGetBlock(); +EXTERN VOID SpPutBlock(); +EXTERN VOID SpGets(); +EXTERN VOID SpPuts(); +EXTERN VOID SpFlush(); +EXTERN VOID SpSeek(); +EXTERN VOID SpTell(); +EXTERN VOID SpEof(); +EXTERN VOID SpError(); +EXTERN VOID SpRemove(); +EXTERN VOID SpRename(); + +EXTERN VOID SpGetkey(); +EXTERN VOID SpPollkey(); +EXTERN VOID SpGetenv(); +EXTERN VOID SpTime(); +EXTERN VOID SpSystem(); +EXTERN VOID SpCommand(); + +EXTERN VOID SpCore(); +EXTERN VOID SpId(); +EXTERN int SpExit(); +EXTERN VOID SpUnknown(); + +#ifdef MSC +EXTERN VOID SpMsdos(); +#endif + +EXTERN LINK OpenLink(); +EXTERN int CloseLink(); +EXTERN int ReadLink(); +EXTERN int WriteLink(); +EXTERN int ResetLink(); +EXTERN int AnalyseLink(); +EXTERN int TestError(); +EXTERN int TestRead(); +EXTERN int TestWrite(); + +EXTERN BYTE GetAKey(); +EXTERN VOID HostBegin(); +EXTERN VOID HostEnd(); +EXTERN VOID ResetTerminal(); + + + + +PUBLIC BYTE Tbuf[TRANSACTION_BUFFER_SIZE]; /* buffer for all server operations */ + +PUBLIC BYTE RealCommandLine [ MAX_COMMAND_LINE_LENGTH+1 ]; +PUBLIC BYTE DoctoredCommandLine [ MAX_COMMAND_LINE_LENGTH+1 ]; + +PUBLIC BOOL AnalyseSwitch; /* command line switches */ +PUBLIC BOOL TestErrorSwitch; +PUBLIC BOOL VerboseSwitch; +PUBLIC BOOL LinkSwitch; +PUBLIC BOOL ResetSwitch; +PUBLIC BOOL ServeSwitch; +PUBLIC BOOL LoadSwitch; +PUBLIC BOOL CocoPops; + +PRIVATE BYTE BootFileName[MAX_BOOT_FILE_LENGTH+1]; + +PRIVATE BYTE LinkName[MAX_LINK_NAME_LENGTH+1]; + +PUBLIC LINK TheLink = -1 ; /* the server's idea of the active link */ + +PUBLIC BYTE *CoreDump; +PUBLIC INT32 CoreSize; + +PRIVATE char *LinkMessages[] = { + "Strange result from link module", + "Transputer no longer available", /* ER_LINK_BAD */ + "No response from transputer", /* ER_LINK_CANT */ + "Comms software failure", /* ER_LINK_SOFT */ + "Zero length data" /* ER_LINK_NODATA */ +}; + +PRIVATE char *HardwareNames[] = { + "???", + "B004", + "B008", + "B010", + "B011", + "B014", + "DRX11", + "QT0", + "IBM_CAT", + "B015", + "B016", + "UDP-Link" +}; + +/* + * Boot - copy the boot file to the link + */ + +PRIVATE VOID Boot() +{ + FILE *Fd; + BYTE Buffer[ BOOT_BUFFER_LENGTH ]; + int Length=0, Count=0; + INT32 Size=0; + static BYTE Flicks[]="|/-\\|/-\\" ; + int Flick=0; + +#ifdef FASTFILEVMS + int extra_length, end_of_file; + + if ((Fd = open (BootFileName,O_RDONLY,0)) == -1) + ABORT(MISC_EXIT, (SE, "cannot find boot file \"%s\"", BootFileName)); + INFO(("Booting root transputer...")); + + while ((Length = read (Fd, Buffer, BOOT_BUFFER_LENGTH)) > 0) { + DEBUG(("%d", Length)); + end_of_file = FALSE; + while (!end_of_file && (Length < BOOT_BUFFER_LENGTH)) { + if ((extra_length = read(Fd, &Buffer[Length], (BOOT_BUFFER_LENGTH-Length))) <= 0) + end_of_file = TRUE; + else + Length = Length + extra_length; + }; + Count = WriteLink (TheLink, Buffer, Length, BOOT_TIMEOUT); + DEBUG(("WriteLink(TheLink, Buffer, %d, BOOT_TIMEOUT) in boot() returned %d\n", Length, Count)); + if (Count != Length) + { + if (Count < 0) + ABORT(MISC_EXIT, (SE, "unable to write byte %d to the boot link because\n%s", + Size, LinkMessages[0-Count])) + else + ABORT(MISC_EXIT, (SE, "unable to write byte %d to the boot link", Size )); + } + Size += Count; + if ( isatty(1) ) { + INFO(( "%c\b", Flicks[Flick] )); + if ( ++Flick == 8 ) + Flick -= 8; + }; + }; +#else + if ( ( Fd=fopen( (char *)BootFileName, "rb" ) ) == NULL ) + ABORT(MISC_EXIT, (SE, "cannot find boot file \"%s\"", BootFileName)); + INFO(("Booting root transputer...")); + while ( ( Length = fread( Buffer, 1, BOOT_BUFFER_LENGTH, Fd ) ) > 0 ) + { + DEBUG(("%d", Length)); + Count = WriteLink( TheLink, Buffer, Length, BOOT_TIMEOUT ); + DEBUG(("WriteLink(TheLink, Buffer, %d, BOOT_TIMEOUT) in boot() returned %d\n", Length, Count)); + if ( Count != Length ) + { + if (Count < 0) +#ifdef MSC + ABORT(MISC_EXIT, (SE, "unable to write byte %ld to the boot link because\n%s", + Size, LinkMessages[0-Count])) +#else + ABORT(MISC_EXIT, (SE, "unable to write byte %d to the boot link because\n%s", + Size, LinkMessages[0-Count])) +#endif + else + ABORT(MISC_EXIT, (SE, "unable to write byte %d to the boot link", Size )); + } + Size += Count; + if (isatty(1)) { + INFO(( "%c\b", Flicks[Flick] )); + if ( ++Flick == 8 ) + Flick -=8; + }; + } +#endif + + if ( isatty(1) ) + { + INFO(( "\r \r" )); + } + else + { + INFO(("ok\n")); + } + DEBUG(( "booted %ld bytes", (long)Size )); +} + + + + +/* + * Core - peek the transputer memory into a buffer + */ + +PRIVATE VOID Core() +#ifdef FASTPEEK +{ + short int bytes_peeked, bytes_unpeeked, bytes_to_peek, num_bytes; + static BYTE Flicks[]="|\\-/|\\-/"; + int Flick = 0; + INT32 addr; + + INFO(("Peeking root transputer...")); + bytes_peeked = 0; + bytes_unpeeked = CoreSize; + + while (bytes_unpeeked > 0) { + bytes_to_peek = bytes_unpeeked; + if (bytes_to_peek > 1024) { + bytes_to_peek = 1024; + }; + addr = (INT32) (bytes_peeked + 0x80000000L); + + num_bytes = PeekLink (TheLink, (char *) &CoreDump[bytes_peeked], + addr, (bytes_to_peek / 4)); /* in words */ + if (num_bytes < 0) { + ABORT(MISC_EXIT, (SE,"timed out peeking byte %d because\n%s", + bytes_peeked, LinkMessages[0-num_bytes])); + }; + bytes_peeked = bytes_peeked + num_bytes; + bytes_unpeeked = bytes_unpeeked - num_bytes; + if (isatty(1)) { + INFO(("%c\b", Flicks[Flick])); + if (++Flick == 8) + Flick -= 8; + }; + }; + if (isatty(1)) { + INFO(("\r \r")); + } else { + INFO(("ok\n")); + }; + DEBUG(("peeked %d bytes",bytes_peeked)); +} +#else +{ + BYTE Buf[5], *c; + INT32 a; + INT32 l; + static BYTE Flicks[]="|\\-/|\\-/" ; + int Flick=0; + register int BytesRead,BytesWritten; + + INFO(( "Peeking root transputer..." )); + Buf[0] = PEEK_TRANSPUTER; + for( a = 0L ; a < CoreSize ; ) + { + l = (a + 0x80000000L); + c = (BYTE *)&l; +#ifdef BIG_ENDIAN + Buf[4]= *c++ ; Buf[3]= *c++ ; Buf[2]= *c++ ; Buf[1]= *c; +#else + Buf[1]= *c++ ; Buf[2]= *c++ ; Buf[3]= *c++ ; Buf[4]= *c; +#endif + BytesWritten = WriteLink(TheLink, &Buf[0], 5, TIMEOUT); + if (BytesWritten != 5) + { + if (BytesWritten < 0) + ABORT(MISC_EXIT, (SE, "timed out peeking word %d because\n%s", a/4, LinkMessages[0-BytesWritten])) + else + ABORT(MISC_EXIT, (SE, "timed out peeking word %d", a/4 )); + } + + BytesRead = ReadLink(TheLink, &Buf[1], 4, TIMEOUT); + if (BytesRead != 4) + { + if (BytesRead < 0) + ABORT(MISC_EXIT, (SE, "timed out in peek of word %d because\n%s", + a/4, LinkMessages[0-BytesRead])) + else + ABORT(MISC_EXIT, (SE, "timed out in peek of word %d", a/4)); + } + + CoreDump[a++] = Buf[1]; + CoreDump[a++] = Buf[2]; + CoreDump[a++] = Buf[3]; + CoreDump[a++] = Buf[4]; + + if ( isatty(1) ) + if ( (a & 255L) == 0L ) + { + INFO(( "%c\b", Flicks[Flick] )); + if ( ++Flick == 8 ) Flick -= 8; + } + } + if ( isatty(1) ) + { + INFO(( "\r \r" )); + } + else + { + INFO(("ok\n")); + } + DEBUG(( "peeked %ld bytes", (long)a )); +} +#endif + + + + +/* + * PrintHelp + */ + + +PRIVATE VOID PrintHelp () +{ + fprintf( stdout, "\n%s : occam 2 toolset host file server\n", PROGRAM_NAME); + fprintf( stdout, "%s&%s version %s.\n", HOST, HardwareNames[BOARD_ID], VERSION_NAME ); + fprintf( stdout, "%s\n", Copyright ); + fprintf( stdout, "Usage: %s {%coption}\n\n", PROGRAM_NAME, SWITCH_CHAR ); + fprintf( stdout, "Options: \n" ); + fprintf( stdout, " SB filename boot the named file (same as %cSR%cSS%cSI%cSC filename)\n", SWITCH_CHAR, SWITCH_CHAR, SWITCH_CHAR, SWITCH_CHAR ); + fprintf( stdout, " SI verbose mode\n"); + fprintf( stdout, " SE test the error flag\n"); + fprintf( stdout, " SL linkname use the named link\n"); + fprintf( stdout, " SR reset the root transputer\n"); + fprintf( stdout, " SA analyse and peek the root transputer\n"); + fprintf( stdout, " SC filename copy the named file to the link\n"); + fprintf( stdout, " SP n set peek size to n Kbytes.\n"); + fprintf( stdout, " SS serve the link\n\n"); +} + + + +/* + * ParseCommandLine + */ + +PRIVATE VOID ParseCommandLine () +{ + register BYTE *s, *t; + int i; + BOOL Gobble=TRUE; + + AnalyseSwitch = 0; + TestErrorSwitch = 0; + VerboseSwitch = 1; + LinkSwitch = 0; + ResetSwitch = 0; + ServeSwitch = 0; + LoadSwitch = 0; + CocoPops = 0; + CoreSize = DEFAULT_CORE_SIZE; + + BootFileName[0]=0; + LinkName[0]=0; + + s = RealCommandLine; + t = DoctoredCommandLine; + + while( (*s) && (*s != ' ') ) /* skip the first argv */ + ++s; + if ( *s == ' ' ) + ++s; + + for(;;) + { + if ( *s == 0 ) /* end of command line */ + return; + if ( (*s==SWITCH_CHAR) && ( (*(s+1)=='s') || (*(s+1)=='S') ) ) + { /* its a server option */ + s += 2; + switch ( *s ) + { + case 'a' : + case 'A' : ++AnalyseSwitch; ++s; break; + + case 'b' : + case 'B' : + ++s; ++ResetSwitch; ++LoadSwitch; ++ServeSwitch; ++VerboseSwitch; + while( *s == ' ' ) + ++s; + i = 0; + while( (*s) && (*s != SWITCH_CHAR) && (*s != ' ') ) + { + if ( i == MAX_BOOT_FILE_LENGTH ) + ABORT(MISC_EXIT, (SE, "boot filename is too long, maximum size is %d characters", MAX_BOOT_FILE_LENGTH )); + BootFileName[i++] = *s++; + } + if ( i == 0 ) + ABORT(MISC_EXIT, (SE, "expected a filename after %csb option", SWITCH_CHAR )); + BootFileName[i] = 0; + break; + + case 'c' : + case 'C' : + ++s; ++LoadSwitch; + while( *s == ' ' ) + ++s; + i = 0; + while( (*s) && ( (*s!=SWITCH_CHAR) && (*s!=' ') ) ) + { + if ( i == MAX_BOOT_FILE_LENGTH ) + ABORT(MISC_EXIT, (SE, "copy filename is too long, maximum size is %d characters", MAX_BOOT_FILE_LENGTH )); + BootFileName[i++] = *s++; + } + if ( i == 0 ) + ABORT(MISC_EXIT, (SE, "expected a filename after %csc option", SWITCH_CHAR )); + BootFileName[i] = 0; + break; + + case 'e' : + case 'E' : ++s; ++TestErrorSwitch; break; + + case 'i' : + case 'I' : ++s; ++VerboseSwitch; break; + + case 'l' : + case 'L' : ++s; ++LinkSwitch; + while( *s == ' ' ) + ++s; + i = 0; + while( (*s) && ( (*s!=SWITCH_CHAR) && (*s!=' ') ) ) + { + if ( i == MAX_LINK_NAME_LENGTH ) + ABORT(MISC_EXIT, (SE, "link name is too long, maximum size is %d characters", MAX_LINK_NAME_LENGTH )); + LinkName[i++] = *s++; + } + if ( i == 0 ) + ABORT(MISC_EXIT, (SE, "expected a name after %csl option", SWITCH_CHAR )); + LinkName[i] = 0; + break; + + case 'p' : + case 'P' : ++s; + while (*s == ' ') + ++s; + CoreSize = (atoi((char *)s) * 1024); + if (CoreSize == 0) + ABORT(MISC_EXIT, (SE, "expected a number after %cSP option\n", SWITCH_CHAR)); + while( (*s) && (*s!=SWITCH_CHAR) ) + ++s; + break; + + case 'r' : + case 'R' : ++s; ++ResetSwitch; break; + + case 's' : + case 'S' : ++s; ++ServeSwitch; break; + + case 'z' : + case 'Z' : ++s; ++CocoPops; break; + + default : + *t++ = SWITCH_CHAR; + *t++ = *(s-1); + Gobble = FALSE; + break; + } + if ( (Gobble == TRUE) && (*s == ' ') ) + ++s; + } + else + { + *t++ = *s++; + } + } +} + + + + +/* + * Serve - the main loop (read buffer from link, call a function, write buffer to link) + */ + +PRIVATE int Serve () +{ + register int Count, Size; + BOOL TerminateFlag = FALSE; + int Result; + + for(;;) + { + if( TestErrorSwitch ) + if( TestError( TheLink ) == 1 ) + ABORT(ERROR_FLAG_EXIT,(SE, "Transputer error flag set")); + DEBUG(("-=-")); + for(;;) + { + Count = ReadLink( TheLink, &Tbuf[0], 8, TIMEOUT ); + if( TestErrorSwitch ) + if( TestError( TheLink ) == 1 ) + ABORT(ERROR_FLAG_EXIT, (SE, "Error flag raised by transputer")); + if( Count > 0 ) + { + if ( Count == 8 ) + break; + Count += ReadLink( TheLink, &Tbuf[Count], 8-Count, TIMEOUT ); + if( Count != 8 ) + ABORT(MISC_EXIT, (SE, "protocol error, got %d bytes at start of a transaction", Count )); + } + else if (Count < 0) + ABORT(MISC_EXIT, (SE, "Unable to get request from link because\n%s", LinkMessages[0-Count])) + else /* Count == 0 */ + DEBUG(("ReadLink retrying")); + + DEBUG(("waiting")); +#ifdef MSC + kbhit(); /* test break */ +#endif + } + /* have 8 */ + Size = Tbuf[0]+Tbuf[1]*256-6 ; + if ( Size ) + { + if ( Size > (TRANSACTION_BUFFER_SIZE - 8 )) + ABORT(MISC_EXIT, (SE, "protocol error, packet size is too large")); + if ( Size < 0 ) + ABORT(MISC_EXIT, (SE, "protocol error, read nonsense from the link")); + Count = ReadLink( TheLink, &Tbuf[8], Size, TIMEOUT ); + if( TestErrorSwitch ) + if( TestError( TheLink ) == 1 ) + ABORT(ERROR_FLAG_EXIT,(SE,"Error flag raised by transputer")); + if( Count != Size ) + { + if (Count < 0) + ABORT(MISC_EXIT, (SE, "protocol error, timed out getting a further %d because\n%s", + Count, LinkMessages[0-Count])) + else + ABORT(MISC_EXIT, (SE, "protocol error, timed out getting a further %d", Count)); + } + DEBUG(( "packet is %d", Count+6 )); + } + + switch( Tbuf[2] ) + { + case SP_OPEN : SpOpen(); break; + case SP_CLOSE : SpClose(); break; + case SP_READ : SpRead(); break; + case SP_WRITE : SpWrite(); break; + case SP_GETBLOCK : SpGetBlock(); break; + case SP_PUTBLOCK : SpPutBlock(); break; + case SP_GETS : SpGets(); break; + case SP_PUTS : SpPuts(); break; + case SP_FLUSH : SpFlush(); break; + case SP_SEEK : SpSeek(); break; + case SP_TELL : SpTell(); break; + case SP_EOF : SpEof(); break; + case SP_FERROR : SpError(); break; + case SP_REMOVE : SpRemove(); break; + case SP_RENAME : SpRename(); break; + case SP_GETKEY : SpGetkey(); break; + case SP_POLLKEY : SpPollkey(); break; + case SP_GETENV : SpGetenv(); break; + case SP_TIME : SpTime(); break; + case SP_SYSTEM : SpSystem(); break; + case SP_EXIT : TerminateFlag = TRUE; + Result = SpExit(); + TestErrorSwitch = FALSE; + break; + case SP_COMMAND : SpCommand(); break; + case SP_CORE : SpCore(); break; + case SP_ID : SpId(); break; +#ifdef MSC + case SP_MSDOS : SpMsdos(); break; +#endif + default : + SpUnknown(); break; + } + + Size = Tbuf[0]+Tbuf[1]*256+2 ; + if ( Size ) + { + if ( Size > TRANSACTION_BUFFER_SIZE ) + ABORT(MISC_EXIT, (SE, "internal error, oversize packet write back")); + DEBUG(( "%d:%d", Size-2, Tbuf[2] )); + Count = WriteLink( TheLink, &Tbuf[0], Size, TIMEOUT ); + if( TestErrorSwitch ) + if( TestError( TheLink ) == 1 ) + ABORT(ERROR_FLAG_EXIT,(SE,"Error flag raised by transputer")); + if( Count != Size ) + { + if (Count < 0) + ABORT(MISC_EXIT, (SE, "protocol error, timed out sending reply message because\n%s", + LinkMessages[0-Count])) + else + ABORT(MISC_EXIT, (SE, "protocol error, timed out sending reply message")); + } + } + else + ABORT(MISC_EXIT, (SE, "internal error, zero size write back")); + + if( TerminateFlag == TRUE ) + return( Result ); + } +} + + + + +PUBLIC void BreakHandler() +{ + BYTE c = 0; + +#ifndef SUN + signal(SIGINT, BreakHandler); +#endif + + fputc('\n', stderr); + while ( c == 0 ) + { + fprintf(stderr,"%s: (x)exit, (s)hell or (c)ontinue? ", PROGRAM_NAME); fflush(stderr); + c = GetAKey(); + fputc(c, stderr); + if ( (c != 10) && (c != 13) ) + fputc('\n', stderr); + fflush(stderr); + switch(c) + { + case 0 : + case 10 : + case 13 : + case 'x': + case 'X': + case 'q': + case 'Q': + DEBUG(("break exit")); + if (CloseLink(TheLink) < 0) + ABORT(MISC_EXIT, (SE, "unable to free transputer link")); + ABORT(USER_EXIT, (SE, "aborted by user")); + case 'c': + case 'C': + break; + case 'S': + case 's': + ResetTerminal(); +#ifdef MSC + (void)system(getenv("COMSPEC")); +#endif +#ifdef SUN + (void)system(getenv("SHELL")); +#endif +#ifdef MINIX + (void)system(getenv("SHELL")); +#endif +#ifdef HELIOS + (void)system(getenv("SHELL")); +#endif +#ifdef VMS + { + long substatus; + INFO(("[Starting DCL]")); + (void)lib$spawn(NULL, 0,0,0,0,0,&substatus,0,0,0); + } +#endif + fprintf(stderr,"\n"); + break; + + case 'i': + if (VerboseSwitch) + VerboseSwitch = 0; + else + VerboseSwitch = 1; + break; + + case 'z': + if (CocoPops) + CocoPops = 0; + else + CocoPops = 1; + break; + + default: + c = 0; + break; + } + } +} + + +PRIVATE int QuotedArg(str) +char *str; +{ + while (*str) { + if ((*str == ' ') || (*str == '\t')) + return TRUE; + + str++; + } + + return FALSE; +} + + +/* + * main + */ + + +PUBLIC int main (argc, argv) + int argc; + char **argv; +{ + int Quoted; + int ExitStatus = MISC_EXIT; + int LinkStatus; + BYTE *c, *ALinkName; + + if ( argc == 1 ) + { + PrintHelp(); + return ( MISC_EXIT ); + } + + HostBegin(); /* terminal initialisation */ + + *RealCommandLine = 0; + while ( argc-- > 0 ) + { + if ( ( MAX_COMMAND_LINE_LENGTH - strlen( (char *)RealCommandLine) ) < strlen( *argv ) ) + { + ABORT(MISC_EXIT, (SE, "Command line too long (at \"%s\")", *argv) ) + } + if (QuotedArg(*argv)) { + Quoted = TRUE; + (void)strcat( (char *)RealCommandLine, "\"" ); + } + else + Quoted = FALSE; + + (void)strcat( (char *)RealCommandLine, *argv ); + if (Quoted) + (void)strcat( (char *)RealCommandLine, "\""); + (void)strcat( (char *)RealCommandLine, " " ); + ++argv; + } + for ( c=RealCommandLine; *c ; ++c ) /* strip of the last space */ + ; + if ( *--c == ' ' ) + *c = 0; + + ParseCommandLine(); + DEBUG(("original line is \"%s\"", RealCommandLine)); + DEBUG(("doctored line is \"%s\"", DoctoredCommandLine)); + + signal( SIGINT, BreakHandler ); +#ifdef SUN + signal( SIGTSTP, SIG_IGN ); /* disable ctrl-z */ +#endif + + if ( CocoPops ) + printf("(analyse=%d error=%d verbose=%d link=%d reset=%d serve=%d load=%d coco=%d)\n", AnalyseSwitch, TestErrorSwitch, VerboseSwitch, LinkSwitch, ResetSwitch, ServeSwitch, LoadSwitch, CocoPops ); + + DEBUG(("peek size = %ld bytes\n", (long)CoreSize)); + if ((CoreDump = (BYTE *) malloc(CoreSize)) == NULL) + ABORT(MISC_EXIT, (SE, "failed to allocate CoreDump buffer\n")); + + DEBUG(("using \"%s\" as the boot file", BootFileName)); + + if ( *LinkName == 0 ) + { + if ( ( ALinkName = (BYTE *)getenv("TRANSPUTER") ) != NULL ) + strcpy( (char *)LinkName, (char *)ALinkName ); + } + + DEBUG(("and \"%s\" as the link name", LinkName)); + + if ( ( TheLink = OpenLink( LinkName ) ) < 1 ) { + if(TheLink == ER_LINK_BAD){ + ABORT(MISC_EXIT, (SE, "Bad link specification")); + } + else{ + ABORT(MISC_EXIT, (SE, "unable to access a transputer")); + } + } + + if ( ResetSwitch && AnalyseSwitch ) + ABORT(MISC_EXIT, (SE, "reset and analyse are incompatible")); + + if ( ResetSwitch ) + { + LinkStatus = ResetLink(TheLink); + if (LinkStatus != 1) + ABORT(MISC_EXIT, (SE, "failed to reset root transputer because\n%s", + LinkMessages[0-LinkStatus])); + DEBUG(("reset root")); + } + + if ( AnalyseSwitch ) + { + LinkStatus = AnalyseLink(TheLink); + if (LinkStatus != 1) + ABORT(MISC_EXIT, (SE, "failed to analyse root transputer because\n%s", + LinkMessages[0-LinkStatus])); + DEBUG(("analyse root")); + Core(); + } + + if ( LoadSwitch ) + Boot(); + + if ( ServeSwitch ) + ExitStatus = Serve(); + else + { + if ( ResetSwitch || AnalyseSwitch || LoadSwitch || TestErrorSwitch ) + ExitStatus = MISC_EXIT; + else + { + INFO(("(no action taken)\n")); + } + } + + if( TestErrorSwitch ) + if( TestError( TheLink ) == 1 ) + ABORT(ERROR_FLAG_EXIT,(SE,"Error flag raised by transputer")); + + signal(SIGINT, SIG_IGN); /* dont want to be interrupted while closing */ + + LinkStatus = CloseLink(TheLink); + if (LinkStatus < 1) + ABORT(MISC_EXIT, (SE, "unable to free transputer link because\n%s", + LinkMessages[0-LinkStatus])); + + HostEnd(); + + return( ExitStatus ); +} + + + +/* + * Eof + */ + diff --git a/minix/commands/inmos/iserver.h b/minix/commands/inmos/iserver.h new file mode 100644 index 000000000..f3ce4f8ac --- /dev/null +++ b/minix/commands/inmos/iserver.h @@ -0,0 +1,303 @@ +/* + -- --------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- iserver.h + -- + -- Server definitions + -- + -- Copyright (c) INMOS Ltd., 1988, 1989, 1990. + -- All Rights Reserved. + -- + -- --------------------------------------------------------------------------- +*/ + +#ifndef _INMOS_H +#include "inmos.h" +#endif + +#define PROGRAM_NAME "iserver" +#define VERSION_NAME "1.42d of 1st Feb, 1990" +#define VERSION_ID 14 + + + + +#define TRANSACTION_BUFFER_SIZE 1024 +#define MAX_SLICE_LENGTH (TRANSACTION_BUFFER_SIZE - 2 - 1) /* largest data item in Tbuf */ + +#define BOOT_BUFFER_LENGTH (1024 * 8) + +#define DEFAULT_CORE_SIZE (1024 * 8) /* peeked at analyse */ +#define TIMEOUT (5) /* basic transaction timeout in 10ths of a second */ +#define BOOT_TIMEOUT (10) + +#define MAX_COMMAND_LINE_LENGTH 512 +#define MAX_BOOT_FILE_LENGTH 256 +#define MAX_LINK_NAME_LENGTH 64 + + +#define PEEK_TRANSPUTER 1 + + + + /* primary server operation tags */ + +#define SP_ZERO 0 + +#define SP_OPEN 10 /* filec.c */ +#define SP_CLOSE 11 +#define SP_READ 12 +#define SP_WRITE 13 +#define SP_GETS 14 +#define SP_PUTS 15 +#define SP_FLUSH 16 +#define SP_SEEK 17 +#define SP_TELL 18 +#define SP_EOF 19 +#define SP_FERROR 20 +#define SP_REMOVE 21 +#define SP_RENAME 22 +#define SP_GETBLOCK 23 +#define SP_PUTBLOCK 24 + +#define SP_GETKEY 30 /* hostc.c */ +#define SP_POLLKEY 31 +#define SP_GETENV 32 +#define SP_TIME 33 +#define SP_SYSTEM 34 +#define SP_EXIT 35 + +#define SP_COMMAND 40 /* serverc.c */ +#define SP_CORE 41 +#define SP_ID 42 + +#define SP_MSDOS 50 /* msdos.c */ + +/* NOT USED AT INMOS - MAY BE USED BY THIRD PARTY ??? +#define SP_SUN 60 +#define SP_MSC 61 +#define SP_VMS 62 +*/ + +#define SP_ALSYS 100 /* Not used by inmos iserver */ +#define SP_KPAR 101 /* Not used by inmos iserver */ + + /* INMOS reserves all numbers up to 127 */ + + + + +#define SP_SUCCESS 0 /* operation results */ +#define SP_UNIMPLEMENTED 1 +#define SP_ERROR 129 + +#define ER_LINK_BAD (-1) /* Failure codes for LinkIO functions */ +#define ER_LINK_CANT (-2) +#define ER_LINK_SOFT (-3) +#define ER_LINK_NODATA (-4) +#define SUCCEEDED (1) + + + /* machine specific stuff */ +#ifndef MSC +#ifndef VMS +#ifndef SUN +#ifndef MINIX +#define UNDEFINED_HOST +#endif +#endif +#endif +#endif + + +#ifdef SUN +#define SWITCH_CHAR '-' +#endif +#ifdef MSC +#define SWITCH_CHAR '/' +#endif +#ifdef VMS +#define SWITCH_CHAR '/' +#endif +#ifdef MINIX +#define SWITCH_CHAR '-' +#endif +#ifdef UNDEFINED_HOST +#define SWITCH_CHAR '-' +#endif + + + /* exit status */ +#ifdef VMS +globalvalue iserv_success; +globalvalue iserv_break; +globalvalue iserv_break; +globalvalue iserv_other; +globalvalue iserv_errorflag; +globalvalue iserv_misc; +globalvalue iserv_fail; + +#define TERMINATE_OK_EXIT (iserv_success) +#define TERMINATE_FAIL_EXIT (iserv_fail) +#define USER_EXIT (iserv_break) +#define ERROR_FLAG_EXIT (iserv_errorflag) +#define MISC_EXIT (iserv_misc) +#define TERMINATE_OTHER_STATUS (iserv_other) +#endif +#ifdef MSC +#define TERMINATE_OK_EXIT (0) +#define TERMINATE_FAIL_EXIT (1) +#define USER_EXIT (2) +#define ERROR_FLAG_EXIT (3) +#define MISC_EXIT (4) +#define TERMINATE_OTHER_STATUS (5) +#endif +#ifdef SUN +#define TERMINATE_OK_EXIT (0) +#define TERMINATE_FAIL_EXIT (1) +#define USER_EXIT (2) +#define ERROR_FLAG_EXIT (3) +#define MISC_EXIT (4) +#define TERMINATE_OTHER_STATUS (5) +#endif +#ifdef MINIX +#define TERMINATE_OK_EXIT (0) +#define TERMINATE_FAIL_EXIT (1) +#define USER_EXIT (2) +#define ERROR_FLAG_EXIT (3) +#define MISC_EXIT (4) +#define TERMINATE_OTHER_STATUS (5) +#endif +#ifdef UNDEFINED_HOST +#define TERMINATE_OK_EXIT (0) +#define TERMINATE_FAIL_EXIT (1) +#define USER_EXIT (2) +#define ERROR_FLAG_EXIT (3) +#define MISC_EXIT (4) +#define TERMINATE_OTHER_STATUS (5) +#endif + + +#ifdef MSC /* DOS cant redirect stderr */ +#define STANDARD_ERROR stdout +#else +#define STANDARD_ERROR stderr +#endif + + + + + /* all this is for SpId */ +#define BOX_X 0 +#define BOX_PC 1 +#define BOX_NEC 2 +#define BOX_VAX 3 +#define BOX_SUN3 4 +#define BOX_S370 5 +#define BOX_SUN4 6 +#define BOX_SUN386 7 +#define BOX_APOLLO 8 + +#define OS_X 0 +#define OS_DOS 1 +#define OS_HELIOS 2 +#define OS_VMS 3 +#define OS_SUN40 4 +#define OS_CMS 5 +#define OS_MINIX 6 + +#ifdef sun3 +#define HOST "Sun3/SunOS4.0" +#define HOST_ID BOX_SUN3 +#define OS_ID OS_SUN40 +#endif + +#ifdef sun4 +#define HOST "Sun4/SunOS4.0" +#define HOST_ID BOX_SUN3 +#define OS_ID OS_SUN40 +#endif + +#ifdef sun386 +#define HOST "Sun386/SunOS4.0" +#define HOST_ID BOX_SUN3 +#define OS_ID OS_SUN40 +#endif + +#ifdef MSC +#define HOST "IBM-PC/MS-DOS" +#ifdef NEC +#undef HOST +#define HOST "NEC-PC/MS-DOS" +#endif +#define HOST_ID BOX_PC +#define OS_ID OS_DOS +#endif + +#ifdef VMS +#define HOST "VAX/VMS" +#define HOST_ID BOX_VAX +#define OS_ID OS_VMS +#endif + +#ifdef HELIOS +#define HOST "HELIOS 1.0" +#define HOST_ID BOX_X +#define OS_ID OS_HELIOS +#endif + +#ifdef MINIX +#define HOST "MINIX" +#define HOST_ID BOX_PC +#define OS_ID OS_MINIX +#endif + +#ifndef HOST_ID +#define HOST "???" +#define HOST_ID BOX_X +#endif + +#ifndef OS_ID +#define OS_ID OS_X +#endif + +#ifdef MINIX +#ifdef B004 +#undef B004 +#undef B008 +#endif +#endif + +#define HW_X 0 +#define B004 1 +#define B008 2 +#define B010 3 +#define B011 4 +#define B014 5 +#define DRX11 6 +#define QT0 7 +#define B015 8 +#define IBM_CAT 9 +#define B016 10 +#define UDP 11 + +#ifndef BOARD_ID +#define BOARD_ID HW_X +#endif + + + + /* some global inlines */ +#define DEBUG(x) { if (CocoPops) { fputs("(", stdout); printf x; fputs(")", stdout); fputc((VerboseSwitch ? '\n' : ' '), stdout); fflush(stdout); } } +#define INFO(x) { if (VerboseSwitch) printf x ; fflush(stdout); } +#define SE STANDARD_ERROR +#define ABORT(xit_code, x) { fprintf(STANDARD_ERROR, "\nError - %s - ", PROGRAM_NAME); fprintf x; fputs(".\n",STANDARD_ERROR); if (TheLink != -1 ) CloseLink(TheLink); HostEnd(); exit(xit_code); } + + + +/* + * Eof + */ + diff --git a/minix/commands/inmos/ispy.1 b/minix/commands/inmos/ispy.1 new file mode 100644 index 000000000..3798666c1 --- /dev/null +++ b/minix/commands/inmos/ispy.1 @@ -0,0 +1,56 @@ +.TH ISPY 1 +.SH NAME +ispy \- inspect and test a Transputer network +.SH SYNOPSIS +\fBispy [\fB\-n\fR] [\fB\-r\fR] [\fB\-c4\fR] [\fB\-cl\fR] [\fB\-cr\fR] [\fB\-cs\fR] [\fB\-l \fIname\fR] [\fB\-x\fR] [\fB\-i\fR] [\fB\-h\fR] +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.TP 5 +.B \-n +# do not reset the root transputer +.TP 5 +.B \-r +# reset the root transputer subsystem +.TP 5 +.B \-c4 +# read the state of all C004s found +.TP 5 +.B \-cl +# read the state of C004s, long form +.TP 5 +.B \-cs +# set all C004s in file +.TP 5 +.B \-l +# use the specified link (else TRANSPUTER env var, else /dev/link0) +.TP 5 +.B \-x +# ignore any file piped in +.TP 5 +.B \-i +# give progress report while working +.TP 5 +.B \-h +# show usage summary +.SH DESCRIPTION +.PP +ispy is the Inmos tool for inspecting and testing a Transputer network. +It gives a summary of the configuration, and can be asked to do more. +.PP +The b004 service must be loaded, and Inmos B004 compatible hardware present. +.SH "SEE ALSO" +.BR mtest (1), +.BR iserver (1), +.BR b004 (4) +.SH AUTHOR +Andy Rabagliati (andyr@wizzy.com) diff --git a/minix/commands/inmos/link.c b/minix/commands/inmos/link.c new file mode 100644 index 000000000..3431a53fa --- /dev/null +++ b/minix/commands/inmos/link.c @@ -0,0 +1,183 @@ + +/* + -- --------------------------------------------------------------------------- + -- + -- link.c - INMOS standard link interface + -- + -- --------------------------------------------------------------------------- +*/ + + + +/* + * + * OpenLink + * + * Ready the link associated with `Name'. + * If `Name' is NULL or "" then any free link can be used. + * Returns any positive integer as a link id or + * a negative value if the open fails. + * + */ + +int OpenLink ( Name ) + char *Name; +{ +} + + + +/* + * + * CloseLink + * + * Close the active link `LinkId'. + * Returns 1 on success or negative if the close failed. + * + */ + +int CloseLink ( LinkId ) + int LinkId; +{ +} + + + +/* + * + * ReadLink + * + * Read `Count' chars into `Buffer' from the specified link. + * LinkId is a vaild link identifier, opened with OpenLink. + * `Timeout' is a non negative integer representing tenths + * of a second. A `Timeout' of zero is an infinite timeout. + * The timeout is for the complete operation. + * If `Timeout' is positive then ReadLink may return having + * read less that the number of chars asked for. + * Returns the number of chars placed in `Buffer' (which may + * be zero) or negative to indicate an error. + * + */ + +int ReadLink ( LinkId, Buffer, Count, Timeout ) + int LinkId; + char *Buffer; + unsigned int Count; + int Timeout; +{ +} + + + +/* + * + * WriteLink + * + * Write `Count' chars from `Buffer' to the specified link. + * LinkId is a vaild link identifier, opened with OpenLink. + * `Timeout' is a non negative integer representing tenths + * of a second. A `Timeout' of zero is an infinite timeout. + * The timeout is for the complete operation. + * If `Timeout' is positive then WriteLink may return having + * written less that the number of chars asked for. + * Returns the number of chars actually written (which may + * be zero) or negative to indicate an error. + * + */ + +int WriteLink ( LinkId, Buffer, Count, Timeout ) + int LinkId; + char *Buffer; + unsigned int Count; + int Timeout; +{ +} + + + +/* + * + * ResetLink + * + * Reset the subsystem associated with the specified link. + * Returns 1 if the reset is successful, negative otherwise. + * + */ + +int ResetLink ( LinkId ) + int LinkId; +{ +} + + + +/* + * + * AnalyseLink + * + * Analyse the subsystem associated with the specified link. + * Returns 1 if the analyse is successful, negative otherwise. + * + */ + +int AnalyseLink ( LinkId ) + int LinkId; +{ +} + + + +/* + * + * TestError + * + * Test the error status associated with the specified link. + * Returns 1 if error is set, 0 if it is not and + * negative to indicate an error. + * + */ + +int TestError ( LinkId ) + int LinkId; +{ +} + + + +/* + * + * TestRead + * + * Test input status of the link. + * Returns 1 if ReadLink will return one byte without timeout, + * 0 if it may not and negative to indicate an error. + * + */ + +int TestRead ( LinkId ) + int LinkId; +{ +} + + + +/* + * + * TestWrite + * + * Test output status of the link. + * Returns 1 if WriteLink can write one byte without timeout, + * 0 if it may not and negative to indicate an error. + * + */ + +int TestWrite ( LinkId ) + int LinkId; +{ +} + + + +/* + * Eof + */ diff --git a/minix/commands/inmos/linkio.h b/minix/commands/inmos/linkio.h new file mode 100644 index 000000000..a622ee62a --- /dev/null +++ b/minix/commands/inmos/linkio.h @@ -0,0 +1,128 @@ +/* Copyright INMOS Limited 1988,1990,1991 */ +/* CMSIDENTIFIER */ +/* PRODUCT:ITEM.VARIANT-TYPE;0(DATE) */ + +#ifndef _LINKIO_H_ + +#define _LINKIO_H_ + +#define NULL_LINK -1 + +#define SUCCEEDED 0 +#define ER_LINK_BAD -1 +#define ER_LINK_CANT -2 +#define ER_LINK_SOFT -3 +#define ER_LINK_NODATA -4 +#define ER_LINK_NOSYNC -5 +#define ER_LINK_BUSY -6 +#define ER_NO_LINK -7 +#define ER_LINK_SYNTAX -8 + +/* Now all the external declarations */ + +#ifdef LNKb004 + +extern int B004OpenLink(const char *Name); +extern int B004CloseLink(int LinkId); +extern int B004ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B004WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B004ResetLink(int LinkId); +extern int B004AnalyseLink(int LinkId); +extern int B004TestError(int LinkId); +extern int B004TestRead(int LinkId); +extern int B004TestWrite(int LinkId); + +#define OpenLink B004OpenLink +#define CloseLink B004CloseLink +#define ReadLink B004ReadLink +#define WriteLink B004WriteLink +#define ResetLink B004ResetLink +#define AnalyseLink B004AnalyseLink + +#endif /* B004 */ + +#ifdef LNKb008 + +extern int B008OpenLink(const char *Name); +extern int B008CloseLink(int LinkId); +extern int B008ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B008WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B008ResetLink(int LinkId); +extern int B008AnalyseLink(int LinkId); +extern int B008TestError(int LinkId); +extern int B008TestRead(int LinkId); +extern int B008TestWrite(int LinkId); + +#endif /* B008 */ + +#ifdef LNKb011 + +extern int B011OpenLink(const char *Name); +extern int B011CloseLink(int LinkId); +extern int B011ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B011WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B011ResetLink(int LinkId); +extern int B011AnalyseLink(int LinkId); +extern int B011TestError(int LinkId); +extern int B011TestRead(int LinkId); +extern int B011TestWrite(int LinkId); + +#endif /* B011 */ + +#ifdef LNKb014 + +extern int B014OpenLink(const char *Name); +extern int B014CloseLink(int LinkId); +extern int B014ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B014WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B014ResetLink(int LinkId); +extern int B014AnalyseLink(int LinkId); +extern int B014TestError(int LinkId); +extern int B014TestRead(int LinkId); +extern int B014TestWrite(int LinkId); + +#endif /* B014 */ + +#ifdef LNKb016 + +extern int B016OpenLink(const char *Name); +extern int B016CloseLink(int LinkId); +extern int B016ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B016WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int B016ResetLink(int LinkId); +extern int B016AnalyseLink(int LinkId); +extern int B016TestError(int LinkId); +extern int B016TestRead(int LinkId); +extern int B016TestWrite(int LinkId); + +#endif /* B016 */ + +#ifdef LNKqt0 + +extern int QT0OpenLink(const char *Name); +extern int QT0CloseLink(int LinkId); +extern int QT0ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int QT0WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int QT0ResetLink(int LinkId); +extern int QT0AnalyseLink(int LinkId); +extern int QT0TestError(int LinkId); +extern int QT0TestRead(int LinkId); +extern int QT0TestWrite(int LinkId); + +#endif /* QT0 */ + +#ifdef S386 + +extern int S386OpenLink(const char *Name); +extern int S386CloseLink(int LinkId); +extern int S386ReadLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int S386WriteLink(int LinkId, char *Buffer, int Count, int Timeout); +extern int S386ResetLink(int LinkId); +extern int S386AnalyseLink(int LinkId); +extern int S386TestError(int LinkId); +extern int S386TestRead(int LinkId); +extern int S386TestWrite(int LinkId); + +#endif /* S386 */ + +#endif /* _LINKIO_H_ */ diff --git a/minix/commands/inmos/mtest.1 b/minix/commands/inmos/mtest.1 new file mode 100644 index 000000000..0ab82074a --- /dev/null +++ b/minix/commands/inmos/mtest.1 @@ -0,0 +1,73 @@ +.TH MTEST 1 +.SH NAME +mtest \- test memory on Transputers found by ispy +.SH SYNOPSIS +\fBispy [\fB\-c\fR] [\fB\-e \fIKiB\fR] [\fB\-l\fR] [\fB\-t \fInum\fR] [\fB\-t2\fR] [\fB\-t4\fR] [\fB\-q\fR] [\fB\-x\fR] [\fB\-0\fR] [\fB\-i\fR] [\fB\-h\fR] +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.TP 5 +.B \-c +# include T2s with C004s on links +.TP 5 +.B \-e +# set ceiling in kilobytes up to which memory is tested +.TP 5 +.B \-l +# suppress printing of progress dots to stderr +.TP 5 +.B \-t +# test only the specified processor +.TP 5 +.B \-t2 +# test T2 processors only +.TP 5 +.B \-t4 +# test T4 and T8 processors only +.TP 5 +.B \-q +# quick memory sizing only +.TP 5 +.B \-x +# give extra information on why memory search stopped +.TP 5 +.B \-0 +# do not include root processor in tests +.TP 5 +.B \-i +# show progress information +.TP 5 +.B \-h +# show usage summary +.SH DESCRIPTION +.PP +mtest is used to test memory on Transputers. +It needs ispy to suppy it with a map of the network. +Pipe output from ispy into mtest, and give mtest the flags that tell it +what to do. +.PP +The b004 service must be loaded, and Inmos B004 compatible hardware present. +.SH EXAMPLES +.TP 20 +.B ispy \| mtest \-t 02 +# Run memory test on processor 02 in the network mapped by ispy. +.SH BUGS +.PP +mtest should be able to test multiple processors in parallel, but this +does not currently work. +Because of this, the \-t option must be used to limit the testing to one. +.SH "SEE ALSO" +.BR ispy (1), +.BR iserver (1), +.BR b004 (4) +.SH AUTHOR +Andy Rabagliati (andyr@wizzy.com) diff --git a/minix/commands/inmos/mtest.c b/minix/commands/inmos/mtest.c new file mode 100644 index 000000000..ee3cc1936 --- /dev/null +++ b/minix/commands/inmos/mtest.c @@ -0,0 +1,690 @@ +/*{{{ BLURB */ +/* -------------------------------------------------- + + * mtest.c -- memory test program + * + * Andy Rabagliati INMOS + * + * Modified by Jeremy Thorp + * + * Adapted for Autronica, TRONDHEIM, Norway, under contract to + * 0yvind Teig for link on their boards. + * + * + * Copyright andyr@wizzy.com (Andy Rabagliati) 30 August 1994 + * 18 January 1995 + * + * This code may be freely used, provided above credits remain intact + * the CREDITS #define below is kept. Any modifications must be + * distributed in source. + * + * -------------------------------------------------- + */ +/*}}} */ + +char *PROGRAM_NAME = "mtest"; + +#define VERSION_NUMBER "3.22" +#define VERSION_DATE "31st Jan 1995" +#define CREDITS "by Andy Rabagliati " +#define WWW "" +#define AUTRONICA "for AUTRONICA, Trondheim, Norway" + + +/*{{{ includes */ +#include +#include +#include +#include + +#ifdef MSDOS +#include "linkio.h" +#endif + +/* + #ifdef HELIOS + #include + #else + #include + #endif + */ + +#include /* for atoi */ + +#include "inmos.h" +#include "mtest32.h" +#include "mtest16.h" +#include "checklib.h" +#include "cklib.h" +/*}}} */ +/*{{{ defines */ + +#define SEGSIZE 511 +#define DOTSIZE 256 + +#define STDERR stderr + +#define HUNKY_DORY 0 +#define BAD_KARMA 1 + +#define SWITCHAR '-' + +/*}}} */ + +/*{{{ struct meminfo */ +struct meminfo + { + unsigned char testno, endmem; + int memspeed; + unsigned long error, memsize, watermark; + }; +/*}}} */ +int Kb2 = DOTSIZE * 32, Mb = 0; +LINK TheLink; + +/*{{{ Usage */ +void +Usage (void) +{ + fprintf (stdout, +"\nUsage: ispy | %s [%coption...] -- version %s of %s.\n\n", + PROGRAM_NAME, SWITCHAR, VERSION_NUMBER, VERSION_DATE); + fprintf (stdout, +"Valid options are: \n"); + fprintf (stdout, +" %cc : Include T2s with C004s on links (default - no)\n", SWITCHAR); + fprintf (stdout, +" %ce : sets ceiling in Kbytes to which memory is tested\n", SWITCHAR); + fprintf (stdout, +" %cl : Do not write ..... dots to stderr\n", SWITCHAR); + fprintf (stdout, +" %ct : test processor only\n", SWITCHAR); + fprintf (stdout, +" %ct2 : test T2s only\n", SWITCHAR); + fprintf (stdout, +" %ct4 : test T4s and T8s only\n", SWITCHAR); + fprintf (stdout, +" %cq : Quick memory sizing option\n", SWITCHAR); + fprintf (stdout, +" %cx : Extra information on why memory search stopped\n", SWITCHAR); + fprintf (stdout, +" %c0 : Do not include root processor in tests\n", SWITCHAR); + fprintf (stdout, +" %ci : show progress information\n", SWITCHAR); + fprintf (stdout, +" %ch : display this help page\n\n", SWITCHAR); + fprintf (stdout, +" terminating <;> means memory wraps,\n"); + fprintf (stdout, +" terminating <.> means memory stops. %cX switch will explain further\n", + SWITCHAR); + fprintf (stdout, +" terminating <|> means %cE ceiling reached\n", SWITCHAR); + fprintf (stdout, +" terminating means no further messages received - a bus error?\n"); + fprintf (stdout, +" or processor not tested\n\n"); + fprintf (stdout, +" %s\n", AUTRONICA); + fprintf (stdout, +"%s %s\n", CREDITS, WWW); + exit (0); +} + +/*}}} */ +/*{{{ getresults */ +struct tpstats * +getresults (LINK TheLink, struct tpstats *root, int *delta) +{ + struct tpstats *p; + struct meminfo *q; + unsigned char results[16]; + unsigned int i, ok; + ok = getiserver (TheLink, &i, (unsigned char *) results, sizeof (results)); + if ((i == 16) && ok) + { + int id; + unsigned long error; + id = results[0] + (results[1] << 8); + p = find (root, id); + if (p == NULL) + AbortExit (PROGRAM_NAME, "Cannot find transputer %d", id); + q = (struct meminfo *) p->extra; + q->testno = results[2]; + q->endmem = results[3]; + for (i = 15, error = 0; i >= 12; i--) + error = (error << 8) + results[i]; + q->error = q->error | error; /* accumulate errors */ + switch (q->endmem) + { + int speed; + case 0: /* still going */ + case 2: /* ceiling */ + for (i = 7, q->memsize = 0; i >= 4; i--) + q->memsize = (q->memsize << 8) + results[i]; + speed = results[8] + (results[9] << 8); + speed = (speed * p->procspeed) / 1000; + switch (bpw (p->tptype)) + { + case 2: + speed = speed / 2; + q->memsize *= 2; + break; + case 4: + q->memsize *= 4; + break; + } + if (q->memspeed) + *delta = speed - q->memspeed; /* otherwise leave it + * alone */ + q->memspeed = speed; + } + return (p); + } + else + { + fprintf (stderr, "getresults error : received %d bytes\n", i); + return (NULL); + } +} + +/*}}} */ +/*{{{ sendparams */ +void +sendparams (LINK TheLink, struct tpstats *p, + int quick, long endaddr) +{ + struct meminfo *q; + unsigned char params[8]; + int i; + q = (struct meminfo *) p->extra; + params[0] = (unsigned char) (p->tpid & 0xFF); + params[1] = (unsigned char) (p->tpid >> 8); + if (quick) + params[2] = 4; + else + params[2] = 0; + params[3] = 0; /* pause */ + switch (bpw (p->tptype)) + { + case 2: + if (endaddr > 64) + endaddr = 64; + endaddr = ((endaddr * 1024) / 2) - 1; + break; + case 4: + endaddr = ((endaddr * 1024) / 4) - 1; + break; + } + for (i = 4; i < 8; i++) + { + params[i] = (unsigned char) (endaddr & 0xFF); + endaddr = endaddr >> 8; + } + setroute (TheLink, p, 4); /* to application */ + if (!sendiserver (TheLink, 8, params)) + AbortExit (PROGRAM_NAME, "sending test parameters to processor %d", p->tpid); + q->watermark = -2048l; + q->memspeed = 0; /* initialise */ + q->memsize = 0l; + q->endmem = 0; +} +/*}}} */ +/*{{{ sortl */ +struct tpstats * +sortl (struct tpstats *root) /* by route length */ +{ + struct tpstats **p; + int sorted; + sorted = FALSE; + while (!sorted) + { + sorted = TRUE; + for (p = (&root); ((*p) != NULL) && ((*p)->next != NULL); p = (&((*p)->next))) + if ((*p)->routelen > (*p)->next->routelen) + { + struct tpstats *temp; + temp = *p; + *p = temp->next; + temp->next = temp->next->next; + (*p)->next = temp; + sorted = FALSE; + } + } + return (root); +} +/*}}} */ +/*{{{ sortid */ +struct tpstats * +sortid (struct tpstats *root) +{ + struct tpstats **p; + int sorted; + sorted = FALSE; + while (!sorted) + { + sorted = TRUE; + for (p = (&root); ((*p) != NULL) && ((*p)->next != NULL); p = (&((*p)->next))) + if ((*p)->tpid > (*p)->next->tpid) + { + struct tpstats *temp; + temp = *p; + *p = temp->next; + temp->next = temp->next->next; + (*p)->next = temp; + sorted = FALSE; + } + } + return (root); +} +/*}}} */ +/*{{{ printresults */ +void +printresults (FILE * stream, struct tpstats *p, + int quick, int extra) +{ + static char *tests[] = + {"", "stuck bits test", + "random byte test", "random word test", + "run code test", + "address test"}; + + struct meminfo *q; + q = (struct meminfo *) p->extra; + /*{{{ bus time out */ + if (q && !q->endmem) + { + fprintf (stream, "\n%s%luK", p->info, (q->memsize - q->watermark) / 1024); + if (!quick) + fprintf (stream, ",%d", q->memspeed); + fprintf (stream, "?"); + } + else + fprintf (stream, "\n%s", p->info); + /*}}} */ + /*{{{ errors on another line */ + if (q && (q->endmem == 1) && extra) + { + unsigned long mint; + switch (bpw (p->tptype)) + { + case 2: + mint = 0x8000; + break; + case 4: + mint = 0x80000000; + break; + default: + mint = 0; + break; + } + fprintf (stream, "\n# 2K block at %0*lX, bits in error %0*lX, %s", + bpw (p->tptype) * 2, mint + 2048l + q->memsize, + bpw (p->tptype) * 2, q->error, tests[q->testno]); + } + /*}}} */ +} +/*}}} */ + +/*{{{ getparams */ +void +getparams (int argc, char *argv[], int *zero, unsigned long *endaddr, + int *c4s, int *logging, int *info, + int *soak, int *T2, int *T4, + int *only, int *quick, int *extra, char *CheckFile) +{ + /*{{{ command line switches */ + ++argv; + while (--argc > 0) + { + char *c; + if ((char) (**argv) != SWITCHAR) + Usage (); /* strcpy(CheckFile, *argv); */ + else { + c = *argv; + ++c; + switch (*c) + { + case '?': + case 'h': + case 'H': + Usage (); + break; + case '0': + *zero = FALSE; + break; + case 'c': + case 'C': + *c4s = TRUE; + break; + case 'e': + case 'E': + if (argc-- == 1) + AbortExit (PROGRAM_NAME, " no address after the E option"); + ++argv; + *endaddr = atol (*argv); + break; + case 'i': + case 'I': + *info = TRUE; + break; + case 'l': + case 'L': + *logging = FALSE; + break; + case 's': + case 'S': + *soak = TRUE; + break; + case 't': + case 'T': + ++c; + switch (*c) + { + case '2': + *T2 = TRUE; + break; + case '4': + *T4 = TRUE; + break; + default: + if (argc-- == 1) + AbortExit (PROGRAM_NAME, " no transputer number after the T option"); + ++argv; + *only = atoi (*argv); + break; + } + break; + case 'q': + case 'Q': + *quick = TRUE; + break; + case 'x': + case 'X': + *extra = TRUE; + break; + default: + Usage (); + break; + } + } + ++argv; + } + /*}}} */ + + if (*only != -1) + *zero = TRUE; + if ((*T2 == FALSE) && (*T4 == FALSE)) + *T2 = *T4 = TRUE; +} +/*}}} */ +/*{{{ main */ +int +main (int argc, char *argv[]) +{ + /*{{{ DECLs */ + struct tpstats *root, *p; + struct meminfo *q; + char Pipe[128], Banner[128]; + char LinkName[64]; + char CheckFile[64]; + int transputers, i; + int logging = TRUE, c4s = FALSE, info = FALSE; + int zero = TRUE, quick = FALSE, extra = FALSE, soak = FALSE; + int T2 = FALSE, T4 = FALSE; + unsigned long endaddr = 0x40000; + int ok; + int only = -1, iterations = 1; + /*}}} */ + CheckFile[0] = '\0'; + getparams (argc, argv, &zero, &endaddr, &c4s, &logging, + &info, &soak, &T2, &T4, &only, &quick, &extra, CheckFile); + if (info) + printf ("# mtest reading ispy results\n"); + if (CheckFile[0]) { + FILE *checkin; + checkin = fopen(CheckFile, "r"); + transputers = lex (checkin, &root, Pipe, LinkName, Banner); + } else + transputers = lex (stdin, &root, Pipe, LinkName, Banner); + root = sortl (root); /* sort by route length in case of /R option */ + if (!transputers--) + AbortExit (PROGRAM_NAME, "No transputers found"); + TheLink = OpenLink (LinkName); + ok = (TheLink > 0); + if (!ok) + AbortExit (PROGRAM_NAME, "Error opening link name \"%s\"", LinkName); + /*{{{ load 'em up */ + if (info) + printf ("# load"); + for (p = root; (p != NULL) && ok; p = p->next) + if (zero || (!zero && (p->parent != NULL))) + { + if ((only == -1) || (only == p->tpid)) /* only load ours */ + switch (bpw (p->tptype)) + { + /*{{{ 16 bitters */ + case 2: + if (T2) + { + if (info) + printf (" %d", p->tpid); + stop (p); + ok = load (TheLink, p, + mtest16_code.CodeSize, + mtest16_code.Offset, + mtest16_code.WorkSpace, + mtest16_code.VectorSpace, + mtest16_code.BytesPerWord, + mtest16_code.Code); + } + break; + /*}}} */ + /*{{{ 32 bitters */ + case 4: + if (T4) + { + if (info) + printf (" %d", p->tpid); + stop (p); + ok = load (TheLink, p, + mtest32_code.CodeSize, + mtest32_code.Offset, + mtest32_code.WorkSpace, + mtest32_code.VectorSpace, + mtest32_code.BytesPerWord, + mtest32_code.Code); + } + /*}}} */ + } + /*{{{ init */ + if (!ok) + printf ("\n%s - Error loading processor %d\n", PROGRAM_NAME, p->tpid); + p->extra = Malloc (sizeof (struct meminfo)); + q = (struct meminfo *) p->extra; + i = strlen (p->info); + p->info[i++] = ' '; + p->info[i] = '\0'; + q->endmem = 3; + q->error = 0UL; + q->memsize = 0UL; + q->watermark = 0UL; + /*}}} */ + } + else + { + p->extra = Malloc (sizeof (struct meminfo)); + q = (struct meminfo *) p->extra; + q->endmem = 3; + q->error = 0UL; + q->memsize = 0UL; + q->watermark = 0UL; + } + /*}}} */ + if (info) + printf ("\n# start"); + while (ok && iterations--) /* there are still iterations to go */ + { + int count = 0; + + if (only == -1) + /*{{{ start them all */ + for (p = root; p != NULL; p = p->next) + { + if (zero || (!zero && (p->parent != NULL))) + { + /*{{{ start T4s ? */ + if (T4 && bpw (p->tptype) == 4) + { + count++; + ((struct meminfo *) p->extra)->endmem = 2; + } + /*}}} */ + /*{{{ start T2s ? */ + if (T2 && bpw (p->tptype) == 2) + { + if (c4s) + { + count++; + ((struct meminfo *) p->extra)->endmem = 2; + } + else + { + for (i = 0; (class (p->linkno[i]) != C4) && (i < 4); i++); + if (i == 4) + { + count++; + ((struct meminfo *) p->extra)->endmem = 2; + } + } + } + /*}}} */ + } + if (((struct meminfo *) p->extra)->endmem != 3) + { + if (info) + printf (" %d", p->tpid); + sendparams (TheLink, p, quick, endaddr); + } + } + /*}}} */ + else + { + /*{{{ only one to be tested */ + for (p = root; (p != NULL) && (p->tpid != only); p = p->next); + if (p != NULL) + { + count++; + ((struct meminfo *) p->extra)->endmem = 2; + if (info) + printf (" %d", p->tpid); + sendparams (TheLink, p, quick, endaddr); + } + /*}}} */ + } + + for (; ok && (count || soak); count--) + { + int endmemory = FALSE; + while (ok && !endmemory) /* we havent received endmem */ + { + int delta = 0; + /*{{{ logging */ + if (!(Kb2++ % (DOTSIZE / 2))) + { + +#ifdef MSC + kbhit (); +#endif + + if (logging) + { + if (Kb2 == ((DOTSIZE * 32) + 1)) + { + for (p = root; p != NULL; p = p->next) + { + q = (struct meminfo *) p->extra; + if (q->error) + printresults (stderr, p, quick, extra); + } + fprintf (stderr, "\n<%5dMb> ", Mb); + Mb += DOTSIZE / 16; + Kb2 = 1; + } + putc ('.', stderr); + fflush (stderr); + } + } + /*}}} */ + /*{{{ get results */ + p = getresults (TheLink, root, &delta); + ok = (p != NULL); + if (ok) + { + char terminator = '$'; + q = (struct meminfo *) p->extra; + switch (q->endmem) + { + case 0: /* still ok */ + case 2: /* ceiling */ + if (!quick && delta) + { + sprintf (&p->info[strlen (p->info)], "%luK,%d ", + ((q->memsize - 2048l) - q->watermark) / 1024, + q->memspeed - delta); + q->watermark = q->memsize - 2048l; + } + } + if (q->endmem) + { + endmemory = TRUE; + switch (q->endmem) + { + case 2: /* ceiling */ + terminator = '|'; + break; + case 1: /* error */ + terminator = '.'; + break; + case 255: /* wrap */ + terminator = ';'; + break; + } + sprintf (&p->info[strlen (p->info)], "%luK", + (q->memsize - q->watermark) / 1024); + if (!quick) + sprintf (&p->info[strlen (p->info)], ",%d%c", + q->memspeed, terminator); + else + sprintf (&p->info[strlen (p->info)], "%c", + terminator); + } + } + else + fprintf (stderr, "Failed to get results\n"); + /*}}} */ + } /* endmemory */ + /*{{{ send params if soak */ + if (soak) + sendparams (TheLink, p, quick, endaddr); + /*}}} */ + } /* count */ + } + /*{{{ print results */ + root = sortid (root); + if (logging) + putc ('\n', stderr); + if (info) + putc ('\n', stdout); + printf ("%s | %s %s\n%s RAM", Pipe, PROGRAM_NAME, VERSION_NUMBER, + Banner); + if (!quick) + printf (",cycle"); + for (p = root; p != NULL; p = p->next) + printresults (stdout, p, quick, extra); + /*}}} */ + CloseLink (TheLink); + printf ("\n"); + return (0); +} +/*}}} */ diff --git a/minix/commands/inmos/mtest16.h b/minix/commands/inmos/mtest16.h new file mode 100644 index 000000000..a53efb851 --- /dev/null +++ b/minix/commands/inmos/mtest16.h @@ -0,0 +1,144 @@ +/* automatically generated code - basename mtest16 */ + + +struct mtest16_struct { + unsigned char Code[1378]; + char Target[10]; + char Mode[10]; + long CodeSize; + long Offset; + long WorkSpace; + long VectorSpace; + int BytesPerWord; + int TotalSpace; +}; + +struct mtest16_struct mtest16_code = { + + { /* code */ + 0x20,0x60,0xB3,0x24, 0xF2,0xD4,0x24,0xF2, 0xD2,0x24,0xF2,0x21, + 0xD0,0x24,0xF2,0xD9, 0x24,0xF2,0x51,0xDA, 0x24,0xF2,0x52,0xDB, + 0x24,0xF2,0x53,0xDC, 0x24,0xF2,0x54,0xD5, 0x24,0xF2,0x55,0xD6, + 0x24,0xF2,0x56,0xD7, 0x24,0xF2,0x57,0xD8, 0x7E,0x15,0xFA,0x30, + 0xD3,0x42,0xD1,0x22, 0x24,0x41,0x21,0xFB, 0xD0,0x2D,0x40,0x21, + 0xFB,0x60,0xDD,0x60, 0x1E,0x23,0xF9,0x64, 0xB9,0x40,0xD5,0x22, + 0x23,0x40,0x21,0xFB, 0x16,0x21,0x40,0x24, 0xFA,0x10,0x24,0x1B, + 0x42,0xF7,0x16,0x24, 0x1B,0x21,0x40,0xF7, 0x16,0x51,0xF1,0xD5, + 0x16,0x52,0xD1,0x71, 0x30,0xD4,0x16,0x52, 0xD2,0x16,0x54,0xDE, + 0x16,0x56,0xD3,0x40, 0x72,0xE0,0x40,0x16, 0x83,0x23,0xFB,0x40, + 0x73,0xE0,0x16,0x83, 0xF1,0xC0,0x28,0xAB, 0x75,0x16,0x51,0x23, + 0xFB,0x72,0x30,0x25, 0xAF,0x16,0xD0,0x72, 0x30,0x72,0x30,0x24, + 0xF2,0xFA,0x24,0x20, 0x40,0xF0,0x22,0x25, 0x96,0x24,0x20,0x40, + 0xD1,0x72,0x30,0x71, 0xF9,0x21,0xA0,0x71, 0x24,0xF2,0xFA,0x30, + 0x71,0xF4,0xC0,0xA7, 0x71,0x24,0x20,0x80, 0xD1,0x61,0x0A,0x73, + 0x30,0xA7,0x41,0x16, 0x83,0x23,0xFB,0x22, 0x0B,0x71,0x72,0x30, + 0xF4,0xA8,0x2F,0x4F, 0x16,0x83,0x23,0xFB, 0x21,0x0E,0x74,0x72, + 0x30,0x22,0x20,0x50, 0xF9,0xC0,0xA6,0x42, 0x16,0x83,0x23,0xFB, + 0x0F,0x72,0x30,0x22, 0x20,0x50,0x67,0x20, 0x20,0xC0,0xA5,0x42, + 0x16,0x83,0x23,0xFB, 0x24,0x19,0x21,0x40, 0xFF,0x7E,0xD0,0x24, + 0x20,0x40,0x72,0x30, 0x24,0xF2,0xFA,0x24, 0x17,0x21,0x2D,0x90, + 0x16,0x24,0x19,0x21, 0x40,0xFB,0x72,0x30, 0x22,0x20,0x50,0x72, + 0xE0,0x69,0x0F,0x6C, 0x0A,0x43,0xD1,0x21, 0x25,0x4D,0x21,0xFB, + 0xD0,0x21,0x41,0x60, 0x14,0xFD,0x2D,0x48, 0x62,0x1C,0xFD,0x60, + 0xBF,0x22,0xF2,0xD0, 0x10,0x21,0x13,0x42, 0xFB,0x60,0x06,0x40, + 0x11,0x81,0x23,0xFB, 0x13,0x21,0x71,0x42, 0xF7,0x73,0x60,0xCF, + 0x29,0xA9,0x11,0x21, 0x71,0x41,0xF7,0x11, 0xF1,0xC0,0x26,0xA9, + 0x13,0x21,0x71,0x42, 0xF7,0x11,0x51,0x21, 0x71,0x41,0xF7,0x73, + 0x60,0x8F,0xD3,0x40, 0x11,0x81,0x23,0xFB, 0x73,0xC0,0x23,0xA3, + 0x11,0x51,0xF1,0x2F, 0xCF,0x22,0xA5,0x41, 0xD6,0x43,0xD7,0x76, + 0x21,0x7C,0xF5,0x44, 0x21,0xFF,0xD0,0x70, 0x21,0x13,0xFA,0x30, + 0xD5,0x70,0x21,0x17, 0xFA,0x30,0xD4,0x15, 0x21,0xF2,0x14,0x21, + 0xF2,0x16,0x21,0x4F, 0x22,0xF1,0x60,0x0E, 0x41,0x11,0x83,0x23, + 0xFB,0x21,0x0C,0x11, 0x51,0xF1,0x21,0x17, 0xFA,0x30,0xD4,0x40, + 0x11,0x83,0x23,0xFB, 0x74,0x60,0x4F,0xFF, 0x74,0x40,0xFE,0x40, + 0xD0,0x13,0x74,0x21, 0x71,0x2E,0x92,0x22, 0x04,0x41,0x11,0x83, + 0xF1,0xF4,0x21,0xA1, 0x11,0x51,0xF1,0x21, 0x17,0xFA,0x30,0xD4, + 0x74,0x60,0x4F,0xFF, 0x11,0x74,0x41,0xFB, 0x0C,0x11,0xF1,0xC2, + 0xA6,0x41,0x11,0x81, 0x23,0xFB,0x02,0x21, 0xF0,0x22,0x02,0x11, + 0x51,0xF1,0xC4,0xAD, 0x11,0x81,0xF1,0xD0, 0x13,0x21,0x12,0x21, + 0x71,0x2A,0x9A,0x21, 0x00,0x11,0x81,0xF1, 0xD0,0x13,0x11,0x51, + 0xF1,0x21,0x17,0xFA, 0x30,0x21,0x71,0x29, 0x98,0x6C,0x09,0x24, + 0xF3,0x41,0xD2,0x43, 0xD3,0x23,0x74,0x72, 0xF5,0x44,0x21,0xFF, + 0x22,0x1B,0xFA,0x30, 0xD1,0x71,0x41,0x24, 0xF8,0x12,0x21,0x45, + 0x22,0xF1,0x22,0x18, 0x41,0x24,0xF8,0x24, 0xF4,0x41,0xD2,0x43, + 0xD3,0x23,0x74,0x72, 0xF5,0x44,0x21,0xFF, 0x22,0x1B,0xFA,0x30, + 0xD1,0x71,0x41,0x40, 0x22,0xFF,0xA2,0x72, 0xD5,0x12,0x21,0x49, + 0x22,0xF1,0x22,0x18, 0x41,0x21,0x4E,0x22, 0xFF,0x24,0xF5,0x23, + 0x74,0x75,0xF5,0x44, 0x21,0xFF,0x22,0x1B, 0xFA,0x30,0xD1,0x14, + 0x71,0x42,0xF7,0x40, 0xD0,0x14,0x23,0x74, 0x22,0x1F,0xFA,0x30, + 0x71,0x23,0x92,0x21, 0x02,0x14,0x22,0x18, 0x42,0xF7,0x40,0xD0, + 0x14,0x23,0x74,0x22, 0x1F,0xFA,0x30,0x22, 0x18,0x21,0x9E,0x67, + 0x06,0x10,0x81,0x23, 0xF9,0x21,0xF5,0x12, 0xF3,0xBD,0x22,0xF0, + 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, 0x00,0x60,0xB5,0x41, 0x7F,0xF4,0xA4,0x7E, + 0x7D,0x42,0xFB,0x7E, 0x30,0x40,0xF9,0x22, 0xAC,0x7E,0x30,0x21, + 0x44,0xF9,0x21,0xA2, 0x11,0x7C,0x21,0x44, 0xF7,0x11,0x7D,0x21, + 0x44,0xFB,0x7E,0x30, 0x61,0x8C,0x7E,0xE0, 0x21,0x01,0x7E,0x30, + 0xD0,0x11,0x7C,0x70, 0xF7,0x7E,0x30,0xD0, 0x11,0x7D,0x70,0xFB, + 0x40,0x7E,0xE0,0x63, 0x0E,0xBB,0x22,0xF0, 0x60,0xBE,0x10,0x73, + 0x21,0x50,0x42,0xF7, 0x74,0x74,0x75,0x23, 0xF4,0x24,0xFA,0x10, + 0x73,0x21,0x50,0x42, 0xF7,0x11,0x73,0x21, 0x50,0x42,0xF7,0x71, + 0x70,0xF4,0x76,0xE0, 0xB2,0x22,0xF0,0x60, 0xBD,0x77,0x56,0xD1, + 0x71,0x41,0x24,0xF6, 0x41,0x21,0xF3,0x22, 0xF2,0xD2,0x77,0x51, + 0xF1,0xD0,0x45,0x70, 0xF9,0x24,0xAE,0x71, 0x30,0xC0,0x24,0xA9, + 0x70,0x42,0xF9,0xAA, 0x43,0x70,0xF4,0x22, 0xAF,0x70,0xC4,0xAE, + 0x23,0x01,0x70,0xAC, 0x41,0x70,0xF4,0x21, 0xA6,0x70,0xC2,0xA2, + 0x21,0x08,0x21,0xF0, 0x71,0x60,0x4F,0x10, 0x21,0x2D,0x9B,0x71, + 0x40,0x10,0x21,0x2D, 0x95,0x21,0x09,0x71, 0x12,0x10,0x25,0x9B, + 0x21,0x02,0x71,0x12, 0x10,0x2E,0x96,0x0C, 0x71,0x75,0x74,0x21, + 0x27,0x93,0x05,0x71, 0x76,0x10,0x21,0x92, 0x70,0x81,0xD0,0x65, + 0x0D,0x70,0x21,0x20, 0x40,0x21,0xF3,0x77, 0x51,0x23,0xFB,0xB3, + 0x22,0xF0,0x60,0xBE, 0x40,0xD0,0x73,0x35, 0xD1,0x71,0xAC,0x74, + 0x70,0xF5,0x70,0x73, 0x34,0xFA,0xE0,0x10, 0x4C,0x22,0xF1,0x40, + 0xD0,0x73,0x35,0xD1, 0x71,0x21,0xA5,0x74, 0x70,0xF5,0x70,0x73, + 0x34,0xFA,0x30,0x23, 0xF3,0x75,0x30,0x24, 0xFB,0x75,0xE0,0x10, + 0x21,0x45,0x22,0xF1, 0xB2,0x22,0xF0,0x60, 0xB6,0x7B,0x35,0x23, + 0xF4,0xD6,0x7B,0x34, 0xD2,0x40,0xD1,0x7C, 0x21,0x29,0x9B,0x40, + 0xD4,0x42,0xD5,0x74, 0xC0,0xA4,0x7C,0x30, 0xD9,0x03,0x79,0x7C, + 0xE0,0x4F,0x7C,0x30, 0x24,0xF6,0xD3,0x4A, 0x73,0xF9,0xC0,0xA6, + 0x26,0x26,0x26,0x41, 0xD3,0x08,0x73,0x2D, 0x4D,0x21,0xFB,0xFA, + 0x30,0xD3,0x7C,0x21, 0x27,0x90,0x27,0x2F, 0x2F,0x4F,0x7C,0x30, + 0x24,0xF6,0x7B,0x35, 0x21,0xFF,0xD0,0x40, 0xD7,0x7B,0x35,0x42, + 0x22,0xFC,0xD8,0x78, 0x24,0xF2,0x21,0xF3, 0x23,0xA3,0x70,0x73, + 0xF5,0x76,0x21,0xFF, 0xD0,0x7C,0x21,0x24, 0x99,0x2F,0x4F,0x7C, + 0x30,0x24,0xF6,0x21, 0x20,0x40,0x21,0xF3, 0xD1,0x74,0xC0,0xA7, + 0x71,0x70,0x72,0xF2, 0x23,0xFB,0x0D,0x70, 0x72,0xF2,0xF1,0x71, + 0x23,0xF3,0x7D,0x30, 0x24,0xFB,0x7D,0xE0, 0x17,0x23,0x43,0x22, + 0xF1,0x14,0x27,0x4B, 0x22,0xF1,0xBA,0x22, 0xF0,0x60,0xB8,0x7A, + 0x21,0x21,0x93,0x40, 0xD3,0x42,0xD4,0x73, 0xC0,0xA4,0x7A,0x30, + 0xD7,0x03,0x77,0x7A, 0xE0,0x4F,0x7A,0x30, 0x24,0xF6,0xD2,0x4A, + 0x72,0xF9,0xC0,0xA6, 0x26,0x26,0x26,0x41, 0xD2,0x08,0x72,0x25, + 0x45,0x21,0xFB,0xFA, 0x30,0xD2,0x7A,0x2E, 0x99,0x27,0x2F,0x2F, + 0x4F,0x7A,0x30,0x24, 0xF6,0x79,0x35,0x21, 0xFF,0xD0,0x40,0xD5, + 0x79,0x35,0x42,0x22, 0xFC,0xD6,0x76,0x24, 0xF2,0x21,0xF3,0x22, + 0xAB,0x70,0x72,0xF5, 0x79,0x35,0x21,0xFF, 0xD0,0x7A,0x2C,0x92, + 0x7A,0x30,0xD1,0x73, 0xC0,0xA7,0x71,0x70, 0x79,0x34,0xFA,0xE0, + 0x0E,0x70,0x79,0x34, 0xFA,0x30,0x71,0x23, 0xF3,0x7B,0x30,0x24, + 0xFB,0x7B,0xE0,0x15, 0x22,0x4B,0x22,0xF1, 0x13,0x27,0x42,0x22, + 0xF1,0xB8,0x22,0xF0, 0xFB,0x03,0xA3,0x04, 0x31,0x0C,0x53,0x12, + 0x67,0x1F,0x9F,0x22, 0x45,0x37,0xEF,0x3E, 0x8D,0x46,0x61,0x66, + 0x00,0x60,0xBC,0x76, 0x23,0xF4,0xD2,0x67, 0x21,0x28,0x41,0x75, + 0xE0,0x76,0x60,0x8E, 0xD1,0x76,0x60,0x8F, 0xD3,0x75,0x75,0x51, + 0x71,0x23,0xF4,0x24, 0xFA,0x62,0x2F,0x26, 0x40,0x75,0xE0,0x67, + 0x21,0x24,0x40,0x75, 0xE1,0x26,0x20,0x28, 0x41,0x76,0x60,0x8D, + 0x75,0xFA,0xE0,0x69, 0x27,0x4F,0x76,0x60, 0x8E,0x75,0xFA,0xE0, + 0x75,0xF6,0xD0,0xD0, 0x72,0x70,0xFC,0x60, 0x88,0x77,0x30,0x24, + 0xFB,0x77,0xE0,0xB4, 0x22,0xF0,0x60,0xBE, 0x74,0x73,0x34,0xE0, + 0x73,0x35,0x60,0x8F, 0xD0,0x73,0x35,0x60, 0x8F,0xD1,0x73,0x34, + 0x73,0x34,0x51,0x70, 0x23,0xF4,0x24,0xFA, 0x40,0xD0,0x73,0x35, + 0xD1,0x71,0x21,0xA3, 0x70,0x73,0x34,0xFA, 0x30,0x74,0x23,0xF3, + 0x75,0x30,0x24,0xFB, 0x75,0xE0,0x10,0x21, 0x43,0x22,0xF1,0xB2, + 0x22,0xF0,0x43,0x71, 0x30,0x24,0xF6,0xD3, 0x73,0xA3,0x73,0xC3, + 0xA8,0x71,0x30,0x41, 0x24,0xF0,0x71,0xE0, 0x0B,0x71,0x30,0x41, + 0x24,0xF0,0x24,0xF2, 0x24,0xFB,0x71,0xE0, 0x22,0xF0 }, + + "TA", /* target */ + "Undefined", /* mode */ + 1378, /* code size */ + 1, /* offset */ + 111, /* workspace */ + 0, /* vectorspace */ + 2, /* bytes per word */ + 1600 /* total code requirement not including parameter space */ + +}; /* end of generated code */ diff --git a/minix/commands/inmos/mtest32.h b/minix/commands/inmos/mtest32.h new file mode 100644 index 000000000..613ae10c8 --- /dev/null +++ b/minix/commands/inmos/mtest32.h @@ -0,0 +1,144 @@ +/* automatically generated code - basename mtest32 */ + + +struct mtest32_struct { + unsigned char Code[1372]; + char Target[10]; + char Mode[10]; + long CodeSize; + long Offset; + long WorkSpace; + long VectorSpace; + int BytesPerWord; + int TotalSpace; +}; + +struct mtest32_struct mtest32_code = { + + { /* code */ + 0x20,0x20,0x20,0x60, 0xB2,0x22,0x24,0x4A, 0x21,0xFB,0xD5,0x24, + 0xF2,0x21,0xD1,0x24, 0xF2,0xDA,0x24,0xF2, 0x51,0xDB,0x24,0xF2, + 0x52,0xDC,0x24,0xF2, 0x53,0xDD,0x24,0xF2, 0x54,0xD6,0x24,0xF2, + 0x55,0xD7,0x24,0xF2, 0x56,0xD8,0x24,0xF2, 0x57,0xD9,0x7F,0x16, + 0xFA,0x30,0xD3,0x24, 0xF2,0xD4,0x24,0xF2, 0xD2,0x42,0xD1,0x22, + 0x20,0x4D,0x21,0xFB, 0xD0,0x2B,0x44,0x21, 0xFB,0x60,0xDD,0x60, + 0x1E,0x23,0xF9,0x63, 0xBB,0x40,0xD9,0x10, 0x23,0x19,0x42,0xF7, + 0x13,0x23,0x19,0x21, 0x40,0xF7,0x13,0x82, 0xF1,0xD9,0x13,0x51, + 0xD1,0x71,0x30,0xD8, 0x13,0x51,0xD2,0x13, 0x52,0xDA,0x13,0x53, + 0xD7,0x40,0x72,0xE0, 0x40,0x13,0x83,0x23, 0xFB,0x40,0x77,0xE0, + 0x13,0x83,0xF1,0xC0, 0x27,0xA9,0x79,0x13, 0x82,0x23,0xFB,0x72, + 0x30,0x24,0xAE,0x13, 0xD0,0x72,0x30,0x72, 0x30,0x24,0xF2,0xFA, + 0x22,0x20,0x40,0xF0, 0x22,0x22,0x9D,0x22, 0x20,0x40,0xD1,0x72, + 0x30,0x71,0xF9,0x21, 0xA0,0x71,0x24,0xF2, 0xFA,0x30,0x71,0xF4, + 0xC0,0xA7,0x71,0x22, 0x20,0x80,0xD1,0x61, 0x0A,0x77,0x30,0xA7, + 0x41,0x13,0x83,0x23, 0xFB,0x21,0x0A,0x71, 0x72,0x30,0xF4,0xA7, + 0x2F,0x4F,0x13,0x83, 0x23,0xFB,0x0E,0x78, 0x72,0x30,0x22,0x20, + 0x80,0xF9,0xC0,0xA5, 0x42,0x13,0x83,0x23, 0xFB,0x23,0x17,0x21, + 0x40,0xFF,0x7A,0xD0, 0x22,0x20,0x40,0x72, 0x30,0x24,0xF2,0xFA, + 0x23,0x15,0x21,0x2B, 0x98,0x13,0x23,0x17, 0x21,0x40,0xFB,0x72, + 0x30,0x28,0x50,0x72, 0xE0,0x67,0x01,0x6A, 0x06,0x43,0xD1,0x21, + 0x24,0x45,0x21,0xFB, 0xD0,0x21,0x41,0x60, 0x18,0xFD,0x2B,0x48, + 0x61,0x15,0xFD,0x60, 0xBF,0x22,0xF2,0xD0, 0x10,0x21,0x14,0x44, + 0xFB,0x60,0x06,0x40, 0x11,0x81,0x23,0xFB, 0x21,0x22,0x4F,0x21, + 0xFB,0x12,0x44,0x24, 0xFA,0x12,0x7D,0x42, 0xF7,0x72,0x2F,0x2F, + 0x2F,0xCF,0x27,0xA3, 0x11,0x7D,0x41,0xF7, 0x11,0xF1,0xC0,0x24, + 0xA4,0x12,0x7D,0x42, 0xF7,0x11,0x82,0x7D, 0x41,0xF7,0x72,0x60, + 0x8F,0xD2,0x40,0x11, 0x81,0x23,0xFB,0x72, 0xC0,0x21,0xA1,0x11, + 0x82,0xF1,0x2F,0xCF, 0xA4,0x21,0x2F,0xFF, 0x05,0x41,0x11,0x83, + 0x23,0xFB,0x21,0x0B, 0x11,0x82,0xF1,0x21, 0x14,0xFA,0x30,0xD3, + 0x40,0x11,0x83,0x23, 0xFB,0x7F,0x73,0x42, 0xFB,0x73,0x40,0xFE, + 0x40,0xD0,0x12,0x73, 0x7D,0x2D,0x9E,0x22, 0x04,0x41,0x11,0x83, + 0xF1,0xF4,0x21,0xA1, 0x11,0x82,0xF1,0x21, 0x14,0xFA,0x30,0xD0, + 0x7F,0x70,0x42,0xFB, 0x11,0x70,0x41,0xFB, 0x0C,0x11,0xF1,0xC2, + 0xA6,0x41,0x11,0x81, 0x23,0xFB,0x02,0x21, 0xF0,0x21,0x0E,0x11, + 0x82,0xF1,0xC4,0xAA, 0x11,0x81,0xF1,0xD0, 0x12,0x1E,0x7D,0x2A, + 0x98,0x0F,0x11,0x81, 0xF1,0xD0,0x12,0x11, 0x82,0xF1,0x21,0x14, + 0xFA,0x30,0x7D,0x29, 0x98,0x69,0x02,0x28, 0x49,0x21,0xFB,0x14, + 0x44,0x24,0xFA,0x24, 0xF3,0x41,0xD2,0x43, 0xD3,0x22,0x7C,0x72, + 0xF5,0x44,0x21,0xFF, 0x22,0x13,0xFA,0x30, 0xD1,0x71,0x41,0x24, + 0xF8,0x12,0x21,0x45, 0x22,0xF1,0x21,0x1F, 0x41,0x24,0xF8,0x24, + 0xF4,0x41,0xD2,0x43, 0xD3,0x22,0x7C,0x72, 0xF5,0x44,0x21,0xFF, + 0x22,0x13,0xFA,0x30, 0xD1,0x71,0x41,0x40, 0x22,0xFF,0xA2,0x72, + 0xD5,0x12,0x21,0x49, 0x22,0xF1,0x21,0x1F, 0x41,0x21,0x4E,0x22, + 0xFF,0x24,0xF5,0x22, 0x7C,0x75,0xF5,0x44, 0x21,0xFF,0x22,0x13, + 0xFA,0x30,0xD1,0x14, 0x71,0x42,0xF7,0x40, 0xD0,0x14,0x22,0x7C, + 0x22,0x17,0xFA,0x30, 0x71,0x22,0x9A,0x21, 0x02,0x14,0x21,0x1F, + 0x44,0xF7,0x40,0xD0, 0x14,0x22,0x7C,0x22, 0x17,0xFA,0x30,0x21, + 0x1F,0x21,0x96,0x68, 0x0E,0x10,0x81,0x23, 0xF9,0x21,0xF5,0x12, + 0xF3,0xBE,0x22,0xF0, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF,0xFF, + 0x00,0x60,0xBA,0x41, 0x7A,0xF4,0xAD,0x79, 0x30,0x28,0x20,0x20, + 0x40,0x25,0xF6,0xD0, 0x10,0x78,0x42,0xFB, 0x79,0x30,0x40,0xF9, + 0x22,0xAC,0x79,0x30, 0x21,0x44,0xF9,0x21, 0xA2,0x11,0x77,0x21, + 0x44,0xF7,0x11,0x78, 0x21,0x44,0xFB,0x79, 0x30,0x61,0x8C,0x79, + 0xE0,0x21,0x01,0x79, 0x30,0xD0,0x11,0x77, 0x70,0xF7,0x79,0x30, + 0xD0,0x11,0x78,0x70, 0xFB,0x40,0x79,0xE0, 0x63,0x0E,0xB6,0x22, + 0xF0,0x60,0xBE,0x10, 0x73,0x21,0x51,0x44, 0xF7,0x74,0x74,0x75, + 0x23,0xF4,0x24,0xFA, 0x10,0x73,0x21,0x51, 0x44,0xF7,0x11,0x73, + 0x21,0x51,0x44,0xF7, 0x71,0x70,0xF4,0x76, 0xE0,0xB2,0x22,0xF0, + 0x60,0xBD,0x77,0x53, 0xD1,0x71,0x43,0x24, 0xF6,0x41,0x21,0xF3, + 0x22,0xF2,0xD2,0x77, 0x82,0xF1,0xD0,0x45, 0x70,0xF9,0x24,0xAE, + 0x71,0x30,0xC0,0x24, 0xA9,0x70,0x42,0xF9, 0xAA,0x43,0x70,0xF4, + 0x22,0xAF,0x70,0xC4, 0xAE,0x23,0x01,0x70, 0xAC,0x41,0x70,0xF4, + 0x21,0xA6,0x70,0xC2, 0xA2,0x21,0x08,0x21, 0xF0,0x71,0x60,0x4F, + 0x10,0x22,0x20,0x90, 0x71,0x40,0x10,0x21, 0x2F,0x9A,0x21,0x09, + 0x71,0x12,0x10,0x25, 0x9B,0x21,0x02,0x71, 0x12,0x10,0x2E,0x97, + 0x0C,0x71,0x75,0x74, 0x21,0x29,0x9C,0x05, 0x71,0x76,0x10,0x21, + 0x92,0x70,0x81,0xD0, 0x65,0x0D,0x70,0x21, 0x20,0x40,0x21,0xF3, + 0x77,0x82,0x23,0xFB, 0xB3,0x22,0xF0,0x60, 0xBE,0x40,0xD0,0x73, + 0x35,0xD1,0x71,0xAC, 0x74,0x70,0xF5,0x70, 0x73,0x34,0xFA,0xE0, + 0x10,0x4C,0x22,0xF1, 0x40,0xD0,0x73,0x35, 0xD1,0x71,0x21,0xA5, + 0x74,0x70,0xF5,0x70, 0x73,0x34,0xFA,0x30, 0x23,0xF3,0x75,0x30, + 0x24,0xFB,0x75,0xE0, 0x10,0x21,0x45,0x22, 0xF1,0xB2,0x22,0xF0, + 0x60,0xB6,0x7B,0x35, 0x23,0xF4,0xD6,0x7B, 0x34,0xD2,0x40,0xD1, + 0x7C,0x21,0x2C,0x90, 0x40,0xD4,0x42,0xD5, 0x74,0xC0,0xA4,0x7C, + 0x30,0xD9,0x03,0x79, 0x7C,0xE0,0x4F,0x7C, 0x30,0x24,0xF6,0xD3, + 0x4E,0x73,0xF9,0xC0, 0xA7,0x21,0x28,0x2A, 0x2F,0x47,0xD3,0x08, + 0x73,0x2D,0x4F,0x21, 0xFB,0xFA,0x30,0xD3, 0x7C,0x21,0x29,0x94, + 0x24,0xF2,0x23,0xF2, 0x7C,0x30,0x24,0xF6, 0x7B,0x35,0x21,0xFF, + 0xD0,0x40,0xD7,0x7B, 0x35,0x42,0x22,0xFC, 0xD8,0x78,0x24,0xF2, + 0x21,0xF3,0x23,0xA3, 0x70,0x73,0xF5,0x76, 0x21,0xFF,0xD0,0x7C, + 0x21,0x26,0x9D,0x2F, 0x4F,0x7C,0x30,0x24, 0xF6,0x21,0x20,0x40, + 0x21,0xF3,0xD1,0x74, 0xC0,0xA7,0x71,0x70, 0x72,0xF2,0x23,0xFB, + 0x0D,0x70,0x72,0xF2, 0xF1,0x71,0x23,0xF3, 0x7D,0x30,0x24,0xFB, + 0x7D,0xE0,0x17,0x23, 0x43,0x22,0xF1,0x14, 0x27,0x4C,0x22,0xF1, + 0xBA,0x22,0xF0,0x60, 0xB8,0x7A,0x21,0x23, 0x97,0x40,0xD3,0x42, + 0xD4,0x73,0xC0,0xA4, 0x7A,0x30,0xD7,0x03, 0x77,0x7A,0xE0,0x4F, + 0x7A,0x30,0x24,0xF6, 0xD2,0x4E,0x72,0xF9, 0xC0,0xA7,0x21,0x28, + 0x2A,0x2F,0x47,0xD2, 0x08,0x72,0x25,0x46, 0x21,0xFB,0xFA,0x30, + 0xD2,0x7A,0x21,0x20, 0x9B,0x24,0xF2,0x23, 0xF2,0x7A,0x30,0x24, + 0xF6,0x79,0x35,0x21, 0xFF,0xD0,0x40,0xD5, 0x79,0x35,0x42,0x22, + 0xFC,0xD6,0x76,0x24, 0xF2,0x21,0xF3,0x22, 0xAB,0x70,0x72,0xF5, + 0x79,0x35,0x21,0xFF, 0xD0,0x7A,0x2E,0x94, 0x7A,0x30,0xD1,0x73, + 0xC0,0xA7,0x71,0x70, 0x79,0x34,0xFA,0xE0, 0x0E,0x70,0x79,0x34, + 0xFA,0x30,0x71,0x23, 0xF3,0x7B,0x30,0x24, 0xFB,0x7B,0xE0,0x15, + 0x22,0x4B,0x22,0xF1, 0x13,0x27,0x44,0x22, 0xF1,0xB8,0x22,0xF0, + 0xFB,0x03,0x00,0x00, 0xA3,0x04,0x00,0x00, 0x31,0x0C,0x00,0x00, + 0x53,0x12,0x00,0x00, 0x67,0x1F,0x00,0x00, 0x9F,0x22,0x00,0x00, + 0x45,0x37,0x00,0x00, 0xEF,0x3E,0x00,0x00, 0x8D,0x46,0x00,0x00, + 0x61,0x66,0x00,0x00, 0xA5,0xAD,0x00,0x00, 0x6B,0x19,0x01,0x00, + 0xF7,0x8A,0x01,0x00, 0xA3,0x86,0x01,0x00, 0x00,0x00,0x00,0x60, + 0xBC,0x23,0x47,0x21, 0xFB,0xD0,0x70,0x32, 0x75,0xE0,0x76,0x60, + 0x8E,0xD2,0x76,0x60, 0x8F,0xD3,0x75,0x75, 0x51,0x72,0x23,0xF4, + 0x24,0xFA,0x70,0x31, 0x75,0xE0,0x70,0x30, 0x76,0x60,0x8D,0x75, + 0xFA,0xE0,0x75,0xF6, 0xD1,0xD1,0x76,0x23, 0xF4,0xD2,0x72,0x71, + 0xFC,0x60,0x82,0x77, 0x30,0x24,0xFB,0x77, 0xE0,0xB4,0x22,0xF0, + 0x81,0x60,0x7F,0xF6, 0x60,0xDF,0x40,0x81, 0x81,0x81,0x81,0x81, + 0x60,0xBE,0x74,0x73, 0x34,0xE0,0x73,0x35, 0x60,0x8F,0xD0,0x73, + 0x35,0x60,0x8F,0xD1, 0x73,0x34,0x73,0x34, 0x51,0x70,0x23,0xF4, + 0x24,0xFA,0x40,0xD0, 0x73,0x35,0xD1,0x71, 0x21,0xA3,0x70,0x73, + 0x34,0xFA,0x30,0x74, 0x23,0xF3,0x75,0x30, 0x24,0xFB,0x75,0xE0, + 0x10,0x21,0x43,0x22, 0xF1,0xB2,0x22,0xF0, 0x43,0x71,0x30,0x24, + 0xF6,0xD3,0x73,0xA3, 0x73,0xC3,0xA8,0x71, 0x30,0x41,0x24,0xF0, + 0x71,0xE0,0x0B,0x71, 0x30,0x41,0x24,0xF0, 0x24,0xF2,0x24,0xFB, + 0x71,0xE0,0x22,0xF0 }, + + "TA", /* target */ + "Undefined", /* mode */ + 1372, /* code size */ + 3, /* offset */ + 94, /* workspace */ + 0, /* vectorspace */ + 4, /* bytes per word */ + 1748 /* total code requirement not including parameter space */ + +}; /* end of generated code */ diff --git a/minix/commands/inmos/pack.h b/minix/commands/inmos/pack.h new file mode 100644 index 000000000..f828b5cf7 --- /dev/null +++ b/minix/commands/inmos/pack.h @@ -0,0 +1,160 @@ + +/* + -- --------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- pack.h + -- + -- Macros to cut and paste the Tbuf + -- + -- Copyright (c) INMOS Ltd., 1988. + -- All Rights Reserved. + -- + -- --------------------------------------------------------------------------- +*/ + + + +#ifndef _INMOS_H +#include "inmos.h" +#endif + + + +/* + * some stuff used in processing all commands + */ + +#define BUFFER_DECLARATIONS register BYTE *InBuf, *OutBuf; int OutCount +#define INIT_BUFFERS InBuf = &Tbuf[3]; OutBuf = &Tbuf[2]; OutCount = 0 +#define REPLY PUT_COUNT( OutCount ); return + + + + +/* + * PACKING ROUTINES + */ + + +/* + * pack one byte with int x + */ + +#define PUT_BYTE(x) {*OutBuf++ = x; OutCount++;} + + +/* + * pack lower 16 bits of int x into 2 bytes + */ + +#ifdef BIG_ENDIAN +#define PUT_INT16(x) {BYTE *c; c=(BYTE *)&x+3; *OutBuf++ = *c--; *OutBuf++ = *c--; OutCount += 2;} +#else +#define PUT_INT16(x) {BYTE *c; c=(BYTE *)&x; *OutBuf++ = *c++; *OutBuf++ = *c; OutCount += 2;} +#endif + + +/* + * pack int32 into 4 bytes + */ + +#ifdef BIG_ENDIAN +#define PUT_INT32(x) {BYTE *c; c=(BYTE *)&x+3; *OutBuf++ = *c--; *OutBuf++ = *c--; *OutBuf++ = *c--; *OutBuf++ = *c; OutCount += 4;} +#else +#define PUT_INT32(x) {BYTE *c; c=(BYTE *)&x; *OutBuf++ = *c++; *OutBuf++ = *c++; *OutBuf++ = *c++; *OutBuf++ = *c; OutCount += 4;} +#endif + + +/* + * pack FILE *x as 4 bytes + */ + +#ifdef MSC +#define PUT_FD(x) {BYTE *c; c=(BYTE *)&x; *OutBuf++ = *c++; *OutBuf++ = *c;*OutBuf++ = 0; *OutBuf++ = 0; OutCount += 4;} +#else +#define PUT_FD(x) PUT_INT32(x) +#endif + + +/* + * pack lower 16 bits of int x as 2 bytes and then pack x bytes from y + */ + +#ifdef BIG_ENDIAN +#define PUT_SLICE(x,y) {int i; BYTE *c; c=(BYTE *)&x+3; *OutBuf++ = *c--; *OutBuf++ = *c--; c=(BYTE *)y; for( i=0; i +#include + +#include "inmos.h" +#include "iserver.h" +#include "pack.h" + + +EXTERN BYTE Tbuf[TRANSACTION_BUFFER_SIZE]; + + +EXTERN BOOL CocoPops; /* for DEBUG */ +EXTERN BOOL VerboseSwitch; + +EXTERN BYTE RealCommandLine[MAX_COMMAND_LINE_LENGTH+1]; /* for SpCommand */ +EXTERN BYTE DoctoredCommandLine[MAX_COMMAND_LINE_LENGTH+1]; + +EXTERN BOOL AnalyseSwitch; /* for SpCore */ +EXTERN BYTE *CoreDump; +EXTERN INT32 CoreSize; + + +/* + * SpCommand + */ + +PUBLIC VOID SpCommand() +{ + BUFFER_DECLARATIONS; + BOOL All; + int Size; + BYTE *Cl; + + DEBUG(( "SP.COMMAND" )); + INIT_BUFFERS; + GET_BYTE( All ); DEBUG(( "%d", All )); + + if ( All ) + Cl = RealCommandLine; + else + Cl = DoctoredCommandLine; + + PUT_BYTE( SP_SUCCESS ); + Size = strlen( (char *)Cl ); + PUT_SLICE( Size, Cl ); + REPLY; +} + + + + +/* + * SpCore + */ + +PUBLIC VOID SpCore() +{ + BUFFER_DECLARATIONS; + INT32 Offset; + int Off, Length; + + DEBUG(( "SP.CORE" )); + INIT_BUFFERS; + + if (AnalyseSwitch == 0) + { + DEBUG(("not peeked")); + PUT_BYTE(SP_ERROR); + REPLY; + } + else + { + GET_INT32( Offset ); DEBUG(( "offset %ld", (long)Offset )); + GET_INT16( Length ); DEBUG(( "length %d", Length )); + Off = (int)Offset; + if ( (Off >= CoreSize) || (Off < 0) || (Length < 0) ) + { + PUT_BYTE( SP_ERROR ); + REPLY; + } + if( Length + (int)Offset > CoreSize ) + { + Length = CoreSize - (int)Offset; + PUT_BYTE( SP_SUCCESS ); + PUT_SLICE( Length, &CoreDump[Offset] ); + REPLY; + } + else + { + PUT_BYTE( SP_SUCCESS ); + PUT_SLICE( Length, &CoreDump[Offset] ); + REPLY; + } + } +} + + + + +/* + * SpId + */ + +PUBLIC VOID SpId() +{ + BUFFER_DECLARATIONS; + BYTE Version, Host, OS, Board; + + DEBUG(( "SP.ID" )); + INIT_BUFFERS; + + Version = VERSION_ID; + Host = HOST_ID; + OS = OS_ID; + Board = BOARD_ID; + + PUT_BYTE( SP_SUCCESS ); + PUT_BYTE( Version ); + PUT_BYTE( Host ); + PUT_BYTE( OS ); + PUT_BYTE( Board ); + REPLY; +} + + + + +PUBLIC VOID SpUnknown() +{ + BUFFER_DECLARATIONS; + INFO(("[Encountered unknown primary tag (%d)]\n", Tbuf[2])); + INIT_BUFFERS; + PUT_BYTE( SP_UNIMPLEMENTED ); + PUT_COUNT( OutCount ); +} + + + +/* + * Eof + */ diff --git a/minix/commands/inmos/type16.h b/minix/commands/inmos/type16.h new file mode 100644 index 000000000..5d78b4f31 --- /dev/null +++ b/minix/commands/inmos/type16.h @@ -0,0 +1,45 @@ +/* automatically generated code - basename type16 */ + + +struct type16_struct { + unsigned char Code[186]; + char Target[10]; + char Mode[10]; + long CodeSize; + long Offset; + long WorkSpace; + long VectorSpace; + int BytesPerWord; + int TotalSpace; +}; + +struct type16_struct type16_code = { + + { /* code */ + 0x60,0xB1,0x24,0xF2, 0xD8,0x24,0xF2,0x51, 0xD9,0x24,0xF2,0x52, + 0xDA,0x24,0xF2,0x53, 0xDB,0x24,0xF2,0x54, 0xD4,0x24,0xF2,0x55, + 0xD5,0x24,0xF2,0x56, 0xD6,0x24,0xF2,0x57, 0xD7,0x21,0x70,0x18, + 0xFA,0xD3,0x21,0x70, 0x14,0xFA,0xD2,0x42, 0xD1,0x28,0x46,0x21, + 0xFB,0xD0,0x4B,0x21, 0xFB,0x68,0xD8,0x68, 0x19,0x23,0xF9,0x68, + 0xB6,0x28,0x1A,0xF3, 0x29,0x13,0xD5,0x60, 0x49,0x61,0x4D,0x40, + 0x21,0x27,0xFC,0xD6, 0xD4,0x74,0xC0,0xA4, 0x76,0x75,0xE0,0x03, + 0x74,0x75,0xE0,0x22, 0xF2,0xD3,0x23,0x2E, 0x48,0x24,0xF1,0x22, + 0xF2,0xD2,0x23,0x2F, 0x4C,0x72,0x73,0xF4, 0x22,0xFC,0x21,0x20, + 0x40,0x21,0xF3,0x29, 0x13,0x51,0x23,0xFB, 0x29,0x77,0x21,0x20, + 0x40,0x21,0xF3,0x29, 0x13,0x83,0x23,0xFB, 0x29,0x13,0x52,0xD1, + 0x40,0xD0,0x10,0x28, 0x79,0x30,0x41,0xF7, 0x22,0xF2,0xD3,0x17, + 0x28,0x79,0x30,0x21, 0x20,0x40,0xF7,0x22, 0xF2,0xD2,0x72,0x73, + 0xF4,0x71,0xE0,0x28, 0x7A,0x30,0xD1,0x71, 0x46,0xFF,0x29,0x13, + 0x71,0x46,0xFB,0x21, 0x2F,0xFF,0x10,0x81, 0x23,0xF9,0x21,0xF5, + 0x28,0x17,0xF3,0xBF, 0x22,0xF0 }, + + "TA", /* target */ + "Undefined", /* mode */ + 186, /* code size */ + 0, /* offset */ + 155, /* workspace */ + 0, /* vectorspace */ + 2, /* bytes per word */ + 496 /* total code requirement not including parameter space */ + +}; /* end of generated code */ diff --git a/minix/commands/inmos/type32.h b/minix/commands/inmos/type32.h new file mode 100644 index 000000000..d43d343ad --- /dev/null +++ b/minix/commands/inmos/type32.h @@ -0,0 +1,53 @@ +/* automatically generated code - basename type32 */ + + +struct type32_struct { + unsigned char Code[284]; + char Target[10]; + char Mode[10]; + long CodeSize; + long Offset; + long WorkSpace; + long VectorSpace; + int BytesPerWord; + int TotalSpace; +}; + +struct type32_struct type32_code = { + + { /* code */ + 0x20,0x20,0x60,0xB2, 0x21,0x20,0x47,0x21, 0xFB,0xD4,0x24,0xF2, + 0xDA,0x24,0xF2,0x51, 0xDB,0x24,0xF2,0x52, 0xDC,0x24,0xF2,0x53, + 0xDD,0x24,0xF2,0x54, 0xD6,0x24,0xF2,0x55, 0xD7,0x24,0xF2,0x56, + 0xD8,0x24,0xF2,0x57, 0xD9,0x7F,0x1A,0xFA, 0xD5,0x42,0xD1,0x2D, + 0x4A,0x21,0xFB,0xD0, 0x4A,0x21,0xFB,0x60, 0xD7,0x60,0x18,0x23, + 0xF9,0x60,0xB5,0x1B, 0xF3,0x21,0x77,0x1E, 0xFA,0xD6,0x1A,0xD1, + 0x60,0x49,0x61,0x4D, 0x40,0x21,0x27,0xFC, 0xD5,0xD4,0x74,0xC0, + 0xAE,0x75,0x28,0x20, 0x20,0x40,0x25,0xF6, 0xD0,0x10,0x71,0x42, + 0x24,0xFA,0x0D,0x74, 0x28,0x20,0x20,0x40, 0x25,0xF6,0xD0,0x10, + 0x71,0x42,0x24,0xFA, 0x71,0x10,0x42,0x24, 0xFA,0x70,0x2F,0x2F, + 0x2F,0x4F,0x24,0xF6, 0x28,0x20,0x20,0x40, 0x23,0xFA,0x60,0xC9, + 0x22,0xA0,0x7C,0x32, 0xD0,0x10,0x28,0xFE, 0x10,0x28,0xFE,0x28, + 0xFF,0xC0,0xA4,0x29, 0xF0,0x60,0xAC,0x10, 0x28,0xF8,0x7C,0x32, + 0x70,0xF4,0xC0,0xA6, 0x7C,0x51,0x71,0x42, 0x24,0xFA,0x22,0xF2, + 0xD3,0x23,0x2E,0x48, 0x24,0xF1,0x22,0xF2, 0xD2,0x23,0x2F,0x4C, + 0x72,0x73,0xF4,0x22, 0xFC,0x21,0x20,0x40, 0x21,0xF3,0x1A,0x82, + 0x23,0xFB,0x21,0x77, 0x21,0x20,0x40,0x21, 0xF3,0x1A,0x83,0x23, + 0xFB,0x1A,0x51,0xD7, 0x40,0xD0,0x10,0x76, 0x30,0x41,0xF7,0x22, + 0xF2,0xD3,0x24,0xF2, 0x21,0x2C,0x50,0x76, 0x30,0x21,0x20,0x40, + 0xF7,0x22,0xF2,0xD2, 0x72,0x73,0xF4,0x28, 0x20,0x20,0x40,0x25, + 0xF6,0xD0,0x10,0x77, 0x42,0x24,0xFA,0x7D, 0x30,0xD0,0x7C,0x70, + 0x42,0xFB,0x1A,0x70, 0x46,0xFB,0x21,0x2F, 0xFF,0x10,0x81,0x23, + 0xF9,0x21,0xF5,0x18, 0xF3,0xBE,0x22,0xF0, 0x06,0x00,0x00,0x00, + 0xF8,0xFF,0xFF,0xFF, 0x00,0x00,0x80,0x7F }, + + "TA", /* target */ + "Undefined", /* mode */ + 284, /* code size */ + 2, /* offset */ + 27, /* workspace */ + 0, /* vectorspace */ + 4, /* bytes per word */ + 392 /* total code requirement not including parameter space */ + +}; /* end of generated code */ diff --git a/minix/commands/inmos/udplink.c b/minix/commands/inmos/udplink.c new file mode 100644 index 000000000..2dfb06228 --- /dev/null +++ b/minix/commands/inmos/udplink.c @@ -0,0 +1,942 @@ +/* + -- ------------------------------------------------------------------------- + -- + -- ISERVER - INMOS standard file server + -- + -- udplink.c + -- + -- Link module for SubSystems connected via the UDP-LINK series of + -- products. + -- + -- Copyright (c) INMOS Limited., 1989, 1990 + -- + -- ------------------------------------------------------------------------ +*/ + +#include +#include +#include +#include + +#ifdef WIN_TCP + +#include +#include +#include +#include +#include +#include +#include +#else + +#include +#include + +#endif /* WIN and VMS */ + +#include +#include +#include +#include +#include +#include + +#include "inmos.h" +#include "iserver.h" +#include "udplink.h" + +#define NULL_LINK -1 +#define MAXLINE (255) +#define MAX_SEND (1400) + +EXTERN int TheLink; +EXTERN BOOL VerboseSwitch; +EXTERN BOOL CocoPops; +EXTERN int errno; + +#ifdef WIN_TCP +EXTERN int uerrno; +#define ERRORCODE uerrno +#else +#define ERRORCODE errno +#endif + +PRIVATE LINK ActiveLink = NULL_LINK; +PRIVATE BYTE DefaultDevice[64] = "TRANSNET"; +PRIVATE unsigned char h_seq = 0;/* host (vax) sequence no */ +PRIVATE unsigned char t_seq = 0;/* transputer sequence no. */ +PRIVATE struct data_dgram inp; +PRIVATE char *saved_buf = NULL; +PRIVATE int saved_len = 0; +PRIVATE int Result = SUCCEEDED; /* link error code status */ + +unsigned char prot_send(); +unsigned char peek_send(); +int timed_read(); +int data_send(); +int data_read(); + +/* OpenLink + - opens a link to the transputer (i.e the server) + + effects : returns either + ER_LINK_BAD (link already open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + or a LINK value (success) +*/ +PUBLIC LINK +OpenLink (Name) +BYTE *Name; +{ + struct sockaddr_in sin, rsin; + struct hostent *hp, *gethostbyname (); + int s, i, param_count; + int xa,xb,xc,xd; + char buf[1024]; + union { + unsigned long l_addr; + unsigned char addr[4]; + } address; + + if (ActiveLink != NULL_LINK) { + return (ER_LINK_BAD); + }; + + if ((*Name == 0) || (Name == NULL)) { + strcpy (Name, DefaultDevice); + }; + + s = socket (AF_INET, SOCK_DGRAM, 0); + + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl (INADDR_ANY); + sin.sin_port = htons (0); + if (bind (s, (struct sockaddr *) & sin, (short int) sizeof (sin)) < 0) { + DEBUG (( "cant bind, err=%d\n", ERRORCODE )); + return (ER_LINK_CANT); + }; + +#ifdef WIN_TCP + if ((hp = gethostbyname (Name)) == 0) { +#else + if ((hp = gethostbyname (Name)) == NULL) { +#endif + param_count = sscanf(Name, "%d.%d.%d.%d", &xa, &xb, &xc, &xd); + address.addr[0] = (unsigned char) xa; + address.addr[1] = (unsigned char) xb; + address.addr[2] = (unsigned char) xc; + address.addr[3] = (unsigned char) xd; + if (param_count == 4) { + rsin.sin_addr.s_addr = address.l_addr; + } else { + DEBUG(( "bad internet address\n" )); + return (ER_LINK_BAD); + }; + } else { /* Name is a textual name */ + bcopy ((char *) hp->h_addr, (char *) &rsin.sin_addr, hp->h_length); + }; + rsin.sin_family = AF_INET; + rsin.sin_port = htons (HOSTLINK_PORT); + + DEBUG (( "remote addr is %s\n", inet_ntoa (rsin.sin_addr) )); + + if (connect (s, (struct sockaddr *) & rsin, sizeof (rsin)) < 0) { + DEBUG (( "cant connect, err = %d\n", ERRORCODE )); + return (ER_LINK_CANT); + }; + + /* start sequence numbers as zero */ + h_seq = 0; + t_seq = 0; + + /* send a SYN frame, receiving an ACK indicates success */ + if (prot_send (s, rp_SYN, h_seq, 2, TRANS_TIMEOUT) != rp_ACK) { + close (s); + h_seq = (h_seq + 1) & 0x007f; + return (ER_LINK_CANT); + } else { + ActiveLink = s; + h_seq = (h_seq + 1) & 0x007f; + return (ActiveLink); + }; +} + +/* CloseLink + - closes the link between the transputer & the host + + effects : returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + SUCCEED (success) +*/ +PUBLIC int CloseLink (LinkId) +LINK LinkId; +{ + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + /* terminate the connection to the transputer */ + if (prot_send (ActiveLink, rp_RST, h_seq, 2, TRANS_TIMEOUT) != rp_ACK) { + return (Result); + } else { + close (ActiveLink); + ActiveLink = NULL_LINK; + return (SUCCEEDED); /* return success value */ + }; +} + +/* ReadLink + - tries to read Count bytes from the link! + + effects : tries to read rp_MAX_DATA_SIZE bytes from the link, + returns either + ER_LINK_BAD (link not open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + the number of bytes (up to the amount requested + in "Count") successfully read +*/ +PUBLIC int ReadLink (LinkId, Buffer, Count, Timeout) +LINK LinkId; +char *Buffer; +unsigned int Count; +int Timeout; +{ + int got; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + if (Count < 1) { + return (ER_LINK_CANT); + }; + + if (Count > rp_MAX_DATA_SIZE) { /* restrict size of read to maximum */ + Count = rp_MAX_DATA_SIZE; + }; + + if (saved_len <= 0) { /* no buffered data, so read some more data */ + saved_len = data_read (ActiveLink, &saved_buf, rp_MAX_DATA_SIZE, + Count, (short int) Timeout); + if (saved_len < 0) { + DEBUG (( "ReadLink - returning %d\n", got )); + return (saved_len); + }; + }; + if (saved_len >= Count) { /* if read more than wanted, just return wanted */ + got = Count; + } else { + got = saved_len; /* if read less than wanted, return read */ + }; + memcpy (Buffer, saved_buf, got); + saved_len = saved_len - got; + saved_buf = saved_buf + got; + DEBUG (( "ReadLink - returning %d\n", got )); + return (got); +} + +/* WriteLink + - tries to write data to the link! + + effects : tries to write up to "Count" bytes to the link. + returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + or number of bytes sucessfully sent +*/ +PUBLIC int WriteLink (LinkId, Buffer, Count, Timeout) +LINK LinkId; +char *Buffer; +short int Count; +int Timeout; +{ + short int i, rem, status; + + rem = Count; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + if (rem < 1) { + return (ER_LINK_CANT); + }; + + while (rem > 0) { + i = (rem > rp_MAX_DATA_SIZE) ? rp_MAX_DATA_SIZE : rem; + status = data_send (ActiveLink, rp_DATA, Buffer, i); + if (!status) { + return (Result); + }; + Buffer += i; + rem -= i; + } + return (Count); +} + +/* ResetLink + - reset the transputer's subsystem + + effects : returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + SUCCEDDED +*/ +PUBLIC int ResetLink (LinkId) +LINK LinkId; +{ + int code; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + /* reset the transputer's subsystem */ + code = prot_send (ActiveLink, rp_RESET, h_seq, 0, TRANS_TIMEOUT); + if (code == rp_NACK) { + return (ER_LINK_BAD); + }; + if (code != rp_ACK) { + return (Result); + } else { + h_seq = (h_seq + 1) & 0X007f; + return (SUCCEEDED); /* return success value */ + }; +} + +/* AnalyseLink + effects : sets analyse mode on the transputer + returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + SUCCEEDED +*/ +PUBLIC int AnalyseLink (LinkId) +LINK LinkId; +{ + int code; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + code = prot_send (ActiveLink, rp_ANALYSE, h_seq, 0, TRANS_TIMEOUT); + if (code == rp_NACK) { + return (ER_LINK_BAD); + }; + if (code != rp_ACK) { + return (Result); + } else { + h_seq = (h_seq + 1) & 0x007f; + return (SUCCEEDED); /* return success value */ + }; +} + +/* PeekLink + - tries to peek 'words' words of data from the transputer + + modifies : Result + effects : returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + 0 (no data could be peeked in the available time) + or number of bytes successfully peeked +*/ +PUBLIC int PeekLink (LinkId, Buffer, address, words) +LINK LinkId; +char *Buffer; +u_long address; +short int words; +{ + struct prot_dgram resp; + int code, tries, data_ok, bytes_returned; + unsigned char next_t_seq, next_h_seq; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + next_t_seq = (t_seq + 1) &0x007f; + next_h_seq = (h_seq + 1) &0x007f; + + for (tries = 1; tries < MAX_RETRIES; tries++) { + code = peek_send (ActiveLink, h_seq, address, words); + if (code == rp_NACK) { + h_seq = next_h_seq; + return (ER_LINK_BAD); + }; + if (code != rp_ACK) { + h_seq = next_h_seq; + return (Result); + } else { + data_ok = timed_read (ActiveLink, (char *) &inp, sizeof(inp), + timeout_period * tries); + if (data_ok >= 2 && (inp.op == rp_DATA && inp.seq == t_seq)) { + h_seq = next_h_seq; + t_seq = next_t_seq; + resp.op = rp_ACK; + resp.seq = inp.seq; + resp.len = 0; + if (send (ActiveLink, (char *) &resp, sizeof(resp), 0) < 0) { + DEBUG (("*fatal error : PeekLink[1] - send failed=%d\n", ERRORCODE )); + return (ER_LINK_SOFT); + } + bytes_returned = ntohs(inp.len); + DEBUG(( "PeekLink :returning %d\n",bytes_returned )); + memcpy (Buffer, inp.data, bytes_returned); + return (bytes_returned); + } else { + if (data_ok >= 2 && inp.op != rp_ACK && inp.op != rp_NACK && + inp.op != rp_CONT && inp.op != rp_ERROR) { + resp.op = rp_ACK; + resp.seq = inp.seq; + resp.len = 0; + if (send (ActiveLink, (char *) &resp, sizeof (resp), 0) < 0) { + DEBUG (("*fatal error : PeekLink[2] - send failed=%d\n", ERRORCODE )); + return (ER_LINK_SOFT); + }; + }; + }; + }; + }; + t_seq = next_t_seq; + h_seq = next_h_seq; + return (ER_LINK_CANT); +}; + +/* TestError + - tests the error state of the transputer + + modifies : h_seq (incremented) + effects : tests the error state of the transputer + returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (transputer doesn't respond) + ER_LINK_SOFT (link software failure) + 0 (error flag not set) + 1 (error flag set) +*/ +PUBLIC int TestError (LinkId) +LINK LinkId; +{ + struct prot_dgram reply; + struct error_dgram resp, error_inq; + int tries, reply_ok, timed_out; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + error_inq.op = rp_ERROR; + error_inq.seq = h_seq; + + for (tries = 1; tries < MAX_RETRIES; tries++) { + if (send (ActiveLink, (char *) &error_inq, sizeof (error_inq), 0) < 0) { + DEBUG (("*fatal error : TestError[1] - send failed =%d\n", ERRORCODE )); + return (ER_LINK_SOFT); + } else { + reply_ok = (timed_read (ActiveLink, (char *) &resp, sizeof (resp), + timeout_period * tries) > 0); + if (reply_ok > 0) { + if (resp.op == rp_NACK) { + return (ER_LINK_BAD); + }; + if (resp.op == rp_ERROR) { + /* reply obtained, so return error status of transputer */ + h_seq = (h_seq + 1) & 0x007f; + return (int) (resp.status); + } else { + if (resp.op != rp_ACK && resp.op != rp_NACK && resp.op != rp_CONT && + resp.op != rp_ERROR) { + reply.op = rp_ACK; + reply.seq = resp.seq; + reply.len = htons ((short int) 0); + reply.timeout = htons ((short int) 0); + if (send (ActiveLink, (char *) &reply, sizeof (reply), 0) < 0) { + DEBUG (("*fatal error : TestError[2] - send failed =%d\n", ERRORCODE )); + return (ER_LINK_SOFT); + }; + }; + }; + }; + }; + }; + /* failed */ + h_seq = (h_seq + 1) &0x007f; + return (ER_LINK_CANT); +}; + +/* TestRead + - test the read operation + effects : returns either + ER_LINK_BAD (link wasn't open) + 0 (link might not be able to read) +*/ +PUBLIC int TestRead (LinkId) +LINK LinkId; +{ + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + } else { + return (0); + }; +} + +/* TestWrite + - test the write operation + effects : returns either + ER_LINK_BAD (link wasn't open) + 0 (link might not be able to write) +*/ +PUBLIC int TestWrite (LinkId) +LINK LinkId; +{ + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + } else { + return (0); + }; +} + +/* TestLink + - tests the link is operational + + effects : tests the link status. returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (link communication failed) + SUCCEEDED (link is ok) +*/ +PUBLIC TestLink (LinkId) +LINK LinkId; +{ + int status; + + if (LinkId != ActiveLink) { + return (ER_LINK_BAD); + }; + + status = prot_send (ActiveLink, rp_ACTIVE, h_seq, 0, TRANS_TIMEOUT); + if (status == rp_NACK) { + return (ER_LINK_BAD); + }; + if (status == rp_TIMEOUT) { + return (Result); + } else { + h_seq = (h_seq + 1) &0x007f; + return (SUCCEEDED); + }; +}; + +/************************ INTERNAL FUNCTIONS ******************************/ + +/* timeout functions */ + +#ifdef WIN_TCP +/* + * Timeout functions under WIN TCP + * Broken select(2) call + * + */ + + +/* timed_read + * + * effects : returns the number of bytes successfully read + * or zero if timeout after time in 'ms' milliseconds + */ + +#define time_event (unsigned long int) 1 /* Event flags and masks */ +#define read_event (unsigned long int) 2 +#define read_mask (unsigned long int) 4 +#define event_mask (unsigned long int) 6 + +#define IO$_RECEIVE IO$_READVBLK /* See WIN/TCP reference manual */ + +PRIVATE int timed_read (socket, buf, buf_size, ms) +LINK socket; +char *buf; +int buf_size; +long ms; +{ + int bytes_read = 0; + unsigned long int flags; + int status; /* status is consistantly ignored */ + int vms_delta_time[2]; /* To store our backdoor version of VMS time */ + int read_iosb[2]; /* i/o status block */ + + vms_delta_time[1] = -1; + vms_delta_time[0] = ms * -10000; /* convert ms to VMS 100 nS intervals */ + + /* Queue read */ + status = SYS$QIO(read_event, socket, IO$_RECEIVE, read_iosb, 0, 0, + buf, buf_size, 0, 0, 0, 0); + if (status != SS$_NORMAL) { + DEBUG (("*fatal error : timed_read - Abnormal QIO status %d\n", status )); + return (ER_LINK_SOFT); + }; + + /* Set up timer */ + status = SYS$SETIMR(time_event, &vms_delta_time, 0, 0); + if (status != SS$_NORMAL) { + DEBUG (("*fatal error : timed_read - Abnormal timer status %d\n", status )); + return (ER_LINK_SOFT); + }; + + /* Wait for read or timer event flag top be set */ + status = SYS$WFLOR(read_event, event_mask); + if (status != SS$_NORMAL) { + DEBUG (("*fatal error : timed_read - Abnormal WFLOR status %d\n", status )); + return (ER_LINK_SOFT); + }; + + /* Findout which event flag was set */ + status = SYS$READEF(read_event, &flags); + if ((status != SS$_WASSET) && (status != SS$_WASCLR)) { + DEBUG (("*fatal error : timed_read - Abnormal READEF status %d\n", status )); + return (ER_LINK_SOFT); + }; + + if ((flags & read_mask) == read_mask) { /* It was a read, not a timeout */ + int fnresult = read_iosb[0] & 0XFFFF; + + status = SYS$CANTIM(0, PSL$C_USER); /* cancel timer */ + + /* Extract length of data from i/o status block */ + bytes_read = (read_iosb[0] & 0XFFFF0000) >> 16; + } else { + status = SYS$CANCEL(socket); + } + return(bytes_read); +} + + +#else /* WIN_TCP (not VMS) */ + +PRIVATE int timed_read (s, buf, len, millisec) +int s; +char *buf; +int len; +long int millisec; +{ + int fdwidth; + fd_set readfds; + struct timeval timeout; + + assert (s < FD_SETSIZE); + + timeout.tv_sec = millisec / 1000; + timeout.tv_usec = (millisec % 1000) * 1000; + + fdwidth = s + 1; + + FD_ZERO (&readfds); + FD_SET (s, &readfds); + + if (select (fdwidth, &readfds, (fd_set *) NULL, (fd_set *) NULL, &timeout) > 0) { + return (read (s, buf, len)); + } else { + return (0); + }; +} + +#endif /* WIN_TCP */ + +/* prot_send + - send a protocol frame to the transputer & obtain a reply + + modifies : Result + effects : sends a frame to the transputer and returns either + ACK, NACK or TIMEOUT (TIMEOUT occurs if an ACK or + NACK of the correct sequence number is received + within the timeout period. the timeout parameter + passed is sent to the transputer & used for its own + timeout checking. If TIMEOUT is returned, inspect + Result for status value. +*/ +PRIVATE unsigned char prot_send (s, op, seq, len, timeout) +LINK s; +unsigned char op, seq; +short int len; +short int timeout; +{ + struct prot_dgram requ, resp; + int tries, reply_ok, numbytes, timeval1, timeval2; + + requ.op = op; + requ.seq = seq; + requ.len = htons ((short int) len); + requ.timeout = htons ((short int) timeout); + + /* + * make upto MAX_RETRIES tries to successfully send a frame to the + * transputer, and get either an ACK or NACK with the correct sequence + * number back + */ + Result = SUCCEEDED; + for (tries = 1; tries < MAX_RETRIES; tries++) { + /* send request packet */ + if (send (s, (char *) &requ, sizeof (requ), 0) < 0) { + DEBUG (( "*fatal error : prot_send - send failed =%d\n", ERRORCODE )); + Result = ER_LINK_SOFT; + return (rp_TIMEOUT); + } else { + /* request sent ok, so get reply */ + time (&timeval1); + reply_ok = FALSE; + + while (!reply_ok) { + numbytes = timed_read (s, (char *) &resp, sizeof (resp), + timeout_period * tries); + if (numbytes > 0) { /* got a reply */ + reply_ok = TRUE; + if ((resp.op == rp_ACK || resp.op == rp_NACK) && (resp.seq == seq)) { + return (resp.op); + }; + }; + time (&timeval2); + if ((timeval2-timeval1) >= QUIETTIMEOUT) { + reply_ok = TRUE; + }; + }; + }; + }; + /* failed */ + Result = ER_LINK_CANT; + return (rp_TIMEOUT); +} + +/* peek_send + - send a peek frame to the transputer & obtain a reply + + modifies : Result + effects : sends a frame to the transputer and returns either + ACK, NACK or TIMEOUT (TIMEOUT occurs if an ACK or + NACK of the correct sequence number is received + within the timeout period. the timeout parameter + passed is sent to the transputer & used for its own + timeout checking. if TIMEOUT is returned, inspect + Result for status value. +*/ +PRIVATE unsigned char peek_send (s, seq, address, numwords) +LINK s; +unsigned char seq; +u_long address; +short int numwords; +{ + struct peek_dgram requ; + struct prot_dgram resp; + int tries, reply_ok, numbytes, timeval1, timeval2; + + requ.op = rp_PEEK; + requ.seq = h_seq; + requ.address = htonl(address); + requ.numwords = htons(numwords); + /* + * make upto MAX_RETRIES tries to successfully send a frame to the + * transputer, and get either an ACK or NACK with the correct sequence + * number back + */ + Result = SUCCEEDED; + for (tries = 1; tries < MAX_RETRIES; tries++) { + /* send request packet */ + if (send (s, (char *) &requ, sizeof (requ), 0) < 0) { + DEBUG (("*fatal error : peek_send - send failed =%d\n", ERRORCODE )); + Result == ER_LINK_SOFT; + return (rp_TIMEOUT); + } else { + /* request sent ok, so get reply */ + reply_ok = FALSE; + time (&timeval1); + while (!reply_ok) { + numbytes = timed_read (s, (char *) &resp, sizeof (resp), + timeout_period * tries); + if (numbytes > 0) { + reply_ok = TRUE; + if ((resp.op == rp_ACK || resp.op == rp_NACK) && (resp.seq == seq)) { + return (resp.op); + }; + }; + time (&timeval2); /* if X seconds elapsed cant contact transputer */ + if ((timeval2-timeval1) >= QUIETTIMEOUT) { + reply_ok = TRUE; + }; + }; + }; + }; + /* failed */ + Result = ER_LINK_CANT; + return (rp_TIMEOUT); +} + +/* data_send + - send data to the transputer & obtain a reply + modifies : Result + effects : returns either + TRUE (data send successfully) + FALSE (send failed -> status returned in Result) +*/ +PRIVATE int data_send (s, op, buff, len) +LINK s; +unsigned char op; +char *buff; +short int len; +{ + struct data_dgram requ; + struct prot_dgram resp, reply; + int tries, count, rcount, reply_ok, tresult, timed_out; + + Result = SUCCEEDED; + + memcpy (requ.data, buff, len); + requ.op = op; + requ.seq = h_seq; + requ.len = htons ((short int) len); + + DEBUG (( "data_send: sending %d\n", len )); + + len += rp_DATA_HEADER; + + for (tries = 1; tries < MAX_RETRIES; tries++) { + /* send request packet */ + if (send (s, (char *) &requ, sizeof (requ), 0) < 0) { + Result = ER_LINK_SOFT; + return (FALSE); + } else { + reply_ok = FALSE; + timed_out = FALSE; + while (!timed_out && !reply_ok) { + tresult = timed_read (s, (char *) &resp, sizeof (resp), + timeout_period * tries); + timed_out = (tresult == 0); + reply_ok = (!timed_out && (resp.op == rp_ACK || resp.op == rp_NACK || + resp.op == rp_CONT || resp.op == rp_SUSP) && resp.seq == h_seq); + if (reply_ok && resp.op == rp_NACK) { + Result = ER_LINK_BAD; + return (Result); + }; + if (!timed_out && resp.op == rp_DATA) { + DEBUG (( "received DATA frame in write\n")); + reply.op = rp_ACK; + reply.seq = resp.seq; + reply.len = 0; + if (send (s, (char *) &reply, sizeof (reply), 0) < 0) { + DEBUG (( "*fatal error : data_send[2] - send failed =%d\n", ERRORCODE )); + Result = ER_LINK_SOFT; + return (FALSE); + }; + }; + }; + if (reply_ok) { + if ((resp.op == rp_SUSP) && (resp.seq == h_seq)) { + reply_ok = FALSE; + timed_out = FALSE; + while (!timed_out && !reply_ok) { + rcount = timed_read (s, (char *) &resp, sizeof (resp), + timeout_period * tries); + timed_out = (rcount == 0); + if (!timed_out && resp.seq == h_seq && resp.op == rp_ACK) { + reply_ok = TRUE; + h_seq = (h_seq + 1) &0x007f; + return (TRUE); + }; + }; + tries = 1; /* transputer didn't do request so retry*/ + } else { + if (resp.op == rp_ACK) { + h_seq = (h_seq + 1) & 0x007f; + return (TRUE); + } else { + DEBUG (( "Invalid sp frame received %d -- Please report\n", resp.op )); + h_seq = (h_seq + 1) & 0x007f; + Result = ER_LINK_CANT; + return (FALSE); + }; + }; + }; + }; + }; + /* failed */ + h_seq = (h_seq + 1) & 0x007f; + Result = ER_LINK_CANT; + return (FALSE); +} + +/* data_read + - read data from transputer + + effects : returns either + ER_LINK_BAD (link wasn't open) + ER_LINK_CANT (link communication failed) + ER_LINK_SOFT (link software failure) + 0 (no data could be read in available time) + or number of bytes successfully read +*/ +PRIVATE int data_read (s, buff, maxlen, len, timeout) +LINK s; +char **buff; +short int maxlen; +short int len; +short int timeout; +{ + struct prot_dgram resp; + int tries, data_ok, code; + unsigned char next_t_seq, next_h_seq; + + next_t_seq = (t_seq + 1) & 0x007f; + next_h_seq = (h_seq + 1) & 0x007f; + + Result = SUCCEEDED; + for (tries = 1; tries < MAX_RETRIES; tries++) { + code = prot_send (s, rp_REQ, h_seq, len, timeout); + if (code == rp_NACK) { + h_seq = next_h_seq; + return (ER_LINK_BAD); + }; + if (code == rp_TIMEOUT) { + h_seq = next_h_seq; + return (Result); + } else { + data_ok = timed_read (s, (char *) &inp, sizeof (inp), + timeout_period * tries); + if (data_ok >= 2 && inp.op == rp_DATA && inp.seq == t_seq) { + h_seq = next_h_seq; + t_seq = next_t_seq; + resp.op = rp_ACK; + resp.seq = inp.seq; + resp.len = 0; + if (send (s, (char *) &resp, sizeof (resp), 0) < 0) { + DEBUG (( "*fatal error : data_read[1] - send failed =%d\n", ERRORCODE )); + return (ER_LINK_SOFT); + }; + DEBUG (( "input len = %d\n", len )); + *buff = (char *) &(inp.data[0]); + DEBUG (( "data_read: returning %d\n", ntohs (inp.len) )); + return (ntohs (inp.len)); + } else { + if ((data_ok >=2) && (inp.op != rp_ACK) && (inp.op != rp_NACK)&& + (inp.op != rp_CONT) && (inp.op != rp_ERROR)) { + resp.op = rp_ACK; + resp.seq = inp.seq; + resp.len = 0; + if (send (s, (char *) &resp, sizeof (resp), 0) < 0) { + DEBUG (( "*fatal error : data_read[2] - send failed =%d\n", ERRORCODE )); + return (ER_LINK_SOFT); + }; + }; + }; + }; + }; + return (ER_LINK_CANT); +} + +/* + * Eof + */ diff --git a/minix/commands/inmos/udplink.h b/minix/commands/inmos/udplink.h new file mode 100644 index 000000000..6be2f4195 --- /dev/null +++ b/minix/commands/inmos/udplink.h @@ -0,0 +1,77 @@ +/* +-- --------------------------------------------------------------------------- +-- +-- ISERVER - INMOS standard file server +-- +-- udplink.h +-- +-- The main body +-- +-- Copyright (c) INMOS Ltd., 1989, 1990 +-- All Rights Reserved. +-- +-- --------------------------------------------------------------------------- +*/ + +#define rp_NULL (unsigned char) 0 +#define rp_DATA (unsigned char) 1 +#define rp_ACK (unsigned char) 2 +#define rp_RESET (unsigned char) 3 +#define rp_ANALYSE (unsigned char) 4 +#define rp_ERROR (unsigned char) 5 +#define rp_SYN (unsigned char) 6 +#define rp_NACK (unsigned char) 7 +#define rp_RST (unsigned char) 8 +#define rp_SUSP (unsigned char) 9 +#define rp_REQ (unsigned char) 10 +#define rp_CONT (unsigned char) 11 +#define rp_ACTIVE (unsigned char) 12 +#define rp_PEEK (unsigned char) 13 +#define rp_TIMEOUT (unsigned char) 255 + +#define rp_DATA_HEADER 4 + +#define rp_MAX_DATA_SIZE 1400 + +/* timeout value send to transputer in prot_dgrams */ +#define TRANS_TIMEOUT 5 + +#define HOSTLINK_PORT 5002 + +#define MAX_RETRIES 20 +#define timeout_period 50 /* initial timeout period in milliseconds */ + +/* timeout for hearing nothing from transputer (in seconds) */ +#define QUIETTIMEOUT 5 + +/* structure used to send/receive data to/from transputer */ +struct data_dgram { + unsigned char op; + unsigned char seq; + short int len; + unsigned char data[rp_MAX_DATA_SIZE]; +}; + +/* structure used to send/receive datagrams to/from transputer */ +struct prot_dgram { + unsigned char op; + unsigned char seq; + short int len; + short int timeout; +}; + +/* structure used to receive rp_ERROR datagrams from transputer */ +struct error_dgram { + unsigned char op; + unsigned char seq; + unsigned char status; + unsigned char dummy_padding; +}; + +/* structure used to send peek datagrams to the transputer */ +struct peek_dgram { + unsigned char op; + unsigned char seq; + short int numwords; + long address; +}; diff --git a/minix/drivers/Makefile b/minix/drivers/Makefile index 328c1415c..ec403cfa9 100644 --- a/minix/drivers/Makefile +++ b/minix/drivers/Makefile @@ -5,6 +5,9 @@ SUBDIR+= audio SUBDIR+= clock SUBDIR+= eeprom SUBDIR+= examples +.if ${MACHINE_ARCH} == "i386" +SUBDIR+= inmos +.endif # ${MACHINE_ARCH} == "i386" SUBDIR+= iommu SUBDIR+= net SUBDIR+= power diff --git a/minix/drivers/inmos/Makefile b/minix/drivers/inmos/Makefile new file mode 100644 index 000000000..d26b43cc0 --- /dev/null +++ b/minix/drivers/inmos/Makefile @@ -0,0 +1,5 @@ +.include + +SUBDIR+= b004 + +.include diff --git a/minix/drivers/inmos/Makefile.inc b/minix/drivers/inmos/Makefile.inc new file mode 100644 index 000000000..01b5f2341 --- /dev/null +++ b/minix/drivers/inmos/Makefile.inc @@ -0,0 +1 @@ +.include "../Makefile.inc" diff --git a/minix/drivers/inmos/b004/Makefile b/minix/drivers/inmos/b004/Makefile new file mode 100644 index 000000000..cc56ca8c2 --- /dev/null +++ b/minix/drivers/inmos/b004/Makefile @@ -0,0 +1,12 @@ +# Makefile for the b004 driver. +PROG= b004 +SRCS= b004.c + +FILES=${PROG}.conf +FILESNAME=${PROG} +FILESDIR= /etc/system.conf.d + +DPADD+= ${LIBCHARDRIVER} ${LIBSYS} +LDADD+= -lchardriver -lsys + +.include diff --git a/minix/drivers/inmos/b004/b004.c b/minix/drivers/inmos/b004/b004.c new file mode 100644 index 000000000..fdcea0441 --- /dev/null +++ b/minix/drivers/inmos/b004/b004.c @@ -0,0 +1,796 @@ +/* + * INMOS B004/B008 Transputer TRAM Motherboard character device + * + * This driver implements the B004 interface, using the I/O port + * block starting at 0x150, for polled communication with the + * Transputer network. It will also detect the presence of the + * B008 extensions, and use those to use DMA for transfers over + * a minimum size, worth the DMA setup overhead. + * + * Only one device is supported, and half duplex communication. + */ + +#include +#include +#include +#include + +#include +#include + +#include "b004.h" + +static int b004_open(devminor_t minor, int access, endpoint_t user_endpt); + +static int b004_close(devminor_t minor); + +static ssize_t b004_read(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, + cdev_id_t id); + +static ssize_t b004_write(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, + cdev_id_t id); + +static int b004_ioctl(devminor_t minor, unsigned long request, + endpoint_t endpt, cp_grant_id_t grant, int flags, + endpoint_t user_endpt, cdev_id_t id); + +static int b004_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id); + +static void b004_alarm(clock_t stamp); + +static void b004_intr(unsigned int mask); + +static void b004_probe(void); +static void b004_initialize(void); +static void b004_reset(void); +static void b004_analyse(void); + +static void dma_read(void); +static void dma_write(void); +static int dma_transfer(phys_bytes dmabuf_phys, size_t count, int do_write); +static void dma_abort(void); + +static void sef_local_startup(void); +static int sef_cb_init(int type, sef_init_info_t *info); +static int sef_cb_lu_state_save(int, int); +static int lu_state_restore(void); + +static struct chardriver b004_tab = { + .cdr_open = b004_open, + .cdr_close = b004_close, + .cdr_read = b004_read, + .cdr_write = b004_write, + .cdr_ioctl = b004_ioctl, + .cdr_cancel = b004_cancel, + .cdr_alarm = b004_alarm, + .cdr_intr = b004_intr +}; + +static int board_type = 0; +static int board_busy = 1; + +static unsigned char *linkbuf; + +static unsigned char *dmabuf; +static phys_bytes dmabuf_phys; +static size_t dmabuf_len = 0; +static int dma_available = 0; +static int dma_disabled = 0; + +static struct { + endpoint_t endpt; + cdev_id_t id; + cp_grant_id_t grant; + int writing; + size_t size; + size_t done; + size_t chunk; +} dma; + +static int probe_active = 0; + +static u32_t system_hz; +static int io_timeout = 0; + +static int irq_hook_id; + +/* + * OPEN: permits only one client to have the device open. + */ + +static int b004_open(devminor_t UNUSED(minor), int UNUSED(access), + endpoint_t UNUSED(user_endpt)) { + + if (board_busy) + return EAGAIN; + + board_busy = 1; + + return OK; +} + +/* + * CLOSE: resets timeout to default; re-enables DMA if the + * client disabled it using ioctl(fd, B004NODMA). + */ + +static int b004_close(devminor_t UNUSED(minor)) { + + io_timeout = system_hz; + + if (dma.endpt != 0) { + sys_setalarm(0, 0); + dma_abort(); + dma.endpt = 0; + } + + if (dma_disabled) { + dma_available = 1; + dma_disabled = 0; + } + + board_busy = 0; + + return OK; +} + +/* + * READ: if DMA available, sets up and initiates a DMA transfer, + * and suspends the caller. Otherwise, does a polled read. + */ + +static ssize_t b004_read(devminor_t UNUSED(minor), u64_t UNUSED(position), + endpoint_t endpt, cp_grant_id_t grant, size_t size, + int UNUSED(flags), cdev_id_t id) { + int ret = OK, b; + size_t i, j, copied; + clock_t now, deadline; + + if (size <= 0) + return EINVAL; + + if (dma.endpt != 0) + return EIO; + + if ((dma_available) && (size >= DMA_THRESHOLD)) { + dma.endpt = endpt; + dma.id = id; + dma.grant = grant; + dma.writing = 0; + dma.size = size; + dma.done = 0; + dma.chunk = 0; + sys_setalarm(io_timeout, 0); + dma_read(); + return EDONTREPLY; + } + + getuptime(&now, NULL, NULL); + deadline = now + io_timeout; + + copied = 0; + for (i = 0, j = 0; i < size; i++) { + while (1) { + sys_inb(B004_ISR, &b); + if (b & B004_READY) { + sys_inb(B004_IDR, &b); + linkbuf[j++] = b; + break; + } else { + if (io_timeout > 0) { + getuptime(&now, NULL, NULL); + if (now > deadline) { + printf("b004: timing out %d byte read at %d\n", size, j); + goto out; + } + } + } + } + if (j == LINKBUF_SIZE) { + ret = sys_safecopyto(endpt, grant, copied, + (vir_bytes)linkbuf, LINKBUF_SIZE); + j = 0; + if (ret == OK) + copied += LINKBUF_SIZE; + else + goto out; + } + } + + out: + if (j > 0) { + ret = sys_safecopyto(endpt, grant, copied, (vir_bytes)linkbuf, j); + if (ret == OK) + copied += j; + } + + if (ret != OK) + return ret; + + return copied; +} + +/* + * WRITE: if DMA available, sets up and initiates a DMA transfer, + * and suspends the caller. Otherwise, does a polled write. + */ + +static ssize_t b004_write(devminor_t UNUSED(minor), u64_t UNUSED(position), + endpoint_t endpt, cp_grant_id_t grant, size_t size, + int UNUSED(flags), cdev_id_t id) { + int ret = OK, b; + size_t i, j, copied, chunk; + clock_t now, deadline; + + if (size <= 0) + return EINVAL; + + if (dma.endpt != 0) + return EIO; + + if ((dma_available) && (size >= DMA_THRESHOLD)) { + dma.endpt = endpt; + dma.id = id; + dma.grant = grant; + dma.writing = 1; + dma.size = size; + dma.done = 0; + dma.chunk = 0; + sys_setalarm(io_timeout, 0); + dma_write(); + return EDONTREPLY; + } + + getuptime(&now, NULL, NULL); + deadline = now + io_timeout; + + copied = 0; + for (i = 0, j = 0; i < size; i++) { + if (j == 0) { + chunk = MIN((size - copied), LINKBUF_SIZE); + ret = sys_safecopyfrom(endpt, grant, copied, (vir_bytes)linkbuf, chunk); + if (ret == OK) + copied += chunk; + else + goto out; + } + while (1) { + sys_inb(B004_OSR, &b); + if (b & B004_READY) { + sys_outb(B004_ODR, linkbuf[j++]); + break; + } else { + if (io_timeout > 0) { + getuptime(&now, NULL, NULL); + if (now > deadline) { + printf("b004: timing out %d byte write at %d\n", size, j); + goto out; + } + } + } + } + if (j == LINKBUF_SIZE) + j = 0; + } + + out: + if (ret != OK) + return ret; + + return i; +} + +/* + * DMA_READ: simple state machine for doing DMA read. Called once + * from READ, above, then one or more times from INTR. + */ + +static void dma_read(void) { + int ret = OK; + + if (dma.chunk > 0) { + ret = sys_safecopyto(dma.endpt, dma.grant, dma.done, + (vir_bytes)dmabuf, dma.chunk); + if (ret == OK) { + dma.done += dma.chunk; + dma.chunk = 0; + } + } + + if (dma.done == dma.size) { + chardriver_reply_task(dma.endpt, dma.id, dma.size); + dma.endpt = 0; + return; + } + + if (dma.chunk == 0) { + dma.chunk = MIN((dma.size - dma.done), dmabuf_len); + ret = dma_transfer(dmabuf_phys, dma.chunk, 0); + } + + if (ret != OK) { + chardriver_reply_task(dma.endpt, dma.id, ret); + dma.endpt = 0; + } +} + +/* + * DMA_WRITE: simple state machine for doing DMA write. Called once + * from WRITE, above, then one or more times from INTR. + */ + +static void dma_write(void) { + int ret = OK; + + if (dma.chunk > 0) { + dma.done += dma.chunk; + dma.chunk = 0; + } + + if (dma.done == dma.size) { + chardriver_reply_task(dma.endpt, dma.id, dma.size); + dma.endpt = 0; + return; + } + + if (dma.chunk == 0) { + dma.chunk = MIN((dma.size - dma.done), dmabuf_len); + ret = sys_safecopyfrom(dma.endpt, dma.grant, dma.done, + (vir_bytes)dmabuf, dma.chunk); + if (ret == OK) + ret = dma_transfer(dmabuf_phys, dma.chunk, 1); + } + + if (ret != OK) { + chardriver_reply_task(dma.endpt, dma.id, ret); + dma.endpt = 0; + } +} + +/* + * DMA_TRANSFER: program the DMA controller for a transfer, then + * enable interrupts and tell the B008 to start it. + */ + +static int dma_transfer(phys_bytes dmabuf_phys, size_t count, int do_write) { + pvb_pair_t byte_out[9]; + int ret; + + pv_set(byte_out[0], DMA_INIT, DMA_MASK); + pv_set(byte_out[1], DMA_FLIPFLOP, 0); + pv_set(byte_out[2], DMA_MODE, do_write ? DMA_WRITE : DMA_READ); + pv_set(byte_out[3], DMA_ADDR, (unsigned) (dmabuf_phys >> 0) & 0xff); + pv_set(byte_out[4], DMA_ADDR, (unsigned) (dmabuf_phys >> 8) & 0xff); + pv_set(byte_out[5], DMA_TOP, (unsigned) (dmabuf_phys >> 16) & 0xff); + pv_set(byte_out[6], DMA_COUNT, (((count - 1) >> 0)) & 0xff); + pv_set(byte_out[7], DMA_COUNT, (count - 1) >> 8); + pv_set(byte_out[8], DMA_INIT, DMA_UNMASK); + + if ((ret = sys_voutb(byte_out, 9)) != OK) + panic("dma_setup: failed to program DMA chip (%d)", ret); + + pv_set(byte_out[0], B004_ISR, do_write ? B004_INT_DIS : B004_INT_ENA); + pv_set(byte_out[1], B004_OSR, do_write ? B004_INT_ENA : B004_INT_DIS); + pv_set(byte_out[2], B008_INT, B008_DMAINT_ENA); + + if ((ret = sys_voutb(byte_out, 3)) != OK) + panic("dma_setup: failed to enable interrupts (%d)", ret); + + sys_irqenable(&irq_hook_id); + + sys_outb(B008_DMA, do_write ? B008_DMAWRITE : B008_DMAREAD); + + return OK; +} + +/* + * DMA_ABORT: abort an ongoing DMA operation, resetting controller. + */ + +static void dma_abort(void) { + pvb_pair_t byte_out[5]; + + pv_set(byte_out[0], B004_ISR, B004_INT_DIS); + pv_set(byte_out[1], B004_OSR, B004_INT_DIS); + pv_set(byte_out[2], B008_INT, B008_INT_DIS); + pv_set(byte_out[3], DMA_INIT, DMA_MASK); + pv_set(byte_out[4], DMA_FLIPFLOP, 0); + + sys_voutb(byte_out, 5); +} + +/* + * ALARM: if a DMA operation is in progress, time it out, log + * this, and return the count of bytes that have already + * been transfered. Otherwise, ignore the alarm. + */ + +static void b004_alarm(clock_t UNUSED(stamp)) { + + if (dma.endpt != 0) { + dma_abort(); + printf("b004: timing out %d byte DMA %s\n", + dma.size, dma.writing ? "write" : "read"); + chardriver_reply_task(dma.endpt, dma.id, dma.done); + dma.endpt = 0; + } +} + +/* + * CANCEL: if the indicated operation is still in progress, cancel + * it, log this, and return EINTR to the client. If not, + * just ignore the CANCEL message; the response was sent + * when the operation completed. + */ + +static int b004_cancel(devminor_t UNUSED(minor), + endpoint_t endpt, cdev_id_t id) { + + if (dma.endpt == endpt && dma.id == id) { + sys_setalarm(0, 0); + dma_abort(); + printf("b004: cancelling %d byte DMA %s\n", + dma.size, dma.writing ? "write" : "read"); + dma.endpt = 0; + return EINTR; + } + + return EDONTREPLY; +} + +/* + * INTR: acknowledge each possible interrupt source, then run the + * next step in the relevant state machine. Note that this + * is where DMA operation timeout alarms are canceled, and + * that we also detect the interrupt from the experimental + * DMA attempt during the initial probe, switching DMA on. + */ + +static void b004_intr(unsigned int UNUSED(mask)) { + pvb_pair_t byte_out[3]; + + pv_set(byte_out[0], B004_ISR, B004_INT_DIS); + pv_set(byte_out[1], B004_OSR, B004_INT_DIS); + pv_set(byte_out[2], B008_INT, B008_INT_DIS); + + if (sys_voutb(byte_out, 3) != OK) + panic("b004: failed to acknowledge interrupt"); + + if (probe_active) { + printf("b004: DMA verified; switching to B008 mode\n"); + board_type = B008; + dma_available = 1; + probe_active = 0; + return; + } + + if (dma.endpt == 0) { + printf("b004: unexpected hardware interrupt\n"); + return; + } + + if (dma.writing) + dma_write(); + else + dma_read(); + + if (dma.endpt == 0) + sys_setalarm(0, 0); + + return; +} + +/* + * IOCTL: handle the various ioctl() calls the driver supports. + */ + +static int b004_ioctl(devminor_t UNUSED(minor), unsigned long request, + endpoint_t endpt, cp_grant_id_t grant, int UNUSED(flags), + endpoint_t UNUSED(user_endpt), cdev_id_t UNUSED(id)) { + int ret; + unsigned int b; + struct b004_flags flag; + int timeout; + + if (dma.endpt != 0) + return EINVAL; + + switch (request) { + + case B004GETTIMEOUT: + timeout = (io_timeout * 10) / system_hz; + ret = sys_safecopyto(endpt, grant, + 0, (vir_bytes)&timeout, sizeof timeout); + break; + + case B004SETTIMEOUT: + ret = sys_safecopyfrom(endpt, grant, + 0, (vir_bytes)&timeout, sizeof timeout); + if ((ret == OK) && (timeout >= 0)) + io_timeout = (timeout * system_hz) / 10; + else + ret = EINVAL; + break; + + case B004TIMEOUT: + ret = (io_timeout * 10) / system_hz; + break; + + case B004BOARDTYPE: + ret = board_type; + break; + + case B004READABLE: + sys_inb(B004_ISR, &b); + ret = b & B004_READY; + break; + + case B004WRITEABLE: + sys_inb(B004_OSR, &b); + ret = b & B004_READY; + break; + + case B004ERROR: + sys_inb(B004_ERROR, &b); + ret = b & B004_HAS_ERROR; + break; + + case B004GETFLAGS: + flag.b004_board = board_type; + flag.b004_timeout = (io_timeout * 10) / system_hz; + sys_inb(B004_ISR, &b); + flag.b004_readable = b & B004_READY; + sys_inb(B004_OSR, &b); + flag.b004_writeable = b & B004_READY; + sys_inb(B004_ERROR, &b); + flag.b004_error = b & B004_HAS_ERROR; + flag.b004_dma_ok = dma_available | dma_disabled; + ret = sys_safecopyto(endpt, grant, 0, (vir_bytes) &flag, sizeof flag); + break; + + case B004DMADISABLE: + dma_disabled |= dma_available; + dma_available = 0; + ret = OK; + break; + + case B004DMAENABLE: + if (dma_disabled) + dma_available = 1; + ret = OK; + break; + + case B004RESET: + b004_reset(); + ret = OK; + break; + + case B004ANALYSE: + b004_analyse(); + ret = OK; + break; + + default: + ret = EINVAL; + } + + return ret; +} + +/* + * Live update: save state. Not tested; not production ready. + */ + +static int sef_cb_lu_state_save(int UNUSED(state), int UNUSED(flags)) { + + ds_publish_u32("board_type", board_type, DSF_OVERWRITE); + ds_publish_u32("io_timeout", io_timeout, DSF_OVERWRITE); + ds_publish_u32("dma_available", dma_available, DSF_OVERWRITE); + ds_publish_u32("dma_disabled", dma_disabled, DSF_OVERWRITE); + + return OK; +} + +/* + * Live update: restore state. Not tested; not production ready. + */ + +static int lu_state_restore() { + u32_t value; + + if (ds_retrieve_u32("board_type", &value) == OK) { + board_type = (int) value; + ds_delete_u32("board_type"); + } + + if (ds_retrieve_u32("io_timeout", &value) == OK) { + io_timeout = (int) value; + ds_delete_u32("io_timeout"); + } + + if (ds_retrieve_u32("dma_available", &value) == OK) { + dma_available = (int) value; + ds_delete_u32("dma_available"); + } + + if (ds_retrieve_u32("dma_disabled", &value) == OK) { + dma_disabled = (int) value; + ds_delete_u32("dma_disabled"); + } + + return OK; +} + +/* + * SEF startup routine; establish callbacks, and fire startup. + */ + +static void sef_local_startup() { + + sef_setcb_init_fresh(sef_cb_init); + sef_setcb_init_lu(sef_cb_init); + sef_setcb_init_restart(sef_cb_init); + + sef_setcb_lu_state_save(sef_cb_lu_state_save); + + sef_startup(); +} + +/* + * SEF initialization: set up default timeout value, allocate + * buffers for communication (polled and DMA), and probe for the + * physical device. Note the strategy for getting a sizeable + * low memory DMA buffer: prefer a properly aligned allocation, + * but accept a double size non-aligned one, and use an aligned + * part of it. The latter is wasteful, but we want the space. + */ + +static int sef_cb_init(int type, sef_init_info_t *UNUSED(info)) { + int off, k; + + if (type == SEF_INIT_LU) + lu_state_restore(); + + if (sys_getinfo(GET_HZ, &system_hz, sizeof(system_hz), 0, 0) != OK) + panic("sef_cb_init: couldn't get system HZ value"); + + if (io_timeout == 0) + io_timeout = system_hz; + + if (!(linkbuf = malloc(LINKBUF_SIZE))) + panic("sef_cb_init: couldn't allocate link buffer"); + + for (k = 64; k >= 1; k /= 2) { + if ((dmabuf = alloc_contig(k * 1024, AC_LOWER16M | AC_ALIGN64K, + &dmabuf_phys))) + break; + if ((dmabuf = alloc_contig(2 * k * 1024, AC_LOWER16M | AC_ALIGN4K, + &dmabuf_phys))) + break; + } + + if (k == 0) + panic("sef_cb_init: couldn't allocate DMA buffer"); + + dmabuf_len = k * 1024; + + if (dmabuf_phys/DMA_ALIGN != (dmabuf_phys+dmabuf_len-1)/DMA_ALIGN) { + off = dmabuf_phys % DMA_ALIGN; + dmabuf += (DMA_ALIGN - off); + dmabuf_phys += (DMA_ALIGN - off); + } + + printf("b004: allocated a %d byte DMA buffer\n", dmabuf_len); + + dma.endpt = 0; + + if (board_type == 0) + b004_probe(); + + if (type != SEF_INIT_LU) + chardriver_announce(); + + if (board_type != 0) + board_busy = 0; + + return OK; +} + +/* + * PROBE: reset the expected B004 compatible hardware, then check + * that the Output Status Register indicates being ready to + * transmit. Once this is established, verify that we can + * enable interrupts properly, then fire off a blind DMA + * write of one byte. If this works, the interrupt handler + * will detect it, and enable DMA use. + * + * The enabling and disabling of the interrupt sources is + * done so the IRQ won't be enabled without active driving + * of the line by the board: otherwise, it'll tri-state its + * output, and this may generate spurious interrupts. + */ + +void b004_probe(void) { + unsigned int b; + + b004_reset(); + + if (sys_outb(B004_OSR, 0) == OK) { + if (sys_inb(B004_OSR, &b) == OK) { + if (b & B004_READY) { + board_type = B004; + irq_hook_id = B004_IRQ; + sys_outb(B004_ISR, B004_INT_ENA); + sys_outb(B004_OSR, B004_INT_ENA); + sys_outb(B008_INT, B008_DMAINT_ENA); + if ((sys_irqsetpolicy(B004_IRQ, 0, &irq_hook_id) != OK) || + (sys_irqenable(&irq_hook_id) != OK)) + panic("sef_cb_init: couldn't enable interrupts"); + sys_irqdisable(&irq_hook_id); + sys_outb(B004_ISR, B004_INT_DIS); + sys_outb(B004_OSR, B004_INT_DIS); + sys_outb(B008_INT, B008_INT_DIS); + printf("b004: probe found a B004 compatible device.\n"); + board_busy = 0; + probe_active = 1; + dmabuf[0] = 0; + dma_transfer(dmabuf_phys, 1, 1); + } + } + } +} + +/* + * RESET: the I/O operations to reset a B004 compatible device. + */ + +void b004_reset(void) { + + sys_outb(B004_ANALYSE, 0); + usleep(B004_RST_DELAY); + sys_outb(B004_RESET, 0); + usleep(B004_RST_DELAY); + sys_outb(B004_RESET, 1); + usleep(B004_RST_DELAY); + sys_outb(B004_RESET, 0); + usleep(B004_RST_DELAY); +} + +/* + * ANALYSE: the I/O operations to switch a B004 compatible device + * into analyse mode; used by debuggers to talk directly + * to the first Transputer on the physical device. + */ + +void b004_analyse(void) { + + sys_outb(B004_ANALYSE, 0); + usleep(B004_RST_DELAY); + sys_outb(B004_RESET, 0); + usleep(B004_RST_DELAY); + sys_outb(B004_ANALYSE, 1); + usleep(B004_RST_DELAY); + sys_outb(B004_RESET, 1); + usleep(B004_RST_DELAY); + sys_outb(B004_RESET, 0); + usleep(B004_RST_DELAY); + sys_outb(B004_ANALYSE, 0); + usleep(B004_RST_DELAY); +} + +/* + * MAIN: run the startup routine, then pass control to the library + * routine that handles character driver messages, and calls + * our various message handler functions, above. + */ + +int main(void) { + + sef_local_startup(); + + chardriver_task(&b004_tab); + + return OK; +} diff --git a/minix/drivers/inmos/b004/b004.conf b/minix/drivers/inmos/b004/b004.conf new file mode 100644 index 000000000..0ebac4295 --- /dev/null +++ b/minix/drivers/inmos/b004/b004.conf @@ -0,0 +1,24 @@ +# +# INMOS B004/B008 Transputer TRAM Motherboard character device +# + +service b004 +{ + io 150:20 # Standard B004 I/O address is $150 + 0:10 # DMA controller + 83 # Also DMA + ; + irq + 5 # Standard B004 IRQ is 3 + ; + system + UMAP # 14 + IRQCTL # 19 + DEVIO # 21 + VDEVIO # 23 + ; + ipc + SYSTEM + ; + uid 0; +}; diff --git a/minix/drivers/inmos/b004/b004.h b/minix/drivers/inmos/b004/b004.h new file mode 100644 index 000000000..b59452368 --- /dev/null +++ b/minix/drivers/inmos/b004/b004.h @@ -0,0 +1,58 @@ +/* + * INMOS B004/B008 Transputer TRAM Motherboard character device + */ + +#ifndef __B004_H +#define __B004_H + +#define B004_IRQ 5 +#define B004_BASE 0x150 + +#define B004_IDR (B004_BASE + 0x0) /* Input data register */ +#define B004_ODR (B004_BASE + 0x1) /* Output data register */ +#define B004_ISR (B004_BASE + 0x2) /* Input status register */ +#define B004_OSR (B004_BASE + 0x3) /* Output status register */ +#define B004_RESET (B004_BASE + 0x10) /* Reset register (write) */ +#define B004_ERROR (B004_BASE + 0x10) /* Error register (read) */ +#define B004_ANALYSE (B004_BASE + 0x11) /* Analyse register */ +#define B008_DMA (B004_BASE + 0x12) /* B008 DMA request register */ +#define B008_INT (B004_BASE + 0x13) /* B008 interrupt ctl. reg. */ + +#define B004_READY 0x1 +#define B004_HAS_ERROR 0x1 +#define B004_INT_ENA 0x2 +#define B004_INT_DIS 0x0 + +#define B004_RST_DELAY 100000 /* 100 milliseconds (usleep) */ + +#define B008_DMAINT_ENA 0x1 +#define B008_ERRINT_ENA 0x2 +#define B008_OUTINT_ENA 0x4 +#define B008_INPINT_ENA 0x8 +#define B008_INT_MASK 0xf +#define B008_INT_DIS 0x0 + +#define B008_DMAWRITE 0x0 /* DMA transfer to B008 board */ +#define B008_DMAREAD 0x1 /* DMA transfer from B008 board */ + +#define LINKBUF_SIZE (64*1024) + +#define DMA_ALIGN (64*1024) /* DMA must stay within a click */ + +#define DMA_THRESHOLD 8 /* Polled I/O for smaller xfers */ + +#define DMA_ADDR 0x002 /* DMA chan 1 port; low 16 addr bits */ +#define DMA_TOP 0x083 /* DMA chan 1 port; high 8 addr bits */ +#define DMA_COUNT 0x003 /* DMA chan 1 port; byte count - 1 */ + +#define DMA_FLIPFLOP 0x00C /* DMA byte pointer flip-flop */ +#define DMA_MODE 0x00B /* DMA mode port */ +#define DMA_INIT 0x00A /* DMA init port */ + +#define DMA_MASK 0x05 /* set mask for DMA channel 1 */ +#define DMA_UNMASK 0x01 /* unset mask for DMA channel 1 */ + +#define DMA_READ 0x05 /* DMA read; chan 1 demand mode */ +#define DMA_WRITE 0x09 /* DMA write; chan 1 demand mode */ + +#endif /* __B004_H */ diff --git a/minix/include/minix/dmap.h b/minix/include/minix/dmap.h index 4617b807d..68d169ebb 100644 --- a/minix/include/minix/dmap.h +++ b/minix/include/minix/dmap.h @@ -77,9 +77,10 @@ /* 56-63 = /dev/vnd[0-7] (vnd) */ #define INPUT_MAJOR 64 /* 64 = /dev/input (input) */ #define USB_BASE_MAJOR 65 /* 65-133 = USB major range */ -#define PCI_MAJOR 134 /* 134 = /dev/pci (pci) */ +#define PCI_MAJOR 134 /* 134 = /dev/pci (pci) */ +#define B004_MAJOR 135 /* 135 = /dev/link0 (transputers) */ -#define NR_DEVICES 135 /* number of (major) devices */ +#define NR_DEVICES 136 /* number of (major) devices */ /* Minor device numbers for memory driver. */ # define RAM_DEV_OLD 0 /* minor device for /dev/ram */ diff --git a/minix/include/sys/Makefile b/minix/include/sys/Makefile index e1ddfcbf8..aef8b6ea1 100644 --- a/minix/include/sys/Makefile +++ b/minix/include/sys/Makefile @@ -3,8 +3,8 @@ INCSDIR= /usr/include/sys # Minix specific system headers INCS= elf64.h elf_common.h elf_core.h elf_generic.h \ - ioc_block.h ioc_disk.h ioc_fb.h ioc_fbd.h ioc_file.h ioc_memory.h \ - ioc_net.h ioc_sound.h ioc_tape.h \ + ioc_b004.h ioc_block.h ioc_disk.h ioc_fb.h ioc_fbd.h ioc_file.h \ + ioc_memory.h ioc_net.h ioc_sound.h ioc_tape.h \ kbdio.h \ procfs.h statfs.h svrctl.h video.h diff --git a/minix/include/sys/ioc_b004.h b/minix/include/sys/ioc_b004.h new file mode 100644 index 000000000..e4236070d --- /dev/null +++ b/minix/include/sys/ioc_b004.h @@ -0,0 +1,35 @@ +/* + * INMOS B004/B008 Transputer TRAM Motherboard character device + */ + +#ifndef _S_I_B004_H +#define _S_I_B004_H + +#include + +#define B004 4 +#define B008 8 + +struct b004_flags { + unsigned int b004_board; + unsigned int b004_timeout; + unsigned char b004_readable; + unsigned char b004_writeable; + unsigned char b004_error; + unsigned char b004_dma_ok; +}; + +#define B004GETTIMEOUT _IOR ('T', 1, int) +#define B004SETTIMEOUT _IOW ('T', 2, int) +#define B004TIMEOUT _IO ('T', 3) +#define B004BOARDTYPE _IO ('T', 4) +#define B004READABLE _IO ('T', 5) +#define B004WRITEABLE _IO ('T', 6) +#define B004ERROR _IO ('T', 7) +#define B004GETFLAGS _IOR ('T', 8, struct b004_flags) +#define B004DMADISABLE _IO ('T', 9) +#define B004DMAENABLE _IO ('T', 10) +#define B004RESET _IO ('T', 11) +#define B004ANALYSE _IO ('T', 12) + +#endif /* _S_I_B004_H */ diff --git a/minix/man/man4/Makefile b/minix/man/man4/Makefile index 7da35b1ae..c09e766d5 100644 --- a/minix/man/man4/Makefile +++ b/minix/man/man4/Makefile @@ -10,4 +10,8 @@ MLINKS += controller.4 aha1540.4 MLINKS += controller.4 ncr810.4 MLINKS += controller.4 dosfile.4 +.if ${MACHINE_ARCH} == "i386" +MAN+= b004.4 +.endif # ${MACHINE_ARCH} == "i386" + .include diff --git a/minix/man/man4/b004.4 b/minix/man/man4/b004.4 new file mode 100644 index 000000000..18f93a939 --- /dev/null +++ b/minix/man/man4/b004.4 @@ -0,0 +1,89 @@ +.TH B004 4 +.SH NAME +b004 \- INMOS B004/B008 Transputer TRAM Motherboard +.SH DESCRIPTION +The +.B b004 +character device driver interfaces to standard Transputer hardware +compatible with the +.B INMOS +motherboards that plugged into the +.B ISA +bus on the +.B IBM PC +and +.B IBM PC AT +computers. +.SH DESCRIPTION +Hardware that interfaces a Transputer, or a network of Transputers, to +a PC, normally implements the interface standard that +.B INMOS +established with their +.B B004 +evaluation board, and which they kept using with the later boards, +although they extended the interface along the way. The +.B B004 +has a simple, polled, interface using a handful of I/O ports on the +.B ISA +bus, The I/O port group was at address 0x150. +.PP +The later +.B B008 +board was configurable to three different I/O port blocks (0x150, +0x200, or 0x300), three choices of +.B DMA +channels (0, 1, or 3), and either +.B IRQ +3 or +.B IRQ +5. +The B008 board could turn the +.B IBM PC AT +into a parallel supercomputer. +The +.B T800 +processor was about ten times as powerful as that machine, you could +fit ten of those on a single +.B B008 +board, and you could squeeze four such boards into the +.B AT, +giving you 400 times the power of the host system. +Three of these boards would have their I/O ports, +.B IRQ, +and +.B DMA +all disabled, being instead internally connected as clients of the +first board in the host system. +.PP +The +.B b004 +driver handles the communication with a +.B B004 +or +.B B008 +compatible board, discovers which of the two it's dealing with, and +handles the I/O operations transparently to the client. It only +allows one client at a time to open the link, and insists on only one +operation at at time being active on the link. This was normal for +drivers for these devices, and is expected by software using them. +.PP +Additionally, the driver supports a number of \fIioctl\fR calls, to +handle various parameter settings, particularly I/O timeout, and +status inquiries. For details of these, read +\fI/usr/include/sys/ioc_b004.h\fR +.SH FILES +The special device used is /dev/link0, as this is the name most +existing applications tend to assume. +.SH BUGS +The driver currently insists that the board must be at I/O address +0x150, and, if a B008, use IRQ 5 and DRQ 1. This is the setup that +tends to fit with semi-modern PCs with an ISA bus, but the driver +could do with an update to make this configurable, either using run +time switches, or by having minor device numbers representing +different combinations of the available options. +.SH "SEE ALSO" +.BR ispy (1), +.BR mtest (1), +.BR iserver (1) +.SH AUTHOR +Tom Ivar Helbekkmo (tih@hamartun.priv.no) diff --git a/sys/sys/ioctl.h b/sys/sys/ioctl.h index 393f57453..c3a7ec8f9 100644 --- a/sys/sys/ioctl.h +++ b/sys/sys/ioctl.h @@ -72,6 +72,7 @@ struct ttysize { #include /* 'b' */ #include /* 'B' */ #include /* 'V' */ +#include /* 'T' */ #include /* 'F' */ #include #endif /* defined(__minix) */