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