Import dtc git at 6a15eb2350426d285130e4c9d84c0bdb6575547a (last rev before bison became required)

This commit is contained in:
Warner Losh 2014-01-27 06:20:36 +00:00
parent ab1c86b34d
commit 939bdb9f6a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/dtc/dist/; revision=261202
102 changed files with 1399 additions and 541 deletions

View File

@ -3,6 +3,7 @@ Device Tree Compiler Manual
I - "dtc", the device tree compiler
1) Obtaining Sources
1.1) Submitting Patches
2) Description
3) Command Line
4) Source File
@ -44,6 +45,10 @@ Tarballs of the 1.0.0 and latest releases are here:
http://www.jdl.com/software/dtc-v1.2.0.tgz
http://www.jdl.com/software/dtc-latest.tgz
1.1) Submitting Patches
Patches should be sent to jdl@jdl.com, and CC'ed to
devicetree-discuss@lists.ozlabs.org.
2) Description

View File

@ -9,7 +9,7 @@
# CONFIG_LOCALVERSION from some future config system.
#
VERSION = 1
PATCHLEVEL = 3
PATCHLEVEL = 4
SUBLEVEL = 0
EXTRAVERSION =
LOCAL_VERSION =
@ -160,18 +160,26 @@ endif
# intermediate target and building them again "for real"
.SECONDARY: $(DTC_GEN_SRCS) $(CONVERT_GEN_SRCS)
install: all $(SCRIPTS)
@$(VECHO) INSTALL
install-bin: all $(SCRIPTS)
@$(VECHO) INSTALL-BIN
$(INSTALL) -d $(DESTDIR)$(BINDIR)
$(INSTALL) $(BIN) $(SCRIPTS) $(DESTDIR)$(BINDIR)
install-lib: all
@$(VECHO) INSTALL-LIB
$(INSTALL) -d $(DESTDIR)$(LIBDIR)
$(INSTALL) $(LIBFDT_lib) $(DESTDIR)$(LIBDIR)
ln -sf $(notdir $(LIBFDT_lib)) $(DESTDIR)$(LIBDIR)/$(LIBFDT_soname)
ln -sf $(LIBFDT_soname) $(DESTDIR)$(LIBDIR)/libfdt.$(SHAREDLIB_EXT)
$(INSTALL) -m 644 $(LIBFDT_archive) $(DESTDIR)$(LIBDIR)
install-includes:
@$(VECHO) INSTALL-INC
$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)
$(INSTALL) -m 644 $(LIBFDT_include) $(DESTDIR)$(INCLUDEDIR)
install: install-bin install-lib install-includes
$(VERSION_FILE): Makefile FORCE
$(call filechk,version)

View File

