Blame view

common/cmd_fdt.c 24.5 KB
781e09ee6   Gerald Van Baren   Add a flattened d...
1
2
3
4
5
6
7
  /*
   * (C) Copyright 2007
   * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
   * Based on code written by:
   *   Pantelis Antoniou <pantelis.antoniou@gmail.com> and
   *   Matthew McClintock <msm@freescale.com>
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
8
   * SPDX-License-Identifier:	GPL-2.0+
781e09ee6   Gerald Van Baren   Add a flattened d...
9
10
11
12
13
14
   */
  
  #include <common.h>
  #include <command.h>
  #include <linux/ctype.h>
  #include <linux/types.h>
781e09ee6   Gerald Van Baren   Add a flattened d...
15
  #include <asm/global_data.h>
781e09ee6   Gerald Van Baren   Add a flattened d...
16
  #include <libfdt.h>
64dbbd40c   Gerald Van Baren   Moved fdt command...
17
  #include <fdt_support.h>
a92fd6577   Simon Glass   sandbox: fdt: Sup...
18
  #include <asm/io.h>
781e09ee6   Gerald Van Baren   Add a flattened d...
19
20
  
  #define MAX_LEVEL	32		/* how deeply nested we will go */
fd61e55dd   Gerald Van Baren   Create new fdt bo...
21
  #define SCRATCHPAD	1024		/* bytes of scratchpad memory */
f0a29d433   Joe Hershberger   fdt: Limit printe...
22
23
24
  #ifndef CONFIG_CMD_FDT_MAX_DUMP
  #define CONFIG_CMD_FDT_MAX_DUMP 64
  #endif
781e09ee6   Gerald Van Baren   Add a flattened d...
25
26
27
28
29
  
  /*
   * Global data (for the gd->bd)
   */
  DECLARE_GLOBAL_DATA_PTR;
d14da9130   Simon Glass   fdt: Add a parame...
30
  static int fdt_valid(struct fdt_header **blobp);
54841ab50   Wolfgang Denk   Make sure that ar...
31
  static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
dbaf07ce6   Kumar Gala   Fix warnings from...
32
  static int fdt_print(const char *pathp, char *prop, int depth);
bc80295b6   Joe Hershberger   fdt: Add get comm...
33
  static int is_printable_string(const void *data, int len);
781e09ee6   Gerald Van Baren   Add a flattened d...
34

781e09ee6   Gerald Van Baren   Add a flattened d...
35
  /*
ae9e97fa9   Gerald Van Baren   libfdt: Move the ...
36
37
38
   * The working_fdt points to our working flattened device tree.
   */
  struct fdt_header *working_fdt;
54f9c8669   Kumar Gala   bootm: Set workin...
39
40
  void set_working_fdt_addr(void *addr)
  {
a92fd6577   Simon Glass   sandbox: fdt: Sup...
41
42
43
44
  	void *buf;
  
  	buf = map_sysmem((ulong)addr, 0);
  	working_fdt = buf;
bfc599664   Simon Glass   Update set_workin...
45
  	setenv_addr("fdtaddr", addr);
54f9c8669   Kumar Gala   bootm: Set workin...
46
  }
