blob: 22b4f5e1a83f624043d316f67316911a3be6a32e [file] [log] [blame]
Sam Protsenko92f95bb2018-08-16 23:34:13 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2018 Linaro Ltd.
4 * Sam Protsenko <semen.protsenko@linaro.org>
5 */
6
Simon Glass5e6201b2019-08-01 09:46:51 -06007#include <env.h>
Sam Protsenko92f95bb2018-08-16 23:34:13 +03008#include <image-android-dt.h>
9#include <common.h>
10
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010011enum cmd_adtimg_info {
12 CMD_ADTIMG_START = 0,
13 CMD_ADTIMG_SIZE,
Sam Protsenko92f95bb2018-08-16 23:34:13 +030014};
15
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010016static int do_adtimg_dump(cmd_tbl_t *cmdtp, int flag, int argc,
17 char * const argv[])
Sam Protsenko92f95bb2018-08-16 23:34:13 +030018{
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
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010041static int adtimg_get_fdt(int argc, char * const argv[],
42 enum cmd_adtimg_info cmd)
Sam Protsenko92f95bb2018-08-16 23:34:13 +030043{
44 ulong hdr_addr;
45 u32 index;
46 char *endp;
47 ulong fdt_addr;
48 u32 fdt_size;
49 char buf[65];
50
51 if (argc != 4)
52 return CMD_RET_USAGE;
53
54 hdr_addr = simple_strtoul(argv[1], &endp, 16);
55 if (*endp != '\0') {
56 printf("Error: Wrong image address\n");
57 return CMD_RET_FAILURE;
58 }
59
60 if (!android_dt_check_header(hdr_addr)) {
61 printf("Error: DT image header is incorrect\n");
62 return CMD_RET_FAILURE;
63 }
64
65 index = simple_strtoul(argv[2], &endp, 0);
66 if (*endp != '\0') {
67 printf("Error: Wrong index\n");
68 return CMD_RET_FAILURE;
69 }
70
71 if (!android_dt_get_fdt_by_index(hdr_addr, index, &fdt_addr, &fdt_size))
72 return CMD_RET_FAILURE;
73
74 switch (cmd) {
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010075 case CMD_ADTIMG_START:
Sam Protsenko92f95bb2018-08-16 23:34:13 +030076 snprintf(buf, sizeof(buf), "%lx", fdt_addr);
77 break;
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010078 case CMD_ADTIMG_SIZE:
Sam Protsenko92f95bb2018-08-16 23:34:13 +030079 snprintf(buf, sizeof(buf), "%x", fdt_size);
80 break;
81 default:
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010082 printf("Error: Unknown cmd_adtimg_info value: %d\n", cmd);
Sam Protsenko92f95bb2018-08-16 23:34:13 +030083 return CMD_RET_FAILURE;
84 }
85
86 env_set(argv[3], buf);
87
88 return CMD_RET_SUCCESS;
89}
90
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010091static int do_adtimg_start(cmd_tbl_t *cmdtp, int flag, int argc,
92 char * const argv[])
Sam Protsenko92f95bb2018-08-16 23:34:13 +030093{
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010094 return adtimg_get_fdt(argc, argv, CMD_ADTIMG_START);
Sam Protsenko92f95bb2018-08-16 23:34:13 +030095}
96
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +010097static int do_adtimg_size(cmd_tbl_t *cmdtp, int flag, int argc,
98 char * const argv[])
Sam Protsenko92f95bb2018-08-16 23:34:13 +030099{
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100100 return adtimg_get_fdt(argc, argv, CMD_ADTIMG_SIZE);
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300101}
102
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100103static cmd_tbl_t cmd_adtimg_sub[] = {
104 U_BOOT_CMD_MKENT(dump, 2, 0, do_adtimg_dump, "", ""),
105 U_BOOT_CMD_MKENT(start, 4, 0, do_adtimg_start, "", ""),
106 U_BOOT_CMD_MKENT(size, 4, 0, do_adtimg_size, "", ""),
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300107};
108
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100109static int do_adtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300110{
111 cmd_tbl_t *cp;
112
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100113 cp = find_cmd_tbl(argv[1], cmd_adtimg_sub, ARRAY_SIZE(cmd_adtimg_sub));
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300114
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100115 /* Strip off leading 'adtimg' command argument */
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300116 argc--;
117 argv++;
118
119 if (!cp || argc > cp->maxargs)
120 return CMD_RET_USAGE;
Boris Brezillonc71dfd12018-12-03 22:54:20 +0100121 if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300122 return CMD_RET_SUCCESS;
123
124 return cp->cmd(cmdtp, flag, argc, argv);
125}
126
127U_BOOT_CMD(
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100128 adtimg, CONFIG_SYS_MAXARGS, 0, do_adtimg,
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300129 "manipulate dtb/dtbo Android image",
130 "dump <addr>\n"
131 " - parse specified image and print its structure info\n"
132 " <addr>: image address in RAM, in hex\n"
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100133 "adtimg start <addr> <index> <varname>\n"
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300134 " - get address (hex) of FDT in the image, by index\n"
135 " <addr>: image address in RAM, in hex\n"
136 " <index>: index of desired FDT in the image\n"
137 " <varname>: name of variable where to store address of FDT\n"
Eugeniu Roscaa91a78e2019-12-24 17:51:07 +0100138 "adtimg size <addr> <index> <varname>\n"
Sam Protsenko92f95bb2018-08-16 23:34:13 +0300139 " - get size (hex, bytes) of FDT in the image, by index\n"
140 " <addr>: image address in RAM, in hex\n"
141 " <index>: index of desired FDT in the image\n"
142 " <varname>: name of variable where to store size of FDT"
143);