dtc-parser.y 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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. #include <stdio.h>
  22. #include "dtc.h"
  23. #include "srcpos.h"
  24. extern int yylex(void);
  25. extern void yyerror(char const *s);
  26. #define ERROR(loc, ...) \
  27. do { \
  28. srcpos_error((loc), "Error", __VA_ARGS__); \
  29. treesource_error = true; \
  30. } while (0)
  31. extern struct boot_info *the_boot_info;
  32. extern bool treesource_error;
  33. %}
  34. %union {
  35. char *propnodename;
  36. char *labelref;
  37. uint8_t byte;
  38. struct data data;
  39. struct {
  40. struct data data;
  41. int bits;
  42. } array;
  43. struct property *prop;
  44. struct property *proplist;
  45. struct node *node;
  46. struct node *nodelist;
  47. struct reserve_info *re;
  48. uint64_t integer;
  49. }
  50. %token DT_V1
  51. %token DT_MEMRESERVE
  52. %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
  53. %token DT_BITS
  54. %token DT_DEL_PROP
  55. %token DT_DEL_NODE
  56. %token <propnodename> DT_PROPNODENAME
  57. %token <integer> DT_LITERAL
  58. %token <integer> DT_CHAR_LITERAL
  59. %token <byte> DT_BYTE
  60. %token <data> DT_STRING
  61. %token <labelref> DT_LABEL
  62. %token <labelref> DT_REF
  63. %token DT_INCBIN
  64. %type <data> propdata
  65. %type <data> propdataprefix
  66. %type <re> memreserve
  67. %type <re> memreserves
  68. %type <array> arrayprefix
  69. %type <data> bytestring
  70. %type <prop> propdef
  71. %type <proplist> proplist
  72. %type <node> devicetree
  73. %type <node> nodedef
  74. %type <node> subnode
  75. %type <nodelist> subnodes
  76. %type <integer> integer_prim
  77. %type <integer> integer_unary
  78. %type <integer> integer_mul
  79. %type <integer> integer_add
  80. %type <integer> integer_shift
  81. %type <integer> integer_rela
  82. %type <integer> integer_eq
  83. %type <integer> integer_bitand
  84. %type <integer> integer_bitxor
  85. %type <integer> integer_bitor
  86. %type <integer> integer_and
  87. %type <integer> integer_or
  88. %type <integer> integer_trinary
  89. %type <integer> integer_expr
  90. %%
  91. sourcefile:
  92. DT_V1 ';' memreserves devicetree
  93. {
  94. the_boot_info = build_boot_info($3, $4,
  95. guess_boot_cpuid($4));
  96. }
  97. ;
  98. memreserves:
  99. /* empty */
  100. {
  101. $$ = NULL;
  102. }
  103. | memreserve memreserves
  104. {
  105. $$ = chain_reserve_entry($1, $2);
  106. }
  107. ;
  108. memreserve:
  109. DT_MEMRESERVE integer_prim integer_prim ';'
  110. {
  111. $$ = build_reserve_entry($2, $3);
  112. }
  113. | DT_LABEL memreserve
  114. {
  115. add_label(&$2->labels, $1);
  116. $$ = $2;
  117. }
  118. ;
  119. devicetree:
  120. '/' nodedef
  121. {
  122. $$ = name_node($2, "");
  123. }
  124. | devicetree '/' nodedef
  125. {
  126. $$ = merge_nodes($1, $3);
  127. }
  128. | devicetree DT_LABEL DT_REF nodedef
  129. {
  130. struct node *target = get_node_by_ref($1, $3);
  131. add_label(&target->labels, $2);
  132. if (target)
  133. merge_nodes(target, $4);
  134. else
  135. ERROR(&@3, "Label or path %s not found", $3);
  136. $$ = $1;
  137. }
  138. | devicetree DT_REF nodedef
  139. {
  140. struct node *target = get_node_by_ref($1, $2);
  141. if (target)
  142. merge_nodes(target, $3);
  143. else
  144. ERROR(&@2, "Label or path %s not found", $2);
  145. $$ = $1;
  146. }
  147. | devicetree DT_DEL_NODE DT_REF ';'
  148. {
  149. struct node *target = get_node_by_ref($1, $3);
  150. if (target)
  151. delete_node(target);
  152. else
  153. ERROR(&@3, "Label or path %s not found", $3);
  154. $$ = $1;
  155. }
  156. ;
  157. nodedef:
  158. '{' proplist subnodes '}' ';'
  159. {
  160. $$ = build_node($2, $3);
  161. }
  162. ;
  163. proplist:
  164. /* empty */
  165. {
  166. $$ = NULL;
  167. }
  168. | proplist propdef
  169. {
  170. $$ = chain_property($2, $1);
  171. }
  172. ;
  173. propdef:
  174. DT_PROPNODENAME '=' propdata ';'
  175. {
  176. $$ = build_property($1, $3);
  177. }
  178. | DT_PROPNODENAME ';'
  179. {
  180. $$ = build_property($1, empty_data);
  181. }
  182. | DT_DEL_PROP DT_PROPNODENAME ';'
  183. {
  184. $$ = build_property_delete($2);
  185. }
  186. | DT_LABEL propdef
  187. {
  188. add_label(&$2->labels, $1);
  189. $$ = $2;
  190. }
  191. ;
  192. propdata:
  193. propdataprefix DT_STRING
  194. {
  195. $$ = data_merge($1, $2);
  196. }
  197. | propdataprefix arrayprefix '>'
  198. {
  199. $$ = data_merge($1, $2.data);
  200. }
  201. | propdataprefix '[' bytestring ']'
  202. {
  203. $$ = data_merge($1, $3);
  204. }
  205. | propdataprefix DT_REF
  206. {
  207. $$ = data_add_marker($1, REF_PATH, $2);
  208. }
  209. | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
  210. {
  211. FILE *f = srcfile_relative_open($4.val, NULL);
  212. struct data d;
  213. if ($6 != 0)
  214. if (fseek(f, $6, SEEK_SET) != 0)
  215. die("Couldn't seek to offset %llu in \"%s\": %s",
  216. (unsigned long long)$6, $4.val,
  217. strerror(errno));
  218. d = data_copy_file(f, $8);
  219. $$ = data_merge($1, d);
  220. fclose(f);
  221. }
  222. | propdataprefix DT_INCBIN '(' DT_STRING ')'
  223. {
  224. FILE *f = srcfile_relative_open($4.val, NULL);
  225. struct data d = empty_data;
  226. d = data_copy_file(f, -1);
  227. $$ = data_merge($1, d);
  228. fclose(f);
  229. }
  230. | propdata DT_LABEL
  231. {
  232. $$ = data_add_marker($1, LABEL, $2);
  233. }
  234. ;
  235. propdataprefix:
  236. /* empty */
  237. {
  238. $$ = empty_data;
  239. }
  240. | propdata ','
  241. {
  242. $$ = $1;
  243. }
  244. | propdataprefix DT_LABEL
  245. {
  246. $$ = data_add_marker($1, LABEL, $2);
  247. }
  248. ;
  249. arrayprefix:
  250. DT_BITS DT_LITERAL '<'
  251. {
  252. unsigned long long bits;
  253. bits = $2;
  254. if ((bits != 8) && (bits != 16) &&
  255. (bits != 32) && (bits != 64)) {
  256. ERROR(&@2, "Array elements must be"
  257. " 8, 16, 32 or 64-bits");
  258. bits = 32;
  259. }
  260. $$.data = empty_data;
  261. $$.bits = bits;
  262. }
  263. | '<'
  264. {
  265. $$.data = empty_data;
  266. $$.bits = 32;
  267. }
  268. | arrayprefix integer_prim
  269. {
  270. if ($1.bits < 64) {
  271. uint64_t mask = (1ULL << $1.bits) - 1;
  272. /*
  273. * Bits above mask must either be all zero
  274. * (positive within range of mask) or all one
  275. * (negative and sign-extended). The second
  276. * condition is true if when we set all bits
  277. * within the mask to one (i.e. | in the
  278. * mask), all bits are one.
  279. */
  280. if (($2 > mask) && (($2 | mask) != -1ULL))
  281. ERROR(&@2, "Value out of range for"
  282. " %d-bit array element", $1.bits);
  283. }
  284. $$.data = data_append_integer($1.data, $2, $1.bits);
  285. }
  286. | arrayprefix DT_REF
  287. {
  288. uint64_t val = ~0ULL >> (64 - $1.bits);
  289. if ($1.bits == 32)
  290. $1.data = data_add_marker($1.data,
  291. REF_PHANDLE,
  292. $2);
  293. else
  294. ERROR(&@2, "References are only allowed in "
  295. "arrays with 32-bit elements.");
  296. $$.data = data_append_integer($1.data, val, $1.bits);
  297. }
  298. | arrayprefix DT_LABEL
  299. {
  300. $$.data = data_add_marker($1.data, LABEL, $2);
  301. }
  302. ;
  303. integer_prim:
  304. DT_LITERAL
  305. | DT_CHAR_LITERAL
  306. | '(' integer_expr ')'
  307. {
  308. $$ = $2;
  309. }
  310. ;
  311. integer_expr:
  312. integer_trinary
  313. ;
  314. integer_trinary:
  315. integer_or
  316. | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; }
  317. ;
  318. integer_or:
  319. integer_and
  320. | integer_or DT_OR integer_and { $$ = $1 || $3; }
  321. ;
  322. integer_and:
  323. integer_bitor
  324. | integer_and DT_AND integer_bitor { $$ = $1 && $3; }
  325. ;
  326. integer_bitor:
  327. integer_bitxor
  328. | integer_bitor '|' integer_bitxor { $$ = $1 | $3; }
  329. ;
  330. integer_bitxor:
  331. integer_bitand
  332. | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; }
  333. ;
  334. integer_bitand:
  335. integer_eq
  336. | integer_bitand '&' integer_eq { $$ = $1 & $3; }
  337. ;
  338. integer_eq:
  339. integer_rela
  340. | integer_eq DT_EQ integer_rela { $$ = $1 == $3; }
  341. | integer_eq DT_NE integer_rela { $$ = $1 != $3; }
  342. ;
  343. integer_rela:
  344. integer_shift
  345. | integer_rela '<' integer_shift { $$ = $1 < $3; }
  346. | integer_rela '>' integer_shift { $$ = $1 > $3; }
  347. | integer_rela DT_LE integer_shift { $$ = $1 <= $3; }
  348. | integer_rela DT_GE integer_shift { $$ = $1 >= $3; }
  349. ;
  350. integer_shift:
  351. integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; }
  352. | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; }
  353. | integer_add
  354. ;
  355. integer_add:
  356. integer_add '+' integer_mul { $$ = $1 + $3; }
  357. | integer_add '-' integer_mul { $$ = $1 - $3; }
  358. | integer_mul
  359. ;
  360. integer_mul:
  361. integer_mul '*' integer_unary { $$ = $1 * $3; }
  362. | integer_mul '/' integer_unary { $$ = $1 / $3; }
  363. | integer_mul '%' integer_unary { $$ = $1 % $3; }
  364. | integer_unary
  365. ;
  366. integer_unary:
  367. integer_prim
  368. | '-' integer_unary { $$ = -$2; }
  369. | '~' integer_unary { $$ = ~$2; }
  370. | '!' integer_unary { $$ = !$2; }
  371. ;
  372. bytestring:
  373. /* empty */
  374. {
  375. $$ = empty_data;
  376. }
  377. | bytestring DT_BYTE
  378. {
  379. $$ = data_append_byte($1, $2);
  380. }
  381. | bytestring DT_LABEL
  382. {
  383. $$ = data_add_marker($1, LABEL, $2);
  384. }
  385. ;
  386. subnodes:
  387. /* empty */
  388. {
  389. $$ = NULL;
  390. }
  391. | subnode subnodes
  392. {
  393. $$ = chain_node($1, $2);
  394. }
  395. | subnode propdef
  396. {
  397. ERROR(&@2, "Properties must precede subnodes");
  398. YYERROR;
  399. }
  400. ;
  401. subnode:
  402. DT_PROPNODENAME nodedef
  403. {
  404. $$ = name_node($2, $1);
  405. }
  406. | DT_DEL_NODE DT_PROPNODENAME ';'
  407. {
  408. $$ = name_node(build_node_delete(), $2);
  409. }
  410. | DT_LABEL subnode
  411. {
  412. add_label(&$2->labels, $1);
  413. $$ = $2;
  414. }
  415. ;
  416. %%
  417. void yyerror(char const *s)
  418. {
  419. ERROR(&yylloc, "%s", s);
  420. }