ae9e97fa9   Gerald Van Baren   libfdt: Move the ...
47
  /*
bc80295b6   Joe Hershberger   fdt: Add get comm...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
   * Get a value from the fdt and format it to be set in the environment
   */
  static int fdt_value_setenv(const void *nodep, int len, const char *var)
  {
  	if (is_printable_string(nodep, len))
  		setenv(var, (void *)nodep);
  	else if (len == 4) {
  		char buf[11];
  
  		sprintf(buf, "0x%08X", *(uint32_t *)nodep);
  		setenv(var, buf);
  	} else if (len%4 == 0 && len <= 20) {
  		/* Needed to print things like sha1 hashes. */
  		char buf[41];
  		int i;
  
  		for (i = 0; i < len; i += sizeof(unsigned int))
  			sprintf(buf + (i * 2), "%08x",
  				*(unsigned int *)(nodep + i));
  		setenv(var, buf);
  	} else {
  		printf("error: unprintable value
  ");
  		return 1;
  	}
  	return 0;
  }
  
  /*
781e09ee6   Gerald Van Baren   Add a flattened d...
77
78
   * Flattened Device Tree command, see the help for parameter definitions.
   */
088f1b199   Kim Phillips   common/cmd_*.c: s...
79
  static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
781e09ee6   Gerald Van Baren   Add a flattened d...
80
  {
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
81
  	if (argc < 2)
4c12eeb8b   Simon Glass   Convert cmd_usage...
82
  		return CMD_RET_USAGE;
781e09ee6   Gerald Van Baren   Add a flattened d...
83

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
84
  	/*
781e09ee6   Gerald Van Baren   Add a flattened d...
85
  	 * Set the address of the fdt
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
86
  	 */
25114033a   Gerald Van Baren   FDT command impro...
87
  	if (argv[1][0] == 'a') {
54f9c8669   Kumar Gala   bootm: Set workin...
88
  		unsigned long addr;
4b5786550   Simon Glass   fdt: Allow fdt co...
89
90
  		int control = 0;
  		struct fdt_header *blob;
781e09ee6   Gerald Van Baren   Add a flattened d...
91
92
93
  		/*
  		 * Set the address [and length] of the fdt.
  		 */
4b5786550   Simon Glass   fdt: Allow fdt co...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  		argc -= 2;
  		argv += 2;
  /* Temporary #ifdef - some archs don't have fdt_blob yet */
  #ifdef CONFIG_OF_CONTROL
  		if (argc && !strcmp(*argv, "-c")) {
  			control = 1;
  			argc--;
  			argv++;
  		}
  #endif
  		if (argc == 0) {
  			if (control)
  				blob = (struct fdt_header *)gd->fdt_blob;
  			else
  				blob = working_fdt;
  			if (!blob || !fdt_valid(&blob))
7dbc38ad9   Kumar Gala   fdt: fdt addr w/o...
110
  				return 1;
4b5786550   Simon Glass   fdt: Allow fdt co...
111
112
113
114
  			printf("The address of the fdt is %#08lx
  ",
  			       control ? (ulong)blob :
  					getenv_hex("fdtaddr", 0));
7dbc38ad9   Kumar Gala   fdt: fdt addr w/o...
115
116
  			return 0;
  		}
4b5786550   Simon Glass   fdt: Allow fdt co...
117
  		addr = simple_strtoul(argv[0], NULL, 16);
a92fd6577   Simon Glass   sandbox: fdt: Sup...
118
  		blob = map_sysmem(addr, 0);
4b5786550   Simon Glass   fdt: Allow fdt co...
119
  		if (!fdt_valid(&blob))
781e09ee6   Gerald Van Baren   Add a flattened d...
120
  			return 1;
4b5786550   Simon Glass   fdt: Allow fdt co...
121
122
123
  		if (control)
  			gd->fdt_blob = blob;
  		else
a92fd6577   Simon Glass   sandbox: fdt: Sup...
124
  			set_working_fdt_addr(blob);
781e09ee6   Gerald Van Baren   Add a flattened d...
125

4b5786550   Simon Glass   fdt: Allow fdt co...
126
  		if (argc >= 2) {
781e09ee6   Gerald Van Baren   Add a flattened d...
127
128
129
130
131
  			int  len;
  			int  err;
  			/*
  			 * Optional new length
  			 */
4b5786550   Simon Glass   fdt: Allow fdt co...
132
133
  			len = simple_strtoul(argv[1], NULL, 16);
  			if (len < fdt_totalsize(blob)) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
134
135
136
  				printf ("New length %d < existing length %d, "
  					"ignoring.
  ",
4b5786550   Simon Glass   fdt: Allow fdt co...
137
  					len, fdt_totalsize(blob));
781e09ee6   Gerald Van Baren   Add a flattened d...
138
139
140
141
  			} else {
  				/*
  				 * Open in place with a new length.
  				 */
4b5786550   Simon Glass   fdt: Allow fdt co...
142
  				err = fdt_open_into(blob, blob, len);
781e09ee6   Gerald Van Baren   Add a flattened d...
143
  				if (err != 0) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
144
145
146
  					printf ("libfdt fdt_open_into(): %s
  ",
  						fdt_strerror(err));
781e09ee6   Gerald Van Baren   Add a flattened d...
147
148
149
  				}
  			}
  		}
e02c94587   Marek Vasut   fdt: Check if the...
150
151
152
153
154
155
156
157
158
159
160
161
162
  		return CMD_RET_SUCCESS;
  	}
  
  	if (!working_fdt) {
  		puts(
  			"No FDT memory address configured. Please configure
  "
  			"the FDT address via \"fdt addr <address>\" command.
  "
  			"Aborting!
  ");
  		return CMD_RET_FAILURE;
  	}
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
163
  	/*
e489b9c07   Kim Phillips   fdt: unshadow glo...
164
  	 * Move the working_fdt
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
165
  	 */
e02c94587   Marek Vasut   fdt: Check if the...
166
  	if (strncmp(argv[1], "mo", 2) == 0) {
781e09ee6   Gerald Van Baren   Add a flattened d...
167
168
169
  		struct fdt_header *newaddr;
  		int  len;
  		int  err;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
170
  		if (argc < 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
171
  			return CMD_RET_USAGE;
781e09ee6   Gerald Van Baren   Add a flattened d...
172
173
174
175
  
  		/*
  		 * Set the address and length of the fdt.
  		 */
e489b9c07   Kim Phillips   fdt: unshadow glo...
176
  		working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
d14da9130   Simon Glass   fdt: Add a parame...
177
  		if (!fdt_valid(&working_fdt))
781e09ee6   Gerald Van Baren   Add a flattened d...
178
  			return 1;
781e09ee6   Gerald Van Baren   Add a flattened d...
179

addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
180
  		newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
6be07cc1c   Gerald Van Baren   Improve fdt move ...
181
182
183
184
185
186
  
  		/*
  		 * If the user specifies a length, use that.  Otherwise use the
  		 * current length.
  		 */
  		if (argc <= 4) {
e489b9c07   Kim Phillips   fdt: unshadow glo...
187
  			len = fdt_totalsize(working_fdt);
6be07cc1c   Gerald Van Baren   Improve fdt move ...
188
189
  		} else {
  			len = simple_strtoul(argv[4], NULL, 16);
e489b9c07   Kim Phillips   fdt: unshadow glo...
190
  			if (len < fdt_totalsize(working_fdt)) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
191
192
193
  				printf ("New length 0x%X < existing length "
  					"0x%X, aborting.
  ",
e489b9c07   Kim Phillips   fdt: unshadow glo...
194
  					len, fdt_totalsize(working_fdt));
6be07cc1c   Gerald Van Baren   Improve fdt move ...
195
196
  				return 1;
  			}
781e09ee6   Gerald Van Baren   Add a flattened d...
197
198
199
200
201
  		}
  
  		/*
  		 * Copy to the new location.
  		 */
e489b9c07   Kim Phillips   fdt: unshadow glo...
202
  		err = fdt_open_into(working_fdt, newaddr, len);
781e09ee6   Gerald Van Baren   Add a flattened d...
203
  		if (err != 0) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
204
205
206
  			printf ("libfdt fdt_open_into(): %s
  ",
  				fdt_strerror(err));
781e09ee6   Gerald Van Baren   Add a flattened d...
207
208
  			return 1;
  		}
e489b9c07   Kim Phillips   fdt: unshadow glo...
209
  		working_fdt = newaddr;
781e09ee6   Gerald Van Baren   Add a flattened d...
210

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
211
  	/*
25114033a   Gerald Van Baren   FDT command impro...
212
  	 * Make a new node
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
213
  	 */
2fb698bf5   Gerald Van Baren   Use strncmp() for...
214
  	} else if (strncmp(argv[1], "mk", 2) == 0) {
25114033a   Gerald Van Baren   FDT command impro...
215
216
217
218
219
220
221
222
  		char *pathp;		/* path */
  		char *nodep;		/* new node to add */
  		int  nodeoffset;	/* node offset from libfdt */
  		int  err;
  
  		/*
  		 * Parameters: Node path, new node to be appended to the path.
  		 */
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
223
  		if (argc < 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
224
  			return CMD_RET_USAGE;
25114033a   Gerald Van Baren   FDT command impro...
225
226
227
  
  		pathp = argv[2];
  		nodep = argv[3];
e489b9c07   Kim Phillips   fdt: unshadow glo...
228
  		nodeoffset = fdt_path_offset (working_fdt, pathp);
25114033a   Gerald Van Baren   FDT command impro...
229
230
231
232
  		if (nodeoffset < 0) {
  			/*
  			 * Not found or something else bad happened.
  			 */
8d04f02f6   Kumar Gala   Update libfdt fro...
233
234
  			printf ("libfdt fdt_path_offset() returned %s
  ",
06e19a077   Gerald Van Baren   For fdt_find_node...
235
  				fdt_strerror(nodeoffset));
25114033a   Gerald Van Baren   FDT command impro...
236
237
  			return 1;
  		}
e489b9c07   Kim Phillips   fdt: unshadow glo...
238
  		err = fdt_add_subnode(working_fdt, nodeoffset, nodep);
25114033a   Gerald Van Baren   FDT command impro...
239
  		if (err < 0) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
240
241
242
  			printf ("libfdt fdt_add_subnode(): %s
  ",
  				fdt_strerror(err));
25114033a   Gerald Van Baren   FDT command impro...
243
244
  			return 1;
  		}
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
245
  	/*
e489b9c07   Kim Phillips   fdt: unshadow glo...
246
  	 * Set the value of a property in the working_fdt.
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
247
  	 */
25114033a   Gerald Van Baren   FDT command impro...
248
  	} else if (argv[1][0] == 's') {
781e09ee6   Gerald Van Baren   Add a flattened d...
249
  		char *pathp;		/* path */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
250
  		char *prop;		/* property */
781e09ee6   Gerald Van Baren   Add a flattened d...
251
  		int  nodeoffset;	/* node offset from libfdt */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
252
253
254
  		static char data[SCRATCHPAD];	/* storage for the property */
  		int  len;		/* new length of the property */
  		int  ret;		/* return value */
781e09ee6   Gerald Van Baren   Add a flattened d...
255
256
  
  		/*
ea6d8be15   Gerald Van Baren   Support setting F...
257
  		 * Parameters: Node path, property, optional value.
781e09ee6   Gerald Van Baren   Add a flattened d...
258
  		 */
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
259
  		if (argc < 4)
4c12eeb8b   Simon Glass   Convert cmd_usage...
260
  			return CMD_RET_USAGE;
781e09ee6   Gerald Van Baren   Add a flattened d...
261
262
263
  
  		pathp  = argv[2];
  		prop   = argv[3];
ea6d8be15   Gerald Van Baren   Support setting F...
264
265
266
  		if (argc == 4) {
  			len = 0;
  		} else {
4abd844d8   Andy Fleming   Fix fdt set comma...
267
  			ret = fdt_parse_prop(&argv[4], argc - 4, data, &len);
ea6d8be15   Gerald Van Baren   Support setting F...
268
269
270
  			if (ret != 0)
  				return ret;
  		}
781e09ee6   Gerald Van Baren   Add a flattened d...
271

e489b9c07   Kim Phillips   fdt: unshadow glo...
272
  		nodeoffset = fdt_path_offset (working_fdt, pathp);
25114033a   Gerald Van Baren   FDT command impro...
273
  		if (nodeoffset < 0) {
781e09ee6   Gerald Van Baren   Add a flattened d...
274
  			/*
25114033a   Gerald Van Baren   FDT command impro...
275
  			 * Not found or something else bad happened.
781e09ee6   Gerald Van Baren   Add a flattened d...
276
  			 */
8d04f02f6   Kumar Gala   Update libfdt fro...
277
278
  			printf ("libfdt fdt_path_offset() returned %s
  ",
06e19a077   Gerald Van Baren   For fdt_find_node...
279
  				fdt_strerror(nodeoffset));
781e09ee6   Gerald Van Baren   Add a flattened d...
280
  			return 1;
25114033a   Gerald Van Baren   FDT command impro...
281
  		}
25114033a   Gerald Van Baren   FDT command impro...
282

e489b9c07   Kim Phillips   fdt: unshadow glo...
283
  		ret = fdt_setprop(working_fdt, nodeoffset, prop, data, len);
25114033a   Gerald Van Baren   FDT command impro...
284
285
286
287
  		if (ret < 0) {
  			printf ("libfdt fdt_setprop(): %s
  ", fdt_strerror(ret));
  			return 1;
781e09ee6   Gerald Van Baren   Add a flattened d...
288
  		}
bc80295b6   Joe Hershberger   fdt: Add get comm...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  	/********************************************************************
  	 * Get the value of a property in the working_fdt.
  	 ********************************************************************/
  	} else if (argv[1][0] == 'g') {
  		char *subcmd;		/* sub-command */
  		char *pathp;		/* path */
  		char *prop;		/* property */
  		char *var;		/* variable to store result */
  		int  nodeoffset;	/* node offset from libfdt */
  		const void *nodep;	/* property node pointer */
  		int  len = 0;		/* new length of the property */
  
  		/*
  		 * Parameters: Node path, property, optional value.
  		 */
  		if (argc < 5)
  			return CMD_RET_USAGE;
  
  		subcmd = argv[2];
  
  		if (argc < 6 && subcmd[0] != 's')
  			return CMD_RET_USAGE;
  
  		var    = argv[3];
  		pathp  = argv[4];
  		prop   = argv[5];
  
  		nodeoffset = fdt_path_offset(working_fdt, pathp);
  		if (nodeoffset < 0) {
  			/*
  			 * Not found or something else bad happened.
  			 */
  			printf("libfdt fdt_path_offset() returned %s
  ",
  				fdt_strerror(nodeoffset));
  			return 1;
  		}
  
  		if (subcmd[0] == 'n' || (subcmd[0] == 's' && argc == 5)) {
  			int reqIndex = -1;
  			int startDepth = fdt_node_depth(
  				working_fdt, nodeoffset);
  			int curDepth = startDepth;
  			int curIndex = -1;
  			int nextNodeOffset = fdt_next_node(
  				working_fdt, nodeoffset, &curDepth);
  
  			if (subcmd[0] == 'n')
  				reqIndex = simple_strtoul(argv[5], NULL, 16);
  
  			while (curDepth > startDepth) {
  				if (curDepth == startDepth + 1)
  					curIndex++;
  				if (subcmd[0] == 'n' && curIndex == reqIndex) {
  					const char *nodeName = fdt_get_name(
  					    working_fdt, nextNodeOffset, NULL);
  
  					setenv(var, (char *)nodeName);
  					return 0;
  				}
  				nextNodeOffset = fdt_next_node(
  					working_fdt, nextNodeOffset, &curDepth);
  				if (nextNodeOffset < 0)
  					break;
  			}
  			if (subcmd[0] == 's') {
  				/* get the num nodes at this level */
bfc599664   Simon Glass   Update set_workin...
356
  				setenv_ulong(var, curIndex + 1);
bc80295b6   Joe Hershberger   fdt: Add get comm...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
  			} else {
  				/* node index not found */
  				printf("libfdt node not found
  ");
  				return 1;
  			}
  		} else {
  			nodep = fdt_getprop(
  				working_fdt, nodeoffset, prop, &len);
  			if (len == 0) {
  				/* no property value */
  				setenv(var, "");
  				return 0;
  			} else if (len > 0) {
  				if (subcmd[0] == 'v') {
  					int ret;
  
  					ret = fdt_value_setenv(nodep, len, var);
  					if (ret != 0)
  						return ret;
  				} else if (subcmd[0] == 'a') {
  					/* Get address */
  					char buf[11];
085b9c3a1   Tom Rini   cmd_fdt.c: Use %p...
380
  					sprintf(buf, "0x%p", nodep);
bc80295b6   Joe Hershberger   fdt: Add get comm...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  					setenv(var, buf);
  				} else if (subcmd[0] == 's') {
  					/* Get size */
  					char buf[11];
  
  					sprintf(buf, "0x%08X", len);
  					setenv(var, buf);
  				} else
  					return CMD_RET_USAGE;
  				return 0;
  			} else {
  				printf("libfdt fdt_getprop(): %s
  ",
  					fdt_strerror(len));
  				return 1;
  			}
  		}
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
398
  	/*
781e09ee6   Gerald Van Baren   Add a flattened d...
399
  	 * Print (recursive) / List (single level)
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
400
  	 */
25114033a   Gerald Van Baren   FDT command impro...
401
  	} else if ((argv[1][0] == 'p') || (argv[1][0] == 'l')) {
781e09ee6   Gerald Van Baren   Add a flattened d...
402
403
  		int depth = MAX_LEVEL;	/* how deep to print */
  		char *pathp;		/* path */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
404
405
  		char *prop;		/* property */
  		int  ret;		/* return value */
f738b4a75   Kumar Gala   Make no options t...
406
  		static char root[2] = "/";
781e09ee6   Gerald Van Baren   Add a flattened d...
407
408
409
410
  
  		/*
  		 * list is an alias for print, but limited to 1 level
  		 */
25114033a   Gerald Van Baren   FDT command impro...
411
  		if (argv[1][0] == 'l') {
781e09ee6   Gerald Van Baren   Add a flattened d...
412
413
414
415
416
417
418
  			depth = 1;
  		}
  
  		/*
  		 * Get the starting path.  The root node is an oddball,
  		 * the offset is zero and has no name.
  		 */
f738b4a75   Kumar Gala   Make no options t...
419
420
421
422
  		if (argc == 2)
  			pathp = root;
  		else
  			pathp = argv[2];
781e09ee6   Gerald Van Baren   Add a flattened d...
423
424
425
426
  		if (argc > 3)
  			prop = argv[3];
  		else
  			prop = NULL;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
427
428
429
  		ret = fdt_print(pathp, prop, depth);
  		if (ret != 0)
  			return ret;
781e09ee6   Gerald Van Baren   Add a flattened d...
430

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
431
  	/*
781e09ee6   Gerald Van Baren   Add a flattened d...
432
  	 * Remove a property/node
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
433
  	 */
2fb698bf5   Gerald Van Baren   Use strncmp() for...
434
  	} else if (strncmp(argv[1], "rm", 2) == 0) {
781e09ee6   Gerald Van Baren   Add a flattened d...
435
436
437
438
439
440
441
  		int  nodeoffset;	/* node offset from libfdt */
  		int  err;
  
  		/*
  		 * Get the path.  The root node is an oddball, the offset
  		 * is zero and has no name.
  		 */
e489b9c07   Kim Phillips   fdt: unshadow glo...
442
  		nodeoffset = fdt_path_offset (working_fdt, argv[2]);
25114033a   Gerald Van Baren   FDT command impro...
443
444
445
446
  		if (nodeoffset < 0) {
  			/*
  			 * Not found or something else bad happened.
  			 */
8d04f02f6   Kumar Gala   Update libfdt fro...
447
448
  			printf ("libfdt fdt_path_offset() returned %s
  ",
06e19a077   Gerald Van Baren   For fdt_find_node...
449
  				fdt_strerror(nodeoffset));
25114033a   Gerald Van Baren   FDT command impro...
450
  			return 1;
781e09ee6   Gerald Van Baren   Add a flattened d...
451
452
453
454
455
456
  		}
  		/*
  		 * Do the delete.  A fourth parameter means delete a property,
  		 * otherwise delete the node.
  		 */
  		if (argc > 3) {
e489b9c07   Kim Phillips   fdt: unshadow glo...
457
  			err = fdt_delprop(working_fdt, nodeoffset, argv[3]);
781e09ee6   Gerald Van Baren   Add a flattened d...
458
  			if (err < 0) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
459
460
461
  				printf("libfdt fdt_delprop():  %s
  ",
  					fdt_strerror(err));
781e09ee6   Gerald Van Baren   Add a flattened d...
462
463
464
  				return err;
  			}
  		} else {
e489b9c07   Kim Phillips   fdt: unshadow glo...
465
  			err = fdt_del_node(working_fdt, nodeoffset);
781e09ee6   Gerald Van Baren   Add a flattened d...
466
  			if (err < 0) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
467
468
469
  				printf("libfdt fdt_del_node():  %s
  ",
  					fdt_strerror(err));
781e09ee6   Gerald Van Baren   Add a flattened d...
470
471
472
  				return err;
  			}
  		}
804887e60   Kumar Gala   Add sub-commands ...
473

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
474
  	/*
804887e60   Kumar Gala   Add sub-commands ...
475
  	 * Display header info
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
476
  	 */
804887e60   Kumar Gala   Add sub-commands ...
477
  	} else if (argv[1][0] == 'h') {
e489b9c07   Kim Phillips   fdt: unshadow glo...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  		u32 version = fdt_version(working_fdt);
  		printf("magic:\t\t\t0x%x
  ", fdt_magic(working_fdt));
  		printf("totalsize:\t\t0x%x (%d)
  ", fdt_totalsize(working_fdt),
  		       fdt_totalsize(working_fdt));
  		printf("off_dt_struct:\t\t0x%x
  ",
  		       fdt_off_dt_struct(working_fdt));
  		printf("off_dt_strings:\t\t0x%x
  ",
  		       fdt_off_dt_strings(working_fdt));
  		printf("off_mem_rsvmap:\t\t0x%x
  ",
  		       fdt_off_mem_rsvmap(working_fdt));
804887e60   Kumar Gala   Add sub-commands ...
493
494
  		printf("version:\t\t%d
  ", version);
e489b9c07   Kim Phillips   fdt: unshadow glo...
495
496
497
  		printf("last_comp_version:\t%d
  ",
  		       fdt_last_comp_version(working_fdt));
804887e60   Kumar Gala   Add sub-commands ...
498
499
500
  		if (version >= 2)
  			printf("boot_cpuid_phys:\t0x%x
  ",
e489b9c07   Kim Phillips   fdt: unshadow glo...
501
  				fdt_boot_cpuid_phys(working_fdt));
804887e60   Kumar Gala   Add sub-commands ...
502
503
504
  		if (version >= 3)
  			printf("size_dt_strings:\t0x%x
  ",
e489b9c07   Kim Phillips   fdt: unshadow glo...
505
  				fdt_size_dt_strings(working_fdt));
804887e60   Kumar Gala   Add sub-commands ...
506
507
508
  		if (version >= 17)
  			printf("size_dt_struct:\t\t0x%x
  ",
e489b9c07   Kim Phillips   fdt: unshadow glo...
509
510
511
512
  				fdt_size_dt_struct(working_fdt));
  		printf("number mem_rsv:\t\t0x%x
  ",
  		       fdt_num_mem_rsv(working_fdt));
804887e60   Kumar Gala   Add sub-commands ...
513
514
  		printf("
  ");
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
515
  	/*
804887e60   Kumar Gala   Add sub-commands ...
516
  	 * Set boot cpu id
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
517
  	 */
2fb698bf5   Gerald Van Baren   Use strncmp() for...
518
  	} else if (strncmp(argv[1], "boo", 3) == 0) {
804887e60   Kumar Gala   Add sub-commands ...
519
  		unsigned long tmp = simple_strtoul(argv[2], NULL, 16);
e489b9c07   Kim Phillips   fdt: unshadow glo...
520
  		fdt_set_boot_cpuid_phys(working_fdt, tmp);
804887e60   Kumar Gala   Add sub-commands ...
521

47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
522
  	/*
804887e60   Kumar Gala   Add sub-commands ...
523
  	 * memory command
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
524
  	 */
2fb698bf5   Gerald Van Baren   Use strncmp() for...
525
  	} else if (strncmp(argv[1], "me", 2) == 0) {
804887e60   Kumar Gala   Add sub-commands ...
526
527
  		uint64_t addr, size;
  		int err;
4b142febf   Heiko Schocher   common: delete CO...
528
529
  		addr = simple_strtoull(argv[2], NULL, 16);
  		size = simple_strtoull(argv[3], NULL, 16);
e489b9c07   Kim Phillips   fdt: unshadow glo...
530
  		err = fdt_fixup_memory(working_fdt, addr, size);
804887e60   Kumar Gala   Add sub-commands ...
531
532
  		if (err < 0)
  			return err;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
533
  	/*
804887e60   Kumar Gala   Add sub-commands ...
534
  	 * mem reserve commands
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
535
  	 */
2fb698bf5   Gerald Van Baren   Use strncmp() for...
536
  	} else if (strncmp(argv[1], "rs", 2) == 0) {
804887e60   Kumar Gala   Add sub-commands ...
537
538
  		if (argv[2][0] == 'p') {
  			uint64_t addr, size;
e489b9c07   Kim Phillips   fdt: unshadow glo...
539
  			int total = fdt_num_mem_rsv(working_fdt);
804887e60   Kumar Gala   Add sub-commands ...
540
541
542
543
544
545
546
  			int j, err;
  			printf("index\t\t   start\t\t    size
  ");
  			printf("-------------------------------"
  				"-----------------
  ");
  			for (j = 0; j < total; j++) {
e489b9c07   Kim Phillips   fdt: unshadow glo...
547
  				err = fdt_get_mem_rsv(working_fdt, j, &addr, &size);
804887e60   Kumar Gala   Add sub-commands ...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  				if (err < 0) {
  					printf("libfdt fdt_get_mem_rsv():  %s
  ",
  							fdt_strerror(err));
  					return err;
  				}
  				printf("    %x\t%08x%08x\t%08x%08x
  ", j,
  					(u32)(addr >> 32),
  					(u32)(addr & 0xffffffff),
  					(u32)(size >> 32),
  					(u32)(size & 0xffffffff));
  			}
  		} else if (argv[2][0] == 'a') {
  			uint64_t addr, size;
  			int err;
804887e60   Kumar Gala   Add sub-commands ...
564
565
  			addr = simple_strtoull(argv[3], NULL, 16);
  			size = simple_strtoull(argv[4], NULL, 16);
e489b9c07   Kim Phillips   fdt: unshadow glo...
566
  			err = fdt_add_mem_rsv(working_fdt, addr, size);
804887e60   Kumar Gala   Add sub-commands ...
567
568
569
570
571
572
573
574
575
  
  			if (err < 0) {
  				printf("libfdt fdt_add_mem_rsv():  %s
  ",
  					fdt_strerror(err));
  				return err;
  			}
  		} else if (argv[2][0] == 'd') {
  			unsigned long idx = simple_strtoul(argv[3], NULL, 16);
e489b9c07   Kim Phillips   fdt: unshadow glo...
576
  			int err = fdt_del_mem_rsv(working_fdt, idx);
804887e60   Kumar Gala   Add sub-commands ...
577
578
579
580
581
582
583
584
585
  
  			if (err < 0) {
  				printf("libfdt fdt_del_mem_rsv():  %s
  ",
  					fdt_strerror(err));
  				return err;
  			}
  		} else {
  			/* Unrecognized command */
4c12eeb8b   Simon Glass   Convert cmd_usage...
586
  			return CMD_RET_USAGE;
804887e60   Kumar Gala   Add sub-commands ...
587
  		}
99dffca3b   Kim Phillips   fdt: allow for bu...
588
  	}
fd61e55dd   Gerald Van Baren   Create new fdt bo...
589
  #ifdef CONFIG_OF_BOARD_SETUP
99dffca3b   Kim Phillips   fdt: allow for bu...
590
  	/* Call the board-specific fixup routine */
2fb698bf5   Gerald Van Baren   Use strncmp() for...
591
  	else if (strncmp(argv[1], "boa", 3) == 0)
e489b9c07   Kim Phillips   fdt: unshadow glo...
592
  		ft_board_setup(working_fdt, gd->bd);
fd61e55dd   Gerald Van Baren   Create new fdt bo...
593
  #endif
99dffca3b   Kim Phillips   fdt: allow for bu...
594
  	/* Create a chosen node */
f953d99fd   Kumar Gala   fdt: added the ab...
595
596
  	else if (argv[1][0] == 'c') {
  		unsigned long initrd_start = 0, initrd_end = 0;
47e26b1bf   Wolfgang Denk   cmd_usage(): simp...
597
  		if ((argc != 2) && (argc != 4))
4c12eeb8b   Simon Glass   Convert cmd_usage...
598
  			return CMD_RET_USAGE;
f953d99fd   Kumar Gala   fdt: added the ab...
599
600
601
602
603
  
  		if (argc == 4) {
  			initrd_start = simple_strtoul(argv[2], NULL, 16);
  			initrd_end = simple_strtoul(argv[3], NULL, 16);
  		}
56844a22b   Heiko Schocher   powerpc: Fix boot...
604
605
  		fdt_chosen(working_fdt, 1);
  		fdt_initrd(working_fdt, initrd_start, initrd_end, 1);
40afac22a   Kumar Gala   fdt: Added resize...
606
607
608
609
610
611
  	}
  	/* resize the fdt */
  	else if (strncmp(argv[1], "re", 2) == 0) {
  		fdt_resize(working_fdt);
  	}
  	else {
99dffca3b   Kim Phillips   fdt: allow for bu...
612
  		/* Unrecognized command */
4c12eeb8b   Simon Glass   Convert cmd_usage...
613
  		return CMD_RET_USAGE;
781e09ee6   Gerald Van Baren   Add a flattened d...
614
615
616
617
  	}
  
  	return 0;
  }
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
618
  /****************************************************************************/
781e09ee6   Gerald Van Baren   Add a flattened d...
619

d14da9130   Simon Glass   fdt: Add a parame...
620
621
622
623
624
625
626
  /**
   * fdt_valid() - Check if an FDT is valid. If not, change it to NULL
   *
   * @blobp: Pointer to FDT pointer
   * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL)
   */
  static int fdt_valid(struct fdt_header **blobp)
781e09ee6   Gerald Van Baren   Add a flattened d...
627
  {
d14da9130   Simon Glass   fdt: Add a parame...
628
629
  	const void *blob = *blobp;
  	int err;
64dbbd40c   Gerald Van Baren   Moved fdt command...
630

d14da9130   Simon Glass   fdt: Add a parame...
631
  	if (blob == NULL) {
64dbbd40c   Gerald Van Baren   Moved fdt command...
632
633
  		printf ("The address of the fdt is invalid (NULL).
  ");
781e09ee6   Gerald Van Baren   Add a flattened d...
634
635
  		return 0;
  	}
64dbbd40c   Gerald Van Baren   Moved fdt command...
636

d14da9130   Simon Glass   fdt: Add a parame...
637
  	err = fdt_check_header(blob);
64dbbd40c   Gerald Van Baren   Moved fdt command...
638
639
640
641
  	if (err == 0)
  		return 1;	/* valid */
  
  	if (err < 0) {
25114033a   Gerald Van Baren   FDT command impro...
642
  		printf("libfdt fdt_check_header(): %s", fdt_strerror(err));
64dbbd40c   Gerald Van Baren   Moved fdt command...
643
644
645
646
  		/*
  		 * Be more informative on bad version.
  		 */
  		if (err == -FDT_ERR_BADVERSION) {
d14da9130   Simon Glass   fdt: Add a parame...
647
  			if (fdt_version(blob) <
e489b9c07   Kim Phillips   fdt: unshadow glo...
648
  			    FDT_FIRST_SUPPORTED_VERSION) {
dc4b0b38d   Andrew Klossner   Fix printf errors.
649
  				printf (" - too old, fdt %d < %d",
d14da9130   Simon Glass   fdt: Add a parame...
650
  					fdt_version(blob),
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
651
  					FDT_FIRST_SUPPORTED_VERSION);
64dbbd40c   Gerald Van Baren   Moved fdt command...
652
  			}
d14da9130   Simon Glass   fdt: Add a parame...
653
  			if (fdt_last_comp_version(blob) >
e489b9c07   Kim Phillips   fdt: unshadow glo...
654
  			    FDT_LAST_SUPPORTED_VERSION) {
dc4b0b38d   Andrew Klossner   Fix printf errors.
655
  				printf (" - too new, fdt %d > %d",
d14da9130   Simon Glass   fdt: Add a parame...
656
  					fdt_version(blob),
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
657
  					FDT_LAST_SUPPORTED_VERSION);
64dbbd40c   Gerald Van Baren   Moved fdt command...
658
  			}
64dbbd40c   Gerald Van Baren   Moved fdt command...
659
660
661
  		}
  		printf("
  ");
d14da9130   Simon Glass   fdt: Add a parame...
662
  		*blobp = NULL;
781e09ee6   Gerald Van Baren   Add a flattened d...
663
664
665
666
  		return 0;
  	}
  	return 1;
  }
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
667
  /****************************************************************************/
781e09ee6   Gerald Van Baren   Add a flattened d...
668
669
  
  /*
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
670
   * Parse the user's input, partially heuristic.  Valid formats:
4abd844d8   Andy Fleming   Fix fdt set comma...
671
   * <0x00112233 4 05>	- an array of cells.  Numbers follow standard
53677ef18   Wolfgang Denk   Big white-space c...
672
   *			C conventions.
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
673
674
675
676
   * [00 11 22 .. nn] - byte stream
   * "string"	- If the the value doesn't start with "<" or "[", it is
   *			treated as a string.  Note that the quotes are
   *			stripped by the parser before we get the string.
4abd844d8   Andy Fleming   Fix fdt set comma...
677
   * newval: An array of strings containing the new property as specified
53677ef18   Wolfgang Denk   Big white-space c...
678
   *	on the command line
4abd844d8   Andy Fleming   Fix fdt set comma...
679
680
681
   * count: The number of strings in the array
   * data: A bytestream to be placed in the property
   * len: The length of the resulting bytestream
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
682
   */
54841ab50   Wolfgang Denk   Make sure that ar...
683
  static int fdt_parse_prop(char * const *newval, int count, char *data, int *len)
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
684
685
  {
  	char *cp;		/* temporary char pointer */
4abd844d8   Andy Fleming   Fix fdt set comma...
686
  	char *newp;		/* temporary newval char pointer */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
687
  	unsigned long tmp;	/* holds converted values */
4abd844d8   Andy Fleming   Fix fdt set comma...
688
  	int stridx = 0;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
689

4abd844d8   Andy Fleming   Fix fdt set comma...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
  	*len = 0;
  	newp = newval[0];
  
  	/* An array of cells */
  	if (*newp == '<') {
  		newp++;
  		while ((*newp != '>') && (stridx < count)) {
  			/*
  			 * Keep searching until we find that last ">"
  			 * That way users don't have to escape the spaces
  			 */
  			if (*newp == '\0') {
  				newp = newval[++stridx];
  				continue;
  			}
  
  			cp = newp;
  			tmp = simple_strtoul(cp, &newp, 0);
088f1b199   Kim Phillips   common/cmd_*.c: s...
708
  			*(__be32 *)data = __cpu_to_be32(tmp);
4abd844d8   Andy Fleming   Fix fdt set comma...
709
710
711
712
713
  			data  += 4;
  			*len += 4;
  
  			/* If the ptr didn't advance, something went wrong */
  			if ((newp - cp) <= 0) {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
714
715
716
717
718
  				printf("Sorry, I could not convert \"%s\"
  ",
  					cp);
  				return 1;
  			}
4abd844d8   Andy Fleming   Fix fdt set comma...
719
720
721
  
  			while (*newp == ' ')
  				newp++;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
722
  		}
4abd844d8   Andy Fleming   Fix fdt set comma...
723
724
725
726
  
  		if (*newp != '>') {
  			printf("Unexpected character '%c'
  ", *newp);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
727
728
  			return 1;
  		}
4abd844d8   Andy Fleming   Fix fdt set comma...
729
  	} else if (*newp == '[') {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
730
731
732
  		/*
  		 * Byte stream.  Convert the values.
  		 */
4abd844d8   Andy Fleming   Fix fdt set comma...
733
  		newp++;
6e748ea00   Ken MacLeod   cmd_fdt.c: fix pa...
734
  		while ((stridx < count) && (*newp != ']')) {
4abd844d8   Andy Fleming   Fix fdt set comma...
735
736
  			while (*newp == ' ')
  				newp++;
6e748ea00   Ken MacLeod   cmd_fdt.c: fix pa...
737
  			if (*newp == '\0') {
4abd844d8   Andy Fleming   Fix fdt set comma...
738
  				newp = newval[++stridx];
6e748ea00   Ken MacLeod   cmd_fdt.c: fix pa...
739
740
741
742
743
744
745
  				continue;
  			}
  			if (!isxdigit(*newp))
  				break;
  			tmp = simple_strtoul(newp, &newp, 16);
  			*data++ = tmp & 0xFF;
  			*len    = *len + 1;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
746
  		}
4abd844d8   Andy Fleming   Fix fdt set comma...
747
  		if (*newp != ']') {
dc4b0b38d   Andrew Klossner   Fix printf errors.
748
749
  			printf("Unexpected character '%c'
  ", *newp);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
750
751
752
753
  			return 1;
  		}
  	} else {
  		/*
6e748ea00   Ken MacLeod   cmd_fdt.c: fix pa...
754
755
756
  		 * Assume it is one or more strings.  Copy it into our
  		 * data area for convenience (including the
  		 * terminating '\0's).
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
757
  		 */
4abd844d8   Andy Fleming   Fix fdt set comma...
758
  		while (stridx < count) {
6e748ea00   Ken MacLeod   cmd_fdt.c: fix pa...
759
  			size_t length = strlen(newp) + 1;
4abd844d8   Andy Fleming   Fix fdt set comma...
760
  			strcpy(data, newp);
6e748ea00   Ken MacLeod   cmd_fdt.c: fix pa...
761
762
  			data += length;
  			*len += length;
4abd844d8   Andy Fleming   Fix fdt set comma...
763
764
  			newp = newval[++stridx];
  		}
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
765
766
767
768
769
770
771
772
  	}
  	return 0;
  }
  
  /****************************************************************************/
  
  /*
   * Heuristic to guess if this is a string or concatenated strings.
781e09ee6   Gerald Van Baren   Add a flattened d...
773
774
775
776
777
778
779
780
781
   */
  
  static int is_printable_string(const void *data, int len)
  {
  	const char *s = data;
  
  	/* zero length is not */
  	if (len == 0)
  		return 0;
8805beec8   Joe Hershberger   fdt: Identify scr...
782
783
784
785
  	/* must terminate with zero or '
  ' */
  	if (s[len - 1] != '\0' && s[len - 1] != '
  ')
781e09ee6   Gerald Van Baren   Add a flattened d...
786
787
788
  		return 0;
  
  	/* printable or a null byte (concatenated strings) */
8805beec8   Joe Hershberger   fdt: Identify scr...
789
  	while (((*s == '\0') || isprint(*s) || isspace(*s)) && (len > 0)) {
781e09ee6   Gerald Van Baren   Add a flattened d...
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
  		/*
  		 * If we see a null, there are three possibilities:
  		 * 1) If len == 1, it is the end of the string, printable
  		 * 2) Next character also a null, not printable.
  		 * 3) Next character not a null, continue to check.
  		 */
  		if (s[0] == '\0') {
  			if (len == 1)
  				return 1;
  			if (s[1] == '\0')
  				return 0;
  		}
  		s++;
  		len--;
  	}
  
  	/* Not the null termination, or not done yet: not printable */
  	if (*s != '\0' || (len != 0))
  		return 0;
  
  	return 1;
  }
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
812
813
814
815
816
817
  
  /*
   * Print the property in the best format, a heuristic guess.  Print as
   * a string, concatenated strings, a byte, word, double word, or (if all
   * else fails) it is printed as a stream of bytes.
   */
781e09ee6   Gerald Van Baren   Add a flattened d...
818
819
820
  static void print_data(const void *data, int len)
  {
  	int j;
781e09ee6   Gerald Van Baren   Add a flattened d...
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
  
  	/* no data, don't print */
  	if (len == 0)
  		return;
  
  	/*
  	 * It is a string, but it may have multiple strings (embedded '\0's).
  	 */
  	if (is_printable_string(data, len)) {
  		puts("\"");
  		j = 0;
  		while (j < len) {
  			if (j > 0)
  				puts("\", \"");
  			puts(data);
  			j    += strlen(data) + 1;
  			data += strlen(data) + 1;
  		}
  		puts("\"");
  		return;
  	}
4abd844d8   Andy Fleming   Fix fdt set comma...
842
  	if ((len %4) == 0) {
f0a29d433   Joe Hershberger   fdt: Limit printe...
843
  		if (len > CONFIG_CMD_FDT_MAX_DUMP)
085b9c3a1   Tom Rini   cmd_fdt.c: Use %p...
844
  			printf("* 0x%p [0x%08x]", data, len);
f0a29d433   Joe Hershberger   fdt: Limit printe...
845
  		else {
088f1b199   Kim Phillips   common/cmd_*.c: s...
846
  			const __be32 *p;
f0a29d433   Joe Hershberger   fdt: Limit printe...
847
848
849
850
851
852
853
  
  			printf("<");
  			for (j = 0, p = data; j < len/4; j++)
  				printf("0x%08x%s", fdt32_to_cpu(p[j]),
  					j < (len/4 - 1) ? " " : "");
  			printf(">");
  		}
4abd844d8   Andy Fleming   Fix fdt set comma...
854
  	} else { /* anything else... hexdump */
f0a29d433   Joe Hershberger   fdt: Limit printe...
855
  		if (len > CONFIG_CMD_FDT_MAX_DUMP)
085b9c3a1   Tom Rini   cmd_fdt.c: Use %p...
856
  			printf("* 0x%p [0x%08x]", data, len);
f0a29d433   Joe Hershberger   fdt: Limit printe...
857
858
859
860
861
862
863
864
  		else {
  			const u8 *s;
  
  			printf("[");
  			for (j = 0, s = data; j < len; j++)
  				printf("%02x%s", s[j], j < len - 1 ? " " : "");
  			printf("]");
  		}
781e09ee6   Gerald Van Baren   Add a flattened d...
865
866
  	}
  }
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
867
868
869
  /****************************************************************************/
  
  /*
e489b9c07   Kim Phillips   fdt: unshadow glo...
870
   * Recursively print (a portion of) the working_fdt.  The depth parameter
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
871
872
   * determines how deeply nested the fdt is printed.
   */
dbaf07ce6   Kumar Gala   Fix warnings from...
873
  static int fdt_print(const char *pathp, char *prop, int depth)
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
874
  {
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
875
876
877
  	static char tabs[MAX_LEVEL+1] =
  		"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
  		"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
dbaf07ce6   Kumar Gala   Fix warnings from...
878
  	const void *nodep;	/* property node pointer */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
879
880
881
882
883
  	int  nodeoffset;	/* node offset from libfdt */
  	int  nextoffset;	/* next node offset from libfdt */
  	uint32_t tag;		/* tag */
  	int  len;		/* length of the property */
  	int  level = 0;		/* keep track of nesting level */
916235281   Gerald Van Baren   Fix fdt printing ...
884
  	const struct fdt_property *fdt_prop;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
885

e489b9c07   Kim Phillips   fdt: unshadow glo...
886
  	nodeoffset = fdt_path_offset (working_fdt, pathp);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
887
888
889
890
  	if (nodeoffset < 0) {
  		/*
  		 * Not found or something else bad happened.
  		 */
8d04f02f6   Kumar Gala   Update libfdt fro...
891
892
  		printf ("libfdt fdt_path_offset() returned %s
  ",
06e19a077   Gerald Van Baren   For fdt_find_node...
893
  			fdt_strerror(nodeoffset));
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
894
895
896
897
898
899
900
  		return 1;
  	}
  	/*
  	 * The user passed in a property as well as node path.
  	 * Print only the given property and then return.
  	 */
  	if (prop) {
e489b9c07   Kim Phillips   fdt: unshadow glo...
901
  		nodep = fdt_getprop (working_fdt, nodeoffset, prop, &len);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
902
903
904
905
906
907
  		if (len == 0) {
  			/* no property value */
  			printf("%s %s
  ", pathp, prop);
  			return 0;
  		} else if (len > 0) {
28f384b17   Gerald Van Baren   Add spaces around...
908
  			printf("%s = ", prop);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
  			print_data (nodep, len);
  			printf("
  ");
  			return 0;
  		} else {
  			printf ("libfdt fdt_getprop(): %s
  ",
  				fdt_strerror(len));
  			return 1;
  		}
  	}
  
  	/*
  	 * The user passed in a node path and no property,
  	 * print the node and all subnodes.
  	 */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
925
  	while(level >= 0) {
e489b9c07   Kim Phillips   fdt: unshadow glo...
926
  		tag = fdt_next_tag(working_fdt, nodeoffset, &nextoffset);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
927
928
  		switch(tag) {
  		case FDT_BEGIN_NODE:
e489b9c07   Kim Phillips   fdt: unshadow glo...
929
  			pathp = fdt_get_name(working_fdt, nodeoffset, NULL);
916235281   Gerald Van Baren   Fix fdt printing ...
930
931
932
933
934
  			if (level <= depth) {
  				if (pathp == NULL)
  					pathp = "/* NULL pointer error */";
  				if (*pathp == '\0')
  					pathp = "/";	/* root is nameless */
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
935
936
937
  				printf("%s%s {
  ",
  					&tabs[MAX_LEVEL - level], pathp);
916235281   Gerald Van Baren   Fix fdt printing ...
938
  			}
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
939
  			level++;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
940
  			if (level >= MAX_LEVEL) {
916235281   Gerald Van Baren   Fix fdt printing ...
941
942
  				printf("Nested too deep, aborting.
  ");
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
943
944
945
946
947
  				return 1;
  			}
  			break;
  		case FDT_END_NODE:
  			level--;
916235281   Gerald Van Baren   Fix fdt printing ...
948
  			if (level <= depth)
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
949
950
951
952
953
954
955
  				printf("%s};
  ", &tabs[MAX_LEVEL - level]);
  			if (level == 0) {
  				level = -1;		/* exit the loop */
  			}
  			break;
  		case FDT_PROP:
e489b9c07   Kim Phillips   fdt: unshadow glo...
956
  			fdt_prop = fdt_offset_ptr(working_fdt, nodeoffset,
916235281   Gerald Van Baren   Fix fdt printing ...
957
  					sizeof(*fdt_prop));
e489b9c07   Kim Phillips   fdt: unshadow glo...
958
  			pathp    = fdt_string(working_fdt,
916235281   Gerald Van Baren   Fix fdt printing ...
959
960
961
  					fdt32_to_cpu(fdt_prop->nameoff));
  			len      = fdt32_to_cpu(fdt_prop->len);
  			nodep    = fdt_prop->data;
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
962
963
964
965
966
967
968
  			if (len < 0) {
  				printf ("libfdt fdt_getprop(): %s
  ",
  					fdt_strerror(len));
  				return 1;
  			} else if (len == 0) {
  				/* the property has no value */
916235281   Gerald Van Baren   Fix fdt printing ...
969
  				if (level <= depth)
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
970
971
972
973
974
  					printf("%s%s;
  ",
  						&tabs[MAX_LEVEL - level],
  						pathp);
  			} else {
916235281   Gerald Van Baren   Fix fdt printing ...
975
  				if (level <= depth) {
28f384b17   Gerald Van Baren   Add spaces around...
976
  					printf("%s%s = ",
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
977
978
979
980
981
982
983
984
985
  						&tabs[MAX_LEVEL - level],
  						pathp);
  					print_data (nodep, len);
  					printf(";
  ");
  				}
  			}
  			break;
  		case FDT_NOP:
dc4b0b38d   Andrew Klossner   Fix printf errors.
986
987
  			printf("%s/* NOP */
  ", &tabs[MAX_LEVEL - level]);
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
988
989
990
991
  			break;
  		case FDT_END:
  			return 1;
  		default:
916235281   Gerald Van Baren   Fix fdt printing ...
992
  			if (level <= depth)
addd8ce83   Gerald Van Baren   Fix cmd_fdt line ...
993
994
995
996
997
998
999
1000
  				printf("Unknown tag 0x%08X
  ", tag);
  			return 1;
  		}
  		nodeoffset = nextoffset;
  	}
  	return 0;
  }
781e09ee6   Gerald Van Baren   Add a flattened d...
1001
  /********************************************************************/
088f1b199   Kim Phillips   common/cmd_*.c: s...
1002
1003
  #ifdef CONFIG_SYS_LONGHELP
  static char fdt_help_text[] =
4b5786550   Simon Glass   fdt: Allow fdt co...
1004
1005
  	"addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>
  "
fd61e55dd   Gerald Van Baren   Create new fdt bo...
1006
1007
1008
1009
  #ifdef CONFIG_OF_BOARD_SETUP
  	"fdt boardsetup                      - Do board-specific set up
  "
  #endif
238cb7a42   Gerald Van Baren   Improve the FDT h...
1010
1011
  	"fdt move   <fdt> <newaddr> <length> - Copy the fdt to <addr> and make it active
  "
40afac22a   Kumar Gala   fdt: Added resize...
1012
1013
  	"fdt resize                          - Resize fdt to size + padding to 4k addr
  "
781e09ee6   Gerald Van Baren   Add a flattened d...
1014
1015
1016
1017
  	"fdt print  <path> [<prop>]          - Recursive print starting at <path>
  "
  	"fdt list   <path> [<prop>]          - Print one level starting at <path>
  "
bc80295b6   Joe Hershberger   fdt: Add get comm...
1018
1019
1020
1021
1022
1023
1024
1025
  	"fdt get value <var> <path> <prop>   - Get <property> and store in <var>
  "
  	"fdt get name <var> <path> <index>   - Get name of node <index> and store in <var>
  "
  	"fdt get addr <var> <path> <prop>    - Get start address of <property> and store in <var>
  "
  	"fdt get size <var> <path> [<prop>]  - Get size of [<property>] or num nodes and store in <var>
  "
781e09ee6   Gerald Van Baren   Add a flattened d...
1026
1027
1028
1029
1030
1031
  	"fdt set    <path> <prop> [<val>]    - Set <property> [to <val>]
  "
  	"fdt mknode <path> <node>            - Create a new node after <path>
  "
  	"fdt rm     <path> [<prop>]          - Delete the node or <property>
  "
804887e60   Kumar Gala   Add sub-commands ...
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
  	"fdt header                          - Display header info
  "
  	"fdt bootcpu <id>                    - Set boot cpuid
  "
  	"fdt memory <addr> <size>            - Add/Update memory node
  "
  	"fdt rsvmem print                    - Show current mem reserves
  "
  	"fdt rsvmem add <addr> <size>        - Add a mem reserve
  "
  	"fdt rsvmem delete <index>           - Delete a mem reserves
  "
f953d99fd   Kumar Gala   fdt: added the ab...
1044
1045
1046
1047
  	"fdt chosen [<start> <end>]          - Add/update the /chosen branch in the tree
  "
  	"                                        <start>/<end> - initrd start/end addr
  "
109c30fb8   Gerald Van Baren   Add note on deref...
1048
  	"NOTE: Dereference aliases by omiting the leading '/', "
088f1b199   Kim Phillips   common/cmd_*.c: s...
1049
1050
1051
1052
1053
1054
  		"e.g. fdt print ethernet0.";
  #endif
  
  U_BOOT_CMD(
  	fdt,	255,	0,	do_fdt,
  	"flattened device tree utility commands", fdt_help_text
781e09ee6   Gerald Van Baren   Add a flattened d...
1055
  );