1 From a77725a9a3c5924e2fd4cd5b3557dd92a8e46f87 Mon Sep 17 00:00:00 2001
2 From: Rob Herring <robh@kernel.org>
3 Date: Mon, 25 Oct 2021 11:05:45 -0500
4 Subject: [PATCH 1/1] scripts/dtc: Update to upstream version
5 v1.6.1-19-g0a3a9d3449c8
7 This adds the following commits from upstream:
9 0a3a9d3449c8 checks: Add an interrupt-map check
10 8fd24744e361 checks: Ensure '#interrupt-cells' only exists in interrupt providers
11 d8d1a9a77863 checks: Drop interrupt provider '#address-cells' check
12 52a16fd72824 checks: Make interrupt_provider check dependent on interrupts_extended_is_cell
13 37fd700685da treesource: Maintain phandle label/path on output
14 e33ce1d6a8c7 flattree: Use '\n', not ';' to separate asm pseudo-ops
15 d24cc189dca6 asm: Use assembler macros instead of cpp macros
16 ff3a30c115ad asm: Use .asciz and .ascii instead of .string
17 5eb5927d81ee fdtdump: fix -Werror=int-to-pointer-cast
18 0869f8269161 libfdt: Add ALIGNMENT error string
19 69595a167f06 checks: Fix bus-range check
20 72d09e2682a4 Makefile: add -Wsign-compare to warning options
21 b587787ef388 checks: Fix signedness comparisons warnings
22 69bed6c2418f dtc: Wrap phandle validity check
23 910221185560 fdtget: Fix signedness comparisons warnings
24 d966f08fcd21 tests: Fix signedness comparisons warnings
25 ecfb438c07fa dtc: Fix signedness comparisons warnings: pointer diff
26 5bec74a6d135 dtc: Fix signedness comparisons warnings: reservednum
27 24e7f511fd4a fdtdump: Fix signedness comparisons warnings
28 b6910bec1161 Bump version to v1.6.1
29 21d61d18f968 Fix CID 1461557
30 4c2ef8f4d14c checks: Introduce is_multiple_of()
31 e59ca36fb70e Make handling of cpp line information more tolerant
32 0c3fd9b6aceb checks: Drop interrupt_cells_is_cell check
33 6b3081abc4ac checks: Add check_is_cell() for all phandle+arg properties
34 2dffc192a77f yamltree: Remove marker ordering dependency
35 61e513439e40 pylibfdt: Rework "avoid unused variable warning" lines
36 c8bddd106095 tests: add a positive gpio test case
37 ad4abfadb687 checks: replace strstr and strrchr with strends
38 09c6a6e88718 dtc.h: add strends for suffix matching
39 9bb9b8d0b4a0 checks: tigthen up nr-gpios prop exception
40 b07b62ee3342 libfdt: Add FDT alignment check to fdt_check_header()
41 a2def5479950 libfdt: Check that the root-node name is empty
42 4ca61f84dc21 libfdt: Check that there is only one root node
43 34d708249a91 dtc: Remove -O dtbo support
44 8e7ff260f755 libfdt: Fix a possible "unchecked return value" warning
45 88875268c05c checks: Warn on node-name and property name being the same
46 9d2279e7e6ee checks: Change node-name check to match devicetree spec
47 f527c867a8c6 util: limit gnu_printf format attribute to gcc >= 4.4.0
49 Reviewed-by: Frank Rowand <frank.rowand@sony.com>
50 Tested-by: Frank Rowand <frank.rowand@sony.com>
51 Signed-off-by: Rob Herring <robh@kernel.org>
53 scripts/dtc/checks.c | 222 ++++++++++++++++++++++--------
54 scripts/dtc/dtc-lexer.l | 2 +-
55 scripts/dtc/dtc.c | 6 +-
56 scripts/dtc/dtc.h | 40 +++++-
57 scripts/dtc/flattree.c | 11 +-
58 scripts/dtc/libfdt/fdt.c | 4 +
59 scripts/dtc/libfdt/fdt_rw.c | 18 ++-
60 scripts/dtc/libfdt/fdt_strerror.c | 1 +
61 scripts/dtc/libfdt/libfdt.h | 7 +
62 scripts/dtc/livetree.c | 6 +-
63 scripts/dtc/treesource.c | 48 +++----
64 scripts/dtc/util.h | 6 +-
65 scripts/dtc/version_gen.h | 2 +-
66 scripts/dtc/yamltree.c | 16 ++-
67 14 files changed, 275 insertions(+), 114 deletions(-)
69 --- a/scripts/dtc/checks.c
70 +++ b/scripts/dtc/checks.c
71 @@ -143,6 +143,14 @@ static void check_nodes_props(struct che
72 check_nodes_props(c, dti, child);
75 +static bool is_multiple_of(int multiple, int divisor)
78 + return multiple == 0;
80 + return (multiple % divisor) == 0;
83 static bool run_check(struct check *c, struct dt_info *dti)
85 struct node *dt = dti->dt;
86 @@ -297,19 +305,20 @@ ERROR(duplicate_property_names, check_du
87 #define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
88 #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
89 #define DIGITS "0123456789"
90 -#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
91 +#define NODECHARS LOWERCASE UPPERCASE DIGITS ",._+-@"
92 +#define PROPCHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
93 #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-"
95 static void check_node_name_chars(struct check *c, struct dt_info *dti,
98 - int n = strspn(node->name, c->data);
99 + size_t n = strspn(node->name, c->data);
101 if (n < strlen(node->name))
102 FAIL(c, dti, node, "Bad character '%c' in node name",
105 -ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
106 +ERROR(node_name_chars, check_node_name_chars, NODECHARS);
108 static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
110 @@ -330,6 +339,20 @@ static void check_node_name_format(struc
112 ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
114 +static void check_node_name_vs_property_name(struct check *c,
115 + struct dt_info *dti,
121 + if (get_property(node->parent, node->name)) {
122 + FAIL(c, dti, node, "node name and property name conflict");
125 +WARNING(node_name_vs_property_name, check_node_name_vs_property_name,
126 + NULL, &node_name_chars);
128 static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
131 @@ -363,14 +386,14 @@ static void check_property_name_chars(st
132 struct property *prop;
134 for_each_property(node, prop) {
135 - int n = strspn(prop->name, c->data);
136 + size_t n = strspn(prop->name, c->data);
138 if (n < strlen(prop->name))
139 FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name",
143 -ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
144 +ERROR(property_name_chars, check_property_name_chars, PROPCHARS);
146 static void check_property_name_chars_strict(struct check *c,
148 @@ -380,7 +403,7 @@ static void check_property_name_chars_st
150 for_each_property(node, prop) {
151 const char *name = prop->name;
152 - int n = strspn(name, c->data);
153 + size_t n = strspn(name, c->data);
155 if (n == strlen(prop->name))
157 @@ -497,7 +520,7 @@ static cell_t check_phandle_prop(struct
159 phandle = propval_cell(prop);
161 - if ((phandle == 0) || (phandle == -1)) {
162 + if (!phandle_is_valid(phandle)) {
163 FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property",
164 phandle, prop->name);
166 @@ -556,7 +579,7 @@ static void check_name_properties(struct
168 return; /* No name property, that's fine */
170 - if ((prop->val.len != node->basenamelen+1)
171 + if ((prop->val.len != node->basenamelen + 1U)
172 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
173 FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead"
174 " of base node name)", prop->val.val);
175 @@ -657,7 +680,6 @@ ERROR(omit_unused_nodes, fixup_omit_unus
177 WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
178 WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
179 -WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
181 WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
182 WARNING_IF_NOT_STRING(model_is_string, "model");
183 @@ -672,8 +694,7 @@ static void check_names_is_string_list(s
184 struct property *prop;
186 for_each_property(node, prop) {
187 - const char *s = strrchr(prop->name, '-');
188 - if (!s || !streq(s, "-names"))
189 + if (!strends(prop->name, "-names"))
192 c->data = prop->name;
193 @@ -753,7 +774,7 @@ static void check_reg_format(struct chec
194 size_cells = node_size_cells(node->parent);
195 entrylen = (addr_cells + size_cells) * sizeof(cell_t);
197 - if (!entrylen || (prop->val.len % entrylen) != 0)
198 + if (!is_multiple_of(prop->val.len, entrylen))
199 FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) "
200 "(#address-cells == %d, #size-cells == %d)",
201 prop->val.len, addr_cells, size_cells);
202 @@ -794,7 +815,7 @@ static void check_ranges_format(struct c
203 "#size-cells (%d) differs from %s (%d)",
204 ranges, c_size_cells, node->parent->fullpath,
206 - } else if ((prop->val.len % entrylen) != 0) {
207 + } else if (!is_multiple_of(prop->val.len, entrylen)) {
208 FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) "
209 "(parent #address-cells == %d, child #address-cells == %d, "
210 "#size-cells == %d)", ranges, prop->val.len,
211 @@ -871,7 +892,7 @@ static void check_pci_device_bus_num(str
213 cells = (cell_t *)prop->val.val;
214 min_bus = fdt32_to_cpu(cells[0]);
215 - max_bus = fdt32_to_cpu(cells[0]);
216 + max_bus = fdt32_to_cpu(cells[1]);
218 if ((bus_num < min_bus) || (bus_num > max_bus))
219 FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)",
220 @@ -1367,9 +1388,9 @@ static void check_property_phandle_args(
221 const struct provider *provider)
223 struct node *root = dti->dt;
224 - int cell, cellsize = 0;
225 + unsigned int cell, cellsize = 0;
227 - if (prop->val.len % sizeof(cell_t)) {
228 + if (!is_multiple_of(prop->val.len, sizeof(cell_t))) {
229 FAIL_PROP(c, dti, node, prop,
230 "property size (%d) is invalid, expected multiple of %zu",
231 prop->val.len, sizeof(cell_t));
232 @@ -1379,14 +1400,14 @@ static void check_property_phandle_args(
233 for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
234 struct node *provider_node;
235 struct property *cellprop;
239 phandle = propval_cell_n(prop, cell);
241 * Some bindings use a cell value 0 or -1 to skip over optional
242 * entries when each index position has a specific definition.
244 - if (phandle == 0 || phandle == -1) {
245 + if (!phandle_is_valid(phandle)) {
246 /* Give up if this is an overlay with external references */
247 if (dti->dtsflags & DTSF_PLUGIN)
249 @@ -1452,7 +1473,8 @@ static void check_provider_cells_propert
251 #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
252 static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
253 - WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
254 + WARNING_IF_NOT_CELL(nm##_is_cell, cells_name); \
255 + WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &nm##_is_cell, &phandle_references);
257 WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
258 WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
259 @@ -1473,24 +1495,17 @@ WARNING_PROPERTY_PHANDLE_CELLS(thermal_s
261 static bool prop_is_gpio(struct property *prop)
266 * *-gpios and *-gpio can appear in property names,
267 * so skip over any false matches (only one known ATM)
269 - if (strstr(prop->name, "nr-gpio"))
270 + if (strends(prop->name, ",nr-gpios"))
273 - str = strrchr(prop->name, '-');
278 - if (!(streq(str, "gpios") || streq(str, "gpio")))
282 + return strends(prop->name, "-gpios") ||
283 + streq(prop->name, "gpios") ||
284 + strends(prop->name, "-gpio") ||
285 + streq(prop->name, "gpio");
288 static void check_gpios_property(struct check *c,
289 @@ -1525,13 +1540,10 @@ static void check_deprecated_gpio_proper
290 struct property *prop;
292 for_each_property(node, prop) {
295 if (!prop_is_gpio(prop))
298 - str = strstr(prop->name, "gpio");
299 - if (!streq(str, "gpio"))
300 + if (!strends(prop->name, "gpio"))
303 FAIL_PROP(c, dti, node, prop,
304 @@ -1561,21 +1573,106 @@ static void check_interrupt_provider(str
307 struct property *prop;
308 + bool irq_provider = node_is_interrupt_provider(node);
310 - if (!node_is_interrupt_provider(node))
311 + prop = get_property(node, "#interrupt-cells");
312 + if (irq_provider && !prop) {
314 + "Missing '#interrupt-cells' in interrupt provider");
318 - prop = get_property(node, "#interrupt-cells");
320 + if (!irq_provider && prop) {
322 - "Missing #interrupt-cells in interrupt provider");
323 + "'#interrupt-cells' found, but node is not an interrupt provider");
327 +WARNING(interrupt_provider, check_interrupt_provider, NULL, &interrupts_extended_is_cell);
329 - prop = get_property(node, "#address-cells");
331 +static void check_interrupt_map(struct check *c,
332 + struct dt_info *dti,
335 + struct node *root = dti->dt;
336 + struct property *prop, *irq_map_prop;
337 + size_t cellsize, cell, map_cells;
339 + irq_map_prop = get_property(node, "interrupt-map");
343 + if (node->addr_cells < 0) {
345 - "Missing #address-cells in interrupt provider");
346 + "Missing '#address-cells' in interrupt-map provider");
349 + cellsize = node_addr_cells(node);
350 + cellsize += propval_cell(get_property(node, "#interrupt-cells"));
352 + prop = get_property(node, "interrupt-map-mask");
353 + if (prop && (prop->val.len != (cellsize * sizeof(cell_t))))
354 + FAIL_PROP(c, dti, node, prop,
355 + "property size (%d) is invalid, expected %zu",
356 + prop->val.len, cellsize * sizeof(cell_t));
358 + if (!is_multiple_of(irq_map_prop->val.len, sizeof(cell_t))) {
359 + FAIL_PROP(c, dti, node, irq_map_prop,
360 + "property size (%d) is invalid, expected multiple of %zu",
361 + irq_map_prop->val.len, sizeof(cell_t));
365 + map_cells = irq_map_prop->val.len / sizeof(cell_t);
366 + for (cell = 0; cell < map_cells; ) {
367 + struct node *provider_node;
368 + struct property *cellprop;
370 + size_t parent_cellsize;
372 + if ((cell + cellsize) >= map_cells) {
373 + FAIL_PROP(c, dti, node, irq_map_prop,
374 + "property size (%d) too small, expected > %zu",
375 + irq_map_prop->val.len, (cell + cellsize) * sizeof(cell_t));
380 + phandle = propval_cell_n(irq_map_prop, cell);
381 + if (!phandle_is_valid(phandle)) {
382 + /* Give up if this is an overlay with external references */
383 + if (!(dti->dtsflags & DTSF_PLUGIN))
384 + FAIL_PROP(c, dti, node, irq_map_prop,
385 + "Cell %zu is not a phandle(%d)",
390 + provider_node = get_node_by_phandle(root, phandle);
391 + if (!provider_node) {
392 + FAIL_PROP(c, dti, node, irq_map_prop,
393 + "Could not get phandle(%d) node for (cell %zu)",
398 + cellprop = get_property(provider_node, "#interrupt-cells");
400 + parent_cellsize = propval_cell(cellprop);
402 + FAIL(c, dti, node, "Missing property '#interrupt-cells' in node %s or bad phandle (referred from interrupt-map[%zu])",
403 + provider_node->fullpath, cell);
407 + cellprop = get_property(provider_node, "#address-cells");
409 + parent_cellsize += propval_cell(cellprop);
411 + cell += 1 + parent_cellsize;
414 -WARNING(interrupt_provider, check_interrupt_provider, NULL);
415 +WARNING(interrupt_map, check_interrupt_map, NULL, &phandle_references, &addr_size_cells, &interrupt_provider);
417 static void check_interrupts_property(struct check *c,
419 @@ -1584,13 +1681,13 @@ static void check_interrupts_property(st
420 struct node *root = dti->dt;
421 struct node *irq_node = NULL, *parent = node;
422 struct property *irq_prop, *prop = NULL;
423 - int irq_cells, phandle;
424 + cell_t irq_cells, phandle;
426 irq_prop = get_property(node, "interrupts");
430 - if (irq_prop->val.len % sizeof(cell_t))
431 + if (!is_multiple_of(irq_prop->val.len, sizeof(cell_t)))
432 FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu",
433 irq_prop->val.len, sizeof(cell_t));
435 @@ -1603,7 +1700,7 @@ static void check_interrupts_property(st
436 prop = get_property(parent, "interrupt-parent");
438 phandle = propval_cell(prop);
439 - if ((phandle == 0) || (phandle == -1)) {
440 + if (!phandle_is_valid(phandle)) {
441 /* Give up if this is an overlay with
442 * external references */
443 if (dti->dtsflags & DTSF_PLUGIN)
444 @@ -1639,7 +1736,7 @@ static void check_interrupts_property(st
447 irq_cells = propval_cell(prop);
448 - if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
449 + if (!is_multiple_of(irq_prop->val.len, irq_cells * sizeof(cell_t))) {
450 FAIL_PROP(c, dti, node, prop,
451 "size is (%d), expected multiple of %d",
452 irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)));
453 @@ -1750,7 +1847,7 @@ WARNING(graph_port, check_graph_port, NU
454 static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
455 struct node *endpoint)
460 struct property *prop;
462 @@ -1760,7 +1857,7 @@ static struct node *get_remote_endpoint(
464 phandle = propval_cell(prop);
465 /* Give up if this is an overlay with external references */
466 - if (phandle == 0 || phandle == -1)
467 + if (!phandle_is_valid(phandle))
470 node = get_node_by_phandle(dti->dt, phandle);
471 @@ -1796,7 +1893,7 @@ WARNING(graph_endpoint, check_graph_endp
472 static struct check *check_table[] = {
473 &duplicate_node_names, &duplicate_property_names,
474 &node_name_chars, &node_name_format, &property_name_chars,
475 - &name_is_string, &name_properties,
476 + &name_is_string, &name_properties, &node_name_vs_property_name,
480 @@ -1804,7 +1901,7 @@ static struct check *check_table[] = {
481 &phandle_references, &path_references,
484 - &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
485 + &address_cells_is_cell, &size_cells_is_cell,
486 &device_type_is_string, &model_is_string, &status_is_string,
489 @@ -1839,26 +1936,43 @@ static struct check *check_table[] = {
490 &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
494 &cooling_device_property,
495 + &cooling_device_is_cell,
500 &interrupts_extended_property,
501 + &interrupts_extended_is_cell,
502 &io_channels_property,
503 + &io_channels_is_cell,
508 &msi_parent_property,
509 + &msi_parent_is_cell,
510 &mux_controls_property,
511 + &mux_controls_is_cell,
514 &power_domains_property,
515 + &power_domains_is_cell,
521 + &sound_dai_is_cell,
522 &thermal_sensors_property,
523 + &thermal_sensors_is_cell,
525 &deprecated_gpio_property,
527 &interrupts_property,
533 @@ -1882,7 +1996,7 @@ static void enable_warning_error(struct
535 static void disable_warning_error(struct check *c, bool warn, bool error)
540 /* Lowering level, also lower it for things this is the prereq
542 @@ -1903,7 +2017,7 @@ static void disable_warning_error(struct
544 void parse_checks_option(bool warn, bool error, const char *arg)
548 const char *name = arg;
551 @@ -1930,7 +2044,7 @@ void parse_checks_option(bool warn, bool
553 void process_checks(bool force, struct dt_info *dti)
559 for (i = 0; i < ARRAY_SIZE(check_table); i++) {
560 --- a/scripts/dtc/dtc-lexer.l
561 +++ b/scripts/dtc/dtc-lexer.l
562 @@ -57,7 +57,7 @@ static void PRINTF(1, 2) lexical_error(c
563 push_input_file(name);
566 -<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
567 +<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)* {
568 char *line, *fnstart, *fnend;
570 /* skip text before line # */
571 --- a/scripts/dtc/dtc.c
572 +++ b/scripts/dtc/dtc.c
574 * Command line options
576 int quiet; /* Level of quietness */
577 -int reservenum; /* Number of memory reservation slots */
578 +unsigned int reservenum;/* Number of memory reservation slots */
579 int minsize; /* Minimum blob size */
580 int padsize; /* Additional padding to blob */
581 int alignsize; /* Additional padding to blob accroding to the alignsize */
582 @@ -197,7 +197,7 @@ int main(int argc, char *argv[])
586 - reservenum = strtol(optarg, NULL, 0);
587 + reservenum = strtoul(optarg, NULL, 0);
590 minsize = strtol(optarg, NULL, 0);
591 @@ -359,8 +359,6 @@ int main(int argc, char *argv[])
593 } else if (streq(outform, "dtb")) {
594 dt_to_blob(outf, dti, outversion);
595 - } else if (streq(outform, "dtbo")) {
596 - dt_to_blob(outf, dti, outversion);
597 } else if (streq(outform, "asm")) {
598 dt_to_asm(outf, dti, outversion);
599 } else if (streq(outform, "null")) {
600 --- a/scripts/dtc/dtc.h
601 +++ b/scripts/dtc/dtc.h
603 * Command line options
605 extern int quiet; /* Level of quietness */
606 -extern int reservenum; /* Number of memory reservation slots */
607 +extern unsigned int reservenum; /* Number of memory reservation slots */
608 extern int minsize; /* Minimum blob size */
609 extern int padsize; /* Additional padding to blob */
610 extern int alignsize; /* Additional padding to blob accroding to the alignsize */
611 @@ -51,6 +51,11 @@ extern int annotate; /* annotate .dts w
613 typedef uint32_t cell_t;
615 +static inline bool phandle_is_valid(cell_t phandle)
617 + return phandle != 0 && phandle != ~0U;
620 static inline uint16_t dtb_ld16(const void *p)
622 const uint8_t *bp = (const uint8_t *)p;
623 @@ -86,6 +91,16 @@ static inline uint64_t dtb_ld64(const vo
624 #define streq(a, b) (strcmp((a), (b)) == 0)
625 #define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0)
626 #define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0))
627 +static inline bool strends(const char *str, const char *suffix)
629 + unsigned int len, suffix_len;
632 + suffix_len = strlen(suffix);
633 + if (len < suffix_len)
635 + return streq(str + len - suffix_len, suffix);
638 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
640 @@ -101,6 +116,12 @@ enum markertype {
645 +static inline bool is_type_marker(enum markertype type)
647 + return type >= TYPE_UINT8;
650 extern const char *markername(enum markertype markertype);
653 @@ -125,7 +146,22 @@ struct data {
655 if ((m)->type == (t))
657 -size_t type_marker_length(struct marker *m);
658 +static inline struct marker *next_type_marker(struct marker *m)
661 + if (is_type_marker(m->type))
666 +static inline size_t type_marker_length(struct marker *m)
668 + struct marker *next = next_type_marker(m->next);
671 + return next->offset - m->offset;
675 void data_free(struct data d);
677 --- a/scripts/dtc/flattree.c
678 +++ b/scripts/dtc/flattree.c
679 @@ -124,7 +124,8 @@ static void asm_emit_cell(void *e, cell_
683 - fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
684 + fprintf(f, "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n"
685 + "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n",
686 (val >> 24) & 0xff, (val >> 16) & 0xff,
687 (val >> 8) & 0xff, val & 0xff);
689 @@ -134,9 +135,9 @@ static void asm_emit_string(void *e, con
693 - fprintf(f, "\t.string\t\"%.*s\"\n", len, str);
694 + fprintf(f, "\t.asciz\t\"%.*s\"\n", len, str);
696 - fprintf(f, "\t.string\t\"%s\"\n", str);
697 + fprintf(f, "\t.asciz\t\"%s\"\n", str);
700 static void asm_emit_align(void *e, int a)
701 @@ -295,7 +296,7 @@ static struct data flatten_reserve_list(
703 struct reserve_info *re;
704 struct data d = empty_data;
708 for (re = reservelist; re; re = re->next) {
709 d = data_append_re(d, re->address, re->size);
710 @@ -438,7 +439,7 @@ static void dump_stringtable_asm(FILE *f
712 while (p < (strbuf.val + strbuf.len)) {
714 - fprintf(f, "\t.string \"%s\"\n", p);
715 + fprintf(f, "\t.asciz \"%s\"\n", p);
719 --- a/scripts/dtc/libfdt/fdt.c
720 +++ b/scripts/dtc/libfdt/fdt.c
721 @@ -90,6 +90,10 @@ int fdt_check_header(const void *fdt)
725 + /* The device tree must be at an 8-byte aligned address */
726 + if ((uintptr_t)fdt & 7)
727 + return -FDT_ERR_ALIGNMENT;
729 if (fdt_magic(fdt) != FDT_MAGIC)
730 return -FDT_ERR_BADMAGIC;
731 if (!can_assume(LATEST)) {
732 --- a/scripts/dtc/libfdt/fdt_rw.c
733 +++ b/scripts/dtc/libfdt/fdt_rw.c
734 @@ -349,7 +349,10 @@ int fdt_add_subnode_namelen(void *fdt, i
737 /* Try to place the new node after the parent's properties */
738 - fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
739 + tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
740 + /* the fdt_subnode_offset_namelen() should ensure this never hits */
741 + if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE))
742 + return -FDT_ERR_INTERNAL;
745 tag = fdt_next_tag(fdt, offset, &nextoffset);
746 @@ -391,7 +394,9 @@ int fdt_del_node(void *fdt, int nodeoffs
749 static void fdt_packblocks_(const char *old, char *new,
750 - int mem_rsv_size, int struct_size)
755 int mem_rsv_off, struct_off, strings_off;
757 @@ -406,8 +411,7 @@ static void fdt_packblocks_(const char *
758 fdt_set_off_dt_struct(new, struct_off);
759 fdt_set_size_dt_struct(new, struct_size);
761 - memmove(new + strings_off, old + fdt_off_dt_strings(old),
762 - fdt_size_dt_strings(old));
763 + memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size);
764 fdt_set_off_dt_strings(new, strings_off);
765 fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
767 @@ -467,7 +471,8 @@ int fdt_open_into(const void *fdt, void
768 return -FDT_ERR_NOSPACE;
771 - fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size);
772 + fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size,
773 + fdt_size_dt_strings(fdt));
774 memmove(buf, tmp, newsize);
776 fdt_set_magic(buf, FDT_MAGIC);
777 @@ -487,7 +492,8 @@ int fdt_pack(void *fdt)
779 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
780 * sizeof(struct fdt_reserve_entry);
781 - fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
782 + fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt),
783 + fdt_size_dt_strings(fdt));
784 fdt_set_totalsize(fdt, fdt_data_size_(fdt));
787 --- a/scripts/dtc/libfdt/fdt_strerror.c
788 +++ b/scripts/dtc/libfdt/fdt_strerror.c
789 @@ -39,6 +39,7 @@ static struct fdt_errtabent fdt_errtable
790 FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
791 FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
792 FDT_ERRTABENT(FDT_ERR_BADFLAGS),
793 + FDT_ERRTABENT(FDT_ERR_ALIGNMENT),
795 #define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0])))
797 --- a/scripts/dtc/libfdt/libfdt.h
798 +++ b/scripts/dtc/libfdt/libfdt.h
799 @@ -131,6 +131,13 @@ uint32_t fdt_next_tag(const void *fdt, i
800 * to work even with unaligned pointers on platforms (such as ARMv5) that don't
801 * like unaligned loads and stores.
803 +static inline uint16_t fdt16_ld(const fdt16_t *p)
805 + const uint8_t *bp = (const uint8_t *)p;
807 + return ((uint16_t)bp[0] << 8) | bp[1];
810 static inline uint32_t fdt32_ld(const fdt32_t *p)
812 const uint8_t *bp = (const uint8_t *)p;
813 --- a/scripts/dtc/livetree.c
814 +++ b/scripts/dtc/livetree.c
815 @@ -526,7 +526,7 @@ struct node *get_node_by_path(struct nod
816 p = strchr(path, '/');
818 for_each_child(tree, child) {
819 - if (p && strprefixeq(path, p - path, child->name))
820 + if (p && strprefixeq(path, (size_t)(p - path), child->name))
821 return get_node_by_path(child, p+1);
822 else if (!p && streq(path, child->name))
824 @@ -559,7 +559,7 @@ struct node *get_node_by_phandle(struct
826 struct node *child, *node;
828 - if ((phandle == 0) || (phandle == -1)) {
829 + if (!phandle_is_valid(phandle)) {
830 assert(generate_fixups);
833 @@ -594,7 +594,7 @@ cell_t get_node_phandle(struct node *roo
834 static cell_t phandle = 1; /* FIXME: ick, static local */
835 struct data d = empty_data;
837 - if ((node->phandle != 0) && (node->phandle != -1))
838 + if (phandle_is_valid(node->phandle))
839 return node->phandle;
841 while (get_node_by_phandle(root, phandle))
842 --- a/scripts/dtc/treesource.c
843 +++ b/scripts/dtc/treesource.c
844 @@ -124,27 +124,6 @@ static void write_propval_int(FILE *f, c
848 -static bool has_data_type_information(struct marker *m)
850 - return m->type >= TYPE_UINT8;
853 -static struct marker *next_type_marker(struct marker *m)
855 - while (m && !has_data_type_information(m))
860 -size_t type_marker_length(struct marker *m)
862 - struct marker *next = next_type_marker(m->next);
865 - return next->offset - m->offset;
869 static const char *delim_start[] = {
871 [TYPE_UINT16] = "/bits/ 16 <",
872 @@ -229,26 +208,39 @@ static void write_propval(FILE *f, struc
873 size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
874 size_t data_len = type_marker_length(m) ? : len - m->offset;
875 const char *p = &prop->val.val[m->offset];
876 + struct marker *m_phandle;
878 - if (has_data_type_information(m)) {
879 + if (is_type_marker(m->type)) {
881 fprintf(f, " %s", delim_start[emit_type]);
882 } else if (m->type == LABEL)
883 fprintf(f, " %s:", m->ref);
884 - else if (m->offset)
887 - if (emit_type == TYPE_NONE) {
888 - assert(chunk_len == 0);
889 + if (emit_type == TYPE_NONE || chunk_len == 0)
895 write_propval_int(f, p, chunk_len, 2);
898 - write_propval_int(f, p, chunk_len, 4);
899 + m_phandle = prop->val.markers;
900 + for_each_marker_of_type(m_phandle, REF_PHANDLE)
901 + if (m->offset == m_phandle->offset)
905 + if (m_phandle->ref[0] == '/')
906 + fprintf(f, "&{%s}", m_phandle->ref);
908 + fprintf(f, "&%s", m_phandle->ref);
909 + if (chunk_len > 4) {
911 + write_propval_int(f, p + 4, chunk_len - 4, 4);
914 + write_propval_int(f, p, chunk_len, 4);
918 write_propval_int(f, p, chunk_len, 8);
919 --- a/scripts/dtc/util.h
920 +++ b/scripts/dtc/util.h
926 -#define PRINTF(i, j) __attribute__((format (printf, i, j)))
928 +#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
929 #define PRINTF(i, j) __attribute__((format (gnu_printf, i, j)))
931 +#define PRINTF(i, j) __attribute__((format (printf, i, j)))
933 #define NORETURN __attribute__((noreturn))
935 --- a/scripts/dtc/version_gen.h
936 +++ b/scripts/dtc/version_gen.h
938 -#define DTC_VERSION "DTC 1.6.0-g183df9e9"
939 +#define DTC_VERSION "DTC 1.6.1-g0a3a9d34"
940 --- a/scripts/dtc/yamltree.c
941 +++ b/scripts/dtc/yamltree.c
942 @@ -29,11 +29,12 @@ char *yaml_error_name[] = {
943 (emitter)->problem, __func__, __LINE__); \
946 -static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, char *data, unsigned int len, int width)
947 +static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers,
948 + char *data, unsigned int seq_offset, unsigned int len, int width)
952 - unsigned int off, start_offset = markers->offset;
956 case 1: tag = "!u8"; break;
957 @@ -66,7 +67,7 @@ static void yaml_propval_int(yaml_emitte
960 for_each_marker_of_type(m, REF_PHANDLE) {
961 - if (m->offset == (start_offset + off)) {
962 + if (m->offset == (seq_offset + off)) {
966 @@ -114,6 +115,7 @@ static void yaml_propval(yaml_emitter_t
968 unsigned int len = prop->val.len;
969 struct marker *m = prop->val.markers;
970 + struct marker *markers = prop->val.markers;
972 /* Emit the property name */
973 yaml_scalar_event_initialize(&event, NULL,
974 @@ -151,19 +153,19 @@ static void yaml_propval(yaml_emitter_t
978 - yaml_propval_int(emitter, m, data, chunk_len, 2);
979 + yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 2);
982 - yaml_propval_int(emitter, m, data, chunk_len, 4);
983 + yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 4);
986 - yaml_propval_int(emitter, m, data, chunk_len, 8);
987 + yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 8);
990 yaml_propval_string(emitter, data, chunk_len);
993 - yaml_propval_int(emitter, m, data, chunk_len, 1);
994 + yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 1);