Rename /usr/src/sys/machine to /usr/src/sys/platform. Give the platform
[dragonfly.git] / usr.sbin / config / config.y
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 }