symbian-qemu-0.9.1-12/dtc-trunk/dtc-parser.y
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     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 
       
    21 %locations
       
    22 
       
    23 %{
       
    24 #include <stdio.h>
       
    25 
       
    26 #include "dtc.h"
       
    27 #include "srcpos.h"
       
    28 
       
    29 extern int yylex(void);
       
    30 
       
    31 extern struct boot_info *the_boot_info;
       
    32 extern int treesource_error;
       
    33 
       
    34 static unsigned long long eval_literal(const char *s, int base, int bits);
       
    35 %}
       
    36 
       
    37 %union {
       
    38 	char *propnodename;
       
    39 	char *literal;
       
    40 	char *labelref;
       
    41 	unsigned int cbase;
       
    42 	uint8_t byte;
       
    43 	struct data data;
       
    44 
       
    45 	uint64_t addr;
       
    46 	cell_t cell;
       
    47 	struct property *prop;
       
    48 	struct property *proplist;
       
    49 	struct node *node;
       
    50 	struct node *nodelist;
       
    51 	struct reserve_info *re;
       
    52 }
       
    53 
       
    54 %token DT_V1
       
    55 %token DT_MEMRESERVE
       
    56 %token <propnodename> DT_PROPNODENAME
       
    57 %token <literal> DT_LITERAL
       
    58 %token <literal> DT_LEGACYLITERAL
       
    59 %token <cbase> DT_BASE
       
    60 %token <byte> DT_BYTE
       
    61 %token <data> DT_STRING
       
    62 %token <labelref> DT_LABEL
       
    63 %token <labelref> DT_REF
       
    64 %token DT_INCBIN
       
    65 
       
    66 %type <data> propdata
       
    67 %type <data> propdataprefix
       
    68 %type <re> memreserve
       
    69 %type <re> memreserves
       
    70 %type <re> v0_memreserve
       
    71 %type <re> v0_memreserves
       
    72 %type <addr> addr
       
    73 %type <data> celllist
       
    74 %type <cbase> cellbase
       
    75 %type <cell> cellval
       
    76 %type <data> bytestring
       
    77 %type <prop> propdef
       
    78 %type <proplist> proplist
       
    79 
       
    80 %type <node> devicetree
       
    81 %type <node> nodedef
       
    82 %type <node> subnode
       
    83 %type <nodelist> subnodes
       
    84 %type <labelref> label
       
    85 
       
    86 %%
       
    87 
       
    88 sourcefile:
       
    89 	  DT_V1 ';' memreserves devicetree
       
    90 		{
       
    91 			the_boot_info = build_boot_info($3, $4, 0);
       
    92 		}
       
    93 	| v0_memreserves devicetree
       
    94 		{
       
    95 			the_boot_info = build_boot_info($1, $2, 0);
       
    96 		}
       
    97 	;
       
    98 
       
    99 memreserves:
       
   100 	  /* empty */
       
   101 		{
       
   102 			$$ = NULL;
       
   103 		}
       
   104 	| memreserve memreserves
       
   105 		{
       
   106 			$$ = chain_reserve_entry($1, $2);
       
   107 		}
       
   108 	;
       
   109 
       
   110 memreserve:
       
   111 	  label DT_MEMRESERVE addr addr ';'
       
   112 		{
       
   113 			$$ = build_reserve_entry($3, $4, $1);
       
   114 		}
       
   115 	;
       
   116 
       
   117 v0_memreserves:
       
   118 	  /* empty */
       
   119 		{
       
   120 			$$ = NULL;
       
   121 		}
       
   122 	| v0_memreserve v0_memreserves
       
   123 		{
       
   124 			$$ = chain_reserve_entry($1, $2);
       
   125 		};
       
   126 	;
       
   127 
       
   128 v0_memreserve:
       
   129 	  memreserve
       
   130 		{
       
   131 			$$ = $1;
       
   132 		}
       
   133 	| label DT_MEMRESERVE addr '-' addr ';'
       
   134 		{
       
   135 			$$ = build_reserve_entry($3, $5 - $3 + 1, $1);
       
   136 		}
       
   137 	;
       
   138 
       
   139 addr:
       
   140 	  DT_LITERAL
       
   141 		{
       
   142 			$$ = eval_literal($1, 0, 64);
       
   143 		}
       
   144 	| DT_LEGACYLITERAL
       
   145 		{
       
   146 			$$ = eval_literal($1, 16, 64);
       
   147 		}
       
   148 	  ;
       
   149 
       
   150 devicetree:
       
   151 	  '/' nodedef
       
   152 		{
       
   153 			$$ = name_node($2, "", NULL);
       
   154 		}
       
   155 	;
       
   156 
       
   157 nodedef:
       
   158 	  '{' proplist subnodes '}' ';'
       
   159 		{
       
   160 			$$ = build_node($2, $3);
       
   161 		}
       
   162 	;
       
   163 
       
   164 proplist:
       
   165 	  /* empty */
       
   166 		{
       
   167 			$$ = NULL;
       
   168 		}
       
   169 	| proplist propdef
       
   170 		{
       
   171 			$$ = chain_property($2, $1);
       
   172 		}
       
   173 	;
       
   174 
       
   175 propdef:
       
   176 	  label DT_PROPNODENAME '=' propdata ';'
       
   177 		{
       
   178 			$$ = build_property($2, $4, $1);
       
   179 		}
       
   180 	| label DT_PROPNODENAME ';'
       
   181 		{
       
   182 			$$ = build_property($2, empty_data, $1);
       
   183 		}
       
   184 	;
       
   185 
       
   186 propdata:
       
   187 	  propdataprefix DT_STRING
       
   188 		{
       
   189 			$$ = data_merge($1, $2);
       
   190 		}
       
   191 	| propdataprefix '<' celllist '>'
       
   192 		{
       
   193 			$$ = data_merge($1, $3);
       
   194 		}
       
   195 	| propdataprefix '[' bytestring ']'
       
   196 		{
       
   197 			$$ = data_merge($1, $3);
       
   198 		}
       
   199 	| propdataprefix DT_REF
       
   200 		{
       
   201 			$$ = data_add_marker($1, REF_PATH, $2);
       
   202 		}
       
   203 	| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
       
   204 		{
       
   205 			struct search_path path = { srcpos_file->dir, NULL, NULL };
       
   206 			struct dtc_file *file = dtc_open_file($4.val, &path);
       
   207 			struct data d = empty_data;
       
   208 
       
   209 			if ($6 != 0)
       
   210 				if (fseek(file->file, $6, SEEK_SET) != 0)
       
   211 					yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
       
   212 						 (unsigned long long)$6,
       
   213 						 $4.val, strerror(errno));
       
   214 
       
   215 			d = data_copy_file(file->file, $8);
       
   216 
       
   217 			$$ = data_merge($1, d);
       
   218 			dtc_close_file(file);
       
   219 		}
       
   220 	| propdataprefix DT_INCBIN '(' DT_STRING ')'
       
   221 		{
       
   222 			struct search_path path = { srcpos_file->dir, NULL, NULL };
       
   223 			struct dtc_file *file = dtc_open_file($4.val, &path);
       
   224 			struct data d = empty_data;
       
   225 
       
   226 			d = data_copy_file(file->file, -1);
       
   227 
       
   228 			$$ = data_merge($1, d);
       
   229 			dtc_close_file(file);
       
   230 		}
       
   231 	| propdata DT_LABEL
       
   232 		{
       
   233 			$$ = data_add_marker($1, LABEL, $2);
       
   234 		}
       
   235 	;
       
   236 
       
   237 propdataprefix:
       
   238 	  /* empty */
       
   239 		{
       
   240 			$$ = empty_data;
       
   241 		}
       
   242 	| propdata ','
       
   243 		{
       
   244 			$$ = $1;
       
   245 		}
       
   246 	| propdataprefix DT_LABEL
       
   247 		{
       
   248 			$$ = data_add_marker($1, LABEL, $2);
       
   249 		}
       
   250 	;
       
   251 
       
   252 celllist:
       
   253 	  /* empty */
       
   254 		{
       
   255 			$$ = empty_data;
       
   256 		}
       
   257 	| celllist cellval
       
   258 		{
       
   259 			$$ = data_append_cell($1, $2);
       
   260 		}
       
   261 	| celllist DT_REF
       
   262 		{
       
   263 			$$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
       
   264 							      $2), -1);
       
   265 		}
       
   266 	| celllist DT_LABEL
       
   267 		{
       
   268 			$$ = data_add_marker($1, LABEL, $2);
       
   269 		}
       
   270 	;
       
   271 
       
   272 cellbase:
       
   273 	  /* empty */
       
   274 		{
       
   275 			$$ = 16;
       
   276 		}
       
   277 	| DT_BASE
       
   278 	;
       
   279 
       
   280 cellval:
       
   281 	  DT_LITERAL
       
   282 		{
       
   283 			$$ = eval_literal($1, 0, 32);
       
   284 		}
       
   285 	| cellbase DT_LEGACYLITERAL
       
   286 		{
       
   287 			$$ = eval_literal($2, $1, 32);
       
   288 		}
       
   289 	;
       
   290 
       
   291 bytestring:
       
   292 	  /* empty */
       
   293 		{
       
   294 			$$ = empty_data;
       
   295 		}
       
   296 	| bytestring DT_BYTE
       
   297 		{
       
   298 			$$ = data_append_byte($1, $2);
       
   299 		}
       
   300 	| bytestring DT_LABEL
       
   301 		{
       
   302 			$$ = data_add_marker($1, LABEL, $2);
       
   303 		}
       
   304 	;
       
   305 
       
   306 subnodes:
       
   307 	  /* empty */
       
   308 		{
       
   309 			$$ = NULL;
       
   310 		}
       
   311 	|  subnode subnodes
       
   312 		{
       
   313 			$$ = chain_node($1, $2);
       
   314 		}
       
   315 	| subnode propdef
       
   316 		{
       
   317 			yyerror("syntax error: properties must precede subnodes");
       
   318 			YYERROR;
       
   319 		}
       
   320 	;
       
   321 
       
   322 subnode:
       
   323 	  label DT_PROPNODENAME nodedef
       
   324 		{
       
   325 			$$ = name_node($3, $2, $1);
       
   326 		}
       
   327 	;
       
   328 
       
   329 label:
       
   330 	  /* empty */
       
   331 		{
       
   332 			$$ = NULL;
       
   333 		}
       
   334 	| DT_LABEL
       
   335 		{
       
   336 			$$ = $1;
       
   337 		}
       
   338 	;
       
   339 
       
   340 %%
       
   341 
       
   342 void yyerrorf(char const *s, ...)
       
   343 {
       
   344 	const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
       
   345 	va_list va;
       
   346 	va_start(va, s);
       
   347 
       
   348 	if (strcmp(fname, "-") == 0)
       
   349 		fname = "stdin";
       
   350 
       
   351 	fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
       
   352 	vfprintf(stderr, s, va);
       
   353 	fprintf(stderr, "\n");
       
   354 
       
   355 	treesource_error = 1;
       
   356 	va_end(va);
       
   357 }
       
   358 
       
   359 void yyerror (char const *s)
       
   360 {
       
   361 	yyerrorf("%s", s);
       
   362 }
       
   363 
       
   364 static unsigned long long eval_literal(const char *s, int base, int bits)
       
   365 {
       
   366 	unsigned long long val;
       
   367 	char *e;
       
   368 
       
   369 	errno = 0;
       
   370 	val = strtoull(s, &e, base);
       
   371 	if (*e)
       
   372 		yyerror("bad characters in literal");
       
   373 	else if ((errno == ERANGE)
       
   374 		 || ((bits < 64) && (val >= (1ULL << bits))))
       
   375 		yyerror("literal out of range");
       
   376 	else if (errno != 0)
       
   377 		yyerror("bad literal");
       
   378 	return val;
       
   379 }