aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/libfdt/fdt.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-09-28 17:25:59 -0400
committerRob Herring <rob.herring@calxeda.com>2012-10-01 12:11:35 -0400
commitcd296721a9645f9f28800a072490fa15458d1fb7 (patch)
tree492b9a268a48af07844fbbd39519f95676ee73fe /scripts/dtc/libfdt/fdt.c
parentacc2097934b5403b97f95763fe99fc115b818061 (diff)
dtc: import latest upstream dtc
This updates scripts/dtc to commit 317a5d9 "dtc: zero out new label objects" from git://git.jdl.com/software/dtc.git. This adds features such as: * /bits/ syntax for cell data. * Math expressions within cell data. * The ability to delete properties or nodes. * Support for #line directives in the input file, which allows the use of cpp on *.dts. * -i command-line option (/include/ path) * -W/-E command-line options for error/warning control. * Removal of spew to STDOUT containing the filename being compiled. * Many additions to the libfdt API. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Jon Loeliger <jdl@jdl.com> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'scripts/dtc/libfdt/fdt.c')
-rw-r--r--scripts/dtc/libfdt/fdt.c61
1 files changed, 41 insertions, 20 deletions
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c
index 2acaec5923ae..e56833ae9b6f 100644
--- a/scripts/dtc/libfdt/fdt.c
+++ b/scripts/dtc/libfdt/fdt.c
@@ -74,7 +74,7 @@ int fdt_check_header(const void *fdt)
74 return 0; 74 return 0;
75} 75}
76 76
77const void *fdt_offset_ptr(const void *fdt, int offset, int len) 77const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
78{ 78{
79 const char *p; 79 const char *p;
80 80
@@ -90,42 +90,53 @@ const void *fdt_offset_ptr(const void *fdt, int offset, int len)
90 return p; 90 return p;
91} 91}
92 92
93uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) 93uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
94{ 94{
95 const uint32_t *tagp, *lenp; 95 const uint32_t *tagp, *lenp;
96 uint32_t tag; 96 uint32_t tag;
97 int offset = startoffset;
97 const char *p; 98 const char *p;
98 99
99 if (offset % FDT_TAGSIZE) 100 *nextoffset = -FDT_ERR_TRUNCATED;
100 return -1;
101
102 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); 101 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
103 if (! tagp) 102 if (!tagp)
104 return FDT_END; /* premature end */ 103 return FDT_END; /* premature end */
105 tag = fdt32_to_cpu(*tagp); 104 tag = fdt32_to_cpu(*tagp);
106 offset += FDT_TAGSIZE; 105 offset += FDT_TAGSIZE;
107 106
107 *nextoffset = -FDT_ERR_BADSTRUCTURE;
108 switch (tag) { 108 switch (tag) {
109 case FDT_BEGIN_NODE: 109 case FDT_BEGIN_NODE:
110 /* skip name */ 110 /* skip name */
111 do { 111 do {
112 p = fdt_offset_ptr(fdt, offset++, 1); 112 p = fdt_offset_ptr(fdt, offset++, 1);
113 } while (p && (*p != '\0')); 113 } while (p && (*p != '\0'));
114 if (! p) 114 if (!p)
115 return FDT_END; 115 return FDT_END; /* premature end */
116 break; 116 break;
117
117 case FDT_PROP: 118 case FDT_PROP:
118 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); 119 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
119 if (! lenp) 120 if (!lenp)
120 return FDT_END; 121 return FDT_END; /* premature end */
121 /* skip name offset, length and value */ 122 /* skip-name offset, length and value */
122 offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); 123 offset += sizeof(struct fdt_property) - FDT_TAGSIZE
124 + fdt32_to_cpu(*lenp);
125 break;
126
127 case FDT_END:
128 case FDT_END_NODE:
129 case FDT_NOP:
123 break; 130 break;
131
132 default:
133 return FDT_END;
124 } 134 }
125 135
126 if (nextoffset) 136 if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
127 *nextoffset = FDT_TAGALIGN(offset); 137 return FDT_END; /* premature end */
128 138
139 *nextoffset = FDT_TAGALIGN(offset);
129 return tag; 140 return tag;
130} 141}
131 142
@@ -138,6 +149,15 @@ int _fdt_check_node_offset(const void *fdt, int offset)
138 return offset; 149 return offset;
139} 150}
140 151
152int _fdt_check_prop_offset(const void *fdt, int offset)
153{
154 if ((offset < 0) || (offset % FDT_TAGSIZE)
155 || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP))
156 return -FDT_ERR_BADOFFSET;
157
158 return offset;
159}
160
141int fdt_next_node(const void *fdt, int offset, int *depth) 161int fdt_next_node(const void *fdt, int offset, int *depth)
142{ 162{
143 int nextoffset = 0; 163 int nextoffset = 0;
@@ -162,15 +182,16 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
162 break; 182 break;
163 183
164 case FDT_END_NODE: 184 case FDT_END_NODE:
165 if (depth) 185 if (depth && ((--(*depth)) < 0))
166 (*depth)--; 186 return nextoffset;
167 break; 187 break;
168 188
169 case FDT_END: 189 case FDT_END:
170 return -FDT_ERR_NOTFOUND; 190 if ((nextoffset >= 0)
171 191 || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth))
172 default: 192 return -FDT_ERR_NOTFOUND;
173 return -FDT_ERR_BADSTRUCTURE; 193 else
194 return nextoffset;
174 } 195 }
175 } while (tag != FDT_BEGIN_NODE); 196 } while (tag != FDT_BEGIN_NODE);
176 197