View | Details | Raw Unified | Return to bug 233863 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/src/stand/powerpc/ofw/ofwfdt.c (-24 / +146 lines)
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;
Lines 141-146 Link Here
141
		 * since that's part of the firmware.
241
		 * since that's part of the firmware.
142
		 */
242
		 */
143
		offset = fdt_path_offset(fdtp, "/memory@0");
243
		offset = fdt_path_offset(fdtp, "/memory@0");
244
		if (offset<=0) offset= fdt_path_offset(fdtp, "/memory@0,0"); // G5's
144
		if (offset > 0)
245
		if (offset > 0)
145
			fdt_delprop(fdtp, offset, "available");
246
			fdt_delprop(fdtp, offset, "available");
146
	}
247
	}
Lines 184-200 Link Here
184
{
285
{
185
        void *buffer;
286
        void *buffer;
186
        size_t buflen = 409600;
287
        size_t buflen = 409600;
288
	int ret;
187
289
188
        buffer = malloc(buflen);
290
        buffer = malloc(buflen);
189
        fdt_create_empty_tree(buffer, buflen);
291
	if (NULL==buffer) {
190
        add_node_to_fdt(buffer, OF_peer(0), fdt_path_offset(buffer, "/"));
292
		printf("fdt_platform_load_dtb: Large buffer malloc failed.\n");
191
        ofwfdt_fixups(buffer);
293
		return 1; // Give up.
192
        fdt_pack(buffer);
294
	}
193
295
194
        fdt_load_dtb_addr(buffer);
296
        ret= fdt_create_empty_tree(buffer, buflen);
297
	if (ret) {
298
		printf("fdt_platform_load_dtb: fdt_create_empty_tree failed\n");
299
		goto cleanup_and_return;
300
	}
301
302
	add_node_to_fdt(buffer, OF_peer(0), fdt_path_offset(buffer, "/"));
303
	ofwfdt_fixups(buffer);
304
305
	ret= fdt_pack(buffer);
306
	if (ret) {
307
		printf("fdt_platform_load_dtb: fdt_pack failed\n");
308
		goto cleanup_and_return;
309
	}
310
311
        ret= fdt_load_dtb_addr(buffer);
312
	if (ret) {
313
		printf("fdt_platform_load_dtb: fdt_load_dtb_addr failed\n");
314
		goto cleanup_and_return;
315
	}
316
317
cleanup_and_return:
195
        free(buffer);
318
        free(buffer);
196
319
        return ret;
197
        return (0);
198
}
320
}
199
321
200
void
322
void
(-)/usr/src/sys/contrib/libfdt/fdt_rw.c (+7 lines)
Lines 358-364 Link Here
358
358
359
	offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
359
	offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
360
	if (offset >= 0)
360
	if (offset >= 0)
361
#if 0
362
// Some Macintoshes have identical package-to-pathname results for
363
// multiple nodes of the same type and unit under the parent node.
364
// Avoid blocking this for fdt.
361
		return -FDT_ERR_EXISTS;
365
		return -FDT_ERR_EXISTS;
366
#else
367
		;
368
#endif
362
	else if (offset != -FDT_ERR_NOTFOUND)
369
	else if (offset != -FDT_ERR_NOTFOUND)
363
		return offset;
370
		return offset;
364
371

Return to bug 233863