1 /* 2 * (C) Copyright 2018 Linaro Ltd. 3 * Sam Protsenko <semen.protsenko@linaro.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <image-android-dt.h> 9 #include <common.h> 10 11 enum cmd_dtimg_info { 12 CMD_DTIMG_START = 0, 13 CMD_DTIMG_SIZE, 14 }; 15 16 static int do_dtimg_dump(cmd_tbl_t *cmdtp, int flag, int argc, 17 char * const argv[]) 18 { 19 char *endp; 20 ulong hdr_addr; 21 22 if (argc != 2) 23 return CMD_RET_USAGE; 24 25 hdr_addr = simple_strtoul(argv[1], &endp, 16); 26 if (*endp != '\0') { 27 printf("Error: Wrong image address\n"); 28 return CMD_RET_FAILURE; 29 } 30 31 if (!android_dt_check_header(hdr_addr)) { 32 printf("Error: DT image header is incorrect\n"); 33 return CMD_RET_FAILURE; 34 } 35 36 android_dt_print_contents(hdr_addr); 37 38 return CMD_RET_SUCCESS; 39 } 40 41 static int dtimg_get_fdt(int argc, char * const argv[], enum cmd_dtimg_info cmd) 42 { 43 ulong hdr_addr; 44 u32 index; 45 char *endp; 46 ulong fdt_addr; 47 u32 fdt_size; 48 char buf[65]; 49 50 if (argc != 4) 51 return CMD_RET_USAGE; 52 53 hdr_addr = simple_strtoul(argv[1], &endp, 16); 54 if (*endp != '\0') { 55 printf("Error: Wrong image address\n"); 56 return CMD_RET_FAILURE; 57 } 58 59 if (!android_dt_check_header(hdr_addr)) { 60 printf("Error: DT image header is incorrect\n"); 61 return CMD_RET_FAILURE; 62 } 63 64 index = simple_strtoul(argv[2], &endp, 0); 65 if (*endp != '\0') { 66 printf("Error: Wrong index\n"); 67 return CMD_RET_FAILURE; 68 } 69 70 if (!android_dt_get_fdt_by_index(hdr_addr, index, &fdt_addr, &fdt_size)) 71 return CMD_RET_FAILURE; 72 73 switch (cmd) { 74 case CMD_DTIMG_START: 75 snprintf(buf, sizeof(buf), "%lx", fdt_addr); 76 break; 77 case CMD_DTIMG_SIZE: 78 snprintf(buf, sizeof(buf), "%x", fdt_size); 79 break; 80 default: 81 printf("Error: Unknown cmd_dtimg_info value: %d\n", cmd); 82 return CMD_RET_FAILURE; 83 } 84 85 env_set(argv[3], buf); 86 87 return CMD_RET_SUCCESS; 88 } 89 90 static int do_dtimg_start(cmd_tbl_t *cmdtp, int flag, int argc, 91 char * const argv[]) 92 { 93 return dtimg_get_fdt(argc, argv, CMD_DTIMG_START); 94 } 95 96 static int do_dtimg_size(cmd_tbl_t *cmdtp, int flag, int argc, 97 char * const argv[]) 98 { 99 return dtimg_get_fdt(argc, argv, CMD_DTIMG_SIZE); 100 } 101 102 static cmd_tbl_t cmd_dtimg_sub[] = { 103 U_BOOT_CMD_MKENT(dump, 2, 0, do_dtimg_dump, "", ""), 104 U_BOOT_CMD_MKENT(start, 4, 0, do_dtimg_start, "", ""), 105 U_BOOT_CMD_MKENT(size, 4, 0, do_dtimg_size, "", ""), 106 }; 107 108 static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 109 { 110 cmd_tbl_t *cp; 111 112 cp = find_cmd_tbl(argv[1], cmd_dtimg_sub, ARRAY_SIZE(cmd_dtimg_sub)); 113 114 /* Strip off leading 'dtimg' command argument */ 115 argc--; 116 argv++; 117 118 if (!cp || argc > cp->maxargs) 119 return CMD_RET_USAGE; 120 if (flag == CMD_FLAG_REPEAT && !cp->repeatable) 121 return CMD_RET_SUCCESS; 122 123 return cp->cmd(cmdtp, flag, argc, argv); 124 } 125 126 U_BOOT_CMD( 127 dtimg, CONFIG_SYS_MAXARGS, 0, do_dtimg, 128 "manipulate dtb/dtbo Android image", 129 "dump <addr>\n" 130 " - parse specified image and print its structure info\n" 131 " <addr>: image address in RAM, in hex\n" 132 "dtimg start <addr> <index> <varname>\n" 133 " - get address (hex) of FDT in the image, by index\n" 134 " <addr>: image address in RAM, in hex\n" 135 " <index>: index of desired FDT in the image\n" 136 " <varname>: name of variable where to store address of FDT\n" 137 "dtimg size <addr> <index> <varname>\n" 138 " - get size (hex, bytes) of FDT in the image, by index\n" 139 " <addr>: image address in RAM, in hex\n" 140 " <index>: index of desired FDT in the image\n" 141 " <varname>: name of variable where to store size of FDT" 142 ); 143