blob: a2c092591692e61d5af690bc2c3c7b6b4e8181cb [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
21%{
David Gibsone37ec7d2008-06-11 11:58:39 +100022#include <stdio.h>
23
David Gibsonfc14dad2005-06-08 17:18:34 +100024#include "dtc.h"
Jon Loeligere45e6fd2007-03-23 15:18:41 -050025#include "srcpos.h"
David Gibsonfc14dad2005-06-08 17:18:34 +100026
Lukasz Wojcik5c8d2e22010-01-29 17:31:51 +010027YYLTYPE yylloc;
28
David Gibson6b8e0562008-03-05 11:47:54 +110029extern int yylex(void);
Jon Loeligere5c8e1d2008-09-12 13:39:49 -050030extern void yyerror(char const *s);
David Gibsonfc14dad2005-06-08 17:18:34 +100031
David Gibsonf0517db2005-07-15 17:14:24 +100032extern struct boot_info *the_boot_info;
Scott Woodad4f54a2008-01-03 17:43:33 -060033extern int treesource_error;
David Gibsonfc14dad2005-06-08 17:18:34 +100034
David Gibson6b8e0562008-03-05 11:47:54 +110035static unsigned long long eval_literal(const char *s, int base, int bits);
David Gibsonfc14dad2005-06-08 17:18:34 +100036%}
37
38%union {
David Gibson9ed27a22007-11-07 11:16:19 +110039 char *propnodename;
40 char *literal;
41 char *labelref;
Jon Loeligeraf0278a2007-02-15 10:59:27 -060042 unsigned int cbase;
David Gibson53359012008-06-25 13:53:07 +100043 uint8_t byte;
David Gibsonfc14dad2005-06-08 17:18:34 +100044 struct data data;
David Gibson9ed27a22007-11-07 11:16:19 +110045
David Gibson53359012008-06-25 13:53:07 +100046 uint64_t addr;
David Gibson9ed27a22007-11-07 11:16:19 +110047 cell_t cell;
David Gibsonfc14dad2005-06-08 17:18:34 +100048 struct property *prop;
49 struct property *proplist;
50 struct node *node;
51 struct node *nodelist;
David Gibsonf040d952005-10-24 18:18:38 +100052 struct reserve_info *re;
David Gibsonfc14dad2005-06-08 17:18:34 +100053}
54
David Gibson9138db52007-11-07 11:17:17 +110055%token DT_V1
David Gibsonf0517db2005-07-15 17:14:24 +100056%token DT_MEMRESERVE
David Gibson9ed27a22007-11-07 11:16:19 +110057%token <propnodename> DT_PROPNODENAME
58%token <literal> DT_LITERAL
Jon Loeligeraf0278a2007-02-15 10:59:27 -060059%token <cbase> DT_BASE
David Gibsonfc14dad2005-06-08 17:18:34 +100060%token <byte> DT_BYTE
61%token <data> DT_STRING
David Gibson9ed27a22007-11-07 11:16:19 +110062%token <labelref> DT_LABEL
63%token <labelref> DT_REF
David Gibsone37ec7d2008-06-11 11:58:39 +100064%token DT_INCBIN
David Gibsonfc14dad2005-06-08 17:18:34 +100065
66%type <data> propdata
David Gibson32da4752007-02-07 16:37:50 +110067%type <data> propdataprefix
David Gibsonf0517db2005-07-15 17:14:24 +100068%type <re> memreserve
David Gibsonf040d952005-10-24 18:18:38 +100069%type <re> memreserves
David Gibson9ed27a22007-11-07 11:16:19 +110070%type <addr> addr
David Gibsonfc14dad2005-06-08 17:18:34 +100071%type <data> celllist
David Gibson9ed27a22007-11-07 11:16:19 +110072%type <cell> cellval
David Gibsonfc14dad2005-06-08 17:18:34 +100073%type <data> bytestring
74%type <prop> propdef
75%type <proplist> proplist
76
David Gibsonf0517db2005-07-15 17:14:24 +100077%type <node> devicetree
David Gibsonfc14dad2005-06-08 17:18:34 +100078%type <node> nodedef
79%type <node> subnode
80%type <nodelist> subnodes
David Gibson9ed27a22007-11-07 11:16:19 +110081%type <labelref> label
David Gibson4102d842005-06-16 14:36:37 +100082
David Gibsonfc14dad2005-06-08 17:18:34 +100083%%
84
Jon Loeliger30807ca2007-10-18 09:42:16 -050085sourcefile:
David Gibson9138db52007-11-07 11:17:17 +110086 DT_V1 ';' memreserves devicetree
87 {
David Gibson548767f2008-05-16 13:22:57 +100088 the_boot_info = build_boot_info($3, $4, 0);
David Gibson9138db52007-11-07 11:17:17 +110089 }
David Gibsonf0517db2005-07-15 17:14:24 +100090 ;
91
Jon Loeliger30807ca2007-10-18 09:42:16 -050092memreserves:
Jon Loeliger56412892007-10-23 09:28:54 -050093 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -050094 {
David Gibsonf040d952005-10-24 18:18:38 +100095 $$ = NULL;
David Gibsonf0517db2005-07-15 17:14:24 +100096 }
Jon Loeliger56412892007-10-23 09:28:54 -050097 | memreserve memreserves
98 {
99 $$ = chain_reserve_entry($1, $2);
100 }
David Gibsonf0517db2005-07-15 17:14:24 +1000101 ;
102
Jon Loeliger30807ca2007-10-18 09:42:16 -0500103memreserve:
David Gibson9ed27a22007-11-07 11:16:19 +1100104 label DT_MEMRESERVE addr addr ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500105 {
Milton Millerd4290332007-07-07 01:18:49 -0500106 $$ = build_reserve_entry($3, $4, $1);
David Gibsonf0517db2005-07-15 17:14:24 +1000107 }
David Gibson9138db52007-11-07 11:17:17 +1100108 ;
109
David Gibson9ed27a22007-11-07 11:16:19 +1100110addr:
111 DT_LITERAL
112 {
David Gibson9138db52007-11-07 11:17:17 +1100113 $$ = eval_literal($1, 0, 64);
114 }
David Gibson9ed27a22007-11-07 11:16:19 +1100115 ;
116
Jon Loeliger30807ca2007-10-18 09:42:16 -0500117devicetree:
118 '/' nodedef
119 {
David Gibsonf0517db2005-07-15 17:14:24 +1000120 $$ = name_node($2, "", NULL);
121 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000122 ;
123
Jon Loeliger30807ca2007-10-18 09:42:16 -0500124nodedef:
125 '{' proplist subnodes '}' ';'
126 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000127 $$ = build_node($2, $3);
128 }
129 ;
130
Jon Loeliger30807ca2007-10-18 09:42:16 -0500131proplist:
Jon Loeliger56412892007-10-23 09:28:54 -0500132 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500133 {
David Gibsonfc14dad2005-06-08 17:18:34 +1000134 $$ = NULL;
135 }
Jon Loeliger7b3fb782007-10-22 16:09:56 -0500136 | proplist propdef
Jon Loeliger56412892007-10-23 09:28:54 -0500137 {
Jon Loeliger7b3fb782007-10-22 16:09:56 -0500138 $$ = chain_property($2, $1);
Jon Loeliger56412892007-10-23 09:28:54 -0500139 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000140 ;
141
Jon Loeliger30807ca2007-10-18 09:42:16 -0500142propdef:
David Gibson9ed27a22007-11-07 11:16:19 +1100143 label DT_PROPNODENAME '=' propdata ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500144 {
David Gibson4102d842005-06-16 14:36:37 +1000145 $$ = build_property($2, $4, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000146 }
David Gibson9ed27a22007-11-07 11:16:19 +1100147 | label DT_PROPNODENAME ';'
Jon Loeliger30807ca2007-10-18 09:42:16 -0500148 {
David Gibson9ad45872005-06-17 14:32:32 +1000149 $$ = build_property($2, empty_data, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000150 }
151 ;
152
Jon Loeliger30807ca2007-10-18 09:42:16 -0500153propdata:
154 propdataprefix DT_STRING
155 {
156 $$ = data_merge($1, $2);
David Gibson32da4752007-02-07 16:37:50 +1100157 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500158 | propdataprefix '<' celllist '>'
159 {
David Gibsonf7497dc2007-11-02 16:54:26 +1100160 $$ = data_merge($1, $3);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500161 }
162 | propdataprefix '[' bytestring ']'
163 {
164 $$ = data_merge($1, $3);
165 }
David Gibsonefbbef82007-12-05 10:43:50 +1100166 | propdataprefix DT_REF
167 {
168 $$ = data_add_marker($1, REF_PATH, $2);
169 }
David Gibsone37ec7d2008-06-11 11:58:39 +1000170 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
171 {
David Gibsond68cb362009-12-08 14:24:42 +1100172 FILE *f = srcfile_relative_open($4.val, NULL);
173 struct data d;
David Gibsone37ec7d2008-06-11 11:58:39 +1000174
175 if ($6 != 0)
David Gibsond68cb362009-12-08 14:24:42 +1100176 if (fseek(f, $6, SEEK_SET) != 0)
David Gibson350c9cc2009-11-12 11:14:04 +1100177 srcpos_error(&yylloc,
Jon Loeligere5c8e1d2008-09-12 13:39:49 -0500178 "Couldn't seek to offset %llu in \"%s\": %s",
179 (unsigned long long)$6,
180 $4.val,
181 strerror(errno));
David Gibsone37ec7d2008-06-11 11:58:39 +1000182
David Gibsond68cb362009-12-08 14:24:42 +1100183 d = data_copy_file(f, $8);
David Gibsone37ec7d2008-06-11 11:58:39 +1000184
185 $$ = data_merge($1, d);
David Gibsond68cb362009-12-08 14:24:42 +1100186 fclose(f);
David Gibsone37ec7d2008-06-11 11:58:39 +1000187 }
188 | propdataprefix DT_INCBIN '(' DT_STRING ')'
189 {
David Gibsond68cb362009-12-08 14:24:42 +1100190 FILE *f = srcfile_relative_open($4.val, NULL);
David Gibsone37ec7d2008-06-11 11:58:39 +1000191 struct data d = empty_data;
192
David Gibsond68cb362009-12-08 14:24:42 +1100193 d = data_copy_file(f, -1);
David Gibsone37ec7d2008-06-11 11:58:39 +1000194
195 $$ = data_merge($1, d);
David Gibsond68cb362009-12-08 14:24:42 +1100196 fclose(f);
David Gibsone37ec7d2008-06-11 11:58:39 +1000197 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500198 | propdata DT_LABEL
199 {
David Gibsondc941772007-11-22 14:39:23 +1100200 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500201 }
David Gibson32da4752007-02-07 16:37:50 +1100202 ;
203
Jon Loeliger30807ca2007-10-18 09:42:16 -0500204propdataprefix:
Jon Loeliger56412892007-10-23 09:28:54 -0500205 /* empty */
206 {
207 $$ = empty_data;
208 }
209 | propdata ','
Jon Loeliger30807ca2007-10-18 09:42:16 -0500210 {
211 $$ = $1;
212 }
213 | propdataprefix DT_LABEL
214 {
David Gibsondc941772007-11-22 14:39:23 +1100215 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500216 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000217 ;
218
Jon Loeliger30807ca2007-10-18 09:42:16 -0500219celllist:
Jon Loeliger56412892007-10-23 09:28:54 -0500220 /* empty */
221 {
222 $$ = empty_data;
223 }
David Gibson9ed27a22007-11-07 11:16:19 +1100224 | celllist cellval
Jon Loeliger30807ca2007-10-18 09:42:16 -0500225 {
David Gibson9ed27a22007-11-07 11:16:19 +1100226 $$ = data_append_cell($1, $2);
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600227 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500228 | celllist DT_REF
229 {
David Gibsondc941772007-11-22 14:39:23 +1100230 $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
231 $2), -1);
David Gibson81f2e892005-06-16 17:04:00 +1000232 }
Jon Loeliger30807ca2007-10-18 09:42:16 -0500233 | celllist DT_LABEL
234 {
David Gibsondc941772007-11-22 14:39:23 +1100235 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500236 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000237 ;
238
David Gibson9ed27a22007-11-07 11:16:19 +1100239cellval:
David Gibson9138db52007-11-07 11:17:17 +1100240 DT_LITERAL
241 {
242 $$ = eval_literal($1, 0, 32);
243 }
David Gibson9ed27a22007-11-07 11:16:19 +1100244 ;
245
Jon Loeliger30807ca2007-10-18 09:42:16 -0500246bytestring:
Jon Loeliger56412892007-10-23 09:28:54 -0500247 /* empty */
248 {
249 $$ = empty_data;
250 }
251 | bytestring DT_BYTE
Jon Loeliger30807ca2007-10-18 09:42:16 -0500252 {
253 $$ = data_append_byte($1, $2);
254 }
255 | bytestring DT_LABEL
256 {
David Gibsondc941772007-11-22 14:39:23 +1100257 $$ = data_add_marker($1, LABEL, $2);
Jon Loeliger30807ca2007-10-18 09:42:16 -0500258 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000259 ;
260
Jon Loeliger30807ca2007-10-18 09:42:16 -0500261subnodes:
Jon Loeliger56412892007-10-23 09:28:54 -0500262 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500263 {
264 $$ = NULL;
265 }
Jon Loeliger56412892007-10-23 09:28:54 -0500266 | subnode subnodes
267 {
268 $$ = chain_node($1, $2);
269 }
David Gibsonc0481022007-12-05 10:27:04 +1100270 | subnode propdef
271 {
Scott Wood3c3ecaa2008-01-04 15:10:47 -0600272 yyerror("syntax error: properties must precede subnodes");
David Gibsonc0481022007-12-05 10:27:04 +1100273 YYERROR;
274 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000275 ;
276
Jon Loeliger30807ca2007-10-18 09:42:16 -0500277subnode:
David Gibson9ed27a22007-11-07 11:16:19 +1100278 label DT_PROPNODENAME nodedef
Jon Loeliger30807ca2007-10-18 09:42:16 -0500279 {
280 $$ = name_node($3, $2, $1);
281 }
David Gibson4102d842005-06-16 14:36:37 +1000282 ;
283
Jon Loeliger30807ca2007-10-18 09:42:16 -0500284label:
Jon Loeliger56412892007-10-23 09:28:54 -0500285 /* empty */
Jon Loeliger30807ca2007-10-18 09:42:16 -0500286 {
287 $$ = NULL;
288 }
Jon Loeliger56412892007-10-23 09:28:54 -0500289 | DT_LABEL
290 {
291 $$ = $1;
292 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000293 ;
294
295%%
296
Jon Loeligere5c8e1d2008-09-12 13:39:49 -0500297void yyerror(char const *s)
David Gibsonfc14dad2005-06-08 17:18:34 +1000298{
Jon Loeligere5c8e1d2008-09-12 13:39:49 -0500299 srcpos_error(&yylloc, "%s", s);
Scott Woodad4f54a2008-01-03 17:43:33 -0600300 treesource_error = 1;
David Gibsonfc14dad2005-06-08 17:18:34 +1000301}
Jon Loeliger39488492007-02-16 09:33:54 -0600302
David Gibson6b8e0562008-03-05 11:47:54 +1100303static unsigned long long eval_literal(const char *s, int base, int bits)
Jon Loeliger39488492007-02-16 09:33:54 -0600304{
David Gibson9ed27a22007-11-07 11:16:19 +1100305 unsigned long long val;
Milton Miller85ab5cc2007-07-07 01:18:48 -0500306 char *e;
Jon Loeliger39488492007-02-16 09:33:54 -0600307
David Gibson9ed27a22007-11-07 11:16:19 +1100308 errno = 0;
309 val = strtoull(s, &e, base);
310 if (*e)
311 yyerror("bad characters in literal");
312 else if ((errno == ERANGE)
313 || ((bits < 64) && (val >= (1ULL << bits))))
314 yyerror("literal out of range");
315 else if (errno != 0)
316 yyerror("bad literal");
317 return val;
Jon Loeliger39488492007-02-16 09:33:54 -0600318}