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