Lines 42-63
Link Here
|
42 |
} |
42 |
} |
43 |
|
43 |
|
44 |
static void |
44 |
static void |
45 |
add_node_to_fdt(void *buffer, phandle_t node, int fdt_offset) |
45 |
add_node_to_fdt(void *buffer, phandle_t parent_node, int fdt_offset) |
46 |
{ |
46 |
{ |
47 |
int i, child_offset, error; |
47 |
int i, child_offset, error; |
48 |
char name[255], *lastprop, *subname; |
48 |
char name[255+1], *lastprop, *subname; // +1 added for always having a trailing '\0' position. |
49 |
void *propbuf; |
49 |
void *propbuf; |
50 |
ssize_t proplen; |
50 |
ssize_t proplen; |
51 |
|
51 |
|
52 |
lastprop = NULL; |
52 |
// WARNING: fdt_setprop adds to the beginning of the property sequence. So, |
53 |
while (OF_nextprop(node, lastprop, name) > 0) { |
53 |
// to avoid reversing the sequence, use it last to first for the originals. |
54 |
proplen = OF_getproplen(node, name); |
|
|
55 |
|
54 |
|
|
|
55 |
int prop_cnt= 0; |
56 |
lastprop= NULL; |
57 |
while (0<OF_nextprop(parent_node, lastprop, name)) { |
58 |
prop_cnt++; |
59 |
lastprop= name; |
60 |
} |
61 |
int prop_want= prop_cnt; |
62 |
for (; 0!=prop_want; prop_want--) { |
63 |
lastprop= NULL; |
64 |
int prop_at= 0; |
65 |
for(; prop_at!=prop_want; prop_at++) { |
66 |
OF_nextprop(parent_node, lastprop, name); |
67 |
lastprop= name; |
68 |
} |
69 |
|
70 |
proplen = OF_getproplen(parent_node, name); |
71 |
|
56 |
/* Detect and correct for errors and strangeness */ |
72 |
/* Detect and correct for errors and strangeness */ |
57 |
if (proplen < 0) |
73 |
if (proplen < 0) { |
|
|
74 |
printf("proplen was negative: %jd while adding property %s to " |
75 |
"parent_node %d\n", (intmax_t)proplen, name, fdt_offset); |
58 |
proplen = 0; |
76 |
proplen = 0; |
59 |
if (proplen > 1024) |
77 |
} |
|
|
78 |
if (proplen > 1024) { |
79 |
printf("proplen was large: %jd while adding property %s to " |
80 |
"parent_node %d\n", (intmax_t)proplen, name, fdt_offset); |
81 |
#if 0 |
82 |
// WARNING: Some Macintoshes end up with video-card driver code as properties. |
83 |
// An example PowerMac7,2 configuration had 2 such properties, each |
84 |
// being 96306 bytes in size. If these were ever used in a truncated |
85 |
// from things would be messed up. So do not force truncations. There |
86 |
// are a few other, smaller properties that bigger than 1 KBytes. I |
87 |
// checked: fdt_platform_load_dtb's 409600 buflen is more than |
88 |
// sufficient for the example context. |
89 |
|
60 |
proplen = 1024; |
90 |
proplen = 1024; |
|
|
91 |
#endif |
92 |
} |
61 |
|
93 |
|
62 |
propbuf = malloc(proplen); |
94 |
propbuf = malloc(proplen); |
63 |
if (propbuf == NULL) { |
95 |
if (propbuf == NULL) { |
Lines 64-88
Link Here
|
64 |
printf("Cannot allocate memory for prop %s\n", name); |
96 |
printf("Cannot allocate memory for prop %s\n", name); |
65 |
return; |
97 |
return; |
66 |
} |
98 |
} |
67 |
OF_getprop(node, name, propbuf, proplen); |
99 |
OF_getprop(parent_node, name, propbuf, proplen); |
68 |
error = fdt_setprop(buffer, fdt_offset, name, propbuf, proplen); |
100 |
error = fdt_setprop(buffer, fdt_offset, name, propbuf, proplen); |
69 |
free(propbuf); |
101 |
free(propbuf); |
70 |
lastprop = name; |
|
|
71 |
if (error) |
102 |
if (error) |
72 |
printf("Error %d adding property %s to " |
103 |
printf("Error %d adding property %s to " |
73 |
"node %d\n", error, name, fdt_offset); |
104 |
"parent_node %d\n", error, name, fdt_offset); |
74 |
} |
105 |
} |
75 |
|
106 |
|
76 |
if (!OF_hasprop(node, "phandle") && !OF_hasprop(node, "linux,phandle") |
107 |
if (!OF_hasprop(parent_node, "phandle") && !OF_hasprop(parent_node, "linux,phandle") |
77 |
&& !OF_hasprop(node, "ibm,phandle")) |
108 |
&& !OF_hasprop(parent_node, "ibm,phandle")) |
78 |
fdt_setprop(buffer, fdt_offset, "phandle", &node, sizeof(node)); |
109 |
fdt_setprop(buffer, fdt_offset, "phandle", &parent_node, sizeof(parent_node)); |
79 |
|
110 |
|
80 |
for (node = OF_child(node); node > 0; node = OF_peer(node)) { |
111 |
// WARNING: fdt_add_subnode adds to the beginning of the node sequence (after |
81 |
OF_package_to_path(node, name, sizeof(name)); |
112 |
// the properties). So, to avoid reversing the sequence, use it last to first |
82 |
subname = strrchr(name, '/'); |
113 |
// for the originals. |
|
|
114 |
|
115 |
// WARNING: openfirmware's package-to-path(nd,nm,len) does not place a trailing '\0' |
116 |
// character in nm when it returns a full_str_len with len<=full_str_len . |
117 |
// For full_str_len<len, a trailing '\0' is placed at nm[full_str_len]. |
118 |
|
119 |
int child_cnt= 0; |
120 |
phandle_t node= OF_child(parent_node); |
121 |
for (; 0<node; node= OF_peer(node)) { |
122 |
child_cnt++; |
123 |
} |
124 |
name[255]= '\0'; // Avoid OF_package_to_path leaving no '\0' at end of long path. |
125 |
int node_want= child_cnt; |
126 |
for (; 0!=node_want; node_want--) { |
127 |
node= OF_child(parent_node); |
128 |
int node_at= 1; |
129 |
for (; node_at!=node_want; node_at++) { |
130 |
node = OF_peer(node); |
131 |
} |
132 |
|
133 |
int full_str_len= OF_package_to_path(node, name, sizeof(name)-1); // Avoids having trailing '\0' missing. |
134 |
if (-1==full_str_len) { // Highly unlikely. |
135 |
printf("add_node_to_fdt got -1 return from OF_packakge_to_path\n"); |
136 |
continue; |
137 |
} |
138 |
|
139 |
// WARNING: For some Macintoshes, name can sometimes contain '\0' characters |
140 |
// in the middle! So there is avoidance-code because the fdt code is |
141 |
// not designed for such. |
142 |
|
143 |
// WARNING: For some Macintoshes, multiple nodes under a parent can have the |
144 |
// same full-path-text (name here). I've adjusted fdt_add_subnode to |
145 |
// allow such to be recorded so that such Macintosh information is |
146 |
// not lost. |
147 |
|
148 |
// full_str_len omits the offical trailing '\0' position. |
149 |
// full_str_len is *not* limited by the sizeof(name)-1 value above: it reports |
150 |
// the space needed to get all the text (ignoring the official trailing '\0'). |
151 |
if (0==full_str_len) { // Highly unlikely. |
152 |
printf("Error: Node name has no bytes before trailing null byte\n"); |
153 |
continue; |
154 |
} |
155 |
if (255<full_str_len) { |
156 |
printf("Error: Node path %s (truncated), needs more than 255+1 bytes\n", name); |
157 |
continue; |
158 |
} |
159 |
|
160 |
// Eliminate any internal '\0' full path characters: makes saved results more standard |
161 |
// and, so, fdt-supported. The extra Macintosh '\0' characters are non-essential. |
162 |
char *from_pos= name; |
163 |
char *to_pos= name; |
164 |
char *original_end= name+full_str_len; |
165 |
while (from_pos<original_end) { |
166 |
if ('\0'!=*from_pos) |
167 |
*to_pos++= *from_pos; |
168 |
else |
169 |
full_str_len--; |
170 |
from_pos++; |
171 |
} |
172 |
*to_pos= '\0'; |
173 |
if (to_pos==name) { // Highly unlikely. |
174 |
printf("Error: Adjusted node name has no bytes before trailing null byte\n"); |
175 |
continue; |
176 |
} |
177 |
|
178 |
subname= strrchr(name,'/'); |
179 |
if (NULL==subname) { // Highly unlikely. |
180 |
printf("Error: Node name %s has no '/'\n", name); |
181 |
continue; |
182 |
} |
83 |
subname++; |
183 |
subname++; |
84 |
child_offset = fdt_add_subnode(buffer, fdt_offset, subname); |
184 |
child_offset = fdt_add_subnode(buffer, fdt_offset, subname); |
85 |
if (child_offset < 0) { |
185 |
if (child_offset < 0) { // Note: fdt_add_subnode was modified to allow duplicate paths. |
86 |
printf("Error %d adding node %s (%s), skipping\n", |
186 |
printf("Error %d adding node %s (%s), skipping\n", |
87 |
child_offset, name, subname); |
187 |
child_offset, name, subname); |
88 |
continue; |
188 |
continue; |