|
|
1.1 root 1: %token DEFBRK COLON OCTAL INTEGER IDENT CSR IVEC OVEC IINT OINT
2: INIT OPEN CLOSE READ WRITE SEEK CNTL IS ON GETC PUTC
3: %{
4: #include <stdio.h>
5:
6: #define NIL (dvptr)0
7:
8: #define CONFIGC "../sys/conf.c" /* name of .c output */
9: #define CONFIGH "../h/conf.h" /* name of .h output */
10: #define DISPCONF "../h/dispconf.h" /* name of dispatcher .h*/
11: #define IODISP "../h/iodisp.h" /* name of dispat loc .h*/
12: #define CONFHREF "<conf.h>" /* how conf.h referenced*/
13: #define CONFIGIN "Configuration" /* name of input file */
14:
15: FILE *confc;
16: FILE *confh;
17: FILE *dispconf;
18: FILE *iodisp;
19:
20: char *dbstr;
21: extern char *malloc();
22: int ndevs = 0;
23: int currname = -1;
24: int currtname = -1;
25: int currdname = -1;
26: int brkcount = 0;
27:
28: struct syment { /* symbol table */
29: char *symname;
30: int symoccurs;
31: } symtab[250];
32:
33: int nsym = 0;
34: int lookup();
35: int linectr = 1;
36: char *doing = "device type declaration";
37: char *s;
38: struct dvtype {
39: char *dvname; /* device name (not used in types)*/
40: char *dvtname; /* type name */
41: int dvtnum; /* symbol table index of type */
42: char *dvdevice; /* device name */
43: int dvcsr; /* Control Status Register addr */
44: int dvivec; /* input interrupt vector */
45: int dvovec; /* Output interrupt vector */
46: char dviint[20]; /* input interrupt routine */
47: char dvoint[20]; /* output interrupt routine */
48: char dvinit[20]; /* init routine name */
49: char dvopen[20]; /* open routine name */
50: char dvclose[20]; /* close routine name */
51: char dvread[20]; /* read routine name */
52: char dvwrite[20]; /* write routine name */
53: char dvcntl[20]; /* control routine name */
54: char dvseek[20]; /* seek routine name */
55: char dvgetc[20]; /* getc routine name */
56: char dvputc[20]; /* putc routine name */
57: int dvminor; /* device number 0,1,... */
58: struct dvtype *dvnext; /* next node on the list */
59: };
60: typedef struct dvtype *dvptr;
61: dvptr ftypes = NIL; /* linked list of device types */
62: dvptr devs = NIL; /* linked list of device decls. */
63: dvptr lastdv = NIL;
64: dvptr currtype = NIL;
65:
66: char *ftout[] =
67: {"#ifndef\tASM\n",
68: "struct\tdevsw\t{\t\t\t/* device table entry */\n",
69: "\tint\tdvnum;\n",
70: "\tchar\t*dvname;\n",
71: "\tint\t(*dvinit)();\n",
72: "\tint\t(*dvopen)();\n",
73: "\tint\t(*dvclose)();\n",
74: "\tint\t(*dvread)();\n",
75: "\tint\t(*dvwrite)();\n",
76: "\tint\t(*dvseek)();\n",
77: "\tint\t(*dvgetc)();\n",
78: "\tint\t(*dvputc)();\n",
79: "\tint\t(*dvcntl)();\n",
80: "\tint\tdvcsr;\n",
81: "\tint\tdvivec;\n",
82: "\tint\tdvovec;\n",
83: "\tint\t(*dviint)();\n",
84: "\tint\t(*dvoint)();\n",
85: "\tchar\t*dvioblk;\n",
86: "\tint\tdvminor;\n",
87: "\t};\n\n",
88: "extern\tstruct\tdevsw devtab[];",
89: "\t\t/* one entry per device */\n",
90: "#endif\n\n",
91: NULL};
92: %}
93: %%
94: config.input : devicetypes devicedescriptors
95: ;
96: devicetypes : ftypes DEFBRK
97: {doing = "device definitions";}
98: ;
99: ftypes : /**/
100: | ftypes ftype
101: ;
102: ftype : tname device.list
103: ;
104: device.list : devheader attribute.list
105: | device.list devheader attribute.list
106: ;
107: devheader : ON id
108: {mktype($2);}
109: ;
110: tname : id COLON
111: {$$ = currtname = cktname($1);}
112: ;
113: id : IDENT
114: {$$ = currname =
115: lookup(yytext,yyleng);
116: }
117: ;
118: attribute.list : /**/
119: | attribute.list attribute
120: ;
121: attribute : CSR number
122: {newattr(CSR,$2);}
123: | IVEC number
124: {newattr(IVEC,$2);}
125: | OVEC number
126: {newattr(OVEC,$2);}
127: | IINT id
128: {newattr(IINT,$2);}
129: | OINT id
130: {newattr(OINT,$2);}
131: | OPEN id
132: {newattr(OPEN,$2);}
133: | CLOSE id
134: {newattr(CLOSE,$2);}
135: | INIT id
136: {newattr(INIT,$2);}
137: | GETC id
138: {newattr(GETC,$2);}
139: | PUTC id
140: {newattr(PUTC,$2);}
141: | READ id
142: {newattr(READ,$2);}
143: | WRITE id
144: {newattr(WRITE,$2);}
145: | SEEK id
146: {newattr(SEEK,$2);}
147: | CNTL id
148: {newattr(CNTL,$2);}
149: ;
150: number : INTEGER
151: /* Assume all input is octal */
152: /* for now; distinction is */
153: /* made in lexical routines */
154: /* just in case of change */
155:
156: {$$ = otoi(yytext,yyleng);}
157: | OCTAL
158: {$$ = otoi(yytext,yyleng);}
159: ;
160: devicedescriptors : /**/
161: | devicedescriptors descriptor
162: ;
163: descriptor : fspec attribute.list
164: ;
165: fspec : dname IS id optional.on
166: {mkdev($1,$3,$4);}
167: ;
168: dname : id
169: {$$ = currdname = ckdname($1);}
170: ;
171: optional.on : /**/
172: {$$ = 0;}
173: | ON id
174: {$$ = $2;}
175: ;
176: %%
177: #include "lex.yy.c"
178: main(argc, argv)
179: int argc;
180: char *argv[];
181: {
182: int n, i, j, l, fcount;
183: dvptr s;
184: int verbose = 0;
185: char *p;
186: char c;
187:
188: if (argc>1 && (strcmp("-v",argv[1])==0)) {
189: argc--;
190: argv++;
191: verbose++;
192: }
193: if (argc>2) {
194: fprintf(stderr,"use: config [-v] [file]\n");
195: exit(1);
196: }
197: if (verbose)
198: printf("Opening input file...\n");
199: if (argc == 2) {
200: if (freopen(argv[1], "r", stdin) == NULL) {
201: fprintf(stderr,"Can't open %s\n",argv[1]);
202: exit(1);
203: }
204: } else { /* try to open Configuration file */
205: if (freopen(CONFIGIN, "r", stdin) == NULL) {
206: fprintf(stderr,"Can't open %s\n", CONFIGIN);
207: exit(1);
208: }
209: }
210:
211: /* Parse the Configuration file */
212:
213: if (verbose)
214: printf("Parsing configuration specs...\n");
215: if ((n=yyparse()) != 0)
216: exit(n);
217:
218: /* write config.h and config.c */
219:
220: if (verbose)
221: printf("Opening output files...\n");
222: if ( (confc=fopen(CONFIGC,"w") ) == NULL) {
223: fprintf(stderr, "Can't write on %s\n", CONFIGC);
224: exit(1);
225: }
226:
227: if ( (confh=fopen(CONFIGH,"w") ) == NULL) {
228: fprintf(stderr, "Can't write on %s\n", CONFIGH);
229: exit(1);
230: }
231: if ( (dispconf=fopen(DISPCONF,"w") ) == NULL) {
232: fprintf(stderr, "Can't write on %s\n",DISPCONF);
233: exit(1);
234: }
235: if ( (iodisp=fopen(IODISP,"w") ) == NULL) {
236: fprintf(stderr, "Can't write on %s\n",IODISP);
237: exit(1);
238: }
239: fprintf(confh,
240: "/* conf.h (GENERATED FILE; DO NOT EDIT) */\n");
241: fprintf(confc,
242: "/* conf.c (GENERATED FILE; DO NOT EDIT) */\n");
243: fprintf(dispconf,
244: "/* dispconf.h (GENERATED FILE; DO NOT EDIT) */\n");
245: fprintf(iodisp,
246: "/* iodisp.h (GENERATED FILE; DO NOT EDIT) */\n");
247: fprintf(confc, "\n#include %s\n", CONFHREF);
248: fprintf(confh, "\n#define\tNULLPTR\t(char *)0\n");
249:
250:
251: if (verbose)
252: printf("Writing output...\n");
253: fprintf(confh,"\n/* Device table declarations */\n");
254: for (i=0 ; (p=ftout[i])!=NULL ; i++)
255: fprintf(confh, "%s", p);
256: fprintf(dispconf,"\n/* vector-to points for each device */\n\n");
257: fprintf(iodisp,"\n/* i/o dispatch vector-to location externs */\n\n");
258: /* write device declarations and definitions; count type refs. */
259:
260: fprintf(confh, "\n/* Device name definitions */\n\n");
261: for (i=0,s=devs; s!=NIL ; s=s->dvnext,i++) {
262: fprintf(confh, "#define\t%-12s%d\t\t\t/* type %-8s */\n",
263: s->dvname, i, s->dvtname);
264: s->dvminor = symtab[s->dvtnum].symoccurs++;
265: }
266:
267: /* write count of device types */
268:
269: fprintf(confh,"\n/* Control block sizes */\n\n");
270: for (i=0 ; i<nsym ; i++)
271: if (symtab[i].symoccurs > 0) {
272: fprintf(confh, "#define\tN%s\t%d\n",
273: symtab[i].symname, symtab[i].symoccurs);
274: }
275: if (ndevs > 0)
276: fprintf(confh, "\n#define\tNDEVS\t%d\n\n", ndevs);
277:
278: /* empty symbol table, collect, and write names of all I/O routines */
279:
280: nsym = 0;
281: for (s=devs; s!=NIL ; s=s->dvnext) {
282: lookup(s->dvinit,strlen(s->dvinit));
283: lookup(s->dvopen,strlen(s->dvopen));
284: lookup(s->dvclose,strlen(s->dvclose));
285: lookup(s->dvread,strlen(s->dvread));
286: lookup(s->dvwrite,strlen(s->dvwrite));
287: lookup(s->dvseek,strlen(s->dvseek));
288: lookup(s->dvcntl,strlen(s->dvcntl));
289: lookup(s->dvgetc,strlen(s->dvgetc));
290: lookup(s->dvputc,strlen(s->dvputc));
291: lookup(s->dviint,strlen(s->dviint));
292: lookup(s->dvoint,strlen(s->dvoint));
293:
294: }
295: fprintf(confh,
296: "/* Declarations of I/O routines referenced */\n\n");
297: fprintf(confh, "#ifndef\tASM\n");
298: for (i=0 ; i<nsym ; i++)
299: fprintf(confh, "extern\tint\t%s();\n", symtab[i].symname);
300: fprintf(confh, "#endif\n");
301:
302:
303: /* produce devtab (giant I/O switch table) */
304:
305: fprintf(confc, "\n/* device independent I/O switch */\n\n");
306: if (ndevs > 0) {
307: fprintf(confc, "struct\tdevsw\tdevtab[NDEVS] = {\n");
308: fprintf(confc, "\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
309: "/* Format of entries is:",
310: "device-number, device-name,",
311: "init, open, close,",
312: "read, write, seek,",
313: "getc, putc, cntl,",
314: "device-csr-address, input-vector, output-vector,",
315: "iint-handler, oint-handler, control-block, minor-device,",
316: "*/");
317: }
318: for (fcount=0,s=devs ; s!=NIL ; s=s->dvnext,fcount++) {
319: fprintf(confc, "\n/* %s is %s */\n\n",s->dvname,s->dvtname);
320: fprintf(confc, "%d, \"%s\",\n", fcount, s->dvname);
321: fprintf(confc, "%s, %s, %s,\n",
322: s->dvinit, s->dvopen, s->dvclose);
323: fprintf(confc, "%s, %s, %s,\n",
324: s->dvread, s->dvwrite, s->dvseek);
325: fprintf(confc, "%s, %s, %s,\n",
326: s->dvgetc, s->dvputc, s->dvcntl);
327: fprintf(confc, "0%06o, 0%03o, 0%03o,\n",
328: s->dvcsr, s->dvivec, s->dvovec);
329: fprintf(confc, "%s, %s, NULLPTR, %d",
330: s->dviint, s->dvoint, s->dvminor);
331: if ( s->dvnext != NIL )
332: fprintf(confc, ",\n");
333: else
334: fprintf(confc, "\n\t};");
335: }
336: for (i=0; i<ndevs; i++) {
337: fprintf(dispconf,"\t.globl\t_devveci%-1d\n",i);
338: fprintf(dispconf,"\t.globl\t_devveco%-1d\n",i);
339: fprintf(dispconf,"\t.align\t2\n");
340: fprintf(dispconf,"_devveci%-1d:\n",i);
341: fprintf(dispconf,"\tmtpr\t$DISABLE, $IPL\n");
342: fprintf(dispconf,"\tbsbw\tioint\n");
343: fprintf(dispconf,"\t.align\t2\n");
344: fprintf(dispconf,"_devveco%-1d:\n",i);
345: fprintf(dispconf,"\tmtpr\t$DISABLE, $IPL\n");
346: fprintf(dispconf,"\tbsbw\tioint\n\n",i);
347: fprintf(iodisp, "extern\tint\tdevveci%-1d();\n",i);
348: fprintf(iodisp, "extern\tint\tdevveco%-1d();\n",i);
349: }
350:
351: /* Copy definitions to output */
352:
353: if (brkcount == 2 && verbose)
354: printf("Copying definitions to %s...\n", CONFIGH);
355: if (brkcount == 2 )
356: while ( (c=input()) != 0) /* lex input routine */
357: putc(c, confh);
358:
359: /* guarantee conf.c written later than conf.c for make */
360:
361: fclose(confh);
362: fprintf(confc, "\n");
363: fclose(confc);
364: fclose(dispconf);
365: fclose(iodisp);
366:
367: /* finish up and write report for user if requested */
368:
369: if (verbose) {
370: printf("\nConfiguration complete. Number of devs=%d:\n\n",ndevs);
371: for (s=devs; s!=NIL ; s=s->dvnext)
372: printf(
373: "Device %s (on %s) csr=0%-7o, ivec=0%-3o, ovec=0%-3o, minor=%d\n",
374: s->dvname, s->dvdevice, s->dvcsr, s->dvivec, s->dvovec,
375: s->dvminor);
376: }
377:
378:
379: }
380:
381:
382: yyerror(s)
383: char *s;
384: {
385: fprintf(stderr,"Syntax error in %s on line %d\n",
386: doing,linectr);
387: }
388:
389:
390: /* lookup -- lookup a name in the symbol table; return position */
391:
392: lookup(str,len)
393: char *str;
394: int len;
395: {
396: int i;
397: char *s;
398:
399: if (len >= 20) {
400: len = 19;
401: fprintf(stderr,"warning: name %s truncated\n",str);
402: }
403: s = malloc(len+1);
404: strncpy(s,str,len);
405: s[len] = '\000';
406: for (i=0 ; i<nsym ; i++)
407: if (strcmp(s,symtab[i].symname) == 0){
408: return(i);
409: }
410: symtab[nsym].symname = s;
411: symtab[nsym].symoccurs = 0;
412: return(nsym++);
413: }
414:
415: atoi(str,len)
416: char *str;
417: int len;
418: {
419: int i;
420: char c;
421:
422: for (i=0; len > 0 ; len--) {
423: c = *str++;
424: i = 10*i + (c - '0');
425: }
426: }
427: otoi(str,len)
428: char *str;
429: int len;
430: {
431: int i;
432: char c;
433:
434: for (i=0; len > 0 ; len--) {
435: c = *str++;
436: if (c > '7')
437: fprintf(stderr,"invalid octal digit on line %d\n",
438: linectr);
439: else
440: i = 8*i + (c - '0');
441: }
442: }
443:
444: /* newattr -- add a new attribute spec to current type/device description */
445:
446: newattr(tok,val)
447: int tok; /* token type (attribute type) */
448: int val; /* symbol number of value */
449: {
450: char *c;
451: dvptr s;
452:
453: if (devs == NIL) /* doing types */
454: s = currtype;
455: else
456: s = lastdv;
457: if (val>=0 && val<nsym) {
458: c = symtab[val].symname;
459: if (strlen(c) > 20 ) {
460: fprintf(stderr,"Internal overflow\n");
461: exit(1);
462: }
463: } else
464: c = NULL;
465:
466: switch (tok) {
467:
468: case CSR: s->dvcsr = val;
469: break;
470: case IVEC: s->dvivec = val;
471: break;
472: case OVEC: s->dvovec = val;
473: break;
474: case IINT: strcpy(s->dviint,c);
475: break;
476: case OINT: strcpy(s->dvoint,c);
477: break;
478: case READ: strcpy(s->dvread,c);
479: break;
480: case WRITE: strcpy(s->dvwrite,c);
481: break;
482: case GETC: strcpy(s->dvgetc,c);
483: break;
484: case PUTC: strcpy(s->dvputc,c);
485: break;
486: case OPEN: strcpy(s->dvopen,c);
487: break;
488: case CLOSE: strcpy(s->dvclose,c);
489: break;
490: case INIT: strcpy(s->dvinit,c);
491: break;
492: case SEEK: strcpy(s->dvseek,c);
493: break;
494: case CNTL: strcpy(s->dvcntl,c);
495: break;
496: default: fprintf(stderr, "Internal error 1\n");
497: }
498: }
499:
500: /* cktname -- check type name for duplicates */
501:
502: cktname(symid)
503: int symid;
504: {
505: dvptr s;
506: extern dvptr ftypes;
507: char *name;
508:
509: name = symtab[symid].symname;
510: for (s=ftypes; s!=NIL ; s=s->dvnext) {
511: if (s->dvtname == name) {
512: fprintf(stderr,"Duplicate type name %s on line %d\n",
513: name,linectr);
514: exit(1);
515: }
516: }
517: return(symid);
518: }
519:
520: /* mktype -- make a node in the type list and initialize to defaults */
521:
522: mktype(deviceid)
523: int deviceid;
524: {
525: dvptr s,p;
526: char *tn,*dn;
527:
528: p = NIL;
529: tn = symtab[currtname].symname;
530: dn = symtab[deviceid].symname;
531: for (s = ftypes; s!=NIL ; s=s->dvnext) {
532: if (s->dvtname == tn && s->dvdevice==dn) {
533: fprintf(stderr,
534: "Duplicate device %s for type %s on line %d\n",
535: dn, tn, linectr);
536: exit(1);
537: }
538: p = s;
539: }
540: currtype = s = (dvptr) malloc( sizeof(struct dvtype));
541: if (ftypes != NIL) {
542: p->dvnext = s;
543: }
544: else {
545: ftypes = s;
546: }
547: initattr(s, currtname, deviceid);
548: }
549:
550: /* initialize attributes in a type declaration node to typename... */
551:
552: initattr(fstr, tnum, deviceid)
553: dvptr fstr;
554: int tnum;
555: int deviceid;
556: {
557: char *typnam;
558:
559: typnam = symtab[tnum].symname;
560: fstr->dvname = NULL;
561: fstr->dvtname = typnam;
562: fstr->dvtnum = tnum;
563: fstr->dvdevice = symtab[deviceid].symname;
564: fstr->dvcsr = 0;
565: fstr->dvivec = 0;
566: fstr->dvovec = 0;
567: strcpy(fstr->dviint,typnam);
568: strcat(fstr->dviint,"iin");
569: strcpy(fstr->dvoint,typnam);
570: strcat(fstr->dvoint,"oin");
571: strcpy(fstr->dvinit,typnam);
572: strcat(fstr->dvinit,"init");
573: strcpy(fstr->dvopen,typnam);
574: strcat(fstr->dvopen,"open");
575: strcpy(fstr->dvclose,typnam);
576: strcat(fstr->dvclose,"close");
577: strcpy(fstr->dvread,typnam);
578: strcat(fstr->dvread,"read");
579: strcpy(fstr->dvwrite,typnam);
580: strcat(fstr->dvwrite,"write");
581: strcpy(fstr->dvcntl,typnam);
582: strcat(fstr->dvcntl,"control");
583: strcpy(fstr->dvseek,typnam);
584: strcat(fstr->dvseek,"seek");
585: strcpy(fstr->dvgetc,typnam);
586: strcat(fstr->dvgetc,"getc");
587: strcpy(fstr->dvputc,typnam);
588: strcat(fstr->dvputc,"putc");
589: fstr->dvminor = 0;
590: }
591:
592: /* mkdev -- make a node on the device list */
593:
594: mkdev(nameid, typid, deviceid)
595: int nameid, typid, deviceid;
596: {
597: dvptr s;
598: char *devn,*tn,*dn;
599: int found;
600:
601: s = (dvptr) malloc(sizeof(struct dvtype));
602: s->dvnext = NIL;
603: if (devs == NIL) {
604: devs = s;
605: lastdv = s;
606: } else {
607: lastdv->dvnext = s;
608: lastdv = s;
609: }
610: ndevs++;
611: tn = symtab[typid].symname;
612: devn = symtab[nameid].symname;
613: if (deviceid >= 0)
614: dn = symtab[deviceid].symname;
615: else
616: dn = NULL;
617: found = 0;
618: for (s=ftypes ; s != NULL ; s=s->dvnext)
619: if (s->dvtname == tn && (dn==NULL || s->dvdevice==dn)) {
620: strdup(lastdv,s,sizeof(struct dvtype));
621: found=1;
622: break;
623: }
624: if (found==0) {
625: fprintf(stderr,
626: "Bad type or device name in declaration of %s on line %d\n",
627: devn, linectr);
628: exit(1);
629: }
630: lastdv->dvnext = NIL;
631: lastdv->dvname = devn;
632: }
633:
634:
635: /* chdname -- check for duplicate device name */
636:
637: ckdname(devid)
638: int devid;
639: {
640: dvptr s;
641: extern dvptr devs;
642: char *name;
643:
644: name = symtab[devid].symname;
645: for (s=devs; s!=NIL ; s=s->dvnext) {
646: if (s->dvname == name) {
647: fprintf(stderr,"Duplicate device name %s on line %d\n",
648: name,linectr);
649: exit(1);
650: }
651: }
652: return(devid);
653: }
654:
655: strdup(tostr,fromstr,len)
656: char *tostr, *fromstr;
657: int len;
658: {
659: for( ; len > 0 ; len--)
660: *tostr++ = *fromstr++;
661: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.