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