common: Drop image.h from common header
[platform/kernel/u-boot.git] / cmd / abootimg.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2020
4  * Sam Protsenko <joe.skb7@gmail.com>
5  */
6
7 #include <android_image.h>
8 #include <common.h>
9 #include <image.h>
10 #include <mapmem.h>
11
12 #define abootimg_addr() \
13         (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr)
14
15 /* Please use abootimg_addr() macro to obtain the boot image address */
16 static ulong _abootimg_addr = -1;
17
18 static int abootimg_get_ver(int argc, char * const argv[])
19 {
20         const struct andr_img_hdr *hdr;
21         int res = CMD_RET_SUCCESS;
22
23         if (argc > 1)
24                 return CMD_RET_USAGE;
25
26         hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
27         if (android_image_check_header(hdr)) {
28                 printf("Error: Boot Image header is incorrect\n");
29                 res = CMD_RET_FAILURE;
30                 goto exit;
31         }
32
33         if (argc == 0)
34                 printf("%u\n", hdr->header_version);
35         else
36                 env_set_ulong(argv[0], hdr->header_version);
37
38 exit:
39         unmap_sysmem(hdr);
40         return res;
41 }
42
43 static int abootimg_get_recovery_dtbo(int argc, char * const argv[])
44 {
45         ulong addr;
46         u32 size;
47
48         if (argc > 2)
49                 return CMD_RET_USAGE;
50
51         if (!android_image_get_dtbo(abootimg_addr(), &addr, &size))
52                 return CMD_RET_FAILURE;
53
54         if (argc == 0) {
55                 printf("%lx\n", addr);
56         } else {
57                 env_set_hex(argv[0], addr);
58                 if (argc == 2)
59                         env_set_hex(argv[1], size);
60         }
61
62         return CMD_RET_SUCCESS;
63 }
64
65 static int abootimg_get_dtb_load_addr(int argc, char * const argv[])
66 {
67         const struct andr_img_hdr *hdr;
68         int res = CMD_RET_SUCCESS;
69
70         if (argc > 1)
71                 return CMD_RET_USAGE;
72
73         hdr = map_sysmem(abootimg_addr(), sizeof(*hdr));
74         if (android_image_check_header(hdr)) {
75                 printf("Error: Boot Image header is incorrect\n");
76                 res = CMD_RET_FAILURE;
77                 goto exit;
78         }
79
80         if (hdr->header_version < 2) {
81                 printf("Error: header_version must be >= 2 for this\n");
82                 res = CMD_RET_FAILURE;
83                 goto exit;
84         }
85
86         if (argc == 0)
87                 printf("%lx\n", (ulong)hdr->dtb_addr);
88         else
89                 env_set_hex(argv[0], (ulong)hdr->dtb_addr);
90
91 exit:
92         unmap_sysmem(hdr);
93         return res;
94 }
95
96 static int abootimg_get_dtb_by_index(int argc, char * const argv[])
97 {
98         const char *index_str;
99         u32 num;
100         char *endp;
101         ulong addr;
102         u32 size;
103
104         if (argc < 1 || argc > 3)
105                 return CMD_RET_USAGE;
106
107         index_str = argv[0] + strlen("--index=");
108         if (index_str[0] == '\0') {
109                 printf("Error: Wrong index num\n");
110                 return CMD_RET_FAILURE;
111         }
112
113         num = simple_strtoul(index_str, &endp, 0);
114         if (*endp != '\0') {
115                 printf("Error: Wrong index num\n");
116                 return CMD_RET_FAILURE;
117         }
118
119         if (!android_image_get_dtb_by_index(abootimg_addr(), num,
120                                             &addr, &size)) {
121                 return CMD_RET_FAILURE;
122         }
123
124         if (argc == 1) {
125                 printf("%lx\n", addr);
126         } else {
127                 if (env_set_hex(argv[1], addr)) {
128                         printf("Error: Can't set [addr_var]\n");
129                         return CMD_RET_FAILURE;
130                 }
131
132                 if (argc == 3) {
133                         if (env_set_hex(argv[2], size)) {
134                                 printf("Error: Can't set [size_var]\n");
135                                 return CMD_RET_FAILURE;
136                         }
137                 }
138         }
139
140         return CMD_RET_SUCCESS;
141 }
142
143 static int abootimg_get_dtb(int argc, char * const argv[])
144 {
145         if (argc < 1)
146                 return CMD_RET_USAGE;
147
148         if (strstr(argv[0], "--index="))
149                 return abootimg_get_dtb_by_index(argc, argv);
150
151         return CMD_RET_USAGE;
152 }
153
154 static int do_abootimg_addr(cmd_tbl_t *cmdtp, int flag, int argc,
155                             char * const argv[])
156 {
157         char *endp;
158         ulong img_addr;
159
160         if (argc != 2)
161                 return CMD_RET_USAGE;
162
163         img_addr = simple_strtoul(argv[1], &endp, 16);
164         if (*endp != '\0') {
165                 printf("Error: Wrong image address\n");
166                 return CMD_RET_FAILURE;
167         }
168
169         _abootimg_addr = img_addr;
170         return CMD_RET_SUCCESS;
171 }
172
173 static int do_abootimg_get(cmd_tbl_t *cmdtp, int flag, int argc,
174                            char * const argv[])
175 {
176         const char *param;
177
178         if (argc < 2)
179                 return CMD_RET_USAGE;
180
181         param = argv[1];
182         argc -= 2;
183         argv += 2;
184         if (!strcmp(param, "ver"))
185                 return abootimg_get_ver(argc, argv);
186         else if (!strcmp(param, "recovery_dtbo"))
187                 return abootimg_get_recovery_dtbo(argc, argv);
188         else if (!strcmp(param, "dtb_load_addr"))
189                 return abootimg_get_dtb_load_addr(argc, argv);
190         else if (!strcmp(param, "dtb"))
191                 return abootimg_get_dtb(argc, argv);
192
193         return CMD_RET_USAGE;
194 }
195
196 static int do_abootimg_dump(cmd_tbl_t *cmdtp, int flag, int argc,
197                             char * const argv[])
198 {
199         if (argc != 2)
200                 return CMD_RET_USAGE;
201
202         if (!strcmp(argv[1], "dtb")) {
203                 if (android_image_print_dtb_contents(abootimg_addr()))
204                         return CMD_RET_FAILURE;
205         } else {
206                 return CMD_RET_USAGE;
207         }
208
209         return CMD_RET_SUCCESS;
210 }
211
212 static cmd_tbl_t cmd_abootimg_sub[] = {
213         U_BOOT_CMD_MKENT(addr, 2, 1, do_abootimg_addr, "", ""),
214         U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""),
215         U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""),
216 };
217
218 static int do_abootimg(cmd_tbl_t *cmdtp, int flag, int argc,
219                        char * const argv[])
220 {
221         cmd_tbl_t *cp;
222
223         cp = find_cmd_tbl(argv[1], cmd_abootimg_sub,
224                           ARRAY_SIZE(cmd_abootimg_sub));
225
226         /* Strip off leading 'abootimg' command argument */
227         argc--;
228         argv++;
229
230         if (!cp || argc > cp->maxargs)
231                 return CMD_RET_USAGE;
232         if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
233                 return CMD_RET_SUCCESS;
234
235         return cp->cmd(cmdtp, flag, argc, argv);
236 }
237
238 U_BOOT_CMD(
239         abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg,
240         "manipulate Android Boot Image",
241         "addr <addr>\n"
242         "    - set the address in RAM where boot image is located\n"
243         "      ($loadaddr is used by default)\n"
244         "abootimg dump dtb\n"
245         "    - print info for all DT blobs in DTB area\n"
246         "abootimg get ver [varname]\n"
247         "    - get header version\n"
248         "abootimg get recovery_dtbo [addr_var [size_var]]\n"
249         "    - get address and size (hex) of recovery DTBO area in the image\n"
250         "      [addr_var]: variable name to contain DTBO area address\n"
251         "      [size_var]: variable name to contain DTBO area size\n"
252         "abootimg get dtb_load_addr [varname]\n"
253         "    - get load address (hex) of DTB, from image header\n"
254         "abootimg get dtb --index=<num> [addr_var [size_var]]\n"
255         "    - get address and size (hex) of DT blob in the image by index\n"
256         "      <num>: index number of desired DT blob in DTB area\n"
257         "      [addr_var]: variable name to contain DT blob address\n"
258         "      [size_var]: variable name to contain DT blob size"
259 );