xref: /rk3399_rockchip-uboot/cmd/script_update.c (revision 0ac34d7f9add9e5c1bf196ada4f60b604975eaa6)
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;
76a951a295SJoseph Chen 
77a951a295SJoseph Chen 	if (argc != 2 || !argv[1])
78a951a295SJoseph Chen 		return CMD_RET_USAGE;
79a951a295SJoseph Chen 
80a951a295SJoseph Chen 	addr = simple_strtoul(argv[1], NULL, 16);
81a951a295SJoseph Chen 	if (!addr)
82a951a295SJoseph Chen 		return CMD_RET_USAGE;
83a951a295SJoseph Chen 
84a951a295SJoseph Chen 	buf = calloc(SCRIPT_FILE_MAX_SIZE, 1);
85a951a295SJoseph Chen 	if (!buf)
86a951a295SJoseph Chen 		return CMD_RET_FAILURE;
87a951a295SJoseph Chen 
88a951a295SJoseph Chen 	script = buf;
89a951a295SJoseph Chen 	memcpy(buf, (char *)addr, SCRIPT_FILE_MAX_SIZE);
90a951a295SJoseph Chen 	while ((next_line = script_next_line(&script)) != NULL) {
91a951a295SJoseph Chen 		printf("\n$ %s\n", next_line);
92a951a295SJoseph Chen 		run_command(next_line, 0);
93a951a295SJoseph Chen 	}
94a951a295SJoseph Chen 	free(buf);
95a951a295SJoseph Chen 
96a951a295SJoseph Chen 	return CMD_RET_SUCCESS;
97a951a295SJoseph Chen }
98a951a295SJoseph Chen 
99a951a295SJoseph Chen static int do_sd_update(cmd_tbl_t *cmdtp, int flag,
100a951a295SJoseph Chen 			int argc, char * const argv[])
101a951a295SJoseph Chen {
102a951a295SJoseph Chen 	char cmd[128];
103a951a295SJoseph Chen 	char *buf;
104a951a295SJoseph Chen 	int ret;
105a951a295SJoseph Chen 
106a951a295SJoseph Chen 	buf = memalign(ARCH_DMA_MINALIGN, SCRIPT_FILE_MAX_SIZE * 2);
107a951a295SJoseph Chen 	if (!buf)
108a951a295SJoseph Chen 		return CMD_RET_FAILURE;
109a951a295SJoseph Chen 
110*0ac34d7fSJoseph Chen 	snprintf(cmd, 128, "fatload mmc 1 0x%08lx sd_update.txt", (ulong)buf);
111a951a295SJoseph Chen 	ret = run_command(cmd, 0);
112*0ac34d7fSJoseph Chen 	if (!ret) {
113*0ac34d7fSJoseph Chen 		snprintf(cmd, 128, "script 0x%08lx", (ulong)buf);
114*0ac34d7fSJoseph Chen 		ret = run_command(cmd, 0);
115*0ac34d7fSJoseph Chen 	}
116a951a295SJoseph Chen 	free(buf);
117a951a295SJoseph Chen 
118a951a295SJoseph Chen 	return ret;
119a951a295SJoseph Chen }
120a951a295SJoseph Chen 
121a951a295SJoseph Chen static int do_usb_update(cmd_tbl_t *cmdtp, int flag,
122a951a295SJoseph Chen 			 int argc, char * const argv[])
123a951a295SJoseph Chen {
124a951a295SJoseph Chen 	char cmd[128];
125a951a295SJoseph Chen 	char *buf;
126a951a295SJoseph Chen 	int ret;
127a951a295SJoseph Chen 
128a951a295SJoseph Chen 	buf = memalign(ARCH_DMA_MINALIGN, SCRIPT_FILE_MAX_SIZE * 2);
129a951a295SJoseph Chen 	if (!buf)
130a951a295SJoseph Chen 		return CMD_RET_FAILURE;
131a951a295SJoseph Chen 
132*0ac34d7fSJoseph Chen 	snprintf(cmd, 128, "usb reset");
133a951a295SJoseph Chen 	ret = run_command(cmd, 0);
134*0ac34d7fSJoseph Chen 	if (!ret) {
135*0ac34d7fSJoseph Chen 		snprintf(cmd, 128, "fatload usb 0 0x%08lx usb_update.txt", (ulong)buf);
136*0ac34d7fSJoseph Chen 		ret = run_command(cmd, 0);
137*0ac34d7fSJoseph Chen 	}
138*0ac34d7fSJoseph Chen 	if (!ret) {
139*0ac34d7fSJoseph Chen 		snprintf(cmd, 128, "script 0x%08lx", (ulong)buf);
140*0ac34d7fSJoseph Chen 		ret = run_command(cmd, 0);
141*0ac34d7fSJoseph Chen 	}
142a951a295SJoseph Chen 	free(buf);
143a951a295SJoseph Chen 
144a951a295SJoseph Chen 	return ret;
145a951a295SJoseph Chen }
146a951a295SJoseph Chen 
147a951a295SJoseph Chen static int do_tftp_update(cmd_tbl_t *cmdtp, int flag,
148a951a295SJoseph Chen 			  int argc, char * const argv[])
149a951a295SJoseph Chen {
150a951a295SJoseph Chen 	char cmd[128];
151a951a295SJoseph Chen 	char *buf;
152a951a295SJoseph Chen 	int dhcp = 0;
153a951a295SJoseph Chen 	int ret;
154a951a295SJoseph Chen 
155a951a295SJoseph Chen 	if ((argc > 1) && !strcmp(argv[1], "-d"))
156a951a295SJoseph Chen 		dhcp = 1;
157a951a295SJoseph Chen 
158a951a295SJoseph Chen 	buf = memalign(ARCH_DMA_MINALIGN, SCRIPT_FILE_MAX_SIZE * 2);
159a951a295SJoseph Chen 	if (!buf)
160a951a295SJoseph Chen 		return CMD_RET_FAILURE;
161a951a295SJoseph Chen 
162a951a295SJoseph Chen 	if (dhcp)
163a951a295SJoseph Chen 		run_command("dhcp", 0);
164a951a295SJoseph Chen 
165*0ac34d7fSJoseph Chen 	snprintf(cmd, 128, "tftp 0x%08lx tftp_update.txt", (ulong)buf);
166a951a295SJoseph Chen 	ret = run_command(cmd, 0);
167*0ac34d7fSJoseph Chen 	if (!ret) {
168*0ac34d7fSJoseph Chen 		snprintf(cmd, 128, "script 0x%08lx", (ulong)buf);
169*0ac34d7fSJoseph Chen 		ret = run_command(cmd, 0);
170*0ac34d7fSJoseph Chen 	}
171a951a295SJoseph Chen 	free(buf);
172a951a295SJoseph Chen 
173a951a295SJoseph Chen 	return ret;
174a951a295SJoseph Chen }
175a951a295SJoseph Chen 
176a951a295SJoseph Chen U_BOOT_CMD(
177a951a295SJoseph Chen 	script, 2, 1, do_script,
178a951a295SJoseph Chen 	"Run a script", "[file addr]"
179a951a295SJoseph Chen );
180a951a295SJoseph Chen 
181a951a295SJoseph Chen U_BOOT_CMD(
182a951a295SJoseph Chen 	sd_update, 1, 1, do_sd_update,
183a951a295SJoseph Chen 	"sdcard auto upgrade", ""
184a951a295SJoseph Chen );
185a951a295SJoseph Chen 
186a951a295SJoseph Chen U_BOOT_CMD(
187a951a295SJoseph Chen 	usb_update, 1, 1, do_usb_update,
188a951a295SJoseph Chen 	"usb auto upgrade", ""
189a951a295SJoseph Chen );
190a951a295SJoseph Chen 
191a951a295SJoseph Chen U_BOOT_CMD(
192a951a295SJoseph Chen 	tftp_update, 2, 1, do_tftp_update,
193a951a295SJoseph Chen 	"tftp auto upgrade", "[-d]"
194a951a295SJoseph Chen );
195a951a295SJoseph Chen 
196