Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (29 commits) of/flattree: forward declare struct device_node in of_fdt.h ipmi: explicitly include of_address.h and of_irq.h sparc: explicitly cast negative phandle checks to s32 powerpc/405: Fix missing #{address,size}-cells in i2c node powerpc/5200: dts: refactor dts files powerpc/5200: dts: Change combatible strings on localbus powerpc/5200: dts: remove unused properties powerpc/5200: dts: rename nodes to prepare for refactoring dts files of/flattree: Update dtc to current mainline. of/device: Don't register disabled devices powerpc/dts: fix syntax bugs in bluestone.dts of: Fixes for OF probing on little endian systems of: make drivers depend on CONFIG_OF instead of CONFIG_PPC_OF of/flattree: Add of_flat_dt_match() helper function of_serial: explicitly include of_irq.h of/flattree: Refactor unflatten_device_tree and add fdt_unflatten_tree of/flattree: Reorder unflatten_dt_node of/flattree: Refactor unflatten_dt_node of/flattree: Add non-boottime device tree functions of/flattree: Add Kconfig for EARLY_FLATTREE ... Fix up trivial conflict in arch/sparc/prom/tree_32.c as per Grant.
This commit is contained in:
@ -200,6 +200,29 @@ quiet_cmd_gzip = GZIP $@
|
||||
cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \
|
||||
(rm -f $@ ; false)
|
||||
|
||||
# DTC
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Generate an assembly file to wrap the output of the device tree compiler
|
||||
quiet_cmd_dt_S_dtb= DTB $@
|
||||
cmd_dt_S_dtb= \
|
||||
( \
|
||||
echo '\#include <asm-generic/vmlinux.lds.h>'; \
|
||||
echo '.section .dtb.init.rodata,"a"'; \
|
||||
echo '.balign STRUCT_ALIGNMENT'; \
|
||||
echo '.global __dtb_$(*F)_begin'; \
|
||||
echo '__dtb_$(*F)_begin:'; \
|
||||
echo '.incbin "$<" '; \
|
||||
echo '__dtb_$(*F)_end:'; \
|
||||
echo '.global __dtb_$(*F)_end'; \
|
||||
echo '.balign STRUCT_ALIGNMENT'; \
|
||||
) > $@
|
||||
|
||||
$(obj)/%.dtb.S: $(obj)/%.dtb
|
||||
$(call cmd,dt_S_dtb)
|
||||
|
||||
quiet_cmd_dtc = DTC $@
|
||||
cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $<
|
||||
|
||||
# Bzip2
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@ -4,7 +4,7 @@ hostprogs-y := dtc
|
||||
always := $(hostprogs-y)
|
||||
|
||||
dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
|
||||
srcpos.o checks.o
|
||||
srcpos.o checks.o util.o
|
||||
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
|
||||
@ -19,6 +19,7 @@ HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
|
||||
HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC)
|
||||
HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
|
||||
HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
|
||||
HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
|
||||
|
||||
HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
|
||||
HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
|
||||
|
@ -278,32 +278,112 @@ static void check_property_name_chars(struct check *c, struct node *dt,
|
||||
}
|
||||
PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
|
||||
|
||||
static void check_explicit_phandles(struct check *c, struct node *root,
|
||||
struct node *node)
|
||||
#define DESCLABEL_FMT "%s%s%s%s%s"
|
||||
#define DESCLABEL_ARGS(node,prop,mark) \
|
||||
((mark) ? "value of " : ""), \
|
||||
((prop) ? "'" : ""), \
|
||||
((prop) ? (prop)->name : ""), \
|
||||
((prop) ? "' in " : ""), (node)->fullpath
|
||||
|
||||
static void check_duplicate_label(struct check *c, struct node *dt,
|
||||
const char *label, struct node *node,
|
||||
struct property *prop, struct marker *mark)
|
||||
{
|
||||
struct property *prop;
|
||||
struct node *othernode = NULL;
|
||||
struct property *otherprop = NULL;
|
||||
struct marker *othermark = NULL;
|
||||
|
||||
othernode = get_node_by_label(dt, label);
|
||||
|
||||
if (!othernode)
|
||||
otherprop = get_property_by_label(dt, label, &othernode);
|
||||
if (!othernode)
|
||||
othermark = get_marker_label(dt, label, &othernode,
|
||||
&otherprop);
|
||||
|
||||
if (!othernode)
|
||||
return;
|
||||
|
||||
if ((othernode != node) || (otherprop != prop) || (othermark != mark))
|
||||
FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
|
||||
" and " DESCLABEL_FMT,
|
||||
label, DESCLABEL_ARGS(node, prop, mark),
|
||||
DESCLABEL_ARGS(othernode, otherprop, othermark));
|
||||
}
|
||||
|
||||
static void check_duplicate_label_node(struct check *c, struct node *dt,
|
||||
struct node *node)
|
||||
{
|
||||
struct label *l;
|
||||
|
||||
for_each_label(node->labels, l)
|
||||
check_duplicate_label(c, dt, l->label, node, NULL, NULL);
|
||||
}
|
||||
static void check_duplicate_label_prop(struct check *c, struct node *dt,
|
||||
struct node *node, struct property *prop)
|
||||
{
|
||||
struct marker *m = prop->val.markers;
|
||||
struct label *l;
|
||||
|
||||
for_each_label(prop->labels, l)
|
||||
check_duplicate_label(c, dt, l->label, node, prop, NULL);
|
||||
|
||||
for_each_marker_of_type(m, LABEL)
|
||||
check_duplicate_label(c, dt, m->ref, node, prop, m);
|
||||
}
|
||||
CHECK(duplicate_label, NULL, check_duplicate_label_node,
|
||||
check_duplicate_label_prop, NULL, ERROR);
|
||||
|
||||
static void check_explicit_phandles(struct check *c, struct node *root,
|
||||
struct node *node, struct property *prop)
|
||||
{
|
||||
struct marker *m;
|
||||
struct node *other;
|
||||
cell_t phandle;
|
||||
|
||||
prop = get_property(node, "linux,phandle");
|
||||
if (! prop)
|
||||
return; /* No phandle, that's fine */
|
||||
if (!streq(prop->name, "phandle")
|
||||
&& !streq(prop->name, "linux,phandle"))
|
||||
return;
|
||||
|
||||
if (prop->val.len != sizeof(cell_t)) {
|
||||
FAIL(c, "%s has bad length (%d) linux,phandle property",
|
||||
node->fullpath, prop->val.len);
|
||||
FAIL(c, "%s has bad length (%d) %s property",
|
||||
node->fullpath, prop->val.len, prop->name);
|
||||
return;
|
||||
}
|
||||
|
||||
m = prop->val.markers;
|
||||
for_each_marker_of_type(m, REF_PHANDLE) {
|
||||
assert(m->offset == 0);
|
||||
if (node != get_node_by_ref(root, m->ref))
|
||||
/* "Set this node's phandle equal to some
|
||||
* other node's phandle". That's nonsensical
|
||||
* by construction. */ {
|
||||
FAIL(c, "%s in %s is a reference to another node",
|
||||
prop->name, node->fullpath);
|
||||
return;
|
||||
}
|
||||
/* But setting this node's phandle equal to its own
|
||||
* phandle is allowed - that means allocate a unique
|
||||
* phandle for this node, even if it's not otherwise
|
||||
* referenced. The value will be filled in later, so
|
||||
* no further checking for now. */
|
||||
return;
|
||||
}
|
||||
|
||||
phandle = propval_cell(prop);
|
||||
|
||||
if ((phandle == 0) || (phandle == -1)) {
|
||||
FAIL(c, "%s has invalid linux,phandle value 0x%x",
|
||||
node->fullpath, phandle);
|
||||
FAIL(c, "%s has bad value (0x%x) in %s property",
|
||||
node->fullpath, phandle, prop->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->phandle && (node->phandle != phandle))
|
||||
FAIL(c, "%s has %s property which replaces existing phandle information",
|
||||
node->fullpath, prop->name);
|
||||
|
||||
other = get_node_by_phandle(root, phandle);
|
||||
if (other) {
|
||||
if (other && (other != node)) {
|
||||
FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
|
||||
node->fullpath, phandle, other->fullpath);
|
||||
return;
|
||||
@ -311,7 +391,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
|
||||
|
||||
node->phandle = phandle;
|
||||
}
|
||||
NODE_CHECK(explicit_phandles, NULL, ERROR);
|
||||
PROP_CHECK(explicit_phandles, NULL, ERROR);
|
||||
|
||||
static void check_name_properties(struct check *c, struct node *root,
|
||||
struct node *node)
|
||||
@ -549,6 +629,9 @@ static struct check *check_table[] = {
|
||||
&duplicate_node_names, &duplicate_property_names,
|
||||
&node_name_chars, &node_name_format, &property_name_chars,
|
||||
&name_is_string, &name_properties,
|
||||
|
||||
&duplicate_label,
|
||||
|
||||
&explicit_phandles,
|
||||
&phandle_references, &path_references,
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
* USA
|
||||
*/
|
||||
|
||||
%option noyywrap noinput nounput yylineno
|
||||
%option noyywrap nounput noinput never-interactive
|
||||
|
||||
%x INCLUDE
|
||||
%x BYTESTRING
|
||||
@ -38,6 +38,13 @@ LINECOMMENT "//".*\n
|
||||
#include "srcpos.h"
|
||||
#include "dtc-parser.tab.h"
|
||||
|
||||
YYLTYPE yylloc;
|
||||
|
||||
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
|
||||
#define YY_USER_ACTION \
|
||||
{ \
|
||||
srcpos_update(&yylloc, yytext, yyleng); \
|
||||
}
|
||||
|
||||
/*#define LEXDEBUG 1*/
|
||||
|
||||
@ -47,15 +54,10 @@ LINECOMMENT "//".*\n
|
||||
#define DPRINT(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
static int dts_version; /* = 0 */
|
||||
static int dts_version = 1;
|
||||
|
||||
#define BEGIN_DEFAULT() if (dts_version == 0) { \
|
||||
DPRINT("<INITIAL>\n"); \
|
||||
BEGIN(INITIAL); \
|
||||
} else { \
|
||||
DPRINT("<V1>\n"); \
|
||||
#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
|
||||
BEGIN(V1); \
|
||||
}
|
||||
|
||||
static void push_input_file(const char *filename);
|
||||
static int pop_input_file(void);
|
||||
@ -75,18 +77,13 @@ static int pop_input_file(void);
|
||||
}
|
||||
|
||||
<*>{STRING} {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("String: %s\n", yytext);
|
||||
yylval.data = data_copy_escape_string(yytext+1,
|
||||
yyleng-2);
|
||||
yylloc.first_line = yylineno;
|
||||
return DT_STRING;
|
||||
}
|
||||
|
||||
<*>"/dts-v1/" {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Keyword: /dts-v1/\n");
|
||||
dts_version = 1;
|
||||
BEGIN_DEFAULT();
|
||||
@ -94,106 +91,57 @@ static int pop_input_file(void);
|
||||
}
|
||||
|
||||
<*>"/memreserve/" {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Keyword: /memreserve/\n");
|
||||
BEGIN_DEFAULT();
|
||||
return DT_MEMRESERVE;
|
||||
}
|
||||
|
||||
<*>{LABEL}: {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Label: %s\n", yytext);
|
||||
yylval.labelref = strdup(yytext);
|
||||
yylval.labelref = xstrdup(yytext);
|
||||
yylval.labelref[yyleng-1] = '\0';
|
||||
return DT_LABEL;
|
||||
}
|
||||
|
||||
<INITIAL>[bodh]# {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
if (*yytext == 'b')
|
||||
yylval.cbase = 2;
|
||||
else if (*yytext == 'o')
|
||||
yylval.cbase = 8;
|
||||
else if (*yytext == 'd')
|
||||
yylval.cbase = 10;
|
||||
else
|
||||
yylval.cbase = 16;
|
||||
DPRINT("Base: %d\n", yylval.cbase);
|
||||
return DT_BASE;
|
||||
}
|
||||
|
||||
<INITIAL>[0-9a-fA-F]+ {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yylval.literal = strdup(yytext);
|
||||
DPRINT("Literal: '%s'\n", yylval.literal);
|
||||
return DT_LEGACYLITERAL;
|
||||
}
|
||||
|
||||
<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yylval.literal = strdup(yytext);
|
||||
yylval.literal = xstrdup(yytext);
|
||||
DPRINT("Literal: '%s'\n", yylval.literal);
|
||||
return DT_LITERAL;
|
||||
}
|
||||
|
||||
\&{LABEL} { /* label reference */
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
<*>\&{LABEL} { /* label reference */
|
||||
DPRINT("Ref: %s\n", yytext+1);
|
||||
yylval.labelref = strdup(yytext+1);
|
||||
yylval.labelref = xstrdup(yytext+1);
|
||||
return DT_REF;
|
||||
}
|
||||
|
||||
"&{/"{PATHCHAR}+\} { /* new-style path reference */
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */
|
||||
yytext[yyleng-1] = '\0';
|
||||
DPRINT("Ref: %s\n", yytext+2);
|
||||
yylval.labelref = strdup(yytext+2);
|
||||
return DT_REF;
|
||||
}
|
||||
|
||||
<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Ref: %s\n", yytext+1);
|
||||
yylval.labelref = strdup(yytext+1);
|
||||
yylval.labelref = xstrdup(yytext+2);
|
||||
return DT_REF;
|
||||
}
|
||||
|
||||
<BYTESTRING>[0-9a-fA-F]{2} {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yylval.byte = strtol(yytext, NULL, 16);
|
||||
DPRINT("Byte: %02x\n", (int)yylval.byte);
|
||||
return DT_BYTE;
|
||||
}
|
||||
|
||||
<BYTESTRING>"]" {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("/BYTESTRING\n");
|
||||
BEGIN_DEFAULT();
|
||||
return ']';
|
||||
}
|
||||
|
||||
<PROPNODENAME>{PROPNODECHAR}+ {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("PropNodeName: %s\n", yytext);
|
||||
yylval.propnodename = strdup(yytext);
|
||||
yylval.propnodename = xstrdup(yytext);
|
||||
BEGIN_DEFAULT();
|
||||
return DT_PROPNODENAME;
|
||||
}
|
||||
|
||||
"/incbin/" {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Binary Include\n");
|
||||
return DT_INCBIN;
|
||||
}
|
||||
@ -203,8 +151,6 @@ static int pop_input_file(void);
|
||||
<*>{LINECOMMENT}+ /* eat C++-style comments */
|
||||
|
||||
<*>. {
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
|
||||
(unsigned)yytext[0]);
|
||||
if (yytext[0] == '[') {
|
||||
@ -221,100 +167,25 @@ static int pop_input_file(void);
|
||||
|
||||
%%
|
||||
|
||||
|
||||
/*
|
||||
* Stack of nested include file contexts.
|
||||
*/
|
||||
|
||||
struct incl_file {
|
||||
struct dtc_file *file;
|
||||
YY_BUFFER_STATE yy_prev_buf;
|
||||
int yy_prev_lineno;
|
||||
struct incl_file *prev;
|
||||
};
|
||||
|
||||
static struct incl_file *incl_file_stack;
|
||||
|
||||
|
||||
/*
|
||||
* Detect infinite include recursion.
|
||||
*/
|
||||
#define MAX_INCLUDE_DEPTH (100)
|
||||
|
||||
static int incl_depth = 0;
|
||||
|
||||
|
||||
static void push_input_file(const char *filename)
|
||||
{
|
||||
struct incl_file *incl_file;
|
||||
struct dtc_file *newfile;
|
||||
struct search_path search, *searchptr = NULL;
|
||||
|
||||
assert(filename);
|
||||
|
||||
if (incl_depth++ >= MAX_INCLUDE_DEPTH)
|
||||
die("Includes nested too deeply");
|
||||
srcfile_push(filename);
|
||||
|
||||
if (srcpos_file) {
|
||||
search.dir = srcpos_file->dir;
|
||||
search.next = NULL;
|
||||
search.prev = NULL;
|
||||
searchptr = &search;
|
||||
}
|
||||
yyin = current_srcfile->f;
|
||||
|
||||
newfile = dtc_open_file(filename, searchptr);
|
||||
|
||||
incl_file = xmalloc(sizeof(struct incl_file));
|
||||
|
||||
/*
|
||||
* Save current context.
|
||||
*/
|
||||
incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
|
||||
incl_file->yy_prev_lineno = yylineno;
|
||||
incl_file->file = srcpos_file;
|
||||
incl_file->prev = incl_file_stack;
|
||||
|
||||
incl_file_stack = incl_file;
|
||||
|
||||
/*
|
||||
* Establish new context.
|
||||
*/
|
||||
srcpos_file = newfile;
|
||||
yylineno = 1;
|
||||
yyin = newfile->file;
|
||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
||||
yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
|
||||
}
|
||||
|
||||
|
||||
static int pop_input_file(void)
|
||||
{
|
||||
struct incl_file *incl_file;
|
||||
|
||||
if (incl_file_stack == 0)
|
||||
if (srcfile_pop() == 0)
|
||||
return 0;
|
||||
|
||||
dtc_close_file(srcpos_file);
|
||||
|
||||
/*
|
||||
* Pop.
|
||||
*/
|
||||
--incl_depth;
|
||||
incl_file = incl_file_stack;
|
||||
incl_file_stack = incl_file->prev;
|
||||
|
||||
/*
|
||||
* Recover old context.
|
||||
*/
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
yy_switch_to_buffer(incl_file->yy_prev_buf);
|
||||
yylineno = incl_file->yy_prev_lineno;
|
||||
srcpos_file = incl_file->file;
|
||||
yyin = incl_file->file ? incl_file->file->file : NULL;
|
||||
|
||||
/*
|
||||
* Free old state.
|
||||
*/
|
||||
free(incl_file);
|
||||
yypop_buffer_state();
|
||||
yyin = current_srcfile->f;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -170,20 +170,7 @@ extern FILE *yyin, *yyout;
|
||||
#define EOB_ACT_END_OF_FILE 1
|
||||
#define EOB_ACT_LAST_MATCH 2
|
||||
|
||||
/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
|
||||
* access to the local variable yy_act. Since yyless() is a macro, it would break
|
||||
* existing scanners that call yyless() from OUTSIDE yylex.
|
||||
* One obvious solution it to make yy_act a global. I tried that, and saw
|
||||
* a 5% performance hit in a non-yylineno scanner, because yy_act is
|
||||
* normally declared as a register variable-- so it is not worth it.
|
||||
*/
|
||||
#define YY_LESS_LINENO(n) \
|
||||
do { \
|
||||
int yyl;\
|
||||
for ( yyl = n; yyl < yyleng; ++yyl )\
|
||||
if ( yytext[yyl] == '\n' )\
|
||||
--yylineno;\
|
||||
}while(0)
|
||||
#define YY_LESS_LINENO(n)
|
||||
|
||||
/* Return all but the first "n" matched characters back to the input stream. */
|
||||
#define yyless(n) \
|
||||
@ -385,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] );
|
||||
*yy_cp = '\0'; \
|
||||
(yy_c_buf_p) = yy_cp;
|
||||
|
||||
#define YY_NUM_RULES 20
|
||||
#define YY_END_OF_BUFFER 21
|
||||
#define YY_NUM_RULES 17
|
||||
#define YY_END_OF_BUFFER 18
|
||||
/* This struct is not used in this scanner,
|
||||
but its presence is necessary. */
|
||||
struct yy_trans_info
|
||||
@ -394,20 +381,19 @@ struct yy_trans_info
|
||||
flex_int32_t yy_verify;
|
||||
flex_int32_t yy_nxt;
|
||||
};
|
||||
static yyconst flex_int16_t yy_accept[104] =
|
||||
static yyconst flex_int16_t yy_accept[94] =
|
||||
{ 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
21, 19, 16, 16, 19, 19, 19, 7, 7, 19,
|
||||
7, 19, 19, 19, 19, 13, 14, 14, 19, 8,
|
||||
8, 16, 0, 2, 0, 0, 9, 0, 0, 0,
|
||||
0, 0, 0, 7, 7, 5, 0, 6, 0, 12,
|
||||
12, 14, 14, 8, 0, 11, 9, 0, 0, 0,
|
||||
0, 18, 0, 0, 0, 0, 8, 0, 17, 0,
|
||||
0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 3, 15,
|
||||
18, 16, 13, 13, 16, 16, 16, 16, 16, 16,
|
||||
16, 10, 11, 11, 6, 6, 13, 0, 2, 0,
|
||||
7, 0, 0, 0, 0, 0, 0, 0, 5, 0,
|
||||
9, 9, 11, 11, 6, 0, 7, 0, 0, 0,
|
||||
0, 15, 0, 0, 0, 0, 6, 0, 14, 0,
|
||||
0, 0, 0, 0, 8, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 3, 12,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
|
||||
|
||||
0, 4, 0
|
||||
|
||||
} ;
|
||||
|
||||
static yyconst flex_int32_t yy_ec[256] =
|
||||
@ -416,16 +402,16 @@ static yyconst flex_int32_t yy_ec[256] =
|
||||
2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 2, 1, 4, 5, 1, 1, 6, 1, 1,
|
||||
1, 7, 8, 8, 9, 8, 10, 11, 12, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 14, 1, 1,
|
||||
1, 1, 8, 8, 15, 15, 15, 15, 15, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 17, 16, 16,
|
||||
1, 18, 19, 1, 16, 1, 15, 20, 21, 22,
|
||||
1, 7, 5, 5, 8, 5, 9, 10, 11, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 13, 1, 1,
|
||||
1, 1, 5, 5, 14, 14, 14, 14, 14, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
|
||||
1, 17, 18, 1, 15, 1, 14, 19, 20, 21,
|
||||
|
||||
23, 15, 16, 24, 25, 16, 16, 26, 27, 28,
|
||||
24, 16, 16, 29, 30, 31, 32, 33, 16, 17,
|
||||
16, 16, 34, 1, 35, 1, 1, 1, 1, 1,
|
||||
22, 14, 15, 15, 23, 15, 15, 24, 25, 26,
|
||||
15, 15, 15, 27, 28, 29, 30, 31, 15, 16,
|
||||
15, 15, 32, 1, 33, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
@ -442,136 +428,114 @@ static yyconst flex_int32_t yy_ec[256] =
|
||||
1, 1, 1, 1, 1
|
||||
} ;
|
||||
|
||||
static yyconst flex_int32_t yy_meta[36] =
|
||||
static yyconst flex_int32_t yy_meta[34] =
|
||||
{ 0,
|
||||
1, 1, 1, 1, 2, 1, 2, 2, 2, 3,
|
||||
4, 4, 4, 5, 6, 7, 7, 1, 1, 6,
|
||||
6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 8, 1
|
||||
1, 1, 1, 1, 2, 1, 2, 2, 3, 4,
|
||||
4, 4, 5, 6, 7, 7, 1, 1, 6, 6,
|
||||
6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 8, 1
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_base[117] =
|
||||
static yyconst flex_int16_t yy_base[106] =
|
||||
{ 0,
|
||||
0, 0, 30, 0, 44, 0, 67, 0, 97, 105,
|
||||
302, 303, 35, 44, 40, 94, 112, 0, 129, 152,
|
||||
296, 295, 159, 0, 176, 303, 0, 116, 95, 165,
|
||||
49, 46, 102, 303, 296, 0, 0, 288, 290, 293,
|
||||
264, 266, 270, 0, 0, 303, 0, 303, 264, 303,
|
||||
0, 0, 195, 101, 0, 0, 0, 0, 284, 125,
|
||||
277, 265, 225, 230, 216, 218, 0, 202, 224, 221,
|
||||
217, 107, 196, 188, 303, 206, 179, 186, 178, 185,
|
||||
183, 162, 161, 150, 169, 160, 145, 125, 303, 303,
|
||||
137, 109, 190, 103, 203, 167, 108, 197, 303, 123,
|
||||
0, 0, 237, 236, 25, 0, 47, 0, 30, 71,
|
||||
244, 247, 82, 84, 84, 211, 95, 229, 218, 0,
|
||||
111, 247, 0, 84, 83, 95, 106, 86, 247, 237,
|
||||
0, 230, 231, 234, 207, 209, 212, 220, 247, 206,
|
||||
247, 218, 0, 106, 116, 0, 0, 0, 223, 89,
|
||||
226, 219, 199, 206, 200, 204, 0, 190, 213, 212,
|
||||
202, 91, 178, 161, 247, 172, 144, 150, 140, 130,
|
||||
140, 124, 128, 120, 138, 137, 123, 122, 247, 247,
|
||||
134, 114, 132, 86, 135, 125, 90, 136, 247, 97,
|
||||
29, 247, 247, 153, 156, 161, 165, 170, 176, 180,
|
||||
|
||||
29, 303, 303, 215, 221, 226, 229, 234, 240, 246,
|
||||
250, 257, 265, 270, 275, 282
|
||||
187, 195, 200, 205, 212
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_def[117] =
|
||||
static yyconst flex_int16_t yy_def[106] =
|
||||
{ 0,
|
||||
103, 1, 1, 3, 3, 5, 103, 7, 3, 3,
|
||||
103, 103, 103, 103, 104, 105, 103, 106, 103, 19,
|
||||
19, 20, 103, 107, 20, 103, 108, 109, 105, 103,
|
||||
103, 103, 104, 103, 104, 110, 111, 103, 112, 113,
|
||||
103, 103, 103, 106, 19, 103, 20, 103, 103, 103,
|
||||
20, 108, 109, 103, 114, 110, 111, 115, 112, 112,
|
||||
113, 103, 103, 103, 103, 103, 114, 115, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 116, 103, 116, 103, 116,
|
||||
93, 1, 1, 1, 1, 5, 93, 7, 1, 1,
|
||||
93, 93, 93, 93, 94, 95, 93, 96, 17, 97,
|
||||
96, 93, 98, 99, 93, 93, 93, 94, 93, 94,
|
||||
100, 93, 101, 102, 93, 93, 93, 96, 93, 93,
|
||||
93, 96, 98, 99, 93, 103, 100, 104, 101, 101,
|
||||
102, 93, 93, 93, 93, 93, 103, 104, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 105, 93, 105, 93, 105,
|
||||
93, 93, 0, 93, 93, 93, 93, 93, 93, 93,
|
||||
|
||||
103, 103, 0, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103
|
||||
93, 93, 93, 93, 93
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_nxt[339] =
|
||||
static yyconst flex_int16_t yy_nxt[281] =
|
||||
{ 0,
|
||||
12, 13, 14, 15, 12, 16, 12, 12, 12, 17,
|
||||
18, 18, 18, 12, 19, 20, 20, 12, 12, 21,
|
||||
19, 21, 19, 22, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 12, 12, 12, 32, 32, 102, 23,
|
||||
12, 12, 12, 34, 20, 32, 32, 32, 32, 20,
|
||||
20, 20, 20, 20, 24, 24, 24, 35, 25, 54,
|
||||
54, 54, 26, 25, 25, 25, 25, 12, 13, 14,
|
||||
15, 27, 12, 27, 27, 27, 23, 27, 27, 27,
|
||||
12, 28, 28, 28, 12, 12, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
12, 13, 14, 15, 12, 16, 12, 12, 17, 12,
|
||||
12, 12, 12, 18, 18, 18, 12, 12, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 12, 12, 19, 20, 20, 20, 92, 21, 25,
|
||||
26, 26, 22, 21, 21, 21, 21, 12, 13, 14,
|
||||
15, 23, 16, 23, 23, 19, 23, 23, 23, 12,
|
||||
24, 24, 24, 12, 12, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 12, 12,
|
||||
25, 26, 26, 27, 27, 27, 27, 29, 43, 29,
|
||||
43, 43, 45, 45, 45, 50, 39, 59, 46, 93,
|
||||
|
||||
12, 12, 29, 36, 103, 34, 17, 30, 31, 31,
|
||||
29, 54, 54, 54, 17, 30, 31, 31, 39, 35,
|
||||
52, 40, 52, 52, 52, 103, 78, 38, 38, 46,
|
||||
101, 60, 79, 41, 69, 97, 42, 94, 43, 45,
|
||||
45, 45, 46, 45, 47, 47, 93, 92, 45, 45,
|
||||
45, 45, 47, 47, 47, 47, 47, 47, 47, 47,
|
||||
47, 47, 47, 47, 47, 39, 47, 91, 40, 90,
|
||||
99, 47, 47, 47, 47, 54, 54, 54, 89, 88,
|
||||
41, 55, 87, 49, 100, 43, 51, 51, 51, 86,
|
||||
51, 95, 95, 96, 85, 51, 51, 51, 51, 52,
|
||||
30, 33, 30, 34, 45, 45, 45, 27, 27, 68,
|
||||
43, 91, 43, 43, 69, 35, 87, 36, 39, 37,
|
||||
42, 42, 42, 39, 42, 45, 45, 45, 89, 42,
|
||||
42, 42, 42, 85, 85, 86, 85, 85, 86, 89,
|
||||
84, 90, 83, 82, 81, 80, 79, 78, 77, 76,
|
||||
75, 74, 90, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 31, 31, 31, 38, 38, 38, 38, 41, 73,
|
||||
41, 43, 72, 43, 71, 43, 43, 44, 33, 44,
|
||||
44, 44, 44, 47, 69, 47, 47, 49, 49, 49,
|
||||
49, 49, 49, 49, 49, 51, 51, 51, 51, 51,
|
||||
|
||||
99, 52, 52, 52, 95, 95, 96, 84, 46, 83,
|
||||
82, 81, 39, 79, 100, 33, 33, 33, 33, 33,
|
||||
33, 33, 33, 37, 80, 77, 37, 37, 37, 44,
|
||||
40, 44, 50, 76, 50, 52, 75, 52, 74, 52,
|
||||
52, 53, 73, 53, 53, 53, 53, 56, 56, 56,
|
||||
72, 56, 56, 57, 71, 57, 57, 59, 59, 59,
|
||||
59, 59, 59, 59, 59, 61, 61, 61, 61, 61,
|
||||
61, 61, 61, 67, 70, 67, 68, 68, 68, 62,
|
||||
68, 68, 98, 98, 98, 98, 98, 98, 98, 98,
|
||||
60, 66, 65, 64, 63, 62, 60, 58, 103, 48,
|
||||
|
||||
48, 103, 11, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103
|
||||
51, 51, 51, 57, 70, 57, 58, 58, 58, 67,
|
||||
58, 58, 88, 88, 88, 88, 88, 88, 88, 88,
|
||||
34, 66, 65, 64, 63, 62, 61, 60, 52, 50,
|
||||
39, 56, 39, 55, 54, 53, 52, 50, 48, 93,
|
||||
40, 39, 32, 93, 19, 19, 11, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93
|
||||
} ;
|
||||
|
||||
static yyconst flex_int16_t yy_chk[339] =
|
||||
static yyconst flex_int16_t yy_chk[281] =
|
||||
{ 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 3, 13, 13, 101, 3,
|
||||
3, 3, 3, 15, 3, 14, 14, 32, 32, 3,
|
||||
3, 3, 3, 3, 5, 5, 5, 15, 5, 31,
|
||||
31, 31, 5, 5, 5, 5, 5, 7, 7, 7,
|
||||
1, 1, 1, 5, 5, 5, 5, 91, 5, 9,
|
||||
9, 9, 5, 5, 5, 5, 5, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
10, 10, 10, 13, 13, 14, 14, 15, 24, 28,
|
||||
24, 24, 25, 25, 25, 50, 24, 50, 25, 90,
|
||||
|
||||
7, 7, 9, 16, 29, 33, 9, 9, 9, 9,
|
||||
10, 54, 54, 54, 10, 10, 10, 10, 17, 33,
|
||||
28, 17, 28, 28, 28, 100, 72, 16, 29, 28,
|
||||
97, 60, 72, 17, 60, 94, 17, 92, 17, 19,
|
||||
19, 19, 19, 19, 19, 19, 91, 88, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 20, 20, 20, 23, 20, 87, 23, 86,
|
||||
96, 20, 20, 20, 20, 30, 30, 30, 85, 84,
|
||||
23, 30, 83, 23, 96, 23, 25, 25, 25, 82,
|
||||
25, 93, 93, 93, 81, 25, 25, 25, 25, 53,
|
||||
15, 17, 28, 17, 26, 26, 26, 27, 27, 62,
|
||||
44, 87, 44, 44, 62, 17, 84, 17, 44, 17,
|
||||
21, 21, 21, 21, 21, 45, 45, 45, 86, 21,
|
||||
21, 21, 21, 83, 83, 83, 85, 85, 85, 88,
|
||||
82, 86, 81, 78, 77, 76, 75, 74, 73, 72,
|
||||
71, 70, 88, 94, 94, 94, 94, 94, 94, 94,
|
||||
94, 95, 95, 95, 96, 96, 96, 96, 97, 69,
|
||||
97, 98, 68, 98, 67, 98, 98, 99, 66, 99,
|
||||
99, 99, 99, 100, 64, 100, 100, 101, 101, 101,
|
||||
101, 101, 101, 101, 101, 102, 102, 102, 102, 102,
|
||||
|
||||
98, 53, 53, 53, 95, 95, 95, 80, 53, 79,
|
||||
78, 77, 76, 74, 98, 104, 104, 104, 104, 104,
|
||||
104, 104, 104, 105, 73, 71, 105, 105, 105, 106,
|
||||
70, 106, 107, 69, 107, 108, 68, 108, 66, 108,
|
||||
108, 109, 65, 109, 109, 109, 109, 110, 110, 110,
|
||||
64, 110, 110, 111, 63, 111, 111, 112, 112, 112,
|
||||
112, 112, 112, 112, 112, 113, 113, 113, 113, 113,
|
||||
113, 113, 113, 114, 62, 114, 115, 115, 115, 61,
|
||||
115, 115, 116, 116, 116, 116, 116, 116, 116, 116,
|
||||
59, 49, 43, 42, 41, 40, 39, 38, 35, 22,
|
||||
|
||||
21, 11, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
|
||||
103, 103, 103, 103, 103, 103, 103, 103
|
||||
102, 102, 102, 103, 63, 103, 104, 104, 104, 61,
|
||||
104, 104, 105, 105, 105, 105, 105, 105, 105, 105,
|
||||
60, 59, 58, 56, 55, 54, 53, 52, 51, 49,
|
||||
42, 40, 38, 37, 36, 35, 34, 33, 32, 30,
|
||||
19, 18, 16, 11, 4, 3, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
|
||||
93, 93, 93, 93, 93, 93, 93, 93, 93, 93
|
||||
} ;
|
||||
|
||||
/* Table of booleans, true if rule could match eol. */
|
||||
static yyconst flex_int32_t yy_rule_can_match_eol[21] =
|
||||
{ 0,
|
||||
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
|
||||
0, };
|
||||
|
||||
static yy_state_type yy_last_accepting_state;
|
||||
static char *yy_last_accepting_cpos;
|
||||
|
||||
@ -616,6 +580,13 @@ char *yytext;
|
||||
#include "srcpos.h"
|
||||
#include "dtc-parser.tab.h"
|
||||
|
||||
YYLTYPE yylloc;
|
||||
|
||||
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
|
||||
#define YY_USER_ACTION \
|
||||
{ \
|
||||
srcpos_update(&yylloc, yytext, yyleng); \
|
||||
}
|
||||
|
||||
/*#define LEXDEBUG 1*/
|
||||
|
||||
@ -625,19 +596,14 @@ char *yytext;
|
||||
#define DPRINT(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
static int dts_version; /* = 0 */
|
||||
static int dts_version = 1;
|
||||
|
||||
#define BEGIN_DEFAULT() if (dts_version == 0) { \
|
||||
DPRINT("<INITIAL>\n"); \
|
||||
BEGIN(INITIAL); \
|
||||
} else { \
|
||||
DPRINT("<V1>\n"); \
|
||||
#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
|
||||
BEGIN(V1); \
|
||||
}
|
||||
|
||||
static void push_input_file(const char *filename);
|
||||
static int pop_input_file(void);
|
||||
#line 641 "dtc-lexer.lex.c"
|
||||
#line 607 "dtc-lexer.lex.c"
|
||||
|
||||
#define INITIAL 0
|
||||
#define INCLUDE 1
|
||||
@ -826,9 +792,9 @@ YY_DECL
|
||||
register char *yy_cp, *yy_bp;
|
||||
register int yy_act;
|
||||
|
||||
#line 64 "dtc-lexer.l"
|
||||
#line 66 "dtc-lexer.l"
|
||||
|
||||
#line 832 "dtc-lexer.lex.c"
|
||||
#line 798 "dtc-lexer.lex.c"
|
||||
|
||||
if ( !(yy_init) )
|
||||
{
|
||||
@ -881,35 +847,21 @@ yy_match:
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 104 )
|
||||
if ( yy_current_state >= 94 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
++yy_cp;
|
||||
}
|
||||
while ( yy_base[yy_current_state] != 303 );
|
||||
while ( yy_current_state != 93 );
|
||||
yy_cp = (yy_last_accepting_cpos);
|
||||
yy_current_state = (yy_last_accepting_state);
|
||||
|
||||
yy_find_action:
|
||||
yy_act = yy_accept[yy_current_state];
|
||||
if ( yy_act == 0 )
|
||||
{ /* have to back up */
|
||||
yy_cp = (yy_last_accepting_cpos);
|
||||
yy_current_state = (yy_last_accepting_state);
|
||||
yy_act = yy_accept[yy_current_state];
|
||||
}
|
||||
|
||||
YY_DO_BEFORE_ACTION;
|
||||
|
||||
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
|
||||
{
|
||||
int yyl;
|
||||
for ( yyl = 0; yyl < yyleng; ++yyl )
|
||||
if ( yytext[yyl] == '\n' )
|
||||
|
||||
yylineno++;
|
||||
;
|
||||
}
|
||||
|
||||
do_action: /* This label is used only to access EOF actions. */
|
||||
|
||||
switch ( yy_act )
|
||||
@ -924,7 +876,7 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
case 1:
|
||||
/* rule 1 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 65 "dtc-lexer.l"
|
||||
#line 67 "dtc-lexer.l"
|
||||
{
|
||||
char *name = strchr(yytext, '\"') + 1;
|
||||
yytext[yyleng-1] = '\0';
|
||||
@ -936,7 +888,7 @@ case YY_STATE_EOF(INCLUDE):
|
||||
case YY_STATE_EOF(BYTESTRING):
|
||||
case YY_STATE_EOF(PROPNODENAME):
|
||||
case YY_STATE_EOF(V1):
|
||||
#line 71 "dtc-lexer.l"
|
||||
#line 73 "dtc-lexer.l"
|
||||
{
|
||||
if (!pop_input_file()) {
|
||||
yyterminate();
|
||||
@ -946,23 +898,18 @@ case YY_STATE_EOF(V1):
|
||||
case 2:
|
||||
/* rule 2 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 77 "dtc-lexer.l"
|
||||
#line 79 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("String: %s\n", yytext);
|
||||
yylval.data = data_copy_escape_string(yytext+1,
|
||||
yyleng-2);
|
||||
yylloc.first_line = yylineno;
|
||||
return DT_STRING;
|
||||
}
|
||||
YY_BREAK
|
||||
case 3:
|
||||
YY_RULE_SETUP
|
||||
#line 87 "dtc-lexer.l"
|
||||
#line 86 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Keyword: /dts-v1/\n");
|
||||
dts_version = 1;
|
||||
BEGIN_DEFAULT();
|
||||
@ -971,10 +918,8 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 4:
|
||||
YY_RULE_SETUP
|
||||
#line 96 "dtc-lexer.l"
|
||||
#line 93 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Keyword: /memreserve/\n");
|
||||
BEGIN_DEFAULT();
|
||||
return DT_MEMRESERVE;
|
||||
@ -982,158 +927,100 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 5:
|
||||
YY_RULE_SETUP
|
||||
#line 104 "dtc-lexer.l"
|
||||
#line 99 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Label: %s\n", yytext);
|
||||
yylval.labelref = strdup(yytext);
|
||||
yylval.labelref = xstrdup(yytext);
|
||||
yylval.labelref[yyleng-1] = '\0';
|
||||
return DT_LABEL;
|
||||
}
|
||||
YY_BREAK
|
||||
case 6:
|
||||
YY_RULE_SETUP
|
||||
#line 113 "dtc-lexer.l"
|
||||
#line 106 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
if (*yytext == 'b')
|
||||
yylval.cbase = 2;
|
||||
else if (*yytext == 'o')
|
||||
yylval.cbase = 8;
|
||||
else if (*yytext == 'd')
|
||||
yylval.cbase = 10;
|
||||
else
|
||||
yylval.cbase = 16;
|
||||
DPRINT("Base: %d\n", yylval.cbase);
|
||||
return DT_BASE;
|
||||
}
|
||||
YY_BREAK
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 128 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yylval.literal = strdup(yytext);
|
||||
DPRINT("Literal: '%s'\n", yylval.literal);
|
||||
return DT_LEGACYLITERAL;
|
||||
}
|
||||
YY_BREAK
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 136 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yylval.literal = strdup(yytext);
|
||||
yylval.literal = xstrdup(yytext);
|
||||
DPRINT("Literal: '%s'\n", yylval.literal);
|
||||
return DT_LITERAL;
|
||||
}
|
||||
YY_BREAK
|
||||
case 9:
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 144 "dtc-lexer.l"
|
||||
#line 112 "dtc-lexer.l"
|
||||
{ /* label reference */
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Ref: %s\n", yytext+1);
|
||||
yylval.labelref = strdup(yytext+1);
|
||||
yylval.labelref = xstrdup(yytext+1);
|
||||
return DT_REF;
|
||||
}
|
||||
YY_BREAK
|
||||
case 10:
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 152 "dtc-lexer.l"
|
||||
#line 118 "dtc-lexer.l"
|
||||
{ /* new-style path reference */
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yytext[yyleng-1] = '\0';
|
||||
DPRINT("Ref: %s\n", yytext+2);
|
||||
yylval.labelref = strdup(yytext+2);
|
||||
yylval.labelref = xstrdup(yytext+2);
|
||||
return DT_REF;
|
||||
}
|
||||
YY_BREAK
|
||||
case 11:
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
#line 161 "dtc-lexer.l"
|
||||
{ /* old-style path reference */
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Ref: %s\n", yytext+1);
|
||||
yylval.labelref = strdup(yytext+1);
|
||||
return DT_REF;
|
||||
}
|
||||
YY_BREAK
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 169 "dtc-lexer.l"
|
||||
#line 125 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
yylval.byte = strtol(yytext, NULL, 16);
|
||||
DPRINT("Byte: %02x\n", (int)yylval.byte);
|
||||
return DT_BYTE;
|
||||
}
|
||||
YY_BREAK
|
||||
case 13:
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
#line 177 "dtc-lexer.l"
|
||||
#line 131 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("/BYTESTRING\n");
|
||||
BEGIN_DEFAULT();
|
||||
return ']';
|
||||
}
|
||||
YY_BREAK
|
||||
case 14:
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
#line 185 "dtc-lexer.l"
|
||||
#line 137 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("PropNodeName: %s\n", yytext);
|
||||
yylval.propnodename = strdup(yytext);
|
||||
yylval.propnodename = xstrdup(yytext);
|
||||
BEGIN_DEFAULT();
|
||||
return DT_PROPNODENAME;
|
||||
}
|
||||
YY_BREAK
|
||||
case 15:
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 194 "dtc-lexer.l"
|
||||
#line 144 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Binary Include\n");
|
||||
return DT_INCBIN;
|
||||
}
|
||||
YY_BREAK
|
||||
case 16:
|
||||
/* rule 16 can match eol */
|
||||
case 13:
|
||||
/* rule 13 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 201 "dtc-lexer.l"
|
||||
#line 149 "dtc-lexer.l"
|
||||
/* eat whitespace */
|
||||
YY_BREAK
|
||||
case 17:
|
||||
/* rule 17 can match eol */
|
||||
case 14:
|
||||
/* rule 14 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 202 "dtc-lexer.l"
|
||||
#line 150 "dtc-lexer.l"
|
||||
/* eat C-style comments */
|
||||
YY_BREAK
|
||||
case 18:
|
||||
/* rule 18 can match eol */
|
||||
case 15:
|
||||
/* rule 15 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 203 "dtc-lexer.l"
|
||||
#line 151 "dtc-lexer.l"
|
||||
/* eat C++-style comments */
|
||||
YY_BREAK
|
||||
case 19:
|
||||
case 16:
|
||||
YY_RULE_SETUP
|
||||
#line 205 "dtc-lexer.l"
|
||||
#line 153 "dtc-lexer.l"
|
||||
{
|
||||
yylloc.file = srcpos_file;
|
||||
yylloc.first_line = yylineno;
|
||||
DPRINT("Char: %c (\\x%02x)\n", yytext[0],
|
||||
(unsigned)yytext[0]);
|
||||
if (yytext[0] == '[') {
|
||||
@ -1148,12 +1035,12 @@ YY_RULE_SETUP
|
||||
return yytext[0];
|
||||
}
|
||||
YY_BREAK
|
||||
case 20:
|
||||
case 17:
|
||||
YY_RULE_SETUP
|
||||
#line 222 "dtc-lexer.l"
|
||||
#line 168 "dtc-lexer.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 1157 "dtc-lexer.lex.c"
|
||||
#line 1044 "dtc-lexer.lex.c"
|
||||
|
||||
case YY_END_OF_BUFFER:
|
||||
{
|
||||
@ -1218,7 +1105,8 @@ ECHO;
|
||||
|
||||
else
|
||||
{
|
||||
yy_cp = (yy_c_buf_p);
|
||||
yy_cp = (yy_last_accepting_cpos);
|
||||
yy_current_state = (yy_last_accepting_state);
|
||||
goto yy_find_action;
|
||||
}
|
||||
}
|
||||
@ -1443,7 +1331,7 @@ static int yy_get_next_buffer (void)
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 104 )
|
||||
if ( yy_current_state >= 94 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
@ -1471,11 +1359,11 @@ static int yy_get_next_buffer (void)
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 104 )
|
||||
if ( yy_current_state >= 94 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
yy_is_jam = (yy_current_state == 103);
|
||||
yy_is_jam = (yy_current_state == 93);
|
||||
|
||||
return yy_is_jam ? 0 : yy_current_state;
|
||||
}
|
||||
@ -1550,11 +1438,6 @@ static int yy_get_next_buffer (void)
|
||||
*(yy_c_buf_p) = '\0'; /* preserve yytext */
|
||||
(yy_hold_char) = *++(yy_c_buf_p);
|
||||
|
||||
if ( c == '\n' )
|
||||
|
||||
yylineno++;
|
||||
;
|
||||
|
||||
return c;
|
||||
}
|
||||
#endif /* ifndef YY_NO_INPUT */
|
||||
@ -1669,10 +1552,6 @@ static void yy_load_buffer_state (void)
|
||||
yyfree((void *) b );
|
||||
}
|
||||
|
||||
#ifndef __cplusplus
|
||||
extern int isatty (int );
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Initializes or reinitializes a buffer.
|
||||
* This function is sometimes called more than once on the same buffer,
|
||||
* such as during a yyrestart() or at EOF.
|
||||
@ -1696,7 +1575,7 @@ extern int isatty (int );
|
||||
b->yy_bs_column = 0;
|
||||
}
|
||||
|
||||
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
|
||||
b->yy_is_interactive = 0;
|
||||
|
||||
errno = oerrno;
|
||||
}
|
||||
@ -2025,9 +1904,6 @@ static int yy_init_globals (void)
|
||||
* This function is called from yylex_destroy(), so don't allocate here.
|
||||
*/
|
||||
|
||||
/* We do not touch yylineno unless the option is enabled. */
|
||||
yylineno = 1;
|
||||
|
||||
(yy_buffer_stack) = 0;
|
||||
(yy_buffer_stack_top) = 0;
|
||||
(yy_buffer_stack_max) = 0;
|
||||
@ -2120,104 +1996,29 @@ void yyfree (void * ptr )
|
||||
|
||||
#define YYTABLES_NAME "yytables"
|
||||
|
||||
#line 222 "dtc-lexer.l"
|
||||
#line 168 "dtc-lexer.l"
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Stack of nested include file contexts.
|
||||
*/
|
||||
|
||||
struct incl_file {
|
||||
struct dtc_file *file;
|
||||
YY_BUFFER_STATE yy_prev_buf;
|
||||
int yy_prev_lineno;
|
||||
struct incl_file *prev;
|
||||
};
|
||||
|
||||
static struct incl_file *incl_file_stack;
|
||||
|
||||
|
||||
/*
|
||||
* Detect infinite include recursion.
|
||||
*/
|
||||
#define MAX_INCLUDE_DEPTH (100)
|
||||
|
||||
static int incl_depth = 0;
|
||||
|
||||
|
||||
static void push_input_file(const char *filename)
|
||||
{
|
||||
struct incl_file *incl_file;
|
||||
struct dtc_file *newfile;
|
||||
struct search_path search, *searchptr = NULL;
|
||||
|
||||
assert(filename);
|
||||
|
||||
if (incl_depth++ >= MAX_INCLUDE_DEPTH)
|
||||
die("Includes nested too deeply");
|
||||
srcfile_push(filename);
|
||||
|
||||
if (srcpos_file) {
|
||||
search.dir = srcpos_file->dir;
|
||||
search.next = NULL;
|
||||
search.prev = NULL;
|
||||
searchptr = &search;
|
||||
}
|
||||
yyin = current_srcfile->f;
|
||||
|
||||
newfile = dtc_open_file(filename, searchptr);
|
||||
|
||||
incl_file = xmalloc(sizeof(struct incl_file));
|
||||
|
||||
/*
|
||||
* Save current context.
|
||||
*/
|
||||
incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
|
||||
incl_file->yy_prev_lineno = yylineno;
|
||||
incl_file->file = srcpos_file;
|
||||
incl_file->prev = incl_file_stack;
|
||||
|
||||
incl_file_stack = incl_file;
|
||||
|
||||
/*
|
||||
* Establish new context.
|
||||
*/
|
||||
srcpos_file = newfile;
|
||||
yylineno = 1;
|
||||
yyin = newfile->file;
|
||||
yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
|
||||
yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
|
||||
}
|
||||
|
||||
|
||||
static int pop_input_file(void)
|
||||
{
|
||||
struct incl_file *incl_file;
|
||||
|
||||
if (incl_file_stack == 0)
|
||||
if (srcfile_pop() == 0)
|
||||
return 0;
|
||||
|
||||
dtc_close_file(srcpos_file);
|
||||
|
||||
/*
|
||||
* Pop.
|
||||
*/
|
||||
--incl_depth;
|
||||
incl_file = incl_file_stack;
|
||||
incl_file_stack = incl_file->prev;
|
||||
|
||||
/*
|
||||
* Recover old context.
|
||||
*/
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
yy_switch_to_buffer(incl_file->yy_prev_buf);
|
||||
yylineno = incl_file->yy_prev_lineno;
|
||||
srcpos_file = incl_file->file;
|
||||
yyin = incl_file->file ? incl_file->file->file : NULL;
|
||||
|
||||
/*
|
||||
* Free old state.
|
||||
*/
|
||||
free(incl_file);
|
||||
yypop_buffer_state();
|
||||
yyin = current_srcfile->f;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,23 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* A Bison parser, made by GNU Bison 2.4.1. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
||||
This program 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@ -29,10 +28,11 @@
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
@ -43,35 +43,24 @@
|
||||
DT_MEMRESERVE = 259,
|
||||
DT_PROPNODENAME = 260,
|
||||
DT_LITERAL = 261,
|
||||
DT_LEGACYLITERAL = 262,
|
||||
DT_BASE = 263,
|
||||
DT_BYTE = 264,
|
||||
DT_STRING = 265,
|
||||
DT_LABEL = 266,
|
||||
DT_REF = 267,
|
||||
DT_INCBIN = 268
|
||||
DT_BASE = 262,
|
||||
DT_BYTE = 263,
|
||||
DT_STRING = 264,
|
||||
DT_LABEL = 265,
|
||||
DT_REF = 266,
|
||||
DT_INCBIN = 267
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define DT_V1 258
|
||||
#define DT_MEMRESERVE 259
|
||||
#define DT_PROPNODENAME 260
|
||||
#define DT_LITERAL 261
|
||||
#define DT_LEGACYLITERAL 262
|
||||
#define DT_BASE 263
|
||||
#define DT_BYTE 264
|
||||
#define DT_STRING 265
|
||||
#define DT_LABEL 266
|
||||
#define DT_REF 267
|
||||
#define DT_INCBIN 268
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 37 "dtc-parser.y"
|
||||
{
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 39 "dtc-parser.y"
|
||||
|
||||
char *propnodename;
|
||||
char *literal;
|
||||
char *labelref;
|
||||
@ -86,28 +75,17 @@ typedef union YYSTYPE
|
||||
struct node *node;
|
||||
struct node *nodelist;
|
||||
struct reserve_info *re;
|
||||
}
|
||||
/* Line 1489 of yacc.c. */
|
||||
#line 92 "dtc-parser.tab.h"
|
||||
YYSTYPE;
|
||||
|
||||
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 83 "dtc-parser.tab.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} YYLTYPE;
|
||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYLTYPE yylloc;
|
||||
|
@ -18,15 +18,17 @@
|
||||
* USA
|
||||
*/
|
||||
|
||||
%locations
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dtc.h"
|
||||
#include "srcpos.h"
|
||||
|
||||
YYLTYPE yylloc;
|
||||
|
||||
extern int yylex(void);
|
||||
extern void print_error(char const *fmt, ...);
|
||||
extern void yyerror(char const *s);
|
||||
|
||||
extern struct boot_info *the_boot_info;
|
||||
extern int treesource_error;
|
||||
@ -55,7 +57,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
|
||||
%token DT_MEMRESERVE
|
||||
%token <propnodename> DT_PROPNODENAME
|
||||
%token <literal> DT_LITERAL
|
||||
%token <literal> DT_LEGACYLITERAL
|
||||
%token <cbase> DT_BASE
|
||||
%token <byte> DT_BYTE
|
||||
%token <data> DT_STRING
|
||||
@ -67,11 +68,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
|
||||
%type <data> propdataprefix
|
||||
%type <re> memreserve
|
||||
%type <re> memreserves
|
||||
%type <re> v0_memreserve
|
||||
%type <re> v0_memreserves
|
||||
%type <addr> addr
|
||||
%type <data> celllist
|
||||
%type <cbase> cellbase
|
||||
%type <cell> cellval
|
||||
%type <data> bytestring
|
||||
%type <prop> propdef
|
||||
@ -81,18 +79,14 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
|
||||
%type <node> nodedef
|
||||
%type <node> subnode
|
||||
%type <nodelist> subnodes
|
||||
%type <labelref> label
|
||||
|
||||
%%
|
||||
|
||||
sourcefile:
|
||||
DT_V1 ';' memreserves devicetree
|
||||
{
|
||||
the_boot_info = build_boot_info($3, $4, 0);
|
||||
}
|
||||
| v0_memreserves devicetree
|
||||
{
|
||||
the_boot_info = build_boot_info($1, $2, 0);
|
||||
the_boot_info = build_boot_info($3, $4,
|
||||
guess_boot_cpuid($4));
|
||||
}
|
||||
;
|
||||
|
||||
@ -108,31 +102,14 @@ memreserves:
|
||||
;
|
||||
|
||||
memreserve:
|
||||
label DT_MEMRESERVE addr addr ';'
|
||||
DT_MEMRESERVE addr addr ';'
|
||||
{
|
||||
$$ = build_reserve_entry($3, $4, $1);
|
||||
$$ = build_reserve_entry($2, $3);
|
||||
}
|
||||
;
|
||||
|
||||
v0_memreserves:
|
||||
/* empty */
|
||||
| DT_LABEL memreserve
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| v0_memreserve v0_memreserves
|
||||
{
|
||||
$$ = chain_reserve_entry($1, $2);
|
||||
};
|
||||
;
|
||||
|
||||
v0_memreserve:
|
||||
memreserve
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| label DT_MEMRESERVE addr '-' addr ';'
|
||||
{
|
||||
$$ = build_reserve_entry($3, $5 - $3 + 1, $1);
|
||||
add_label(&$2->labels, $1);
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
@ -141,16 +118,26 @@ addr:
|
||||
{
|
||||
$$ = eval_literal($1, 0, 64);
|
||||
}
|
||||
| DT_LEGACYLITERAL
|
||||
{
|
||||
$$ = eval_literal($1, 16, 64);
|
||||
}
|
||||
;
|
||||
|
||||
devicetree:
|
||||
'/' nodedef
|
||||
{
|
||||
$$ = name_node($2, "", NULL);
|
||||
$$ = name_node($2, "");
|
||||
}
|
||||
| devicetree '/' nodedef
|
||||
{
|
||||
$$ = merge_nodes($1, $3);
|
||||
}
|
||||
| devicetree DT_REF nodedef
|
||||
{
|
||||
struct node *target = get_node_by_ref($1, $2);
|
||||
|
||||
if (target)
|
||||
merge_nodes(target, $3);
|
||||
else
|
||||
print_error("label or path, '%s', not found", $2);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
@ -173,13 +160,18 @@ proplist:
|
||||
;
|
||||
|
||||
propdef:
|
||||
label DT_PROPNODENAME '=' propdata ';'
|
||||
DT_PROPNODENAME '=' propdata ';'
|
||||
{
|
||||
$$ = build_property($2, $4, $1);
|
||||
$$ = build_property($1, $3);
|
||||
}
|
||||
| label DT_PROPNODENAME ';'
|
||||
| DT_PROPNODENAME ';'
|
||||
{
|
||||
$$ = build_property($2, empty_data, $1);
|
||||
$$ = build_property($1, empty_data);
|
||||
}
|
||||
| DT_LABEL propdef
|
||||
{
|
||||
add_label(&$2->labels, $1);
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
@ -202,31 +194,30 @@ propdata:
|
||||
}
|
||||
| propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
|
||||
{
|
||||
struct search_path path = { srcpos_file->dir, NULL, NULL };
|
||||
struct dtc_file *file = dtc_open_file($4.val, &path);
|
||||
struct data d = empty_data;
|
||||
FILE *f = srcfile_relative_open($4.val, NULL);
|
||||
struct data d;
|
||||
|
||||
if ($6 != 0)
|
||||
if (fseek(file->file, $6, SEEK_SET) != 0)
|
||||
yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
|
||||
(unsigned long long)$6,
|
||||
$4.val, strerror(errno));
|
||||
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));
|
||||
|
||||
d = data_copy_file(file->file, $8);
|
||||
d = data_copy_file(f, $8);
|
||||
|
||||
$$ = data_merge($1, d);
|
||||
dtc_close_file(file);
|
||||
fclose(f);
|
||||
}
|
||||
| propdataprefix DT_INCBIN '(' DT_STRING ')'
|
||||
{
|
||||
struct search_path path = { srcpos_file->dir, NULL, NULL };
|
||||
struct dtc_file *file = dtc_open_file($4.val, &path);
|
||||
FILE *f = srcfile_relative_open($4.val, NULL);
|
||||
struct data d = empty_data;
|
||||
|
||||
d = data_copy_file(file->file, -1);
|
||||
d = data_copy_file(f, -1);
|
||||
|
||||
$$ = data_merge($1, d);
|
||||
dtc_close_file(file);
|
||||
fclose(f);
|
||||
}
|
||||
| propdata DT_LABEL
|
||||
{
|
||||
@ -269,23 +260,11 @@ celllist:
|
||||
}
|
||||
;
|
||||
|
||||
cellbase:
|
||||
/* empty */
|
||||
{
|
||||
$$ = 16;
|
||||
}
|
||||
| DT_BASE
|
||||
;
|
||||
|
||||
cellval:
|
||||
DT_LITERAL
|
||||
{
|
||||
$$ = eval_literal($1, 0, 32);
|
||||
}
|
||||
| cellbase DT_LEGACYLITERAL
|
||||
{
|
||||
$$ = eval_literal($2, $1, 32);
|
||||
}
|
||||
;
|
||||
|
||||
bytestring:
|
||||
@ -308,57 +287,44 @@ subnodes:
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| subnode subnodes
|
||||
| subnode subnodes
|
||||
{
|
||||
$$ = chain_node($1, $2);
|
||||
}
|
||||
| subnode propdef
|
||||
{
|
||||
yyerror("syntax error: properties must precede subnodes");
|
||||
print_error("syntax error: properties must precede subnodes");
|
||||
YYERROR;
|
||||
}
|
||||
;
|
||||
|
||||
subnode:
|
||||
label DT_PROPNODENAME nodedef
|
||||
DT_PROPNODENAME nodedef
|
||||
{
|
||||
$$ = name_node($3, $2, $1);
|
||||
$$ = name_node($2, $1);
|
||||
}
|
||||
;
|
||||
|
||||
label:
|
||||
/* empty */
|
||||
| DT_LABEL subnode
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| DT_LABEL
|
||||
{
|
||||
$$ = $1;
|
||||
add_label(&$2->labels, $1);
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerrorf(char const *s, ...)
|
||||
void print_error(char const *fmt, ...)
|
||||
{
|
||||
const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
|
||||
va_list va;
|
||||
va_start(va, s);
|
||||
|
||||
if (strcmp(fname, "-") == 0)
|
||||
fname = "stdin";
|
||||
|
||||
fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
|
||||
vfprintf(stderr, s, va);
|
||||
fprintf(stderr, "\n");
|
||||
va_start(va, fmt);
|
||||
srcpos_verror(&yylloc, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
treesource_error = 1;
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void yyerror (char const *s)
|
||||
{
|
||||
yyerrorf("%s", s);
|
||||
void yyerror(char const *s) {
|
||||
print_error("%s", s);
|
||||
}
|
||||
|
||||
static unsigned long long eval_literal(const char *s, int base, int bits)
|
||||
@ -369,11 +335,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
|
||||
errno = 0;
|
||||
val = strtoull(s, &e, base);
|
||||
if (*e)
|
||||
yyerror("bad characters in literal");
|
||||
print_error("bad characters in literal");
|
||||
else if ((errno == ERANGE)
|
||||
|| ((bits < 64) && (val >= (1ULL << bits))))
|
||||
yyerror("literal out of range");
|
||||
print_error("literal out of range");
|
||||
else if (errno != 0)
|
||||
yyerror("bad literal");
|
||||
print_error("bad literal");
|
||||
return val;
|
||||
}
|
||||
|
@ -30,30 +30,7 @@ int quiet; /* Level of quietness */
|
||||
int reservenum; /* Number of memory reservation slots */
|
||||
int minsize; /* Minimum blob size */
|
||||
int padsize; /* Additional padding to blob */
|
||||
|
||||
char *join_path(const char *path, const char *name)
|
||||
{
|
||||
int lenp = strlen(path);
|
||||
int lenn = strlen(name);
|
||||
int len;
|
||||
int needslash = 1;
|
||||
char *str;
|
||||
|
||||
len = lenp + lenn + 2;
|
||||
if ((lenp > 0) && (path[lenp-1] == '/')) {
|
||||
needslash = 0;
|
||||
len--;
|
||||
}
|
||||
|
||||
str = xmalloc(len);
|
||||
memcpy(str, path, lenp);
|
||||
if (needslash) {
|
||||
str[lenp] = '/';
|
||||
lenp++;
|
||||
}
|
||||
memcpy(str+lenp, name, lenn+1);
|
||||
return str;
|
||||
}
|
||||
int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
|
||||
|
||||
static void fill_fullpaths(struct node *tree, const char *prefix)
|
||||
{
|
||||
@ -104,8 +81,15 @@ static void __attribute__ ((noreturn)) usage(void)
|
||||
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-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");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
@ -115,7 +99,7 @@ int main(int argc, char *argv[])
|
||||
const char *inform = "dts";
|
||||
const char *outform = "dts";
|
||||
const char *outname = "-";
|
||||
int force = 0, check = 0;
|
||||
int force = 0, check = 0, sort = 0;
|
||||
const char *arg;
|
||||
int opt;
|
||||
FILE *outf = NULL;
|
||||
@ -127,7 +111,7 @@ int main(int argc, char *argv[])
|
||||
minsize = 0;
|
||||
padsize = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) {
|
||||
switch (opt) {
|
||||
case 'I':
|
||||
inform = optarg;
|
||||
@ -165,6 +149,22 @@ int main(int argc, char *argv[])
|
||||
case 'v':
|
||||
printf("Version: %s\n", DTC_VERSION);
|
||||
exit(0);
|
||||
case 'H':
|
||||
if (streq(optarg, "legacy"))
|
||||
phandle_format = PHANDLE_LEGACY;
|
||||
else if (streq(optarg, "epapr"))
|
||||
phandle_format = PHANDLE_EPAPR;
|
||||
else if (streq(optarg, "both"))
|
||||
phandle_format = PHANDLE_BOTH;
|
||||
else
|
||||
die("Invalid argument \"%s\" to -H option\n",
|
||||
optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
sort = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
usage();
|
||||
@ -182,6 +182,9 @@ 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");
|
||||
|
||||
fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
|
||||
inform, outform, arg);
|
||||
|
||||
@ -200,6 +203,8 @@ int main(int argc, char *argv[])
|
||||
fill_fullpaths(bi->dt, "");
|
||||
process_checks(force, bi);
|
||||
|
||||
if (sort)
|
||||
sort_tree(bi);
|
||||
|
||||
if (streq(outname, "-")) {
|
||||
outf = stdout;
|
||||
|
@ -34,7 +34,17 @@
|
||||
#include <libfdt_env.h>
|
||||
#include <fdt.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debug(fmt,args...) printf(fmt, ##args)
|
||||
#else
|
||||
#define debug(fmt,args...)
|
||||
#endif
|
||||
|
||||
|
||||
#define DEFAULT_FDT_VERSION 17
|
||||
|
||||
/*
|
||||
* Command line options
|
||||
*/
|
||||
@ -42,36 +52,11 @@ extern int quiet; /* Level of quietness */
|
||||
extern int reservenum; /* Number of memory reservation slots */
|
||||
extern int minsize; /* Minimum blob size */
|
||||
extern int padsize; /* Additional padding to blob */
|
||||
extern int phandle_format; /* Use linux,phandle or phandle properties */
|
||||
|
||||
static inline void __attribute__((noreturn)) die(char * str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, str);
|
||||
fprintf(stderr, "FATAL ERROR: ");
|
||||
vfprintf(stderr, str, ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static inline void *xmalloc(size_t len)
|
||||
{
|
||||
void *new = malloc(len);
|
||||
|
||||
if (! new)
|
||||
die("malloc() failed\n");
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static inline void *xrealloc(void *p, size_t len)
|
||||
{
|
||||
void *new = realloc(p, len);
|
||||
|
||||
if (! new)
|
||||
die("realloc() failed (len=%d)\n", len);
|
||||
|
||||
return new;
|
||||
}
|
||||
#define PHANDLE_LEGACY 0x1
|
||||
#define PHANDLE_EPAPR 0x2
|
||||
#define PHANDLE_BOTH 0x3
|
||||
|
||||
typedef uint32_t cell_t;
|
||||
|
||||
@ -140,13 +125,18 @@ int data_is_one_string(struct data d);
|
||||
#define MAX_NODENAME_LEN 31
|
||||
|
||||
/* Live trees */
|
||||
struct label {
|
||||
char *label;
|
||||
struct label *next;
|
||||
};
|
||||
|
||||
struct property {
|
||||
char *name;
|
||||
struct data val;
|
||||
|
||||
struct property *next;
|
||||
|
||||
char *label;
|
||||
struct label *labels;
|
||||
};
|
||||
|
||||
struct node {
|
||||
@ -163,22 +153,28 @@ struct node {
|
||||
cell_t phandle;
|
||||
int addr_cells, size_cells;
|
||||
|
||||
char *label;
|
||||
struct label *labels;
|
||||
};
|
||||
|
||||
#define for_each_label(l0, l) \
|
||||
for ((l) = (l0); (l); (l) = (l)->next)
|
||||
|
||||
#define for_each_property(n, p) \
|
||||
for ((p) = (n)->proplist; (p); (p) = (p)->next)
|
||||
|
||||
#define for_each_child(n, c) \
|
||||
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
|
||||
|
||||
struct property *build_property(char *name, struct data val, char *label);
|
||||
void add_label(struct label **labels, char *label);
|
||||
|
||||
struct property *build_property(char *name, struct data val);
|
||||
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 *name_node(struct node *node, char *name, char *label);
|
||||
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 add_child(struct node *parent, struct node *child);
|
||||
@ -186,6 +182,10 @@ void add_child(struct node *parent, struct node *child);
|
||||
const char *get_unitname(struct node *node);
|
||||
struct property *get_property(struct node *node, const char *propname);
|
||||
cell_t propval_cell(struct property *prop);
|
||||
struct property *get_property_by_label(struct node *tree, const char *label,
|
||||
struct node **node);
|
||||
struct marker *get_marker_label(struct node *tree, const char *label,
|
||||
struct node **node, struct property **prop);
|
||||
struct node *get_subnode(struct node *node, const char *nodename);
|
||||
struct node *get_node_by_path(struct node *tree, const char *path);
|
||||
struct node *get_node_by_label(struct node *tree, const char *label);
|
||||
@ -193,6 +193,8 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
|
||||
struct node *get_node_by_ref(struct node *tree, const char *ref);
|
||||
cell_t get_node_phandle(struct node *root, struct node *node);
|
||||
|
||||
uint32_t guess_boot_cpuid(struct node *tree);
|
||||
|
||||
/* Boot info (tree plus memreserve information */
|
||||
|
||||
struct reserve_info {
|
||||
@ -200,10 +202,10 @@ struct reserve_info {
|
||||
|
||||
struct reserve_info *next;
|
||||
|
||||
char *label;
|
||||
struct label *labels;
|
||||
};
|
||||
|
||||
struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
|
||||
struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
|
||||
struct reserve_info *chain_reserve_entry(struct reserve_info *first,
|
||||
struct reserve_info *list);
|
||||
struct reserve_info *add_reserve_entry(struct reserve_info *list,
|
||||
@ -218,6 +220,7 @@ struct boot_info {
|
||||
|
||||
struct boot_info *build_boot_info(struct reserve_info *reservelist,
|
||||
struct node *tree, uint32_t boot_cpuid_phys);
|
||||
void sort_tree(struct boot_info *bi);
|
||||
|
||||
/* Checks */
|
||||
|
||||
@ -239,8 +242,4 @@ struct boot_info *dt_from_source(const char *f);
|
||||
|
||||
struct boot_info *dt_from_fs(const char *dirname);
|
||||
|
||||
/* misc */
|
||||
|
||||
char *join_path(const char *path, const char *name);
|
||||
|
||||
#endif /* _DTC_H */
|
||||
|
@ -52,9 +52,9 @@ struct emitter {
|
||||
void (*string)(void *, char *, int);
|
||||
void (*align)(void *, int);
|
||||
void (*data)(void *, struct data);
|
||||
void (*beginnode)(void *, const char *);
|
||||
void (*endnode)(void *, const char *);
|
||||
void (*property)(void *, const char *);
|
||||
void (*beginnode)(void *, struct label *labels);
|
||||
void (*endnode)(void *, struct label *labels);
|
||||
void (*property)(void *, struct label *labels);
|
||||
};
|
||||
|
||||
static void bin_emit_cell(void *e, cell_t val)
|
||||
@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struct data d)
|
||||
*dtbuf = data_append_data(*dtbuf, d.val, d.len);
|
||||
}
|
||||
|
||||
static void bin_emit_beginnode(void *e, const char *label)
|
||||
static void bin_emit_beginnode(void *e, struct label *labels)
|
||||
{
|
||||
bin_emit_cell(e, FDT_BEGIN_NODE);
|
||||
}
|
||||
|
||||
static void bin_emit_endnode(void *e, const char *label)
|
||||
static void bin_emit_endnode(void *e, struct label *labels)
|
||||
{
|
||||
bin_emit_cell(e, FDT_END_NODE);
|
||||
}
|
||||
|
||||
static void bin_emit_property(void *e, const char *label)
|
||||
static void bin_emit_property(void *e, struct label *labels)
|
||||
{
|
||||
bin_emit_cell(e, FDT_PROP);
|
||||
}
|
||||
@ -127,11 +127,21 @@ static void emit_offset_label(FILE *f, const char *label, int offset)
|
||||
fprintf(f, "%s\t= . + %d\n", label, offset);
|
||||
}
|
||||
|
||||
#define ASM_EMIT_BELONG(f, fmt, ...) \
|
||||
{ \
|
||||
fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \
|
||||
fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \
|
||||
fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \
|
||||
fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \
|
||||
}
|
||||
|
||||
static void asm_emit_cell(void *e, cell_t val)
|
||||
{
|
||||
FILE *f = e;
|
||||
|
||||
fprintf(f, "\t.long\t0x%x\n", val);
|
||||
fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
|
||||
(val >> 24) & 0xff, (val >> 16) & 0xff,
|
||||
(val >> 8) & 0xff, val & 0xff);
|
||||
}
|
||||
|
||||
static void asm_emit_string(void *e, char *str, int len)
|
||||
@ -156,7 +166,7 @@ static void asm_emit_align(void *e, int a)
|
||||
{
|
||||
FILE *f = e;
|
||||
|
||||
fprintf(f, "\t.balign\t%d\n", a);
|
||||
fprintf(f, "\t.balign\t%d, 0\n", a);
|
||||
}
|
||||
|
||||
static void asm_emit_data(void *e, struct data d)
|
||||
@ -169,8 +179,7 @@ static void asm_emit_data(void *e, struct data d)
|
||||
emit_offset_label(f, m->ref, m->offset);
|
||||
|
||||
while ((d.len - off) >= sizeof(uint32_t)) {
|
||||
fprintf(f, "\t.long\t0x%x\n",
|
||||
fdt32_to_cpu(*((uint32_t *)(d.val+off))));
|
||||
asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off))));
|
||||
off += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
@ -182,37 +191,43 @@ static void asm_emit_data(void *e, struct data d)
|
||||
assert(off == d.len);
|
||||
}
|
||||
|
||||
static void asm_emit_beginnode(void *e, const char *label)
|
||||
static void asm_emit_beginnode(void *e, struct label *labels)
|
||||
{
|
||||
FILE *f = e;
|
||||
struct label *l;
|
||||
|
||||
if (label) {
|
||||
fprintf(f, "\t.globl\t%s\n", label);
|
||||
fprintf(f, "%s:\n", label);
|
||||
for_each_label(labels, l) {
|
||||
fprintf(f, "\t.globl\t%s\n", l->label);
|
||||
fprintf(f, "%s:\n", l->label);
|
||||
}
|
||||
fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
|
||||
fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
|
||||
asm_emit_cell(e, FDT_BEGIN_NODE);
|
||||
}
|
||||
|
||||
static void asm_emit_endnode(void *e, const char *label)
|
||||
static void asm_emit_endnode(void *e, struct label *labels)
|
||||
{
|
||||
FILE *f = e;
|
||||
struct label *l;
|
||||
|
||||
fprintf(f, "\t.long\tFDT_END_NODE\n");
|
||||
if (label) {
|
||||
fprintf(f, "\t.globl\t%s_end\n", label);
|
||||
fprintf(f, "%s_end:\n", label);
|
||||
fprintf(f, "\t/* FDT_END_NODE */\n");
|
||||
asm_emit_cell(e, FDT_END_NODE);
|
||||
for_each_label(labels, l) {
|
||||
fprintf(f, "\t.globl\t%s_end\n", l->label);
|
||||
fprintf(f, "%s_end:\n", l->label);
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_emit_property(void *e, const char *label)
|
||||
static void asm_emit_property(void *e, struct label *labels)
|
||||
{
|
||||
FILE *f = e;
|
||||
struct label *l;
|
||||
|
||||
if (label) {
|
||||
fprintf(f, "\t.globl\t%s\n", label);
|
||||
fprintf(f, "%s:\n", label);
|
||||
for_each_label(labels, l) {
|
||||
fprintf(f, "\t.globl\t%s\n", l->label);
|
||||
fprintf(f, "%s:\n", l->label);
|
||||
}
|
||||
fprintf(f, "\t.long\tFDT_PROP\n");
|
||||
fprintf(f, "\t/* FDT_PROP */\n");
|
||||
asm_emit_cell(e, FDT_PROP);
|
||||
}
|
||||
|
||||
static struct emitter asm_emitter = {
|
||||
@ -248,7 +263,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
|
||||
struct node *child;
|
||||
int seen_name_prop = 0;
|
||||
|
||||
emit->beginnode(etarget, tree->label);
|
||||
emit->beginnode(etarget, tree->labels);
|
||||
|
||||
if (vi->flags & FTF_FULLPATH)
|
||||
emit->string(etarget, tree->fullpath, 0);
|
||||
@ -265,7 +280,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
|
||||
|
||||
nameoff = stringtable_insert(strbuf, prop->name);
|
||||
|
||||
emit->property(etarget, prop->label);
|
||||
emit->property(etarget, prop->labels);
|
||||
emit->cell(etarget, prop->val.len);
|
||||
emit->cell(etarget, nameoff);
|
||||
|
||||
@ -292,7 +307,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
|
||||
flatten_tree(child, emit, etarget, strbuf, vi);
|
||||
}
|
||||
|
||||
emit->endnode(etarget, tree->label);
|
||||
emit->endnode(etarget, tree->labels);
|
||||
}
|
||||
|
||||
static struct data flatten_reserve_list(struct reserve_info *reservelist,
|
||||
@ -413,10 +428,13 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version)
|
||||
if (padlen > 0)
|
||||
blob = data_append_zeroes(blob, padlen);
|
||||
|
||||
fwrite(blob.val, blob.len, 1, f);
|
||||
|
||||
if (ferror(f))
|
||||
die("Error writing device tree blob: %s\n", strerror(errno));
|
||||
if (fwrite(blob.val, blob.len, 1, f) != 1) {
|
||||
if (ferror(f))
|
||||
die("Error writing device tree blob: %s\n",
|
||||
strerror(errno));
|
||||
else
|
||||
die("Short write on device tree blob\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* data_merge() frees the right-hand element so only the blob
|
||||
@ -455,39 +473,44 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
|
||||
die("Unknown device tree blob version %d\n", version);
|
||||
|
||||
fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
|
||||
fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
|
||||
fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
|
||||
fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
|
||||
fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
|
||||
fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
|
||||
fprintf(f, "\n");
|
||||
|
||||
emit_label(f, symprefix, "blob_start");
|
||||
emit_label(f, symprefix, "header");
|
||||
fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
|
||||
fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version);
|
||||
fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n",
|
||||
vi->last_comp_version);
|
||||
|
||||
if (vi->flags & FTF_BOOTCPUID)
|
||||
fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
|
||||
bi->boot_cpuid_phys);
|
||||
|
||||
if (vi->flags & FTF_STRTABSIZE)
|
||||
fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
|
||||
fprintf(f, "\t/* magic */\n");
|
||||
asm_emit_cell(f, FDT_MAGIC);
|
||||
fprintf(f, "\t/* totalsize */\n");
|
||||
ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t/* off_dt_struct */\n");
|
||||
ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t/* off_dt_strings */\n");
|
||||
ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t/* off_mem_rsvmap */\n");
|
||||
ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start",
|
||||
symprefix, symprefix);
|
||||
fprintf(f, "\t/* version */\n");
|
||||
asm_emit_cell(f, vi->version);
|
||||
fprintf(f, "\t/* last_comp_version */\n");
|
||||
asm_emit_cell(f, vi->last_comp_version);
|
||||
|
||||
if (vi->flags & FTF_STRUCTSIZE)
|
||||
fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n",
|
||||
if (vi->flags & FTF_BOOTCPUID) {
|
||||
fprintf(f, "\t/* boot_cpuid_phys */\n");
|
||||
asm_emit_cell(f, bi->boot_cpuid_phys);
|
||||
}
|
||||
|
||||
if (vi->flags & FTF_STRTABSIZE) {
|
||||
fprintf(f, "\t/* size_dt_strings */\n");
|
||||
ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start",
|
||||
symprefix, symprefix);
|
||||
}
|
||||
|
||||
if (vi->flags & FTF_STRUCTSIZE) {
|
||||
fprintf(f, "\t/* size_dt_struct */\n");
|
||||
ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start",
|
||||
symprefix, symprefix);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reserve map entries.
|
||||
@ -505,16 +528,17 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
|
||||
* as it appears .quad isn't available in some assemblers.
|
||||
*/
|
||||
for (re = bi->reservelist; re; re = re->next) {
|
||||
if (re->label) {
|
||||
fprintf(f, "\t.globl\t%s\n", re->label);
|
||||
fprintf(f, "%s:\n", re->label);
|
||||
struct label *l;
|
||||
|
||||
for_each_label(re->labels, l) {
|
||||
fprintf(f, "\t.globl\t%s\n", l->label);
|
||||
fprintf(f, "%s:\n", l->label);
|
||||
}
|
||||
fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
|
||||
(unsigned int)(re->re.address >> 32),
|
||||
(unsigned int)(re->re.address & 0xffffffff));
|
||||
fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
|
||||
(unsigned int)(re->re.size >> 32),
|
||||
(unsigned int)(re->re.size & 0xffffffff));
|
||||
ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32));
|
||||
ASM_EMIT_BELONG(f, "0x%08x",
|
||||
(unsigned int)(re->re.address & 0xffffffff));
|
||||
ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32));
|
||||
ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff));
|
||||
}
|
||||
for (i = 0; i < reservenum; i++) {
|
||||
fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
|
||||
@ -524,7 +548,9 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
|
||||
|
||||
emit_label(f, symprefix, "struct_start");
|
||||
flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
|
||||
fprintf(f, "\t.long\tFDT_END\n");
|
||||
|
||||
fprintf(f, "\t/* FDT_END */\n");
|
||||
asm_emit_cell(f, FDT_END);
|
||||
emit_label(f, symprefix, "struct_end");
|
||||
|
||||
emit_label(f, symprefix, "strings_start");
|
||||
@ -601,7 +627,7 @@ static char *flat_read_string(struct inbuf *inb)
|
||||
len++;
|
||||
} while ((*p++) != '\0');
|
||||
|
||||
str = strdup(inb->ptr);
|
||||
str = xstrdup(inb->ptr);
|
||||
|
||||
inb->ptr += len;
|
||||
|
||||
@ -643,7 +669,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
|
||||
p++;
|
||||
}
|
||||
|
||||
return strdup(inb->base + offset);
|
||||
return xstrdup(inb->base + offset);
|
||||
}
|
||||
|
||||
static struct property *flat_read_property(struct inbuf *dtbuf,
|
||||
@ -663,7 +689,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
|
||||
|
||||
val = flat_read_data(dtbuf, proplen);
|
||||
|
||||
return build_property(name, val, NULL);
|
||||
return build_property(name, val);
|
||||
}
|
||||
|
||||
|
||||
@ -688,7 +714,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
|
||||
if (re.size == 0)
|
||||
break;
|
||||
|
||||
new = build_reserve_entry(re.address, re.size, NULL);
|
||||
new = build_reserve_entry(re.address, re.size);
|
||||
reservelist = add_reserve_entry(reservelist, new);
|
||||
}
|
||||
|
||||
@ -710,7 +736,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
|
||||
if (!streq(ppath, "/"))
|
||||
plen++;
|
||||
|
||||
return strdup(cpath + plen);
|
||||
return xstrdup(cpath + plen);
|
||||
}
|
||||
|
||||
static struct node *unflatten_tree(struct inbuf *dtbuf,
|
||||
@ -776,7 +802,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
|
||||
|
||||
struct boot_info *dt_from_blob(const char *fname)
|
||||
{
|
||||
struct dtc_file *dtcf;
|
||||
FILE *f;
|
||||
uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
|
||||
uint32_t off_dt, off_str, off_mem_rsvmap;
|
||||
int rc;
|
||||
@ -791,14 +817,14 @@ struct boot_info *dt_from_blob(const char *fname)
|
||||
uint32_t val;
|
||||
int flags = 0;
|
||||
|
||||
dtcf = dtc_open_file(fname, NULL);
|
||||
f = srcfile_relative_open(fname, NULL);
|
||||
|
||||
rc = fread(&magic, sizeof(magic), 1, dtcf->file);
|
||||
if (ferror(dtcf->file))
|
||||
rc = fread(&magic, sizeof(magic), 1, f);
|
||||
if (ferror(f))
|
||||
die("Error reading DT blob magic number: %s\n",
|
||||
strerror(errno));
|
||||
if (rc < 1) {
|
||||
if (feof(dtcf->file))
|
||||
if (feof(f))
|
||||
die("EOF reading DT blob magic number\n");
|
||||
else
|
||||
die("Mysterious short read reading magic number\n");
|
||||
@ -808,11 +834,11 @@ struct boot_info *dt_from_blob(const char *fname)
|
||||
if (magic != FDT_MAGIC)
|
||||
die("Blob has incorrect magic number\n");
|
||||
|
||||
rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
|
||||
if (ferror(dtcf->file))
|
||||
rc = fread(&totalsize, sizeof(totalsize), 1, f);
|
||||
if (ferror(f))
|
||||
die("Error reading DT blob size: %s\n", strerror(errno));
|
||||
if (rc < 1) {
|
||||
if (feof(dtcf->file))
|
||||
if (feof(f))
|
||||
die("EOF reading DT blob size\n");
|
||||
else
|
||||
die("Mysterious short read reading blob size\n");
|
||||
@ -832,12 +858,12 @@ struct boot_info *dt_from_blob(const char *fname)
|
||||
p = blob + sizeof(magic) + sizeof(totalsize);
|
||||
|
||||
while (sizeleft) {
|
||||
if (feof(dtcf->file))
|
||||
if (feof(f))
|
||||
die("EOF before reading %d bytes of DT blob\n",
|
||||
totalsize);
|
||||
|
||||
rc = fread(p, 1, sizeleft, dtcf->file);
|
||||
if (ferror(dtcf->file))
|
||||
rc = fread(p, 1, sizeleft, f);
|
||||
if (ferror(f))
|
||||
die("Error reading DT blob: %s\n",
|
||||
strerror(errno));
|
||||
|
||||
@ -900,7 +926,7 @@ struct boot_info *dt_from_blob(const char *fname)
|
||||
|
||||
free(blob);
|
||||
|
||||
dtc_close_file(dtcf);
|
||||
fclose(f);
|
||||
|
||||
return build_boot_info(reservelist, tree, boot_cpuid_phys);
|
||||
}
|
||||
|
@ -58,10 +58,9 @@ static struct node *read_fstree(const char *dirname)
|
||||
"WARNING: Cannot open %s: %s\n",
|
||||
tmpnam, strerror(errno));
|
||||
} else {
|
||||
prop = build_property(strdup(de->d_name),
|
||||
prop = build_property(xstrdup(de->d_name),
|
||||
data_copy_file(pfile,
|
||||
st.st_size),
|
||||
NULL);
|
||||
st.st_size));
|
||||
add_property(tree, prop);
|
||||
fclose(pfile);
|
||||
}
|
||||
@ -69,8 +68,7 @@ static struct node *read_fstree(const char *dirname)
|
||||
struct node *newchild;
|
||||
|
||||
newchild = read_fstree(tmpnam);
|
||||
newchild = name_node(newchild, strdup(de->d_name),
|
||||
NULL);
|
||||
newchild = name_node(newchild, xstrdup(de->d_name));
|
||||
add_child(tree, newchild);
|
||||
}
|
||||
|
||||
@ -86,8 +84,8 @@ struct boot_info *dt_from_fs(const char *dirname)
|
||||
struct node *tree;
|
||||
|
||||
tree = read_fstree(dirname);
|
||||
tree = name_node(tree, "", NULL);
|
||||
tree = name_node(tree, "");
|
||||
|
||||
return build_boot_info(NULL, tree, 0);
|
||||
return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
|
||||
}
|
||||
|
||||
|
@ -24,17 +24,30 @@
|
||||
* Tree building functions
|
||||
*/
|
||||
|
||||
struct property *build_property(char *name, struct data val, char *label)
|
||||
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))
|
||||
return;
|
||||
|
||||
new = xmalloc(sizeof(*new));
|
||||
new->label = label;
|
||||
new->next = *labels;
|
||||
*labels = new;
|
||||
}
|
||||
|
||||
struct property *build_property(char *name, struct data val)
|
||||
{
|
||||
struct property *new = xmalloc(sizeof(*new));
|
||||
|
||||
memset(new, 0, sizeof(*new));
|
||||
|
||||
new->name = name;
|
||||
new->val = val;
|
||||
|
||||
new->next = NULL;
|
||||
|
||||
new->label = label;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
@ -78,17 +91,82 @@ struct node *build_node(struct property *proplist, struct node *children)
|
||||
return new;
|
||||
}
|
||||
|
||||
struct node *name_node(struct node *node, char *name, char * label)
|
||||
struct node *name_node(struct node *node, char *name)
|
||||
{
|
||||
assert(node->name == NULL);
|
||||
|
||||
node->name = name;
|
||||
|
||||
node->label = label;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
||||
{
|
||||
struct property *new_prop, *old_prop;
|
||||
struct node *new_child, *old_child;
|
||||
struct label *l;
|
||||
|
||||
/* Add new node labels to old node */
|
||||
for_each_label(new_node->labels, l)
|
||||
add_label(&old_node->labels, l->label);
|
||||
|
||||
/* Move properties from the new node to the old node. If there
|
||||
* is a collision, replace the old value with the new */
|
||||
while (new_node->proplist) {
|
||||
/* Pop the property off the list */
|
||||
new_prop = new_node->proplist;
|
||||
new_node->proplist = new_prop->next;
|
||||
new_prop->next = NULL;
|
||||
|
||||
/* Look for a collision, set new value if there is */
|
||||
for_each_property(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)
|
||||
add_label(&old_prop->labels, l->label);
|
||||
|
||||
old_prop->val = new_prop->val;
|
||||
free(new_prop);
|
||||
new_prop = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if no collision occurred, add property to the old node. */
|
||||
if (new_prop)
|
||||
add_property(old_node, new_prop);
|
||||
}
|
||||
|
||||
/* Move the override child nodes into the primary node. If
|
||||
* there is a collision, then merge the nodes. */
|
||||
while (new_node->children) {
|
||||
/* Pop the child node off the list */
|
||||
new_child = new_node->children;
|
||||
new_node->children = new_child->next_sibling;
|
||||
new_child->parent = NULL;
|
||||
new_child->next_sibling = NULL;
|
||||
|
||||
/* Search for a collision. Merge if there is */
|
||||
for_each_child(old_node, old_child) {
|
||||
if (streq(old_child->name, new_child->name)) {
|
||||
merge_nodes(old_child, new_child);
|
||||
new_child = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if no collision occured, add child to the old node. */
|
||||
if (new_child)
|
||||
add_child(old_node, new_child);
|
||||
}
|
||||
|
||||
/* The new node contents are now merged into the old node. Free
|
||||
* the new node. */
|
||||
free(new_node);
|
||||
|
||||
return old_node;
|
||||
}
|
||||
|
||||
struct node *chain_node(struct node *first, struct node *list)
|
||||
{
|
||||
assert(first->next_sibling == NULL);
|
||||
@ -124,18 +202,15 @@ void add_child(struct node *parent, struct node *child)
|
||||
*p = child;
|
||||
}
|
||||
|
||||
struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
|
||||
char *label)
|
||||
struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
|
||||
{
|
||||
struct reserve_info *new = xmalloc(sizeof(*new));
|
||||
|
||||
memset(new, 0, sizeof(*new));
|
||||
|
||||
new->re.address = address;
|
||||
new->re.size = size;
|
||||
|
||||
new->next = NULL;
|
||||
|
||||
new->label = label;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
@ -208,6 +283,60 @@ cell_t propval_cell(struct property *prop)
|
||||
return fdt32_to_cpu(*((cell_t *)prop->val.val));
|
||||
}
|
||||
|
||||
struct property *get_property_by_label(struct node *tree, const char *label,
|
||||
struct node **node)
|
||||
{
|
||||
struct property *prop;
|
||||
struct node *c;
|
||||
|
||||
*node = tree;
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
struct label *l;
|
||||
|
||||
for_each_label(prop->labels, l)
|
||||
if (streq(l->label, label))
|
||||
return prop;
|
||||
}
|
||||
|
||||
for_each_child(tree, c) {
|
||||
prop = get_property_by_label(c, label, node);
|
||||
if (prop)
|
||||
return prop;
|
||||
}
|
||||
|
||||
*node = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct marker *get_marker_label(struct node *tree, const char *label,
|
||||
struct node **node, struct property **prop)
|
||||
{
|
||||
struct marker *m;
|
||||
struct property *p;
|
||||
struct node *c;
|
||||
|
||||
*node = tree;
|
||||
|
||||
for_each_property(tree, p) {
|
||||
*prop = p;
|
||||
m = p->val.markers;
|
||||
for_each_marker_of_type(m, LABEL)
|
||||
if (streq(m->ref, label))
|
||||
return m;
|
||||
}
|
||||
|
||||
for_each_child(tree, c) {
|
||||
m = get_marker_label(c, label, node, prop);
|
||||
if (m)
|
||||
return m;
|
||||
}
|
||||
|
||||
*prop = NULL;
|
||||
*node = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct node *get_subnode(struct node *node, const char *nodename)
|
||||
{
|
||||
struct node *child;
|
||||
@ -245,11 +374,13 @@ struct node *get_node_by_path(struct node *tree, const char *path)
|
||||
struct node *get_node_by_label(struct node *tree, const char *label)
|
||||
{
|
||||
struct node *child, *node;
|
||||
struct label *l;
|
||||
|
||||
assert(label && (strlen(label) > 0));
|
||||
|
||||
if (tree->label && streq(tree->label, label))
|
||||
return tree;
|
||||
for_each_label(tree->labels, l)
|
||||
if (streq(l->label, label))
|
||||
return tree;
|
||||
|
||||
for_each_child(tree, child) {
|
||||
node = get_node_by_label(child, label);
|
||||
@ -293,16 +424,186 @@ cell_t get_node_phandle(struct node *root, struct node *node)
|
||||
if ((node->phandle != 0) && (node->phandle != -1))
|
||||
return node->phandle;
|
||||
|
||||
assert(! get_property(node, "linux,phandle"));
|
||||
|
||||
while (get_node_by_phandle(root, phandle))
|
||||
phandle++;
|
||||
|
||||
node->phandle = phandle;
|
||||
add_property(node,
|
||||
build_property("linux,phandle",
|
||||
data_append_cell(empty_data, phandle),
|
||||
NULL));
|
||||
|
||||
if (!get_property(node, "linux,phandle")
|
||||
&& (phandle_format & PHANDLE_LEGACY))
|
||||
add_property(node,
|
||||
build_property("linux,phandle",
|
||||
data_append_cell(empty_data, phandle)));
|
||||
|
||||
if (!get_property(node, "phandle")
|
||||
&& (phandle_format & PHANDLE_EPAPR))
|
||||
add_property(node,
|
||||
build_property("phandle",
|
||||
data_append_cell(empty_data, phandle)));
|
||||
|
||||
/* If the node *does* have a phandle property, we must
|
||||
* be dealing with a self-referencing phandle, which will be
|
||||
* fixed up momentarily in the caller */
|
||||
|
||||
return node->phandle;
|
||||
}
|
||||
|
||||
uint32_t guess_boot_cpuid(struct node *tree)
|
||||
{
|
||||
struct node *cpus, *bootcpu;
|
||||
struct property *reg;
|
||||
|
||||
cpus = get_node_by_path(tree, "/cpus");
|
||||
if (!cpus)
|
||||
return 0;
|
||||
|
||||
|
||||
bootcpu = cpus->children;
|
||||
if (!bootcpu)
|
||||
return 0;
|
||||
|
||||
reg = get_property(bootcpu, "reg");
|
||||
if (!reg || (reg->val.len != sizeof(uint32_t)))
|
||||
return 0;
|
||||
|
||||
/* FIXME: Sanity check node? */
|
||||
|
||||
return propval_cell(reg);
|
||||
}
|
||||
|
||||
static int cmp_reserve_info(const void *ax, const void *bx)
|
||||
{
|
||||
const struct reserve_info *a, *b;
|
||||
|
||||
a = *((const struct reserve_info * const *)ax);
|
||||
b = *((const struct reserve_info * const *)bx);
|
||||
|
||||
if (a->re.address < b->re.address)
|
||||
return -1;
|
||||
else if (a->re.address > b->re.address)
|
||||
return 1;
|
||||
else if (a->re.size < b->re.size)
|
||||
return -1;
|
||||
else if (a->re.size > b->re.size)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sort_reserve_entries(struct boot_info *bi)
|
||||
{
|
||||
struct reserve_info *ri, **tbl;
|
||||
int n = 0, i = 0;
|
||||
|
||||
for (ri = bi->reservelist;
|
||||
ri;
|
||||
ri = ri->next)
|
||||
n++;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
tbl = xmalloc(n * sizeof(*tbl));
|
||||
|
||||
for (ri = bi->reservelist;
|
||||
ri;
|
||||
ri = ri->next)
|
||||
tbl[i++] = ri;
|
||||
|
||||
qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
|
||||
|
||||
bi->reservelist = tbl[0];
|
||||
for (i = 0; i < (n-1); i++)
|
||||
tbl[i]->next = tbl[i+1];
|
||||
tbl[n-1]->next = NULL;
|
||||
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
static int cmp_prop(const void *ax, const void *bx)
|
||||
{
|
||||
const struct property *a, *b;
|
||||
|
||||
a = *((const struct property * const *)ax);
|
||||
b = *((const struct property * const *)bx);
|
||||
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
static void sort_properties(struct node *node)
|
||||
{
|
||||
int n = 0, i = 0;
|
||||
struct property *prop, **tbl;
|
||||
|
||||
for_each_property(node, prop)
|
||||
n++;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
tbl = xmalloc(n * sizeof(*tbl));
|
||||
|
||||
for_each_property(node, prop)
|
||||
tbl[i++] = prop;
|
||||
|
||||
qsort(tbl, n, sizeof(*tbl), cmp_prop);
|
||||
|
||||
node->proplist = tbl[0];
|
||||
for (i = 0; i < (n-1); i++)
|
||||
tbl[i]->next = tbl[i+1];
|
||||
tbl[n-1]->next = NULL;
|
||||
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
static int cmp_subnode(const void *ax, const void *bx)
|
||||
{
|
||||
const struct node *a, *b;
|
||||
|
||||
a = *((const struct node * const *)ax);
|
||||
b = *((const struct node * const *)bx);
|
||||
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
static void sort_subnodes(struct node *node)
|
||||
{
|
||||
int n = 0, i = 0;
|
||||
struct node *subnode, **tbl;
|
||||
|
||||
for_each_child(node, subnode)
|
||||
n++;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
tbl = xmalloc(n * sizeof(*tbl));
|
||||
|
||||
for_each_child(node, subnode)
|
||||
tbl[i++] = subnode;
|
||||
|
||||
qsort(tbl, n, sizeof(*tbl), cmp_subnode);
|
||||
|
||||
node->children = tbl[0];
|
||||
for (i = 0; i < (n-1); i++)
|
||||
tbl[i]->next_sibling = tbl[i+1];
|
||||
tbl[n-1]->next_sibling = NULL;
|
||||
|
||||
free(tbl);
|
||||
}
|
||||
|
||||
static void sort_node(struct node *node)
|
||||
{
|
||||
struct node *c;
|
||||
|
||||
sort_properties(node);
|
||||
sort_subnodes(node);
|
||||
for_each_child(node, c)
|
||||
sort_node(c);
|
||||
}
|
||||
|
||||
void sort_tree(struct boot_info *bi)
|
||||
{
|
||||
sort_reserve_entries(bi);
|
||||
sort_node(bi->dt);
|
||||
}
|
||||
|
@ -17,100 +17,232 @@
|
||||
* USA
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dtc.h"
|
||||
#include "srcpos.h"
|
||||
|
||||
/*
|
||||
* Like yylineno, this is the current open file pos.
|
||||
*/
|
||||
|
||||
struct dtc_file *srcpos_file;
|
||||
|
||||
static int dtc_open_one(struct dtc_file *file,
|
||||
const char *search,
|
||||
const char *fname)
|
||||
static char *dirname(const char *path)
|
||||
{
|
||||
const char *slash = strrchr(path, '/');
|
||||
|
||||
if (slash) {
|
||||
int len = slash - path;
|
||||
char *dir = xmalloc(len + 1);
|
||||
|
||||
memcpy(dir, path, len);
|
||||
dir[len] = '\0';
|
||||
return dir;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct srcfile_state *current_srcfile; /* = NULL */
|
||||
|
||||
/* Detect infinite include recursion. */
|
||||
#define MAX_SRCFILE_DEPTH (100)
|
||||
static int srcfile_depth; /* = 0 */
|
||||
|
||||
FILE *srcfile_relative_open(const char *fname, char **fullnamep)
|
||||
{
|
||||
FILE *f;
|
||||
char *fullname;
|
||||
|
||||
if (search) {
|
||||
fullname = xmalloc(strlen(search) + strlen(fname) + 2);
|
||||
|
||||
strcpy(fullname, search);
|
||||
strcat(fullname, "/");
|
||||
strcat(fullname, fname);
|
||||
} else {
|
||||
fullname = strdup(fname);
|
||||
}
|
||||
|
||||
file->file = fopen(fullname, "r");
|
||||
if (!file->file) {
|
||||
free(fullname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
file->name = fullname;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct dtc_file *dtc_open_file(const char *fname,
|
||||
const struct search_path *search)
|
||||
{
|
||||
static const struct search_path default_search = { NULL, NULL, NULL };
|
||||
|
||||
struct dtc_file *file;
|
||||
const char *slash;
|
||||
|
||||
file = xmalloc(sizeof(struct dtc_file));
|
||||
|
||||
slash = strrchr(fname, '/');
|
||||
if (slash) {
|
||||
char *dir = xmalloc(slash - fname + 1);
|
||||
|
||||
memcpy(dir, fname, slash - fname);
|
||||
dir[slash - fname] = 0;
|
||||
file->dir = dir;
|
||||
} else {
|
||||
file->dir = NULL;
|
||||
}
|
||||
|
||||
if (streq(fname, "-")) {
|
||||
file->name = "stdin";
|
||||
file->file = stdin;
|
||||
return file;
|
||||
f = stdin;
|
||||
fullname = xstrdup("<stdin>");
|
||||
} else {
|
||||
if (!current_srcfile || !current_srcfile->dir
|
||||
|| (fname[0] == '/'))
|
||||
fullname = xstrdup(fname);
|
||||
else
|
||||
fullname = join_path(current_srcfile->dir, fname);
|
||||
|
||||
f = fopen(fullname, "r");
|
||||
if (!f)
|
||||
die("Couldn't open \"%s\": %s\n", fname,
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
if (fname[0] == '/') {
|
||||
file->file = fopen(fname, "r");
|
||||
if (!file->file)
|
||||
goto fail;
|
||||
if (fullnamep)
|
||||
*fullnamep = fullname;
|
||||
else
|
||||
free(fullname);
|
||||
|
||||
file->name = strdup(fname);
|
||||
return file;
|
||||
}
|
||||
|
||||
if (!search)
|
||||
search = &default_search;
|
||||
|
||||
while (search) {
|
||||
if (dtc_open_one(file, search->dir, fname))
|
||||
return file;
|
||||
|
||||
if (errno != ENOENT)
|
||||
goto fail;
|
||||
|
||||
search = search->next;
|
||||
}
|
||||
|
||||
fail:
|
||||
die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
|
||||
return f;
|
||||
}
|
||||
|
||||
void dtc_close_file(struct dtc_file *file)
|
||||
void srcfile_push(const char *fname)
|
||||
{
|
||||
if (fclose(file->file))
|
||||
die("Error closing \"%s\": %s\n", file->name, strerror(errno));
|
||||
struct srcfile_state *srcfile;
|
||||
|
||||
free(file->dir);
|
||||
free(file);
|
||||
if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
|
||||
die("Includes nested too deeply");
|
||||
|
||||
srcfile = xmalloc(sizeof(*srcfile));
|
||||
|
||||
srcfile->f = srcfile_relative_open(fname, &srcfile->name);
|
||||
srcfile->dir = dirname(srcfile->name);
|
||||
srcfile->prev = current_srcfile;
|
||||
|
||||
srcfile->lineno = 1;
|
||||
srcfile->colno = 1;
|
||||
|
||||
current_srcfile = srcfile;
|
||||
}
|
||||
|
||||
int srcfile_pop(void)
|
||||
{
|
||||
struct srcfile_state *srcfile = current_srcfile;
|
||||
|
||||
assert(srcfile);
|
||||
|
||||
current_srcfile = srcfile->prev;
|
||||
|
||||
if (fclose(srcfile->f))
|
||||
die("Error closing \"%s\": %s\n", srcfile->name,
|
||||
strerror(errno));
|
||||
|
||||
/* FIXME: We allow the srcfile_state structure to leak,
|
||||
* because it could still be referenced from a location
|
||||
* variable being carried through the parser somewhere. To
|
||||
* fix this we could either allocate all the files from a
|
||||
* table, or use a pool allocator. */
|
||||
|
||||
return current_srcfile ? 1 : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The empty source position.
|
||||
*/
|
||||
|
||||
struct srcpos srcpos_empty = {
|
||||
.first_line = 0,
|
||||
.first_column = 0,
|
||||
.last_line = 0,
|
||||
.last_column = 0,
|
||||
.file = NULL,
|
||||
};
|
||||
|
||||
#define TAB_SIZE 8
|
||||
|
||||
void srcpos_update(struct srcpos *pos, const char *text, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
pos->file = current_srcfile;
|
||||
|
||||
pos->first_line = current_srcfile->lineno;
|
||||
pos->first_column = current_srcfile->colno;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (text[i] == '\n') {
|
||||
current_srcfile->lineno++;
|
||||
current_srcfile->colno = 1;
|
||||
} else if (text[i] == '\t') {
|
||||
current_srcfile->colno =
|
||||
ALIGN(current_srcfile->colno, TAB_SIZE);
|
||||
} else {
|
||||
current_srcfile->colno++;
|
||||
}
|
||||
|
||||
pos->last_line = current_srcfile->lineno;
|
||||
pos->last_column = current_srcfile->colno;
|
||||
}
|
||||
|
||||
struct srcpos *
|
||||
srcpos_copy(struct srcpos *pos)
|
||||
{
|
||||
struct srcpos *pos_new;
|
||||
|
||||
pos_new = xmalloc(sizeof(struct srcpos));
|
||||
memcpy(pos_new, pos, sizeof(struct srcpos));
|
||||
|
||||
return pos_new;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
srcpos_dump(struct srcpos *pos)
|
||||
{
|
||||
printf("file : \"%s\"\n",
|
||||
pos->file ? (char *) pos->file : "<no file>");
|
||||
printf("first_line : %d\n", pos->first_line);
|
||||
printf("first_column: %d\n", pos->first_column);
|
||||
printf("last_line : %d\n", pos->last_line);
|
||||
printf("last_column : %d\n", pos->last_column);
|
||||
printf("file : %s\n", pos->file->name);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
srcpos_string(struct srcpos *pos)
|
||||
{
|
||||
const char *fname = "<no-file>";
|
||||
char *pos_str;
|
||||
int rc;
|
||||
|
||||
if (pos)
|
||||
fname = pos->file->name;
|
||||
|
||||
|
||||
if (pos->first_line != pos->last_line)
|
||||
rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
|
||||
pos->first_line, pos->first_column,
|
||||
pos->last_line, pos->last_column);
|
||||
else if (pos->first_column != pos->last_column)
|
||||
rc = asprintf(&pos_str, "%s:%d.%d-%d", fname,
|
||||
pos->first_line, pos->first_column,
|
||||
pos->last_column);
|
||||
else
|
||||
rc = asprintf(&pos_str, "%s:%d.%d", fname,
|
||||
pos->first_line, pos->first_column);
|
||||
|
||||
if (rc == -1)
|
||||
die("Couldn't allocate in srcpos string");
|
||||
|
||||
return pos_str;
|
||||
}
|
||||
|
||||
void
|
||||
srcpos_verror(struct srcpos *pos, char const *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);
|
||||
|
||||
srcstr = srcpos_string(pos);
|
||||
|
||||
fprintf(stderr, "Warning: %s ", srcstr);
|
||||
vfprintf(stderr, fmt, va);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
@ -17,69 +17,70 @@
|
||||
* USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Augment the standard YYLTYPE with a filenum index into an
|
||||
* array of all opened filenames.
|
||||
*/
|
||||
#ifndef _SRCPOS_H_
|
||||
#define _SRCPOS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct dtc_file {
|
||||
struct srcfile_state {
|
||||
FILE *f;
|
||||
char *name;
|
||||
char *dir;
|
||||
const char *name;
|
||||
FILE *file;
|
||||
int lineno, colno;
|
||||
struct srcfile_state *prev;
|
||||
};
|
||||
|
||||
#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
|
||||
typedef struct YYLTYPE {
|
||||
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);
|
||||
|
||||
struct srcpos {
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
struct dtc_file *file;
|
||||
} YYLTYPE;
|
||||
|
||||
#define YYLTYPE_IS_DECLARED 1
|
||||
#define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
/* Cater to old parser templates. */
|
||||
#ifndef YYID
|
||||
#define YYID(n) (n)
|
||||
#endif
|
||||
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
do \
|
||||
if (YYID (N)) \
|
||||
{ \
|
||||
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
|
||||
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
|
||||
(Current).last_line = YYRHSLOC (Rhs, N).last_line; \
|
||||
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \
|
||||
(Current).file = YYRHSLOC (Rhs, N).file; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(Current).first_line = (Current).last_line = \
|
||||
YYRHSLOC (Rhs, 0).last_line; \
|
||||
(Current).first_column = (Current).last_column = \
|
||||
YYRHSLOC (Rhs, 0).last_column; \
|
||||
(Current).file = YYRHSLOC (Rhs, 0).file; \
|
||||
} \
|
||||
while (YYID (0))
|
||||
|
||||
|
||||
|
||||
extern void yyerror(char const *);
|
||||
extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
extern struct dtc_file *srcpos_file;
|
||||
|
||||
struct search_path {
|
||||
const char *dir; /* NULL for current directory */
|
||||
struct search_path *prev, *next;
|
||||
struct srcfile_state *file;
|
||||
};
|
||||
|
||||
extern struct dtc_file *dtc_open_file(const char *fname,
|
||||
const struct search_path *search);
|
||||
extern void dtc_close_file(struct dtc_file *file);
|
||||
#define YYLTYPE struct srcpos
|
||||
|
||||
#define YYLLOC_DEFAULT(Current, Rhs, N) \
|
||||
do { \
|
||||
if (N) { \
|
||||
(Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
|
||||
(Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
|
||||
(Current).last_line = YYRHSLOC(Rhs, N).last_line; \
|
||||
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \
|
||||
(Current).file = YYRHSLOC(Rhs, N).file; \
|
||||
} else { \
|
||||
(Current).first_line = (Current).last_line = \
|
||||
YYRHSLOC(Rhs, 0).last_line; \
|
||||
(Current).first_column = (Current).last_column = \
|
||||
YYRHSLOC(Rhs, 0).last_column; \
|
||||
(Current).file = YYRHSLOC (Rhs, 0).file; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Fictional source position used for IR nodes that are
|
||||
* created without otherwise knowing a true source position.
|
||||
* For example,constant definitions from the command line.
|
||||
*/
|
||||
extern struct srcpos srcpos_empty;
|
||||
|
||||
extern void srcpos_update(struct srcpos *pos, const char *text, int len);
|
||||
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)));
|
||||
|
||||
#endif /* _SRCPOS_H_ */
|
||||
|
@ -32,8 +32,8 @@ struct boot_info *dt_from_source(const char *fname)
|
||||
the_boot_info = NULL;
|
||||
treesource_error = 0;
|
||||
|
||||
srcpos_file = dtc_open_file(fname, NULL);
|
||||
yyin = srcpos_file->file;
|
||||
srcfile_push(fname);
|
||||
yyin = current_srcfile->f;
|
||||
|
||||
if (yyparse() != 0)
|
||||
die("Unable to parse input tree\n");
|
||||
@ -63,26 +63,20 @@ static void write_propval_string(FILE *f, struct data val)
|
||||
{
|
||||
const char *str = val.val;
|
||||
int i;
|
||||
int newchunk = 1;
|
||||
struct marker *m = val.markers;
|
||||
|
||||
assert(str[val.len-1] == '\0');
|
||||
|
||||
while (m && (m->offset == 0)) {
|
||||
if (m->type == LABEL)
|
||||
fprintf(f, "%s: ", m->ref);
|
||||
m = m->next;
|
||||
}
|
||||
fprintf(f, "\"");
|
||||
|
||||
for (i = 0; i < (val.len-1); i++) {
|
||||
char c = str[i];
|
||||
|
||||
if (newchunk) {
|
||||
while (m && (m->offset <= i)) {
|
||||
if (m->type == LABEL) {
|
||||
assert(m->offset == i);
|
||||
fprintf(f, "%s: ", m->ref);
|
||||
}
|
||||
m = m->next;
|
||||
}
|
||||
fprintf(f, "\"");
|
||||
newchunk = 0;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case '\a':
|
||||
fprintf(f, "\\a");
|
||||
@ -113,7 +107,14 @@ static void write_propval_string(FILE *f, struct data val)
|
||||
break;
|
||||
case '\0':
|
||||
fprintf(f, "\", ");
|
||||
newchunk = 1;
|
||||
while (m && (m->offset < i)) {
|
||||
if (m->type == LABEL) {
|
||||
assert(m->offset == (i+1));
|
||||
fprintf(f, "%s: ", m->ref);
|
||||
}
|
||||
m = m->next;
|
||||
}
|
||||
fprintf(f, "\"");
|
||||
break;
|
||||
default:
|
||||
if (isprint(c))
|
||||
@ -234,10 +235,11 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
|
||||
{
|
||||
struct property *prop;
|
||||
struct node *child;
|
||||
struct label *l;
|
||||
|
||||
write_prefix(f, level);
|
||||
if (tree->label)
|
||||
fprintf(f, "%s: ", tree->label);
|
||||
for_each_label(tree->labels, l)
|
||||
fprintf(f, "%s: ", l->label);
|
||||
if (tree->name && (*tree->name))
|
||||
fprintf(f, "%s {\n", tree->name);
|
||||
else
|
||||
@ -245,8 +247,8 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
|
||||
|
||||
for_each_property(tree, prop) {
|
||||
write_prefix(f, level+1);
|
||||
if (prop->label)
|
||||
fprintf(f, "%s: ", prop->label);
|
||||
for_each_label(prop->labels, l)
|
||||
fprintf(f, "%s: ", l->label);
|
||||
fprintf(f, "%s", prop->name);
|
||||
write_propval(f, prop);
|
||||
}
|
||||
@ -266,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_info *bi)
|
||||
fprintf(f, "/dts-v1/;\n\n");
|
||||
|
||||
for (re = bi->reservelist; re; re = re->next) {
|
||||
if (re->label)
|
||||
fprintf(f, "%s: ", re->label);
|
||||
struct label *l;
|
||||
|
||||
for_each_label(re->labels, l)
|
||||
fprintf(f, "%s: ", l->label);
|
||||
fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
|
||||
(unsigned long long)re->re.address,
|
||||
(unsigned long long)re->re.size);
|
||||
|
59
scripts/dtc/util.c
Normal file
59
scripts/dtc/util.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
char *xstrdup(const char *s)
|
||||
{
|
||||
int len = strlen(s) + 1;
|
||||
char *dup = xmalloc(len);
|
||||
|
||||
memcpy(dup, s, len);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
char *join_path(const char *path, const char *name)
|
||||
{
|
||||
int lenp = strlen(path);
|
||||
int lenn = strlen(name);
|
||||
int len;
|
||||
int needslash = 1;
|
||||
char *str;
|
||||
|
||||
len = lenp + lenn + 2;
|
||||
if ((lenp > 0) && (path[lenp-1] == '/')) {
|
||||
needslash = 0;
|
||||
len--;
|
||||
}
|
||||
|
||||
str = xmalloc(len);
|
||||
memcpy(str, path, lenp);
|
||||
if (needslash) {
|
||||
str[lenp] = '/';
|
||||
lenp++;
|
||||
}
|
||||
memcpy(str+lenp, name, lenn+1);
|
||||
return str;
|
||||
}
|
56
scripts/dtc/util.h
Normal file
56
scripts/dtc/util.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef _UTIL_H
|
||||
#define _UTIL_H
|
||||
|
||||
/*
|
||||
* Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program 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 program 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 program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*/
|
||||
|
||||
static inline void __attribute__((noreturn)) die(char * str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, str);
|
||||
fprintf(stderr, "FATAL ERROR: ");
|
||||
vfprintf(stderr, str, ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static inline void *xmalloc(size_t len)
|
||||
{
|
||||
void *new = malloc(len);
|
||||
|
||||
if (!new)
|
||||
die("malloc() failed\n");
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static inline void *xrealloc(void *p, size_t len)
|
||||
{
|
||||
void *new = realloc(p, len);
|
||||
|
||||
if (!new)
|
||||
die("realloc() failed (len=%d)\n", len);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
extern char *xstrdup(const char *s);
|
||||
extern char *join_path(const char *path, const char *name);
|
||||
|
||||
#endif /* _UTIL_H */
|
@ -1 +1 @@
|
||||
#define DTC_VERSION "DTC 1.2.0"
|
||||
#define DTC_VERSION "DTC 1.2.0-g37c0b6a0"
|
||||
|
Reference in New Issue
Block a user