123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- From 5f84cb93eef9f8a8ff7f49d593893f252744d0fe Mon Sep 17 00:00:00 2001
- From: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
- Date: Wed, 26 Aug 2015 18:28:08 +0300
- Subject: [PATCH] scripts/dtc: Update to version with overlays
- Update to mainline dtc with overlay support
- Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
- ---
- checks.c | 20 +++++-
- dtc-lexer.l | 5 ++
- dtc-parser.y | 54 ++++++++++++++--
- dtc.c | 83 ++++++++++++++++++++++--
- dtc.h | 13 +++-
- livetree.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- treesource.c | 3 +
- util.c | 2 +-
- 8 files changed, 367 insertions(+), 15 deletions(-)
- diff --git a/checks.c b/checks.c
- index 3bf0fa4..af25c2b 100644
- --- a/checks.c
- +++ b/checks.c
- @@ -465,8 +465,12 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
-
- refnode = get_node_by_ref(dt, m->ref);
- if (! refnode) {
- - FAIL(c, "Reference to non-existent node or label \"%s\"\n",
- - m->ref);
- + if (!source_is_plugin)
- + FAIL(c, "Reference to non-existent node or "
- + "label \"%s\"\n", m->ref);
- + else /* mark the entry as unresolved */
- + *((cell_t *)(prop->val.val + m->offset)) =
- + cpu_to_fdt32(0xffffffff);
- continue;
- }
-
- @@ -559,7 +563,7 @@ static void check_reg_format(struct check *c, struct node *dt,
- size_cells = node_size_cells(node->parent);
- entrylen = (addr_cells + size_cells) * sizeof(cell_t);
-
- - if ((prop->val.len % entrylen) != 0)
- + if (!entrylen || (prop->val.len % entrylen) != 0)
- FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
- "(#address-cells == %d, #size-cells == %d)",
- node->fullpath, prop->val.len, addr_cells, size_cells);
- @@ -651,6 +655,15 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
- }
- TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
-
- +static void check_deprecated_plugin_syntax(struct check *c,
- + struct node *dt)
- +{
- + if (deprecated_plugin_syntax_warning)
- + FAIL(c, "Use '/dts-v1/ /plugin/'; syntax. /dts-v1/; /plugin/; "
- + "is going to be removed in next versions");
- +}
- +TREE_WARNING(deprecated_plugin_syntax, NULL);
- +
- static struct check *check_table[] = {
- &duplicate_node_names, &duplicate_property_names,
- &node_name_chars, &node_name_format, &property_name_chars,
- @@ -668,6 +681,7 @@ static struct check *check_table[] = {
-
- &avoid_default_addr_size,
- &obsolete_chosen_interrupt_controller,
- + &deprecated_plugin_syntax,
-
- &always_fail,
- };
- diff --git a/dtc-lexer.l b/dtc-lexer.l
- index 0ee1caf..dd44ba2 100644
- --- a/dtc-lexer.l
- +++ b/dtc-lexer.l
- @@ -113,6 +113,11 @@ static void lexical_error(const char *fmt, ...);
- return DT_V1;
- }
-
- +<*>"/plugin/" {
- + DPRINT("Keyword: /plugin/\n");
- + return DT_PLUGIN;
- + }
- +
- <*>"/memreserve/" {
- DPRINT("Keyword: /memreserve/\n");
- BEGIN_DEFAULT();
- diff --git a/dtc-parser.y b/dtc-parser.y
- index ea57e0a..7d9652d 100644
- --- a/dtc-parser.y
- +++ b/dtc-parser.y
- @@ -19,6 +19,7 @@
- */
- %{
- #include <stdio.h>
- +#include <inttypes.h>
-
- #include "dtc.h"
- #include "srcpos.h"
- @@ -52,9 +53,11 @@ extern bool treesource_error;
- struct node *nodelist;
- struct reserve_info *re;
- uint64_t integer;
- + bool is_plugin;
- }
-
- %token DT_V1
- +%token DT_PLUGIN
- %token DT_MEMRESERVE
- %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
- %token DT_BITS
- @@ -71,6 +74,7 @@ extern bool treesource_error;
-
- %type <data> propdata
- %type <data> propdataprefix
- +%type <is_plugin> plugindecl
- %type <re> memreserve
- %type <re> memreserves
- %type <array> arrayprefix
- @@ -101,10 +105,39 @@ extern bool treesource_error;
- %%
-
- sourcefile:
- - DT_V1 ';' memreserves devicetree
- + basesource
- + | pluginsource
- + ;
- +
- +basesource:
- + DT_V1 ';' plugindecl memreserves devicetree
- + {
- + source_is_plugin = $3;
- + if (source_is_plugin)
- + deprecated_plugin_syntax_warning = true;
- + the_boot_info = build_boot_info($4, $5,
- + guess_boot_cpuid($5));
- + }
- + ;
- +
- +plugindecl:
- + /* empty */
- + {
- + $$ = false;
- + }
- + | DT_PLUGIN ';'
- + {
- + $$ = true;
- + }
- + ;
- +
- +pluginsource:
- + DT_V1 DT_PLUGIN ';' memreserves devicetree
- {
- - the_boot_info = build_boot_info($3, $4,
- - guess_boot_cpuid($4));
- + source_is_plugin = true;
- + deprecated_plugin_syntax_warning = false;
- + the_boot_info = build_boot_info($4, $5,
- + guess_boot_cpuid($5));
- }
- ;
-
- @@ -144,10 +177,14 @@ 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 {
- + if (symbol_fixup_support)
- + add_orphan_node($1, $3, $2);
- + else
- + ERROR(&@2, "Label or path %s not found", $2);
- + }
- $$ = $1;
- }
- | devicetree DT_DEL_NODE DT_REF ';'
- @@ -162,6 +199,11 @@ devicetree:
-
- $$ = $1;
- }
- + | /* empty */
- + {
- + /* build empty node */
- + $$ = name_node(build_node(NULL, NULL), "");
- + }
- ;
-
- nodedef:
- diff --git a/dtc.c b/dtc.c
- index 8c4add6..ee37be9 100644
- --- a/dtc.c
- +++ b/dtc.c
- @@ -18,6 +18,8 @@
- * USA
- */
-
- +#include <sys/stat.h>
- +
- #include "dtc.h"
- #include "srcpos.h"
-
- @@ -29,6 +31,8 @@ int reservenum; /* Number of memory reservation slots */
- int minsize; /* Minimum blob size */
- int padsize; /* Additional padding to blob */
- int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
- +int symbol_fixup_support;
- +int auto_label_aliases;
-
- static void fill_fullpaths(struct node *tree, const char *prefix)
- {
- @@ -51,7 +55,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
- #define FDT_VERSION(version) _FDT_VERSION(version)
- #define _FDT_VERSION(version) #version
- static const char usage_synopsis[] = "dtc [options] <input file>";
- -static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv";
- +static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:@Ahv";
- static struct option const usage_long_opts[] = {
- {"quiet", no_argument, NULL, 'q'},
- {"in-format", a_argument, NULL, 'I'},
- @@ -69,6 +73,8 @@ static struct option const usage_long_opts[] = {
- {"phandle", a_argument, NULL, 'H'},
- {"warning", a_argument, NULL, 'W'},
- {"error", a_argument, NULL, 'E'},
- + {"symbols", no_argument, NULL, '@'},
- + {"auto-alias", no_argument, NULL, 'A'},
- {"help", no_argument, NULL, 'h'},
- {"version", no_argument, NULL, 'v'},
- {NULL, no_argument, NULL, 0x0},
- @@ -99,16 +105,63 @@ static const char * const usage_opts_help[] = {
- "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
- "\n\tEnable/disable warnings (prefix with \"no-\")",
- "\n\tEnable/disable errors (prefix with \"no-\")",
- + "\n\tEnable symbols/fixup support",
- + "\n\tEnable auto-alias of labels",
- "\n\tPrint this help and exit",
- "\n\tPrint version and exit",
- NULL,
- };
-
- +static const char *guess_type_by_name(const char *fname, const char *fallback)
- +{
- + const char *s;
- +
- + s = strrchr(fname, '.');
- + if (s == NULL)
- + return fallback;
- + if (!strcasecmp(s, ".dts"))
- + return "dts";
- + if (!strcasecmp(s, ".dtb"))
- + return "dtb";
- + return fallback;
- +}
- +
- +static const char *guess_input_format(const char *fname, const char *fallback)
- +{
- + struct stat statbuf;
- + uint32_t magic;
- + FILE *f;
- +
- + if (stat(fname, &statbuf) != 0)
- + return fallback;
- +
- + if (S_ISDIR(statbuf.st_mode))
- + return "fs";
- +
- + if (!S_ISREG(statbuf.st_mode))
- + return fallback;
- +
- + f = fopen(fname, "r");
- + if (f == NULL)
- + return fallback;
- + if (fread(&magic, 4, 1, f) != 1) {
- + fclose(f);
- + return fallback;
- + }
- + fclose(f);
- +
- + magic = fdt32_to_cpu(magic);
- + if (magic == FDT_MAGIC)
- + return "dtb";
- +
- + return guess_type_by_name(fname, fallback);
- +}
- +
- int main(int argc, char *argv[])
- {
- struct boot_info *bi;
- - const char *inform = "dts";
- - const char *outform = "dts";
- + const char *inform = NULL;
- + const char *outform = NULL;
- const char *outname = "-";
- const char *depname = NULL;
- bool force = false, sort = false;
- @@ -186,7 +239,12 @@ int main(int argc, char *argv[])
- case 'E':
- parse_checks_option(false, true, optarg);
- break;
- -
- + case '@':
- + symbol_fixup_support = 1;
- + break;
- + case 'A':
- + auto_label_aliases = 1;
- + break;
- case 'h':
- usage(NULL);
- default:
- @@ -213,6 +271,17 @@ int main(int argc, char *argv[])
- fprintf(depfile, "%s:", outname);
- }
-
- + if (inform == NULL)
- + inform = guess_input_format(arg, "dts");
- + if (outform == NULL) {
- + outform = guess_type_by_name(outname, NULL);
- + if (outform == NULL) {
- + if (streq(inform, "dts"))
- + outform = "dtb";
- + else
- + outform = "dts";
- + }
- + }
- if (streq(inform, "dts"))
- bi = dt_from_source(arg);
- else if (streq(inform, "fs"))
- @@ -236,6 +305,12 @@ int main(int argc, char *argv[])
- if (sort)
- sort_tree(bi);
-
- + if (symbol_fixup_support || auto_label_aliases)
- + generate_label_node(bi->dt, bi->dt);
- +
- + if (symbol_fixup_support)
- + generate_fixups_node(bi->dt, bi->dt);
- +
- if (streq(outname, "-")) {
- outf = stdout;
- } else {
- diff --git a/dtc.h b/dtc.h
- index 56212c8..d025111 100644
- --- a/dtc.h
- +++ b/dtc.h
- @@ -20,7 +20,7 @@
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
- -
- +#define _GNU_SOURCE
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- @@ -54,6 +54,14 @@ extern int reservenum; /* Number of memory reservation slots */
- extern int minsize; /* Minimum blob size */
- extern int padsize; /* Additional padding to blob */
- extern int phandle_format; /* Use linux,phandle or phandle properties */
- +extern int symbol_fixup_support;/* enable symbols & fixup support */
- +extern int auto_label_aliases; /* auto generate labels -> aliases */
- +
- +/*
- + * Tree source globals
- + */
- +extern bool source_is_plugin;
- +extern bool deprecated_plugin_syntax_warning;
-
- #define PHANDLE_LEGACY 0x1
- #define PHANDLE_EPAPR 0x2
- @@ -194,6 +202,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);
- @@ -244,6 +253,8 @@ struct boot_info {
- struct boot_info *build_boot_info(struct reserve_info *reservelist,
- struct node *tree, uint32_t boot_cpuid_phys);
- void sort_tree(struct boot_info *bi);
- +void generate_label_node(struct node *node, struct node *dt);
- +void generate_fixups_node(struct node *node, struct node *dt);
-
- /* Checks */
-
- diff --git a/livetree.c b/livetree.c
- index e229b84..1ef9fc4 100644
- --- a/livetree.c
- +++ b/livetree.c
- @@ -216,6 +216,34 @@ 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 *ovl = xmalloc(sizeof(*ovl));
- + struct property *p;
- + struct data d = empty_data;
- + char *name;
- + int ret;
- +
- + memset(ovl, 0, sizeof(*ovl));
- +
- + d = data_add_marker(d, REF_PHANDLE, ref);
- + d = data_append_integer(d, 0xffffffff, 32);
- +
- + p = build_property("target", d);
- + add_property(ovl, p);
- +
- + ret = asprintf(&name, "fragment@%u",
- + next_orphan_fragment++);
- + if (ret == -1)
- + die("asprintf() failed\n");
- + name_node(ovl, name);
- + name_node(new_node, "__overlay__");
- +
- + add_child(dt, ovl);
- + add_child(ovl, new_node);
- +}
- +
- struct node *chain_node(struct node *first, struct node *list)
- {
- assert(first->next_sibling == NULL);
- @@ -709,3 +737,177 @@ void sort_tree(struct boot_info *bi)
- sort_reserve_entries(bi);
- sort_node(bi->dt);
- }
- +
- +void generate_label_node(struct node *node, struct node *dt)
- +{
- + struct node *c, *an;
- + struct property *p;
- + struct label *l;
- + int has_label;
- + char *gen_node_name;
- +
- + if (auto_label_aliases)
- + gen_node_name = "aliases";
- + else
- + gen_node_name = "__symbols__";
- +
- + /* Make sure the label isn't already there */
- + has_label = 0;
- + for_each_label(node->labels, l) {
- + has_label = 1;
- + break;
- + }
- +
- + if (has_label) {
- +
- + /* an is the aliases/__symbols__ node */
- + an = get_subnode(dt, gen_node_name);
- + /* if no node exists, create it */
- + if (!an) {
- + an = build_node(NULL, NULL);
- + name_node(an, gen_node_name);
- + add_child(dt, an);
- + }
- +
- + /* now add the label in the node */
- + for_each_label(node->labels, l) {
- + /* check whether the label already exists */
- + p = get_property(an, l->label);
- + if (p) {
- + fprintf(stderr, "WARNING: label %s already"
- + " exists in /%s", l->label,
- + gen_node_name);
- + continue;
- + }
- +
- + /* insert it */
- + p = build_property(l->label,
- + data_copy_escape_string(node->fullpath,
- + strlen(node->fullpath)));
- + add_property(an, p);
- + }
- +
- + /* force allocation of a phandle for this node */
- + if (symbol_fixup_support)
- + (void)get_node_phandle(dt, node);
- + }
- +
- + for_each_child(node, c)
- + generate_label_node(c, dt);
- +}
- +
- +static void add_fixup_entry(struct node *dt, struct node *node,
- + struct property *prop, struct marker *m)
- +{
- + struct node *fn; /* local fixup node */
- + struct property *p;
- + char *fixups_name = "__fixups__";
- + struct data d;
- + char *entry;
- + int ret;
- +
- + /* fn is the node we're putting entries in */
- + fn = get_subnode(dt, fixups_name);
- + /* if no node exists, create it */
- + if (!fn) {
- + fn = build_node(NULL, NULL);
- + name_node(fn, fixups_name);
- + add_child(dt, fn);
- + }
- +
- + ret = asprintf(&entry, "%s:%s:%u",
- + node->fullpath, prop->name, m->offset);
- + if (ret == -1)
- + die("asprintf() failed\n");
- +
- + p = get_property(fn, m->ref);
- + d = data_append_data(p ? p->val : empty_data, entry, strlen(entry) + 1);
- + if (!p)
- + add_property(fn, build_property(m->ref, d));
- + else
- + p->val = d;
- +}
- +
- +static void add_local_fixup_entry(struct node *dt, struct node *node,
- + struct property *prop, struct marker *m,
- + struct node *refnode)
- +{
- + struct node *lfn, *wn, *nwn; /* local fixup node, walk node, new */
- + struct property *p;
- + struct data d;
- + char *local_fixups_name = "__local_fixups__";
- + char *s, *e, *comp;
- + int len;
- +
- + /* fn is the node we're putting entries in */
- + lfn = get_subnode(dt, local_fixups_name);
- + /* if no node exists, create it */
- + if (!lfn) {
- + lfn = build_node(NULL, NULL);
- + name_node(lfn, local_fixups_name);
- + add_child(dt, lfn);
- + }
- +
- + /* walk the path components creating nodes if they don't exist */
- + comp = NULL;
- + /* start skipping the first / */
- + s = node->fullpath + 1;
- + wn = lfn;
- + while (*s) {
- + /* retrieve path component */
- + e = strchr(s, '/');
- + if (e == NULL)
- + e = s + strlen(s);
- + len = e - s;
- + comp = xrealloc(comp, len + 1);
- + memcpy(comp, s, len);
- + comp[len] = '\0';
- +
- + /* if no node exists, create it */
- + nwn = get_subnode(wn, comp);
- + if (!nwn) {
- + nwn = build_node(NULL, NULL);
- + name_node(nwn, strdup(comp));
- + add_child(wn, nwn);
- + }
- + wn = nwn;
- +
- + /* last path component */
- + if (!*e)
- + break;
- +
- + /* next path component */
- + s = e + 1;
- + }
- + free(comp);
- +
- + p = get_property(wn, prop->name);
- + d = data_append_cell(p ? p->val : empty_data, (cell_t)m->offset);
- + if (!p)
- + add_property(wn, build_property(prop->name, d));
- + else
- + p->val = d;
- +}
- +
- +void generate_fixups_node(struct node *node, struct node *dt)
- +{
- + struct node *c;
- + struct property *prop;
- + struct marker *m;
- + struct node *refnode;
- +
- + for_each_property(node, prop) {
- + m = prop->val.markers;
- + for_each_marker_of_type(m, REF_PHANDLE) {
- + refnode = get_node_by_ref(dt, m->ref);
- + if (!refnode)
- + add_fixup_entry(dt, node, prop, m);
- + else
- + add_local_fixup_entry(dt, node, prop, m,
- + refnode);
- + }
- + }
- +
- + for_each_child(node, c)
- + generate_fixups_node(c, dt);
- +}
- diff --git a/treesource.c b/treesource.c
- index a55d1d1..e1d6657 100644
- --- a/treesource.c
- +++ b/treesource.c
- @@ -28,6 +28,9 @@ extern YYLTYPE yylloc;
- struct boot_info *the_boot_info;
- bool treesource_error;
-
- +bool source_is_plugin;
- +bool deprecated_plugin_syntax_warning;
- +
- struct boot_info *dt_from_source(const char *fname)
- {
- the_boot_info = NULL;
- diff --git a/util.c b/util.c
- index 9d65226..cbb945b 100644
- --- a/util.c
- +++ b/util.c
- @@ -349,7 +349,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size)
- void utilfdt_print_data(const char *data, int len)
- {
- int i;
- - const char *p = data;
- const char *s;
-
- /* no data, don't print */
- @@ -376,6 +375,7 @@ void utilfdt_print_data(const char *data, int len)
- i < (len - 1) ? " " : "");
- printf(">");
- } else {
- + const unsigned char *p = (const unsigned char *)data;
- printf(" = [");
- for (i = 0; i < len; i++)
- printf("%02x%s", *p++, i < len - 1 ? " " : "");
- --
- 2.7.0
|