Skip to content

Commit

Permalink
scripts/dtc: Update to upstream version v1.4.7-14-gc86da84d30e4
Browse files Browse the repository at this point in the history
Major changes are I2C and SPI bus checks, YAML output format (for
future validation), some new libfdt functions, and more libfdt
validation of dtbs.

The YAML addition adds an optional dependency on libyaml. pkg-config is
used to test for it and pkg-config became a kconfig dependency in 4.18.

This adds the following commits from upstream:

c86da84d30e4 Add support for YAML encoded output
361b5e7d8067 Make type_marker_length helper public
bfbfab047e45 pylibfdt: Add a means to add and delete notes
9005f4108e7c pylibfdt: Allow delprop() to return errors
b94c056b137e Make valgrind optional
fd06c54d4711 tests: Better testing of dtc -I fs mode
c3f50c9a86d9 tests: Allow dtbs_equal_unordered to ignore mem reserves
0ac9fdee37c7 dtc: trivial '-I fs -O dts' test
0fd1c8c783f3 pylibfdt: fdt_get_mem_rsv returns 2 uint64_t values
04853cad18f4 pylibfdt: Don't incorrectly / unnecessarily override uint64_t typemap
9619c8619c37 Kill bogus TYPE_BLOB marker type
ac68ff92ae20 parser: add TYPE_STRING marker to path references
90a190eb04d9 checks: add SPI bus checks
53a1bd546905 checks: add I2C bus checks
88f18909db73 dtc: Bump version to v1.4.7
85bce8b2f06d tests: Correction to vg_prepare_blob()
57f7f9e7bc7c tests: Don't call memcmp() with NULL arguments
c12b2b0c20eb libfdt: fdt_address_cells() and fdt_size_cells()
3fe0eeda0b7f livetree: Set phandle properties type to uint32
853649acceba pylibfdt: Support the sequential-write interface
9b0e4fe26093 tests: Improve fdt_resize() tests
1087504bb3e8 libfdt: Add necessary header padding in fdt_create()
c72fa777e613 libfdt: Copy the struct region in fdt_resize()
32b9c6130762 Preserve datatype markers when emitting dts format
6dcb8ba408ec libfdt: Add helpers for accessing unaligned words
42607f21d43e tests: Fix incorrect check name 'prop_name_chars'
9d78c33bf8a1 tests: fix grep for checks error messages
b770f3d1c13f pylibfdt: Support setting the name of a node
2f0d07e678e0 pylibfdt: Add functions to set and get properties as strings
354d3dc55939 pylibfdt: Update the bytearray size with pack()
3c374d46acce pylibfdt: Allow reading integer values from properties
49d32ce40bb4 pylibfdt: Use an unsigned type for fdt32_t
481246a0c13a pylibfdt: Avoid accessing the internal _fdt member in tests
9aafa33d99ed pylibfdt: Add functions to update properties
5a598671fdbf pylibfdt: Support device-tree creation/expansion
483e170625e1 pylibfdt: Add support for reading the memory reserve map
29bb05aa4200 pylibfdt: Add support for the rest of the header functions
582a7159a5d0 pylibfdt: Add support for fdt_next_node()
f0f8c9169819 pylibfdt: Reorder functions to match libfdt.h
64a69d123935 pylibfdt: Return string instead of bytearray from getprop()
4d09a83420df fdtput: Add documentation
e617cbe1bd67 fdtget: Add documentation
180a93924014 Use <inttypes.h> format specifiers in a bunch of places we should
b9af3b396576 scripts/dtc: Fixed format mismatch in fprintf
4b8fcc3d015c libfdt: Add fdt_check_full() function
c14223fb2292 tests: Use valgrind client requests for better checking
5b67d2b955a3 tests: Better handling of valgrind errors saving blobs
e2556aaeb506 tests: Remove unused #define
fb9c6abddaa8 Use size_t for blob lengths in utilfdt_read*
0112fda03bf6 libfdt: Add fdt_header_size()
6473a21d8bfe Consolidate utilfdt_read_len() variants
d5db5382c5e5 libfdt: Safer access to memory reservations
719d582e98ec libfdt: Propagate name errors in fdt_getprop_by_offset()
70166d62a27f libfdt: Safer access to strings section
eb890c0f77dc libfdt: Make fdt_check_header() more thorough
899d6fad93f3 libfdt: Improve sequential write state checking
04b5b4062ccd libfdt: Clean up header checking functions
44d3efedc816 Preserve datatype information when parsing dts
f0be81bd8de0 Make Property a subclass of bytearray
24b1f3f064d4 pylibfdt: Add a method to access the device tree directly

Signed-off-by: Rob Herring <[email protected]>
  • Loading branch information
robherring committed Sep 20, 2018
1 parent c36d5a6 commit f858927
Show file tree
Hide file tree
Showing 23 changed files with 1,033 additions and 236 deletions.
7 changes: 7 additions & 0 deletions scripts/dtc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
# Source files need to get at the userspace version of libfdt_env.h to compile
HOST_EXTRACFLAGS := -I$(src)/libfdt

