scripts/dtc: Update to upstream version v1.4.5-3-gb1a60033c110

This adds the following commits from upstream:

b1a6003 tests: Add a test for overlays syntactic sugar
737b2df overlay: Add syntactic sugar version of overlays
497432f checks: Use proper format modifier for size_t
22a65c5 dtc: Bump version to v1.4.5
c575d80 Add fdtoverlay to .gitignore
b6a6f94 fdtoverlay: Sanity check blob size
8c1eb15 pylibfdt: Use Python2 explicitly
ee3d26f checks: add interrupts property check
c1e7738 checks: add gpio binding properties check
b3bbac0 checks: add phandle with arg property checks

[ sync with Linux commit: 4201d057ea91c3d6efd2db65219bc91fae413bc2 ]

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
master
Masahiro Yamada 7 years ago committed by Tom Rini
parent 0d82161823
commit 999a78d5cf
  1. 280
      scripts/dtc/checks.c
  2. 216
      scripts/dtc/dtc-lexer.lex.c_shipped
  3. 464
      scripts/dtc/dtc-parser.tab.c_shipped
  4. 8
      scripts/dtc/dtc-parser.tab.h_shipped
  5. 20
      scripts/dtc/dtc-parser.y
  6. 2
      scripts/dtc/dtc.h
  7. 96
      scripts/dtc/libfdt/fdt_addresses.c
  8. 861
      scripts/dtc/libfdt/fdt_overlay.c
  9. 28
      scripts/dtc/livetree.c
  10. 2
      scripts/dtc/version_gen.h

