1*35524Sbostic /* 2*35524Sbostic * Copyright (c) 1988 The Regents of the University of California. 3*35524Sbostic * All rights reserved. 4*35524Sbostic * 5*35524Sbostic * This code is derived from software contributed to Berkeley by 6*35524Sbostic * Computer Consoles Inc. 7*35524Sbostic * 8*35524Sbostic * Redistribution and use in source and binary forms are permitted 9*35524Sbostic * provided that the above copyright notice and this paragraph are 10*35524Sbostic * duplicated in all such forms and that any documentation, 11*35524Sbostic * advertising materials, and other materials related to such 12*35524Sbostic * distribution and use acknowledge that the software was developed 13*35524Sbostic * by the University of California, Berkeley. The name of the 14*35524Sbostic * University may not be used to endorse or promote products derived 15*35524Sbostic * from this software without specific prior written permission. 16*35524Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*35524Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*35524Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19*35524Sbostic */ 20*35524Sbostic 2130988Ssam #ifndef lint 22*35524Sbostic char copyright[] = 23*35524Sbostic "@(#) Copyright (c) 1988 The Regents of the University of California.\n\ 24*35524Sbostic All rights reserved.\n"; 25*35524Sbostic #endif /* not lint */ 2630988Ssam 27*35524Sbostic #ifndef lint 28*35524Sbostic static char sccsid[] = "@(#)enpload.c 5.2 (Berkeley) 09/18/88"; 29*35524Sbostic #endif /* not lint */ 30*35524Sbostic 3130988Ssam /* 3230988Ssam * CMC Ethernet ``Microcode'' Loader. 3330988Ssam */ 3430988Ssam #include <stdio.h> 3530988Ssam #include <a.out.h> 3630988Ssam 3730988Ssam #include <sys/types.h> 3830988Ssam #include <sys/file.h> 3930988Ssam #include <sys/ioctl.h> 4030988Ssam #include <tahoeif/if_enpreg.h> 4130988Ssam 4230988Ssam char *dev; 4330988Ssam 4430988Ssam main(argc, argv) 4530988Ssam int argc; 4630988Ssam char *argv[]; 4730988Ssam { 4830988Ssam int enp = -1, fd, first = 1, nostart = 0; 4930988Ssam 5030988Ssam argc--, argv++; 5130988Ssam if (argc > 0) { 5230988Ssam enp = open(dev = argv[0], O_RDWR); 5330988Ssam if (enp < 0) { 5430988Ssam fprintf(stderr, "enpload: "); 5530988Ssam perror(dev); 5630988Ssam exit(-1); 5730988Ssam } 5830988Ssam argc--, argv++; 5930988Ssam } 6030988Ssam for (; argc > 0; argc--, argv++) { 6130988Ssam if (strcmp(argv[0], "-s") == 0 || strcmp(argv[0], "-S") == 0) { 6230988Ssam nostart++; 6330988Ssam continue; 6430988Ssam } 6530988Ssam if (first) { 6630988Ssam /* 6730988Ssam * Reset device before first file is loaded. 6830988Ssam */ 6930988Ssam if (ioctl(enp, ENPIORESET) < 0) { 7030988Ssam fprintf(stderr, "enpload: %s: ", dev); 7130988Ssam perror("ioctl (ENPIORESET)"); 7230988Ssam exit(-1); 7330988Ssam } 7430988Ssam first = !first; 7530988Ssam } 7630988Ssam if ((fd = open(argv[0], O_RDONLY)) < 0) { 7730988Ssam fprintf(stderr, "enpload: "), perror(argv[0]); 7830988Ssam exit(1); 7930988Ssam } 8030988Ssam enpload(enp, fd, argv[0]); 8130988Ssam close(fd); 8230988Ssam } 8330988Ssam if (enp != -1 && !nostart && ioctl(enp, ENPIOGO) < 0) { 8430988Ssam fprintf(stderr, "enpload: "); 8530988Ssam perror("ioctl (ENPIOGO)"); 8630988Ssam exit(-1); 8730988Ssam } 8830988Ssam exit(0); 8930988Ssam } 9030988Ssam 9130988Ssam #define RELO 0x03FFFF /* relocation offset */ 9230988Ssam #define ENPMSTART 0x0 /* start of memory */ 9330988Ssam #define BSIZE 512 /* buffer size */ 9430988Ssam char buff[BSIZE]; 9530988Ssam char zbuf[BSIZE]; 9630988Ssam 9730988Ssam enpload(enp, fd, filename) 9830988Ssam int enp, fd; 9930988Ssam char *filename; 10030988Ssam { 10130988Ssam int cnt, size, lstart; 10230988Ssam struct exec hdr; 10330988Ssam 10430988Ssam if (read(fd, &hdr, sizeof (hdr)) != sizeof (hdr)) { 10530988Ssam fprintf(stderr, "enpload: %s: Read short (header).\n", 10630988Ssam filename); 10730988Ssam exit(1); 10830988Ssam } 10930988Ssam if (N_BADMAG(hdr)) { 11030988Ssam fprintf(stderr, "enpload: %s: Bad magic number.\n", filename); 11130988Ssam exit(1); 11230988Ssam } 11330988Ssam size = hdr.a_text + hdr.a_data; 11430988Ssam lstart = (ENPMSTART + (hdr.a_entry & RELO)) - 0x1000; 11530988Ssam 11630988Ssam printf("%s: Loading %s...", dev, filename); 11730988Ssam (void) lseek(enp, lstart + size, L_SET); 11830988Ssam while (hdr.a_bss >= BSIZE) { 11930988Ssam if (write(enp, zbuf, BSIZE) != BSIZE) { 12030988Ssam fprintf(stderr, "enpload: Bss write error.\n"); 12130988Ssam exit(-1); 12230988Ssam } 12330988Ssam hdr.a_bss -= BSIZE; 12430988Ssam } 12530988Ssam if (hdr.a_bss > 0 && write(enp, zbuf, hdr.a_bss) != hdr.a_bss) { 12630988Ssam fprintf(stderr, "enpload: Bss write error.\n"); 12730988Ssam exit(-1); 12830988Ssam } 12930988Ssam (void) lseek(enp, lstart, L_SET); 13030988Ssam while (size > BSIZE) { 13130988Ssam cnt = read(fd, buff, BSIZE); 13230988Ssam size -= cnt; 13330988Ssam if (write(enp, buff, cnt) != cnt) { 13430988Ssam fprintf(stderr, "enpload: Write error.\n"); 13530988Ssam exit(-1); 13630988Ssam } 13730988Ssam } 13830988Ssam if (size > 0) { 13930988Ssam cnt = read(fd, buff, size); 14030988Ssam if (write(enp, buff, cnt) != cnt) { 14130988Ssam fprintf(stderr, "enpload: Write error.\n"); 14230988Ssam exit(-1); 14330988Ssam } 14430988Ssam } 14530988Ssam printf("done.\n"); 14630988Ssam } 147