diff options
Diffstat (limited to 'util/uut/main.c')
-rw-r--r-- | util/uut/main.c | 770 |
1 files changed, 0 insertions, 770 deletions
diff --git a/util/uut/main.c b/util/uut/main.c deleted file mode 100644 index 146ddc0275..0000000000 --- a/util/uut/main.c +++ /dev/null @@ -1,770 +0,0 @@ -/* - * Copyright 2018 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include <errno.h> -#include <getopt.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> - -#include "com_port.h" -#include "compile_time_macros.h" -#include "main.h" -#include "misc_util.h" -#include "opr.h" - -/*---------------------------------------------------------------------------- - * Constant definitions - *--------------------------------------------------------------------------- - */ - -#define MAX_FILE_NAME_SIZE 512 -#define MAX_PARAM_SIZE 32 -#define MAX_MSG_SIZE 128 -#define MAX_SYNC_RETRIES 3 - -/* Default values */ -#define DEFAULT_BAUD_RATE 115200 -#define DEFAULT_PORT_NAME "ttyS0" -#define DEFAULT_DEV_NUM 0 -#define DEFAULT_FLASH_OFFSET 0 - -/* The magic number in monitor header */ -#define MONITOR_HDR_TAG 0xA5075001 -/* The location of monitor header */ -#define MONITOR_HDR_ADDR 0x200C3000 -/* The start address of the monitor little firmware to execute */ -#define MONITOR_ADDR 0x200C3020 -/* The start address to store the firmware segment to be programmed */ -#define FIRMWARE_START_ADDR 0x10090000 -/* Divide the ec firmware image into 4K byte */ -#define FIRMWARE_SEGMENT 0x1000 -/* Register address for chip ID */ -#define NPCX_SRID_CR 0x400C101C -/* Register address for device ID */ -#define NPCX_DEVICE_ID_CR 0x400C1022 -#define NPCX_FLASH_BASE_ADDR 0x64000000 - -/*--------------------------------------------------------------------------- - * Global variables - *--------------------------------------------------------------------------- - */ -bool verbose; -bool console; -struct comport_fields port_cfg; - -/*--------------------------------------------------------------------------- - * Local variables - *--------------------------------------------------------------------------- - */ - -static const char tool_name[] = {"LINUX UART Update Tool"}; -static const char tool_version[] = {"2.0.1"}; - -static char port_name[MAX_PARAM_SIZE]; -static char opr_name[MAX_PARAM_SIZE]; -static char file_name[MAX_FILE_NAME_SIZE]; -static char addr_str[MAX_PARAM_SIZE]; -static char size_str[MAX_PARAM_SIZE]; -static uint32_t baudrate; -static uint32_t dev_num; -static uint32_t flash_offset; -static bool auto_mode; -static bool read_flash_flag; - -struct npcx_chip_info { - uint8_t device_id; - uint8_t chip_id; - uint32_t flash_size; -}; - -const static struct npcx_chip_info chip_info[] = { - { - /* NPCX796FA */ - .device_id = 0x21, - .chip_id = 0x06, - .flash_size = 1024 * 1024, - }, - - { - /* NPCX796FB */ - .device_id = 0x21, - .chip_id = 0x07, - .flash_size = 1024 * 1024, - }, - - { - /* NPCX796FC */ - .device_id = 0x29, - .chip_id = 0x07, - .flash_size = 512 * 1024, - }, - - { - /* NPCX797FC */ - .device_id = 0x20, - .chip_id = 0x07, - .flash_size = 512 * 1024, - }, - - { - /* NPCX797WB */ - .device_id = 0x24, - .chip_id = 0x07, - .flash_size = 1024 * 1024, - }, - - { - /* NPCX797WC */ - .device_id = 0x2C, - .chip_id = 0x07, - .flash_size = 512 * 1024, - }, - - { - /* NPCX993F */ - .device_id = 0x25, - .chip_id = 0x09, - .flash_size = 512 * 1024, - }, - - { - /* NPCX996F */ - .device_id = 0x21, - .chip_id = 0x09, - .flash_size = 512 * 1024, - }, -}; -/*--------------------------------------------------------------------------- - * Functions prototypes - *--------------------------------------------------------------------------- - */ - -static void param_parse_cmd_line(int argc, char *argv[]); -static void param_check_opr_num(const char *opr); -static uint32_t param_get_file_size(const char *file_name); -static uint32_t param_get_str_size(char *string); -static void main_print_version(void); -static void tool_usage(void); -static void exit_uart_app(int32_t exit_status); - -enum EXIT_CODE { - EC_OK = 0x00, - EC_PORT_ERR = 0x01, - EC_BAUDRATE_ERR = 0x02, - EC_SYNC_ERR = 0x03, - EC_DEV_NUM_ERR = 0x04, - EC_OPR_MUM_ERR = 0x05, - EC_ALIGN_ERR = 0x06, - EC_FILE_ERR = 0x07, - EC_UNSUPPORTED_CMD_ERR = 0x08 -}; - -/*--------------------------------------------------------------------------- - * Function implementation - *--------------------------------------------------------------------------- - */ - -/*--------------------------------------------------------------------------- - * Function: image_auto_write - * - * Parameters: offset - The start address of the flash to write the firmware - * to. - * buffer - The buffer holds data of the firmware. - * file_size - the size to be programmed. - * Returns: 1 for a successful operation, 0 otherwise. - * Side effects: - * Description: - * Divide the firmware to segments and program them one by one. - *--------------------------------------------------------------------------- - */ -static bool image_auto_write(uint32_t offset, uint8_t *buffer, - uint32_t file_size) -{ - uint32_t data_buf[4]; - uint32_t addr, chunk_remain, file_seg, flash_index, seg; - uint32_t count, percent, total; - uint32_t i; - - flash_index = offset; - /* Monitor tag */ - data_buf[0] = MONITOR_HDR_TAG; - - file_seg = file_size; - total = 0; - while (file_seg) { - seg = (file_seg > FIRMWARE_SEGMENT) ? - FIRMWARE_SEGMENT : file_seg; - /* - * Check if the content of the segment is all 0xff. - * If yes, there is no need to write. - * Call the monitor to erase the segment only for - * time efficiency. - */ - for (i = 0; i < seg && buffer[i] == 0xFF; i++) - ; - if (i == seg) { - data_buf[1] = seg; - /* - * Set src_addr = 0 as a flag. When the monitor read 0 - * from this field, it will do sector erase only. - */ - data_buf[2] = 0; - data_buf[3] = flash_index; - opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR, - sizeof(data_buf)); - if (opr_execute_return(MONITOR_ADDR) != true) - return false; - file_seg -= seg; - flash_index += seg; - buffer += seg; - total += seg; - percent = total * 100 / file_size; - printf("\r[%d%%] %d/%d", percent, total, file_size); - fflush(stdout); - continue; - } - chunk_remain = seg; - addr = FIRMWARE_START_ADDR; - /* the size to be programmed */ - data_buf[1] = seg; - /* The source(RAM) address where the firmware is stored. */ - data_buf[2] = FIRMWARE_START_ADDR; - /* - * The offset of the flash where the segment to be programmed. - */ - data_buf[3] = flash_index; - /* Write the monitor header to RAM */ - opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR, - sizeof(data_buf)); - while (chunk_remain) { - count = (chunk_remain > MAX_RW_DATA_SIZE) ? - MAX_RW_DATA_SIZE : chunk_remain; - if (opr_write_chunk(buffer, addr, count) != true) - return false; - - addr += count; - buffer += count; - chunk_remain -= count; - total += count; - percent = total * 100 / file_size; - printf("\r[%d%%] %d/%d", percent, total, file_size); - } - fflush(stdout); - if (opr_execute_return(MONITOR_ADDR) != true) - return false; - file_seg -= seg; - flash_index += seg; - } - printf("\n"); - /* Clear the UUT header tag */ - data_buf[0] = 0; - opr_write_chunk((uint8_t *)data_buf, MONITOR_HDR_ADDR, 4); - return true; -} - -static bool get_flash_size(uint32_t *flash_size) -{ - uint8_t dev_id, chip_id, i; - - if (opr_read_chunk(&dev_id, NPCX_DEVICE_ID_CR, 1) != true) - return false; - - if (opr_read_chunk(&chip_id, NPCX_SRID_CR, 1) != true) - return false; - - for (i = 0; i < ARRAY_SIZE(chip_info); i++) { - if (chip_info[i].device_id == dev_id && - chip_info[i].chip_id == chip_id) { - *flash_size = chip_info[i].flash_size; - return true; - } - } - printf("Unknown NPCX device ID:0x%02x chip ID:0x%02x\n", - dev_id, chip_id); - - return false; -} - -/*--------------------------------------------------------------------------- - * Function: read_input_file - * - * Parameters: size - The size of input file. - * file_name - The name if input file. - * Returns: The address of the buffer allocated to stroe file content. - * Side effects: - * Description: - * Read the file content into an allocated buffer. - *--------------------------------------------------------------------------- - */ -static uint8_t *read_input_file(uint32_t size, const char *file_name) -{ - uint8_t *buffer; - FILE *input_fp; - - buffer = (uint8_t *)(malloc(size)); - if (!buffer) { - fprintf(stderr, "Cannot allocate %d bytes\n", size); - return NULL; - } - input_fp = fopen(file_name, "r"); - if (!input_fp) { - display_color_msg(FAIL, - "ERROR: cannot open file %s\n", file_name); - free(buffer); - return NULL; - } - if (fread(buffer, size, 1, input_fp) != 1) { - fprintf(stderr, "Cannot read %s\n", file_name); - fclose(input_fp); - free(buffer); - return NULL; - } - fclose(input_fp); - return buffer; -} - -/*--------------------------------------------------------------------------- - * Function: main - * - * Parameters: argc - Argument Count. - * argv - Argument Vector. - * Returns: 1 for a successful operation, 0 otherwise. - * Side effects: - * Description: - * Console application main operation. - *--------------------------------------------------------------------------- - */ -int main(int argc, char *argv[]) -{ - char *stop_str; - char aux_buf[MAX_FILE_NAME_SIZE]; - uint32_t size = 0; - uint32_t addr = 0; - enum sync_result sr; - uint8_t *buffer; - int sync_cnt; - - if (argc <= 1) - exit(EC_UNSUPPORTED_CMD_ERR); - - /* Setup defaults */ - strncpy(port_name, DEFAULT_PORT_NAME, sizeof(port_name)); - baudrate = DEFAULT_BAUD_RATE; - dev_num = DEFAULT_DEV_NUM; - flash_offset = DEFAULT_FLASH_OFFSET; - opr_name[0] = '\0'; - verbose = true; - console = false; - auto_mode = false; - read_flash_flag = false; - - param_parse_cmd_line(argc, argv); - - /* Configure COM Port parameters */ - port_cfg.baudrate = MAX(baudrate, BR_LOW_LIMIT); - port_cfg.byte_size = CS8; - port_cfg.flow_control = 0; - port_cfg.parity = 0; - port_cfg.stop_bits = 0; - - /* - * Open a ComPort device. If user haven't specified such, use ComPort 1 - */ - if (opr_open_port(port_name, port_cfg) != true) - exit(EC_PORT_ERR); - - if (baudrate == 0) { /* Scan baud rate range */ - opr_scan_baudrate(); - exit_uart_app(EC_OK); - } - - /* Verify Host and Device are synchronized */ - DISPLAY_MSG(("Performing a Host/Device synchronization check...\n")); - for (sync_cnt = 1; sync_cnt <= MAX_SYNC_RETRIES; sync_cnt++) { - sr = opr_check_sync(baudrate); - if (sr == SR_OK) - break; - /* - * If it fails, try it again up to three times. - * It might fail for garbage data drainage from H1, or - * for timeout due to unstable data transfer yet. - */ - display_color_msg(FAIL, - "Host/Device synchronization failed, error = %d," - " fail count = %d\n", sr, sync_cnt); - } - if (sync_cnt > MAX_SYNC_RETRIES) - exit_uart_app(EC_SYNC_ERR); - - if (auto_mode) { - size = param_get_file_size(file_name); - if (size == 0) - exit_uart_app(EC_FILE_ERR); - - buffer = read_input_file(size, file_name); - if (!buffer) - exit_uart_app(EC_FILE_ERR); - - printf("Write file %s at %d with %d bytes\n", - file_name, flash_offset, size); - if (image_auto_write(flash_offset, buffer, size)) { - printf("Flash Done.\n"); - free(buffer); - exit_uart_app(EC_OK); - } - free(buffer); - exit_uart_app(-1); - } - - if (read_flash_flag) { - uint32_t flash_size; - - if (get_flash_size(&flash_size)) { - printf("Read %d bytes from flash...\n", flash_size); - opr_read_mem(file_name, NPCX_FLASH_BASE_ADDR, - flash_size); - exit_uart_app(EC_OK); - } - - printf("Fail to read the flash size\n"); - exit_uart_app(-1); - } - - param_check_opr_num(opr_name); - - /* Write buffer data to chosen address */ - if (strcmp(opr_name, OPR_WRITE_MEM) == 0) { - addr = strtoull(addr_str, &stop_str, 0); - - if (console) { - /* - * Copy the input string to an auxiliary buffer, since - * string is altered by param_get_str_size - */ - memcpy(aux_buf, file_name, sizeof(file_name)); - /* Retrieve input size */ - size = param_get_str_size(file_name); - /* Ensure non-zero size */ - if (size == 0) - exit_uart_app(EC_FILE_ERR); - opr_write_mem((uint8_t *)(aux_buf), addr, size); - } else { - size = param_get_file_size(file_name); - if (size == 0) - exit_uart_app(EC_FILE_ERR); - buffer = read_input_file(size, file_name); - if (!buffer) - exit_uart_app(EC_FILE_ERR); - opr_write_mem(buffer, addr, size); - free(buffer); - } - } else if (strcmp(opr_name, OPR_READ_MEM) == 0) { - /* Read data to chosen address */ - - addr = strtoull(addr_str, &stop_str, 0); - size = strtoull(size_str, &stop_str, 0); - - opr_read_mem(file_name, addr, size); - } else if (strcmp(opr_name, OPR_EXECUTE_EXIT) == 0) { - /* Execute From Address a non-return code */ - - addr = strtoull(addr_str, &stop_str, 0); - - opr_execute_exit(addr); - exit_uart_app(EC_OK); - } else if (strcmp(opr_name, OPR_EXECUTE_CONT) == 0) { - /* Execute From Address a returnable code */ - - addr = strtoull(addr_str, &stop_str, 0); - - opr_execute_return(addr); - } else { - exit_uart_app(EC_UNSUPPORTED_CMD_ERR); - } - - exit_uart_app(EC_OK); - return 0; -} - -/*--------------------------------------------------------------------------- - * Function: param_parse_cmd_line - * - * Parameters: argc - Argument Count. - * argv - Argument Vector. - * Returns: None. - * Side effects: - * Description: - * Parse command line parameters. - *--------------------------------------------------------------------------- - */ - -static const struct option long_opts[] = { - {"version", 0, 0, 'v'}, - {"help", 0, 0, 'h'}, - {"quiet", 0, 0, 'q'}, - {"console", 0, 0, 'c'}, - {"auto", 0, 0, 'A'}, - {"read-flash", 0, 0, 'r'}, - {"baudrate", 1, 0, 'b'}, - {"opr", 1, 0, 'o'}, - {"port", 1, 0, 'p'}, - {"file", 1, 0, 'f'}, - {"addr", 1, 0, 'a'}, - {"size", 1, 0, 's'}, - {"offset", 1, 0, 'O'}, - {NULL, 0, 0, 0} -}; - -static const char *short_opts = "vhqcArb:o:p:f:a:s:O:?"; - -static void param_parse_cmd_line(int argc, char *argv[]) -{ - int opt, idx; - - while ((opt = getopt_long(argc, argv, short_opts, - long_opts, &idx)) != -1) { - - switch (opt) { - case 'v': - main_print_version(); - exit(EC_OK); - case 'h': - case '?': - tool_usage(); - opr_usage(); - exit(EC_OK); - case 'q': - verbose = false; - break; - case 'c': - console = true; - break; - case 'A': - auto_mode = true; - break; - case 'r': - read_flash_flag = true; - break; - case 'b': - if (sscanf(optarg, "%du", &baudrate) == 0) - exit(EC_BAUDRATE_ERR); - break; - case 'o': - strncpy(opr_name, optarg, sizeof(opr_name)); - opr_name[sizeof(opr_name)-1] = '\0'; - break; - case 'p': - strncpy(port_name, optarg, sizeof(port_name)); - port_name[sizeof(port_name)-1] = '\0'; - break; - case 'f': - strncpy(file_name, optarg, sizeof(file_name)); - file_name[sizeof(file_name)-1] = '\0'; - break; - case 'a': - strncpy(addr_str, optarg, sizeof(addr_str)); - addr_str[sizeof(addr_str)-1] = '\0'; - break; - case 's': - strncpy(size_str, optarg, sizeof(size_str)); - size_str[sizeof(size_str)-1] = '\0'; - break; - case 'O': - flash_offset = strtol(optarg, NULL, 0); - break; - } - } -} - -/*--------------------------------------------------------------------------- - * Function: param_check_opr_num - * - * Parameters: opr - Operation Number. - * Returns: none. - * Side effects: - * Description: - * Verify the validity of operation Number. - *--------------------------------------------------------------------------- - */ -static void param_check_opr_num(const char *opr) -{ - - if ((strcasecmp(opr, OPR_WRITE_MEM) != 0) && - (strcasecmp(opr, OPR_READ_MEM) != 0) && - (strcasecmp(opr, OPR_EXECUTE_EXIT) != 0) && - (strcasecmp(opr, OPR_EXECUTE_CONT) != 0)) { - display_color_msg(FAIL, - "ERROR: Operation %s not supported, Supported " - "operations are %s, %s, %s & %s\n", - opr, OPR_WRITE_MEM, OPR_READ_MEM, OPR_EXECUTE_EXIT, - OPR_EXECUTE_CONT); - exit_uart_app(EC_OPR_MUM_ERR); - } -} - -/*--------------------------------------------------------------------------- - * Function: param_get_file_size - * - * Parameters: file_name - input file name. - * Returns: size of file (in bytes). - * Side effects: - * Description: - * Retrieve the size (in bytes) of a given file. - *-------------------------------------------------------------------------- - */ -static uint32_t param_get_file_size(const char *file_name) -{ - struct stat fst; - - if (stat(file_name, &fst)) { - display_color_msg(FAIL, - "ERROR: Could not stat file [%s]\n", file_name); - return 0; - } - return fst.st_size; - -} - -/*--------------------------------------------------------------------------- - * Function: param_get_str_size - * - * Parameters: string - input string. - * Returns: size of double-words (in bytes). - * Side effects: - * Description: - * Retrieve the size (in bytes) of double-word values in a given string. - * E.g., given the string "1234 AB5678 FF", return 12 (for three - * double-words). - *--------------------------------------------------------------------------- - */ -static uint32_t param_get_str_size(char *string) -{ - uint32_t str_size = 0; - char seps[] = " "; - char *token = NULL; - - /* Verify string is non-NULL */ - if ((string == NULL) || (strlen(string) == 0)) { - display_color_msg(FAIL, - "ERROR: Zero length input string provided\n"); - return 0; - } - - /* Read first token from string */ - token = strtok(string, seps); - - /* Loop while there are tokens in "string" */ - while (token != NULL) { - str_size++; - token = strtok(NULL, seps); - } - - /* Refer to each token as a double-word */ - str_size *= sizeof(uint32_t); - return str_size; -} - -/*-------------------------------------------------------------------------- - * Function: tool_usage - * - * Parameters: none. - * Returns: none. - * Side effects: - * Description: - * Prints the console application help menu. - *-------------------------------------------------------------------------- - */ -static void tool_usage(void) -{ - printf("%s version %s\n\n", tool_name, tool_version); - printf("General switches:\n"); - printf(" -v, --version - Print version\n"); - printf(" -h, --help - Help menu\n"); - printf(" -q, --quiet - Suppress verbose mode (default is " - "verbose ON)\n"); - printf(" -c, --console - Print data to console (default is " - "print to file)\n"); - printf(" -p, --port <name> - Serial port name (default is %s)\n", - DEFAULT_PORT_NAME); - printf(" -b, --baudrate <num> - COM Port baud-rate (default is %d)\n", - DEFAULT_BAUD_RATE); - printf(" -A, --auto - Enable auto mode. (default is off)\n"); - printf(" -O, --offset <num> - With --auto, assign the offset of"); - printf(" flash where the image to be written.\n"); - printf(" -r, --read-flash - With --file=<file>, Read the whole" - " flash content and write it to <file>.\n"); - printf("\n"); - printf("Operation specific switches:\n"); - printf(" -o, --opr <name> - Operation number (see list below)\n"); - printf(" -f, --file <name> - Input/output file name\n"); - printf(" -a, --addr <num> - Start memory address\n"); - printf(" -s, --size <num> - Size of data to read\n"); - printf("\n"); -} - -/*-------------------------------------------------------------------------- - * Function: main_print_version - * - * Parameters: none - * Returns: none - * Side effects: - * Description: - * This routine prints the tool version - *-------------------------------------------------------------------------- - */ -static void main_print_version(void) -{ - printf("%s version %s\n\n", tool_name, tool_version); -} - -/*--------------------------------------------------------------------------- - * Function: exit_uart_app - * - * Parameters: none. - * Returns: none. - * Side effects: - * Description: - * Exit "nicely" the application. - *--------------------------------------------------------------------------- - */ -static void exit_uart_app(int32_t exit_status) -{ - if (opr_close_port() != true) - display_color_msg(FAIL, "ERROR: Port close failed.\n"); - - exit(exit_status); -} - -/*--------------------------------------------------------------------------- - * Function: display_color_msg - * - * Parameters: - * success - SUCCESS for successful message, FAIL for erroneous - * massage. - * fmt - Massage to dispaly (format and arguments). - * - * Returns: none - * Side effects: Using DISPLAY_MSG macro. - * Description: - * This routine displays a message using color attributes: - * In case of a successful message, use green foreground text on - * black background. - * In case of an erroneous message, use red foreground text on - * black background. - *--------------------------------------------------------------------------- - */ -void display_color_msg(bool success, const char *fmt, ...) -{ - va_list argptr; - - va_start(argptr, fmt); - vprintf(fmt, argptr); - va_end(argptr); -} |