-Wno-avoid_unnecessary_addr_size \
-Wno-alias_paths \
-Wno-graph_child_address \
+ -Wno-interrupt_map \
-Wno-simple_bus_reg
else
DTC_FLAGS += -Wunique_unit_address_if_enabled
} else if (strprefixeq(node->name, node->basenamelen, "i2c")) {
struct node *child;
for_each_child(node, child) {
- if (strprefixeq(child->name, node->basenamelen, "i2c-bus"))
+ if (strprefixeq(child->name, child->basenamelen, "i2c-bus"))
return;
}
node->bus = &i2c_bus;
static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti,
struct node *node)
{
- struct property *prop;
struct node *child;
- bool has_reg = false;
if (!node->parent || node->addr_cells < 0 || node->size_cells < 0)
return;
return;
for_each_child(node, child) {
- prop = get_property(child, "reg");
- if (prop)
- has_reg = true;
+ /*
+ * Even if the child devices' address space is not mapped into
+ * the parent bus (no 'ranges' property on node), children can
+ * still have registers on a local bus, or map local addresses
+ * to another subordinate address space. The properties on the
+ * child nodes then make #address-cells/#size-cells necessary:
+ */
+ if (get_property(child, "reg") || get_property(child, "ranges"))
+ return;
}
- if (!has_reg)
- FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" property");
+ FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\", \"dma-ranges\" or child \"reg\" or \"ranges\" property");
}
WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
cellprop = get_property(provider_node, "#address-cells");
if (cellprop)
parent_cellsize += propval_cell(cellprop);
+ else
+ FAIL_PROP(c, dti, node, irq_map_prop,
+ "Missing property '#address-cells' in node %s, using 0 as fallback",
+ provider_node->fullpath);
cell += 1 + parent_cellsize;
if (cell > map_cells)
{
struct marker *m;
- m = xmalloc(sizeof(*m));
- m->offset = d.len;
- m->type = type;
- m->ref = ref;
- m->next = NULL;
+ m = alloc_marker(d.len, type, ref);
return data_append_markers(d, m);
}
return true;
}
+
+struct data data_insert_data(struct data d, struct marker *m, struct data old)
+{
+ unsigned int offset = m->offset;
+ struct marker *next = m->next;
+ struct marker *marker;
+ struct data new_data;
+ char *ref;
+
+ new_data = data_insert_at_marker(d, m, old.val, old.len);
+
+ /* Copy all markers from old value */
+ marker = old.markers;
+ for_each_marker(marker) {
+ ref = NULL;
+
+ if (marker->ref)
+ ref = xstrdup(marker->ref);
+
+ m->next = alloc_marker(marker->offset + offset, marker->type,
+ ref);
+ m = m->next;
+ }
+ m->next = next;
+
+ return new_data;
+}
+
+struct marker *alloc_marker(unsigned int offset, enum markertype type,
+ char *ref)
+{
+ struct marker *m;
+
+ m = xmalloc(sizeof(*m));
+ m->offset = offset;
+ m->type = type;
+ m->ref = ref;
+ m->next = NULL;
+
+ return m;
+}
return DT_LABEL;
}
+<V1>{LABEL} {
+ /* Missed includes or macro definitions while
+ * preprocessing can lead to unexpected identifiers in
+ * the input. Report a slightly more informative error
+ * in this case */
+
+ lexical_error("Unexpected '%s'", yytext);
+
+ /* Treat it as a literal which often generates further
+ * useful error messages */
+
+ yylval.integer = 0;
+ return DT_LITERAL;
+ }
+
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
char *e;
DPRINT("Integer Literal: '%s'\n", yytext);
unsigned int reservenum;/* Number of memory reservation slots */
int minsize; /* Minimum blob size */
int padsize; /* Additional padding to blob */
-int alignsize; /* Additional padding to blob accroding to the alignsize */
+int alignsize; /* Additional padding to blob according to the alignsize */
int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */
int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */
if (!depfile)
die("Couldn't open dependency file %s: %s\n", depname,
strerror(errno));
- fprintf(depfile, "%s:", outname);
+
+ fprint_path_escaped(depfile, outname);
+ fputc(':', depfile);
}
if (inform == NULL)
extern unsigned int reservenum; /* Number of memory reservation slots */
extern int minsize; /* Minimum blob size */
extern int padsize; /* Additional padding to blob */
-extern int alignsize; /* Additional padding to blob accroding to the alignsize */
+extern int alignsize; /* Additional padding to blob according to the alignsize */
extern int phandle_format; /* Use linux,phandle or phandle properties */
extern int generate_symbols; /* generate symbols for nodes with labels */
extern int generate_fixups; /* generate fixups */
struct data data_append_byte(struct data d, uint8_t byte);
struct data data_append_zeroes(struct data d, int len);
struct data data_append_align(struct data d, int align);
+struct data data_insert_data(struct data d, struct marker *m, struct data old);
+struct marker *alloc_marker(unsigned int offset, enum markertype type,
+ char *ref);
struct data data_add_marker(struct data d, enum markertype type, char *ref);
bool data_is_one_string(struct data d);
char *tmp = NULL;
char *tmpo;
int ret;
+ bool has_symbols;
/*
* We take copies first, because a failed apply can trash
fdt_strerror(ret));
goto fail;
}
+ ret = fdt_path_offset(tmp, "/__symbols__");
+ has_symbols = ret >= 0;
memcpy(tmpo, overlay, fdt_totalsize(overlay));
if (ret) {
fprintf(stderr, "\nFailed to apply '%s': %s\n",
name, fdt_strerror(ret));
+ if (!has_symbols) {
+ fprintf(stderr,
+ "base blob does not have a '/__symbols__' node, "
+ "make sure you have compiled the base blob with '-@' option\n");
+ }
goto fail;
}
* Reserve map entries.
* Align the reserve map to a doubleword boundary.
* Each entry is an (address, size) pair of u64 values.
- * Always supply a zero-sized temination entry.
+ * Always supply a zero-sized termination entry.
*/
asm_emit_align(f, 8);
emit_label(f, symprefix, "reserve_map");
return offset;
}
-const char *fdt_find_string_(const char *strtab, int tabsize, const char *s)
+const char *fdt_find_string_len_(const char *strtab, int tabsize, const char *s,
+ int slen)
{
- int len = strlen(s) + 1;
- const char *last = strtab + tabsize - len;
+ const char *last = strtab + tabsize - (slen + 1);
const char *p;
for (p = strtab; p <= last; p++)
- if (memcmp(p, s, len) == 0)
+ if (memcmp(p, s, slen) == 0 && p[slen] == '\0')
return p;
return NULL;
}
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*/
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
struct fdt_header {
fdt32_t magic; /* magic word FDT_MAGIC */
char data[];
};
-#endif /* !__ASSEMBLY */
+#endif /* !__ASSEMBLER__ */
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(fdt32_t)
/**
* 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
* 0 on success
* Negative error code on failure
*/
-static int overlay_fixup_one_phandle(void *fdt, void *fdto,
- int symbols_off,
+static int overlay_fixup_one_phandle(void *fdto, int symbols_off,
const char *path, uint32_t path_len,
const char *name, uint32_t name_len,
int poffset, uint32_t phandle)
name, name_len, poffset,
&phandle_prop,
sizeof(phandle_prop));
-};
+}
/**
* overlay_fixup_phandle - Set an overlay phandle to the base one
if ((*endptr != '\0') || (endptr <= (sep + 1)))
return -FDT_ERR_BADOVERLAY;
- ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
+ ret = overlay_fixup_one_phandle(fdto, symbols_off,
path, path_len, name, name_len,
poffset, phandle);
if (ret)
* allocated. Ignored if can_assume(NO_ROLLBACK)
* @return offset of string in the string table (whether found or added)
*/
-static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
+static int fdt_find_add_string_(void *fdt, const char *s, int slen,
+ int *allocated)
{
char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
const char *p;
char *new;
- int len = strlen(s) + 1;
int err;
if (!can_assume(NO_ROLLBACK))
*allocated = 0;
- p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
+ p = fdt_find_string_len_(strtab, fdt_size_dt_strings(fdt), s, slen);
if (p)
/* found it */
return (p - strtab);
new = strtab + fdt_size_dt_strings(fdt);
- err = fdt_splice_string_(fdt, len);
+ err = fdt_splice_string_(fdt, slen + 1);
if (err)
return err;
if (!can_assume(NO_ROLLBACK))
*allocated = 1;
- memcpy(new, s, len);
+ memcpy(new, s, slen);
+ new[slen] = '\0';
+
return (new - strtab);
}
return fdt_splice_mem_rsv_(fdt, re, 1, 0);
}
-static int fdt_resize_property_(void *fdt, int nodeoffset, const char *name,
+static int fdt_resize_property_(void *fdt, int nodeoffset,
+ const char *name, int namelen,
int len, struct fdt_property **prop)
{
int oldlen;
int err;
- *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+ *prop = fdt_get_property_namelen_w(fdt, nodeoffset, name, namelen,
+ &oldlen);
if (!*prop)
return oldlen;
}
static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
- int len, struct fdt_property **prop)
+ int namelen, int len, struct fdt_property **prop)
{
int proplen;
int nextoffset;
if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
return nextoffset;
- namestroff = fdt_find_add_string_(fdt, name, &allocated);
+ namestroff = fdt_find_add_string_(fdt, name, namelen, &allocated);
if (namestroff < 0)
return namestroff;
return 0;
}
-int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
- int len, void **prop_data)
+int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, int len, void **prop_data)
{
struct fdt_property *prop;
int err;
FDT_RW_PROBE(fdt);
- err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop);
+ err = fdt_resize_property_(fdt, nodeoffset, name, namelen, len, &prop);
if (err == -FDT_ERR_NOTFOUND)
- err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
+ err = fdt_add_property_(fdt, nodeoffset, name, namelen, len,
+ &prop);
if (err)
return err;
return 0;
}
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, const void *val, int len)
{
void *prop_data;
int err;
- err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
+ err = fdt_setprop_placeholder_namelen(fdt, nodeoffset, name, namelen,
+ len, &prop_data);
if (err)
return err;
prop->len = cpu_to_fdt32(newlen);
memcpy(prop->data + oldlen, val, len);
} else {
- err = fdt_add_property_(fdt, nodeoffset, name, len, &prop);
+ err = fdt_add_property_(fdt, nodeoffset, name, strlen(name),
+ len, &prop);
if (err)
return err;
memcpy(prop->data, val, len);
#endif
#define FDT_FIRST_SUPPORTED_VERSION 0x02
-#define FDT_LAST_COMPATIBLE_VERSION 0x10
+#define FDT_LAST_COMPATIBLE_VERSION 0x10
#define FDT_LAST_SUPPORTED_VERSION 0x11
/* Error codes: informative error codes */
struct fdt_header *fdth = (struct fdt_header *)fdt; \
fdth->name = cpu_to_fdt32(val); \
}
-fdt_set_hdr_(magic);
-fdt_set_hdr_(totalsize);
-fdt_set_hdr_(off_dt_struct);
-fdt_set_hdr_(off_dt_strings);
-fdt_set_hdr_(off_mem_rsvmap);
-fdt_set_hdr_(version);
-fdt_set_hdr_(last_comp_version);
-fdt_set_hdr_(boot_cpuid_phys);
-fdt_set_hdr_(size_dt_strings);
-fdt_set_hdr_(size_dt_struct);
+fdt_set_hdr_(magic)
+fdt_set_hdr_(totalsize)
+fdt_set_hdr_(off_dt_struct)
+fdt_set_hdr_(off_dt_strings)
+fdt_set_hdr_(off_mem_rsvmap)
+fdt_set_hdr_(version)
+fdt_set_hdr_(last_comp_version)
+fdt_set_hdr_(boot_cpuid_phys)
+fdt_set_hdr_(size_dt_strings)
+fdt_set_hdr_(size_dt_struct)
#undef fdt_set_hdr_
/**
/**
* fdt_header_size_ - internal function to get header size from a version number
- * @version: devicetree version number
+ * @version: device tree version number
*
* Return: size of DTB header in bytes
*/
* -FDT_ERR_BADPATH, given path does not begin with '/' and the first
* component is not a valid alias
* -FDT_ERR_NOTFOUND, if the requested node does not exist
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* structure block offset of the property (>=0), on success
* -FDT_ERR_NOTFOUND, if the requested node has no properties
* -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* structure block offset of the next property (>=0), on success
* -FDT_ERR_NOTFOUND, if the given property is the last in its node
* -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
int nodeoffset,
const char *name,
int namelen, int *lenp);
+static inline struct fdt_property *
+fdt_get_property_namelen_w(void *fdt, int nodeoffset, const char *name,
+ int namelen, int *lenp)
+{
+ return (struct fdt_property *)(uintptr_t)fdt_get_property_namelen(
+ fdt, nodeoffset, name, namelen, lenp);
+}
#endif
/**
* to within the device blob itself, not a copy of the value). If
* lenp is non-NULL, the length of the property value is also
* returned, in the integer pointed to by lenp. If namep is non-NULL,
- * the property's namne will also be returned in the char * pointed to
+ * the property's name will also be returned in the char * pointed to
* by namep (this will be a pointer to within the device tree's string
* block, not a new copy of the name).
*
* pointer to the property's value
* if lenp is non-NULL, *lenp contains the length of the property
* value (>=0)
- * if namep is non-NULL *namep contiains a pointer to the property
+ * if namep is non-NULL *namep contains a pointer to the property
* name.
* NULL, on error
* if lenp is non-NULL, *lenp contains an error code (<0):
/**
* fdt_get_alias_namelen - get alias based on substring
* @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
+ * @name: name of the alias to look up
* @namelen: number of characters of name to consider
*
* Identical to fdt_get_alias(), but only examine the first @namelen
/**
* fdt_get_alias - retrieve the path referenced by a given alias
* @fdt: pointer to the device tree blob
- * @name: name of the alias th look up
+ * @name: name of the alias to look up
*
* fdt_get_alias() retrieves the value of a given alias. That is, the
* value of the property named @name in the node /aliases.
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
- * 2, if the node has no #address-cells property
- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ * 2, if the node has no #address-cells property
+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #address-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
*
* returns:
* 0 <= n < FDT_MAX_NCELLS, on success
- * 1, if the node has no #size-cells property
- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ * 1, if the node has no #size-cells property
+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
* #size-cells property
* -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* @fdt: pointer to the device tree blob
* @name: name of property to add
* @len: length of property value in bytes
- * @valp: returns a pointer to where where the value should be placed
+ * @valp: returns a pointer to where the value should be placed
*
* returns:
* 0, on success
*/
int fdt_set_name(void *fdt, int nodeoffset, const char *name);
+/**
+ * fdt_setprop_namelen - create or change a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: length of the name
+ * @val: pointer to data to set the property value to
+ * @len: length of the property value
+ *
+ * fdt_setprop_namelen() sets the value of the named property in the given
+ * node to the given value and length, creating the property if it
+ * does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, const void *val, int len);
+
/**
* fdt_setprop - create or change a property
* @fdt: pointer to the device tree blob
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len);
+static inline int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ return fdt_setprop_namelen(fdt, nodeoffset, name, strlen(name), val,
+ len);
+}
+
+/**
+ * fdt_setprop_placeholder_namelen - allocate space for a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: length of the name
+ * @len: length of the property value
+ * @prop_data: return pointer to property data
+ *
+ * fdt_setprop_placeholder_namelen() allocates the named property in the given node.
+ * If the property exists it is resized. In either case a pointer to the
+ * property data is returned.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name,
+ int namelen, int len, void **prop_data);
/**
* fdt_setprop_placeholder - allocate space for a property
* @len: length of the property value
* @prop_data: return pointer to property data
*
- * fdt_setprop_placeholer() allocates the named property in the given node.
+ * fdt_setprop_placeholder() allocates the named property in the given node.
* If the property exists it is resized. In either case a pointer to the
* property data is returned.
*
* -FDT_ERR_BADLAYOUT,
* -FDT_ERR_TRUNCATED, standard meanings
*/
-int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
- int len, void **prop_data);
+static inline int fdt_setprop_placeholder(void *fdt, int nodeoffset,
+ const char *name, int len,
+ void **prop_data)
+{
+ return fdt_setprop_placeholder_namelen(fdt, nodeoffset, name,
+ strlen(name), len, prop_data);
+}
/**
* fdt_setprop_u32 - set a property to a 32-bit integer
#define fdt_setprop_string(fdt, nodeoffset, name, str) \
fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+/**
+ * fdt_setprop_namelen_string - set a property to a string value
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: number of characters of name to consider
+ * @str: string value for the property
+ *
+ * fdt_setprop_namelen_string() sets the value of the named property in the
+ * given node to the given string value (using the length of the
+ * string to determine the new length of the property), or creates a
+ * new property with that value if it does not already exist.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+#define fdt_setprop_namelen_string(fdt, nodeoffset, name, namelen, str) \
+ fdt_setprop_namelen((fdt), (nodeoffset), (name), (namelen), (str), \
+ strlen(str) + 1)
/**
* fdt_setprop_empty - set a property to an empty value
* @nodeoffset: offset of the node whose property to nop
* @name: name of the property to nop
*
- * fdt_del_property() will delete the given property.
+ * fdt_delprop() will delete the given property.
*
* This function will delete data from the blob, and will therefore
* change the offsets of some existing nodes.
* change the offsets of some existing nodes.
*
* returns:
- * structure block offset of the created nodeequested subnode (>=0), on
- * success
+ * structure block offset of the created subnode (>=0), on success
* -FDT_ERR_NOTFOUND, if the requested subnode does not exist
* -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
* tag
* blob to contain the new node
* -FDT_ERR_NOSPACE
* -FDT_ERR_BADLAYOUT
- * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADMAGIC,
* -FDT_ERR_BADVERSION,
* -FDT_ERR_BADSTATE,
* -FDT_ERR_BADSTRUCTURE,
* returns:
* 0, on success
* -FDT_ERR_NOSPACE, there's not enough space in the base device tree
- * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
+ * -FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or
* properties in the base DT
* -FDT_ERR_BADPHANDLE,
* -FDT_ERR_BADOVERLAY,
int fdt_check_node_offset_(const void *fdt, int offset);
int fdt_check_prop_offset_(const void *fdt, int offset);
-const char *fdt_find_string_(const char *strtab, int tabsize, const char *s);
+
+const char *fdt_find_string_len_(const char *strtab, int tabsize, const char *s,
+ int s_len);
+static inline const char *fdt_find_string_(const char *strtab, int tabsize,
+ const char *s)
+{
+ return fdt_find_string_len_(strtab, tabsize, s, strlen(s));
+}
+
int fdt_node_end_offset_(void *fdt, int nodeoffset);
static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
}
/*
- * Internal helpers to access tructural elements of the device tree
- * blob (rather than for exaple reading integers from within property
+ * Internal helpers to access structural elements of the device tree
+ * blob (rather than for example reading integers from within property
* values). We assume that we are either given a naturally aligned
* address for the platform or if we are not, we are on a platform
* where unaligned memory reads will be handled in a graceful manner.
old_prop->val = new_prop->val;
old_prop->deleted = 0;
- free(old_prop->srcpos);
+ srcpos_free(old_prop->srcpos);
old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
struct node *child;
for_each_child(node, child)
- if (streq(child->name, nodename))
+ if (streq(child->name, nodename) && !child->deleted)
return child;
return NULL;
/* 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]);
+ nwn = build_root_node(wn, compp[i]);
}
free(compp);
void generate_fixups_tree(struct dt_info *dti, const char *name)
{
+ struct node *n = get_subnode(dti->dt, name);
+
+ /* Start with an empty __fixups__ node to not get duplicates */
+ if (n)
+ n->deleted = true;
+
if (!any_fixup_tree(dti, dti->dt))
return;
- generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+ generate_fixups_tree_internal(dti,
+ build_and_name_child_node(dti->dt, name),
dti->dt);
}
void generate_local_fixups_tree(struct dt_info *dti, const char *name)
{
+ struct node *n = get_subnode(dti->dt, name);
+
+ /* Start with an empty __local_fixups__ node to not get duplicates */
+ if (n)
+ n->deleted = true;
if (!any_local_fixup_tree(dti, dti->dt))
return;
- generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+ generate_local_fixups_tree_internal(dti,
+ build_and_name_child_node(dti->dt, name),
dti->dt);
}
strerror(errno));
}
- if (depfile)
- fprintf(depfile, " %s", fullname);
+ if (depfile) {
+ fputc(' ', depfile);
+ fprint_path_escaped(depfile, fullname);
+ }
if (fullnamep)
*fullnamep = fullname;
return pos;
}
+void srcpos_free(struct srcpos *pos)
+{
+ struct srcpos *p_next;
+
+ while (pos) {
+ p_next = pos->next;
+ free(pos);
+ pos = p_next;
+ }
+}
+
char *
srcpos_string(struct srcpos *pos)
{
extern struct srcpos *srcpos_copy(struct srcpos *pos);
extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
struct srcpos *old_srcpos);
+extern void srcpos_free(struct srcpos *pos);
extern char *srcpos_string(struct srcpos *pos);
extern char *srcpos_string_first(struct srcpos *pos, int level);
extern char *srcpos_string_last(struct srcpos *pos, int level);
[TYPE_STRING] = "",
};
+/*
+ * The invariants in the marker list are:
+ * - offsets are non-strictly monotonically increasing
+ * - for a single offset there is at most one type marker
+ * - for a single offset that has both a type marker and non-type markers, the
+ * type marker appears before the others.
+ */
+static struct marker **add_marker(struct marker **mi,
+ enum markertype type, unsigned int offset, char *ref)
+{
+ struct marker *nm;
+
+ while (*mi && (*mi)->offset < offset)
+ mi = &(*mi)->next;
+
+ if (*mi && (*mi)->offset == offset && is_type_marker((*mi)->type)) {
+ if (is_type_marker(type))
+ return mi;
+ mi = &(*mi)->next;
+ }
+
+ if (*mi && (*mi)->offset == offset && type == (*mi)->type)
+ return mi;
+
+ nm = xmalloc(sizeof(*nm));
+ nm->type = type;
+ nm->offset = offset;
+ nm->ref = ref;
+ nm->next = *mi;
+ *mi = nm;
+
+ return &nm->next;
+}
+
static void add_string_markers(struct property *prop)
{
int l, len = prop->val.len;
const char *p = prop->val.val;
+ struct marker **mi = &prop->val.markers;
- for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1) {
- struct marker *m, **nextp;
-
- m = xmalloc(sizeof(*m));
- m->offset = l;
- m->type = TYPE_STRING;
- m->ref = NULL;
- m->next = NULL;
-
- /* Find the end of the markerlist */
- nextp = &prop->val.markers;
- while (*nextp)
- nextp = &((*nextp)->next);
- *nextp = m;
- }
+ for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1)
+ mi = add_marker(mi, TYPE_STRING, l, NULL);
}
static enum markertype guess_value_type(struct property *prop)
#include "util.h"
#include "version_gen.h"
+void fprint_path_escaped(FILE *fp, const char *path)
+{
+ const char *p = path;
+
+ while (*p) {
+ if (*p == ' ') {
+ fputc('\\', fp);
+ fputc(' ', fp);
+ } else {
+ fputc(*p, fp);
+ }
+
+ p++;
+ }
+}
+
char *xstrdup(const char *s)
{
int len = strlen(s) + 1;
exit(1);
}
+/**
+ * Writes path to fp, escaping spaces with a backslash.
+ */
+void fprint_path_escaped(FILE *fp, const char *path);
+
static inline void *xmalloc(size_t len)
{
void *new = malloc(len);
-#define DTC_VERSION "DTC 1.7.0-gbcd02b52"
+#define DTC_VERSION "DTC 1.7.2-g52f07dcc"