1 /* 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Computer Consoles Inc. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the University of California, Berkeley. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 */ 20 21 #ifndef lint 22 char copyright[] = 23 "@(#) Copyright (c) 1988 The Regents of the University of California.\n\ 24 All rights reserved.\n"; 25 #endif /* not lint */ 26 27 #ifndef lint 28 static char sccsid[] = "@(#)enpload.c 5.2 (Berkeley) 09/18/88"; 29 #endif /* not lint */ 30 31 /* 32 * CMC Ethernet ``Microcode'' Loader. 33 */ 34 #include <stdio.h> 35 #include <a.out.h> 36 37 #include <sys/types.h> 38 #include <sys/file.h> 39 #include <sys/ioctl.h> 40 #include <tahoeif/if_enpreg.h> 41 42 char *dev; 43 44 main(argc, argv) 45 int argc; 46 char *argv[]; 47 { 48 int enp = -1, fd, first = 1, nostart = 0; 49 50 argc--, argv++; 51 if (argc > 0) { 52 enp = open(dev = argv[0], O_RDWR); 53 if (enp < 0) { 54 fprintf(stderr, "enpload: "); 55 perror(dev); 56 exit(-1); 57 } 58 argc--, argv++; 59 } 60 for (; argc > 0; argc--, argv++) { 61 if (strcmp(argv[0], "-s") == 0 || strcmp(argv[0], "-S") == 0) { 62 nostart++; 63 continue; 64 } 65 if (first) { 66 /* 67 * Reset device before first file is loaded. 68 */ 69 if (ioctl(enp, ENPIORESET) < 0) { 70 fprintf(stderr, "enpload: %s: ", dev); 71 perror("ioctl (ENPIORESET)"); 72 exit(-1); 73 } 74 first = !first; 75 } 76 if ((fd = open(argv[0], O_RDONLY)) < 0) { 77 fprintf(stderr, "enpload: "), perror(argv[0]); 78 exit(1); 79 } 80 enpload(enp, fd, argv[0]); 81 close(fd); 82 } 83 if (enp != -1 && !nostart && ioctl(enp, ENPIOGO) < 0) { 84 fprintf(stderr, "enpload: "); 85 perror("ioctl (ENPIOGO)"); 86 exit(-1); 87 } 88 exit(0); 89 } 90 91 #define RELO 0x03FFFF /* relocation offset */ 92 #define ENPMSTART 0x0 /* start of memory */ 93 #define BSIZE 512 /* buffer size */ 94 char buff[BSIZE]; 95 char zbuf[BSIZE]; 96 97 enpload(enp, fd, filename) 98 int enp, fd; 99 char *filename; 100 { 101 int cnt, size, lstart; 102 struct exec hdr; 103 104 if (read(fd, &hdr, sizeof (hdr)) != sizeof (hdr)) { 105 fprintf(stderr, "enpload: %s: Read short (header).\n", 106 filename); 107 exit(1); 108 } 109 if (N_BADMAG(hdr)) { 110 fprintf(stderr, "enpload: %s: Bad magic number.\n", filename); 111 exit(1); 112 } 113 size = hdr.a_text + hdr.a_data; 114 lstart = (ENPMSTART + (hdr.a_entry & RELO)) - 0x1000; 115 116 printf("%s: Loading %s...", dev, filename); 117 (void) lseek(enp, lstart + size, L_SET); 118 while (hdr.a_bss >= BSIZE) { 119 if (write(enp, zbuf, BSIZE) != BSIZE) { 120 fprintf(stderr, "enpload: Bss write error.\n"); 121 exit(-1); 122 } 123 hdr.a_bss -= BSIZE; 124 } 125 if (hdr.a_bss > 0 && write(enp, zbuf, hdr.a_bss) != hdr.a_bss) { 126 fprintf(stderr, "enpload: Bss write error.\n"); 127 exit(-1); 128 } 129 (void) lseek(enp, lstart, L_SET); 130 while (size > BSIZE) { 131 cnt = read(fd, buff, BSIZE); 132 size -= cnt; 133 if (write(enp, buff, cnt) != cnt) { 134 fprintf(stderr, "enpload: Write error.\n"); 135 exit(-1); 136 } 137 } 138 if (size > 0) { 139 cnt = read(fd, buff, size); 140 if (write(enp, buff, cnt) != cnt) { 141 fprintf(stderr, "enpload: Write error.\n"); 142 exit(-1); 143 } 144 } 145 printf("done.\n"); 146 } 147