|
|
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.