xref: /dragonfly/usr.sbin/config/config.y (revision cd1c6085)
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 int yylex(void);
108 
109 %}
110 %%
111 Configuration:
112 	Many_specs
113 		;
114 
115 Many_specs:
116 	Many_specs Spec
117 		|
118 	/* lambda */
119 		;
120 
121 Spec:
122 	Device_spec SEMICOLON
123 	      = { newdev(&cur); } |
124 	Config_spec SEMICOLON
125 		|
126 	SEMICOLON
127 		|
128 	error SEMICOLON
129 		;
130 
131 Config_spec:
132 	CONFIG_PLATFORM Save_id
133 	    = {
134 		if (platformname != NULL) {
135 		    errx(1, "%d: only one platform directive is allowed",
136 			yyline);
137 		}
138 		platformname = $2;
139 	      } |
140 	CONFIG_MACHINE Save_id
141 	    = {
142 		if (machinename != NULL) {
143 		    errx(1, "%d: only one machine directive is allowed",
144 			yyline);
145 		}
146 		machinename = $2;
147 	      } |
148 	CONFIG_MACHINE_ARCH Save_id
149 	      = {
150 		if (machinearchname != NULL) {
151 		    errx(1, "%d: only one machine_arch directive is allowed",
152 			yyline);
153 		}
154 		machinearchname = $2;
155 	      } |
156 	CPU Save_id
157 	      = {
158 		struct cputype *cp;
159 
160 		cp = malloc(sizeof(struct cputype));
161 		bzero(cp, sizeof(*cp));
162 		cp->cpu_name = $2;
163 		cp->cpu_next = cputype;
164 		cputype = cp;
165 	      } |
166 	OPTIONS Opt_list
167 		|
168 	MAKEOPTIONS Mkopt_list
169 		|
170 	IDENT ID
171 	      = { ident = $2; } |
172 	System_spec
173 		|
174 	MAXUSERS NUMBER
175 	      = { maxusers = $2; };
176 
177 System_spec:
178 	CONFIG System_id System_parameter_list
179 	  = { errx(1,"line %d: root/dump/swap specifications obsolete", yyline);}
180 	  |
181 	CONFIG System_id
182 	  ;
183 
184 System_id:
185 	Save_id
186 	      = {
187 		struct opt *op;
188 
189 		op = malloc(sizeof(struct opt));
190 		bzero(op, sizeof(*op));
191 		op->op_name = strdup("KERNEL");
192 		op->op_ownfile = 0;
193 		op->op_next = mkopt;
194 		op->op_value = $1;
195 		op->op_line = yyline + 1;
196 		mkopt = op;
197 	      };
198 
199 System_parameter_list:
200 	  System_parameter_list ID
201 	| ID
202 	;
203 
204 device_name:
205 	  Save_id
206 		= { $$ = $1; }
207 	| Save_id NUMBER
208 		= {
209 			char buf[80];
210 
211 			snprintf(buf, sizeof(buf), "%s%d", $1, $2);
212 			$$ = strdup(buf);
213 			free($1);
214 		}
215 	| Save_id NUMBER ID
216 		= {
217 			char buf[80];
218 
219 			snprintf(buf, sizeof(buf), "%s%d%s", $1, $2, $3);
220 			$$ = strdup(buf);
221 			free($1);
222 		}
223 	| Save_id NUMBER ID NUMBER
224 		= {
225 			char buf[80];
226 
227 			snprintf(buf, sizeof(buf), "%s%d%s%d",
228 			     $1, $2, $3, $4);
229 			$$ = strdup(buf);
230 			free($1);
231 		}
232 	| Save_id NUMBER ID NUMBER ID
233 		= {
234 			char buf[80];
235 
236 			snprintf(buf, sizeof(buf), "%s%d%s%d%s",
237 			     $1, $2, $3, $4, $5);
238 			$$ = strdup(buf);
239 			free($1);
240 		}
241 	;
242 
243 Opt_list:
244 	Opt_list COMMA Option
245 		|
246 	Option
247 		;
248 
249 Option:
250 	Save_id
251 	      = {
252 		struct opt *op;
253 
254 		op = malloc(sizeof(struct opt));
255 		bzero(op, sizeof(*op));
256 		op->op_name = $1;
257 		op->op_next = opt;
258 		op->op_value = 0;
259 		/*
260 		 * op->op_line is 1-based; yyline is 0-based but is now 1
261 		 * larger than when `Save_id' was lexed.
262 		 */
263 		op->op_line = yyline;
264 		opt = op;
265 		if (strchr(op->op_name, '=') != NULL)
266 			errx(1, "line %d: The `=' in options should not be quoted", yyline);
267 	      } |
268 	Save_id EQUALS Opt_value
269 	      = {
270 		struct opt *op;
271 
272 		op = malloc(sizeof(struct opt));
273 		bzero(op, sizeof(*op));
274 		op->op_name = $1;
275 		op->op_next = opt;
276 		op->op_value = $3;
277 		op->op_line = yyline + 1;
278 		opt = op;
279 	      } ;
280 
281 Opt_value:
282 	ID
283 		= { $$ = $1; } |
284 	NUMBER
285 		= {
286 			char buf[80];
287 
288 			snprintf(buf, sizeof(buf), "%d", $1);
289 			$$ = strdup(buf);
290 		} ;
291 
292 Save_id:
293 	ID
294 	      = { $$ = $1; }
295 	;
296 
297 Mkopt_list:
298 	Mkopt_list COMMA Mkoption
299 		|
300 	Mkoption
301 		;
302 
303 Mkoption:
304 	Save_id EQUALS Opt_value
305 	      = {
306 		struct opt *op;
307 
308 		op = malloc(sizeof(struct opt));
309 		bzero(op, sizeof(*op));
310 		op->op_name = $1;
311 		op->op_ownfile = 0;	/* for now */
312 		op->op_next = mkopt;
313 		op->op_value = $3;
314 		op->op_line = yyline + 1;
315 		mkopt = op;
316 	      } ;
317 
318 Dev:
319 	ID
320 	      = { $$ = $1; }
321 	;
322 
323 Device_spec:
324 	DEVICE Dev_spec
325 	      = { cur.d_type = DEVICE; } |
326 	PSEUDO_DEVICE Init_dev Dev
327 	      = {
328 		cur.d_name = $3;
329 		cur.d_type = PSEUDO_DEVICE;
330 		} |
331 	PSEUDO_DEVICE Init_dev Dev NUMBER
332 	      = {
333 		cur.d_name = $3;
334 		cur.d_type = PSEUDO_DEVICE;
335 		cur.d_count = $4;
336 		} ;
337 
338 Dev_spec:
339 	Init_dev Dev
340 	      = {
341 		cur.d_name = $2;
342 		cur.d_unit = UNKNOWN;
343 		} |
344 	Init_dev Dev NUMBER Dev_info
345 	      = {
346 		cur.d_name = $2;
347 		cur.d_unit = $3;
348 		};
349 
350 Init_dev:
351 	/* lambda */
352 	      = { init_dev(&cur); };
353 
354 Dev_info:
355 	Con_info Info_list
356 		|
357 	/* lambda */
358 		;
359 
360 Con_info:
361 	AT Dev NUMBER
362 	      = {
363 		connect($2, $3);
364 		cur.d_conn = $2;
365 		cur.d_connunit = $3;
366 		} |
367 	AT NEXUS NUMBER
368 	      = {
369 	        cur.d_conn = "nexus";
370 	        cur.d_connunit = 0;
371 	        };
372 
373 Info_list:
374 	Info_list Info
375 		|
376 	/* lambda */
377 		;
378 
379 Info:
380 	BUS NUMBER	/* device scbus1 at ahc0 bus 1 - twin channel */
381 	      = { cur.d_bus = $2; } |
382 	TARGET NUMBER
383 	      = { cur.d_target = $2; } |
384 	UNIT NUMBER
385 	      = { cur.d_lun = $2; } |
386 	DRIVE NUMBER
387 	      = { cur.d_drive = $2; } |
388 	IRQ NUMBER
389 	      = { cur.d_irq = $2; } |
390 	DRQ NUMBER
391 	      = { cur.d_drq = $2; } |
392 	IOMEM NUMBER
393 	      = { cur.d_maddr = $2; } |
394 	IOSIZ NUMBER
395 	      = { cur.d_msize = $2; } |
396 	PORT device_name
397 	      = { cur.d_port = $2; } |
398 	PORT NUMBER
399 	      = { cur.d_portn = $2; } |
400 	FLAGS NUMBER
401 	      = { cur.d_flags = $2; } |
402 	DISABLE
403 	      = { cur.d_disabled = 1; }
404 
405 %%
406 
407 static void
408 yyerror(const char *s)
409 {
410 
411 	errx(1, "line %d: %s", yyline + 1, s);
412 }
413 
414 /*
415  * add a device to the list of devices
416  */
417 static void
418 newdev(struct device *dp)
419 {
420 	struct device *np, *xp;
421 
422 	if (dp->d_unit >= 0) {
423 		for (xp = dtab; xp != NULL; xp = xp->d_next) {
424 			if ((xp->d_unit == dp->d_unit) &&
425 			    !strcmp(xp->d_name, dp->d_name)) {
426 				errx(1, "line %d: already seen device %s%d",
427 				    yyline, xp->d_name, xp->d_unit);
428 			}
429 		}
430 	}
431 	np = malloc(sizeof(*np));
432 	bzero(np, sizeof(*np));
433 	*np = *dp;
434 	np->d_next = NULL;
435 	if (curp == NULL)
436 		dtab = np;
437 	else
438 		curp->d_next = np;
439 	curp = np;
440 }
441 
442 
443 /*
444  * find the pointer to connect to the given device and number.
445  * returns 0 if no such device and prints an error message
446  */
447 static int
448 connect(char *dev, int num)
449 {
450 	struct device *dp;
451 
452 	if (num == QUES) {
453 		for (dp = dtab; dp != NULL; dp = dp->d_next)
454 			if (!strcmp(dp->d_name, dev))
455 				break;
456 		if (dp == NULL) {
457 			snprintf(errbuf, sizeof(errbuf),
458 			    "no %s's to wildcard", dev);
459 			yyerror(errbuf);
460 			return(0);
461 		}
462 		return(1);
463 	}
464 	for (dp = dtab; dp != NULL; dp = dp->d_next) {
465 		if ((num != dp->d_unit) || strcmp(dev, dp->d_name))
466 			continue;
467 		if (dp->d_type != DEVICE) {
468 			snprintf(errbuf, sizeof(errbuf),
469 			    "%s connected to non-device", dev);
470 			yyerror(errbuf);
471 			return(0);
472 		}
473 		return(1);
474 	}
475 	snprintf(errbuf, sizeof(errbuf), "%s %d not defined", dev, num);
476 	yyerror(errbuf);
477 	return(0);
478 }
479 
480 void
481 init_dev(struct device *dp)
482 {
483 
484 	dp->d_name = "OHNO!!!";
485 	dp->d_type = DEVICE;
486 	dp->d_conn = 0;
487 	dp->d_disabled = 0;
488 	dp->d_flags = 0;
489 	dp->d_bus = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit =
490 	    dp->d_count = UNKNOWN;
491 	dp->d_port = NULL;
492 	dp->d_portn = -1;
493 	dp->d_irq = -1;
494 	dp->d_drq = -1;
495 	dp->d_maddr = 0;
496 	dp->d_msize = 0;
497 }
498