1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2012, Google Inc. All rights reserved.
4 */
5
6 #include <bootstage.h>
7 #include <command.h>
8 #include <vsprintf.h>
9 #include <linux/string.h>
10
do_bootstage_report(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])11 static int do_bootstage_report(struct cmd_tbl *cmdtp, int flag, int argc,
12 char *const argv[])
13 {
14 bootstage_report();
15
16 return 0;
17 }
18
19 #if IS_ENABLED(CONFIG_BOOTSTAGE_STASH)
get_base_size(int argc,char * const argv[],ulong * basep,ulong * sizep)20 static int get_base_size(int argc, char *const argv[], ulong *basep,
21 ulong *sizep)
22 {
23 char *endp;
24
25 *basep = CONFIG_BOOTSTAGE_STASH_ADDR;
26 *sizep = CONFIG_BOOTSTAGE_STASH_SIZE;
27 if (argc < 2)
28 return 0;
29 *basep = hextoul(argv[1], &endp);
30 if (*argv[1] == 0 || *endp != 0)
31 return -1;
32 if (argc == 2)
33 return 0;
34 *sizep = hextoul(argv[2], &endp);
35 if (*argv[2] == 0 || *endp != 0)
36 return -1;
37
38 return 0;
39 }
40
do_bootstage_stash(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])41 static int do_bootstage_stash(struct cmd_tbl *cmdtp, int flag, int argc,
42 char *const argv[])
43 {
44 ulong base, size;
45 int ret;
46
47 if (get_base_size(argc, argv, &base, &size))
48 return CMD_RET_USAGE;
49 if (base == -1UL) {
50 printf("No bootstage stash area defined\n");
51 return 1;
52 }
53
54 if (0 == strcmp(argv[0], "stash"))
55 ret = bootstage_stash((void *)base, size);
56 else
57 ret = bootstage_unstash((void *)base, size);
58 if (ret)
59 return 1;
60
61 return 0;
62 }
63 #endif
64
65 static struct cmd_tbl cmd_bootstage_sub[] = {
66 U_BOOT_CMD_MKENT(report, 2, 1, do_bootstage_report, "", ""),
67 #if IS_ENABLED(CONFIG_BOOTSTAGE_STASH)
68 U_BOOT_CMD_MKENT(stash, 4, 0, do_bootstage_stash, "", ""),
69 U_BOOT_CMD_MKENT(unstash, 4, 0, do_bootstage_stash, "", ""),
70 #endif
71 };
72
73 /*
74 * Process a bootstage sub-command
75 */
do_boostage(struct cmd_tbl * cmdtp,int flag,int argc,char * const argv[])76 static int do_boostage(struct cmd_tbl *cmdtp, int flag, int argc,
77 char *const argv[])
78 {
79 struct cmd_tbl *c;
80
81 /* Strip off leading 'bootstage' command argument */
82 argc--;
83 argv++;
84
85 c = find_cmd_tbl(argv[0], cmd_bootstage_sub,
86 ARRAY_SIZE(cmd_bootstage_sub));
87
88 if (c)
89 return c->cmd(cmdtp, flag, argc, argv);
90 else
91 return CMD_RET_USAGE;
92 }
93
94 U_BOOT_CMD(bootstage, 4, 1, do_boostage,
95 "Boot stage command",
96 " - check boot progress and timing\n"
97 "report - Print a report\n"
98 #if IS_ENABLED(CONFIG_BOOTSTAGE_STASH)
99 "stash [<start> [<size>]] - Stash data into memory\n"
100 "unstash [<start> [<size>]] - Unstash data from memory\n"
101 #endif
102 );
103