dtc-parser.y 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. %locations
  21. %{
  22. #include "dtc.h"
  23. #include "srcpos.h"
  24. int yylex(void);
  25. unsigned long long eval_literal(const char *s, int base, int bits);
  26. extern struct boot_info *the_boot_info;
  27. %}
  28. %union {
  29. char *propnodename;
  30. char *literal;
  31. char *labelref;
  32. unsigned int cbase;
  33. u8 byte;
  34. struct data data;
  35. u64 addr;
  36. cell_t cell;
  37. struct property *prop;
  38. struct property *proplist;
  39. struct node *node;
  40. struct node *nodelist;
  41. struct reserve_info *re;
  42. }
  43. %token DT_V1
  44. %token DT_MEMRESERVE
  45. %token <propnodename> DT_PROPNODENAME
  46. %token <literal> DT_LITERAL
  47. %token <literal> DT_LEGACYLITERAL
  48. %token <cbase> DT_BASE
  49. %token <byte> DT_BYTE
  50. %token <data> DT_STRING
  51. %token <labelref> DT_LABEL
  52. %token <labelref> DT_REF
  53. %type <data> propdata
  54. %type <data> propdataprefix
  55. %type <re> memreserve
  56. %type <re> memreserves
  57. %type <re> v0_memreserve
  58. %type <re> v0_memreserves
  59. %type <addr> addr
  60. %type <data> celllist
  61. %type <cbase> cellbase
  62. %type <cell> cellval
  63. %type <data> bytestring
  64. %type <prop> propdef
  65. %type <proplist> proplist
  66. %type <node> devicetree
  67. %type <node> nodedef
  68. %type <node> subnode
  69. %type <nodelist> subnodes
  70. %type <labelref> label
  71. %%
  72. sourcefile:
  73. DT_V1 ';' memreserves devicetree
  74. {
  75. the_boot_info = build_boot_info($3, $4);
  76. }
  77. | v0_memreserves devicetree
  78. {
  79. the_boot_info = build_boot_info($1, $2);
  80. }
  81. ;
  82. memreserves:
  83. /* empty */
  84. {
  85. $$ = NULL;
  86. }
  87. | memreserve memreserves
  88. {
  89. $$ = chain_reserve_entry($1, $2);
  90. }
  91. ;
  92. memreserve:
  93. label DT_MEMRESERVE addr addr ';'
  94. {
  95. $$ = build_reserve_entry($3, $4, $1);
  96. }
  97. ;
  98. v0_memreserves:
  99. /* empty */
  100. {
  101. $$ = NULL;
  102. }
  103. | v0_memreserve v0_memreserves
  104. {
  105. $$ = chain_reserve_entry($1, $2);
  106. };
  107. ;
  108. v0_memreserve:
  109. memreserve
  110. {
  111. $$ = $1;
  112. }
  113. | label DT_MEMRESERVE addr '-' addr ';'
  114. {
  115. $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
  116. }
  117. ;
  118. addr:
  119. DT_LITERAL
  120. {
  121. $$ = eval_literal($1, 0, 64);
  122. }
  123. | DT_LEGACYLITERAL
  124. {
  125. $$ = eval_literal($1, 16, 64);
  126. }
  127. ;
  128. devicetree:
  129. '/' nodedef
  130. {
  131. $$ = name_node($2, "", NULL);
  132. }
  133. ;
  134. nodedef:
  135. '{' proplist subnodes '}' ';'
  136. {
  137. $$ = build_node($2, $3);
  138. }
  139. ;
  140. proplist:
  141. /* empty */
  142. {
  143. $$ = NULL;
  144. }
  145. | proplist propdef
  146. {
  147. $$ = chain_property($2, $1);
  148. }
  149. ;
  150. propdef:
  151. label DT_PROPNODENAME '=' propdata ';'
  152. {
  153. $$ = build_property($2, $4, $1);
  154. }
  155. | label DT_PROPNODENAME ';'
  156. {
  157. $$ = build_property($2, empty_data, $1);
  158. }
  159. ;
  160. propdata:
  161. propdataprefix DT_STRING
  162. {
  163. $$ = data_merge($1, $2);
  164. }
  165. | propdataprefix '<' celllist '>'
  166. {
  167. $$ = data_merge($1, $3);
  168. }
  169. | propdataprefix '[' bytestring ']'
  170. {
  171. $$ = data_merge($1, $3);
  172. }
  173. | propdataprefix DT_REF
  174. {
  175. $$ = data_add_marker($1, REF_PATH, $2);
  176. }
  177. | propdata DT_LABEL
  178. {
  179. $$ = data_add_marker($1, LABEL, $2);
  180. }
  181. ;
  182. propdataprefix:
  183. /* empty */
  184. {
  185. $$ = empty_data;
  186. }
  187. | propdata ','
  188. {
  189. $$ = $1;
  190. }
  191. | propdataprefix DT_LABEL
  192. {
  193. $$ = data_add_marker($1, LABEL, $2);
  194. }
  195. ;
  196. celllist:
  197. /* empty */
  198. {
  199. $$ = empty_data;
  200. }
  201. | celllist cellval
  202. {
  203. $$ = data_append_cell($1, $2);
  204. }
  205. | celllist DT_REF
  206. {
  207. $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
  208. $2), -1);
  209. }
  210. | celllist DT_LABEL
  211. {
  212. $$ = data_add_marker($1, LABEL, $2);
  213. }
  214. ;
  215. cellbase:
  216. /* empty */
  217. {
  218. $$ = 16;
  219. }
  220. | DT_BASE
  221. ;
  222. cellval:
  223. DT_LITERAL
  224. {
  225. $$ = eval_literal($1, 0, 32);
  226. }
  227. | cellbase DT_LEGACYLITERAL
  228. {
  229. $$ = eval_literal($2, $1, 32);
  230. }
  231. ;
  232. bytestring:
  233. /* empty */
  234. {
  235. $$ = empty_data;
  236. }
  237. | bytestring DT_BYTE
  238. {
  239. $$ = data_append_byte($1, $2);
  240. }
  241. | bytestring DT_LABEL
  242. {
  243. $$ = data_add_marker($1, LABEL, $2);
  244. }
  245. ;
  246. subnodes:
  247. /* empty */
  248. {
  249. $$ = NULL;
  250. }
  251. | subnode subnodes
  252. {
  253. $$ = chain_node($1, $2);
  254. }
  255. | subnode propdef
  256. {
  257. yyerror("syntax error: properties must precede subnodes\n");
  258. YYERROR;
  259. }
  260. ;
  261. subnode:
  262. label DT_PROPNODENAME nodedef
  263. {
  264. $$ = name_node($3, $2, $1);
  265. }
  266. ;
  267. label:
  268. /* empty */
  269. {
  270. $$ = NULL;
  271. }
  272. | DT_LABEL
  273. {
  274. $$ = $1;
  275. }
  276. ;
  277. %%
  278. void yyerror (char const *s)
  279. {
  280. const char *fname = srcpos_filename_for_num(yylloc.filenum);
  281. if (strcmp(fname, "-") == 0)
  282. fname = "stdin";
  283. fprintf(stderr, "%s:%d %s\n",
  284. fname, yylloc.first_line, s);
  285. }
  286. unsigned long long eval_literal(const char *s, int base, int bits)
  287. {
  288. unsigned long long val;
  289. char *e;
  290. errno = 0;
  291. val = strtoull(s, &e, base);
  292. if (*e)
  293. yyerror("bad characters in literal");
  294. else if ((errno == ERANGE)
  295. || ((bits < 64) && (val >= (1ULL << bits))))
  296. yyerror("literal out of range");
  297. else if (errno != 0)
  298. yyerror("bad literal");
  299. return val;
  300. }