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