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