@ -956,6 +956,265 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
WARNING(obsolete_chosen_interrupt_controller,
check_obsolete_chosen_interrupt_controller, NULL);
struct provider {
const char *prop_name;
const char *cell_name;
bool optional;
};
static void check_property_phandle_args(struct check *c,
struct dt_info *dti,
struct node *node,
struct property *prop,
const struct provider *provider)
{
struct node *root = dti->dt;
int cell, cellsize = 0;
if (prop->val.len % sizeof(cell_t)) {
FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
return;
}
for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
struct node *provider_node;
struct property *cellprop;
int phandle;
phandle = propval_cell_n(prop, cell);
/*
* Some bindings use a cell value 0 or -1 to skip over optional
* entries when each index position has a specific definition.
*/
if (phandle == 0 || phandle == -1) {
cellsize = 0;
continue;
}
/* If we have markers, verify the current cell is a phandle */
if (prop->val.markers) {
struct marker *m = prop->val.markers;
for_each_marker_of_type(m, REF_PHANDLE) {
if (m->offset == (cell * sizeof(cell_t)))
break;
}
if (!m)
FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
prop->name, cell, node->fullpath);
}
provider_node = get_node_by_phandle(root, phandle);
if (!provider_node) {
FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
node->fullpath, prop->name, cell);
break;
}
cellprop = get_property(provider_node, provider->cell_name);
if (cellprop) {
cellsize = propval_cell(cellprop);
} else if (provider->optional) {
cellsize = 0;
} else {
FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
provider->cell_name,
provider_node->fullpath,
node->fullpath, prop->name, cell);
break;
}
if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
prop->name, prop->val.len, cellsize, node->fullpath);
}
}
}
static void check_provider_cells_property(struct check *c,
struct dt_info *dti,
struct node *node)
{
struct provider *provider = c->data;
struct property *prop;
prop = get_property(node, provider->prop_name);
if (!prop)
return;
check_property_phandle_args(c, dti, node, prop, provider);
}
#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
static bool prop_is_gpio(struct property *prop)
{
char *str;
/*
* *-gpios and *-gpio can appear in property names,
* so skip over any false matches (only one known ATM)
*/
if (strstr(prop->name, "nr-gpio"))
return false;
str = strrchr(prop->name, '-');
if (str)
str++;
else
str = prop->name;
if (!(streq(str, "gpios") || streq(str, "gpio")))
return false;
return true;
}
static void check_gpios_property(struct check *c,
struct dt_info *dti,
struct node *node)
{
struct property *prop;
/* Skip GPIO hog nodes which have 'gpios' property */
if (get_property(node, "gpio-hog"))
return;
for_each_property(node, prop) {
struct provider provider;
if (!prop_is_gpio(prop))
continue;
provider.prop_name = prop->name;
provider.cell_name = "#gpio-cells";
provider.optional = false;
check_property_phandle_args(c, dti, node, prop, &provider);
}
}
WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
static void check_deprecated_gpio_property(struct check *c,
struct dt_info *dti,
struct node *node)
{
struct property *prop;
for_each_property(node, prop) {
char *str;
if (!prop_is_gpio(prop))
continue;
str = strstr(prop->name, "gpio");
if (!streq(str, "gpio"))
continue;
FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
node->fullpath, prop->name);
}
}
CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
static bool node_is_interrupt_provider(struct node *node)
{
struct property *prop;
prop = get_property(node, "interrupt-controller");
if (prop)
return true;
prop = get_property(node, "interrupt-map");
if (prop)
return true;
return false;
}
static void check_interrupts_property(struct check *c,
struct dt_info *dti,
struct node *node)
{
struct node *root = dti->dt;
struct node *irq_node = NULL, *parent = node;
struct property *irq_prop, *prop = NULL;
int irq_cells, phandle;
irq_prop = get_property(node, "interrupts");
if (!irq_prop)
return;
if (irq_prop->val.len % sizeof(cell_t))
FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
irq_prop->name, irq_prop->val.len, sizeof(cell_t),
node->fullpath);
while (parent && !prop) {
if (parent != node && node_is_interrupt_provider(parent)) {
irq_node = parent;
break;
}
prop = get_property(parent, "interrupt-parent");
if (prop) {
phandle = propval_cell(prop);
irq_node = get_node_by_phandle(root, phandle);
if (!irq_node) {
FAIL(c, dti, "Bad interrupt-parent phandle for %s",
node->fullpath);
return;
}
if (!node_is_interrupt_provider(irq_node))
FAIL(c, dti,
"Missing interrupt-controller or interrupt-map property in %s",
irq_node->fullpath);
break;
}
parent = parent->parent;
}
if (!irq_node) {
FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
return;
}
prop = get_property(irq_node, "#interrupt-cells");
if (!prop) {
FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
irq_node->fullpath);
return;
}
irq_cells = propval_cell(prop);
if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
FAIL(c, dti,
"interrupts size is (%d), expected multiple of %d in %s",
irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
node->fullpath);
}
}
WARNING(interrupts_property, check_interrupts_property, &phandle_references);
static struct check *check_table[] = {
&duplicate_node_names, &duplicate_property_names,
&node_name_chars, &node_name_format, &property_name_chars,
@ -987,6 +1246,27 @@ static struct check *check_table[] = {
&avoid_default_addr_size,
&obsolete_chosen_interrupt_controller,
&clocks_property,
&cooling_device_property,
&dmas_property,
&hwlocks_property,
&interrupts_extended_property,
&io_channels_property,
&iommus_property,
&mboxes_property,
&msi_parent_property,
&mux_controls_property,
&phys_property,
&power_domains_property,
&pwms_property,
&resets_property,
&sound_dais_property,
&thermal_sensors_property,
&deprecated_gpio_property,
&gpios_property,
&interrupts_property,
&always_fail,
};

@ -8,8 +8,8 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 35
#define YY_FLEX_MINOR_VERSION 6
#define YY_FLEX_SUBMINOR_VERSION 1
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
@ -88,25 +88,13 @@ typedef unsigned int flex_uint32_t;
#endif /* ! FLEXINT_H */
#ifdef __cplusplus
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#else /* ! __cplusplus */
/* C99 requires __STDC__ to be defined as 1. */
#if defined (__STDC__)
#define YY_USE_CONST
#endif /* defined (__STDC__) */
#endif /* ! __cplusplus */
#ifdef YY_USE_CONST
/* TODO: this is always defined, so inline it */
#define yyconst const
#if defined(__GNUC__) && __GNUC__ >= 3
#define yynoreturn __attribute__((__noreturn__))
#else
#define yyconst
#define yynoreturn
#endif
/* Returned upon end-of-file. */
@ -162,6 +150,11 @@ typedef unsigned int flex_uint32_t;
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
extern int yyleng;
extern FILE *yyin, *yyout;
@ -171,6 +164,7 @@ extern FILE *yyin, *yyout;
#define EOB_ACT_LAST_MATCH 2
#define YY_LESS_LINENO(n)
#define YY_LINENO_REWIND_TO(ptr)
/* Return all but the first "n" matched characters back to the input stream. */
#define yyless(n) \
@ -188,11 +182,6 @@ extern FILE *yyin, *yyout;
#define unput(c) yyunput( c, (yytext_ptr) )
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
@ -205,7 +194,7 @@ struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
yy_size_t yy_buf_size;
int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
@ -233,7 +222,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@ -261,7 +250,7 @@ struct yy_buffer_state
/* Stack of input buffers. */
static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
/* We provide macros for accessing buffer states in case in the
* future we want to put the buffer states in a more general
@ -284,7 +273,7 @@ static int yy_n_chars; /* number of characters read into yy_ch_buf */
int yyleng;
/* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0;
static char *yy_c_buf_p = NULL;
static int yy_init = 0; /* whether we need to initialize */
static int yy_start = 0; /* start state number */
@ -341,12 +330,12 @@ void yyfree (void * );
/* Begin user sect3 */
#define yywrap(n) 1
#define yywrap() (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
typedef unsigned char YY_CHAR;
FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
FILE *yyin = NULL, *yyout = NULL;
typedef int yy_state_type;
@ -355,19 +344,22 @@ extern int yylineno;
int yylineno = 1;
extern char *yytext;
#ifdef yytext_ptr
#undef yytext_ptr
#endif
#define yytext_ptr yytext
static yy_state_type yy_get_previous_state (void );
static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
static int yy_get_next_buffer (void );
static void yy_fatal_error (yyconst char msg[] );
static void yynoreturn yy_fatal_error (yyconst char* msg );
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
(yytext_ptr) = yy_bp; \
yyleng = (size_t) (yy_cp - yy_bp); \
yyleng = (int) (yy_cp - yy_bp); \
(yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp;
@ -403,7 +395,7 @@ static yyconst flex_int16_t yy_accept[166] =
0, 0, 0, 8, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
static yyconst YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
4, 4, 4, 1, 1, 1, 1, 1, 1, 1,
@ -435,7 +427,7 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
static yyconst flex_int32_t yy_meta[48] =
static yyconst YY_CHAR yy_meta[48] =
{ 0,
1, 1, 1, 1, 1, 1, 2, 3, 1, 2,
2, 2, 4, 5, 5, 5, 6, 1, 1, 1,
@ -444,7 +436,7 @@ static yyconst flex_int32_t yy_meta[48] =
8, 8, 8, 8, 3, 1, 4
} ;
static yyconst flex_int16_t yy_base[180] =
static yyconst flex_uint16_t yy_base[180] =
{ 0,
0, 393, 35, 392, 66, 391, 38, 107, 397, 401,
55, 113, 377, 112, 111, 111, 114, 42, 376, 106,
@ -490,7 +482,7 @@ static yyconst flex_int16_t yy_def[180] =
165, 165, 165, 165, 165, 165, 165, 165, 165
} ;
static yyconst flex_int16_t yy_nxt[449] =
static yyconst flex_uint16_t yy_nxt[449] =
{ 0,
10, 11, 12, 11, 13, 14, 10, 15, 16, 10,
10, 10, 17, 10, 10, 10, 10, 18, 19, 20,
@ -665,7 +657,7 @@ static void push_input_file(const char *filename);
static bool pop_input_file(void);
static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
#line 669 "dtc-lexer.lex.c"
#line 661 "dtc-lexer.lex.c"
#define INITIAL 0
#define BYTESTRING 1
@ -701,19 +693,19 @@ void yyset_extra (YY_EXTRA_TYPE user_defined );
FILE *yyget_in (void );
void yyset_in (FILE * in_str );
void yyset_in (FILE * _in_str );
FILE *yyget_out (void );
void yyset_out (FILE * out_str );
void yyset_out (FILE * _out_str );
int yyget_leng (void );
int yyget_leng (void );
char *yyget_text (void );
int yyget_lineno (void );
void yyset_lineno (int line_number );
void yyset_lineno (int _line_number );
/* Macros after this point can all be overridden by user definitions in
* section 1.
@ -727,6 +719,10 @@ extern int yywrap (void );
#endif
#endif
#ifndef YY_NO_UNPUT
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy (char *,yyconst char *,int );
#endif
@ -760,7 +756,7 @@ static int input (void );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@ -784,7 +780,7 @@ static int input (void );
else \
{ \
errno=0; \
while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@ -839,7 +835,7 @@ extern int yylex (void);
/* Code executed at the end of each rule. */
#ifndef YY_BREAK
#define YY_BREAK break;
#define YY_BREAK /*LINTED*/break;
#endif
#define YY_RULE_SETUP \
@ -852,14 +848,10 @@ extern int yylex (void);
*/
YY_DECL
{
register yy_state_type yy_current_state;
register char *yy_cp, *yy_bp;
register int yy_act;
yy_state_type yy_current_state;
char *yy_cp, *yy_bp;
int yy_act;
#line 69 "dtc-lexer.l"
#line 862 "dtc-lexer.lex.c"
if ( !(yy_init) )
{
(yy_init) = 1;
@ -886,7 +878,12 @@ YY_DECL
yy_load_buffer_state( );
}
while ( 1 ) /* loops until end-of-file is reached */
{
#line 69 "dtc-lexer.l"
#line 885 "dtc-lexer.lex.c"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
yy_cp = (yy_c_buf_p);
@ -903,7 +900,7 @@ YY_DECL
yy_match:
do
{
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
if ( yy_accept[yy_current_state] )
{
(yy_last_accepting_state) = yy_current_state;
@ -915,7 +912,7 @@ yy_match:
if ( yy_current_state >= 166 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++yy_cp;
}
while ( yy_current_state != 165 );
@ -1256,7 +1253,7 @@ YY_RULE_SETUP
#line 272 "dtc-lexer.l"
ECHO;
YY_BREAK
#line 1260 "dtc-lexer.lex.c"
#line 1257 "dtc-lexer.lex.c"
case YY_END_OF_BUFFER:
{
@ -1386,6 +1383,7 @@ ECHO;
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
} /* end of user's declarations */
} /* end of yylex */
/* yy_get_next_buffer - try to read in a new buffer
@ -1397,9 +1395,9 @@ ECHO;
*/
static int yy_get_next_buffer (void)
{
register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
register char *source = (yytext_ptr);
register int number_to_move, i;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = (yytext_ptr);
int number_to_move, i;
int ret_val;
if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@ -1428,7 +1426,7 @@ static int yy_get_next_buffer (void)
/* Try to read more data. */
/* First move last chars to start of buffer. */
number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@ -1448,7 +1446,7 @@ static int yy_get_next_buffer (void)
{ /* Not enough room in the buffer - grow it. */
/* just a shorter name for the current buffer */
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
int yy_c_buf_p_offset =
(int) ((yy_c_buf_p) - b->yy_ch_buf);
@ -1468,7 +1466,7 @@ static int yy_get_next_buffer (void)
}
else
/* Can't grow it, we don't own it. */
b->yy_ch_buf = 0;
b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@ -1486,7 +1484,7 @@ static int yy_get_next_buffer (void)
/* Read in more data. */
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
(yy_n_chars), (size_t) num_to_read );
(yy_n_chars), num_to_read );
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
@ -1510,9 +1508,9 @@ static int yy_get_next_buffer (void)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@ -1531,15 +1529,15 @@ static int yy_get_next_buffer (void)
static yy_state_type yy_get_previous_state (void)
{
register yy_state_type yy_current_state;
register char *yy_cp;
yy_state_type yy_current_state;
char *yy_cp;
yy_current_state = (yy_start);
yy_current_state += YY_AT_BOL();
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
{
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
if ( yy_accept[yy_current_state] )
{
(yy_last_accepting_state) = yy_current_state;
@ -1551,7 +1549,7 @@ static int yy_get_next_buffer (void)
if ( yy_current_state >= 166 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
}
return yy_current_state;
@ -1564,10 +1562,10 @@ static int yy_get_next_buffer (void)
*/
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
{
register int yy_is_jam;
register char *yy_cp = (yy_c_buf_p);
int yy_is_jam;
char *yy_cp = (yy_c_buf_p);
register YY_CHAR yy_c = 1;
YY_CHAR yy_c = 1;
if ( yy_accept[yy_current_state] )
{
(yy_last_accepting_state) = yy_current_state;
@ -1579,12 +1577,16 @@ static int yy_get_next_buffer (void)
if ( yy_current_state >= 166 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
yy_is_jam = (yy_current_state == 165);
return yy_is_jam ? 0 : yy_current_state;
return yy_is_jam ? 0 : yy_current_state;
}
#ifndef YY_NO_UNPUT
#endif
#ifndef YY_NO_INPUT
#ifdef __cplusplus
static int yyinput (void)
@ -1633,7 +1635,7 @@ static int yy_get_next_buffer (void)
case EOB_ACT_END_OF_FILE:
{
if ( yywrap( ) )
return EOF;
return 0;
if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE;
@ -1736,7 +1738,7 @@ static void yy_load_buffer_state (void)
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_buf_size = size;
b->yy_buf_size = (yy_size_t)size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
@ -1891,15 +1893,15 @@ static void yyensure_buffer_stack (void)
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
num_to_alloc = 1;
num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
);
if ( ! (yy_buffer_stack) )
YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
(yy_buffer_stack_max) = num_to_alloc;
(yy_buffer_stack_top) = 0;
return;
@ -1908,7 +1910,7 @@ static void yyensure_buffer_stack (void)
if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
/* Increase the buffer to prepare for a possible push. */
int grow_size = 8 /* arbitrary grow size */;
yy_size_t grow_size = 8 /* arbitrary grow size */;
num_to_alloc = (yy_buffer_stack_max) + grow_size;
(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
@ -1928,7 +1930,7 @@ static void yyensure_buffer_stack (void)
* @param base the character buffer
* @param size the size in bytes of the character buffer
*
* @return the newly allocated buffer state object.
* @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
{
@ -1938,7 +1940,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
return 0;
return NULL;
b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
@ -1947,7 +1949,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
b->yy_input_file = 0;
b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
@ -1970,7 +1972,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
{
return yy_scan_bytes(yystr,strlen(yystr) );
return yy_scan_bytes(yystr,(int) strlen(yystr) );
}
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@ -1988,7 +1990,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
n = (yy_size_t) (_yybytes_len + 2);
buf = (char *) yyalloc(n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
@ -2014,9 +2016,9 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
#define YY_EXIT_FAILURE 2
#endif
static void yy_fatal_error (yyconst char* msg )
static void yynoreturn yy_fatal_error (yyconst char* msg )
{
(void) fprintf( stderr, "%s\n", msg );
(void) fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@ -2044,7 +2046,7 @@ static void yy_fatal_error (yyconst char* msg )
*/
int yyget_lineno (void)
{
return yylineno;
}
@ -2082,29 +2084,29 @@ char *yyget_text (void)
}
/** Set the current line number.
* @param line_number
* @param _line_number line number
*
*/
void yyset_lineno (int line_number )
void yyset_lineno (int _line_number )
{
yylineno = line_number;
yylineno = _line_number;
}
/** Set the input stream. This does not discard the current
* input buffer.
* @param in_str A readable stream.
* @param _in_str A readable stream.
*
* @see yy_switch_to_buffer
*/
void yyset_in (FILE * in_str )
void yyset_in (FILE * _in_str )
{
yyin = in_str ;
yyin = _in_str ;
}
void yyset_out (FILE * out_str )
void yyset_out (FILE * _out_str )
{
yyout = out_str ;
yyout = _out_str ;
}
int yyget_debug (void)
@ -2112,9 +2114,9 @@ int yyget_debug (void)
return yy_flex_debug;
}
void yyset_debug (int bdebug )
void yyset_debug (int _bdebug )
{
yy_flex_debug = bdebug ;
yy_flex_debug = _bdebug ;
}
static int yy_init_globals (void)
@ -2123,10 +2125,10 @@ static int yy_init_globals (void)
* This function is called from yylex_destroy(), so don't allocate here.
*/
(yy_buffer_stack) = 0;
(yy_buffer_stack) = NULL;
(yy_buffer_stack_top) = 0;
(yy_buffer_stack_max) = 0;
(yy_c_buf_p) = (char *) 0;
(yy_c_buf_p) = NULL;
(yy_init) = 0;
(yy_start) = 0;
@ -2135,8 +2137,8 @@ static int yy_init_globals (void)
yyin = stdin;
yyout = stdout;
#else
yyin = (FILE *) 0;
yyout = (FILE *) 0;
yyin = NULL;
yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
@ -2174,7 +2176,8 @@ int yylex_destroy (void)
#ifndef yytext_ptr
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
{
register int i;
int i;
for ( i = 0; i < n; ++i )
s1[i] = s2[i];
}
@ -2183,7 +2186,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen (yyconst char * s )
{
register int n;
int n;
for ( n = 0; s[n]; ++n )
;
@ -2193,11 +2196,12 @@ static int yy_flex_strlen (yyconst char * s )
void *yyalloc (yy_size_t size )
{
return (void *) malloc( size );
return malloc(size);
}
void *yyrealloc (void * ptr, yy_size_t size )
{
/* The cast to (char *) in the following accommodates both
* implementations that use char* generic pointers, and those
* that use void* generic pointers. It works with the latter
@ -2205,12 +2209,12 @@ void *yyrealloc (void * ptr, yy_size_t size )
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
return (void *) realloc( (char *) ptr, size );
return realloc(ptr, size);
}
void yyfree (void * ptr )
{
free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
}
#define YYTABLES_NAME "yytables"

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.0.2. */
/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "3.0.2"
#define YYBISON_VERSION "3.0.4"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -143,7 +143,7 @@ extern int yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
#line 39 "dtc-parser.y" /* yacc.c:355 */
@ -168,6 +168,8 @@ union YYSTYPE
#line 170 "dtc-parser.tab.c" /* yacc.c:355 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
@ -195,7 +197,7 @@ int yyparse (void);
/* Copy the second part of user declarations. */
#line 199 "dtc-parser.tab.c" /* yacc.c:358 */
#line 201 "dtc-parser.tab.c" /* yacc.c:358 */
#ifdef short
# undef short
@ -446,7 +448,7 @@ union yyalloc
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 30
/* YYNRULES -- Number of rules. */
#define YYNRULES 84
#define YYNRULES 85
/* YYNSTATES -- Number of states. */
#define YYNSTATES 149
@ -497,14 +499,14 @@ static const yytype_uint8 yytranslate[] =
static const yytype_uint16 yyrline[] =
{
0, 109, 109, 117, 121, 128, 129, 139, 142, 149,
153, 161, 165, 170, 181, 191, 206, 214, 217, 224,
228, 232, 236, 244, 248, 252, 256, 260, 276, 286,
294, 297, 301, 308, 324, 329, 348, 362, 369, 370,
371, 378, 382, 383, 387, 388, 392, 393, 397, 398,
402, 403, 407, 408, 412, 413, 414, 418, 419, 420,
421, 422, 426, 427, 428, 432, 433, 434, 438, 439,
448, 457, 461, 462, 463, 464, 469, 472, 476, 484,
487, 491, 499, 503, 507
153, 161, 165, 170, 181, 200, 213, 220, 228, 231,
238, 242, 246, 250, 258, 262, 266, 270, 274, 290,
300, 308, 311, 315, 322, 338, 343, 362, 376, 383,
384, 385, 392, 396, 397, 401, 402, 406, 407, 411,
412, 416, 417, 421, 422, 426, 427, 428, 432, 433,
434, 435, 436, 440, 441, 442, 446, 447, 448, 452,
453, 462, 471, 475, 476, 477, 478, 483, 486, 490,
498, 501, 505, 513, 517, 521
};
#endif
@ -580,20 +582,20 @@ static const yytype_int8 yypact[] =
static const yytype_uint8 yydefact[] =
{
0, 0, 0, 5, 7, 3, 1, 6, 0, 0,
0, 7, 0, 38, 39, 0, 0, 10, 0, 2,
8, 4, 0, 0, 0, 72, 0, 41, 42, 44,
46, 48, 50, 52, 54, 57, 64, 67, 71, 0,
17, 11, 0, 0, 0, 0, 73, 74, 75, 40,
16, 7, 0, 39, 40, 0, 0, 10, 0, 2,
8, 4, 0, 0, 0, 73, 0, 42, 43, 45,
47, 49, 51, 53, 55, 58, 65, 68, 72, 0,
18, 11, 0, 0, 0, 0, 74, 75, 76, 41,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
79, 0, 0, 14, 12, 45, 0, 47, 49, 51,
53, 55, 56, 60, 61, 59, 58, 62, 63, 65,
66, 69, 68, 70, 0, 0, 0, 0, 18, 0,
79, 15, 13, 0, 0, 0, 20, 30, 82, 22,
84, 0, 81, 80, 43, 21, 83, 0, 0, 16,
29, 19, 31, 0, 23, 32, 26, 0, 76, 34,
0, 0, 0, 0, 37, 36, 24, 35, 33, 0,
77, 78, 25, 0, 28, 0, 0, 0, 27
80, 0, 0, 14, 12, 46, 0, 48, 50, 52,
54, 56, 57, 61, 62, 60, 59, 63, 64, 66,
67, 70, 69, 71, 0, 0, 0, 0, 19, 0,
80, 15, 13, 0, 0, 0, 21, 31, 83, 23,
85, 0, 82, 81, 44, 22, 84, 0, 0, 17,
30, 20, 32, 0, 24, 33, 27, 0, 77, 35,
0, 0, 0, 0, 38, 37, 25, 36, 34, 0,
78, 79, 26, 0, 29, 0, 0, 0, 28
};
/* YYPGOTO[NTERM-NUM]. */
@ -676,28 +678,28 @@ static const yytype_uint8 yystos[] =
static const yytype_uint8 yyr1[] =
{
0, 48, 49, 50, 50, 51, 51, 52, 52, 53,
53, 54, 54, 54, 54, 54, 55, 56, 56, 57,
57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
59, 59, 59, 60, 60, 60, 60, 60, 61, 61,
61, 62, 63, 63, 64, 64, 65, 65, 66, 66,
67, 67, 68, 68, 69, 69, 69, 70, 70, 70,
70, 70, 71, 71, 71, 72, 72, 72, 73, 73,
73, 73, 74, 74, 74, 74, 75, 75, 75, 76,
76, 76, 77, 77, 77
53, 54, 54, 54, 54, 54, 54, 55, 56, 56,
57, 57, 57, 57, 58, 58, 58, 58, 58, 58,
58, 59, 59, 59, 60, 60, 60, 60, 60, 61,
61, 61, 62, 63, 63, 64, 64, 65, 65, 66,
66, 67, 67, 68, 68, 69, 69, 69, 70, 70,
70, 70, 70, 71, 71, 71, 72, 72, 72, 73,
73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
76, 76, 76, 77, 77, 77
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
static const yytype_uint8 yyr2[] =
{
0, 2, 3, 2, 4, 1, 2, 0, 2, 4,
2, 2, 3, 4, 3, 4, 5, 0, 2, 4,
2, 3, 2, 2, 3, 4, 2, 9, 5, 2,
0, 2, 2, 3, 1, 2, 2, 2, 1, 1,
3, 1, 1, 5, 1, 3, 1, 3, 1, 3,
1, 3, 1, 3, 1, 3, 3, 1, 3, 3,
3, 3, 3, 3, 1, 3, 3, 1, 3, 3,
3, 1, 1, 2, 2, 2, 0, 2, 2, 0,
2, 2, 2, 3, 2
2, 2, 3, 4, 3, 4, 0, 5, 0, 2,
4, 2, 3, 2, 2, 3, 4, 2, 9, 5,
2, 0, 2, 2, 3, 1, 2, 2, 2, 1,
1, 3, 1, 1, 5, 1, 3, 1, 3, 1,
3, 1, 3, 1, 3, 1, 3, 3, 1, 3,
3, 3, 3, 3, 3, 1, 3, 3, 1, 3,
3, 3, 1, 1, 2, 2, 2, 0, 2, 2,
0, 2, 2, 2, 3, 2
};
@ -1472,7 +1474,7 @@ yyreduce:
parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
guess_boot_cpuid((yyvsp[0].node)));
}
#line 1476 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1478 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 3:
@ -1480,7 +1482,7 @@ yyreduce:
{
(yyval.flags) = DTSF_V1;
}
#line 1484 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1486 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 4:
@ -1488,7 +1490,7 @@ yyreduce:
{
(yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
}
#line 1492 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1494 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 6:
@ -1498,7 +1500,7 @@ yyreduce:
ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
(yyval.flags) = (yyvsp[-1].flags);
}
#line 1502 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1504 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 7:
@ -1506,7 +1508,7 @@ yyreduce:
{
(yyval.re) = NULL;
}
#line 1510 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1512 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 8:
@ -1514,7 +1516,7 @@ yyreduce:
{
(yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
}
#line 1518 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1520 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 9:
@ -1522,7 +1524,7 @@ yyreduce:
{
(yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
}
#line 1526 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1528 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 10:
@ -1531,7 +1533,7 @@ yyreduce:
add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
(yyval.re) = (yyvsp[0].re);
}
#line 1535 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1537 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 11:
@ -1539,7 +1541,7 @@ yyreduce:
{
(yyval.node) = name_node((yyvsp[0].node), "");
}
#line 1543 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1545 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 12:
@ -1547,7 +1549,7 @@ yyreduce:
{
(yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
}
#line 1551 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1553 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 13:
@ -1562,7 +1564,7 @@ yyreduce:
ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
(yyval.node) = (yyvsp[-3].node);
}
#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1568 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 14:
@ -1570,17 +1572,26 @@ yyreduce:
{
struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
if (target)
if (target) {
merge_nodes(target, (yyvsp[0].node));
else
ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
} else {
/*
* We rely on the rule being always:
* versioninfo plugindecl memreserves devicetree
* so $-1 is what we want (plugindecl)
*/
if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
else
ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
}
(yyval.node) = (yyvsp[-2].node);
}
#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 15:
#line 192 "dtc-parser.y" /* yacc.c:1646 */
#line 201 "dtc-parser.y" /* yacc.c:1646 */
{
struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
@ -1592,100 +1603,109 @@ yyreduce:
(yyval.node) = (yyvsp[-3].node);
}
#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 16:
#line 207 "dtc-parser.y" /* yacc.c:1646 */
#line 213 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
/* build empty node */
(yyval.node) = name_node(build_node(NULL, NULL), "");
}
#line 1604 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 17:
#line 214 "dtc-parser.y" /* yacc.c:1646 */
#line 221 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.proplist) = NULL;
(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
}
#line 1612 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 18:
#line 218 "dtc-parser.y" /* yacc.c:1646 */
#line 228 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
(yyval.proplist) = NULL;
}
#line 1620 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 19:
#line 225 "dtc-parser.y" /* yacc.c:1646 */
#line 232 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
}
#line 1628 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 20:
#line 229 "dtc-parser.y" /* yacc.c:1646 */
#line 239 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
}
#line 1636 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 21:
#line 233 "dtc-parser.y" /* yacc.c:1646 */
#line 243 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
}
#line 1644 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 22:
#line 237 "dtc-parser.y" /* yacc.c:1646 */
#line 247 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
}
#line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 23:
#line 251 "dtc-parser.y" /* yacc.c:1646 */
{
add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
(yyval.prop) = (yyvsp[0].prop);
}
#line 1653 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 23:
#line 245 "dtc-parser.y" /* yacc.c:1646 */
case 24:
#line 259 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
}
#line 1661 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 24:
#line 249 "dtc-parser.y" /* yacc.c:1646 */
case 25:
#line 263 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
}
#line 1669 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 25:
#line 253 "dtc-parser.y" /* yacc.c:1646 */
case 26:
#line 267 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
}
#line 1677 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 26:
#line 257 "dtc-parser.y" /* yacc.c:1646 */
case 27:
#line 271 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
}
#line 1685 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 27:
#line 261 "dtc-parser.y" /* yacc.c:1646 */
case 28:
#line 275 "dtc-parser.y" /* yacc.c:1646 */
{
FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
struct data d;
@ -1701,11 +1721,11 @@ yyreduce:
(yyval.data) = data_merge((yyvsp[-8].data), d);
fclose(f);
}
#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 28:
#line 277 "dtc-parser.y" /* yacc.c:1646 */
case 29:
#line 291 "dtc-parser.y" /* yacc.c:1646 */
{
FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
struct data d = empty_data;
@ -1715,43 +1735,43 @@ yyreduce:
(yyval.data) = data_merge((yyvsp[-4].data), d);
fclose(f);
}
#line 1719 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 29:
#line 287 "dtc-parser.y" /* yacc.c:1646 */
case 30:
#line 301 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
#line 1727 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 30:
#line 294 "dtc-parser.y" /* yacc.c:1646 */
case 31:
#line 308 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = empty_data;
}
#line 1735 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 31:
#line 298 "dtc-parser.y" /* yacc.c:1646 */
case 32:
#line 312 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = (yyvsp[-1].data);
}
#line 1743 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 32:
#line 302 "dtc-parser.y" /* yacc.c:1646 */
case 33:
#line 316 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
#line 1751 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 33:
#line 309 "dtc-parser.y" /* yacc.c:1646 */
case 34:
#line 323 "dtc-parser.y" /* yacc.c:1646 */
{
unsigned long long bits;
@ -1767,20 +1787,20 @@ yyreduce:
(yyval.array).data = empty_data;
(yyval.array).bits = bits;
}
#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 34:
#line 325 "dtc-parser.y" /* yacc.c:1646 */
case 35:
#line 339 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.array).data = empty_data;
(yyval.array).bits = 32;
}
#line 1780 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 35:
#line 330 "dtc-parser.y" /* yacc.c:1646 */
case 36:
#line 344 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[-1].array).bits < 64) {
uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@ -1799,11 +1819,11 @@ yyreduce:
(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
}
#line 1803 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 36:
#line 349 "dtc-parser.y" /* yacc.c:1646 */
case 37:
#line 363 "dtc-parser.y" /* yacc.c:1646 */
{
uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
@ -1817,129 +1837,129 @@ yyreduce:
(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
}
#line 1821 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 37:
#line 363 "dtc-parser.y" /* yacc.c:1646 */
case 38:
#line 377 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
}
#line 1829 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 40:
#line 372 "dtc-parser.y" /* yacc.c:1646 */
case 41:
#line 386 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.integer) = (yyvsp[-1].integer);
}
#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 43:
#line 383 "dtc-parser.y" /* yacc.c:1646 */
case 44:
#line 397 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 45:
#line 388 "dtc-parser.y" /* yacc.c:1646 */
case 46:
#line 402 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 47:
#line 393 "dtc-parser.y" /* yacc.c:1646 */
case 48:
#line 407 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 49:
#line 398 "dtc-parser.y" /* yacc.c:1646 */
case 50:
#line 412 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 51:
#line 403 "dtc-parser.y" /* yacc.c:1646 */
case 52:
#line 417 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 53:
#line 408 "dtc-parser.y" /* yacc.c:1646 */
case 54:
#line 422 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 55:
#line 413 "dtc-parser.y" /* yacc.c:1646 */
case 56:
#line 427 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 56:
#line 414 "dtc-parser.y" /* yacc.c:1646 */
case 57:
#line 428 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 58:
#line 419 "dtc-parser.y" /* yacc.c:1646 */
case 59:
#line 433 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 59:
#line 420 "dtc-parser.y" /* yacc.c:1646 */
case 60:
#line 434 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 60:
#line 421 "dtc-parser.y" /* yacc.c:1646 */
case 61:
#line 435 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 61:
#line 422 "dtc-parser.y" /* yacc.c:1646 */
case 62:
#line 436 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 62:
#line 426 "dtc-parser.y" /* yacc.c:1646 */
case 63:
#line 440 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 63:
#line 427 "dtc-parser.y" /* yacc.c:1646 */
case 64:
#line 441 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 65:
#line 432 "dtc-parser.y" /* yacc.c:1646 */
case 66:
#line 446 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
#line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 66:
#line 433 "dtc-parser.y" /* yacc.c:1646 */
case 67:
#line 447 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
#line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 68:
#line 438 "dtc-parser.y" /* yacc.c:1646 */
case 69:
#line 452 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
#line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 69:
#line 440 "dtc-parser.y" /* yacc.c:1646 */
case 70:
#line 454 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[0].integer) != 0) {
(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@ -1948,11 +1968,11 @@ yyreduce:
(yyval.integer) = 0;
}
}
#line 1952 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 70:
#line 449 "dtc-parser.y" /* yacc.c:1646 */
case 71:
#line 463 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[0].integer) != 0) {
(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@ -1961,103 +1981,103 @@ yyreduce:
(yyval.integer) = 0;
}
}
#line 1965 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 73:
#line 462 "dtc-parser.y" /* yacc.c:1646 */
case 74:
#line 476 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = -(yyvsp[0].integer); }
#line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 74:
#line 463 "dtc-parser.y" /* yacc.c:1646 */
case 75:
#line 477 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = ~(yyvsp[0].integer); }
#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 75:
#line 464 "dtc-parser.y" /* yacc.c:1646 */
case 76:
#line 478 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = !(yyvsp[0].integer); }
#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 76:
#line 469 "dtc-parser.y" /* yacc.c:1646 */
case 77:
#line 483 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = empty_data;
}
#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 77:
#line 473 "dtc-parser.y" /* yacc.c:1646 */
case 78:
#line 487 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
}
#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 78:
#line 477 "dtc-parser.y" /* yacc.c:1646 */
case 79:
#line 491 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
#line 2007 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 79:
#line 484 "dtc-parser.y" /* yacc.c:1646 */
case 80:
#line 498 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.nodelist) = NULL;
}
#line 2015 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 80:
#line 488 "dtc-parser.y" /* yacc.c:1646 */
case 81:
#line 502 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
}
#line 2023 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 81:
#line 492 "dtc-parser.y" /* yacc.c:1646 */
case 82:
#line 506 "dtc-parser.y" /* yacc.c:1646 */
{
ERROR(&(yylsp[0]), "Properties must precede subnodes");
YYERROR;
}
#line 2032 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 82:
#line 500 "dtc-parser.y" /* yacc.c:1646 */
case 83:
#line 514 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
}
#line 2040 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 83:
#line 504 "dtc-parser.y" /* yacc.c:1646 */
case 84:
#line 518 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
}
#line 2048 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 84:
#line 508 "dtc-parser.y" /* yacc.c:1646 */
case 85:
#line 522 "dtc-parser.y" /* yacc.c:1646 */
{
add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
(yyval.node) = (yyvsp[0].node);
}
#line 2057 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
#line 2061 "dtc-parser.tab.c" /* yacc.c:1646 */
#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@ -2292,7 +2312,7 @@ yyreturn:
#endif
return yyresult;
}
#line 514 "dtc-parser.y" /* yacc.c:1906 */
#line 528 "dtc-parser.y" /* yacc.c:1906 */
void yyerror(char const *s)

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.0.2. */
/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -72,7 +72,7 @@ extern int yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
#line 39 "dtc-parser.y" /* yacc.c:1909 */
@ -97,6 +97,8 @@ union YYSTYPE
#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif

@ -182,10 +182,19 @@ devicetree:
{
struct node *target = get_node_by_ref($1, $2);
if (target)
if (target) {
merge_nodes(target, $3);
else
ERROR(&@2, "Label or path %s not found", $2);
} else {
/*
* We rely on the rule being always:
* versioninfo plugindecl memreserves devicetree
* so $-1 is what we want (plugindecl)
*/
if ($<flags>-1 & DTSF_PLUGIN)
add_orphan_node($1, $3, $2);
else
ERROR(&@2, "Label or path %s not found", $2);
}
$$ = $1;
}
| devicetree DT_DEL_NODE DT_REF ';'
@ -200,6 +209,11 @@ devicetree:
$$ = $1;
}
| /* empty */
{
/* build empty node */
$$ = name_node(build_node(NULL, NULL), "");
}
;
nodedef:

@ -203,6 +203,7 @@ struct node *build_node_delete(void);
struct node *name_node(struct node *node, char *name);
struct node *chain_node(struct node *first, struct node *list);
struct node *merge_nodes(struct node *old_node, struct node *new_node);
void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
void add_property(struct node *node, struct property *prop);
void delete_property_by_name(struct node *node, char *name);
@ -216,6 +217,7 @@ void append_to_property(struct node *node,
const char *get_unitname(struct node *node);
struct property *get_property(struct node *node, const char *propname);
cell_t propval_cell(struct property *prop);
cell_t propval_cell_n(struct property *prop, int n);
struct property *get_property_by_label(struct node *tree, const char *label,
struct node **node);
struct marker *get_marker_label(struct node *tree, const char *label,

@ -0,0 +1,96 @@
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
*
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
* a) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "libfdt_env.h"
#include <fdt.h>
#include <libfdt.h>
#include "libfdt_internal.h"
int fdt_address_cells(const void *fdt, int nodeoffset)
{
const fdt32_t *ac;
int val;
int len;
ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
if (!ac)
return 2;
if (len != sizeof(*ac))
return -FDT_ERR_BADNCELLS;
val = fdt32_to_cpu(*ac);
if ((val <= 0) || (val > FDT_MAX_NCELLS))
return -FDT_ERR_BADNCELLS;
return val;
}
int fdt_size_cells(const void *fdt, int nodeoffset)
{
const fdt32_t *sc;
int val;
int len;
sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
if (!sc)
return 2;
if (len != sizeof(*sc))
return -FDT_ERR_BADNCELLS;
val = fdt32_to_cpu(*sc);
if ((val < 0) || (val > FDT_MAX_NCELLS))
return -FDT_ERR_BADNCELLS;
return val;
}

@ -0,0 +1,861 @@
#include "libfdt_env.h"
#include <fdt.h>
#include <libfdt.h>
#include "libfdt_internal.h"
/**
* overlay_get_target_phandle - retrieves the target phandle of a fragment
* @fdto: pointer to the device tree overlay blob
* @fragment: node offset of the fragment in the overlay
*
* overlay_get_target_phandle() retrieves the target phandle of an
* overlay fragment when that fragment uses a phandle (target
* property) instead of a path (target-path property).
*
* returns:
* the phandle pointed by the target property
* 0, if the phandle was not found
* -1, if the phandle was malformed
*/
static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
{
const fdt32_t *val;
int len;
val = fdt_getprop(fdto, fragment, "target", &len);
if (!val)
return 0;
if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
return (uint32_t)-1;
return fdt32_to_cpu(*val);
}
/**
* overlay_get_target - retrieves the offset of a fragment's target
* @fdt: Base device tree blob
* @fdto: Device tree overlay blob
* @fragment: node offset of the fragment in the overlay
* @pathp: pointer which receives the path of the target (or NULL)
*
* overlay_get_target() retrieves the target offset in the base
* device tree of a fragment, no matter how the actual targetting is
* done (through a phandle or a path)
*
* returns:
* the targetted node offset in the base device tree
* Negative error code on error
*/
static int overlay_get_target(const void *fdt, const void *fdto,
int fragment, char const **pathp)
{
uint32_t phandle;
const char *path = NULL;
int path_len = 0, ret;
/* Try first to do a phandle based lookup */
phandle = overlay_get_target_phandle(fdto, fragment);
if (phandle == (uint32_t)-1)
return -FDT_ERR_BADPHANDLE;
/* no phandle, try path */
if (!phandle) {
/* And then a path based lookup */
path = fdt_getprop(fdto, fragment, "target-path", &path_len);
if (path)
ret = fdt_path_offset(fdt, path);
else
ret = path_len;
} else
ret = fdt_node_offset_by_phandle(fdt, phandle);
/*
* If we haven't found either a target or a
* target-path property in a node that contains a
* __overlay__ subnode (we wouldn't be called
* otherwise), consider it a improperly written
* overlay
*/
if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
ret = -FDT_ERR_BADOVERLAY;
/* return on error */
if (ret < 0)
return ret;
/* return pointer to path (if available) */
if (pathp)
*pathp = path ? path : NULL;
return ret;
}
/**
* overlay_phandle_add_offset - Increases a phandle by an offset
* @fdt: Base device tree blob
* @node: Device tree overlay blob
* @name: Name of the property to modify (phandle or linux,phandle)
* @delta: offset to apply
*
* overlay_phandle_add_offset() increments a node phandle by a given
* offset.
*
* returns:
* 0 on success.
* Negative error code on error
*/
static int overlay_phandle_add_offset(void *fdt, int node,
const char *name, uint32_t delta)
{
const fdt32_t *val;
uint32_t adj_val;
int len;
val = fdt_getprop(fdt, node, name, &len);
if (!val)
return len;
if (len != sizeof(*val))
return -FDT_ERR_BADPHANDLE;
adj_val = fdt32_to_cpu(*val);
if ((adj_val + delta) < adj_val)
return -FDT_ERR_NOPHANDLES;
adj_val += delta;
if (adj_val == (uint32_t)-1)
return -FDT_ERR_NOPHANDLES;
return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
}
/**
* overlay_adjust_node_phandles - Offsets the phandles of a node
* @fdto: Device tree overlay blob
* @node: Offset of the node we want to adjust
* @delta: Offset to shift the phandles of
*
* overlay_adjust_node_phandles() adds a constant to all the phandles
* of a given node. This is mainly use as part of the overlay
* application process, when we want to update all the overlay
* phandles to not conflict with the overlays of the base device tree.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_adjust_node_phandles(void *fdto, int node,
uint32_t delta)
{
int child;
int ret;
ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
if (ret && ret != -FDT_ERR_NOTFOUND)
return ret;
ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
if (ret && ret != -FDT_ERR_NOTFOUND)
return ret;
fdt_for_each_subnode(child, fdto, node) {
ret = overlay_adjust_node_phandles(fdto, child, delta);
if (ret)
return ret;
}
return 0;
}
/**
* overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
* @fdto: Device tree overlay blob
* @delta: Offset to shift the phandles of
*
* overlay_adjust_local_phandles() adds a constant to all the
* phandles of an overlay. This is mainly use as part of the overlay
* application process, when we want to update all the overlay
* phandles to not conflict with the overlays of the base device tree.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
{
/*
* Start adjusting the phandles from the overlay root
*/
return overlay_adjust_node_phandles(fdto, 0, delta);
}
/**
* overlay_update_local_node_references - Adjust the overlay references
* @fdto: Device tree overlay blob
* @tree_node: Node offset of the node to operate on
* @fixup_node: Node offset of the matching local fixups node
* @delta: Offset to shift the phandles of
*
* overlay_update_local_nodes_references() update the phandles
* pointing to a node within the device tree overlay by adding a
* constant delta.
*
* This is mainly used as part of a device tree application process,
* where you want the device tree overlays phandles to not conflict
* with the ones from the base device tree before merging them.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_update_local_node_references(void *fdto,
int tree_node,
int fixup_node,
uint32_t delta)
{
int fixup_prop;
int fixup_child;
int ret;
fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
const fdt32_t *fixup_val;
const char *tree_val;
const char *name;
int fixup_len;
int tree_len;
int i;
fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
&name, &fixup_len);
if (!fixup_val)
return fixup_len;
if (fixup_len % sizeof(uint32_t))
return -FDT_ERR_BADOVERLAY;
tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
if (!tree_val) {
if (tree_len == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
return tree_len;
}
for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
fdt32_t adj_val;
uint32_t poffset;
poffset = fdt32_to_cpu(fixup_val[i]);
/*
* phandles to fixup can be unaligned.
*
* Use a memcpy for the architectures that do
* not support unaligned accesses.
*/
memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
ret = fdt_setprop_inplace_namelen_partial(fdto,
tree_node,
name,
strlen(name),
poffset,
&adj_val,
sizeof(adj_val));
if (ret == -FDT_ERR_NOSPACE)
return -FDT_ERR_BADOVERLAY;
if (ret)
return ret;
}
}
fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
NULL);
int tree_child;
tree_child = fdt_subnode_offset(fdto, tree_node,
fixup_child_name);
if (tree_child == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
if (tree_child < 0)
return tree_child;
ret = overlay_update_local_node_references(fdto,
tree_child,
fixup_child,
delta);
if (ret)
return ret;
}
return 0;
}
/**
* overlay_update_local_references - Adjust the overlay references
* @fdto: Device tree overlay blob
* @delta: Offset to shift the phandles of
*
* overlay_update_local_references() update all the phandles pointing
* to a node within the device tree overlay by adding a constant
* delta to not conflict with the base overlay.
*
* This is mainly used as part of a device tree application process,
* where you want the device tree overlays phandles to not conflict
* with the ones from the base device tree before merging them.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_update_local_references(void *fdto, uint32_t delta)
{
int fixups;
fixups = fdt_path_offset(fdto, "/__local_fixups__");
if (fixups < 0) {
/* There's no local phandles to adjust, bail out */
if (fixups == -FDT_ERR_NOTFOUND)
return 0;
return fixups;
}
/*
* Update our local references from the root of the tree
*/
return overlay_update_local_node_references(fdto, 0, fixups,
delta);
}
/**
* overlay_fixup_one_phandle - Set an overlay phandle to the base one
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
* @symbols_off: Node offset of the symbols node in the base device tree
* @path: Path to a node holding a phandle in the overlay
* @path_len: number of path characters to consider
* @name: Name of the property holding the phandle reference in the overlay
* @name_len: number of name characters to consider
* @poffset: Offset within the overlay property where the phandle is stored
* @label: Label of the node referenced by the phandle
*
* overlay_fixup_one_phandle() resolves an overlay phandle pointing to
* a node in the base device tree.
*
* This is part of the device tree overlay application process, when
* you want all the phandles in the overlay to point to the actual
* base dt nodes.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_fixup_one_phandle(void *fdt, void *fdto,
int symbols_off,
const char *path, uint32_t path_len,
const char *name, uint32_t name_len,
int poffset, const char *label)
{
const char *symbol_path;
uint32_t phandle;
fdt32_t phandle_prop;
int symbol_off, fixup_off;
int prop_len;
if (symbols_off < 0)
return symbols_off;
symbol_path = fdt_getprop(fdt, symbols_off, label,
&prop_len);
if (!symbol_path)
return prop_len;
symbol_off = fdt_path_offset(fdt, symbol_path);
if (symbol_off < 0)
return symbol_off;
phandle = fdt_get_phandle(fdt, symbol_off);
if (!phandle)
return -FDT_ERR_NOTFOUND;
fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
if (fixup_off == -FDT_ERR_NOTFOUND)
return -FDT_ERR_BADOVERLAY;
if (fixup_off < 0)
return fixup_off;
phandle_prop = cpu_to_fdt32(phandle);
return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
name, name_len, poffset,
&phandle_prop,
sizeof(phandle_prop));
};
/**
* overlay_fixup_phandle - Set an overlay phandle to the base one
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
* @symbols_off: Node offset of the symbols node in the base device tree
* @property: Property offset in the overlay holding the list of fixups
*
* overlay_fixup_phandle() resolves all the overlay phandles pointed
* to in a __fixups__ property, and updates them to match the phandles
* in use in the base device tree.
*
* This is part of the device tree overlay application process, when
* you want all the phandles in the overlay to point to the actual
* base dt nodes.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
int property)
{
const char *value;
const char *label;
int len;
value = fdt_getprop_by_offset(fdto, property,
&label, &len);
if (!value) {
if (len == -FDT_ERR_NOTFOUND)
return -FDT_ERR_INTERNAL;
return len;
}
do {
const char *path, *name, *fixup_end;
const char *fixup_str = value;
uint32_t path_len, name_len;
uint32_t fixup_len;
char *sep, *endptr;
int poffset, ret;
fixup_end = memchr(value, '\0', len);
if (!fixup_end)
return -FDT_ERR_BADOVERLAY;
fixup_len = fixup_end - fixup_str;
len -= fixup_len + 1;
value += fixup_len + 1;
path = fixup_str;
sep = memchr(fixup_str, ':', fixup_len);
if (!sep || *sep != ':')
return -FDT_ERR_BADOVERLAY;
path_len = sep - path;
if (path_len == (fixup_len - 1))
return -FDT_ERR_BADOVERLAY;
fixup_len -= path_len + 1;
name = sep + 1;
sep = memchr(name, ':', fixup_len);
if (!sep || *sep != ':')
return -FDT_ERR_BADOVERLAY;
name_len = sep - name;
if (!name_len)
return -FDT_ERR_BADOVERLAY;
poffset = strtoul(sep + 1, &endptr, 10);
if ((*endptr != '\0') || (endptr <= (sep + 1)))
return -FDT_ERR_BADOVERLAY;
ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
path, path_len, name, name_len,
poffset, label);
if (ret)
return ret;
} while (len > 0);
return 0;
}
/**
* overlay_fixup_phandles - Resolve the overlay phandles to the base
* device tree
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
*
* overlay_fixup_phandles() resolves all the overlay phandles pointing
* to nodes in the base device tree.
*
* This is one of the steps of the device tree overlay application
* process, when you want all the phandles in the overlay to point to
* the actual base dt nodes.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_fixup_phandles(void *fdt, void *fdto)
{
int fixups_off, symbols_off;
int property;
/* We can have overlays without any fixups */
fixups_off = fdt_path_offset(fdto, "/__fixups__");
if (fixups_off == -FDT_ERR_NOTFOUND)
return 0; /* nothing to do */
if (fixups_off < 0)
return fixups_off;
/* And base DTs without symbols */
symbols_off = fdt_path_offset(fdt, "/__symbols__");
if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
return symbols_off;
fdt_for_each_property_offset(property, fdto, fixups_off) {
int ret;
ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
if (ret)
return ret;
}
return 0;
}
/**
* overlay_apply_node - Merges a node into the base device tree
* @fdt: Base Device Tree blob
* @target: Node offset in the base device tree to apply the fragment to
* @fdto: Device tree overlay blob
* @node: Node offset in the overlay holding the changes to merge
*
* overlay_apply_node() merges a node into a target base device tree
* node pointed.
*
* This is part of the final step in the device tree overlay
* application process, when all the phandles have been adjusted and
* resolved and you just have to merge overlay into the base device
* tree.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_apply_node(void *fdt, int target,
void *fdto, int node)
{
int property;
int subnode;
fdt_for_each_property_offset(property, fdto, node) {
const char *name;
const void *prop;
int prop_len;
int ret;
prop = fdt_getprop_by_offset(fdto, property, &name,
&prop_len);
if (prop_len == -FDT_ERR_NOTFOUND)
return -FDT_ERR_INTERNAL;
if (prop_len < 0)
return prop_len;
ret = fdt_setprop(fdt, target, name, prop, prop_len);
if (ret)
return ret;
}
fdt_for_each_subnode(subnode, fdto, node) {
const char *name = fdt_get_name(fdto, subnode, NULL);
int nnode;
int ret;
nnode = fdt_add_subnode(fdt, target, name);
if (nnode == -FDT_ERR_EXISTS) {
nnode = fdt_subnode_offset(fdt, target, name);
if (nnode == -FDT_ERR_NOTFOUND)
return -FDT_ERR_INTERNAL;
}
if (nnode < 0)
return nnode;
ret = overlay_apply_node(fdt, nnode, fdto, subnode);
if (ret)
return ret;
}
return 0;
}
/**
* overlay_merge - Merge an overlay into its base device tree
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
*
* overlay_merge() merges an overlay into its base device tree.
*
* This is the next to last step in the device tree overlay application
* process, when all the phandles have been adjusted and resolved and
* you just have to merge overlay into the base device tree.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_merge(void *fdt, void *fdto)
{
int fragment;
fdt_for_each_subnode(fragment, fdto, 0) {
int overlay;
int target;
int ret;
/*
* Each fragments will have an __overlay__ node. If
* they don't, it's not supposed to be merged
*/
overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
if (overlay == -FDT_ERR_NOTFOUND)
continue;
if (overlay < 0)
return overlay;
target = overlay_get_target(fdt, fdto, fragment, NULL);
if (target < 0)
return target;
ret = overlay_apply_node(fdt, target, fdto, overlay);
if (ret)
return ret;
}
return 0;
}
static int get_path_len(const void *fdt, int nodeoffset)
{
int len = 0, namelen;
const char *name;
FDT_CHECK_HEADER(fdt);
for (;;) {
name = fdt_get_name(fdt, nodeoffset, &namelen);
if (!name)
return namelen;
/* root? we're done */
if (namelen == 0)
break;
nodeoffset = fdt_parent_offset(fdt, nodeoffset);
if (nodeoffset < 0)
return nodeoffset;
len += namelen + 1;
}
/* in case of root pretend it's "/" */
if (len == 0)
len++;
return len;
}
/**
* overlay_symbol_update - Update the symbols of base tree after a merge
* @fdt: Base Device Tree blob
* @fdto: Device tree overlay blob
*
* overlay_symbol_update() updates the symbols of the base tree with the
* symbols of the applied overlay
*
* This is the last step in the device tree overlay application
* process, allowing the reference of overlay symbols by subsequent
* overlay operations.
*
* returns:
* 0 on success
* Negative error code on failure
*/
static int overlay_symbol_update(void *fdt, void *fdto)
{
int root_sym, ov_sym, prop, path_len, fragment, target;
int len, frag_name_len, ret, rel_path_len;
const char *s, *e;
const char *path;
const char *name;
const char *frag_name;
const char *rel_path;
const char *target_path;
char *buf;
void *p;
ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
/* if no overlay symbols exist no problem */
if (ov_sym < 0)
return 0;
root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
/* it no root symbols exist we should create them */
if (root_sym == -FDT_ERR_NOTFOUND)
root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
/* any error is fatal now */
if (root_sym < 0)
return root_sym;
/* iterate over each overlay symbol */
fdt_for_each_property_offset(prop, fdto, ov_sym) {
path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
if (!path)
return path_len;
/* verify it's a string property (terminated by a single \0) */
if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
return -FDT_ERR_BADVALUE;
/* keep end marker to avoid strlen() */
e = path + path_len;
/* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
if (*path != '/')
return -FDT_ERR_BADVALUE;
/* get fragment name first */
s = strchr(path + 1, '/');
if (!s)
return -FDT_ERR_BADOVERLAY;
frag_name = path + 1;
frag_name_len = s - path - 1;
/* verify format; safe since "s" lies in \0 terminated prop */
len = sizeof("/__overlay__/") - 1;
if ((e - s) < len || memcmp(s, "/__overlay__/", len))
return -FDT_ERR_BADOVERLAY;
rel_path = s + len;
rel_path_len = e - rel_path;
/* find the fragment index in which the symbol lies */
ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
frag_name_len);
/* not found? */
if (ret < 0)
return -FDT_ERR_BADOVERLAY;
fragment = ret;
/* an __overlay__ subnode must exist */
ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
if (ret < 0)
return -FDT_ERR_BADOVERLAY;
/* get the target of the fragment */
ret = overlay_get_target(fdt, fdto, fragment, &target_path);
if (ret < 0)
return ret;
target = ret;
/* if we have a target path use */
if (!target_path) {
ret = get_path_len(fdt, target);
if (ret < 0)
return ret;
len = ret;
} else {
len = strlen(target_path);
}
ret = fdt_setprop_placeholder(fdt, root_sym, name,
len + (len > 1) + rel_path_len + 1, &p);
if (ret < 0)
return ret;
if (!target_path) {
/* again in case setprop_placeholder changed it */
ret = overlay_get_target(fdt, fdto, fragment, &target_path);
if (ret < 0)
return ret;
target = ret;
}
buf = p;
if (len > 1) { /* target is not root */
if (!target_path) {
ret = fdt_get_path(fdt, target, buf, len + 1);
if (ret < 0)
return ret;
} else
memcpy(buf, target_path, len + 1);
} else
len--;
buf[len] = '/';
memcpy(buf + len + 1, rel_path, rel_path_len);
buf[len + 1 + rel_path_len] = '\0';
}
return 0;
}
int fdt_overlay_apply(void *fdt, void *fdto)
{
uint32_t delta = fdt_get_max_phandle(fdt);
int ret;
FDT_CHECK_HEADER(fdt);
FDT_CHECK_HEADER(fdto);
ret = overlay_adjust_local_phandles(fdto, delta);
if (ret)
goto err;
ret = overlay_update_local_references(fdto, delta);
if (ret)
goto err;
ret = overlay_fixup_phandles(fdt, fdto);
if (ret)
goto err;
ret = overlay_merge(fdt, fdto);
if (ret)
goto err;
ret = overlay_symbol_update(fdt, fdto);
if (ret)
goto err;
/*
* The overlay has been damaged, erase its magic.
*/
fdt_set_magic(fdto, ~0);
return 0;
err:
/*
* The overlay might have been damaged, erase its magic.
*/
fdt_set_magic(fdto, ~0);
/*
* The base device tree might have been damaged, erase its
* magic.
*/
fdt_set_magic(fdt, ~0);
return ret;
}

@ -216,6 +216,28 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
return old_node;
}
void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
{
static unsigned int next_orphan_fragment = 0;
struct node *node;
struct property *p;
struct data d = empty_data;
char *name;
d = data_add_marker(d, REF_PHANDLE, ref);
d = data_append_integer(d, 0xffffffff, 32);
p = build_property("target", d);
xasprintf(&name, "fragment@%u",
next_orphan_fragment++);
name_node(new_node, "__overlay__");
node = build_node(p, new_node);
name_node(node, name);
add_child(dt, node);
}
struct node *chain_node(struct node *first, struct node *list)
{
assert(first->next_sibling == NULL);
@ -396,6 +418,12 @@ cell_t propval_cell(struct property *prop)
return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
}
cell_t propval_cell_n(struct property *prop, int n)
{
assert(prop->val.len / sizeof(cell_t) >= n);
return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
}
struct property *get_property_by_label(struct node *tree, const char *label,
struct node **node)
{

@ -1 +1 @@
#define DTC_VERSION "DTC 1.4.4-gfe50bd1e"
#define DTC_VERSION "DTC 1.4.5-gb1a60033"

Loading…
Cancel
Save