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
47extern int current_lineno;
48
49void yyerror(char *msg, ...);
50static 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
83cis:	  chain
84		{ cis_root = $1; }
85	| chain mfc
86		{ cis_root = $1; }
87	;
88
89chain:	  /* 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
106mfc:	  MFC '{' chain '}'
107		{ mfc[nf++] = $3; }
108	| mfc ',' '{' chain '}'
109		{ mfc[nf++] = $4; }
110	;
111
112tuple:	  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
136dev_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
148attr_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
160vers_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
184manfid:	  MANFID NUMBER ',' NUMBER
185		{
186		    $$ = calloc(1, sizeof(cisparse_t));
187		    $$->manfid.manf = $2;
188		    $$->manfid.card = $4;
189		}
190	;
191
192funcid:	  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
203cjedec:	  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
217ajedec:	  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
231config:	  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
240pwr:	  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
277pwrlist:  /* 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
288timing:	  cftab TIMING
289	| timing WAIT TIME
290	| timing READY TIME
291	| timing RESERVED TIME
292	;
293
294io:	  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
317mem:	  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
339irq:	  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
354cftab:	  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
387checksum: CHECKSUM NUMBER '-' NUMBER '=' NUMBER
388	{ $$ = NULL; }
389
390%%
391
392static 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
400void 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
413void main(int argc, char *argv[])
414{
415    if (argc > 1)
416	parse_cis(argv[1]);
417}
418#endif
419