1 %union { 2 char *str; 3 int val; 4 struct file_list *file; 5 } 6 7 %token ANY 8 %token AT 9 %token BUS 10 %token COMMA 11 %token CONFIG 12 %token CONFIG_MACHINE 13 %token CONFIG_MACHINE_ARCH 14 %token CONFIG_PLATFORM 15 %token CPU 16 %token DEVICE 17 %token DISABLE 18 %token DRIVE 19 %token DRQ 20 %token EQUALS 21 %token FLAGS 22 %token IDENT 23 %token IOMEM 24 %token IOSIZ 25 %token IRQ 26 %token MAXUSERS 27 %token MINUS 28 %token NEXUS 29 %token OPTIONS 30 %token MAKEOPTIONS 31 %token PORT 32 %token PSEUDO_DEVICE 33 %token SEMICOLON 34 %token TARGET 35 %token TTY 36 %token UNIT 37 %token VECTOR 38 39 %token <str> ID 40 %token <val> NUMBER 41 %token <val> FPNUMBER 42 43 %type <str> Save_id 44 %type <str> Opt_value 45 %type <str> Dev 46 %type <str> device_name 47 48 %{ 49 50 /* 51 * Copyright (c) 1988, 1993 52 * The Regents of the University of California. All rights reserved. 53 * 54 * Redistribution and use in source and binary forms, with or without 55 * modification, are permitted provided that the following conditions 56 * are met: 57 * 1. Redistributions of source code must retain the above copyright 58 * notice, this list of conditions and the following disclaimer. 59 * 2. Redistributions in binary form must reproduce the above copyright 60 * notice, this list of conditions and the following disclaimer in the 61 * documentation and/or other materials provided with the distribution. 62 * 3. Neither the name of the University nor the names of its contributors 63 * may be used to endorse or promote products derived from this software 64 * without specific prior written permission. 65 * 66 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 68 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 69 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 70 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 71 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 72 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 73 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 74 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 76 * SUCH DAMAGE. 77 * 78 * @(#)config.y 8.1 (Berkeley) 6/6/93 79 * $FreeBSD: src/usr.sbin/config/config.y,v 1.42.2.1 2001/01/23 00:09:32 peter Exp $ 80 */ 81 82 #include <ctype.h> 83 #include <err.h> 84 #include <stdio.h> 85 #include <string.h> 86 87 #include "config.h" 88 89 static struct device cur; 90 static struct device *curp = 0; 91 92 struct device *dtab; 93 char *ident; 94 int yyline; 95 struct file_list *ftab; 96 char errbuf[80]; 97 int maxusers; 98 99 static int connect(char *, int); 100 static void yyerror(const char *s); 101 102 #if YYPATCH < 20180510 103 int yylex(void); 104 #endif 105 106 %} 107 %% 108 Configuration: 109 Many_specs 110 ; 111 112 Many_specs: 113 Many_specs Spec 114 | 115 /* lambda */ 116 ; 117 118 Spec: 119 Device_spec SEMICOLON { newdev(&cur); } 120 | 121 Config_spec SEMICOLON 122 | 123 SEMICOLON 124 | 125 error SEMICOLON 126 ; 127 128 Config_spec: 129 CONFIG_PLATFORM Save_id { 130 if (platformname != NULL) { 131 errx(1, "%d: only one platform directive is allowed", 132 yyline); 133 } 134 platformname = $2; 135 } | 136 CONFIG_MACHINE Save_id { 137 if (machinename != NULL) { 138 errx(1, "%d: only one machine directive is allowed", 139 yyline); 140 } 141 machinename = $2; 142 } | 143 CONFIG_MACHINE_ARCH Save_id { 144 if (machinearchname != NULL) { 145 errx(1, "%d: only one machine_arch directive is allowed", 146 yyline); 147 } 148 machinearchname = $2; 149 } | 150 CPU Save_id { 151 struct cputype *cp; 152 153 cp = malloc(sizeof(struct cputype)); 154 bzero(cp, sizeof(*cp)); 155 cp->cpu_name = $2; 156 cp->cpu_next = cputype; 157 cputype = cp; 158 } | 159 OPTIONS Opt_list 160 | 161 MAKEOPTIONS Mkopt_list 162 | 163 IDENT ID { ident = $2; } 164 | 165 System_spec 166 | 167 MAXUSERS NUMBER { maxusers = $2; }; 168 169 System_spec: 170 CONFIG System_id System_parameter_list { 171 errx(1,"line %d: root/dump/swap specifications obsolete", 172 yyline); 173 } | 174 CONFIG System_id 175 ; 176 177 System_id: 178 Save_id { 179 struct opt *op; 180 181 op = malloc(sizeof(struct opt)); 182 bzero(op, sizeof(*op)); 183 op->op_name = strdup("KERNEL"); 184 op->op_ownfile = 0; 185 op->op_next = mkopt; 186 op->op_value = $1; 187 op->op_line = yyline + 1; 188 mkopt = op; 189 }; 190 191 System_parameter_list: 192 System_parameter_list ID 193 | ID 194 ; 195 196 device_name: 197 Save_id { $$ = $1; } 198 | Save_id NUMBER { 199 char buf[80]; 200 201 snprintf(buf, sizeof(buf), "%s%d", $1, $2); 202 $$ = strdup(buf); 203 free($1); 204 } 205 | Save_id NUMBER ID { 206 char buf[80]; 207 208 snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3); 209 $$ = strdup(buf); 210 free($1); 211 } 212 | Save_id NUMBER ID NUMBER { 213 char buf[80]; 214 215 snprintf(buf, sizeof(buf), "%s%d%s%d", 216 $1, $2, $3, $4); 217 $$ = strdup(buf); 218 free($1); 219 } 220 | Save_id NUMBER ID NUMBER ID { 221 char buf[80]; 222 223 snprintf(buf, sizeof(buf), "%s%d%s%d%s", 224 $1, $2, $3, $4, $5); 225 $$ = strdup(buf); 226 free($1); 227 } 228 ; 229 230 Opt_list: 231 Opt_list COMMA Option 232 | 233 Option 234 ; 235 236 Option: 237 Save_id { 238 struct opt *op; 239 240 op = malloc(sizeof(struct opt)); 241 bzero(op, sizeof(*op)); 242 op->op_name = $1; 243 op->op_next = opt; 244 op->op_value = 0; 245 /* 246 * op->op_line is 1-based; yyline is 0-based but is now 1 247 * larger than when `Save_id' was lexed. 248 */ 249 op->op_line = yyline; 250 opt = op; 251 if (strchr(op->op_name, '=') != NULL) 252 errx(1, "line %d: The `=' in options should not be quoted", yyline); 253 } | 254 Save_id EQUALS Opt_value { 255 struct opt *op; 256 257 op = malloc(sizeof(struct opt)); 258 bzero(op, sizeof(*op)); 259 op->op_name = $1; 260 op->op_next = opt; 261 op->op_value = $3; 262 op->op_line = yyline + 1; 263 opt = op; 264 } ; 265 266 Opt_value: 267 ID { $$ = $1; } | 268 NUMBER { 269 char buf[80]; 270 271 snprintf(buf, sizeof(buf), "%d", $1); 272 $$ = strdup(buf); 273 } ; 274 275 Save_id: 276 ID { $$ = $1; } 277 ; 278 279 Mkopt_list: 280 Mkopt_list COMMA Mkoption 281 | 282 Mkoption 283 ; 284 285 Mkoption: 286 Save_id EQUALS Opt_value { 287 struct opt *op; 288 289 op = malloc(sizeof(struct opt)); 290 bzero(op, sizeof(*op)); 291 op->op_name = $1; 292 op->op_ownfile = 0; /* for now */ 293 op->op_next = mkopt; 294 op->op_value = $3; 295 op->op_line = yyline + 1; 296 mkopt = op; 297 } ; 298 299 Dev: 300 ID { $$ = $1; } 301 ; 302 303 Device_spec: 304 DEVICE Dev_spec { cur.d_type = DEVICE; } 305 | 306 PSEUDO_DEVICE Init_dev Dev { 307 cur.d_name = $3; 308 cur.d_type = PSEUDO_DEVICE; 309 } | 310 PSEUDO_DEVICE Init_dev Dev NUMBER { 311 cur.d_name = $3; 312 cur.d_type = PSEUDO_DEVICE; 313 cur.d_count = $4; 314 } ; 315 316 Dev_spec: 317 Init_dev Dev { 318 cur.d_name = $2; 319 cur.d_unit = UNKNOWN; 320 } | 321 Init_dev Dev NUMBER Dev_info { 322 cur.d_name = $2; 323 cur.d_unit = $3; 324 } ; 325 326 Init_dev: 327 /* lambda */ { init_dev(&cur); }; 328 329 Dev_info: 330 Con_info Info_list 331 | 332 /* lambda */ 333 ; 334 335 Con_info: 336 AT Dev NUMBER { 337 connect($2, $3); 338 cur.d_conn = $2; 339 cur.d_connunit = $3; 340 } | 341 AT NEXUS NUMBER { 342 cur.d_conn = "nexus"; 343 cur.d_connunit = 0; 344 } ; 345 346 Info_list: 347 Info_list Info 348 | 349 /* lambda */ 350 ; 351 352 Info: 353 BUS NUMBER { cur.d_bus = $2; } 354 | 355 TARGET NUMBER { cur.d_target = $2; } 356 | 357 UNIT NUMBER { cur.d_lun = $2; } 358 | 359 DRIVE NUMBER { cur.d_drive = $2; } 360 | 361 IRQ NUMBER { cur.d_irq = $2; } 362 | 363 DRQ NUMBER { cur.d_drq = $2; } 364 | 365 IOMEM NUMBER { cur.d_maddr = $2; } 366 | 367 IOSIZ NUMBER { cur.d_msize = $2; } 368 | 369 PORT device_name { cur.d_port = $2; } 370 | 371 PORT NUMBER { cur.d_portn = $2; } 372 | 373 FLAGS NUMBER { cur.d_flags = $2; } 374 | 375 DISABLE { cur.d_disabled = 1; } 376 377 %% 378 379 static void 380 yyerror(const char *s) 381 { 382 383 errx(1, "line %d: %s", yyline + 1, s); 384 } 385 386 /* 387 * add a device to the list of devices 388 */ 389 static void 390 newdev(struct device *dp) 391 { 392 struct device *np, *xp; 393 394 if (dp->d_unit >= 0) { 395 for (xp = dtab; xp != NULL; xp = xp->d_next) { 396 if ((xp->d_unit == dp->d_unit) && 397 !strcmp(xp->d_name, dp->d_name)) { 398 errx(1, "line %d: already seen device %s%d", 399 yyline, xp->d_name, xp->d_unit); 400 } 401 } 402 } 403 np = malloc(sizeof(*np)); 404 bzero(np, sizeof(*np)); 405 *np = *dp; 406 np->d_next = NULL; 407 if (curp == NULL) 408 dtab = np; 409 else 410 curp->d_next = np; 411 curp = np; 412 } 413 414 415 /* 416 * find the pointer to connect to the given device and number. 417 * returns 0 if no such device and prints an error message 418 */ 419 static int 420 connect(char *dev, int num) 421 { 422 struct device *dp; 423 424 if (num == QUES) { 425 for (dp = dtab; dp != NULL; dp = dp->d_next) 426 if (!strcmp(dp->d_name, dev)) 427 break; 428 if (dp == NULL) { 429 snprintf(errbuf, sizeof(errbuf), 430 "no %s's to wildcard", dev); 431 yyerror(errbuf); 432 return(0); 433 } 434 return(1); 435 } 436 for (dp = dtab; dp != NULL; dp = dp->d_next) { 437 if ((num != dp->d_unit) || strcmp(dev, dp->d_name)) 438 continue; 439 if (dp->d_type != DEVICE) { 440 snprintf(errbuf, sizeof(errbuf), 441 "%s connected to non-device", dev); 442 yyerror(errbuf); 443 return(0); 444 } 445 return(1); 446 } 447 snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num); 448 yyerror(errbuf); 449 return(0); 450 } 451 452 void 453 init_dev(struct device *dp) 454 { 455 456 dp->d_name = "OHNO!!!"; 457 dp->d_type = DEVICE; 458 dp->d_conn = 0; 459 dp->d_disabled = 0; 460 dp->d_flags = 0; 461 dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit = 462 dp->d_count = UNKNOWN; 463 dp->d_port = NULL; 464 dp->d_portn = -1; 465 dp->d_irq = -1; 466 dp->d_drq = -1; 467 dp->d_maddr = 0; 468 dp->d_msize = 0; 469 } 470