Transition to C-style literals (cut the next)
cover Transition to C-style literals (cut the next)
Here's a new version of my patches to switch us over to dts-v1 and C-style literals. This version addresses some of the problems Jon pointed out with the last version, and adds some polish in the last patch which enables dts-v1 output for -Odts mode.
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 1/3 dtc: Simplify lexing/parsing of literals vs. node/property names
The current scheme of having CELLDATA and MEMRESERVE states to recognize hex literals instead of node or property names is arse-backwards. The patch switches things around so that literals are lexed in normal states, and property/node names are only recognized in the special PROPNODENAME state, which is only entered after a { or a ;, and is left as soon as we scan a property/node name or a keyword.
--- dtc-lexer.l | 105 +++++++++++--------------------------------------- dtc-parser.y | 123 ++++++++++++++++++++++++++--------------------------------- 2 files changed, 80 insertions(+), 148 deletions(-)
dtc-lexer.l +29 -80
@@ -21,9 +21,8 @@ %option noyywrap nounput yylineno %x INCLUDE -%x CELLDATA %x BYTESTRING -%x MEMRESERVE +%x PROPNODENAME PROPCHAR [a-zA-Z0-9,._+*#?-] UNITCHAR [0-9a-f,]
@@ -51,7 +50,7 @@ %% -"/include/" BEGIN(INCLUDE); +<*>"/include/" BEGIN(INCLUDE); <INCLUDE>\"[^"\n]*\" { yytext[strlen(yytext) - 1] = 0;
@@ -63,13 +62,13 @@ } -<<EOF>> { +<*><<EOF>> { if (!pop_input_file()) { yyterminate(); } } -\"([^\\"]|\\.)*\" { +<*>\"([^\\"]|\\.)*\" { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("String: %s\n", yytext);
@@ -79,45 +78,24 @@ return DT_STRING; } -"/memreserve/" { +<*>"/memreserve/" { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); - BEGIN(MEMRESERVE); - return DT_MEMRESERVE; - } - -<MEMRESERVE>[0-9a-fA-F]+ { - yylloc.filenum = srcpos_filenum; - yylloc.first_line = yylineno; - if (yyleng > 2*sizeof(yylval.addr)) { - fprintf(stderr, "Address value %s too large\n", - yytext); - } - yylval.addr = (u64) strtoull(yytext, NULL, 16); - DPRINT("Addr: %llx\n", - (unsigned long long)yylval.addr); - return DT_ADDR; - } - -<MEMRESERVE>";" { - yylloc.filenum = srcpos_filenum; - yylloc.first_line = yylineno; - DPRINT("/MEMRESERVE\n"); BEGIN(INITIAL); - return ';'; + return DT_MEMRESERVE; } <*>[a-zA-Z_][a-zA-Z0-9_]*: { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Label: %s\n", yytext); - yylval.str = strdup(yytext); - yylval.str[yyleng-1] = '\0'; + yylval.labelref = strdup(yytext); + yylval.labelref[yyleng-1] = '\0'; return DT_LABEL; } -<CELLDATA>[bodh]# { +[bodh]# { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; if (*yytext == 'b')
@@ -132,27 +110,19 @@ return DT_BASE; } -<CELLDATA>[0-9a-fA-F]+ { - yylloc.filenum = srcpos_filenum; - yylloc.first_line = yylineno; - yylval.str = strdup(yytext); - DPRINT("Cell: '%s'\n", yylval.str); - return DT_CELL; - } - -<CELLDATA>">" { +[0-9a-fA-F]+ { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; - DPRINT("/CELLDATA\n"); - BEGIN(INITIAL); - return '>'; + yylval.literal = strdup(yytext); + DPRINT("Literal: '%s'\n", yylval.literal); + return DT_LITERAL; } -<CELLDATA>\&{REFCHAR}* { +\&{REFCHAR}* { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Ref: %s\n", yytext+1); - yylval.str = strdup(yytext+1); + yylval.labelref = strdup(yytext+1); return DT_REF; }
@@ -172,30 +142,13 @@ return ']'; } -, { /* Technically this is a valid property name, - but we'd rather use it as punctuation, so detect it - here in preference */ +<PROPNODENAME>{PROPCHAR}+(@{UNITCHAR}+)? { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; - DPRINT("Char (propname like): %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); - return yytext[0]; - } - -{PROPCHAR}+ { - yylloc.filenum = srcpos_filenum; - yylloc.first_line = yylineno; - DPRINT("PropName: %s\n", yytext); - yylval.str = strdup(yytext); - return DT_PROPNAME; - } - -{PROPCHAR}+(@{UNITCHAR}+)? { - yylloc.filenum = srcpos_filenum; - yylloc.first_line = yylineno; - DPRINT("NodeName: %s\n", yytext); - yylval.str = strdup(yytext); - return DT_NODENAME; + DPRINT("PropNodeName: %s\n", yytext); + yylval.propnodename = strdup(yytext); + BEGIN(INITIAL); + return DT_PROPNODENAME; }
@@ -213,21 +166,17 @@ <*>. { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; - switch (yytext[0]) { - case '<': - DPRINT("CELLDATA\n"); - BEGIN(CELLDATA); - break; - case '[': - DPRINT("BYTESTRING\n"); - BEGIN(BYTESTRING); - break; - default: - + if (yytext[0] == '[') { + DPRINT("<BYTESTRING>\n"); + BEGIN(BYTESTRING); + } + if ((yytext[0] == '{') + || (yytext[0] == ';')) { + DPRINT("<PROPNODENAME>\n"); + BEGIN(PROPNODENAME); + } DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); - break; - } return yytext[0]; }
dtc-parser.y +55 -68
220 lines not on this page · raw message
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 2/3 dtc: Switch dtc to C-style literals
In reply to David Gibsondtc: Switch dtc to C-style literals
This patch introduces a new version of dts file, distinguished from older files by starting with the special token /dts-v1/. dts files in the new version take C-style literals instead of the old bare hex or OF-style base notation. In addition, the "range" for of memreserve entries (/memreserve/ f0000-fffff) is no longer recognized in the new format.
--- dtc-lexer.l | 40 ++++++++++++++++++++++++++++++++-------- dtc-parser.y | 38 ++++++++++++++++++++++++++++++++++++-- tests/run_tests.sh | 4 ++++ tests/test_tree1.dts | 14 ++++++++------ tests/test_tree1_dts0.dts | 27 +++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 16 deletions(-)
dtc-lexer.l +32 -8
@@ -23,6 +23,7 @@ %x INCLUDE %x BYTESTRING %x PROPNODENAME +%s V1 PROPCHAR [a-zA-Z0-9,._+*#?-] UNITCHAR [0-9a-f,]
@@ -44,12 +45,18 @@ #define DPRINT(fmt, ...) do { } while (0) #endif +static int dts_version; /* = 0 */ - +#define BEGIN_DEFAULT() if (dts_version == 0) { \ + DPRINT("<INITIAL>\n"); \ + BEGIN(INITIAL); \ + } else { \ + DPRINT("<V1>\n"); \ + BEGIN(V1); \ + } %} %% - <*>"/include/" BEGIN(INCLUDE); <INCLUDE>\"[^"\n]*\" {
@@ -58,7 +65,7 @@ /* Some unrecoverable error.*/ exit(1); } - BEGIN(INITIAL); + BEGIN_DEFAULT(); }
@@ -78,11 +85,20 @@ return DT_STRING; } +<*>"/dts-v1/" { + yylloc.filenum = srcpos_filenum; + yylloc.first_line = yylineno; + DPRINT("Keyword: /dts-v1/\n"); + dts_version = 1; + BEGIN_DEFAULT(); + return DT_V1; + } + <*>"/memreserve/" { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("Keyword: /memreserve/\n"); - BEGIN(INITIAL); + BEGIN_DEFAULT(); return DT_MEMRESERVE; }
@@ -95,7 +111,7 @@ return DT_LABEL; } -[bodh]# { +<INITIAL>[bodh]# { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; if (*yytext == 'b')
@@ -110,7 +126,15 @@ return DT_BASE; } -[0-9a-fA-F]+ { +<INITIAL>[0-9a-fA-F]+ { + yylloc.filenum = srcpos_filenum; + yylloc.first_line = yylineno; + yylval.literal = strdup(yytext); + DPRINT("Literal: '%s'\n", yylval.literal); + return DT_LEGACYLITERAL; + } + +<V1>[0-9]+|0[xX][0-9a-fA-F]+ { yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; yylval.literal = strdup(yytext);
@@ -138,7 +162,7 @@ yylloc.filenum = srcpos_filenum; yylloc.first_line = yylineno; DPRINT("/BYTESTRING\n"); - BEGIN(INITIAL); + BEGIN_DEFAULT(); return ']'; }
@@ -147,7 +171,7 @@ yylloc.first_line = yylineno; DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = strdup(yytext); - BEGIN(INITIAL); + BEGIN_DEFAULT(); return DT_PROPNODENAME; }
dtc-parser.y +36 -2
@@ -48,9 +48,11 @@ struct reserve_info *re; } +%token DT_V1 %token DT_MEMRESERVE %token <propnodename> DT_PROPNODENAME %token <literal> DT_LITERAL +%token <literal> DT_LEGACYLITERAL %token <cbase> DT_BASE %token <byte> DT_BYTE %token <data> DT_STRING
@@ -61,6 +63,8 @@ %type <data> propdataprefix %type <re> memreserve %type <re> memreserves +%type <re> v0_memreserve +%type <re> v0_memreserves %type <addr> addr %type <data> celllist %type <cbase> cellbase
@@ -78,7 +82,11 @@ %% sourcefile: - memreserves devicetree + DT_V1 ';' memreserves devicetree + { + the_boot_info = build_boot_info($3, $4); + } + | v0_memreserves devicetree { the_boot_info = build_boot_info($1, $2); }
@@ -100,6 +108,24 @@ { $$ = build_reserve_entry($3, $4, $1); } + ; + +v0_memreserves: + /* empty */ + { + $$ = NULL; + } + | v0_memreserve v0_memreserves + { + $$ = chain_reserve_entry($1, $2); + }; + ; + +v0_memreserve: + memreserve + { + $$ = $1; + } | label DT_MEMRESERVE addr '-' addr ';' { $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
@@ -108,6 +134,10 @@ addr: DT_LITERAL + { + $$ = eval_literal($1, 0, 64); + } + | DT_LEGACYLITERAL { $$ = eval_literal($1, 16, 64); }
@@ -211,7 +241,11 @@ ; cellval: - cellbase DT_LITERAL + DT_LITERAL + { + $$ = eval_literal($1, 0, 32); + } + | cellbase DT_LEGACYLITERAL { $$ = eval_literal($2, $1, 32); }
tests/run_tests.sh +4 -0
@@ -124,6 +124,10 @@ tree1_tests_rw dtc_tree1.test.dtb run_test dtbs_equal_ordered dtc_tree1.test.dtb test_tree1.dtb + run_test dtc.sh -I dts -O dtb -o dtc_tree1_dts0.test.dtb test_tree1_dts0.dts + tree1_tests dtc_tree1_dts0.test.dtb + tree1_tests_rw dtc_tree1_dts0.test.dtb + run_test dtc.sh -I dts -O dtb -o dtc_escapes.test.dtb escapes.dts run_test string_escapes dtc_escapes.test.dtb
tests/test_tree1.dts +8 -6
@@ -1,9 +1,11 @@ -/memreserve/ deadbeef00000000-deadbeef000fffff; -/memreserve/ 75bcd15 1000; +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; / { compatible = "test_tree1"; - prop-int = <deadbeef>; + prop-int = <0xdeadbeef>; prop-str = "hello world"; subnode@1 {
@@ -12,16 +14,16 @@ subsubnode { compatible = "subsubnode1", "subsubnode"; - prop-int = <h# deadbeef>; + prop-int = <0xdeadbeef>; }; }; subnode@2 { - prop-int = <d# 123456789>; + prop-int = <123456789>; subsubnode@0 { compatible = "subsubnode2", "subsubnode"; - prop-int = <o# 0726746425>; + prop-int = <0726746425>; }; }; };
tests/test_tree1_dts0.dts new file +27 -0
@@ -0,0 +1,27 @@ +/memreserve/ deadbeef00000000-deadbeef000fffff; +/memreserve/ 75bcd15 1000; + +/ { + compatible = "test_tree1"; + prop-int = <deadbeef>; + prop-str = "hello world"; + + subnode@1 { + compatible = "subnode1"; + prop-int = [deadbeef]; + + subsubnode { + compatible = "subsubnode1", "subsubnode"; + prop-int = <h# deadbeef>; + }; + }; + + subnode@2 { + prop-int = <d# 123456789>; + + subsubnode@0 { + compatible = "subsubnode2", "subsubnode"; + prop-int = <o# 0726746425>; + }; + }; +};
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
PATCH 3/3 dtc: -Odts produces v1 output
In reply to David GibsonThis patch alters the -Odts mode output so that it uses dts-v1 format. This means that dtc -Idts -Odts used on a v0 dts file will convert that file to v1.
--- treesource.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
treesource.c +5 -3
@@ -141,7 +141,7 @@ l = l->next; } -fprintf (f,"%x" ,be32_to_cpu (*cp++)); +fprintf (f,"0x%x" ,be32_to_cpu (*cp++));if ((void *)cp >= propend)break ;fprintf (f," " );
@@ -258,12 +258,14 @@ {struct reserve_info *re; +fprintf (f,"/dts-v1/;\n\n" ); +for (re = bi->reservelist; re; re = re->next) {if (re->label)fprintf (f,"%s: " , re->label); -fprintf (f,"/memreserve/\t%016llx-%016llx;\n" , +fprintf (f,"/memreserve/\t0x%016llx 0x%016llx;\n" , (unsigned long long )re->re.address, - (unsigned long long )(re->re.address + re->re.size -1 )); + (unsigned long long )re->re.size); }write_tree_source_node (f, bi->dt,0 );
Signature · 4 lines
David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson