xref: /haiku/src/bin/pcmcia-cs/yacc_cis.y (revision 21258e2674226d6aa732321b6f8494841895af5f)
1 %{
2 /*
3  * yacc_cis.y 1.13 2001/08/24 12:21:41
4  *
5  * The contents of this file are subject to the Mozilla Public License
6  * Version 1.1 (the "License"); you may not use this file except in
7  * compliance with the License. You may obtain a copy of the License
8  * at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS"
11  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
12  * the License for the specific language governing rights and
13  * limitations under the License.
14  *
15  * The initial developer of the original code is David A. Hinds
16  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
17  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
18  *
19  * Alternatively, the contents of this file may be used under the
20  * terms of the GNU General Public License version 2 (the "GPL"), in
21  * which case the provisions of the GPL are applicable instead of the
22  * above.  If you wish to allow the use of your version of this file
23  * only under the terms of the GPL and not to allow others to use
24  * your version of this file under the MPL, indicate your decision by
25  * deleting the provisions above and replace them with the notice and
26  * other provisions required by the GPL.  If you do not delete the
27  * provisions above, a recipient may use your version of this file
28  * under either the MPL or the GPL.
29  */
30 
31 #include <sys/types.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdarg.h>
36 #include <math.h>
37 
38 #include <pcmcia/cs_types.h>
39 #include <pcmcia/cs.h>
40 #include <pcmcia/cistpl.h>
41 
42 #include "pack_cis.h"
43 
44 /* If bison: generate nicer error messages */
45 #define YYERROR_VERBOSE 1
46 
47 extern int current_lineno;
48 
49 void yyerror(char *msg, ...);
50 static tuple_info_t *new_tuple(u_char type, cisparse_t *parse);
51 
52 %}
53 
54 %token STRING NUMBER FLOAT VOLTAGE CURRENT SIZE
55 %token VERS_1 MANFID FUNCID CONFIG CFTABLE MFC CHECKSUM
56 %token POST ROM BASE LAST_INDEX CJEDEC AJEDEC
57 %token DEV_INFO ATTR_DEV_INFO NO_INFO
58 %token TIME TIMING WAIT READY RESERVED
59 %token VNOM VMIN VMAX ISTATIC IAVG IPEAK IDOWN
60 %token VCC VPP1 VPP2 IO MEM
61 %token DEFAULT BVD WP RDYBSY MWAIT AUDIO READONLY PWRDOWN
62 %token BIT8 BIT16 LINES RANGE
63 %token IRQ_NO MASK LEVEL PULSE SHARED
64 
65 %union {
66     char *str;
67     u_long num;
68     float flt;
69     cistpl_power_t pwr;
70     cisparse_t *parse;
71     tuple_info_t *tuple;
72 }
73 
74 %type <str> STRING
75 %type <num> NUMBER SIZE VOLTAGE CURRENT TIME
76 %type <flt> FLOAT
77 %type <pwr> pwr pwrlist
78 %type <parse> vers_1 manfid funcid config cftab io mem irq timing
79 %type <parse> dev_info attr_dev_info checksum cjedec ajedec
80 %type <tuple> tuple chain cis;
81 %%
82 
83 cis:	  chain
84 		{ cis_root = $1; }
85 	| chain mfc
86 		{ cis_root = $1; }
87 	;
88 
89 chain:	  /* nothing */
90 		{ $$ = NULL; }
91 	| chain tuple
92 		{
93 		    if ($1 == NULL) {
94 			$$ = $2;
95 		    } else if ($2 == NULL) {
96 			$$ = $1;
97 		    } else {
98 			tuple_info_t *tail = $1;
99 			while (tail->next != NULL) tail = tail->next;
100 			tail->next = $2;
101 			$$ = $1;
102 		    }
103 		}
104 	;
105 
106 mfc:	  MFC '{' chain '}'
107 		{ mfc[nf++] = $3; }
108 	| mfc ',' '{' chain '}'
109 		{ mfc[nf++] = $4; }
110 	;
111 
112 tuple:	  dev_info
113 		{ $$ = new_tuple(CISTPL_DEVICE, $1); }
114 	| attr_dev_info
115 		{ $$ = new_tuple(CISTPL_DEVICE_A, $1); }
116 	| vers_1
117 		{ $$ = new_tuple(CISTPL_VERS_1, $1); }
118 	| manfid
119 		{ $$ = new_tuple(CISTPL_MANFID, $1); }
120 	| funcid
121 		{ $$ = new_tuple(CISTPL_FUNCID, $1); }
122 	| config
123 		{ $$ = new_tuple(CISTPL_CONFIG, $1); }
124 	| cftab
125 		{ $$ = new_tuple(CISTPL_CFTABLE_ENTRY, $1); }
126 	| checksum
127 		{ $$ = NULL; }
128 	| error
129 		{ $$ = NULL; }
130 	| cjedec
131 		{ $$ = new_tuple(CISTPL_JEDEC_C, $1); }
132 	| ajedec
133 		{ $$ = new_tuple(CISTPL_JEDEC_A, $1); }
134 	;
135 
136 dev_info: DEV_INFO
137 		{ $$ = calloc(1, sizeof(cisparse_t)); }
138 	| dev_info NUMBER TIME ',' SIZE
139 		{
140 		    $$->device.dev[$$->device.ndev].type = $2;
141 		    $$->device.dev[$$->device.ndev].speed = $3;
142 		    $$->device.dev[$$->device.ndev].size = $5;
143 		    $$->device.ndev++;
144 		}
145 	| dev_info NO_INFO
146 	;
147 
148 attr_dev_info: ATTR_DEV_INFO
149 		{ $$ = calloc(1, sizeof(cisparse_t)); }
150 	| attr_dev_info NUMBER TIME ',' SIZE
151 		{
152 		    $$->device.dev[$$->device.ndev].type = $2;
153 		    $$->device.dev[$$->device.ndev].speed = $3;
154 		    $$->device.dev[$$->device.ndev].size = $5;
155 		    $$->device.ndev++;
156 		}
157 	| attr_dev_info NO_INFO
158 	;
159 
160 vers_1:	  VERS_1 FLOAT
161 		{
162 		    $$ = calloc(1, sizeof(cisparse_t));
163 		    $$->version_1.major = $2;
164 		    $2 -= floor($2+0.01);
165 		    while (fabs($2 - floor($2+0.5)) > 0.01) {
166 			$2 *= 10;
167 		    }
168 		    $$->version_1.minor = $2+0.01;
169 		}
170 	| vers_1 ',' STRING
171 		{
172 		    cistpl_vers_1_t *v = &$$->version_1;
173 		    u_int pos = 0;
174 		    if (v->ns) {
175 			pos = v->ofs[v->ns-1];
176 			pos += strlen(v->str+pos)+1;
177 		    }
178 		    v->ofs[v->ns] = pos;
179 		    strcpy(v->str+pos, $3);
180 		    v->ns++;
181 		}
182 	;
183 
184 manfid:	  MANFID NUMBER ',' NUMBER
185 		{
186 		    $$ = calloc(1, sizeof(cisparse_t));
187 		    $$->manfid.manf = $2;
188 		    $$->manfid.card = $4;
189 		}
190 	;
191 
192 funcid:	  FUNCID NUMBER
193 		{
194 		    $$ = calloc(1, sizeof(cisparse_t));
195 		    $$->funcid.func = $2;
196 		}
197 	| funcid POST
198 		{ $$->funcid.sysinit |= CISTPL_SYSINIT_POST; }
199 	| funcid ROM
200 		{ $$->funcid.sysinit |= CISTPL_SYSINIT_ROM; }
201 	;
202 
203 cjedec:	  CJEDEC NUMBER NUMBER
204 		{
205 		    $$ = calloc(1, sizeof(cisparse_t));
206 		    $$->jedec.id[0].mfr = $2;
207 		    $$->jedec.id[0].info = $3;
208 		    $$->jedec.nid = 1;
209 		}
210 	| cjedec ',' NUMBER NUMBER
211 		{
212 		    $$->jedec.id[$$->jedec.nid].mfr = $3;
213 		    $$->jedec.id[$$->jedec.nid++].info = $4;
214 		}
215 	;
216 
217 ajedec:	  AJEDEC NUMBER NUMBER
218 		{
219 		    $$ = calloc(1, sizeof(cisparse_t));
220 		    $$->jedec.id[0].mfr = $2;
221 		    $$->jedec.id[0].info = $3;
222 		    $$->jedec.nid = 1;
223 		}
224 	| ajedec ',' NUMBER NUMBER
225 		{
226 		    $$->jedec.id[$$->jedec.nid].mfr = $3;
227 		    $$->jedec.id[$$->jedec.nid++].info = $4;
228 		}
229 	;
230 
231 config:	  CONFIG BASE NUMBER MASK NUMBER  LAST_INDEX NUMBER
232 		{
233 		    $$ = calloc(1, sizeof(cisparse_t));
234 		    $$->config.base = $3;
235 		    $$->config.rmask[0] = $5;
236 		    $$->config.last_idx = $7;
237 		}
238 	;
239 
240 pwr:	  VNOM VOLTAGE
241 		{
242 		    $$.present = CISTPL_POWER_VNOM;
243 		    $$.param[0] = $2;
244 		}
245 	| VMIN VOLTAGE
246 		{
247 		    $$.present = CISTPL_POWER_VMIN;
248 		    $$.param[0] = $2;
249 		}
250 	| VMAX VOLTAGE
251 		{
252 		    $$.present = CISTPL_POWER_VMAX;
253 		    $$.param[0] = $2;
254 		}
255 	| ISTATIC CURRENT
256 		{
257 		    $$.present = CISTPL_POWER_ISTATIC;
258 		    $$.param[0] = $2;
259 		}
260 	| IAVG CURRENT
261 		{
262 		    $$.present = CISTPL_POWER_IAVG;
263 		    $$.param[0] = $2;
264 		}
265 	| IPEAK CURRENT
266 		{
267 		    $$.present = CISTPL_POWER_IPEAK;
268 		    $$.param[0] = $2;
269 		}
270 	| IDOWN CURRENT
271 		{
272 		    $$.present = CISTPL_POWER_IDOWN;
273 		    $$.param[0] = $2;
274 		}
275 	;
276 
277 pwrlist:  /* nothing */
278 		{
279 		    $$.present = 0;
280 		}
281 	| pwrlist pwr
282 		{
283 		    $$.present |= 1<<($2.present);
284 		    $$.param[$2.present] = $2.param[0];
285 		}
286 	;
287 
288 timing:	  cftab TIMING
289 	| timing WAIT TIME
290 	| timing READY TIME
291 	| timing RESERVED TIME
292 	;
293 
294 io:	  cftab IO NUMBER '-' NUMBER
295 		{
296 		    int n = $$->cftable_entry.io.nwin;
297 		    $$->cftable_entry.io.win[n].base = $3;
298 		    $$->cftable_entry.io.win[n].len = $5-$3+1;
299 		    $$->cftable_entry.io.nwin++;
300 		}
301 	| io ',' NUMBER '-' NUMBER
302 		{
303 		    int n = $$->cftable_entry.io.nwin;
304 		    $$->cftable_entry.io.win[n].base = $3;
305 		    $$->cftable_entry.io.win[n].len = $5-$3+1;
306 		    $$->cftable_entry.io.nwin++;
307 		}
308 	| io BIT8
309 		{ $$->cftable_entry.io.flags |= CISTPL_IO_8BIT; }
310 	| io BIT16
311 		{ $$->cftable_entry.io.flags |= CISTPL_IO_16BIT; }
312 	| io LINES '=' NUMBER ']'
313 		{ $$->cftable_entry.io.flags |= $4; }
314 	| io RANGE
315 	;
316 
317 mem:	  cftab MEM NUMBER '-' NUMBER '@' NUMBER
318 		{
319 		    int n = $$->cftable_entry.mem.nwin;
320 		    $$->cftable_entry.mem.win[n].card_addr = $3;
321 		    $$->cftable_entry.mem.win[n].host_addr = $7;
322 		    $$->cftable_entry.mem.win[n].len = $5-$3+1;
323 		    $$->cftable_entry.mem.nwin++;
324 		}
325 	| mem ',' NUMBER '-' NUMBER '@' NUMBER
326 		{
327 		    int n = $$->cftable_entry.mem.nwin;
328 		    $$->cftable_entry.mem.win[n].card_addr = $3;
329 		    $$->cftable_entry.mem.win[n].host_addr = $7;
330 		    $$->cftable_entry.mem.win[n].len = $5-$3+1;
331 		    $$->cftable_entry.mem.nwin++;
332 		}
333 	| mem BIT8
334 		{ $$->cftable_entry.io.flags |= CISTPL_IO_8BIT; }
335 	| mem BIT16
336 		{ $$->cftable_entry.io.flags |= CISTPL_IO_16BIT; }
337 	;
338 
339 irq:	  cftab IRQ_NO NUMBER
340 		{ $$->cftable_entry.irq.IRQInfo1 = ($3 & 0x0f); }
341 	| cftab IRQ_NO MASK NUMBER
342 		{
343 		    $$->cftable_entry.irq.IRQInfo1 = IRQ_INFO2_VALID;
344 		    $$->cftable_entry.irq.IRQInfo2 = $4;
345 		}
346 	| irq PULSE
347 		{ $$->cftable_entry.irq.IRQInfo1 |= IRQ_PULSE_ID; }
348 	| irq LEVEL
349 		{ $$->cftable_entry.irq.IRQInfo1 |= IRQ_LEVEL_ID; }
350 	| irq SHARED
351 		{ $$->cftable_entry.irq.IRQInfo1 |= IRQ_SHARE_ID; }
352 	;
353 
354 cftab:	  CFTABLE NUMBER
355 		{
356 		    $$ = calloc(1, sizeof(cisparse_t));
357 		    $$->cftable_entry.index = $2;
358 		}
359 	| cftab DEFAULT
360 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_DEFAULT; }
361 	| cftab BVD
362 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_BVDS; }
363 	| cftab WP
364 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_WP; }
365 	| cftab RDYBSY
366 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_RDYBSY; }
367 	| cftab MWAIT
368 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_MWAIT; }
369 	| cftab AUDIO
370 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_AUDIO; }
371 	| cftab READONLY
372 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_READONLY; }
373 	| cftab PWRDOWN
374 		{ $$->cftable_entry.flags |= CISTPL_CFTABLE_PWRDOWN; }
375 	| cftab VCC pwrlist
376 		{ $$->cftable_entry.vcc = $3; }
377 	| cftab VPP1 pwrlist
378 		{ $$->cftable_entry.vpp1 = $3; }
379 	| cftab VPP2 pwrlist
380 		{ $$->cftable_entry.vpp2 = $3; }
381 	| io
382 	| mem
383 	| irq
384 	| timing
385 	;
386 
387 checksum: CHECKSUM NUMBER '-' NUMBER '=' NUMBER
388 	{ $$ = NULL; }
389 
390 %%
391 
392 static tuple_info_t *new_tuple(u_char type, cisparse_t *parse)
393 {
394     tuple_info_t *t = calloc(1, sizeof(tuple_info_t));
395     t->type = type;
396     t->parse = parse;
397     t->next = NULL;
398 }
399 
400 void yyerror(char *msg, ...)
401 {
402     va_list ap;
403     char str[256];
404 
405     va_start(ap, msg);
406     sprintf(str, "error at line %d: ", current_lineno);
407     vsprintf(str+strlen(str), msg, ap);
408     fprintf(stderr, "%s\n", str);
409     va_end(ap);
410 }
411 
412 #ifdef DEBUG
413 void main(int argc, char *argv[])
414 {
415     if (argc > 1)
416 	parse_cis(argv[1]);
417 }
418 #endif
419