scripts/dtc: Update to upstream version 0931cea3ba20
Sync to upstream dtc commit 0931cea3ba20 ("dtc: fdtdump: check fdt if
not in scanning mode"). In particular, this pulls in dtc overlay
support.
This adds the following commits from upstream:
f88865469b65 dtc: Fix memory leak in character literal parsing
00fbb8696b66 Rename boot_info
1ef86ad2c24f dtc: Clean up /dts-v1/ and /plugin/ handling in grammar
e3c769aa9c16 dtc: Don't always generate __symbols__ for plugins
c96cb3c0169e tests: Don't use -@ on plugin de/recompile tests
66381538ce24 tests: Remove "suppression of fixups" tests
ba765b273f0f tests: Clarify dtc overlay tests
6ea8cd944fcd tests: More thorough tests of libfdt overlay application without dtc
7d8ef6e1db97 tests: Correct fdt handling of overlays without fixups and base trees without symbols
b4dc0ed8b127 tests: Fix double expansion bugs in test code
3ea879dc0c8f tests: Split overlay tests into those with do/don't exercise dtc plugin generation
47b4d66a2f11 tests: Test auto-alias generation on base tree, not overlay
72e1ad811523 tests: Make overlay/plugin tests unconditional
e7b3c3b5951b tests: Add overlay tests
9637e3f772a9 tests: Add check_path test
20f29d8d41f6 dtc: Plugin and fixup support
a2c92cac53f8 dtc: Document the dynamic plugin internals
8f70ac39801d checks: Pass boot_info instead of root node
ea10f953878f libfdt: add missing errors to fdt_strerror()
daa75e8fa594 libfdt: fix fdt_stringlist_search()
e28eff5b787a libfdt: fix fdt_stringlist_count()
ae97c7722840 tests: overlay: Rename the device tree blobs to be more explicit
96162d2bd9cb tests: overlay: Add test suffix to the compiled blobs
5ce8634733b7 libfdt: Add fdt_overlay_apply to the exported symbols
804a9db90ad2 fdt: strerr: Remove spurious BADOVERLAY
e8c3a1a493fa tests: overlay: Move back the bad fixup tests
7a72d89d3f81 libfdt: overlay: Fix symbols and fixups nodes condition
cabbaa972cdd libfdt: overlay: Report a bad overlay for mismatching local fixups
deb0a5c1aeaa libfdt: Add BADPHANDLE error string
7b7a6be9ba15 libfdt: Don't use 'index' as a local variable name
aea8860d831e tests: Add tests cases for the overlay code
0cdd06c5135b libfdt: Add overlay application function
39240cc865cf libfdt: Extend the reach of FDT_ERR_BADPHANDLE
4aa3a6f5e6d9 libfdt: Add new errors for the overlay code
6d1832c9e64b dtc: Remove "home page" link
45fd440a9561 Fix some typing errors in libfdt.h and livetree.c
a59be4939c13 Merge tag 'v1.4.2'
a34bb721caca dtc: Fix assorted problems in the testcases for the -a option
874f40588d3e Implement the -a option to pad dtb aligned
ec02b34c05be dtc: Makefile improvements for release uploading
1ed45d40a137 dtc: Bump version to 1.4.2
36fd7331fb11 libfdt: simplify fdt_del_mem_rsv()
d877364e4a0f libfdt: Add fdt_setprop_inplace_namelen_partial
3e9037aaad44 libfdt: Add fdt_getprop_namelen_w
84e0e1346c68 libfdt: Add max phandle retrieval function
d29126c90acb libfdt: Add iterator over properties
902d0f0953d0 libfdt: Add a subnodes iterator macro
c539075ba8ba fdtput.c: Fix memory leak.
f79ddb83e185 fdtget.c: Fix memory leak
1074ee54b63f convert-dtsv0-lexer.l: fix memory leak
e24d39a024e6 fdtdump.c: make sure size_t argument to memchr is always unsigned.
44a59713cf05 Remove unused srcpos_dump() function
cb9241ae3453 DTC: Fix memory leak on flatname.
1ee0ae24ea09 Simplify check field and macro names
9d97527a8621 Remove property check functions
2e709d158e11 Remove tree check functions
c4cb12e193e3 Alter grammar to allow multiple /dts-v1/ tags
d71d25d76012 Use xasprintf() in srcpos
9dc404958e9c util: Add xasprintf portable asprintf variant
beef80b8b55f Correct a missing space in a fdt_header cast
68d43cec1253 Correct line lengths in libfdt.h
b0dbceafd49a Correct space-after-tab in libfdt.h
Signed-off-by: Rob Herring <robh@kernel.org>
This commit is contained in:
@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
||||
}
|
||||
}
|
||||
|
||||
/* if no collision occured, add child to the old node. */
|
||||
/* if no collision occurred, add child to the old node. */
|
||||
if (new_child)
|
||||
add_child(old_node, new_child);
|
||||
}
|
||||
@ -296,6 +296,23 @@ void delete_node(struct node *node)
|
||||
delete_labels(&node->labels);
|
||||
}
|
||||
|
||||
void append_to_property(struct node *node,
|
||||
char *name, const void *data, int len)
|
||||
{
|
||||
struct data d;
|
||||
struct property *p;
|
||||
|
||||
p = get_property(node, name);
|
||||
if (p) {
|
||||
d = data_append_data(p->val, data, len);
|
||||
p->val = d;
|
||||
} else {
|
||||
d = data_append_data(empty_data, data, len);
|
||||
p = build_property(name, d);
|
||||
add_property(node, p);
|
||||
}
|
||||
}
|
||||
|
||||
struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
|
||||
{
|
||||
struct reserve_info *new = xmalloc(sizeof(*new));
|
||||
@ -335,17 +352,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
|
||||
return list;
|
||||
}
|
||||
|
||||
struct boot_info *build_boot_info(struct reserve_info *reservelist,
|
||||
struct node *tree, uint32_t boot_cpuid_phys)
|
||||
struct dt_info *build_dt_info(unsigned int dtsflags,
|
||||
struct reserve_info *reservelist,
|
||||
struct node *tree, uint32_t boot_cpuid_phys)
|
||||
{
|
||||
struct boot_info *bi;
|
||||
struct dt_info *dti;
|
||||
|
||||
bi = xmalloc(sizeof(*bi));
|
||||
bi->reservelist = reservelist;
|
||||
bi->dt = tree;
|
||||
bi->boot_cpuid_phys = boot_cpuid_phys;
|
||||
dti = xmalloc(sizeof(*dti));
|
||||
dti->dtsflags = dtsflags;
|
||||
dti->reservelist = reservelist;
|
||||
dti->dt = tree;
|
||||
dti->boot_cpuid_phys = boot_cpuid_phys;
|
||||
|
||||
return bi;
|
||||
return dti;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -592,12 +611,12 @@ static int cmp_reserve_info(const void *ax, const void *bx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sort_reserve_entries(struct boot_info *bi)
|
||||
static void sort_reserve_entries(struct dt_info *dti)
|
||||
{
|
||||
struct reserve_info *ri, **tbl;
|
||||
int n = 0, i = 0;
|
||||
|
||||
for (ri = bi->reservelist;
|
||||
for (ri = dti->reservelist;
|
||||
ri;
|
||||
ri = ri->next)
|
||||
n++;
|
||||
@ -607,14 +626,14 @@ static void sort_reserve_entries(struct boot_info *bi)
|
||||
|
||||
tbl = xmalloc(n * sizeof(*tbl));
|
||||
|
||||
for (ri = bi->reservelist;
|
||||
for (ri = dti->reservelist;
|
||||
ri;
|
||||
ri = ri->next)
|
||||
tbl[i++] = ri;
|
||||
|
||||
qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
|
||||
|
||||
bi->reservelist = tbl[0];
|
||||
dti->reservelist = tbl[0];
|
||||
for (i = 0; i < (n-1); i++)
|
||||
tbl[i]->next = tbl[i+1];
|
||||
tbl[n-1]->next = NULL;
|
||||
@ -704,8 +723,256 @@ static void sort_node(struct node *node)
|
||||
sort_node(c);
|
||||
}
|
||||
|
||||
void sort_tree(struct boot_info *bi)
|
||||
void sort_tree(struct dt_info *dti)
|
||||
{
|
||||
sort_reserve_entries(bi);
|
||||
sort_node(bi->dt);
|
||||
sort_reserve_entries(dti);
|
||||
sort_node(dti->dt);
|
||||
}
|
||||
|
||||
/* utility helper to avoid code duplication */
|
||||
static struct node *build_and_name_child_node(struct node *parent, char *name)
|
||||
{
|
||||
struct node *node;
|
||||
|
||||
node = build_node(NULL, NULL);
|
||||
name_node(node, xstrdup(name));
|
||||
add_child(parent, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct node *build_root_node(struct node *dt, char *name)
|
||||
{
|
||||
struct node *an;
|
||||
|
||||
an = get_subnode(dt, name);
|
||||
if (!an)
|
||||
an = build_and_name_child_node(dt, name);
|
||||
|
||||
if (!an)
|
||||
die("Could not build root node /%s\n", name);
|
||||
|
||||
return an;
|
||||
}
|
||||
|
||||
static bool any_label_tree(struct dt_info *dti, struct node *node)
|
||||
{
|
||||
struct node *c;
|
||||
|
||||
if (node->labels)
|
||||
return true;
|
||||
|
||||
for_each_child(node, c)
|
||||
if (any_label_tree(dti, c))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void generate_label_tree_internal(struct dt_info *dti,
|
||||
struct node *an, struct node *node,
|
||||
bool allocph)
|
||||
{
|
||||
struct node *dt = dti->dt;
|
||||
struct node *c;
|
||||
struct property *p;
|
||||
struct label *l;
|
||||
|
||||
/* if there are labels */
|
||||
if (node->labels) {
|
||||
|
||||
/* 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,
|
||||
an->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* insert it */
|
||||
p = build_property(l->label,
|
||||
data_copy_mem(node->fullpath,
|
||||
strlen(node->fullpath) + 1));
|
||||
add_property(an, p);
|
||||
}
|
||||
|
||||
/* force allocation of a phandle for this node */
|
||||
if (allocph)
|
||||
(void)get_node_phandle(dt, node);
|
||||
}
|
||||
|
||||
for_each_child(node, c)
|
||||
generate_label_tree_internal(dti, an, c, allocph);
|
||||
}
|
||||
|
||||
static bool any_fixup_tree(struct dt_info *dti, struct node *node)
|
||||
{
|
||||
struct node *c;
|
||||
struct property *prop;
|
||||
struct marker *m;
|
||||
|
||||
for_each_property(node, prop) {
|
||||
m = prop->val.markers;
|
||||
for_each_marker_of_type(m, REF_PHANDLE) {
|
||||
if (!get_node_by_ref(dti->dt, m->ref))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_child(node, c) {
|
||||
if (any_fixup_tree(dti, c))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void add_fixup_entry(struct dt_info *dti, struct node *fn,
|
||||
struct node *node, struct property *prop,
|
||||
struct marker *m)
|
||||
{
|
||||
char *entry;
|
||||
|
||||
/* m->ref can only be a REF_PHANDLE, but check anyway */
|
||||
assert(m->type == REF_PHANDLE);
|
||||
|
||||
/* there shouldn't be any ':' in the arguments */
|
||||
if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
|
||||
die("arguments should not contain ':'\n");
|
||||
|
||||
xasprintf(&entry, "%s:%s:%u",
|
||||
node->fullpath, prop->name, m->offset);
|
||||
append_to_property(fn, m->ref, entry, strlen(entry) + 1);
|
||||
}
|
||||
|
||||
static void generate_fixups_tree_internal(struct dt_info *dti,
|
||||
struct node *fn,
|
||||
struct node *node)
|
||||
{
|
||||
struct node *dt = dti->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(dti, fn, node, prop, m);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_child(node, c)
|
||||
generate_fixups_tree_internal(dti, fn, c);
|
||||
}
|
||||
|
||||
static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
|
||||
{
|
||||
struct node *c;
|
||||
struct property *prop;
|
||||
struct marker *m;
|
||||
|
||||
for_each_property(node, prop) {
|
||||
m = prop->val.markers;
|
||||
for_each_marker_of_type(m, REF_PHANDLE) {
|
||||
if (get_node_by_ref(dti->dt, m->ref))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_child(node, c) {
|
||||
if (any_local_fixup_tree(dti, c))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void add_local_fixup_entry(struct dt_info *dti,
|
||||
struct node *lfn, struct node *node,
|
||||
struct property *prop, struct marker *m,
|
||||
struct node *refnode)
|
||||
{
|
||||
struct node *wn, *nwn; /* local fixup node, walk node, new */
|
||||
uint32_t value_32;
|
||||
char **compp;
|
||||
int i, depth;
|
||||
|
||||
/* walk back retreiving depth */
|
||||
depth = 0;
|
||||
for (wn = node; wn; wn = wn->parent)
|
||||
depth++;
|
||||
|
||||
/* allocate name array */
|
||||
compp = xmalloc(sizeof(*compp) * depth);
|
||||
|
||||
/* store names in the array */
|
||||
for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
|
||||
compp[i] = wn->name;
|
||||
|
||||
/* walk the path components creating nodes if they don't exist */
|
||||
for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
|
||||
/* if no node exists, create it */
|
||||
nwn = get_subnode(wn, compp[i]);
|
||||
if (!nwn)
|
||||
nwn = build_and_name_child_node(wn, compp[i]);
|
||||
}
|
||||
|
||||
free(compp);
|
||||
|
||||
value_32 = cpu_to_fdt32(m->offset);
|
||||
append_to_property(wn, prop->name, &value_32, sizeof(value_32));
|
||||
}
|
||||
|
||||
static void generate_local_fixups_tree_internal(struct dt_info *dti,
|
||||
struct node *lfn,
|
||||
struct node *node)
|
||||
{
|
||||
struct node *dt = dti->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_local_fixup_entry(dti, lfn, node, prop, m, refnode);
|
||||
}
|
||||
}
|
||||
|
||||
for_each_child(node, c)
|
||||
generate_local_fixups_tree_internal(dti, lfn, c);
|
||||
}
|
||||
|
||||
void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
|
||||
{
|
||||
if (!any_label_tree(dti, dti->dt))
|
||||
return;
|
||||
generate_label_tree_internal(dti, build_root_node(dti->dt, name),
|
||||
dti->dt, allocph);
|
||||
}
|
||||
|
||||
void generate_fixups_tree(struct dt_info *dti, char *name)
|
||||
{
|
||||
if (!any_fixup_tree(dti, dti->dt))
|
||||
return;
|
||||
generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
|
||||
dti->dt);
|
||||
}
|
||||
|
||||
void generate_local_fixups_tree(struct dt_info *dti, char *name)
|
||||
{
|
||||
if (!any_local_fixup_tree(dti, dti->dt))
|
||||
return;
|
||||
generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
|
||||
dti->dt);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user