|
|
1.1 root 1: #include <a.out.h>
2: #include <fcntl.h>
3: #include <stdio.h>
4:
5: #define mkioctl(type,value) (0x20000000|('type'<<8)|value)
6:
7: #define ENPIOGO mkioctl( S,1 ) /* start the enp */
8: #define ENPIORESET mkioctl( S,2 ) /* reset the enp */
9:
10: #define ENP0 0x0 /* Enp's 0 Memory */
11: #define ENP1 0x0 /* Enp's 1 Memory */
12: #define ENP2 0x0 /* Enp's 2 Memory */
13: #define ENP3 0x0 /* Enp's 3 Memory */
14:
15: #define RELO 0x03FFFF /* ENP->Kernel Mask */
16:
17: #define BUTTON 0x1000 /* Addr to "push" for startup */
18: #define JADDR 0x1004 /* Start vector goes here */
19: #define JUMP 0x8080 /* "jump" command */
20:
21: /*
22: * ENP "device" table (so we can load multiple ENPs)
23: * See ENP/30 User Guide
24: */
25:
26: typedef struct enp
27: {
28: char name[8]; /* Device's "name" */
29: long mstart; /* Host's idea of enp mem org */
30: long button; /* Addr of "go" button */
31: long jaddr; /* Addr of "jump" command */
32: } ENP;
33:
34: ENP enp_tab[] =
35: {
36: { "enp0", ENP0, ENP0 + BUTTON, ENP0 + JADDR, },
37: { "enp1", ENP1, ENP1 + BUTTON, ENP1 + JADDR, },
38: { "enp2", ENP2, ENP2 + BUTTON, ENP2 + JADDR, },
39: { "enp3", ENP3, ENP3 + BUTTON, ENP3 + JADDR, },
40: };
41: short num_enp = sizeof(enp_tab) / sizeof(enp_tab[0]);
42:
43: ENP *getenp();
44: short enpfid = -1; /* dev "enpram" fid */
45:
46:
47: /*
48: * For loading from a.out files ...
49: */
50:
51: #define BSIZE 512 /* Size buffer we use */
52: #define MAXFILE 4 /* Max of 4 a.outs */
53: #define MAXBIN 4 /* bin files on command line */
54:
55: typedef struct bins
56: {
57: short b_fid;
58: char *b_name;
59: } BINS;
60:
61: BINS file_tab[ MAXFILE ]; /* fid/name of a.outs */
62:
63: char enpdev[] = "/dev/enpXram";
64: char buff[ BSIZE ]; /* I/O Buffer */
65: char zbuf[ BSIZE ]; /* For quick clearing */
66:
67: int nostart;
68: int noload;
69:
70: main( argc,argv )
71: int argc;
72: char **argv;
73: {
74: register BINS *fp; /* File params */
75: register short fcnt,i; /* Files to load */
76: struct exec hdr; /* a.out header */
77: int cnt; /* I/O count */
78: long f_size,bss_size; /* text + data & bss */
79:
80: register ENP *ep; /* enp_tab pointer */
81: unsigned long enp_go; /* Start up vector */
82: short enp_jump = JUMP; /* "jump" command */
83: long lstart; /* Start loading at */
84: long cstart; /* Clear from */
85:
86:
87: if( (argc < 3) || (argc > 3 + MAXBIN) )
88: {
89: printf( "usage: enpload dev file_1 [ file_2 ... file_4 ]\n" );
90: exit( 1 );
91: }
92: argv++;
93: if( (ep = getenp( *argv++ )) == 0 )
94: {
95: printf( "Bad ENP device name!\n" );
96: exit( 1 );
97: }
98:
99: enpdev[8] = ep->name[3];
100: dup2(1,2); /* redirect sdterr to stdout */
101: if( (enpfid = open(enpdev,O_RDWR)) == -1 )
102: {
103: sprintf(zbuf, "enpload: Can't open %s ram", ep->name);
104: perror( zbuf );
105: exit( 1 );
106: }
107:
108: /* Collect file names and compute number of them */
109:
110: fp = file_tab; fcnt = 0;
111: while( *argv )
112: {
113: if( argv[0][0] == '-' )
114: {
115: if( argv[0][1] == 'L' )
116: noload = 1;
117: else
118: if( argv[0][1] == 'S' )
119: nostart = 1;
120: argv++;
121: }
122: else
123: {
124: fp->b_name = *argv++;
125: fp++; fcnt++;
126: }
127: }
128:
129: /* Zero buffer used to clear bss storage in ENP */
130:
131: for( i = 0; i < BSIZE; i++ )
132: {
133: zbuf[i] = 0;
134: }
135:
136: if( noload )
137: {
138: printf("Restart %s at 0xf02000\n", ep->name);
139: ioctl( enpfid,ENPIOGO,0xf02000 );
140: exit( 0 );
141: }
142: ioctl( enpfid,ENPIORESET,0 );
143:
144: /* Open, validate, and load each file_tab[] file */
145:
146: for( i = 0; i < fcnt; i++ )
147: {
148: fp = &file_tab[i];
149: if( (fp->b_fid = open( fp->b_name,O_RDONLY )) == -1 )
150: {
151: printf( "enpload: Can't open %s!\n",fp->b_name );
152: closem( i-1 );
153: exit( 1 );
154: }
155:
156: if( read( fp->b_fid,&hdr,sizeof( hdr ) ) != sizeof( hdr) )
157: {
158: printf( "enpload: %s Bad header!\n",fp->b_name );
159: closem( i );
160: exit( 1 );
161: }
162:
163: if( N_BADMAG( hdr ) )
164: {
165: printf( "enpload: %s Bad magic!\n",fp->b_name );
166: closem( i );
167: exit( 1 );
168: }
169:
170: f_size = hdr.a_text + hdr.a_data;
171: bss_size = hdr.a_bss;
172: lstart = (ep->mstart + (hdr.a_entry & RELO)) - 0x1000;
173: cstart = lstart + f_size;
174:
175: printf("Loading %s --- ", enpdev);
176: printf( "with file: %s --- ",fp->b_name );
177: /*
178: printf( "text + data: %d bss: %d\n",f_size,bss_size );
179: printf( "ENP's a_entry addr: %06X\n",hdr.a_entry );
180: printf( "load start:%06X bss start:%06X\n",lstart,cstart );
181:
182: printf( "Clearing bss ... " );
183: */
184: lseek( enpfid,cstart,0 );
185: while( bss_size >= BSIZE )
186: {
187: if( write( enpfid,zbuf,BSIZE ) != BSIZE )
188: printf("enpload: bss write error\n");
189: bss_size -= BSIZE;
190: }
191: if( bss_size > 0 )
192: {
193: write( enpfid,zbuf,bss_size );
194: }
195: /*
196: printf( "DONE!\n" );
197: */
198:
199: /*
200: printf( "Loading ... " );
201: */
202: lseek( enpfid,lstart,0 );
203: while( f_size > BSIZE )
204: {
205: cnt = read( fp->b_fid,buff,BSIZE );
206: f_size -= cnt;
207: if( write( enpfid,buff,cnt ) != cnt )
208: perror("enpload: write");
209: }
210: if( f_size > 0 )
211: {
212: cnt = read( fp->b_fid,buff,f_size );
213: write( enpfid,buff,cnt );
214: }
215: printf( "DONE!\n" );
216: }
217:
218: /* Last file, we exec this one */
219:
220: if( nostart == 0 )
221: {
222: enp_go = hdr.a_entry;
223: /*
224: printf( "Starting ENP execution at %X ... ",enp_go );
225: */
226: ioctl( enpfid,ENPIOGO, enp_go );
227: /*
228: printf( "DONE!\n" );
229: */
230: }
231: }
232:
233:
234: ENP *
235: getenp( np )
236: register char *np;
237: {
238: register ENP *ep;
239:
240: for( ep = enp_tab; ep < &enp_tab[num_enp]; ep++ )
241: if( strcmp( np,ep->name ) == 0 )
242: {
243: return( ep );
244: }
245: return( 0 );
246: }
247:
248:
249: closem( cnt )
250: register short cnt;
251: {
252: register BINS *fp;
253:
254: for( fp = file_tab; fp < &file_tab[cnt]; fp++ )
255: {
256: close( fp->b_fid );
257: }
258: if( enpfid != -1 )
259: {
260: close( enpfid );
261: }
262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.