ifeq ($(wildcard /usr/include/yaml.h),)
HOST_EXTRACFLAGS += -DNO_YAML
else
dtc-objs += yamltree.o
HOSTLDLIBS_dtc := -lyaml
endif

# Generated files need one more search path to include headers in source tree
HOSTCFLAGS_dtc-lexer.lex.o := -I$(src)
HOSTCFLAGS_dtc-parser.tab.o := -I$(src)
Expand Down
4 changes: 4 additions & 0 deletions scripts/dtc/Makefile.dtc
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ DTC_SRCS = \
treesource.c \
util.c

ifneq ($(NO_YAML),1)
DTC_SRCS += yamltree.c
endif

DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
143 changes: 143 additions & 0 deletions scripts/dtc/checks.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,143 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
}
WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);

static const struct bus_type i2c_bus = {
.name = "i2c-bus",
};

static void check_i2c_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
{
if (strprefixeq(node->name, node->basenamelen, "i2c-bus") ||
strprefixeq(node->name, node->basenamelen, "i2c-arb")) {
node->bus = &i2c_bus;
} else if (strprefixeq(node->name, node->basenamelen, "i2c")) {
struct node *child;
for_each_child(node, child) {
if (strprefixeq(child->name, node->basenamelen, "i2c-bus"))
return;
}
node->bus = &i2c_bus;
} else
return;

if (!node->children)
return;

if (node_addr_cells(node) != 1)
FAIL(c, dti, node, "incorrect #address-cells for I2C bus");
if (node_size_cells(node) != 0)
FAIL(c, dti, node, "incorrect #size-cells for I2C bus");

}
WARNING(i2c_bus_bridge, check_i2c_bus_bridge, NULL, &addr_size_cells);

static void check_i2c_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
{
struct property *prop;
const char *unitname = get_unitname(node);
char unit_addr[17];
uint32_t reg = 0;
int len;
cell_t *cells = NULL;

if (!node->parent || (node->parent->bus != &i2c_bus))
return;

prop = get_property(node, "reg");
if (prop)
cells = (cell_t *)prop->val.val;

if (!cells) {
FAIL(c, dti, node, "missing or empty reg property");
return;
}

reg = fdt32_to_cpu(*cells);
snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
if (!streq(unitname, unit_addr))
FAIL(c, dti, node, "I2C bus unit address format error, expected \"%s\"",
unit_addr);

for (len = prop->val.len; len > 0; len -= 4) {
reg = fdt32_to_cpu(*(cells++));
if (reg > 0x3ff)
FAIL_PROP(c, dti, node, prop, "I2C address must be less than 10-bits, got \"0x%x\"",
reg);

}
}
WARNING(i2c_bus_reg, check_i2c_bus_reg, NULL, &reg_format, &i2c_bus_bridge);

static const struct bus_type spi_bus = {
.name = "spi-bus",
};

static void check_spi_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
{

if (strprefixeq(node->name, node->basenamelen, "spi")) {
node->bus = &spi_bus;
} else {
/* Try to detect SPI buses which don't have proper node name */
struct node *child;

if (node_addr_cells(node) != 1 || node_size_cells(node) != 0)
return;

for_each_child(node, child) {
struct property *prop;
for_each_property(child, prop) {
if (strprefixeq(prop->name, 4, "spi-")) {
node->bus = &spi_bus;
break;
}
}
if (node->bus == &spi_bus)
break;
}

if (node->bus == &spi_bus && get_property(node, "reg"))
FAIL(c, dti, node, "node name for SPI buses should be 'spi'");
}
if (node->bus != &spi_bus || !node->children)
return;

if (node_addr_cells(node) != 1)
FAIL(c, dti, node, "incorrect #address-cells for SPI bus");
if (node_size_cells(node) != 0)
FAIL(c, dti, node, "incorrect #size-cells for SPI bus");

}
WARNING(spi_bus_bridge, check_spi_bus_bridge, NULL, &addr_size_cells);

static void check_spi_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
{
struct property *prop;
const char *unitname = get_unitname(node);
char unit_addr[9];
uint32_t reg = 0;
cell_t *cells = NULL;

if (!node->parent || (node->parent->bus != &spi_bus))
return;

prop = get_property(node, "reg");
if (prop)
cells = (cell_t *)prop->val.val;

if (!cells) {
FAIL(c, dti, node, "missing or empty reg property");
return;
}

reg = fdt32_to_cpu(*cells);
snprintf(unit_addr, sizeof(unit_addr), "%x", reg);
if (!streq(unitname, unit_addr))
FAIL(c, dti, node, "SPI bus unit address format error, expected \"%s\"",
unit_addr);
}
WARNING(spi_bus_reg, check_spi_bus_reg, NULL, &reg_format, &spi_bus_bridge);

