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