xref: /dragonfly/usr.sbin/config/config.y (revision 7ff0fc30)
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