xref: /rk3399_rockchip-uboot/cmd/script_update.c (revision 1bb4e9bafc0ca58e92f894fcc8eddb0a4ed571d6)
1 /*
2  * (C) Copyright 2022 Rockchip Electronics Co., Ltd.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <malloc.h>
9 
10 /*
11  * Script file example:
12  **************************
13  * > # script file start
14  * > echo "hello world"
15  * > % script file end
16  **************************
17  */
18 #define SCRIPT_FILE_MAX_SIZE	(12 * 1024)
19 #define SCRIPT_FILE_COMMENT	'#'
20 #define SCRIPT_FILE_END		'%'
21 #define IS_COMMENT(x)		(SCRIPT_FILE_COMMENT == (x))
22 #define IS_FILE_END(x)		(SCRIPT_FILE_END == (x))
23 #define IS_LINE_END(x)		('\r' == (x) || '\n' == (x))
24 #define MAX_LINE_SIZE		8000
25 
26 static char *script_next_line(char **line_buf_ptr)
27 {
28 	char *line_buf = (*line_buf_ptr);
29 	char *next_line;
30 	int i = 0;
31 
32 	/* strip '\r', '\n' and comment */
33 	while (1) {
34 		/* strip '\r' & '\n' */
35 		if (IS_LINE_END(line_buf[0])) {
36 			line_buf++;
37 		/* strip comment */
38 		} else if (IS_COMMENT(line_buf[0])) {
39 			for (i = 0; !IS_LINE_END(line_buf[0]) && i <= MAX_LINE_SIZE; i++)
40 				line_buf++;
41 
42 			if (i > MAX_LINE_SIZE) {
43 				line_buf[0] = SCRIPT_FILE_END;
44 				printf("Error: max line length is %d!!!\n", MAX_LINE_SIZE);
45 				break;
46 			}
47 		} else {
48 			break;
49 		}
50 	}
51 
52 	/* get next line */
53 	if (IS_FILE_END(line_buf[0])) {
54 		next_line = NULL;
55 	} else {
56 		next_line = line_buf;
57 		for (i = 0; !IS_LINE_END(line_buf[0]) && i <= MAX_LINE_SIZE; i++)
58 			line_buf++;
59 
60 		if (i > MAX_LINE_SIZE) {
61 			next_line = NULL;
62 			printf("Error: max line length is %d!!!\n", MAX_LINE_SIZE);
63 		} else {
64 			line_buf[0] = '\0';
65 			*line_buf_ptr = line_buf + 1;
66 		}
67 	}
68 
69 	return next_line;
70 }
71 
72 static int do_script(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
73 {
74 	char *next_line, *script, *buf;
75 	ulong addr;
76 
77 	if (argc != 2 || !argv[1])
78 		return CMD_RET_USAGE;
79 
80 	addr = simple_strtoul(argv[1], NULL, 16);
81 	if (!addr)
82 		return CMD_RET_USAGE;
83 
84 	buf = calloc(SCRIPT_FILE_MAX_SIZE, 1);
85 	if (!buf)
86 		return CMD_RET_FAILURE;
87 
88 	script = buf;
89 	memcpy(buf, (char *)addr, SCRIPT_FILE_MAX_SIZE);
90 	while ((next_line = script_next_line(&script)) != NULL) {
91 		printf("\n$ %s\n", next_line);
92 		run_command(next_line, 0);
93 	}
94 
95 	free(buf);
96 
97 	return CMD_RET_SUCCESS;
98 }
99 
100 static int do_sd_update(cmd_tbl_t *cmdtp, int flag,
101 			int argc, char * const argv[])
102 {
103 	char cmd[128];
104 	char *buf;
105 	int ret;
106 
107 	buf = memalign(ARCH_DMA_MINALIGN, SCRIPT_FILE_MAX_SIZE * 2);
108 	if (!buf)
109 		return CMD_RET_FAILURE;
110 
111 	snprintf(cmd, 128,
112 		 "fatload mmc 1 0x%08lx sd_update.txt && script 0x%08lx",
113 		 (ulong)buf, (ulong)buf);
114 	ret = run_command(cmd, 0);
115 	free(buf);
116 
117 	return ret;
118 }
119 
120 static int do_usb_update(cmd_tbl_t *cmdtp, int flag,
121 			 int argc, char * const argv[])
122 {
123 	char cmd[128];
124 	char *buf;
125 	int ret;
126 
127 	buf = memalign(ARCH_DMA_MINALIGN, SCRIPT_FILE_MAX_SIZE * 2);
128 	if (!buf)
129 		return CMD_RET_FAILURE;
130 
131 	snprintf(cmd, 128,
132 		 "usb reset && fatload usb 0 0x%08lx usb_update.txt && script 0x%08lx",
133 		 (ulong)buf, (ulong)buf);
134 	ret = run_command(cmd, 0);
135 	free(buf);
136 
137 	return ret;
138 }
139 
140 static int do_tftp_update(cmd_tbl_t *cmdtp, int flag,
141 			  int argc, char * const argv[])
142 {
143 	char cmd[128];
144 	char *buf;
145 	int dhcp = 0;
146 	int ret;
147 
148 	if ((argc > 1) && !strcmp(argv[1], "-d"))
149 		dhcp = 1;
150 
151 	buf = memalign(ARCH_DMA_MINALIGN, SCRIPT_FILE_MAX_SIZE * 2);
152 	if (!buf)
153 		return CMD_RET_FAILURE;
154 
155 	if (dhcp)
156 		run_command("dhcp", 0);
157 
158 	snprintf(cmd, 128,
159 		 "tftp 0x%08lx tftp_update.txt && script 0x%08lx",
160 		 (ulong)buf, (ulong)buf);
161 	ret = run_command(cmd, 0);
162 	free(buf);
163 
164 	return ret;
165 }
166 
167 U_BOOT_CMD(
168 	script, 2, 1, do_script,
169 	"Run a script", "[file addr]"
170 );
171 
172 U_BOOT_CMD(
173 	sd_update, 1, 1, do_sd_update,
174 	"sdcard auto upgrade", ""
175 );
176 
177 U_BOOT_CMD(
178 	usb_update, 1, 1, do_usb_update,
179 	"usb auto upgrade", ""
180 );
181 
182 U_BOOT_CMD(
183 	tftp_update, 2, 1, do_tftp_update,
184 	"tftp auto upgrade", "[-d]"
185 );
186 
187