|
|
1.1 root 1: %union {
2: int i;
3: char *cp;
4: struct idlst *idlst;
5: }
6: %token CPU IDENT CONFIG ANY DEVICE UBA MBA NEXUS CSR DRIVE VECTOR OPTIONS
7: %token CONTROLLER PSEUDO_DEVICE FLAGS ID SEMICOLON NUMBER FPNUMBER TRACE
8: %token DISK SLAVE AT HZ TIMEZONE DST MAXUSERS MASTER MAKEFILE COMMA MINUS
9: %token MACHINE PRIORITY
10: %token VME16D16 VME24D16 VME32D16 VME16D32 VME24D32 VME32D32
11: %type <cp> Save_id ID Dev
12: %type <i> NUMBER FPNUMBER
13: %type <idlst> Id_list
14: %{
15: /* config.y 1.11 81/05/22 */
16: #include "config.h"
17: #include <stdio.h>
18: struct device cur;
19: struct device *curp = NULL;
20: char *temp_id;
21: %}
22: %%
23: Configuration:
24: Many_specs
25: ;
26:
27: Many_specs:
28: Many_specs Spec
29: |
30: ;
31:
32: Spec:
33: Device_spec SEMICOLON = { newdev(&cur); } |
34: Config_spec SEMICOLON |
35: TRACE SEMICOLON = { do_trace = ! do_trace; } |
36: SEMICOLON |
37: error SEMICOLON
38: ;
39:
40: Config_spec:
41: MACHINE Save_id
42: = {
43: if (eq($2, "vax")) {
44: machine = MACHINE_VAX;
45: machinename = "vax";
46: } else if (eq($2, "sun2")) {
47: machine = MACHINE_SUN2;
48: machinename = "sun2";
49: } else if (eq($2, "sun3")) {
50: machine = MACHINE_SUN3;
51: machinename = "sun3";
52: } else
53: yyerror("Unknown machine type");
54: } |
55: CPU Save_id = {
56: struct cputype *cp = (struct cputype *)malloc(sizeof (struct cputype));
57: cp->cpu_name = ns($2);
58: cp->cpu_next = cputype;
59: cputype = cp;
60: free(temp_id);
61: } |
62: OPTIONS Opt_list |
63: IDENT ID { ident = ns($2); } |
64: CONFIG Save_id ID = { mkconf(temp_id, $3); free(temp_id); } |
65: HZ NUMBER = {
66: yyerror("HZ specification obsolete; delete");
67: hz = 60;
68: } |
69: TIMEZONE NUMBER = { timezone = 60 * $2; check_tz(); } |
70: TIMEZONE NUMBER DST = { timezone = 60 * $2; dst = 1; check_tz(); } |
71: TIMEZONE FPNUMBER = { timezone = $2; check_tz(); } |
72: TIMEZONE FPNUMBER DST = { timezone = $2; dst = 1; check_tz(); } |
73: MINUS TIMEZONE NUMBER =
74: { timezone = -60 * $3; check_tz(); } |
75: MINUS TIMEZONE NUMBER DST =
76: { timezone = -60 * $3; dst = 1; check_tz(); } |
77: MINUS TIMEZONE FPNUMBER =
78: { timezone = -$3; check_tz(); } |
79: MINUS TIMEZONE FPNUMBER DST =
80: { timezone = -$3; dst = 1; check_tz(); } |
81: MAKEFILE ID =
82: { mkfile = ns($2); } |
83: MAXUSERS NUMBER = { maxusers = $2; }
84: ;
85:
86: Opt_list:
87: Opt_list COMMA Option |
88: Option
89: ;
90:
91: Option:
92: Save_id = {
93: struct opt *op = (struct opt *)malloc(sizeof (struct opt));
94: op->op_name = ns($1);
95: op->op_next = opt;
96: opt = op;
97: free(temp_id);
98: }
99: ;
100:
101: Save_id:
102: ID = { $$ = temp_id = ns($1); }
103: ;
104:
105: Dev:
106: UBA
107: = {
108: if (machine != MACHINE_VAX)
109: yyerror("wrong machine type for uba");
110: $$ = ns("uba");
111: } |
112: MBA
113: = {
114: if (machine != MACHINE_VAX)
115: yyerror("wrong machine type for mba");
116: $$ = ns("mba");
117: } |
118: VME16D16
119: = {
120: if (machine != MACHINE_SUN2 && machine != MACHINE_SUN3)
121: yyerror("wrong machine type for vme16d16");
122: $$ = ns("vme16d16");
123: } |
124: VME24D16
125: = {
126: if (machine != MACHINE_SUN2 && machine != MACHINE_SUN3)
127: yyerror("wrong machine type for vme24d16");
128: $$ = ns("vme24d16");
129: } |
130: VME32D16
131: = {
132: if (machine != MACHINE_SUN3)
133: yyerror("wrong machine type for vme32d16");
134: $$ = ns("vme32d16");
135: } |
136: VME16D32
137: = {
138: if (machine != MACHINE_SUN3)
139: yyerror("wrong machine type for vme16d32");
140: $$ = ns("vme16d32");
141: } |
142: VME24D32
143: = {
144: if (machine != MACHINE_SUN3)
145: yyerror("wrong machine type for vme24d32");
146: $$ = ns("vme24d32");
147: } |
148: VME32D32
149: = {
150: if (machine != MACHINE_SUN3)
151: yyerror("wrong machine type for vme32d32");
152: $$ = ns("vme32d32");
153: } |
154: ID = { $$ = ns($1); }
155: ;
156:
157: Device_spec:
158: DEVICE Dev_name Dev_info Int_spec = { cur.d_type = DEVICE; } |
159: MASTER Dev_name Dev_info Int_spec = { cur.d_type = MASTER; } |
160: DISK Dev_name Dev_info Int_spec =
161: { cur.d_dk = 1; cur.d_type = DEVICE; } |
162: CONTROLLER Dev_name Dev_info Int_spec = { cur.d_type = CONTROLLER; } |
163: PSEUDO_DEVICE Init_dev Dev =
164: { cur.d_name = $3; cur.d_type = PSEUDO_DEVICE; } |
165: PSEUDO_DEVICE Init_dev Dev NUMBER =
166: { cur.d_name = $3; cur.d_type = PSEUDO_DEVICE;
167: cur.d_count = $4; }
168: ;
169:
170: Dev_name:
171: Init_dev Dev NUMBER = {
172: cur.d_name = $2;
173: if (eq($2, "mba"))
174: seen_mba = TRUE;
175: else if (eq($2, "uba"))
176: seen_uba = TRUE;
177: cur.d_unit = $3;
178: }
179: ;
180:
181: Init_dev:
182: = { init_dev(&cur); }
183: ;
184:
185: Dev_info:
186: Con_info Info_list
187: |
188: ;
189:
190: Con_info:
191: AT Dev NUMBER = {
192: if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) {
193: sprintf(errbuf,
194: "%s must be connected to a nexus", cur.d_name);
195: yyerror(errbuf);
196: }
197: cur.d_conn = connect($2, $3);
198: } |
199: AT NEXUS NUMBER = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; }
200: ;
201:
202: Info_list:
203: Info_list Info
204: |
205: ;
206:
207: Info:
208: CSR NUMBER
209: {
210: cur.d_addr = $2;
211: if (machine == MACHINE_SUN2 || machine == MACHINE_SUN3)
212: bus_encode($2, &cur);
213: } |
214: DRIVE NUMBER = { cur.d_drive = $2; } |
215: SLAVE NUMBER =
216: {
217: if (cur.d_conn != NULL && cur.d_conn != TO_NEXUS
218: && cur.d_conn->d_type == MASTER)
219: cur.d_slave = $2;
220: else
221: yyerror("can't specify slave--not to master");
222: } |
223: FLAGS NUMBER = { cur.d_flags = $2; }
224: ;
225:
226: Int_spec:
227: Vec_spec
228: = { cur.d_pri = 0; } |
229: PRIORITY NUMBER
230: = { cur.d_pri = $2; } |
231: Vec_spec PRIORITY NUMBER
232: = { cur.d_pri = $3; } |
233: PRIORITY NUMBER Vec_spec
234: = { cur.d_pri = $2; } |
235: /* lambda */
236: ;
237:
238: Vec_spec:
239: VECTOR Id_list = { cur.d_vec = $2; };
240:
241: Id_list:
242: Save_id =
243: { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
244: a->id = $1; a->id_next = 0; a->vec = 0; $$ = a; } |
245: Save_id NUMBER =
246: { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
247: a->id = $1; a->id_next = 0; a->vec = $2; $$ = a; } |
248: Save_id Id_list =
249: { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
250: a->id = $1; a->id_next = $2; a->vec = 0; $$ = a; } |
251: Save_id NUMBER Id_list
252: { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
253: a->id = $1; a->id_next = $3; a->vec = $2; $$ = a; };
254:
255: %%
256:
257: yyerror(s)
258: char *s;
259: {
260: fprintf(stderr, "config: %s at line %d\n", s, yyline);
261: }
262:
263: /*
264: * ns:
265: * Return the passed string in a new space
266: */
267:
268: char *
269: ns(str)
270: register char *str;
271: {
272: register char *cp;
273:
274: cp = malloc(strlen(str)+1);
275: strcpy(cp, str);
276: return cp;
277: }
278:
279: /*
280: * newdev
281: * Add a device to the list
282: */
283:
284: newdev(dp)
285: register struct device *dp;
286: {
287: register struct device *np;
288:
289: np = (struct device *) malloc(sizeof *np);
290: *np = *dp;
291: if (curp == NULL)
292: dtab = np;
293: else
294: curp->d_next = np;
295: curp = np;
296: }
297:
298: /*
299: * mkconf
300: * Note that a configuration should be made
301: */
302:
303: mkconf(dev, sysname)
304: char *dev, *sysname;
305: {
306: register struct file_list *fl;
307:
308: fl = (struct file_list *) malloc(sizeof *fl);
309: fl->f_fn = ns(dev);
310: fl->f_needs = ns(sysname);
311: if (confp == NULL)
312: conf_list = fl;
313: else
314: confp->f_next = fl;
315: confp = fl;
316: }
317:
318: /*
319: * Connect:
320: * Find the pointer to connect to the given device and number.
321: * returns NULL if no such device and prints an error message
322: */
323:
324: struct device *connect(dev, num)
325: register char *dev;
326: register int num;
327: {
328: register struct device *dp;
329: struct device *huhcon();
330:
331: if (num == QUES)
332: return huhcon(dev);
333: for (dp = dtab; dp != NULL; dp = dp->d_next)
334: if ((num == dp->d_unit) && eq(dev, dp->d_name))
335: if (dp->d_type != CONTROLLER && dp->d_type != MASTER)
336: {
337: sprintf(errbuf, "%s connected to non-controller", dev);
338: yyerror(errbuf);
339: return NULL;
340: }
341: else
342: return dp;
343: sprintf(errbuf, "%s %d not defined", dev, num);
344: yyerror(errbuf);
345: return NULL;
346: }
347:
348: /*
349: * huhcon
350: * Connect to an unspecific thing
351: */
352:
353: struct device *huhcon(dev)
354: register char *dev;
355: {
356: register struct device *dp, *dcp;
357: struct device rdev;
358: int oldtype;
359:
360: /*
361: * First make certain that there are some of these to wildcard on
362: */
363: for (dp = dtab; dp != NULL; dp = dp->d_next)
364: if (eq(dp->d_name, dev))
365: break;
366: if (dp == NULL)
367: {
368: sprintf(errbuf, "no %s's to wildcard", dev);
369: yyerror(errbuf);
370: return NULL;
371: }
372: oldtype = dp->d_type;
373: dcp = dp->d_conn;
374: /*
375: * Now see if there is already a wildcard entry for this device
376: * (e.g. Search for a "uba ?")
377: */
378: for (; dp != NULL; dp = dp->d_next)
379: if (eq(dev, dp->d_name) && dp->d_unit == -1)
380: break;
381: /*
382: * If there isn't, make one becuase everything needs to be connected
383: * to something.
384: */
385: if (dp == NULL)
386: {
387: dp = &rdev;
388: init_dev(dp);
389: dp->d_unit = QUES;
390: dp->d_name = ns(dev);
391: dp->d_type = oldtype;
392: newdev(dp);
393: dp = curp;
394: /*
395: * Connect it to the same thing that other similar things are
396: * connected to, but make sure it is a wildcard unit
397: * (e.g. up connected to sc ?, here we make connect sc? to a uba?)
398: * If other things like this are on the NEXUS or if the aren't
399: * connected to anything, then make the same connection, else
400: * call ourself to connect to another unspecific device.
401: */
402: if (dcp == TO_NEXUS || dcp == NULL)
403: dp->d_conn = dcp;
404: else
405: dp->d_conn = connect(dcp->d_name, QUES);
406: }
407: return dp;
408: }
409:
410: /*
411: * init_dev:
412: * Set up the fields in the current device to their
413: * default values.
414: */
415:
416: init_dev(dp)
417: register struct device *dp;
418: {
419: dp->d_name = "OHNO!!!";
420: dp->d_type = DEVICE;
421: dp->d_conn = NULL;
422: dp->d_vec = NULL;
423: dp->d_addr = UNKNOWN;
424: dp->d_flags = dp->d_dk = 0;
425: dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
426: dp->d_count = 0;
427: dp->d_mach = dp->d_bus = 0;
428: dp->d_pri = 0;
429: }
430:
431: /*
432: * Check_nexus:
433: * Make certain that this is a reasonable type of thing to put
434: * on the nexus.
435: */
436:
437: check_nexus(dev, num)
438: register struct device *dev;
439: int num;
440: {
441: switch (machine) {
442:
443: case MACHINE_VAX:
444: if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba"))
445: yyerror("only uba's and mba's should be connected to the nexus");
446: if (num != QUES)
447: yyerror("can't give specific nexus numbers");
448: break;
449:
450: case MACHINE_SUN2:
451: if (!eq(dev->d_name, "virtual") &&
452: !eq(dev->d_name, "obmem") &&
453: !eq(dev->d_name, "obio") &&
454: !eq(dev->d_name, "mbmem") &&
455: !eq(dev->d_name, "mbio") &&
456: !eq(dev->d_name, "vme16d16") &&
457: !eq(dev->d_name, "vme24d16")) {
458: (void)sprintf(errbuf,
459: "unknown bus type `%s' for nexus connection on %s",
460: dev->d_name, machinename);
461: yyerror(errbuf);
462: }
463: break;
464:
465: case MACHINE_SUN3:
466: if (!eq(dev->d_name, "virtual") &&
467: !eq(dev->d_name, "obmem") &&
468: !eq(dev->d_name, "obio") &&
469: !eq(dev->d_name, "vme16d16") &&
470: !eq(dev->d_name, "vme24d16") &&
471: !eq(dev->d_name, "vme32d16") &&
472: !eq(dev->d_name, "vme16d32") &&
473: !eq(dev->d_name, "vme24d32") &&
474: !eq(dev->d_name, "vme32d32")) {
475: (void)sprintf(errbuf,
476: "unknown bus type `%s' for nexus connection on %s",
477: dev->d_name, machinename);
478: yyerror(errbuf);
479: }
480: break;
481: }
482: }
483:
484: /*
485: * Check the timezone to make certain it is sensible
486: */
487:
488: check_tz()
489: {
490: if (timezone > 24 * 60)
491: yyerror("timezone is unreasonable");
492: else
493: hadtz = TRUE;
494: }
495:
496: /*
497: * bi_info gives the magic number used to construct the token for
498: * the autoconf code. bi_max is the maximum value (across all
499: * machine types for a given architecture) that a given "bus
500: * type" can legally have.
501: */
502: struct bus_info {
503: char *bi_name;
504: u_short bi_info;
505: u_int bi_max;
506: };
507:
508: struct bus_info sun2_info[] = {
509: { "virtual", 0x0001, (1<<24)-1 },
510: { "obmem", 0x0002, (1<<23)-1 },
511: { "obio", 0x0004, (1<<23)-1 },
512: { "mbmem", 0x0010, (1<<20)-1 },
513: { "mbio", 0x0020, (1<<16)-1 },
514: { "vme16d16", 0x0100, (1<<16)-1 },
515: { "vme24d16", 0x0200, (1<<24)-(1<<16)-1 },
516: { (char *)0, 0, 0 }
517: };
518:
519: struct bus_info sun3_info[] = {
520: { "virtual", 0x0001, (1<<32)-1 },
521: { "obmem", 0x0002, (1<<32)-1 },
522: { "obio", 0x0004, (1<<21)-1 },
523: { "vme16d16", 0x0100, (1<<16)-1 },
524: { "vme24d16", 0x0200, (1<<24)-(1<<16)-1 },
525: { "vme32d16", 0x0400, (1<<32)-(1<<24)-1 },
526: { "vme16d32", 0x1000, (1<<16) },
527: { "vme24d32", 0x2000, (1<<24)-(1<<16)-1 },
528: { "vme32d32", 0x4000, (1<<32)-(1<<24)-1 },
529: { (char *)0, 0, 0 }
530: };
531:
532: bus_encode(addr, dp)
533: u_int addr;
534: register struct device *dp;
535: {
536: register char *busname;
537: register struct bus_info *bip;
538: register int num;
539:
540: if (machine == MACHINE_SUN2)
541: bip = sun2_info;
542: else if (machine == MACHINE_SUN3)
543: bip = sun3_info;
544: else {
545: yyerror("bad machine type for bus_encode");
546: exit(1);
547: }
548:
549: if (dp->d_conn == TO_NEXUS || dp->d_conn == 0) {
550: yyerror("bad connection");
551: exit(1);
552: }
553:
554: busname = dp->d_conn->d_name;
555: num = dp->d_conn->d_unit;
556:
557: for (; bip->bi_name != 0; bip++)
558: if (eq(busname, bip->bi_name))
559: break;
560:
561: if (bip->bi_name == 0) {
562: (void)sprintf(errbuf, "bad bus type '%s' for machine %s",
563: busname, machinename);
564: yyerror(errbuf);
565: } else if (addr > bip->bi_max) {
566: (void)sprintf(errbuf,
567: "0x%x exceeds maximum address 0x%x allowed for %s",
568: addr, bip->bi_max, busname);
569: yyerror(errbuf);
570: } else {
571: dp->d_bus = bip->bi_info; /* set up bus type info */
572: if (num != QUES)
573: /*
574: * Set up cpu type since the connecting
575: * bus type is not wildcarded.
576: */
577: dp->d_mach = num;
578: }
579: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.