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