@ -53,7 +53,7 @@ struct check {
void *data;
bool warn, error;
enum checkstatus status;
int inprogress;
bool inprogress;
int num_prereqs;
struct check **prereq;
};
@ -141,9 +141,9 @@ static void check_nodes_props(struct check *c, struct node *dt, struct node *nod
check_nodes_props(c, dt, child);
}
static int run_check(struct check *c, struct node *dt)
static bool run_check(struct check *c, struct node *dt)
{
int error = 0;
bool error = false;
int i;
assert(!c->inprogress);
@ -151,11 +151,11 @@ static int run_check(struct check *c, struct node *dt)
if (c->status != UNCHECKED)
goto out;
c->inprogress = 1;
c->inprogress = true;
for (i = 0; i < c->num_prereqs; i++) {
struct check *prq = c->prereq[i];
error |= run_check(prq, dt);
error = error || run_check(prq, dt);
if (prq->status != PASSED) {
c->status = PREREQ;
check_msg(c, "Failed prerequisite '%s'",
@ -177,9 +177,9 @@ static int run_check(struct check *c, struct node *dt)
TRACE(c, "\tCompleted, status %d", c->status);
out:
c->inprogress = 0;
c->inprogress = false;
if ((c->status != PASSED) && (c->error))
error = 1;
error = true;
return error;
}
@ -256,11 +256,15 @@ static void check_duplicate_property_names(struct check *c, struct node *dt,
{
struct property *prop, *prop2;
for_each_property(node, prop)
for (prop2 = prop->next; prop2; prop2 = prop2->next)
for_each_property(node, prop) {
for (prop2 = prop->next; prop2; prop2 = prop2->next) {
if (prop2->deleted)
continue;
if (streq(prop->name, prop2->name))
FAIL(c, "Duplicate property name %s in %s",
prop->name, node->fullpath);
}
}
}
NODE_ERROR(duplicate_property_names, NULL);
@ -729,7 +733,7 @@ void parse_checks_option(bool warn, bool error, const char *optarg)
die("Unrecognized check name \"%s\"\n", name);
}
void process_checks(int force, struct boot_info *bi)
void process_checks(bool force, struct boot_info *bi)
{
struct node *dt = bi->dt;
int i;

View File

@ -50,8 +50,6 @@ static int saw_hyphen; /* = 0 */
static unsigned long long last_val;
static char *last_name; /* = NULL */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
const struct {
const char *pattern;
int obase, width;
@ -194,11 +192,15 @@ const struct {
}
%%
static void usage(void)
{
fprintf(stderr, "convert-dtsv0 <v0 dts file>...\n");
exit(3);
}
/* Usage related data. */
static const char usage_synopsis[] = "convert-dtsv0 [options] <v0 dts file>...";
static const char usage_short_opts[] = "" USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
USAGE_COMMON_LONG_OPTS
};
static const char * const usage_opts_help[] = {
USAGE_COMMON_OPTS_HELP
};
static void convert_file(const char *fname)
{
@ -226,10 +228,16 @@ static void convert_file(const char *fname)
int main(int argc, char *argv[])
{
int opt;
int i;
while ((opt = util_getopt_long()) != EOF) {
switch (opt) {
case_USAGE_COMMON_FLAGS
}
}
if (argc < 2)
usage();
usage("missing filename");
for (i = 1; i < argc; i++) {
fprintf(stderr, "Converting %s from dts v0 to dts v1\n", argv[i]);

10
data.c
View File

@ -250,20 +250,20 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref)
return data_append_markers(d, m);
}
int data_is_one_string(struct data d)
bool data_is_one_string(struct data d)
{
int i;
int len = d.len;
if (len == 0)
return 0;
return false;
for (i = 0; i < len-1; i++)
if (d.val[i] == '\0')
return 0;
return false;
if (d.val[len-1] != '\0')
return 0;
return false;
return 1;
return true;
}

View File

@ -40,6 +40,7 @@ LINECOMMENT "//".*\n
#include "dtc-parser.tab.h"
YYLTYPE yylloc;
extern bool treesource_error;
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
#define YY_USER_ACTION \
@ -61,7 +62,8 @@ static int dts_version = 1;
BEGIN(V1); \
static void push_input_file(const char *filename);
static int pop_input_file(void);
static bool pop_input_file(void);
static void lexical_error(const char *fmt, ...);
%}
%%
@ -71,6 +73,27 @@ static int pop_input_file(void);
push_input_file(name);
}
<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? {
char *line, *tmp, *fn;
/* skip text before line # */
line = yytext;
while (!isdigit((unsigned char)*line))
line++;
/* skip digits in line # */
tmp = line;
while (!isspace((unsigned char)*tmp))
tmp++;
/* "NULL"-terminate line # */
*tmp = '\0';
/* start of filename */
fn = strchr(tmp + 1, '"') + 1;
/* strip trailing " from filename */
tmp = strchr(fn, '"');
*tmp = 0;
/* -1 since #line is the number of the next line */
srcpos_set_line(xstrdup(fn), atoi(line) - 1);
}
<*><<EOF>> {
if (!pop_input_file()) {
yyterminate();
@ -103,6 +126,20 @@ static int pop_input_file(void);
return DT_BITS;
}
<*>"/delete-property/" {
DPRINT("Keyword: /delete-property/\n");
DPRINT("<PROPNODENAME>\n");
BEGIN(PROPNODENAME);
return DT_DEL_PROP;
}
<*>"/delete-node/" {
DPRINT("Keyword: /delete-node/\n");
DPRINT("<PROPNODENAME>\n");
BEGIN(PROPNODENAME);
return DT_DEL_NODE;
}
<*>{LABEL}: {
DPRINT("Label: %s\n", yytext);
yylval.labelref = xstrdup(yytext);
@ -111,15 +148,42 @@ static int pop_input_file(void);
}
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
yylval.literal = xstrdup(yytext);
DPRINT("Literal: '%s'\n", yylval.literal);
char *e;
DPRINT("Integer Literal: '%s'\n", yytext);
errno = 0;
yylval.integer = strtoull(yytext, &e, 0);
assert(!(*e) || !e[strspn(e, "UL")]);
if (errno == ERANGE)
lexical_error("Integer literal '%s' out of range",
yytext);
else
/* ERANGE is the only strtoull error triggerable
* by strings matching the pattern */
assert(errno == 0);
return DT_LITERAL;
}
<*>{CHAR_LITERAL} {
yytext[yyleng-1] = '\0';
yylval.literal = xstrdup(yytext+1);
DPRINT("Character literal: %s\n", yylval.literal);
struct data d;
DPRINT("Character literal: %s\n", yytext);
d = data_copy_escape_string(yytext+1, yyleng-2);
if (d.len == 1) {
lexical_error("Empty character literal");
yylval.integer = 0;
return DT_CHAR_LITERAL;
}
yylval.integer = (unsigned char)d.val[0];
if (d.len > 2)
lexical_error("Character literal has %d"
" characters instead of 1",
d.len - 1);
return DT_CHAR_LITERAL;
}
@ -148,9 +212,10 @@ static int pop_input_file(void);
return ']';
}
<PROPNODENAME>{PROPNODECHAR}+ {
<PROPNODENAME>\\?{PROPNODECHAR}+ {
DPRINT("PropNodeName: %s\n", yytext);
yylval.propnodename = xstrdup(yytext);
yylval.propnodename = xstrdup((yytext[0] == '\\') ?
yytext + 1 : yytext);
BEGIN_DEFAULT();
return DT_PROPNODENAME;
}
@ -202,13 +267,24 @@ static void push_input_file(const char *filename)
}
static int pop_input_file(void)
static bool pop_input_file(void)
{
if (srcfile_pop() == 0)
return 0;
return false;
yypop_buffer_state();
yyin = current_srcfile->f;
return 1;
return true;
}
static void lexical_error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
srcpos_verror(&yylloc, "Lexical error", fmt, ap);
va_end(ap);
treesource_error = true;
}

View File

@ -31,15 +31,11 @@ extern void print_error(char const *fmt, ...);
extern void yyerror(char const *s);
extern struct boot_info *the_boot_info;
extern int treesource_error;
static unsigned long long eval_literal(const char *s, int base, int bits);
static unsigned char eval_char_literal(const char *s);
extern bool treesource_error;
%}
%union {
char *propnodename;
char *literal;
char *labelref;
unsigned int cbase;
uint8_t byte;
@ -62,9 +58,11 @@ static unsigned char eval_char_literal(const char *s);
%token DT_MEMRESERVE
%token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
%token DT_BITS
%token DT_DEL_PROP
%token DT_DEL_NODE
%token <propnodename> DT_PROPNODENAME
%token <literal> DT_LITERAL
%token <literal> DT_CHAR_LITERAL
%token <integer> DT_LITERAL
%token <integer> DT_CHAR_LITERAL
%token <cbase> DT_BASE
%token <byte> DT_BYTE
%token <data> DT_STRING
@ -153,6 +151,17 @@ devicetree:
print_error("label or path, '%s', not found", $2);
$$ = $1;
}
| devicetree DT_DEL_NODE DT_REF ';'
{
struct node *target = get_node_by_ref($1, $3);
if (!target)
print_error("label or path, '%s', not found", $3);
else
delete_node(target);
$$ = $1;
}
;
nodedef:
@ -182,6 +191,10 @@ propdef:
{
$$ = build_property($1, empty_data);
}
| DT_DEL_PROP DT_PROPNODENAME ';'
{
$$ = build_property_delete($2);
}
| DT_LABEL propdef
{
add_label(&$2->labels, $1);
@ -213,10 +226,9 @@ propdata:
if ($6 != 0)
if (fseek(f, $6, SEEK_SET) != 0)
print_error("Couldn't seek to offset %llu in \"%s\": %s",
(unsigned long long)$6,
$4.val,
strerror(errno));
die("Couldn't seek to offset %llu in \"%s\": %s",
(unsigned long long)$6, $4.val,
strerror(errno));
d = data_copy_file(f, $8);
@ -257,18 +269,20 @@ propdataprefix:
arrayprefix:
DT_BITS DT_LITERAL '<'
{
$$.data = empty_data;
$$.bits = eval_literal($2, 0, 7);
unsigned long long bits;
if (($$.bits != 8) &&
($$.bits != 16) &&
($$.bits != 32) &&
($$.bits != 64))
bits = $2;
if ((bits != 8) && (bits != 16) &&
(bits != 32) && (bits != 64))
{
print_error("Only 8, 16, 32 and 64-bit elements"
" are currently supported");
$$.bits = 32;
bits = 32;
}
$$.data = empty_data;
$$.bits = bits;
}
| '<'
{
@ -317,13 +331,7 @@ arrayprefix:
integer_prim:
DT_LITERAL
{
$$ = eval_literal($1, 0, 64);
}
| DT_CHAR_LITERAL
{
$$ = eval_char_literal($1);
}
| '(' integer_expr ')'
{
$$ = $2;
@ -440,6 +448,10 @@ subnode:
{
$$ = name_node($2, $1);
}
| DT_DEL_NODE DT_PROPNODENAME ';'
{
$$ = name_node(build_node_delete(), $2);
}
| DT_LABEL subnode
{
add_label(&$2->labels, $1);
@ -454,58 +466,12 @@ void print_error(char const *fmt, ...)
va_list va;
va_start(va, fmt);
srcpos_verror(&yylloc, fmt, va);
srcpos_verror(&yylloc, "Error", fmt, va);
va_end(va);
treesource_error = 1;
treesource_error = true;
}
void yyerror(char const *s) {
print_error("%s", s);
}
static unsigned long long eval_literal(const char *s, int base, int bits)
{
unsigned long long val;
char *e;
errno = 0;
val = strtoull(s, &e, base);
if (*e) {
size_t uls = strspn(e, "UL");
if (e[uls])
print_error("bad characters in literal");
}
if ((errno == ERANGE)
|| ((bits < 64) && (val >= (1ULL << bits))))
print_error("literal out of range");
else if (errno != 0)
print_error("bad literal");
return val;
}
static unsigned char eval_char_literal(const char *s)
{
int i = 1;
char c = s[0];
if (c == '\0')
{
print_error("empty character literal");
return 0;
}
/*
* If the first character in the character literal is a \ then process
* the remaining characters as an escape encoding. If the first
* character is neither an escape or a terminator it should be the only
* character in the literal and will be returned.
*/
if (c == '\\')
c = get_escape_char(s, &i);
if (s[i] != '\0')
print_error("malformed character literal");
return c;
}

125
dtc.c
View File

@ -21,8 +21,6 @@
#include "dtc.h"
#include "srcpos.h"
#include "version_gen.h"
/*
* Command line options
*/
@ -49,55 +47,60 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
fill_fullpaths(child, tree->fullpath);
}
static void __attribute__ ((noreturn)) usage(void)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\tdtc [options] <input file>\n");
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, "\t-h\n");
fprintf(stderr, "\t\tThis help text\n");
fprintf(stderr, "\t-q\n");
fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n");
fprintf(stderr, "\t-I <input format>\n");
fprintf(stderr, "\t\tInput formats are:\n");
fprintf(stderr, "\t\t\tdts - device tree source text\n");
fprintf(stderr, "\t\t\tdtb - device tree blob\n");
fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n");
fprintf(stderr, "\t-o <output file>\n");
fprintf(stderr, "\t-O <output format>\n");
fprintf(stderr, "\t\tOutput formats are:\n");
fprintf(stderr, "\t\t\tdts - device tree source text\n");
fprintf(stderr, "\t\t\tdtb - device tree blob\n");
fprintf(stderr, "\t\t\tasm - assembler source\n");
fprintf(stderr, "\t-V <output version>\n");
fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
fprintf(stderr, "\t-d <output dependency file>\n");
fprintf(stderr, "\t-R <number>\n");
fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
fprintf(stderr, "\t-S <bytes>\n");
fprintf(stderr, "\t\tMake the blob at least <bytes> long (extra space)\n");
fprintf(stderr, "\t-p <bytes>\n");
fprintf(stderr, "\t\tAdd padding to the blob of <bytes> long (extra space)\n");
fprintf(stderr, "\t-b <number>\n");
fprintf(stderr, "\t\tSet the physical boot cpu\n");
fprintf(stderr, "\t-f\n");
fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
fprintf(stderr, "\t-i\n");
fprintf(stderr, "\t\tAdd a path to search for include files\n");
fprintf(stderr, "\t-s\n");
fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n");
fprintf(stderr, "\t-v\n");
fprintf(stderr, "\t\tPrint DTC version and exit\n");
fprintf(stderr, "\t-H <phandle format>\n");
fprintf(stderr, "\t\tphandle formats are:\n");
fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n");
fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n");
fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n");
fprintf(stderr, "\t-W [no-]<checkname>\n");
fprintf(stderr, "\t-E [no-]<checkname>\n");
fprintf(stderr, "\t\t\tenable or disable warnings and errors\n");
exit(3);
}
/* Usage related data. */
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 struct option const usage_long_opts[] = {
{"quiet", no_argument, NULL, 'q'},
{"in-format", a_argument, NULL, 'I'},
{"out", a_argument, NULL, 'o'},
{"out-format", a_argument, NULL, 'O'},
{"out-version", a_argument, NULL, 'V'},
{"out-dependency", a_argument, NULL, 'd'},
{"reserve", a_argument, NULL, 'R'},
{"space", a_argument, NULL, 'S'},
{"pad", a_argument, NULL, 'p'},
{"boot-cpu", a_argument, NULL, 'b'},
{"force", no_argument, NULL, 'f'},
{"include", a_argument, NULL, 'i'},
{"sort", no_argument, NULL, 's'},
{"phandle", a_argument, NULL, 'H'},
{"warning", a_argument, NULL, 'W'},
{"error", a_argument, NULL, 'E'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0x0},
};
static const char * const usage_opts_help[] = {
"\n\tQuiet: -q suppress warnings, -qq errors, -qqq all",
"\n\tInput formats are:\n"
"\t\tdts - device tree source text\n"
"\t\tdtb - device tree blob\n"
"\t\tfs - /proc/device-tree style directory",
"\n\tOutput file",
"\n\tOutput formats are:\n"
"\t\tdts - device tree source text\n"
"\t\tdtb - device tree blob\n"
"\t\tasm - assembler source",
"\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION);
"\n\tOutput dependency file",
"\n\ttMake space for <number> reserve map entries (for dtb and asm output)",
"\n\tMake the blob at least <bytes> long (extra space)",
"\n\tAdd padding to the blob of <bytes> long (extra space)",
"\n\tSet the physical boot cpu",
"\n\tTry to produce output even if the input tree has errors",
"\n\tAdd a path to search for include files",
"\n\tSort nodes and properties before outputting (useful for comparing trees)",
"\n\tValid phandle formats are:\n"
"\t\tlegacy - \"linux,phandle\" properties only\n"
"\t\tepapr - \"phandle\" properties only\n"
"\t\tboth - Both \"linux,phandle\" and \"phandle\" properties",
"\n\tEnable/disable warnings (prefix with \"no-\")",
"\n\tEnable/disable errors (prefix with \"no-\")",
"\n\tPrint this help and exit",
"\n\tPrint version and exit",
NULL,
};
int main(int argc, char *argv[])
{
@ -106,7 +109,7 @@ int main(int argc, char *argv[])
const char *outform = "dts";
const char *outname = "-";
const char *depname = NULL;
int force = 0, sort = 0;
bool force = false, sort = false;
const char *arg;
int opt;
FILE *outf = NULL;
@ -118,8 +121,7 @@ int main(int argc, char *argv[])
minsize = 0;
padsize = 0;
while ((opt = getopt(argc, argv, "hI:O:o:V:d:R:S:p:fqb:i:vH:sW:E:"))
!= EOF) {
while ((opt = util_getopt_long()) != EOF) {
switch (opt) {
case 'I':
inform = optarg;
@ -146,7 +148,7 @@ int main(int argc, char *argv[])
padsize = strtol(optarg, NULL, 0);
break;
case 'f':
force = 1;
force = true;
break;
case 'q':
quiet++;
@ -158,8 +160,7 @@ int main(int argc, char *argv[])
srcfile_add_search_path(optarg);
break;
case 'v':
printf("Version: %s\n", DTC_VERSION);
exit(0);
util_version();
case 'H':
if (streq(optarg, "legacy"))
phandle_format = PHANDLE_LEGACY;
@ -173,7 +174,7 @@ int main(int argc, char *argv[])
break;
case 's':
sort = 1;
sort = true;
break;
case 'W':
@ -185,13 +186,14 @@ int main(int argc, char *argv[])
break;
case 'h':
usage(NULL);
default:
usage();
usage("unknown option");
}
}
if (argc > (optind+1))
usage();
usage("missing files");
else if (argc < (optind+1))
arg = "-";
else
@ -201,9 +203,6 @@ int main(int argc, char *argv[])
if (minsize && padsize)
die("Can't set both -p and -S\n");
if (minsize)
fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n");
if (depname) {
depfile = fopen(depname, "w");
if (!depfile)

33
dtc.h
View File

@ -66,7 +66,6 @@ typedef uint32_t cell_t;
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* Data blobs */
enum markertype {
@ -119,7 +118,7 @@ struct data data_append_align(struct data d, int align);
struct data data_add_marker(struct data d, enum markertype type, char *ref);
int data_is_one_string(struct data d);
bool data_is_one_string(struct data d);
/* DT constraints */
@ -128,11 +127,13 @@ int data_is_one_string(struct data d);
/* Live trees */
struct label {
bool deleted;
char *label;
struct label *next;
};
struct property {
bool deleted;
char *name;
struct data val;
@ -142,6 +143,7 @@ struct property {
};
struct node {
bool deleted;
char *name;
struct property *proplist;
struct node *children;
@ -158,28 +160,47 @@ struct node {
struct label *labels;
};
#define for_each_label(l0, l) \
#define for_each_label_withdel(l0, l) \
for ((l) = (l0); (l); (l) = (l)->next)
#define for_each_property(n, p) \
#define for_each_label(l0, l) \
for_each_label_withdel(l0, l) \
if (!(l)->deleted)
#define for_each_property_withdel(n, p) \
for ((p) = (n)->proplist; (p); (p) = (p)->next)
#define for_each_child(n, c) \
#define for_each_property(n, p) \
for_each_property_withdel(n, p) \
if (!(p)->deleted)
#define for_each_child_withdel(n, c) \
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
#define for_each_child(n, c) \
for_each_child_withdel(n, c) \
if (!(c)->deleted)
void add_label(struct label **labels, char *label);
void delete_labels(struct label **labels);
struct property *build_property(char *name, struct data val);
struct property *build_property_delete(char *name);
struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children);
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_property(struct node *node, struct property *prop);
void delete_property_by_name(struct node *node, char *name);
void delete_property(struct property *prop);
void add_child(struct node *parent, struct node *child);
void delete_node_by_name(struct node *parent, char *name);
void delete_node(struct node *node);
const char *get_unitname(struct node *node);
struct property *get_property(struct node *node, const char *propname);
@ -227,7 +248,7 @@ void sort_tree(struct boot_info *bi);
/* Checks */
void parse_checks_option(bool warn, bool error, const char *optarg);
void process_checks(int force, struct boot_info *bi);
void process_checks(bool force, struct boot_info *bi);
/* Flattened trees */

133
fdtdump.c
View File

@ -2,14 +2,16 @@
* fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fdt.h>
#include <libfdt.h>
#include <libfdt_env.h>
#include <fdt.h>
#include "util.h"
@ -17,33 +19,29 @@
#define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a))))
#define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4)))
static void print_data(const char *data, int len)
static const char *tagname(uint32_t tag)
{
int i;
const char *p = data;
/* no data, don't print */
if (len == 0)
return;
if (util_is_printable_string(data, len)) {
printf(" = \"%s\"", (const char *)data);
} else if ((len % 4) == 0) {
printf(" = <");
for (i = 0; i < len; i += 4)
printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)),
i < (len - 4) ? " " : "");
printf(">");
} else {
printf(" = [");
for (i = 0; i < len; i++)
printf("%02x%s", *p++, i < len - 1 ? " " : "");
printf("]");
}
static const char * const names[] = {
#define TN(t) [t] #t
TN(FDT_BEGIN_NODE),
TN(FDT_END_NODE),
TN(FDT_PROP),
TN(FDT_NOP),
TN(FDT_END),
#undef TN
};
if (tag < ARRAY_SIZE(names))
if (names[tag])
return names[tag];
return "FDT_???";
}
static void dump_blob(void *blob)
#define dumpf(fmt, args...) \
do { if (debug) printf("// " fmt, ## args); } while (0)
static void dump_blob(void *blob, bool debug)
{
uintptr_t blob_off = (uintptr_t)blob;
struct fdt_header *bph = blob;
uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
@ -97,7 +95,8 @@ static void dump_blob(void *blob)
p = p_struct;
while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
dumpf("%04zx: tag: 0x%08x (%s)\n",
(uintptr_t)p - blob_off - 4, tag, tagname(tag));
if (tag == FDT_BEGIN_NODE) {
s = p;
@ -136,27 +135,93 @@ static void dump_blob(void *blob)
p = PALIGN(p + sz, 4);
dumpf("%04zx: string: %s\n", (uintptr_t)s - blob_off, s);
dumpf("%04zx: value\n", (uintptr_t)t - blob_off);
printf("%*s%s", depth * shift, "", s);
print_data(t, sz);
utilfdt_print_data(t, sz);
printf(";\n");
}
}
/* Usage related data. */
static const char usage_synopsis[] = "fdtdump [options] <file>";
static const char usage_short_opts[] = "ds" USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
{"debug", no_argument, NULL, 'd'},
{"scan", no_argument, NULL, 's'},
USAGE_COMMON_LONG_OPTS
};
static const char * const usage_opts_help[] = {
"Dump debug information while decoding the file",
"Scan for an embedded fdt in file",
USAGE_COMMON_OPTS_HELP
};
int main(int argc, char *argv[])
{
int opt;
const char *file;
char *buf;
bool debug = false;
bool scan = false;
off_t len;
if (argc < 2) {
fprintf(stderr, "supply input filename\n");
return 5;
while ((opt = util_getopt_long()) != EOF) {
switch (opt) {
case_USAGE_COMMON_FLAGS
case 'd':
debug = true;
break;
case 's':
scan = true;
break;
}
}
if (optind != argc - 1)
usage("missing input filename");
file = argv[optind];
buf = utilfdt_read_len(file, &len);
if (!buf)
die("could not read: %s\n", file);
/* try and locate an embedded fdt in a bigger blob */
if (scan) {
unsigned char smagic[4];
char *p = buf;
char *endp = buf + len;
fdt_set_magic(smagic, FDT_MAGIC);
/* poor man's memmem */
while (true) {
p = memchr(p, smagic[0], endp - p - 4);
if (!p)
break;
if (fdt_magic(p) == FDT_MAGIC) {
/* try and validate the main struct */
off_t this_len = endp - p;
fdt32_t max_version = 17;
if (fdt_version(p) <= max_version &&
fdt_last_comp_version(p) < max_version &&
fdt_totalsize(p) < this_len &&
fdt_off_dt_struct(p) < this_len &&
fdt_off_dt_strings(p) < this_len)
break;
if (debug)
printf("%s: skipping fdt magic at offset %#zx\n",
file, p - buf);
}
++p;
}
if (!p)
die("%s: could not locate fdt magic\n", file);
printf("%s: found fdt at offset %#zx\n", file, p - buf);
buf = p;
}
buf = utilfdt_read(argv[1]);
if (buf)
dump_blob(buf);
else
return 10;
dump_blob(buf, debug);
return 0;
}

View File

@ -277,33 +277,33 @@ static int do_fdtget(struct display_info *disp, const char *filename,
return 0;
}
static const char *usage_msg =
"fdtget - read values from device tree\n"
"\n"
"Each value is printed on a new line.\n\n"
"Usage:\n"
/* Usage related data. */
static const char usage_synopsis[] =
"read values from device tree\n"
" fdtget <options> <dt file> [<node> <property>]...\n"
" fdtget -p <options> <dt file> [<node> ]...\n"
"Options:\n"
"\t-t <type>\tType of data\n"
"\t-p\t\tList properties for each node\n"
"\t-l\t\tList subnodes for each node\n"
"\t-d\t\tDefault value to display when the property is "
"missing\n"
"\t-h\t\tPrint this help\n\n"
"\n"
"Each value is printed on a new line.\n"
USAGE_TYPE_MSG;
static void usage(const char *msg)
{
if (msg)
fprintf(stderr, "Error: %s\n\n", msg);
fprintf(stderr, "%s", usage_msg);
exit(2);
}
static const char usage_short_opts[] = "t:pld:" USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
{"type", a_argument, NULL, 't'},
{"properties", no_argument, NULL, 'p'},
{"list", no_argument, NULL, 'l'},
{"default", a_argument, NULL, 'd'},
USAGE_COMMON_LONG_OPTS,
};
static const char * const usage_opts_help[] = {
"Type of data",
"List properties for each node",
"List subnodes for each node",
"Default value to display when the property is missing",
USAGE_COMMON_OPTS_HELP
};
int main(int argc, char *argv[])
{
int opt;
char *filename = NULL;
struct display_info disp;
int args_per_step = 2;
@ -312,20 +312,14 @@ int main(int argc, char *argv[])
memset(&disp, '\0', sizeof(disp));
disp.size = -1;
disp.mode = MODE_SHOW_VALUE;
for (;;) {
int c = getopt(argc, argv, "d:hlpt:");
if (c == -1)
break;
switch (c) {
case 'h':
case '?':
usage(NULL);
while ((opt = util_getopt_long()) != EOF) {
switch (opt) {
case_USAGE_COMMON_FLAGS
case 't':
if (utilfdt_decode_type(optarg, &disp.type,
&disp.size))
usage("Invalid type string");
usage("invalid type string");
break;
case 'p':
@ -347,7 +341,7 @@ int main(int argc, char *argv[])
if (optind < argc)
filename = argv[optind++];
if (!filename)
usage("Missing filename");
usage("missing filename");
argv += optind;
argc -= optind;
@ -358,7 +352,7 @@ int main(int argc, char *argv[])
/* Check for node, property arguments */
if (args_per_step == 2 && (argc % 2))
usage("Must have an even number of arguments");
usage("must have an even number of arguments");
if (do_fdtget(&disp, filename, argv, argc, args_per_step))
return 1;

135
fdtput.c
View File

@ -131,19 +131,59 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count,
return 0;
}
static int store_key_value(void *blob, const char *node_name,
#define ALIGN(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1))
static char *_realloc_fdt(char *fdt, int delta)
{
int new_sz = fdt_totalsize(fdt) + delta;
fdt = xrealloc(fdt, new_sz);
fdt_open_into(fdt, fdt, new_sz);
return fdt;
}
static char *realloc_node(char *fdt, const char *name)
{
int delta;
/* FDT_BEGIN_NODE, node name in off_struct and FDT_END_NODE */
delta = sizeof(struct fdt_node_header) + ALIGN(strlen(name) + 1)
+ FDT_TAGSIZE;
return _realloc_fdt(fdt, delta);
}
static char *realloc_property(char *fdt, int nodeoffset,
const char *name, int newlen)
{
int delta = 0;
int oldlen = 0;
if (!fdt_get_property(fdt, nodeoffset, name, &oldlen))
/* strings + property header */
delta = sizeof(struct fdt_property) + strlen(name) + 1;
if (newlen > oldlen)
/* actual value in off_struct */
delta += ALIGN(newlen) - ALIGN(oldlen);
return _realloc_fdt(fdt, delta);
}
static int store_key_value(char **blob, const char *node_name,
const char *property, const char *buf, int len)
{
int node;
int err;
node = fdt_path_offset(blob, node_name);
node = fdt_path_offset(*blob, node_name);
if (node < 0) {
report_error(node_name, -1, node);
return -1;
}
err = fdt_setprop(blob, node, property, buf, len);
err = fdt_setprop(*blob, node, property, buf, len);
if (err == -FDT_ERR_NOSPACE) {
*blob = realloc_property(*blob, node, property, len);
err = fdt_setprop(*blob, node, property, buf, len);
}
if (err) {
report_error(property, -1, err);
return -1;
@ -161,7 +201,7 @@ static int store_key_value(void *blob, const char *node_name,
* @param in_path Path to process
* @return 0 if ok, -1 on error
*/
static int create_paths(void *blob, const char *in_path)
static int create_paths(char **blob, const char *in_path)
{
const char *path = in_path;
const char *sep;
@ -177,10 +217,11 @@ static int create_paths(void *blob, const char *in_path)
if (!sep)
sep = path + strlen(path);
node = fdt_subnode_offset_namelen(blob, offset, path,
node = fdt_subnode_offset_namelen(*blob, offset, path,
sep - path);
if (node == -FDT_ERR_NOTFOUND) {
node = fdt_add_subnode_namelen(blob, offset, path,
*blob = realloc_node(*blob, path);
node = fdt_add_subnode_namelen(*blob, offset, path,
sep - path);
}
if (node < 0) {
@ -203,7 +244,7 @@ static int create_paths(void *blob, const char *in_path)
* @param node_name Name of node to create
* @return new node offset if found, or -1 on failure
*/
static int create_node(void *blob, const char *node_name)
static int create_node(char **blob, const char *node_name)
{
int node = 0;
char *p;
@ -215,15 +256,17 @@ static int create_node(void *blob, const char *node_name)
}
*p = '\0';
*blob = realloc_node(*blob, p + 1);
if (p > node_name) {
node = fdt_path_offset(blob, node_name);
node = fdt_path_offset(*blob, node_name);
if (node < 0) {
report_error(node_name, -1, node);
return -1;
}
}
node = fdt_add_subnode(blob, node, p + 1);
node = fdt_add_subnode(*blob, node, p + 1);
if (node < 0) {
report_error(p + 1, -1, node);
return -1;
@ -250,66 +293,64 @@ static int do_fdtput(struct display_info *disp, const char *filename,
* store them into the property.
*/
assert(arg_count >= 2);
if (disp->auto_path && create_paths(blob, *arg))
if (disp->auto_path && create_paths(&blob, *arg))
return -1;
if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) ||
store_key_value(blob, *arg, arg[1], value, len))
store_key_value(&blob, *arg, arg[1], value, len))
ret = -1;
break;
case OPER_CREATE_NODE:
for (; ret >= 0 && arg_count--; arg++) {
if (disp->auto_path)
ret = create_paths(blob, *arg);
ret = create_paths(&blob, *arg);
else
ret = create_node(blob, *arg);
ret = create_node(&blob, *arg);
}
break;
}
if (ret >= 0)
if (ret >= 0) {
fdt_pack(blob);
ret = utilfdt_write(filename, blob);
}
free(blob);
return ret;
}
static const char *usage_msg =
"fdtput - write a property value to a device tree\n"
"\n"
"The command line arguments are joined together into a single value.\n"
"\n"
"Usage:\n"
/* Usage related data. */
static const char usage_synopsis[] =
"write a property value to a device tree\n"
" fdtput <options> <dt file> <node> <property> [<value>...]\n"
" fdtput -c <options> <dt file> [<node>...]\n"
"Options:\n"
"\t-c\t\tCreate nodes if they don't already exist\n"
"\t-p\t\tAutomatically create nodes as needed for the node path\n"
"\t-t <type>\tType of data\n"
"\t-v\t\tVerbose: display each value decoded from command line\n"
"\t-h\t\tPrint this help\n\n"
"\n"
"The command line arguments are joined together into a single value.\n"
USAGE_TYPE_MSG;
static void usage(const char *msg)
{
if (msg)
fprintf(stderr, "Error: %s\n\n", msg);
fprintf(stderr, "%s", usage_msg);
exit(2);
}
static const char usage_short_opts[] = "cpt:v" USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
{"create", no_argument, NULL, 'c'},
{"auto-path", no_argument, NULL, 'p'},
{"type", a_argument, NULL, 't'},
{"verbose", no_argument, NULL, 'v'},
USAGE_COMMON_LONG_OPTS,
};
static const char * const usage_opts_help[] = {
"Create nodes if they don't already exist",
"Automatically create nodes as needed for the node path",
"Type of data",
"Display each value decoded from command line",
USAGE_COMMON_OPTS_HELP
};
int main(int argc, char *argv[])
{
int opt;
struct display_info disp;
char *filename = NULL;
memset(&disp, '\0', sizeof(disp));
disp.size = -1;
disp.oper = OPER_WRITE_PROP;
for (;;) {
int c = getopt(argc, argv, "chpt:v");
if (c == -1)
break;
while ((opt = util_getopt_long()) != EOF) {
/*
* TODO: add options to:
* - delete property
@ -317,15 +358,13 @@ int main(int argc, char *argv[])
* - rename node
* - pack fdt before writing
* - set amount of free space when writing
* - expand fdt if value doesn't fit
*/
switch (c) {
switch (opt) {
case_USAGE_COMMON_FLAGS
case 'c':
disp.oper = OPER_CREATE_NODE;
break;
case 'h':
case '?':
usage(NULL);
case 'p':
disp.auto_path = 1;
break;
@ -344,16 +383,16 @@ int main(int argc, char *argv[])
if (optind < argc)
filename = argv[optind++];
if (!filename)
usage("Missing filename");
usage("missing filename");
argv += optind;
argc -= optind;
if (disp.oper == OPER_WRITE_PROP) {
if (argc < 1)
usage("Missing node");
usage("missing node");
if (argc < 2)
usage("Missing property");
usage("missing property");
}
if (do_fdtput(&disp, filename, argv, argc))

View File

@ -261,7 +261,10 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
{
struct property *prop;
struct node *child;
int seen_name_prop = 0;
bool seen_name_prop = false;
if (tree->deleted)
return;
emit->beginnode(etarget, tree->labels);
@ -276,7 +279,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
int nameoff;
if (streq(prop->name, "name"))
seen_name_prop = 1;
seen_name_prop = true;
nameoff = stringtable_insert(strbuf, prop->name);

View File

@ -4,7 +4,7 @@
# be easily embeddable into other systems of Makefiles.
#
LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
LIBFDT_INCLUDES = fdt.h libfdt.h
LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
LIBFDT_VERSION = version.lds
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)

View File

@ -92,7 +92,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
{
const uint32_t *tagp, *lenp;
const fdt32_t *tagp, *lenp;
uint32_t tag;
int offset = startoffset;
const char *p;
@ -198,6 +198,34 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
return offset;
}
int fdt_first_subnode(const void *fdt, int offset)
{
int depth = 0;
offset = fdt_next_node(fdt, offset, &depth);
if (offset < 0 || depth != 1)
return -FDT_ERR_NOTFOUND;
return offset;
}
int fdt_next_subnode(const void *fdt, int offset)
{
int depth = 1;
/*
* With respect to the parent, the depth of the next subnode will be
* the same as the last.
*/
do {
offset = fdt_next_node(fdt, offset, &depth);
if (offset < 0 || depth < 1)
return -FDT_ERR_NOTFOUND;
} while (depth > 1);
return offset;
}
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
{
int len = strlen(s) + 1;

View File

@ -1,48 +1,99 @@
#ifndef _FDT_H
#define _FDT_H
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
* a) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ASSEMBLY__
struct fdt_header {
uint32_t magic; /* magic word FDT_MAGIC */
uint32_t totalsize; /* total size of DT block */
uint32_t off_dt_struct; /* offset to structure */
uint32_t off_dt_strings; /* offset to strings */
uint32_t off_mem_rsvmap; /* offset to memory reserve map */
uint32_t version; /* format version */
uint32_t last_comp_version; /* last compatible version */
fdt32_t magic; /* magic word FDT_MAGIC */
fdt32_t totalsize; /* total size of DT block */
fdt32_t off_dt_struct; /* offset to structure */
fdt32_t off_dt_strings; /* offset to strings */
fdt32_t off_mem_rsvmap; /* offset to memory reserve map */
fdt32_t version; /* format version */
fdt32_t last_comp_version; /* last compatible version */
/* version 2 fields below */
uint32_t boot_cpuid_phys; /* Which physical CPU id we're
fdt32_t boot_cpuid_phys; /* Which physical CPU id we're
booting on */
/* version 3 fields below */
uint32_t size_dt_strings; /* size of the strings block */
fdt32_t size_dt_strings; /* size of the strings block */
/* version 17 fields below */
uint32_t size_dt_struct; /* size of the structure block */
fdt32_t size_dt_struct; /* size of the structure block */
};
struct fdt_reserve_entry {
uint64_t address;
uint64_t size;
fdt64_t address;
fdt64_t size;
};
struct fdt_node_header {
uint32_t tag;
fdt32_t tag;
char name[0];
};
struct fdt_property {
uint32_t tag;
uint32_t len;
uint32_t nameoff;
fdt32_t tag;
fdt32_t len;
fdt32_t nameoff;
char data[0];
};
#endif /* !__ASSEMBLY */
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(uint32_t)
#define FDT_TAGSIZE sizeof(fdt32_t)
#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
#define FDT_END_NODE 0x2 /* End node */
@ -51,10 +102,10 @@ struct fdt_property {
#define FDT_NOP 0x4 /* nop */
#define FDT_END 0x9
#define FDT_V1_SIZE (7*sizeof(uint32_t))
#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))
#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))
#define FDT_V1_SIZE (7*sizeof(fdt32_t))
#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t))
#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))
#define FDT_V16_SIZE FDT_V3_SIZE
#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))
#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))
#endif /* _FDT_H */

View File

@ -322,7 +322,7 @@ const void *fdt_getprop(const void *fdt, int nodeoffset,
uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
{
const uint32_t *php;
const fdt32_t *php;
int len;
/* FIXME: This is a bit sub-optimal, since we potentially scan
@ -515,8 +515,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
return offset; /* error from fdt_next_node() */
}
static int _fdt_stringlist_contains(const char *strlist, int listlen,
const char *str)
int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)
{
int len = strlen(str);
const char *p;
@ -542,7 +541,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
if (!prop)
return len;
if (_fdt_stringlist_contains(prop, len, compatible))
if (fdt_stringlist_contains(prop, len, compatible))
return 0;
else
return 1;

View File

@ -339,7 +339,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
int nodelen;
int err;
uint32_t tag;
uint32_t *endtag;
fdt32_t *endtag;
FDT_RW_CHECK_HEADER(fdt);
@ -366,7 +366,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
memcpy(nh->name, name, namelen);
endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
*endtag = cpu_to_fdt32(FDT_END_NODE);
return offset;

View File

@ -107,6 +107,38 @@ int fdt_create(void *buf, int bufsize)
return 0;
}
int fdt_resize(void *fdt, void *buf, int bufsize)
{
size_t headsize, tailsize;
char *oldtail, *newtail;
FDT_SW_CHECK_HEADER(fdt);
headsize = fdt_off_dt_struct(fdt);
tailsize = fdt_size_dt_strings(fdt);
if ((headsize + tailsize) > bufsize)
return -FDT_ERR_NOSPACE;
oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
newtail = (char *)buf + bufsize - tailsize;
/* Two cases to avoid clobbering data if the old and new
* buffers partially overlap */
if (buf <= fdt) {
memmove(buf, fdt, headsize);
memmove(newtail, oldtail, tailsize);
} else {
memmove(newtail, oldtail, tailsize);
memmove(buf, fdt, headsize);
}
fdt_set_off_dt_strings(buf, bufsize);
fdt_set_totalsize(buf, bufsize);
return 0;
}
int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
{
struct fdt_reserve_entry *re;
@ -153,7 +185,7 @@ int fdt_begin_node(void *fdt, const char *name)
int fdt_end_node(void *fdt)
{
uint32_t *en;
fdt32_t *en;
FDT_SW_CHECK_HEADER(fdt);
@ -213,7 +245,7 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
int fdt_finish(void *fdt)
{
char *p = (char *)fdt;
uint32_t *end;
fdt32_t *end;
int oldstroffset, newstroffset;
uint32_t tag;
int offset, nextoffset;

View File

@ -74,7 +74,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
static void _fdt_nop_region(void *start, int len)
{
uint32_t *p;
fdt32_t *p;
for (p = start; (char *)p < ((char *)start + len); p++)
*p = cpu_to_fdt32(FDT_NOP);

View File

@ -136,6 +136,28 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
int fdt_next_node(const void *fdt, int offset, int *depth);
/**
* fdt_first_subnode() - get offset of first direct subnode
*
* @fdt: FDT blob
* @offset: Offset of node to check
* @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none
*/
int fdt_first_subnode(const void *fdt, int offset);
/**
* fdt_next_subnode() - get offset of next direct subnode
*
* After first calling fdt_first_subnode(), call this function repeatedly to
* get direct subnodes of a parent node.
*
* @fdt: FDT blob
* @offset: Offset of previous subnode
* @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
* subnodes
*/
int fdt_next_subnode(const void *fdt, int offset);
/**********************************************************************/
/* General functions */
/**********************************************************************/
@ -582,7 +604,7 @@ const char *fdt_get_alias_namelen(const void *fdt,
* value of the property named 'name' in the node /aliases.
*
* returns:
* a pointer to the expansion of the alias named 'name', of it exists
* a pointer to the expansion of the alias named 'name', if it exists
* NULL, if the given alias or the /aliases node does not exist
*/
const char *fdt_get_alias(const void *fdt, const char *name);
@ -816,6 +838,20 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
const char *compatible);
/**
* fdt_stringlist_contains - check a string list property for a string
* @strlist: Property containing a list of strings to check
* @listlen: Length of property
* @str: String to search for
*
* This is a utility function provided for convenience. The list contains
* one or more strings, each terminated by \0, as is found in a device tree
* "compatible" property.
*
* @return: 1 if the string is found in the list, 0 not found, or invalid list
*/
int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
/**********************************************************************/
/* Write-in-place functions */
/**********************************************************************/
@ -882,8 +918,8 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
const char *name, uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
fdt32_t tmp = cpu_to_fdt32(val);
return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
}
/**
@ -917,8 +953,8 @@ static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset,
static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset,
const char *name, uint64_t val)
{
val = cpu_to_fdt64(val);
return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
fdt64_t tmp = cpu_to_fdt64(val);
return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp));
}
/**
@ -987,19 +1023,20 @@ int fdt_nop_node(void *fdt, int nodeoffset);
/**********************************************************************/
int fdt_create(void *buf, int bufsize);
int fdt_resize(void *fdt, void *buf, int bufsize);
int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
int fdt_finish_reservemap(void *fdt);
int fdt_begin_node(void *fdt, const char *name);
int fdt_property(void *fdt, const char *name, const void *val, int len);
static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_property(fdt, name, &val, sizeof(val));
fdt32_t tmp = cpu_to_fdt32(val);
return fdt_property(fdt, name, &tmp, sizeof(tmp));
}
static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val)
{
val = cpu_to_fdt64(val);
return fdt_property(fdt, name, &val, sizeof(val));
fdt64_t tmp = cpu_to_fdt64(val);
return fdt_property(fdt, name, &tmp, sizeof(tmp));
}
static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
{
@ -1154,8 +1191,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
fdt32_t tmp = cpu_to_fdt32(val);
return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
}
/**
@ -1189,8 +1226,8 @@ static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name,
static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name,
uint64_t val)
{
val = cpu_to_fdt64(val);
return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
fdt64_t tmp = cpu_to_fdt64(val);
return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
}
/**
@ -1296,8 +1333,8 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
const char *name, uint32_t val)
{
val = cpu_to_fdt32(val);
return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
fdt32_t tmp = cpu_to_fdt32(val);
return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
}
/**
@ -1331,8 +1368,8 @@ static inline int fdt_appendprop_u32(void *fdt, int nodeoffset,
static inline int fdt_appendprop_u64(void *fdt, int nodeoffset,
const char *name, uint64_t val)
{
val = cpu_to_fdt64(val);
return fdt_appendprop(fdt, nodeoffset, name, &val, sizeof(val));
fdt64_t tmp = cpu_to_fdt64(val);
return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp));
}
/**

View File

@ -1,29 +1,111 @@
#ifndef _LIBFDT_ENV_H
#define _LIBFDT_ENV_H
/*
* libfdt - Flat Device Tree manipulation
* Copyright (C) 2006 David Gibson, IBM Corporation.
* Copyright 2012 Kim Phillips, Freescale Semiconductor.
*
* libfdt is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
*
* a) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* Alternatively,
*
* b) Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define EXTRACT_BYTE(n) ((unsigned long long)((uint8_t *)&x)[n])
static inline uint16_t fdt16_to_cpu(uint16_t x)
{
return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1);
}
#define cpu_to_fdt16(x) fdt16_to_cpu(x)
#ifdef __CHECKER__
#define __force __attribute__((force))
#define __bitwise __attribute__((bitwise))
#else
#define __force
#define __bitwise
#endif
static inline uint32_t fdt32_to_cpu(uint32_t x)
{
return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3);
}
#define cpu_to_fdt32(x) fdt32_to_cpu(x)
typedef uint16_t __bitwise fdt16_t;
typedef uint32_t __bitwise fdt32_t;
typedef uint64_t __bitwise fdt64_t;
static inline uint64_t fdt64_to_cpu(uint64_t x)
#define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n])
#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))
#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \
(EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3))
#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \
(EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \
(EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \
(EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7))
static inline uint16_t fdt16_to_cpu(fdt16_t x)
{
return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32)
| (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);
return (__force uint16_t)CPU_TO_FDT16(x);
}
#define cpu_to_fdt64(x) fdt64_to_cpu(x)
static inline fdt16_t cpu_to_fdt16(uint16_t x)
{
return (__force fdt16_t)CPU_TO_FDT16(x);
}
static inline uint32_t fdt32_to_cpu(fdt32_t x)
{
return (__force uint32_t)CPU_TO_FDT32(x);
}
static inline fdt32_t cpu_to_fdt32(uint32_t x)
{
return (__force fdt32_t)CPU_TO_FDT32(x);
}
static inline uint64_t fdt64_to_cpu(fdt64_t x)
{
return (__force uint64_t)CPU_TO_FDT64(x);
}
static inline fdt64_t cpu_to_fdt64(uint64_t x)
{
return (__force fdt64_t)CPU_TO_FDT64(x);
}
#undef CPU_TO_FDT64
#undef CPU_TO_FDT32
#undef CPU_TO_FDT16
#undef EXTRACT_BYTE
#endif /* _LIBFDT_ENV_H */

View File

@ -48,6 +48,12 @@ LIBFDT_1.2 {
fdt_strerror;
fdt_offset_ptr;
fdt_next_tag;
fdt_appendprop;
fdt_create_empty_tree;
fdt_first_property_offset;
fdt_get_property_by_offset;
fdt_getprop_by_offset;
fdt_next_property_offset;
local:
*;

View File

@ -29,16 +29,27 @@ void add_label(struct label **labels, char *label)
struct label *new;
/* Make sure the label isn't already there */
for_each_label(*labels, new)
if (streq(new->label, label))
for_each_label_withdel(*labels, new)
if (streq(new->label, label)) {
new->deleted = 0;
return;
}
new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
new->label = label;
new->next = *labels;
*labels = new;
}
void delete_labels(struct label **labels)
{
struct label *label;
for_each_label(*labels, label)
label->deleted = 1;
}
struct property *build_property(char *name, struct data val)
{
struct property *new = xmalloc(sizeof(*new));
@ -51,6 +62,18 @@ struct property *build_property(char *name, struct data val)
return new;
}
struct property *build_property_delete(char *name)
{
struct property *new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
new->name = name;
new->deleted = 1;
return new;
}
struct property *chain_property(struct property *first, struct property *list)
{
assert(first->next == NULL);
@ -91,6 +114,17 @@ struct node *build_node(struct property *proplist, struct node *children)
return new;
}
struct node *build_node_delete(void)
{
struct node *new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
new->deleted = 1;
return new;
}
struct node *name_node(struct node *node, char *name)
{
assert(node->name == NULL);
@ -106,8 +140,10 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
struct node *new_child, *old_child;
struct label *l;
old_node->deleted = 0;
/* Add new node labels to old node */
for_each_label(new_node->labels, l)
for_each_label_withdel(new_node->labels, l)
add_label(&old_node->labels, l->label);
/* Move properties from the new node to the old node. If there
@ -118,14 +154,21 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
new_node->proplist = new_prop->next;
new_prop->next = NULL;
if (new_prop->deleted) {
delete_property_by_name(old_node, new_prop->name);
free(new_prop);
continue;
}
/* Look for a collision, set new value if there is */
for_each_property(old_node, old_prop) {
for_each_property_withdel(old_node, old_prop) {
if (streq(old_prop->name, new_prop->name)) {
/* Add new labels to old property */
for_each_label(new_prop->labels, l)
for_each_label_withdel(new_prop->labels, l)
add_label(&old_prop->labels, l->label);
old_prop->val = new_prop->val;
old_prop->deleted = 0;
free(new_prop);
new_prop = NULL;
break;
@ -146,8 +189,14 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
new_child->parent = NULL;
new_child->next_sibling = NULL;
if (new_child->deleted) {
delete_node_by_name(old_node, new_child->name);
free(new_child);
continue;
}
/* Search for a collision. Merge if there is */
for_each_child(old_node, old_child) {
for_each_child_withdel(old_node, old_child) {
if (streq(old_child->name, new_child->name)) {
merge_nodes(old_child, new_child);
new_child = NULL;
@ -188,6 +237,25 @@ void add_property(struct node *node, struct property *prop)
*p = prop;
}
void delete_property_by_name(struct node *node, char *name)
{
struct property *prop = node->proplist;
while (prop) {
if (!strcmp(prop->name, name)) {
delete_property(prop);
return;
}
prop = prop->next;
}
}
void delete_property(struct property *prop)
{
prop->deleted = 1;
delete_labels(&prop->labels);
}
void add_child(struct node *parent, struct node *child)
{
struct node **p;
@ -202,6 +270,32 @@ void add_child(struct node *parent, struct node *child)
*p = child;
}
void delete_node_by_name(struct node *parent, char *name)
{
struct node *node = parent->children;
while (node) {
if (!strcmp(node->name, name)) {
delete_node(node);
return;
}
node = node->next_sibling;
}
}
void delete_node(struct node *node)
{
struct property *prop;
struct node *child;
node->deleted = 1;
for_each_child(node, child)
delete_node(child);
for_each_property(node, prop)
delete_property(prop);
delete_labels(&node->labels);
}
struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
{
struct reserve_info *new = xmalloc(sizeof(*new));
@ -353,8 +447,11 @@ struct node *get_node_by_path(struct node *tree, const char *path)
const char *p;
struct node *child;
if (!path || ! (*path))
if (!path || ! (*path)) {
if (tree->deleted)
return NULL;
return tree;
}
while (path[0] == '/')
path++;
@ -397,8 +494,11 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
assert((phandle != 0) && (phandle != -1));
if (tree->phandle == phandle)
if (tree->phandle == phandle) {
if (tree->deleted)
return NULL;
return tree;
}
for_each_child(tree, child) {
node = get_node_by_phandle(child, phandle);
@ -535,7 +635,7 @@ static void sort_properties(struct node *node)
int n = 0, i = 0;
struct property *prop, **tbl;
for_each_property(node, prop)
for_each_property_withdel(node, prop)
n++;
if (n == 0)
@ -543,7 +643,7 @@ static void sort_properties(struct node *node)
tbl = xmalloc(n * sizeof(*tbl));
for_each_property(node, prop)
for_each_property_withdel(node, prop)
tbl[i++] = prop;
qsort(tbl, n, sizeof(*tbl), cmp_prop);
@ -571,7 +671,7 @@ static void sort_subnodes(struct node *node)
int n = 0, i = 0;
struct node *subnode, **tbl;
for_each_child(node, subnode)
for_each_child_withdel(node, subnode)
n++;
if (n == 0)
@ -579,7 +679,7 @@ static void sort_subnodes(struct node *node)
tbl = xmalloc(n * sizeof(*tbl));
for_each_child(node, subnode)
for_each_child_withdel(node, subnode)
tbl[i++] = subnode;
qsort(tbl, n, sizeof(*tbl), cmp_subnode);
@ -598,7 +698,7 @@ static void sort_node(struct node *node)
sort_properties(node);
sort_subnodes(node);
for_each_child(node, c)
for_each_child_withdel(node, c)
sort_node(c);
}

View File

@ -159,7 +159,7 @@ void srcfile_push(const char *fname)
current_srcfile = srcfile;
}
int srcfile_pop(void)
bool srcfile_pop(void)
{
struct srcfile_state *srcfile = current_srcfile;
@ -177,7 +177,7 @@ int srcfile_pop(void)
* fix this we could either allocate all the files from a
* table, or use a pool allocator. */
return current_srcfile ? 1 : 0;
return current_srcfile ? true : false;
}
void srcfile_add_search_path(const char *dirname)
@ -290,41 +290,32 @@ srcpos_string(struct srcpos *pos)
return pos_str;
}
void
srcpos_verror(struct srcpos *pos, char const *fmt, va_list va)
void srcpos_verror(struct srcpos *pos, const char *prefix,
const char *fmt, va_list va)
{
const char *srcstr;
srcstr = srcpos_string(pos);
fprintf(stdout, "Error: %s ", srcstr);
vfprintf(stdout, fmt, va);
fprintf(stdout, "\n");
}
void
srcpos_error(struct srcpos *pos, char const *fmt, ...)
{
va_list va;
va_start(va, fmt);
srcpos_verror(pos, fmt, va);
va_end(va);
}
void
srcpos_warn(struct srcpos *pos, char const *fmt, ...)
{
const char *srcstr;
va_list va;
va_start(va, fmt);
char *srcstr;
srcstr = srcpos_string(pos);
fprintf(stderr, "Warning: %s ", srcstr);
fprintf(stderr, "%s: %s ", prefix, srcstr);
vfprintf(stderr, fmt, va);
fprintf(stderr, "\n");
free(srcstr);
}
void srcpos_error(struct srcpos *pos, const char *prefix,
const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
srcpos_verror(pos, prefix, fmt, va);
va_end(va);
}
void srcpos_set_line(char *f, int l)
{
current_srcfile->name = f;
current_srcfile->lineno = l;
}

View File

@ -21,6 +21,7 @@
#define _SRCPOS_H_
#include <stdio.h>
#include <stdbool.h>
struct srcfile_state {
FILE *f;
@ -55,7 +56,7 @@ extern struct srcfile_state *current_srcfile; /* = NULL */
FILE *srcfile_relative_open(const char *fname, char **fullnamep);
void srcfile_push(const char *fname);
int srcfile_pop(void);
bool srcfile_pop(void);
/**
* Add a new directory to the search path for input files
@ -106,11 +107,13 @@ extern struct srcpos *srcpos_copy(struct srcpos *pos);
extern char *srcpos_string(struct srcpos *pos);
extern void srcpos_dump(struct srcpos *pos);
extern void srcpos_verror(struct srcpos *pos, char const *, va_list va)
__attribute__((format(printf, 2, 0)));
extern void srcpos_error(struct srcpos *pos, char const *, ...)
__attribute__((format(printf, 2, 3)));
extern void srcpos_warn(struct srcpos *pos, char const *, ...)
__attribute__((format(printf, 2, 3)));
extern void srcpos_verror(struct srcpos *pos, const char *prefix,
const char *fmt, va_list va)
__attribute__((format(printf, 3, 0)));
extern void srcpos_error(struct srcpos *pos, const char *prefix,
const char *fmt, ...)
__attribute__((format(printf, 3, 4)));
extern void srcpos_set_line(char *f, int l);
#endif /* _SRCPOS_H_ */

View File

@ -12,7 +12,7 @@ LIB_TESTS_L = get_mem_rsv \
sw_tree1 \
move_and_save mangle-layout nopulate \
open_pack rw_tree1 set_name setprop del_property del_node \
appendprop1 appendprop2 \
appendprop1 appendprop2 propname_escapes \
string_escapes references path-references phandle_format \
boot-cpuid incbin \
extra-terminating-null \
@ -20,7 +20,8 @@ LIB_TESTS_L = get_mem_rsv \
dtb_reverse dtbs_equal_unordered \
add_subnode_with_nops path_offset_aliases \
utilfdt_test \
integer-expressions
integer-expressions \
subnode_iterate
LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)
LIBTREE_TESTS_L = truncated_property

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -1,6 +1,9 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <0>;
aliases {
s1 = &sub1;
ss1 = &subsub1;
@ -9,6 +12,7 @@
sub1: subnode@1 {
compatible = "subnode1";
reg = <1>;
subsub1: subsubnode {
compatible = "subsubnode1", "subsubnode";

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -26,7 +26,6 @@
#include <dlfcn.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -21,7 +21,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <stdint.h>
#include <limits.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <stdint.h>
#include <limits.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -25,9 +25,7 @@
#include <fcntl.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include <libfdt_env.h>
#include "testdata.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -8,7 +8,7 @@ rm -f $LOG $EXPECT
trap "rm -f $LOG $EXPECT" 0
expect="$1"
/bin/echo -e $expect >$EXPECT
printf '%b\n' "$expect" > $EXPECT
shift
verbose_run_log_check "$LOG" $VALGRIND $DTGET "$@"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <stdint.h>
#include <errno.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -8,12 +8,17 @@
/include/ "include5.dts" = <0xdeadbeef>;
prop-int64 /include/ "include5a.dts";
prop-str = /include/ "include6.dts";
#address-cells = <1>;
#size-cells = <0>;
/include/ "include7.dts"
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
/include/ "include8.dts"
phandle = <0x2001>;

View File

@ -1,5 +1,6 @@
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {

View File

@ -1 +1,2 @@
subsubnode@0 {
subsubnode@0 {
reg = <0>;

View File

@ -25,7 +25,6 @@
#include <errno.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <limits.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <limits.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <stdint.h>
#include <stdarg.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <stdint.h>
#include <stdarg.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <stdint.h>
#include <stdarg.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <limits.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <limits.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -7,6 +7,7 @@ if [ -z "$CC" ]; then
fi
export QUIET_TEST=1
STOP_ON_FAIL=0
export VALGRIND=
VGCODE=126
@ -24,6 +25,9 @@ base_run_test() {
tot_pass=$((tot_pass + 1))
else
ret="$?"
if [ "$STOP_ON_FAIL" -eq 1 ]; then
exit 1
fi
if [ "$ret" -eq 1 ]; then
tot_config=$((tot_config + 1))
elif [ "$ret" -eq 2 ]; then
@ -80,7 +84,7 @@ wrap_test () {
}
run_wrap_test () {
echo -n "$@: "
shorten_echo "$@: "
base_run_test wrap_test "$@"
}
@ -190,6 +194,14 @@ libfdt_tests () {
tree1_tests unfinished_tree1.test.dtb
run_test dtbs_equal_ordered test_tree1.dtb sw_tree1.test.dtb
# Resizing tests
for mode in resize realloc; do
run_test sw_tree1 $mode
tree1_tests sw_tree1.test.dtb
tree1_tests unfinished_tree1.test.dtb
run_test dtbs_equal_ordered test_tree1.dtb sw_tree1.test.dtb
done
# fdt_move tests
for tree in test_tree1.dtb sw_tree1.test.dtb unfinished_tree1.test.dtb; do
rm -f moved.$tree shunted.$tree deshunted.$tree
@ -241,6 +253,9 @@ libfdt_tests () {
tree1_tests_rw noppy.$basetree
done
run_dtc_test -I dts -O dtb -o subnode_iterate.dtb subnode_iterate.dts
run_test subnode_iterate subnode_iterate.dtb
# Tests for behaviour on various sorts of corrupted trees
run_test truncated_property
@ -254,6 +269,11 @@ dtc_tests () {
tree1_tests_rw dtc_tree1.test.dtb
run_test dtbs_equal_ordered dtc_tree1.test.dtb test_tree1.dtb
run_dtc_test -I dts -O dtb -o dtc_escapes.test.dtb propname_escapes.dts
run_test propname_escapes dtc_escapes.test.dtb
run_dtc_test -I dts -O dtb -o line_directives.test.dtb line_directives.dts
run_dtc_test -I dts -O dtb -o dtc_escapes.test.dtb escapes.dts
run_test string_escapes dtc_escapes.test.dtb
@ -367,6 +387,13 @@ dtc_tests () {
run_dtc_test -I dts -O dtb -o dtc_tree1_merge_path.test.dtb test_tree1_merge_path.dts
tree1_tests dtc_tree1_merge_path.test.dtb test_tree1.dtb
# Check prop/node delete functionality
run_dtc_test -I dts -O dtb -o dtc_tree1_delete.test.dtb test_tree1_delete.dts
tree1_tests dtc_tree1_delete.test.dtb
run_dtc_test -I dts -O dts -o delete_reinstate_multilabel.dts.test.dts delete_reinstate_multilabel.dts
run_wrap_test cmp delete_reinstate_multilabel.dts.test.dts delete_reinstate_multilabel_ref.dts
# Check some checks
check_tests dup-nodename.dts duplicate_node_names
check_tests dup-propname.dts duplicate_property_names
@ -486,9 +513,10 @@ fdtget_tests () {
# run_fdtget_test <expected-result> [<flags>] <file> <node> <property>
run_fdtget_test "MyBoardName" $dtb / model
run_fdtget_test "MyBoardName MyBoardFamilyName" $dtb / compatible
run_fdtget_test "77 121 66 111 \
97 114 100 78 97 109 101 0 77 121 66 111 97 114 100 70 97 109 105 \
108 121 78 97 109 101 0" $dtb / compatible
108 121 78 97 109 101 0" -t bu $dtb / compatible
run_fdtget_test "MyBoardName MyBoardFamilyName" -t s $dtb / compatible
run_fdtget_test 32768 $dtb /cpus/PowerPC,970@1 d-cache-size
run_fdtget_test 8000 -tx $dtb /cpus/PowerPC,970@1 d-cache-size
@ -533,8 +561,8 @@ fdtput_tests () {
-tx "a0b0c0d deeaae ef000000"
run_fdtput_test "$(cat $text)" $dtb /randomnode blob -ts "$(cat $text)"
# This should be larger than available space in the fdt
run_wrap_error_test $DTPUT $dtb /randomnode blob -ts "$(cat $text $text)"
# Test expansion of the blob when insufficient room for property
run_fdtput_test "$(cat $text $text)" $dtb /randomnode blob -ts "$(cat $text $text)"
# Start again with a fresh dtb
run_dtc_test -O dtb -p $(stat -c %s $text) -o $dtb $dts
@ -556,7 +584,9 @@ fdtput_tests () {
run_fdtput_test "fine wine" $dtb /blackadder/the-second/potato drink \
"-ts" "fine wine"
run_wrap_test $DTPUT $dtb -p /you/are/drunk/sir/winston slurp -ts twice
run_wrap_error_test $DTPUT $dtb -cp "$(cat $text $text)/longish"
# Test expansion of the blob when insufficent room for a new node
run_wrap_test $DTPUT $dtb -cp "$(cat $text $text)/longish"
# Allowed to create an existing node with -p
run_wrap_test $DTPUT $dtb -cp /chosen
@ -569,7 +599,7 @@ utilfdt_tests () {
run_test utilfdt_test
}
while getopts "vt:m" ARG ; do
while getopts "vt:me" ARG ; do
case $ARG in
"v")
unset QUIET_TEST
@ -580,6 +610,9 @@ while getopts "vt:m" ARG ; do
"m")
VALGRIND="valgrind --tool=memcheck -q --error-exitcode=$VGCODE"
;;
"e")
STOP_ON_FAIL=1
;;
esac
done

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -25,7 +25,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -22,7 +22,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <ctype.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"
@ -32,24 +31,92 @@
#define SPACE 65536
#define CHECK(code) \
{ \
err = (code); \
if (err) \
FAIL(#code ": %s", fdt_strerror(err)); \
static enum {
FIXED = 0,
RESIZE,
REALLOC,
} alloc_mode;
static void realloc_fdt(void **fdt, size_t *size, bool created)
{
switch (alloc_mode) {
case FIXED:
if (!(*fdt))
fdt = xmalloc(*size);
else
FAIL("Ran out of space");
return;
case RESIZE:
if (!(*fdt)) {
fdt = xmalloc(SPACE);
} else if (*size < SPACE) {
*size += 1;
fdt_resize(*fdt, *fdt, *size);
} else {
FAIL("Ran out of space");
}
return;
case REALLOC:
*size += 1;
*fdt = xrealloc(*fdt, *size);
if (created)
fdt_resize(*fdt, *fdt, *size);
return;
default:
CONFIG("Bad allocation mode");
}
}
#define CHECK(code) \
do { \
err = (code); \
if (err == -FDT_ERR_NOSPACE) \
realloc_fdt(&fdt, &size, created); \
else if (err) \
FAIL(#code ": %s", fdt_strerror(err)); \
} while (err != 0)
int main(int argc, char *argv[])
{
void *fdt;
void *fdt = NULL;
size_t size;
int err;
bool created = false;
test_init(argc, argv);
fdt = xmalloc(SPACE);
CHECK(fdt_create(fdt, SPACE));
if (argc == 1) {
alloc_mode = FIXED;
size = SPACE;
} else if (argc == 2) {
if (streq(argv[1], "resize")) {
alloc_mode = REALLOC;
size = 0;
} else if (streq(argv[1], "realloc")) {
alloc_mode = REALLOC;
size = 0;
} else {
char *endp;
size = strtoul(argv[1], &endp, 0);
if (*endp == '\0')
alloc_mode = FIXED;
else
CONFIG("Bad allocation mode \"%s\" specified",
argv[1]);
}
}
fdt = xmalloc(size);
CHECK(fdt_create(fdt, size));
created = true;
CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_1, TEST_SIZE_1));
CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_2, TEST_SIZE_2));
CHECK(fdt_finish_reservemap(fdt));
@ -58,9 +125,12 @@ int main(int argc, char *argv[])
CHECK(fdt_property_u32(fdt, "prop-int", TEST_VALUE_1));
CHECK(fdt_property_u64(fdt, "prop-int64", TEST_VALUE64_1));
CHECK(fdt_property_string(fdt, "prop-str", TEST_STRING_1));
CHECK(fdt_property_u32(fdt, "#address-cells", 1));
CHECK(fdt_property_u32(fdt, "#size-cells", 0));
CHECK(fdt_begin_node(fdt, "subnode@1"));
CHECK(fdt_property_string(fdt, "compatible", "subnode1"));
CHECK(fdt_property_u32(fdt, "reg", 1));
CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1));
CHECK(fdt_begin_node(fdt, "subsubnode"));
CHECK(fdt_property(fdt, "compatible", "subsubnode1\0subsubnode",
@ -72,9 +142,13 @@ int main(int argc, char *argv[])
CHECK(fdt_end_node(fdt));
CHECK(fdt_begin_node(fdt, "subnode@2"));
CHECK(fdt_property_u32(fdt, "reg", 2));
CHECK(fdt_property_cell(fdt, "linux,phandle", PHANDLE_1));
CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_2));
CHECK(fdt_property_u32(fdt, "#address-cells", 1));
CHECK(fdt_property_u32(fdt, "#size-cells", 0));
CHECK(fdt_begin_node(fdt, "subsubnode@0"));
CHECK(fdt_property_u32(fdt, "reg", 0));
CHECK(fdt_property_cell(fdt, "phandle", PHANDLE_2));
CHECK(fdt_property(fdt, "compatible", "subsubnode2\0subsubnode",
23));

View File

@ -1,38 +1,3 @@
/dts-v1/;
/memreserve/ 0xdeadbeef00000000 0x100000;
/memreserve/ 123456789 010000;
/ {
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>;
prop-str = "hello world";
subnode@1 {
compatible = "subnode1";
prop-int = [deadbeef];
subsubnode {
compatible = "subsubnode1", "subsubnode";
prop-int = <0xdeadbeef>;
};
ss1 {
};
};
subnode@2 {
linux,phandle = <0x2000>;
prop-int = <123456789>;
ssn0: subsubnode@0 {
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;
};
ss2 {
};
};
};
/include/ "test_tree1_body.dtsi"

View File

@ -6,9 +6,12 @@
compatible = "test_tree1";
prop-int = "wrong!";
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
subsubnode {
compatible = "subsubnode1", "subsubnode";
@ -20,8 +23,11 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
ss2 {
};
@ -36,6 +42,7 @@
};
subnode@2 {
ssn0: subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -8,9 +8,12 @@
prop-int = <0xdeadbeef>;
prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -23,10 +26,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
ssn0: subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
prop-int = <0xbad>;
};

View File

@ -8,9 +8,12 @@
prop-int = <0xdeadbeef>;
prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -23,10 +26,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
ssn0: subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
prop-int = <0xbad>;
};

View File

@ -6,9 +6,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -21,10 +24,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -6,9 +6,12 @@
/ {
compatible = "test_tree1";
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -21,10 +24,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -7,9 +7,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
subsubnode {
compatible = "subsubnode1", "subsubnode";
@ -21,10 +24,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -7,9 +7,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -22,10 +25,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -7,9 +7,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbefe>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -22,10 +25,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -7,9 +7,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -23,10 +26,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -7,9 +7,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -22,10 +25,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -7,9 +7,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -24,8 +27,12 @@
subnode@2 {
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -8,9 +8,12 @@
compatible = "test_tree1";
prop-int = <0xdeadbeef>;
prop-str = "hello world";
#address-cells = <1>;
#size-cells = <0>;
subnode@1 {
compatible = "subnode1";
reg = <1>;
prop-int = [deadbeef];
subsubnode {
@ -23,10 +26,14 @@
};
subnode@2 {
reg = <2>;
linux,phandle = <0x2000>;
prop-int = <123456789>;
#address-cells = <1>;
#size-cells = <0>;
subsubnode@0 {
reg = <0>;
phandle = <0x2001>;
compatible = "subsubnode2", "subsubnode";
prop-int = <0726746425>;

View File

@ -92,9 +92,12 @@ test_tree1_struct:
PROP_INT(test_tree1, prop_int, TEST_VALUE_1)
PROP_INT64(test_tree1, prop_int64, TEST_VALUE64_1)
PROP_STR(test_tree1, prop_str, TEST_STRING_1)
PROP_INT(test_tree1, address_cells, 1)
PROP_INT(test_tree1, size_cells, 0)
BEGIN_NODE("subnode@1")
PROP_STR(test_tree1, compatible, "subnode1")
PROP_INT(test_tree1, reg, 1)
PROP_INT(test_tree1, prop_int, TEST_VALUE_1)
BEGIN_NODE("subsubnode")
@ -108,10 +111,14 @@ test_tree1_struct:
END_NODE
BEGIN_NODE("subnode@2")
PROP_INT(test_tree1, reg, 2)
PROP_INT(test_tree1, linux_phandle, PHANDLE_1)
PROP_INT(test_tree1, prop_int, TEST_VALUE_2)
PROP_INT(test_tree1, address_cells, 1)
PROP_INT(test_tree1, size_cells, 0)
BEGIN_NODE("subsubnode@0")
PROP_INT(test_tree1, reg, 0)
PROP_INT(test_tree1, phandle, PHANDLE_2)
PROP_STR(test_tree1, compatible, "subsubnode2\0subsubnode")
PROP_INT(test_tree1, prop_int, TEST_VALUE_2)
@ -133,6 +140,9 @@ test_tree1_strings:
STRING(test_tree1, prop_str, "prop-str")
STRING(test_tree1, linux_phandle, "linux,phandle")
STRING(test_tree1, phandle, "phandle")
STRING(test_tree1, reg, "reg")
STRING(test_tree1, address_cells, "#address-cells")
STRING(test_tree1, size_cells, "#size-cells")
test_tree1_strings_end:
test_tree1_end:

View File

@ -23,7 +23,6 @@
#include <string.h>
#include <stdint.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -24,7 +24,6 @@
#include <stdint.h>
#include <stdarg.h>
#include <fdt.h>
#include <libfdt.h>
#include <util.h>

View File

@ -26,7 +26,6 @@
#include <dlfcn.h>
#include <fdt.h>
#include <libfdt.h>
#include "tests.h"

View File

@ -26,12 +26,12 @@ extern int yyparse(void);
extern YYLTYPE yylloc;
struct boot_info *the_boot_info;
int treesource_error;
bool treesource_error;
struct boot_info *dt_from_source(const char *fname)
{
the_boot_info = NULL;
treesource_error = 0;
treesource_error = false;
srcfile_push(fname);
yyin = current_srcfile->f;
@ -54,9 +54,9 @@ static void write_prefix(FILE *f, int level)
fputc('\t', f);
}
static int isstring(char c)
static bool isstring(char c)
{
return (isprint(c)
return (isprint((unsigned char)c)
|| (c == '\0')
|| strchr("\a\b\t\n\v\f\r", c));
}
@ -119,7 +119,7 @@ static void write_propval_string(FILE *f, struct data val)
fprintf(f, "\"");
break;
default:
if (isprint(c))
if (isprint((unsigned char)c))
fprintf(f, "%c", c);
else
fprintf(f, "\\x%02hhx", c);

Some files were not shown because too many files have changed in this diff Show More