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