BSD 4_3_Tahoe development
[unix-history] / usr / src / cci / enpload.c
CommitLineData
f6458c6a
C
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
26typedef 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
34ENP 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};
41short num_enp = sizeof(enp_tab) / sizeof(enp_tab[0]);
42
43ENP *getenp();
44short 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
55typedef struct bins
56{
57 short b_fid;
58 char *b_name;
59} BINS;
60
61BINS file_tab[ MAXFILE ]; /* fid/name of a.outs */
62
63char enpdev[] = "/dev/enpXram";
64char buff[ BSIZE ]; /* I/O Buffer */
65char zbuf[ BSIZE ]; /* For quick clearing */
66
67int nostart;
68int noload;
69
70main( argc,argv )
71int argc;
72char **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
234ENP *
235getenp( np )
236register 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
249closem( cnt )
250register 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}