static void check_unit_address_format(struct check *c, struct dt_info *dti,
struct node *node)
{
Expand Down Expand Up @@ -1582,6 +1719,12 @@ static struct check *check_table[] = {
&simple_bus_bridge,
&simple_bus_reg,

&i2c_bus_bridge,
&i2c_bus_reg,

&spi_bus_bridge,
&spi_bus_reg,

&avoid_default_addr_size,
&avoid_unnecessary_addr_size,
&unique_unit_address,
Expand Down
4 changes: 3 additions & 1 deletion scripts/dtc/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ struct data data_copy_escape_string(const char *s, int len)
struct data d;
char *q;

d = data_grow_for(empty_data, len + 1);
d = data_add_marker(empty_data, TYPE_STRING, NULL);
d = data_grow_for(d, len + 1);

q = d.val;
while (i < len) {
Expand All @@ -94,6 +95,7 @@ struct data data_copy_file(FILE *f, size_t maxlen)
{
struct data d = empty_data;

d = data_add_marker(d, TYPE_NONE, NULL);
while (!feof(f) && (d.len < maxlen)) {
size_t chunksize, ret;

Expand Down
16 changes: 11 additions & 5 deletions scripts/dtc/dtc-parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ propdata:
}
| propdataprefix DT_REF
{
$1 = data_add_marker($1, TYPE_STRING, $2);
$$ = data_add_marker($1, REF_PATH, $2);
}
| propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')'
Expand Down Expand Up @@ -340,22 +341,27 @@ arrayprefix:
DT_BITS DT_LITERAL '<'
{
unsigned long long bits;
enum markertype type = TYPE_UINT32;

bits = $2;

if ((bits != 8) && (bits != 16) &&
(bits != 32) && (bits != 64)) {
switch (bits) {
case 8: type = TYPE_UINT8; break;
case 16: type = TYPE_UINT16; break;
case 32: type = TYPE_UINT32; break;
case 64: type = TYPE_UINT64; break;
default:
ERROR(&@2, "Array elements must be"
" 8, 16, 32 or 64-bits");
bits = 32;
}

$$.data = empty_data;
$$.data = data_add_marker(empty_data, type, NULL);
$$.bits = bits;
}
| '<'
{
$$.data = empty_data;
$$.data = data_add_marker(empty_data, TYPE_UINT32, NULL);
$$.bits = 32;
}
| arrayprefix integer_prim
Expand Down Expand Up @@ -499,7 +505,7 @@ integer_unary:
bytestring:
/* empty */
{
$$ = empty_data;
$$ = data_add_marker(empty_data, TYPE_UINT8, NULL);
}
| bytestring DT_BYTE
{
Expand Down
11 changes: 11 additions & 0 deletions scripts/dtc/dtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ static const char * const usage_opts_help[] = {
"\n\tOutput formats are:\n"
"\t\tdts - device tree source text\n"
"\t\tdtb - device tree blob\n"
#ifndef NO_YAML
"\t\tyaml - device tree encoded as YAML\n"
#endif
"\t\tasm - assembler source",
"\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
"\n\tOutput dependency file",
Expand Down Expand Up @@ -128,6 +131,8 @@ static const char *guess_type_by_name(const char *fname, const char *fallback)
return fallback;
if (!strcasecmp(s, ".dts"))
return "dts";
if (!strcasecmp(s, ".yaml"))
return "yaml";
if (!strcasecmp(s, ".dtb"))
return "dtb";
return fallback;
Expand Down Expand Up @@ -350,6 +355,12 @@ int main(int argc, char *argv[])

if (streq(outform, "dts")) {
dt_to_source(outf, dti);
#ifndef NO_YAML
} else if (streq(outform, "yaml")) {
if (!streq(inform, "dts"))
die("YAML output format requires dts input format\n");
dt_to_yaml(outf, dti);
#endif
} else if (streq(outform, "dtb")) {
dt_to_blob(outf, dti, outversion);
} else if (streq(outform, "asm")) {
Expand Down
13 changes: 13 additions & 0 deletions scripts/dtc/dtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,17 @@ typedef uint32_t cell_t;

/* Data blobs */
enum markertype {
TYPE_NONE,
REF_PHANDLE,
REF_PATH,
LABEL,
TYPE_UINT8,
TYPE_UINT16,
TYPE_UINT32,
TYPE_UINT64,
TYPE_STRING,
};
extern const char *markername(enum markertype markertype);

struct marker {
enum markertype type;
Expand All @@ -101,6 +108,8 @@ struct data {
for_each_marker(m) \
if ((m)->type == (t))

size_t type_marker_length(struct marker *m);

void data_free(struct data d);

struct data data_grow_for(struct data d, int xlen);
Expand Down Expand Up @@ -290,6 +299,10 @@ struct dt_info *dt_from_blob(const char *fname);
void dt_to_source(FILE *f, struct dt_info *dti);
struct dt_info *dt_from_source(const char *f);

/* YAML source */

void dt_to_yaml(FILE *f, struct dt_info *dti);

/* FS trees */

struct dt_info *dt_from_fs(const char *dirname);
Expand Down
2 changes: 1 addition & 1 deletion scripts/dtc/flattree.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int version)
padlen = 0;
if (quiet < 1)
fprintf(stderr,
"Warning: blob size %d >= minimum size %d\n",
"Warning: blob size %"PRIu32" >= minimum size %d\n",
fdt32_to_cpu(fdt.totalsize), minsize);
}
}
Expand Down
Loading

0 comments on commit f858927

Please sign in to comment.