File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <ctype.h>
0038 #include <inttypes.h>
0039 #include <stdio.h>
0040 #include <stdlib.h>
0041 #include <string.h>
0042 #include <time.h>
0043 #include <unistd.h>
0044
0045 #include <rtems/shell.h>
0046 #include <rtems/rtems-fdt-shell.h>
0047
0048
0049
0050
0051 typedef int (*rtems_fdt_shell_handler) (int argc, char *argv[]);
0052
0053
0054
0055
0056 typedef struct
0057 {
0058 const char* name;
0059 rtems_fdt_shell_handler handler;
0060 const char* help;
0061 } rtems_fdt_shell_cmd;
0062
0063
0064
0065
0066 static long rtems_fdt_test_timeout = 5;
0067
0068
0069
0070
0071 static rtems_fdt_handle cmd_fdt_handle;
0072
0073
0074
0075
0076 static void rtems_fdt_default_write (uintptr_t address, uint32_t value);
0077 static uint32_t rtems_fdt_default_read (uintptr_t address);
0078
0079 static rtems_fdt_write_handler write_handler = rtems_fdt_default_write;;
0080 static rtems_fdt_read_handler read_handler = rtems_fdt_default_read;
0081
0082 static void
0083 rtems_fdt_default_write (uintptr_t address, uint32_t value)
0084 {
0085 volatile uint32_t* ap = (uint32_t*) address;
0086 *ap = value;
0087 }
0088
0089 static uint32_t
0090 rtems_fdt_default_read (uintptr_t address)
0091 {
0092 volatile uint32_t* ap = (uint32_t*) address;
0093 return *ap;
0094 }
0095
0096
0097 static void
0098 rtems_fdt_write (uintptr_t address, uint32_t value)
0099 {
0100 write_handler (address, value);
0101 }
0102
0103 static uint32_t
0104 rtems_fdt_read (uintptr_t address)
0105 {
0106 return read_handler (address);
0107 }
0108
0109 static int
0110 rtems_fdt_wrong_number_of_args (void)
0111 {
0112 printf ("error: wrong number of arguments\n");
0113 return 1;
0114 }
0115
0116 static int
0117 rtems_fdt_invalid_args (const char* arg)
0118 {
0119 printf ("error: invalid argument: %s\n", arg);
0120 return 1;
0121 }
0122
0123 static int
0124 rtems_fdt_extra_args (const char* arg)
0125 {
0126 printf ("error: extra argument is invalid: %s\n", arg);
0127 return 1;
0128 }
0129
0130 static int
0131 rtems_fdt_check_error (int errval, const char* message, const char* path)
0132 {
0133 if (errval < 0)
0134 {
0135 if (path)
0136 printf ("error: %s: %s: (%d) %s\n",
0137 message, path, errval, rtems_fdt_strerror (errval));
0138 else
0139 printf ("error: %s: (%d) %s\n",
0140 message, errval, rtems_fdt_strerror (errval));
0141 return 1;
0142 }
0143 return 0;
0144 }
0145
0146 static bool
0147 rtems_fdt_get_value32 (const char* path,
0148 const char* property,
0149 size_t size,
0150 uint32_t* value)
0151 {
0152 return true;
0153 }
0154
0155 static int
0156 rtems_fdt_shell_ld (int argc, char *argv[])
0157 {
0158 if (argc != 2)
0159 return rtems_fdt_wrong_number_of_args ();
0160
0161 return rtems_fdt_check_error (rtems_fdt_load (argv[1], &cmd_fdt_handle),
0162 "loading FTB", argv[1]);
0163 }
0164
0165 static int
0166 rtems_fdt_shell_uld (int argc, char *argv[])
0167 {
0168 if (argc != 2)
0169 return rtems_fdt_wrong_number_of_args ();
0170
0171 return rtems_fdt_check_error (rtems_fdt_unload (&cmd_fdt_handle),
0172 "unloading FTB", argv[1]);
0173 }
0174
0175 static int
0176 rtems_fdt_shell_ls (int argc, char *argv[])
0177 {
0178 char* path = NULL;
0179 bool recursive = false;
0180 bool long_path = false;
0181 bool debug = false;
0182 int arg = 1;
0183 size_t path_len = 0;
0184 int total_entries = 0;
0185 int num_entries = 0;
0186 int max_name_len = 0;
0187 int name_offset = 0;
0188 int i = 0;
0189
0190 while (arg < argc)
0191 {
0192 if (argv[arg][0] == '-')
0193 {
0194 if (argv[arg][2] != 0)
0195 return rtems_fdt_invalid_args (argv[arg]);
0196
0197 switch (argv[arg][1])
0198 {
0199 case 'l':
0200 long_path = true;
0201 break;
0202 case 'r':
0203 recursive = true;
0204 break;
0205 case 'd':
0206 debug = true;
0207 break;
0208 default:
0209 return rtems_fdt_invalid_args (argv[arg]);
0210 }
0211 }
0212 else
0213 {
0214 if (path)
0215 return rtems_fdt_extra_args (argv[arg]);
0216 if (strcmp (argv[arg], "/") != 0)
0217 path = argv[arg];
0218 }
0219 ++arg;
0220 }
0221
0222 if (path == NULL)
0223 {
0224 path = "";
0225 }
0226 else
0227 {
0228 if (path[0] != '/')
0229 name_offset = 1;
0230 }
0231
0232
0233 path_len = strlen (path);
0234
0235 if (path_len > 0 && path[path_len - 1] == '/')
0236 path_len--;
0237
0238
0239 total_entries = rtems_fdt_num_entries(&cmd_fdt_handle);
0240
0241 for (i = 0; i < total_entries; i++)
0242 {
0243
0244 const char *name = rtems_fdt_entry_name(&cmd_fdt_handle, i);
0245 size_t name_len = strlen(name);
0246
0247 if ((name_len >= path_len + name_offset) &&
0248 ((strncmp (path, name + name_offset, path_len) == 0) &&
0249 ((name[path_len + name_offset] == '/' ||
0250 name[path_len + name_offset] == '\0'))) &&
0251 (recursive || name_len == path_len + name_offset ||
0252 (strchr(&name[path_len + name_offset + 1], '/') == NULL)))
0253 {
0254 ++num_entries;
0255 if (long_path)
0256 {
0257 if (name_len > max_name_len)
0258 {
0259 max_name_len = name_len;
0260 }
0261 }
0262 else if (name_len != path_len)
0263 {
0264 if (name_len - path_len > max_name_len)
0265 {
0266 max_name_len = name_len - path_len;
0267 }
0268 }
0269 }
0270 }
0271
0272 printf("Total: %d of %d\n", num_entries, total_entries);
0273
0274 for (i = 0; i < total_entries; i++)
0275 {
0276
0277 const char *name = rtems_fdt_entry_name(&cmd_fdt_handle, i);
0278 size_t name_len = strlen(name);
0279
0280 if ((name_len >= path_len + name_offset) &&
0281 ((strncmp (path, name + name_offset, path_len) == 0) &&
0282 ((name[path_len + name_offset] == '/' ||
0283 name[path_len + name_offset] == '\0'))) &&
0284 (recursive || name_len == path_len + name_offset ||
0285 (strchr(&name[path_len + name_offset + 1], '/') == NULL)))
0286 {
0287 const char* print_name = ".";
0288
0289 if (long_path)
0290 {
0291 print_name = name + name_offset;
0292 }
0293 else if (name_len != path_len + name_offset)
0294 {
0295 print_name = &name[path_len + name_offset + 1];
0296 }
0297
0298 printf ("%-*s", max_name_len, print_name);
0299
0300 if (debug)
0301 {
0302
0303 int printed = 0;
0304 const int noffset = rtems_fdt_entry_offset(&cmd_fdt_handle, i);
0305 int poffset = rtems_fdt_first_prop_offset(&cmd_fdt_handle, noffset);
0306 int address_cells =
0307 rtems_fdt_getprop_address_cells(&cmd_fdt_handle, noffset);
0308 int size_cells = rtems_fdt_getprop_size_cells(&cmd_fdt_handle, noffset);
0309 printf("cells(a:%d s:%d) ", address_cells, size_cells);
0310 while (poffset >= 0)
0311 {
0312 int plen = 0;
0313 const char* pname = NULL;
0314 const uint8_t *pvalue =
0315 rtems_fdt_getprop_by_offset(&cmd_fdt_handle, poffset, &pname, &plen);
0316 if (pvalue != NULL)
0317 {
0318 int b;
0319 if (printed > 0)
0320 printf(",");
0321 ++printed;
0322 printf(" %s %i:", pname, plen);
0323 for (b = 0; b < plen; ++b)
0324 {
0325 if (b > 0 && (b % 4) == 0)
0326 printf(" ");
0327 printf("%02" PRIx8, *pvalue++);
0328 }
0329 }
0330 poffset = rtems_fdt_next_prop_offset(&cmd_fdt_handle, poffset);
0331 }
0332 }
0333
0334 printf("\n");
0335 }
0336 }
0337
0338 return 0;
0339 }
0340
0341 static int
0342 rtems_fdt_shell_wr (int argc, char *argv[])
0343 {
0344 rtems_fdt_address_map addr_map;
0345 uint64_t offset = 0;
0346 uint32_t value;
0347 int fmt;
0348 int r;
0349
0350 if ((argc < 3) || (argc > 4))
0351 return rtems_fdt_wrong_number_of_args ();
0352
0353 if (argc == 3)
0354 {
0355 value = strtoul (argv[2], 0, 0);
0356 }
0357 else
0358 {
0359 offset = strtoull (argv[2], 0, 0);
0360 value = strtoul (argv[3], 0, 0);
0361 }
0362
0363 r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
0364 if (r < 0)
0365 {
0366 printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
0367 return 1;
0368 }
0369
0370 if (offset >= addr_map.size)
0371 {
0372 printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
0373 return 1;
0374 }
0375
0376 addr_map.address += offset;
0377
0378 fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
0379
0380 printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 "\n", fmt, addr_map.address, value);
0381
0382 rtems_fdt_write (addr_map.address, value);
0383
0384 return 0;
0385 }
0386
0387 static int
0388 rtems_fdt_shell_rd (int argc, char *argv[])
0389 {
0390 rtems_fdt_address_map addr_map;
0391 uint32_t offset = 0;
0392 int fmt;
0393 int r;
0394
0395 if ((argc < 1) || (argc > 3))
0396 return rtems_fdt_wrong_number_of_args ();
0397
0398 if (argc == 3)
0399 offset = strtoul (argv[2], 0, 0);
0400
0401 r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
0402 if (r < 0)
0403 {
0404 printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
0405 return 1;
0406 }
0407
0408 if (offset >= addr_map.size)
0409 {
0410 printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
0411 return 1;
0412 }
0413
0414 addr_map.address += offset;
0415
0416 fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
0417
0418 printf ("0x%0*" PRIx64 " => 0x%08" PRIx32 "\n",
0419 fmt, addr_map.address, rtems_fdt_read (addr_map.address));
0420
0421 return 0;
0422 }
0423
0424 static int
0425 rtems_fdt_shell_set (int argc, char *argv[])
0426 {
0427 rtems_fdt_address_map addr_map;
0428 uint32_t offset = 0;
0429 uint32_t value;
0430 int mask_arg;
0431 uint32_t mask;
0432 int fmt;
0433 int r;
0434
0435 if ((argc < 3) || (argc > 4))
0436 return rtems_fdt_wrong_number_of_args ();
0437
0438 if (argc == 3)
0439 mask_arg = 2;
0440 else
0441 {
0442 offset = strtoul (argv[2], 0, 0);
0443 mask_arg = 3;
0444 }
0445
0446 r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
0447 if (r < 0)
0448 {
0449 printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
0450 return 1;
0451 }
0452
0453 if (offset >= addr_map.size)
0454 {
0455 printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
0456 return 1;
0457 }
0458
0459 addr_map.address += offset;
0460
0461 fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
0462
0463 if (isdigit ((unsigned char) argv[mask_arg][0]))
0464 mask = strtoul (argv[mask_arg], 0, 0);
0465 else
0466 {
0467 mask = 0;
0468 if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
0469 return 1;
0470 }
0471
0472 value = rtems_fdt_read (addr_map.address);
0473
0474 printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 " = 0x%08" PRIx32 " | 0x%08" PRIx32 "\n",
0475 fmt, addr_map.address, value | mask, value, mask);
0476
0477 rtems_fdt_write (addr_map.address, value | mask);
0478
0479 return 0;
0480 }
0481
0482 static int
0483 rtems_fdt_shell_cl (int argc, char *argv[])
0484 {
0485 rtems_fdt_address_map addr_map;
0486 uint32_t offset = 0;
0487 uint32_t value;
0488 int mask_arg;
0489 uint32_t mask;
0490 int fmt;
0491 int r;
0492
0493 if ((argc < 3) || (argc > 4))
0494 return rtems_fdt_wrong_number_of_args ();
0495
0496 if (argc == 3)
0497 mask_arg = 2;
0498 else
0499 {
0500 offset = strtoul (argv[2], 0, 0);
0501 mask_arg = 3;
0502 }
0503
0504 r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
0505 if (r < 0)
0506 {
0507 printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
0508 return 1;
0509 }
0510
0511 if (offset >= addr_map.size)
0512 {
0513 printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
0514 return 1;
0515 }
0516
0517 addr_map.address += offset;
0518
0519 fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
0520
0521 if (isdigit ((unsigned char) argv[mask_arg][0]))
0522 mask = strtoul (argv[mask_arg], 0, 0);
0523 else
0524 {
0525 mask = 0;
0526 if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
0527 return 1;
0528 }
0529
0530 value = rtems_fdt_read (addr_map.address);
0531
0532 printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 " = 0x%08" PRIx32 \
0533 " & ~0x%08" PRIx32 " (0x%08" PRIx32 ")\n",
0534 fmt, addr_map.address, value & ~mask, value, mask, ~mask);
0535
0536 rtems_fdt_write (addr_map.address, value & ~mask);
0537
0538 return 0;
0539 }
0540
0541 static int
0542 rtems_fdt_shell_up (int argc, char *argv[])
0543 {
0544 rtems_fdt_address_map addr_map;
0545 uint32_t offset = 0;
0546 uint32_t set;
0547 uint32_t value;
0548 int mask_arg;
0549 uint32_t mask;
0550 int fmt;
0551 int r;
0552
0553 if ((argc < 4) || (argc > 5))
0554 return rtems_fdt_wrong_number_of_args ();
0555
0556 if (argc == 4)
0557 mask_arg = 2;
0558 else
0559 {
0560 offset = strtoul (argv[2], 0, 0);
0561 mask_arg = 3;
0562 }
0563
0564 set = strtoul (argv[mask_arg + 1], 0, 0);
0565
0566 r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
0567 if (r < 0)
0568 {
0569 printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
0570 return 1;
0571 }
0572
0573 if (offset >= addr_map.size)
0574 {
0575 printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
0576 return 1;
0577 }
0578
0579 addr_map.address += offset;
0580
0581 fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
0582
0583 if (isdigit ((unsigned char) argv[mask_arg][0]))
0584 mask = strtoul (argv[mask_arg], 0, 0);
0585 else
0586 {
0587 mask = 0;
0588 if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
0589 return 1;
0590 }
0591
0592 value = rtems_fdt_read (addr_map.address);
0593
0594 printf ("0x%0*" PRIx64 " <= 0x%08" PRIx32 " = (0x%08" PRIx32 \
0595 " & ~0x%08" PRIx32 " (0x%08" PRIx32 ")) | 0x%08" PRIx32 "\n",
0596 fmt, addr_map.address, (value & ~mask) | set, value, mask, ~mask, set);
0597
0598 rtems_fdt_write (addr_map.address, (value & ~mask) | set);
0599
0600 return 0;
0601 }
0602
0603 static int
0604 rtems_fdt_shell_tst (int argc, char *argv[])
0605 {
0606 rtems_fdt_address_map addr_map;
0607 uint32_t offset = 0;
0608 uint32_t test;
0609 uint32_t value = 0;
0610 int mask_arg;
0611 uint32_t mask;
0612 time_t start;
0613 int fmt;
0614 int r;
0615
0616 if ((argc < 4) || (argc > 5))
0617 return rtems_fdt_wrong_number_of_args ();
0618
0619 if (argc == 4)
0620 mask_arg = 2;
0621 else
0622 {
0623 offset = strtoul (argv[2], 0, 0);
0624 mask_arg = 3;
0625 }
0626
0627 test = strtoul (argv[mask_arg + 1], 0, 0);
0628
0629 r = rtems_fdt_getprop_address_map(&cmd_fdt_handle, argv[1], "reg", &addr_map);
0630 if (r < 0)
0631 {
0632 printf("error: invalid reg address map: %d: %s\n", -r, argv[1]);
0633 return 1;
0634 }
0635
0636 if (offset >= addr_map.size)
0637 {
0638 printf("error: offset out of range: %" PRIu64 ": %s\n", addr_map.size, argv[1]);
0639 return 1;
0640 }
0641
0642 addr_map.address += offset;
0643
0644 fmt = addr_map.address >= 0x0000000100000000ULL ? 16 : 8;
0645
0646 if (isdigit ((unsigned char) argv[mask_arg][0]))
0647 mask = strtoul (argv[mask_arg], 0, 0);
0648 else
0649 {
0650 mask = 0;
0651 if (!rtems_fdt_get_value32 (argv[mask_arg], "mask", sizeof (uint32_t), &mask))
0652 return 1;
0653 }
0654
0655 start = time (NULL);
0656
0657 printf ("0x%0*" PRIx64 " => (value & 0x%08" PRIx32 ") == 0x%08" PRIx32 \
0658 " for %ld seconds\n",
0659 fmt, addr_map.address, mask, test, rtems_fdt_test_timeout);
0660
0661 while ((time (NULL) - start) < rtems_fdt_test_timeout)
0662 {
0663 int i;
0664 for (i = 0; i < 10000; ++i)
0665 {
0666 value = rtems_fdt_read (addr_map.address);
0667 if ((value & mask) == test)
0668 return 0;
0669 }
0670 }
0671
0672 printf ("0x%0*" PRIx64 " => 0x%08" PRIx32 ": timeout\n", fmt, addr_map.address, value);
0673
0674 return 1;
0675 }
0676
0677 static int
0678 rtems_fdt_shell_nap (int argc, char *argv[])
0679 {
0680 uint32_t time;
0681
0682 if (argc != 2)
0683 return rtems_fdt_wrong_number_of_args ();
0684
0685 time = strtoul (argv[1], 0, 0);
0686
0687 if (time == 0)
0688 {
0689 printf ("error: 0 is not a valid time; check you have a valid number.\n");
0690 return 1;
0691 }
0692
0693 usleep (time * 1000);
0694
0695 return 0;
0696 }
0697
0698 static int
0699 rtems_fdt_shell_to (int argc, char *argv[])
0700 {
0701 uint32_t to;
0702
0703 if (argc == 1)
0704 {
0705 printf ("timeout: %ld seconds\n", rtems_fdt_test_timeout);
0706 return 0;
0707 }
0708
0709 if (argc != 2)
0710 return rtems_fdt_wrong_number_of_args ();
0711
0712 to = strtoul (argv[1], 0, 0);
0713
0714 if (to == 0)
0715 {
0716 printf ("error: 0 is not a valid timeout; check you have a number.\n");
0717 return 1;
0718 }
0719
0720 rtems_fdt_test_timeout = to;
0721
0722 return 0;
0723 }
0724
0725 static void
0726 rtems_fdt_shell_usage (const char* arg)
0727 {
0728 printf ("%s: FDT Help\n", arg);
0729 printf (" %s [-hl] <command>\n", arg);
0730 printf (" where:\n");
0731 printf (" command: The FDT subcommand. See -l for a list plus help.\n");
0732 printf (" -h: This help\n");
0733 printf (" -l: The command list.\n");
0734 }
0735
0736 static const rtems_fdt_shell_cmd table[] =
0737 {
0738 { "ld", rtems_fdt_shell_ld, "<filename> : Load a FDT blob" },
0739 { "uld", rtems_fdt_shell_uld, "Uload an FDT blob" },
0740 { "ls", rtems_fdt_shell_ls, "<path> : List the nodes at the path and optionally below" },
0741 { "wr", rtems_fdt_shell_wr, "<path> [<offset>] <value> : Write the value." },
0742 { "rd", rtems_fdt_shell_rd, "<path> [<offset>] : Read the value." },
0743 { "set", rtems_fdt_shell_set, "<path> [<offset>] <mask> : Set the mask bits" },
0744 { "cl", rtems_fdt_shell_cl, "<path> [<offset>] <mask> : Clear the mask bits." },
0745 { "up", rtems_fdt_shell_up, "<path> [<offset>] <mask> <value> : Update the mask bit with value" },
0746 { "tst", rtems_fdt_shell_tst, "<path> [<offset>] <mask> <value> : Testing loop for masked value." },
0747 { "nap", rtems_fdt_shell_nap, "<time> : Sleep for the time period. It is in milli-seconds." },
0748 { "to", rtems_fdt_shell_to, "<value> : Set the test timeout (seconds)" },
0749 };
0750
0751 #define RTEMS_FDT_COMMANDS (sizeof (table) / sizeof (const rtems_fdt_shell_cmd))
0752
0753 static int
0754 rtems_fdt_shell_command (int argc, char* argv[])
0755 {
0756 int arg;
0757 size_t t;
0758
0759 for (arg = 1; arg < argc; arg++)
0760 {
0761 if (argv[arg][0] != '-')
0762 break;
0763
0764 switch (argv[arg][1])
0765 {
0766 case 'h':
0767 rtems_fdt_shell_usage (argv[0]);
0768 return 0;
0769 case 'l':
0770 printf ("%s: commands are:\n", argv[0]);
0771 for (t = 0; t < RTEMS_FDT_COMMANDS; ++t)
0772 printf (" %-3s %s\n", table[t].name, table[t].help);
0773 return 0;
0774 default:
0775 printf ("error: unknown option: %s\n", argv[arg]);
0776 return 1;
0777 }
0778 }
0779
0780 if ((argc - arg) < 1)
0781 printf ("error: you need to provide a command, try %s -h\n", argv[0]);
0782 else
0783 {
0784 for (t = 0; t < RTEMS_FDT_COMMANDS; ++t)
0785 {
0786 if (strncmp (argv[arg], table[t].name, strlen (argv[arg])) == 0)
0787 {
0788 int r = table[t].handler (argc - arg, argv + 1);
0789 return r;
0790 }
0791 }
0792 printf ("error: command not found: %s (try -h)\n", argv[arg]);
0793 }
0794
0795 return 1;
0796 }
0797
0798 void
0799 rtems_fdt_add_shell_command(void)
0800 {
0801 rtems_shell_add_cmd ("fdt", "mem",
0802 "Flattened device tree", rtems_fdt_shell_command);
0803 }
0804
0805 rtems_fdt_handle*
0806 rtems_fdt_get_shell_handle (void)
0807 {
0808 return &cmd_fdt_handle;
0809 }
0810
0811 rtems_fdt_write_handler
0812 rtems_fdt_set_shell_write_handler (rtems_fdt_write_handler handler)
0813 {
0814 rtems_fdt_write_handler tmp = write_handler;
0815 write_handler = handler;
0816 return tmp;
0817 }
0818
0819 rtems_fdt_read_handler
0820 rtems_fdt_set_shell_read_handler (rtems_fdt_read_handler handler)
0821 {
0822 rtems_fdt_read_handler tmp = read_handler;
0823 read_handler = handler;
0824 return tmp;
0825 }