blob: 19bc58e9beb995ebaddce02b1f57c4cc3d47cf5e [file] [log] [blame]
David Gibsonfc14dad2005-06-08 17:18:34 +10001/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
David Gibson86dbcbd2005-10-19 16:00:31 +100021%glr-parser
22%locations
23
David Gibsonfc14dad2005-06-08 17:18:34 +100024%{
25#include "dtc.h"
Jon Loeligere45e6fd2007-03-23 15:18:41 -050026#include "srcpos.h"
David Gibsonfc14dad2005-06-08 17:18:34 +100027
Jon Loeliger39488492007-02-16 09:33:54 -060028int yylex(void);
Jon Loeliger39488492007-02-16 09:33:54 -060029cell_t cell_from_string(char *s, unsigned int base);
David Gibsonfc14dad2005-06-08 17:18:34 +100030
David Gibsonf0517db2005-07-15 17:14:24 +100031extern struct boot_info *the_boot_info;
David Gibsonfc14dad2005-06-08 17:18:34 +100032
33%}
34
35%union {
36 cell_t cval;
Jon Loeligeraf0278a2007-02-15 10:59:27 -060037 unsigned int cbase;
David Gibson03a9b9d2005-07-11 16:49:52 +100038 u8 byte;
David Gibsonfc14dad2005-06-08 17:18:34 +100039 char *str;
40 struct data data;
41 struct property *prop;
42 struct property *proplist;
43 struct node *node;
44 struct node *nodelist;
45 int datalen;
46 int hexlen;
David Gibsonf0517db2005-07-15 17:14:24 +100047 u64 addr;
David Gibsonf040d952005-10-24 18:18:38 +100048 struct reserve_info *re;
David Gibsonfc14dad2005-06-08 17:18:34 +100049}
50
David Gibsonf0517db2005-07-15 17:14:24 +100051%token DT_MEMRESERVE
52%token <addr> DT_ADDR
David Gibsonfc14dad2005-06-08 17:18:34 +100053%token <str> DT_PROPNAME
54%token <str> DT_NODENAME
Jon Loeligeraf0278a2007-02-15 10:59:27 -060055%token <cbase> DT_BASE
56%token <str> DT_CELL
David Gibsonfc14dad2005-06-08 17:18:34 +100057%token <byte> DT_BYTE
58%token <data> DT_STRING
59%token <str> DT_UNIT
David Gibson4102d842005-06-16 14:36:37 +100060%token <str> DT_LABEL
David Gibson81f2e892005-06-16 17:04:00 +100061%token <str> DT_REF
David Gibsonfc14dad2005-06-08 17:18:34 +100062
63%type <data> propdata
David Gibson32da4752007-02-07 16:37:50 +110064%type <data> propdataprefix
David Gibsonf0517db2005-07-15 17:14:24 +100065%type <re> memreserve
David Gibsonf040d952005-10-24 18:18:38 +100066%type <re> memreserves
Jon Loeligeraf0278a2007-02-15 10:59:27 -060067%type <cbase> opt_cell_base
David Gibsonfc14dad2005-06-08 17:18:34 +100068%type <data> celllist
69%type <data> bytestring
70%type <prop> propdef
71%type <proplist> proplist
72
David Gibsonf0517db2005-07-15 17:14:24 +100073%type <node> devicetree
David Gibsonfc14dad2005-06-08 17:18:34 +100074%type <node> nodedef
75%type <node> subnode
76%type <nodelist> subnodes
David Gibson4102d842005-06-16 14:36:37 +100077%type <str> label
78%type <str> nodename
79
David Gibsonfc14dad2005-06-08 17:18:34 +100080%%
81
David Gibsonf0517db2005-07-15 17:14:24 +100082sourcefile: memreserves devicetree {
83 the_boot_info = build_boot_info($1, $2);
84 }
85 ;
86
David Gibsonf040d952005-10-24 18:18:38 +100087memreserves: memreserve memreserves {
88 $$ = chain_reserve_entry($1, $2);
David Gibsonf0517db2005-07-15 17:14:24 +100089 }
90 | /* empty */ {
David Gibsonf040d952005-10-24 18:18:38 +100091 $$ = NULL;
David Gibsonf0517db2005-07-15 17:14:24 +100092 }
93 ;
94
Milton Millerd4290332007-07-07 01:18:49 -050095memreserve: label DT_MEMRESERVE DT_ADDR DT_ADDR ';' {
96 $$ = build_reserve_entry($3, $4, $1);
David Gibsonf0517db2005-07-15 17:14:24 +100097 }
Milton Millerd4290332007-07-07 01:18:49 -050098 | label DT_MEMRESERVE DT_ADDR '-' DT_ADDR ';' {
99 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
David Gibsonf0517db2005-07-15 17:14:24 +1000100 }
101 ;
102
103devicetree: '/' nodedef {
104 $$ = name_node($2, "", NULL);
105 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000106 ;
107
108nodedef: '{' proplist subnodes '}' ';' {
109 $$ = build_node($2, $3);
110 }
111 ;
112
113proplist: propdef proplist {
114 $$ = chain_property($1, $2);
115 }
116 | /* empty */ {
117 $$ = NULL;
118 }
119 ;
120
David Gibson4102d842005-06-16 14:36:37 +1000121propdef: label DT_PROPNAME '=' propdata ';' {
122 $$ = build_property($2, $4, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000123 }
David Gibson4102d842005-06-16 14:36:37 +1000124 | label DT_PROPNAME ';' {
David Gibson9ad45872005-06-17 14:32:32 +1000125 $$ = build_property($2, empty_data, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000126 }
127 ;
128
David Gibson32da4752007-02-07 16:37:50 +1100129propdata: propdataprefix DT_STRING { $$ = data_merge($1, $2); }
130 | propdataprefix '<' celllist '>' {
131 $$ = data_merge(data_append_align($1, sizeof(cell_t)), $3);
132 }
133 | propdataprefix '[' bytestring ']' { $$ = data_merge($1, $3); }
Milton Miller6a99b132007-07-07 01:18:51 -0500134 | propdata DT_LABEL { $$ = data_add_label($1, $2); }
David Gibson32da4752007-02-07 16:37:50 +1100135 ;
136
137propdataprefix: propdata ',' { $$ = $1; }
Milton Miller6a99b132007-07-07 01:18:51 -0500138 | propdataprefix DT_LABEL { $$ = data_add_label($1, $2); }
David Gibson32da4752007-02-07 16:37:50 +1100139 | /* empty */ { $$ = empty_data; }
David Gibsonfc14dad2005-06-08 17:18:34 +1000140 ;
141
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600142opt_cell_base:
143 /* empty */
144 { $$ = 16; }
145 | DT_BASE
146 ;
147
148celllist: celllist opt_cell_base DT_CELL {
149 $$ = data_append_cell($1,
Jon Loeliger39488492007-02-16 09:33:54 -0600150 cell_from_string($3, $2));
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600151 }
David Gibson81f2e892005-06-16 17:04:00 +1000152 | celllist DT_REF {
153 $$ = data_append_cell(data_add_fixup($1, $2), -1);
154 }
Milton Miller6a99b132007-07-07 01:18:51 -0500155 | celllist DT_LABEL { $$ = data_add_label($1, $2); }
David Gibsonfc14dad2005-06-08 17:18:34 +1000156 | /* empty */ { $$ = empty_data; }
157 ;
158
159bytestring: bytestring DT_BYTE { $$ = data_append_byte($1, $2); }
Milton Miller6a99b132007-07-07 01:18:51 -0500160 | bytestring DT_LABEL { $$ = data_add_label($1, $2); }
David Gibsonfc14dad2005-06-08 17:18:34 +1000161 | /* empty */ { $$ = empty_data; }
162 ;
163
164subnodes: subnode subnodes {
165 $$ = chain_node($1, $2);
166 }
167 | /* empty */ { $$ = NULL; }
168 ;
169
David Gibson4102d842005-06-16 14:36:37 +1000170subnode: label nodename nodedef { $$ = name_node($3, $2, $1); }
171 ;
172
173nodename: DT_NODENAME { $$ = $1; }
174 | DT_PROPNAME { $$ = $1; }
175 ;
176
177label: DT_LABEL { $$ = $1; }
178 | /* empty */ { $$ = NULL; }
David Gibsonfc14dad2005-06-08 17:18:34 +1000179 ;
180
181%%
182
183void yyerror (char const *s)
184{
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500185 const char *fname = srcpos_filename_for_num(yylloc.filenum);
186
187 if (strcmp(fname, "-") == 0)
188 fname = "stdin";
189
190 fprintf(stderr, "%s:%d %s\n",
191 fname, yylloc.first_line, s);
David Gibsonfc14dad2005-06-08 17:18:34 +1000192}
Jon Loeliger39488492007-02-16 09:33:54 -0600193
194
195/*
196 * Convert a string representation of a numeric cell
197 * in the given base into a cell.
198 *
Milton Miller85ab5cc2007-07-07 01:18:48 -0500199 * FIXME: should these specification errors be fatal instead?
Jon Loeliger39488492007-02-16 09:33:54 -0600200 */
201
202cell_t cell_from_string(char *s, unsigned int base)
203{
204 cell_t c;
Milton Miller85ab5cc2007-07-07 01:18:48 -0500205 char *e;
Jon Loeliger39488492007-02-16 09:33:54 -0600206
Milton Miller85ab5cc2007-07-07 01:18:48 -0500207 c = strtoul(s, &e, base);
208 if (*e) {
209 fprintf(stderr,
210 "Line %d: Invalid cell value '%s' : "
211 "%c is not a base %d digit; %d assumed\n",
212 yylloc.first_line, s, *e, base, c);
213 }
214
Jon Loeliger39488492007-02-16 09:33:54 -0600215 if (errno == EINVAL || errno == ERANGE) {
216 fprintf(stderr,
217 "Line %d: Invalid cell value '%s'; %d assumed\n",
218 yylloc.first_line, s, c);
Milton Miller85ab5cc2007-07-07 01:18:48 -0500219 errno = 0;
Jon Loeliger39488492007-02-16 09:33:54 -0600220 }
221
222 return c;
223}