blob: 4698793ade95620f0c6cc5707803c63190c0ddac [file] [log] [blame]
David Gibsonfc14dad2005-06-08 17:18:34 +10001/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
David Gibson63dc9c72007-09-18 11:44:04 +10004 *
David Gibsonfc14dad2005-06-08 17:18:34 +10005 * 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.
David Gibson63dc9c72007-09-18 11:44:04 +100014 *
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
David Gibsonfc14dad2005-06-08 17:18:34 +100019 */
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
Jon Loeliger30807ca2007-10-18 09:42:16 -050082sourcefile:
83 memreserves devicetree
84 {
David Gibsonf0517db2005-07-15 17:14:24 +100085 the_boot_info = build_boot_info($1, $2);
86 }
87 ;
88
Jon Loeliger30807ca2007-10-18 09:42:16 -050089memreserves:
90 memreserve memreserves
91 {
David Gibsonf040d952005-10-24 18:18:38 +100092 $$ = chain_reserve_entry($1, $2);
David Gibsonf0517db2005-07-15 17:14:24 +100093 }
Jon Loeliger30807ca2007-10-18 09:42:16 -050094 | /* empty */
95 {
David Gibsonf040d952005-10-24 18:18:38 +100096 $$ = NULL;
David Gibsonf0517db2005-07-15 17:14:24 +100097 }
98 ;
99
Jon Loeliger30807ca2007-10-18 09:42:16 -0500100memreserve:
101 label DT_MEMRESERVE DT_ADDR DT_ADDR ';'
102 {
Milton Millerd4290332007-07-07 01:18:49 -0500103 $$ = build_reserve_entry($3, $4, $1);
David Gibsonf0517db2005-07-15 17:14:24 +1000104 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500105 | label DT_MEMRESERVE DT_ADDR '-' DT_ADDR ';'
106 {
Milton Millerd4290332007-07-07 01:18:49 -0500107 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
David Gibsonf0517db2005-07-15 17:14:24 +1000108 }
109 ;
110
Jon Loeliger30807ca2007-10-18 09:42:16 -0500111devicetree:
112 '/' nodedef
113 {
David Gibsonf0517db2005-07-15 17:14:24 +1000114 $$ = name_node($2, "", NULL);
115 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000116 ;
117
Jon Loeliger30807ca2007-10-18 09:42:16 -0500118nodedef:
119 '{' proplist subnodes '}' ';'
120 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000121 $$ = build_node($2, $3);
122 }
123 ;
124
Jon Loeliger30807ca2007-10-18 09:42:16 -0500125proplist:
126 propdef proplist
127 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000128 $$ = chain_property($1, $2);
129 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500130 | /* empty */
131 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000132 $$ = NULL;
133 }
134 ;
135
Jon Loeliger30807ca2007-10-18 09:42:16 -0500136propdef:
137 label DT_PROPNAME '=' propdata ';'
138 {
David Gibson4102d842005-06-16 14:36:37 +1000139 $$ = build_property($2, $4, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000140 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500141 | label DT_PROPNAME ';'
142 {
David Gibson9ad45872005-06-17 14:32:32 +1000143 $$ = build_property($2, empty_data, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000144 }
145 ;
146
Jon Loeliger30807ca2007-10-18 09:42:16 -0500147propdata:
148 propdataprefix DT_STRING
149 {
150 $$ = data_merge($1, $2);
David Gibson32da4752007-02-07 16:37:50 +1100151 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500152 | propdataprefix '<' celllist '>'
153 {
154 $$ = data_merge(data_append_align($1,
155 sizeof(cell_t)), $3);
156 }
157 | propdataprefix '[' bytestring ']'
158 {
159 $$ = data_merge($1, $3);
160 }
161 | propdata DT_LABEL
162 {
163 $$ = data_add_label($1, $2);
164 }
David Gibson32da4752007-02-07 16:37:50 +1100165 ;
166
Jon Loeliger30807ca2007-10-18 09:42:16 -0500167propdataprefix:
168 propdata ','
169 {
170 $$ = $1;
171 }
172 | propdataprefix DT_LABEL
173 {
174 $$ = data_add_label($1, $2);
175 }
176 | /* empty */
177 {
178 $$ = empty_data;
179 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000180 ;
181
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600182opt_cell_base:
183 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500184 {
185 $$ = 16;
186 }
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600187 | DT_BASE
188 ;
189
Jon Loeliger30807ca2007-10-18 09:42:16 -0500190celllist:
191 celllist opt_cell_base DT_CELL
192 {
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600193 $$ = data_append_cell($1,
Jon Loeliger39488492007-02-16 09:33:54 -0600194 cell_from_string($3, $2));
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600195 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500196 | celllist DT_REF
197 {
David Gibson81f2e892005-06-16 17:04:00 +1000198 $$ = data_append_cell(data_add_fixup($1, $2), -1);
199 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500200 | celllist DT_LABEL
201 {
202 $$ = data_add_label($1, $2);
203 }
204 | /* empty */
205 {
206 $$ = empty_data;
207 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000208 ;
209
Jon Loeliger30807ca2007-10-18 09:42:16 -0500210bytestring:
211 bytestring DT_BYTE
212 {
213 $$ = data_append_byte($1, $2);
214 }
215 | bytestring DT_LABEL
216 {
217 $$ = data_add_label($1, $2);
218 }
219 | /* empty */
220 {
221 $$ = empty_data;
222 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000223 ;
224
Jon Loeliger30807ca2007-10-18 09:42:16 -0500225subnodes:
226 subnode subnodes
227 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000228 $$ = chain_node($1, $2);
229 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500230 | /* empty */
231 {
232 $$ = NULL;
233 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000234 ;
235
Jon Loeliger30807ca2007-10-18 09:42:16 -0500236subnode:
237 label nodename nodedef
238 {
239 $$ = name_node($3, $2, $1);
240 }
David Gibson4102d842005-06-16 14:36:37 +1000241 ;
242
Jon Loeliger30807ca2007-10-18 09:42:16 -0500243nodename:
244 DT_NODENAME
245 {
246 $$ = $1;
247 }
248 | DT_PROPNAME
249 {
250 $$ = $1;
251 }
David Gibson4102d842005-06-16 14:36:37 +1000252 ;
253
Jon Loeliger30807ca2007-10-18 09:42:16 -0500254label:
255 DT_LABEL
256 {
257 $$ = $1;
258 }
259 | /* empty */
260 {
261 $$ = NULL;
262 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000263 ;
264
265%%
266
267void yyerror (char const *s)
268{
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500269 const char *fname = srcpos_filename_for_num(yylloc.filenum);
270
271 if (strcmp(fname, "-") == 0)
272 fname = "stdin";
273
274 fprintf(stderr, "%s:%d %s\n",
275 fname, yylloc.first_line, s);
David Gibsonfc14dad2005-06-08 17:18:34 +1000276}
Jon Loeliger39488492007-02-16 09:33:54 -0600277
278
279/*
280 * Convert a string representation of a numeric cell
281 * in the given base into a cell.
282 *
Milton Miller85ab5cc2007-07-07 01:18:48 -0500283 * FIXME: should these specification errors be fatal instead?
Jon Loeliger39488492007-02-16 09:33:54 -0600284 */
285
286cell_t cell_from_string(char *s, unsigned int base)
287{
288 cell_t c;
Milton Miller85ab5cc2007-07-07 01:18:48 -0500289 char *e;
Jon Loeliger39488492007-02-16 09:33:54 -0600290
Milton Miller85ab5cc2007-07-07 01:18:48 -0500291 c = strtoul(s, &e, base);
292 if (*e) {
293 fprintf(stderr,
294 "Line %d: Invalid cell value '%s' : "
295 "%c is not a base %d digit; %d assumed\n",
296 yylloc.first_line, s, *e, base, c);
297 }
298
Jon Loeliger39488492007-02-16 09:33:54 -0600299 if (errno == EINVAL || errno == ERANGE) {
300 fprintf(stderr,
301 "Line %d: Invalid cell value '%s'; %d assumed\n",
302 yylloc.first_line, s, c);
Milton Miller85ab5cc2007-07-07 01:18:48 -0500303 errno = 0;
Jon Loeliger39488492007-02-16 09:33:54 -0600304 }
305
306 return c;
307}