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