blob: 39d9dac3097a860732723877c915e1194f950c0b [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);
29void yyerror(char const *);
30cell_t cell_from_string(char *s, unsigned int base);
David Gibsonfc14dad2005-06-08 17:18:34 +100031
David Gibsonf0517db2005-07-15 17:14:24 +100032extern struct boot_info *the_boot_info;
David Gibsonfc14dad2005-06-08 17:18:34 +100033
34%}
35
36%union {
37 cell_t cval;
Jon Loeligeraf0278a2007-02-15 10:59:27 -060038 unsigned int cbase;
David Gibson03a9b9d2005-07-11 16:49:52 +100039 u8 byte;
David Gibsonfc14dad2005-06-08 17:18:34 +100040 char *str;
41 struct data data;
42 struct property *prop;
43 struct property *proplist;
44 struct node *node;
45 struct node *nodelist;
46 int datalen;
47 int hexlen;
David Gibsonf0517db2005-07-15 17:14:24 +100048 u64 addr;
David Gibsonf040d952005-10-24 18:18:38 +100049 struct reserve_info *re;
David Gibsonfc14dad2005-06-08 17:18:34 +100050}
51
David Gibsonf0517db2005-07-15 17:14:24 +100052%token DT_MEMRESERVE
53%token <addr> DT_ADDR
David Gibsonfc14dad2005-06-08 17:18:34 +100054%token <str> DT_PROPNAME
55%token <str> DT_NODENAME
Jon Loeligeraf0278a2007-02-15 10:59:27 -060056%token <cbase> DT_BASE
57%token <str> DT_CELL
David Gibsonfc14dad2005-06-08 17:18:34 +100058%token <byte> DT_BYTE
59%token <data> DT_STRING
60%token <str> DT_UNIT
David Gibson4102d842005-06-16 14:36:37 +100061%token <str> DT_LABEL
David Gibson81f2e892005-06-16 17:04:00 +100062%token <str> DT_REF
David Gibsonfc14dad2005-06-08 17:18:34 +100063
64%type <data> propdata
David Gibson32da4752007-02-07 16:37:50 +110065%type <data> propdataprefix
David Gibsonf0517db2005-07-15 17:14:24 +100066%type <re> memreserve
David Gibsonf040d952005-10-24 18:18:38 +100067%type <re> memreserves
Jon Loeligeraf0278a2007-02-15 10:59:27 -060068%type <cbase> opt_cell_base
David Gibsonfc14dad2005-06-08 17:18:34 +100069%type <data> celllist
70%type <data> bytestring
71%type <prop> propdef
72%type <proplist> proplist
73
David Gibsonf0517db2005-07-15 17:14:24 +100074%type <node> devicetree
David Gibsonfc14dad2005-06-08 17:18:34 +100075%type <node> nodedef
76%type <node> subnode
77%type <nodelist> subnodes
David Gibson4102d842005-06-16 14:36:37 +100078%type <str> label
79%type <str> nodename
80
David Gibsonfc14dad2005-06-08 17:18:34 +100081%%
82
David Gibsonf0517db2005-07-15 17:14:24 +100083sourcefile: memreserves devicetree {
84 the_boot_info = build_boot_info($1, $2);
85 }
86 ;
87
David Gibsonf040d952005-10-24 18:18:38 +100088memreserves: memreserve memreserves {
89 $$ = chain_reserve_entry($1, $2);
David Gibsonf0517db2005-07-15 17:14:24 +100090 }
91 | /* empty */ {
David Gibsonf040d952005-10-24 18:18:38 +100092 $$ = NULL;
David Gibsonf0517db2005-07-15 17:14:24 +100093 }
94 ;
95
96memreserve: DT_MEMRESERVE DT_ADDR DT_ADDR ';' {
David Gibsonf040d952005-10-24 18:18:38 +100097 $$ = build_reserve_entry($2, $3, NULL);
David Gibsonf0517db2005-07-15 17:14:24 +100098 }
99 | DT_MEMRESERVE DT_ADDR '-' DT_ADDR ';' {
David Gibsonf040d952005-10-24 18:18:38 +1000100 $$ = build_reserve_entry($2, $4 - $2 + 1, NULL);
David Gibsonf0517db2005-07-15 17:14:24 +1000101 }
102 ;
103
104devicetree: '/' nodedef {
105 $$ = name_node($2, "", NULL);
106 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000107 ;
108
109nodedef: '{' proplist subnodes '}' ';' {
110 $$ = build_node($2, $3);
111 }
112 ;
113
114proplist: propdef proplist {
115 $$ = chain_property($1, $2);
116 }
117 | /* empty */ {
118 $$ = NULL;
119 }
120 ;
121
David Gibson4102d842005-06-16 14:36:37 +1000122propdef: label DT_PROPNAME '=' propdata ';' {
123 $$ = build_property($2, $4, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000124 }
David Gibson4102d842005-06-16 14:36:37 +1000125 | label DT_PROPNAME ';' {
David Gibson9ad45872005-06-17 14:32:32 +1000126 $$ = build_property($2, empty_data, $1);
David Gibsonfc14dad2005-06-08 17:18:34 +1000127 }
128 ;
129
David Gibson32da4752007-02-07 16:37:50 +1100130propdata: propdataprefix DT_STRING { $$ = data_merge($1, $2); }
131 | propdataprefix '<' celllist '>' {
132 $$ = data_merge(data_append_align($1, sizeof(cell_t)), $3);
133 }
134 | propdataprefix '[' bytestring ']' { $$ = data_merge($1, $3); }
135 ;
136
137propdataprefix: propdata ',' { $$ = $1; }
138 | /* empty */ { $$ = empty_data; }
David Gibsonfc14dad2005-06-08 17:18:34 +1000139 ;
140
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600141opt_cell_base:
142 /* empty */
143 { $$ = 16; }
144 | DT_BASE
145 ;
146
147celllist: celllist opt_cell_base DT_CELL {
148 $$ = data_append_cell($1,
Jon Loeliger39488492007-02-16 09:33:54 -0600149 cell_from_string($3, $2));
Jon Loeligeraf0278a2007-02-15 10:59:27 -0600150 }
David Gibson81f2e892005-06-16 17:04:00 +1000151 | celllist DT_REF {
152 $$ = data_append_cell(data_add_fixup($1, $2), -1);
153 }
David Gibsonfc14dad2005-06-08 17:18:34 +1000154 | /* empty */ { $$ = empty_data; }
155 ;
156
157bytestring: bytestring DT_BYTE { $$ = data_append_byte($1, $2); }
158 | /* empty */ { $$ = empty_data; }
159 ;
160
161subnodes: subnode subnodes {
162 $$ = chain_node($1, $2);
163 }
164 | /* empty */ { $$ = NULL; }
165 ;
166
David Gibson4102d842005-06-16 14:36:37 +1000167subnode: label nodename nodedef { $$ = name_node($3, $2, $1); }
168 ;
169
170nodename: DT_NODENAME { $$ = $1; }
171 | DT_PROPNAME { $$ = $1; }
172 ;
173
174label: DT_LABEL { $$ = $1; }
175 | /* empty */ { $$ = NULL; }
David Gibsonfc14dad2005-06-08 17:18:34 +1000176 ;
177
178%%
179
180void yyerror (char const *s)
181{
Jon Loeligere45e6fd2007-03-23 15:18:41 -0500182 const char *fname = srcpos_filename_for_num(yylloc.filenum);
183
184 if (strcmp(fname, "-") == 0)
185 fname = "stdin";
186
187 fprintf(stderr, "%s:%d %s\n",
188 fname, yylloc.first_line, s);
David Gibsonfc14dad2005-06-08 17:18:34 +1000189}
Jon Loeliger39488492007-02-16 09:33:54 -0600190
191
192/*
193 * Convert a string representation of a numeric cell
194 * in the given base into a cell.
195 *
196 * FIXME: The string "abc123", base 10, should be flagged
197 * as an error due to the leading "a", but isn't yet.
198 */
199
200cell_t cell_from_string(char *s, unsigned int base)
201{
202 cell_t c;
203
204 c = strtoul(s, NULL, base);
205 if (errno == EINVAL || errno == ERANGE) {
206 fprintf(stderr,
207 "Line %d: Invalid cell value '%s'; %d assumed\n",
208 yylloc.first_line, s, c);
209 }
210
211 return c;
212}