diff options
-rw-r--r-- | Makefile.rules | 4 | ||||
-rw-r--r-- | util/build.mk | 4 | ||||
-rwxr-xr-x | util/flash_ec | 22 | ||||
-rw-r--r-- | util/uut/cmd.c | 482 | ||||
-rw-r--r-- | util/uut/cmd.h | 69 | ||||
-rw-r--r-- | util/uut/com_port.h | 149 | ||||
-rw-r--r-- | util/uut/l_com_port.c | 388 | ||||
-rw-r--r-- | util/uut/lib_crc.c | 109 | ||||
-rw-r--r-- | util/uut/lib_crc.h | 68 | ||||
-rw-r--r-- | util/uut/main.c | 456 | ||||
-rw-r--r-- | util/uut/main.h | 74 | ||||
-rw-r--r-- | util/uut/opr.c | 511 | ||||
-rw-r--r-- | util/uut/opr.h | 57 |
13 files changed, 2380 insertions, 13 deletions
diff --git a/Makefile.rules b/Makefile.rules index 7cf6438b3c..7ae5761c24 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -14,7 +14,7 @@ build-utils := $(foreach u,$(build-util-bin),$(out)/util/$(u)) host-utils := $(foreach u,$(host-util-bin),$(out)/util/$(u)) build-art := $(foreach u,$(build-util-art),$(out)/$(u)) build-srcs := $(foreach u,$(build-util-bin),$(sort $($(u)-objs:%.o=util/%.c) $(wildcard util/$(u).c))) -host-srcs := $(foreach u,$(host-util-bin),$(sort $($(u)-objs:%.o=util/%.c) util/$(u).c)) +host-srcs := $(foreach u,$(host-util-bin),$(sort $($(u)-objs:%.o=util/%.c) $(wildcard util/$(u).c))) # Don't do a build test on the following boards: skip_boards = OWNERS host @@ -80,7 +80,7 @@ cmd_c_to_build = $(BUILDCC) $(BUILD_CFLAGS) \ cmd_c_to_vif = $(BUILDCC) $(BUILD_CFLAGS) $(STANDALONE_FLAGS) \ -MMD -MF $@.d -c $< -flto -o $@ cmd_c_to_host = $(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -MMD -MF $@.d -o $@ \ - $(sort $(foreach c,$($(*F)-objs),util/$(c:%.o=%.c)) $*.c) + $(sort $(foreach c,$($(*F)-objs),util/$(c:%.o=%.c)) $(wildcard $*.c)) cmd_cxx_to_host = $(HOSTCXX) -std=c++0x $(COMMON_WARN) $(HOST_CXXFLAGS)\ -I ./$($(notdir $@)_ROOT) -o $@ $(filter %.cc,$^) $($(notdir $@)_LIBS) cmd_host_test = ./util/run_host_test $* $(silent) diff --git a/util/build.mk b/util/build.mk index 10a97b17f5..13e4dc55d1 100644 --- a/util/build.mk +++ b/util/build.mk @@ -13,6 +13,10 @@ build-util-art+=util/export_taskinfo.so ifeq ($(CHIP),npcx) build-util-bin+=ecst endif +host-util-bin+=uartupdatetool +uartupdatetool-objs=uut/main.o uut/cmd.o uut/opr.o uut/l_com_port.o \ + uut/lib_crc.o +$(out)/util/uartupdatetool: HOST_CFLAGS+=-Iutil/ # Build on a limited subset of boards to save build time ifeq ($(BOARD),meowth_fp) build-util-bin+=ectool_servo diff --git a/util/flash_ec b/util/flash_ec index b0fbad8832..a91709ee7f 100755 --- a/util/flash_ec +++ b/util/flash_ec @@ -918,7 +918,7 @@ function flash_npcx_jtag() { function flash_npcx_uut() { TOOL_PATH="${EC_DIR}/build/${BOARD}/util:$PATH" - NPCX_UUT=$(PATH="${TOOL_PATH}" which Uartupdatetool) + NPCX_UUT=$(PATH="${TOOL_PATH}" which uartupdatetool) EC_UART="$(servo_ec_uart)" BUILD_PATH="${EC_DIR}/build/${BOARD}" @@ -944,9 +944,9 @@ function flash_npcx_uut() { info "${MCU} UART pty : ${EC_UART}" claim_pty ${EC_UART} - # Remove the prefix "/dev/" because Uartupdatetool will add it. + # Remove the prefix "/dev/" because uartupdatetool will add it. EC_UART=${EC_UART#/dev/} - MON_PARAMS="-port ${EC_UART} -baudrate 115200" + MON_PARAMS="--port ${EC_UART} --baudrate 115200" # Read the RO image size EC_IMG_SIZE=$(printf "%08X" $(stat -c "%s" ${IMG_RO})) @@ -959,13 +959,13 @@ function flash_npcx_uut() { info "Start to flash RO image.." # Start to program EC RO image # Load monitor header binary to address 0x200C3000 - ${NPCX_UUT} ${MON_PARAMS} -opr wr -addr ${MON_HDR_ADDR} -file ${T} + ${NPCX_UUT} ${MON_PARAMS} --opr wr --addr ${MON_HDR_ADDR} --file ${T} # Load monitor binary to address 0x200C3020 - ${NPCX_UUT} ${MON_PARAMS} -opr wr -addr ${MON_ADDR} -file ${MON} + ${NPCX_UUT} ${MON_PARAMS} --opr wr --addr ${MON_ADDR} --file ${MON} # Load RO image to Code RAM range. - ${NPCX_UUT} ${MON_PARAMS} -opr wr -addr ${EC_IMG_ADDR} -file ${IMG_RO} + ${NPCX_UUT} ${MON_PARAMS} --opr wr --addr ${EC_IMG_ADDR} --file ${IMG_RO} # Execute the monitor to program RO image on SPI flash - ${NPCX_UUT} ${MON_PARAMS} -opr call -addr ${MON_ADDR} + ${NPCX_UUT} ${MON_PARAMS} --opr call --addr ${MON_ADDR} # Read the RW image size EC_IMG_SIZE=$(printf "%08X" $(stat -c "%s" ${IMG_RW})) @@ -978,13 +978,13 @@ function flash_npcx_uut() { info "Start to flash RW image.." # Start to program EC RW image # Load monitor header binary to address 0x200C3000 - ${NPCX_UUT} ${MON_PARAMS} -opr wr -addr ${MON_HDR_ADDR} -file ${T} + ${NPCX_UUT} ${MON_PARAMS} --opr wr --addr ${MON_HDR_ADDR} --file ${T} # Load monitor binary to address 0x200C3020 - ${NPCX_UUT} ${MON_PARAMS} -opr wr -addr ${MON_ADDR} -file ${MON} + ${NPCX_UUT} ${MON_PARAMS} --opr wr --addr ${MON_ADDR} --file ${MON} # Load RW image to Code RAM range. - ${NPCX_UUT} ${MON_PARAMS} -opr wr -addr ${EC_IMG_ADDR} -file ${IMG_RW} + ${NPCX_UUT} ${MON_PARAMS} --opr wr --addr ${EC_IMG_ADDR} --file ${IMG_RW} # Execute the monitor to program RW image on SPI flash - ${NPCX_UUT} ${MON_PARAMS} -opr call -addr ${MON_ADDR} + ${NPCX_UUT} ${MON_PARAMS} --opr call --addr ${MON_ADDR} # Reconnect the EC-3PO interpreter to the UART. dut_control ${MCU}_ec3po_interp_connect:on || \ diff --git a/util/uut/cmd.c b/util/uut/cmd.c new file mode 100644 index 0000000000..97611bbf8e --- /dev/null +++ b/util/uut/cmd.c @@ -0,0 +1,482 @@ +/* + * 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. + */ + +/* This file creates the UART Program Protocol API commands. */ + +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include "cmd.h" +#include "lib_crc.h" +#include "main.h" + + /* Extracting Byte - 8 bit: MSB, LSB */ +#define MSB(u16) ((uint8_t)((uint16_t)(u16) >> 8)) +#define LSB(u16) ((uint8_t)(u16)) + +/*---------------------------------------------------------------------------- + * SPI Flash commands + *--------------------------------------------------------------------------- + */ + +#define SPI_READ_JEDEC_ID_CMD 0x9F +#define SPI_WRITE_ENABLE_CMD 0x06 +#define SPI_WRITE_DISABLE_CMD 0x04 +#define SPI_READ_STATUS_REG_CMD 0x05 +#define SPI_WRITE_STATUS_REG_CMD 0x01 +#define SPI_READ_DATA_CMD 0x03 +#define SPI_PAGE_PRGM_CMD 0x02 +#define SPI_SECTOR_ERASE_CMD 0xD8 +#define SPI_BULK_ERASE_CMD 0xC7 +#define SPI_READ_PID_CMD 0x90 + +union cmd_addr { + uint8_t c_adr[4]; + uint32_t h_adr; +}; + +/*---------------------------------------------------------------------------- + * Function implementation + *--------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * Function: cmd_create_sync + * + * Parameters: cmd_info - Pointer to a command buffer. + * cmd_len - Pointer to command length. + * Returns: none. + * Side effects: + * Description: + * Create a Host to Device SYNC protocol command. + * The total command length is written to 'cmd_len'. + *--------------------------------------------------------------------------- + */ +void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len) +{ + uint32_t len = 0; + + /* Build the command buffer */ + cmd_info[len++] = UFPP_H2D_SYNC_CMD; + + /* Return total command length */ + *cmd_len = len; +} + +/*--------------------------------------------------------------------------- + * Function: cmd_create_write + * + * Parameters: addr - Memory address to write to. + * size - Size of daya (in bytes) to write to memory. + * data_buf - Pointer to data buffer containing raw data to write. + * cmd_info - Pointer to a command buffer. + * cmd_len - Pointer to command length. + * Returns: none. + * Side effects: + * Description: + * Create a WRITE protocol command. + * The command buffer is enclosed by CRC, calculated on command + * information and raw data. + * The total command length is written to 'cmd_len'. + *--------------------------------------------------------------------------- + */ +void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf, + uint8_t *cmd_info, uint32_t *cmd_len) +{ + uint32_t i; + union cmd_addr adr_tr; + uint16_t crc = 0; + uint32_t len = 0; + + /* Build the command buffer */ + cmd_info[len++] = UFPP_WRITE_CMD; + cmd_info[len++] = (uint8_t)(size - 1); + + /* Insert Address */ + adr_tr.h_adr = addr; + cmd_info[len++] = adr_tr.c_adr[3]; + cmd_info[len++] = adr_tr.c_adr[2]; + cmd_info[len++] = adr_tr.c_adr[1]; + cmd_info[len++] = adr_tr.c_adr[0]; + + /* Insert data */ + memcpy(&cmd_info[len], data_buf, size); + len += size; + + /* Calculate CRC */ + for (i = 0; i < len; i++) + crc = update_crc(crc, (char)cmd_info[i]); + + /* Insert CRC */ + cmd_info[len++] = MSB(crc); + cmd_info[len++] = LSB(crc); + + /* Return total command length */ + *cmd_len = len; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_create_read + * + * Parameters: addr - Memory address to read from. + * size - Size of daya (in bytes) to read from memory. + * cmd_info - Pointer to a command buffer. + * cmd_len - Pointer to command length. + * Returns: none. + * Side effects: + * Description: + * Create a READ protocol command. + * The command buffer is enclosed by CRC, calculated on command + * information and raw data. + * The total command length is written to 'cmd_len'. + *--------------------------------------------------------------------------- + */ +void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info, + uint32_t *cmd_len) +{ + uint32_t i; + union cmd_addr adr_tr; + uint16_t crc = 0; + uint32_t len = 0; + + /* Build the command buffer */ + cmd_info[len++] = UFPP_READ_CMD; + cmd_info[len++] = (uint8_t)size; + + /* Insert Address */ + adr_tr.h_adr = addr; + cmd_info[len++] = adr_tr.c_adr[3]; + cmd_info[len++] = adr_tr.c_adr[2]; + cmd_info[len++] = adr_tr.c_adr[1]; + cmd_info[len++] = adr_tr.c_adr[0]; + + /* Calculate CRC */ + for (i = 0; i < len; i++) + crc = update_crc(crc, (char)cmd_info[i]); + + /* Insert CRC */ + cmd_info[len++] = MSB(crc); + cmd_info[len++] = LSB(crc); + + /* Return total command length */ + *cmd_len = len; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_create_exec + * + * Parameters: addr - Memory address to execute from. + * cmd_info - Pointer to a command buffer. + * cmd_len - Pointer to command length. + * Returns: none. + * Side effects: + * Description: + * Create an FCALL protocol command. + * The command buffer is enclosed by CRC, calculated on command + * information and raw data. + * The total command length is written to 'cmd_len'. + *--------------------------------------------------------------------------- + */ +void cmd_create_exec(uint32_t addr, uint8_t *cmd_info, uint32_t *cmd_len) +{ + uint32_t i; + union cmd_addr adr_tr; + uint16_t crc = 0; + uint32_t len = 0; + + /* Build the command buffer */ + cmd_info[len++] = UFPP_FCALL_CMD; + cmd_info[len++] = 0; + + /* Insert Address */ + adr_tr.h_adr = addr; + cmd_info[len++] = adr_tr.c_adr[3]; + cmd_info[len++] = adr_tr.c_adr[2]; + cmd_info[len++] = adr_tr.c_adr[1]; + cmd_info[len++] = adr_tr.c_adr[0]; + + /* Calculate CRC */ + for (i = 0; i < len; i++) + crc = update_crc(crc, (char)cmd_info[i]); + + /* Insert CRC */ + cmd_info[len++] = MSB(crc); + cmd_info[len++] = LSB(crc); + + /* Return total command length */ + *cmd_len = len; +} + +/*--------------------------------------------------------------------------- + * Function: cmd_build_sync + * + * Parameters: cmd_buf - Pointer to a command buffer. + * cmd_num - Pointer to command number. + * Returns: none. + * Description: + * Build a synchronization command buffer. + * The total command number is written to 'cmd_num'. + *--------------------------------------------------------------------------- + */ +void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num) +{ + uint32_t cmd = 0; + + cmd_create_sync(cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size); + cmd_buf[cmd].resp_size = 1; + cmd++; + + *cmd_num = cmd; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_build_exec_exit + * + * Parameters: addr - Memory address to execute from. + * cmd_buf - Pointer to a command buffer. + * cmd_num - Pointer to command number. + * Returns: none. + * Side effects: + * Description: + * Build an Excute command buffer. + * Command does not expect the executed code to return, that is, + * only FCALL protocol + * command code is expected. + * Determine the expected response size per each command. + * The total command number is written to 'cmd_num'. + *--------------------------------------------------------------------------- + */ +void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf, + uint32_t *cmd_num) +{ + uint32_t cmd = 0; + + cmd_create_exec(addr, cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size); + cmd_buf[cmd].resp_size = 1; + cmd++; + + *cmd_num = cmd; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_build_exec_ret + * + * Parameters: addr - Memory address to execute from. + * cmd_buf - Pointer to a command buffer. + * cmd_num - Pointer to command number. + * Returns: none. + * Side effects: + * Description: + * Build an Excute command buffer. + * Command expects the executed code to return, that is, + * FCALL_RSLT protocol command + * code is expected, together with the execution result. + * Determine the expected response size per each command. + * The total command number is written to 'cmd_num'. + *--------------------------------------------------------------------------- + */ +void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf, + uint32_t *cmd_num) +{ + uint32_t cmd = 0; + + cmd_create_exec(addr, cmd_buf[cmd].cmd, &cmd_buf[cmd].cmd_size); + cmd_buf[cmd].resp_size = 3; + cmd++; + + *cmd_num = cmd; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_disp_sync + * + * Parameters: resp_buf - Pointer to a response buffer. + * Returns: TRUE if successful, FALSE in the case of an error. + * Side effects: + * Description: + * Display SYNC command response information. + *--------------------------------------------------------------------------- + */ +bool cmd_disp_sync(uint8_t *resp_buf) +{ + if (resp_buf[0] == (uint8_t)(UFPP_D2H_SYNC_CMD)) { + display_color_msg(SUCCESS, "Host/Device are synchronized\n"); + return true; + } + + display_color_msg(FAIL, "Host/Device synchronization failed!!!\n"); + return false; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_disp_write + * + * Parameters: resp_buf - Pointer to a response buffer. + * resp_size - Response size. + * resp_num - Response packet number. + * Returns: TRUE if successful, FALSE in the case of an error. + * Side effects: + * Description: + * Display WRITE command response information. + *--------------------------------------------------------------------------- + */ +bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, + uint32_t total_size) +{ + if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) { + display_color_msg(SUCCESS, + "\rTransmitted packet of size %lu bytes, packet " + "[%lu]out of [%lu]", + resp_size, resp_num, total_size); + return true; + } + + display_color_msg(FAIL, "\nWrite packet [%lu] Failed\n", resp_num); + return false; +} + +/*----------------------------------------------------------------------------- + * Function: cmd_disp_read + * + * Parameters: resp_buf - Pointer to a response buffer. + * resp_size - Response size. + * resp_num - Response packet number. + * Returns: TRUE if successful, FALSE in the case of an error. + * Side effects: + * Description: + * Display READ command response information. + *--------------------------------------------------------------------------- + */ +bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, + uint32_t total_size) +{ + if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) { + display_color_msg(SUCCESS, + "\rReceived packet of size %lu bytes, packet [%lu] out " + "of [%lu]", + resp_size, resp_num, total_size); + return true; + } + + display_color_msg(FAIL, "\nRead packet [%lu] Failed\n", resp_num); + return false; +} + +/*---------------------------------------------------------------------------- + * Function: cmd_disp_data + * + * Parameters: resp_buf - Pointer to a response buffer. + * resp_size - Response size. + * Returns: none. + * Side effects: + * Description: + * Display raw data, read from memory. + *--------------------------------------------------------------------------- + */ +void cmd_disp_data(uint8_t *resp_buf, uint32_t resp_size) +{ + uint32_t idx; + uint32_t i; + + for (idx = 0; idx < resp_size; idx += 4) { + if ((idx % 16) == 0) + printf("\n"); + + printf("0x"); + for (i = 4; i > 0; i--) + printf("%02x", resp_buf[idx + i - 1]); + + if ((idx % 4) == 0) + printf(" "); + } + + printf("\n"); +} + +/*---------------------------------------------------------------------------- + * Function: cmd_disp_flash_erase_dev + * + * Parameters: resp_buf - Pointer to a response buffer. + * dev_num - Flash Device Number. + * Returns: none. + * Side effects: + * Description: + * Display BULK_ERASE command response information. + *--------------------------------------------------------------------------- + */ +void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num) +{ + if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) { + display_color_msg(SUCCESS, + "Flash Erase of device [%lu] Passed\n", dev_num); + } else { + display_color_msg( + FAIL, "Flash Erase of device [%lu] Failed\n", dev_num); + } +} + +/*--------------------------------------------------------------------------- + * Function: cmd_disp_flash_erase_sect + * + * Parameters: resp_buf - Pointer to a response buffer. + * Returns: none. + * Side effects: + * Description: + * Display BULK_ERASE command response information. + *--------------------------------------------------------------------------- + */ +void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num) +{ + if (resp_buf[0] == (uint8_t)(UFPP_WRITE_CMD)) { + display_color_msg(SUCCESS, + "Sector Erase of device [%lu] Passed\n", dev_num); + } else { + display_color_msg( + FAIL, "Sector Erase of device [%lu] Failed\n", dev_num); + } +} + +/*--------------------------------------------------------------------------- + * Function: cmd_disp_exec_exit + * + * Parameters: resp_buf - Pointer to a response buffer. + * Returns: none. + * Side effects: + * Description: + * Display Execute command response information. + *--------------------------------------------------------------------------- + */ +void cmd_disp_exec_exit(uint8_t *resp_buf) +{ + if (resp_buf[0] == (uint8_t)(UFPP_FCALL_CMD)) + display_color_msg(SUCCESS, "Execute Command Passed\n"); + else + display_color_msg(FAIL, "Execute Command Failed\n"); +} + +/*--------------------------------------------------------------------------- + * Function: cmd_disp_exec_ret + * + * Parameters: resp_buf - Pointer to a response buffer. + * Returns: none. + * Side effects: + * Description: + * Display Execute Result command response information. + *--------------------------------------------------------------------------- + */ +void cmd_disp_exec_ret(uint8_t *resp_buf) +{ + if (resp_buf[1] == (uint8_t)(UFPP_FCALL_RSLT_CMD)) { + display_color_msg(SUCCESS, + "Execute Command Passed, execution result is [0x%X]\n", + resp_buf[2]); + } else { + display_color_msg(FAIL, + "Execute Command Failed [0x%X] [0x%X], rslt=[0x%X]\n", + resp_buf[0], resp_buf[1], resp_buf[2]); + } +} diff --git a/util/uut/cmd.h b/util/uut/cmd.h new file mode 100644 index 0000000000..44cebbe989 --- /dev/null +++ b/util/uut/cmd.h @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#ifndef __UTIL_UUT_CMD_H +#define __UTIL_UUT_CMD_H + +#include <stdbool.h> + +/*--------------------------------------------------------------------------- + * Constant definitions + *--------------------------------------------------------------------------- + */ + +#define MAX_CMD_BUF_SIZE 10 +#define MAX_RESP_BUF_SIZE 512 + +enum uart_protocol_cmd { + UFPP_H2D_SYNC_CMD = 0x55, /* Single-Byte Host to Device */ + /* synchronization command */ + UFPP_D2H_SYNC_CMD = 0x5A, /* Single-Byte Device to Host */ + /* synchronization response */ + UFPP_WRITE_CMD = 0x07, /* Write command and response */ + UFPP_READ_CMD = 0x1C, /* Read command and response */ + UFPP_READ_CRC_CMD = 0x89, /* Read CRC command and response */ + UFPP_FCALL_CMD = 0x70, /* Call function command */ + UFPP_FCALL_RSLT_CMD = 0x73, /* Call function response */ + UFPP_SPI_CMD = 0x92, /* SPI specific command */ + UFPP_ERROR_CMD = 0xFF /* Error response */ +}; + +struct command_node { + uint8_t cmd[512]; + uint32_t cmd_size; + uint32_t resp_size; +}; + +/*--------------------------------------------------------------------------- + * Functions prototypes + *--------------------------------------------------------------------------- + */ + +void cmd_create_sync(uint8_t *cmd_info, uint32_t *cmd_len); +void cmd_create_write(uint32_t addr, uint32_t size, uint8_t *data_buf, + uint8_t *cmd_info, uint32_t *cmd_len); +void cmd_create_read(uint32_t addr, uint8_t size, uint8_t *cmd_info, + uint32_t *cmd_len); +void cmd_create_exec(uint32_t addr, uint8_t *cmd_info, uint32_t *cmd_len); + +void cmd_build_sync(struct command_node *cmd_buf, uint32_t *cmd_num); +void cmd_build_exec_exit(uint32_t addr, struct command_node *cmd_buf, + uint32_t *cmd_num); +void cmd_build_exec_ret(uint32_t addr, struct command_node *cmd_buf, + uint32_t *cmd_num); + +bool cmd_disp_sync(uint8_t *resp_buf); +bool cmd_disp_write(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, + uint32_t total_size); +bool cmd_disp_read(uint8_t *resp_buf, uint32_t resp_size, uint32_t resp_num, + uint32_t total_size); +void cmd_disp_data(uint8_t *resp_buf, uint32_t resp_size); +void cmd_disp_flash_erase_dev(uint8_t *resp_buf, uint32_t dev_num); +void cmd_disp_flash_erase_sect(uint8_t *resp_buf, uint32_t dev_num); +void cmd_disp_exec_exit(uint8_t *resp_buf); +void cmd_disp_exec_ret(uint8_t *resp_buf); + +#endif /* __UTIL_UUT_CMD_H */ diff --git a/util/uut/com_port.h b/util/uut/com_port.h new file mode 100644 index 0000000000..36331f2fb6 --- /dev/null +++ b/util/uut/com_port.h @@ -0,0 +1,149 @@ +/* + * 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. + */ + +/* This file defines the ComPort interface header file. */ + +#ifndef __UTIL_UUT_COM_PORT_H +#define __UTIL_UUT_COM_PORT_H + +#include <stdbool.h> +#include <termios.h> + +#ifdef __cplusplus +extern "C" { +#endif +/*--------------------------------------------------------------------------- + * ComPort INTERFACE + *--------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------- + * Constant definitions + *--------------------------------------------------------------------------- + */ +#define INVALID_HANDLE_VALUE -1 + +/*--------------------------------------------------------------------------- + * Type definitions + *--------------------------------------------------------------------------- + */ +#define COMP_PORT_PREFIX_1 "ttyS" +#define COMP_PORT_PREFIX_2 "ttyUSB" +#define COMP_PORT_PREFIX_3 "pts" + +struct comport_fields { + uint32_t baudrate; /* Baudrate at which running */ + tcflag_t byte_size; /* Number of bits/byte, 4-8 */ + tcflag_t parity; /* 0-4=None,Odd,Even,Mark,Space */ + uint8_t stop_bits; /* 0,1,2 = 1, 1.5, 2 */ + uint8_t flow_control; /* 0-none, 1-SwFlowControl,2-HwFlowControl */ +}; + +/*--------------------------------------------------------------------------- + * Function: int com_port_open() + * + * Purpose: Open the specified ComPort device. + * + * Params: com_port_dev_name - The name of the device to open + * com_port_fields - a struct filled with Comport settings, see + * definition above. + * + * Returns: INVALID_HANDLE_VALUE (-1) - invalid handle. + * Other value - Handle to be used in other Comport APIs + * + * Comments: The returned handle can be used for other Win32 API communication + * function by casting it to HANDLE. + * + *--------------------------------------------------------------------------- + */ +int com_port_open(const char *com_port_dev_name, + struct comport_fields com_port_fields); + +/*--------------------------------------------------------------------------- + * Function: int com_config_uart() + * + * Purpose: Configures the Uart port properties. + * + * Params: h_dev_drv - the opened handle returned by com_port_open() + * com_port_fields - a struct filled with Comport settings, see + * definition above. + * + * Returns: 1 if successful + * 0 in the case of an error. + * + *--------------------------------------------------------------------------- + */ +bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields); + +/*--------------------------------------------------------------------------- + * Function: bool ComPortClose() + * + * Purpose: Close the ComPort device specified by Handle + * + * Params: device_id - the opened handle returned by com_port_open() + * + * Returns: 1 if successful + * 0 in the case of an error. + * + *--------------------------------------------------------------------------- + */ +bool com_port_close(int device_id); + +/*--------------------------------------------------------------------------- + * Function: bool com_port_write_bin() + * + * Purpose: Send binary data through Comport + * + * Params: device_id - the opened handle returned by com_port_open() + * buffer - contains the binary data to send + * buf_size - the size of data to send + * + * Returns: 1 if successful + * 0 in the case of an error. + * + * Comments: The caller must ensure that buf_size is not bigger than + * Buffer size. + * + *--------------------------------------------------------------------------- + */ +bool com_port_write_bin(int device_id, const uint8_t *buffer, + uint32_t buf_size); + +/*--------------------------------------------------------------------------- + * Function: uint32_t com_port_read_bin() + * + * Purpose: Read a binary data from Comport + * + * Params: device_id - the opened handle returned by com_port_open() + * buffer - this buffer will contain the arrived data + * buf_size - maximum data size to read + * + * Returns: The number of bytes read. + * + * Comments: The caller must ensure that Size is not bigger than Buffer size. + * + *--------------------------------------------------------------------------- + */ +uint32_t com_port_read_bin(int device_id, uint8_t *buffer, uint32_t buf_size); + +/*--------------------------------------------------------------------------- + * Function: uint32_t com_port_wait_read() + * + * Purpose: Wait until a byte is received for read + * + * Params: device_id - the opened handle returned by com_port_open() + * + * Returns: The number of bytes that are waiting in RX queue. + * + *--------------------------------------------------------------------------- + */ +uint32_t com_port_wait_read(int device_id); + +#ifdef __cplusplus +} +#endif + +#endif /* __UTIL_UUT_COM_PORT_H */ diff --git a/util/uut/l_com_port.c b/util/uut/l_com_port.c new file mode 100644 index 0000000000..ccd29558ec --- /dev/null +++ b/util/uut/l_com_port.c @@ -0,0 +1,388 @@ +/* + * 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 <fcntl.h> +#include <poll.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <unistd.h> + +#include "com_port.h" +#include "main.h" + +/*--------------------------------------------------------------------------- + * Constant definitions + *--------------------------------------------------------------------------- + */ + +#define INBUFSIZE 2048 +#define OUTBUFSIZE 2048 +#define LOWER_THRESHOLD 16 +#define UPPER_THRESHOLD 512 +#define XOFF_CHAR 0x13 +#define XON_CHAR 0x11 + +#define UART_FIFO_SIZE 16 + +#define COMMAND_TIMEOUT 10000 /* 10 seconds */ + +/*--------------------------------------------------------------------------- + * Global variables + *--------------------------------------------------------------------------- + */ +static struct termios savetty; + +/*--------------------------------------------------------------------------- + * Functions prototypes + *--------------------------------------------------------------------------- + */ + +/*-------------------------------------------------------------------------- + * Local Function implementation + *-------------------------------------------------------------------------- + */ + +/*-------------------------------------------------------------------------- + * Function: convert_baudrate_to_baudrate_mask + * + * Parameters: + * baudrate - Bauderate value. + * + * Returns: Baudrate mask. + * Side effects: + * Description: + * This routine convert from baudrate mode to paudrate mask. + *-------------------------------------------------------------------------- + */ +static speed_t convert_baudrate_to_baudrate_mask(uint32_t baudrate) +{ + switch (baudrate) { + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + default: + return B0; + } +} + +/*------------------------------------------------------------------------- + * Function: set_read_blocking + * + * Parameters: + * dev_drv - The opened handle returned by com_port_open() + * block - TRUE means read in blocking mode + * FALSE means read in non-blocking mode. + * + * Returns: none + * Side effects: + * Description: + * This routine set/unset read blocking mode. + *-------------------------------------------------------------------------- + */ +void set_read_blocking(int dev_drv, bool block) +{ + struct termios tty; + + memset(&tty, 0, sizeof(tty)); + + if (tcgetattr(dev_drv, &tty) != 0) { + display_color_msg(FAIL, + "set_read_blocking Error: %d Fail to get attribute " + "from Device number %lu.\n", + errno, dev_drv); + return; + } + + tty.c_cc[VMIN] = block; + tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */ + + if (tcsetattr(dev_drv, TCSANOW, &tty) != 0) { + display_color_msg(FAIL, + "set_read_blocking Error: %d Fail to set attribute to " + "Device number %lu.\n", + errno, dev_drv); + } +} + +/*-------------------------------------------------------------------------- + * Global Function implementation + *-------------------------------------------------------------------------- + */ + +/****************************************************************************** + * Function: int com_config_uart() + * + * Purpose: Configures the Uart port properties. + * + * Params: h_dev_drv - the opened handle returned by com_port_open() + * com_port_fields - a struct filled with Comport settings, see + * definition above. + * + * Returns: 1 if successful + * 0 in the case of an error. + * + ***************************************************************************** + */ +bool com_config_uart(int h_dev_drv, struct comport_fields com_port_fields) +{ + struct termios tty; + speed_t baudrate; + + memset(&tty, 0, sizeof(tty)); + + if (tcgetattr(h_dev_drv, &tty) != 0) { + display_color_msg(FAIL, + "com_config_uart Error: Fail to get attribute from " + "Device number %lu.\n", + h_dev_drv); + return false; + } + + baudrate = convert_baudrate_to_baudrate_mask(com_port_fields.baudrate); + cfsetospeed(&tty, baudrate); + cfsetispeed(&tty, baudrate); + + tty.c_cflag |= baudrate; + + tty.c_cflag |= com_port_fields.byte_size; + + /* + * disable IGNBRK for mismatched speed tests; otherwise receive break + * as \000 chars + */ + + /* Set port to be in a "raw" mode. */ + tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | + ICRNL | IXON); + tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + + tty.c_oflag = ~OPOST; + tty.c_cc[VMIN] = 0; /* read doesn't block */ + tty.c_cc[VTIME] = 5; /* 0.5 seconds read timeout */ + + tty.c_iflag |= (com_port_fields.flow_control == 0x01) + ? (IXON | IXOFF) + : 0x00; /* xon/xoff ctrl */ + + tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ + /* enable reading */ + tty.c_cflag &= ~(PARENB | PARODD); /* shut off parity */ + tty.c_cflag |= com_port_fields.parity; + /* Stop bits */ + tty.c_cflag |= (com_port_fields.stop_bits == 0x02) ? CSTOPB : 0x00; + /* HW flow control */ + tty.c_cflag |= (com_port_fields.flow_control == 0x02) ? CRTSCTS : 0x00; + + /* Flush Port, then applies attributes */ + tcflush(h_dev_drv, TCIFLUSH); + + if (tcsetattr(h_dev_drv, TCSANOW, &tty) != 0) { + display_color_msg(FAIL, + "com_config_uart Error: %d setting port handle %d: %s.\n", + errno, h_dev_drv, strerror(errno)); + return false; + } + + return true; +} + +/****************************************************************************** + * Function: int com_port_open() + * + * Purpose: Open the specified ComPort device and return its handle. + * + * Params: com_port_dev_name - The name of the device to open + * com_port_fields - a struct filled with Comport settings + * + * Returns: INVALID_HANDLE_VALUE (-1) - invalid handle. + * Other value - Handle to be used in other Comport APIs + * + * Comments: The returned handle can be used for other Win32 API communication + * function. + * + ***************************************************************************** + */ +int com_port_open(const char *com_port_dev_name, + struct comport_fields com_port_fields) +{ + int port_handler; + + port_handler = open(com_port_dev_name, O_RDWR | O_NOCTTY); + + if (port_handler < 0) { + display_color_msg(FAIL, + "com_port_open Error %d opening %s: %s\n", + errno, com_port_dev_name, strerror(errno)); + return INVALID_HANDLE_VALUE; + } + + tcgetattr(port_handler, &savetty); + + if (!com_config_uart(port_handler, com_port_fields)) { + display_color_msg(FAIL, + "com_port_open() Error %d, Failed on com_config_uart() %s, " + "%s\n", + errno, com_port_dev_name, strerror(errno)); + return INVALID_HANDLE_VALUE; + } + + return port_handler; +} + +/****************************************************************************** + * Function: com_port_close() + * + * Purpose: Close the ComPort device specified by Handle + * + * Params: device_id - the opened handle returned by com_port_open() + * + * Returns: 1 if successful + * 0 in the case of an error. + * + ***************************************************************************** + */ +bool com_port_close(int device_id) +{ + tcsetattr(device_id, TCSANOW, &savetty); + + if (close(device_id) == INVALID_HANDLE_VALUE) { + display_color_msg(FAIL, + "com_port_close() Error: %d Device com%u was not opened, " + "%s.\n", + errno, (uint32_t)device_id, strerror(errno)); + return false; + } + + return true; +} + +/****************************************************************************** + * Function: com_port_write_bin() + * + * Purpose: Send binary data through Comport + * + * Params: device_id - the opened handle returned by com_port_open() + * buffer - contains the binary data to send + * buf_size - the size of data to send + * + * Returns: 1 if successful + * 0 in the case of an error. + * + * Comments: The caller must ensure that buf_size is not bigger than + * buffer size. + * + ***************************************************************************** + */ +bool com_port_write_bin(int device_id, const uint8_t *buffer, + uint32_t buf_size) +{ + uint32_t bytes_written; + + bytes_written = write(device_id, buffer, buf_size); + if (bytes_written != buf_size) { + display_color_msg(FAIL, + "com_port_write_bin() Error: %d Failed to write data to " + "Uart Port %d, %s.\n", + errno, (uint32_t)device_id, strerror(errno)); + + return false; + } + + return true; +} + +/****************************************************************************** + * Function: uint32_t com_port_read_bin() + * + * Purpose: Read a binary data from Comport + * + * Params: device_id - the opened handle returned by com_port_open() + * buffer - this buffer will contain the arrived data + * buf_size - maximum data size to read + * + * Returns: The number of bytes read. + * + * Comments: The caller must ensure that Size is not bigger than buffer size. + * + ***************************************************************************** + */ +uint32_t com_port_read_bin(int device_id, uint8_t *buffer, uint32_t buf_size) +{ + int32_t read_bytes; + + /* Reset read blocking mode */ + set_read_blocking(device_id, false); + + read_bytes = read(device_id, buffer, buf_size); + + if (read_bytes == -1) { + display_color_msg(FAIL, + "com_port_read_bin() Error: %d Device number %lu was not " + "opened, %s.\n", + errno, (uint32_t)device_id, strerror(errno)); + } + + return read_bytes; +} + +/****************************************************************************** + * Function: uint32_t com_port_wait_read() + * + * Purpose: Wait until a byte is received for read + * + * Params: device_id - the opened handle returned by com_port_open() + * + * Returns: The number of bytes that are waiting in RX queue. + * + ***************************************************************************** + */ +uint32_t com_port_wait_read(int device_id) +{ + int32_t bytes; + int32_t ret_val; + struct pollfd fds; + + /* Set read blocking mode */ + set_read_blocking(device_id, true); + + /* Wait up to 10 sec until byte is received for read. */ + fds.fd = device_id; + fds.events = POLLIN; + ret_val = poll(&fds, 1, COMMAND_TIMEOUT); + if (ret_val < 0) { + display_color_msg(FAIL, + "com_port_wait_read() Error: %d Device number %lu %s\n", + errno, (uint32_t)device_id, strerror(errno)); + return 0; + } + + bytes = 0; + + /* If data is ready for read. */ + if (ret_val > 0) { + /* Get number of bytes that are ready to be read. */ + if (ioctl(device_id, FIONREAD, &bytes) < 0) { + display_color_msg(FAIL, + "com_port_wait_for_read() Error: %d Device number " + "%lu %s\n", + errno, (uint32_t)device_id, strerror(errno)); + return 0; + } + } + + return bytes; +} diff --git a/util/uut/lib_crc.c b/util/uut/lib_crc.c new file mode 100644 index 0000000000..176e91327c --- /dev/null +++ b/util/uut/lib_crc.c @@ -0,0 +1,109 @@ +/* + * 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. + */ + +/* + * The file lib_crc.c contains the functions used for the calculation of + * CRC-16 cyclic redundancy values. + */ + +#include "lib_crc.h" + +/********************************************************************* + * * + * Library : lib_crc * + * File : lib_crc.c * + * Author : Lammert Bies 1999-2005 * + * E-mail : info@lammertbies.nl * + * Language : ANSI C * + * * + * * + * Description * + * =========== * + * * + * The file lib_crc.c contains the private and public func- * + * tions used for the calculation of CRC-16, CRC-CCITT and * + * CRC-32 cyclic redundancy values. * + * * + * * + * Dependencies * + * ============ * + * * + * lib_crc.h CRC definitions and prototypes * + * * + * * + * Modification history * + * ==================== * + * * + * Date Version Comment * + * * + * 2005-05-14 1.12 Added CRC-CCITT with start value 0 * + * * + * 2005-02-05 1.11 Fixed bug in CRC-DNP routine * + * * + * 2005-02-04 1.10 Added CRC-DNP routines * + * * + * 1999-02-21 1.01 Added FALSE and TRUE mnemonics * + * * + * 1999-01-22 1.00 Initial source * + * * + ********************************************************************* + */ + +/* CRC16 lookup table for polynom 0xA001 */ +static const unsigned short crc16_tab[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + +/********************************************************************* + * * + * unsigned short update_crc( unsigned long crc, unsigned char c ) * + * * + * The function update_crc calculates a new CRC-16 value * + * based on the previous value of the CRC and the next byte * + * of the data to be checked. * + * * + ********************************************************************* + */ +unsigned short update_crc(unsigned short crc, unsigned char c) +{ + unsigned short tmp; + + tmp = crc ^ (0x00ff & (unsigned short)c); + crc = (crc >> 8) ^ crc16_tab[tmp & 0xff]; + + return crc; +} diff --git a/util/uut/lib_crc.h b/util/uut/lib_crc.h new file mode 100644 index 0000000000..58db81c4e5 --- /dev/null +++ b/util/uut/lib_crc.h @@ -0,0 +1,68 @@ +/* + * 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. + */ + +/* + * This file contains public definitions and prototypes for the CRC functions. + */ + +#ifndef __UTIL_UUT_LIB_CRC_H +#define __UTIL_UUT_LIB_CRC_H + +/*-------------------------------------------------------------------*\ + * * + * Library : lib_crc * + * File : lib_crc.h * + * Author : Lammert Bies 1999-2005 * + * E-mail : info@lammertbies.nl * + * Language : ANSI C * + * * + * * + * Description * + * =========== * + * * + * The file lib_crc.h contains public definitions and proto- * + * types for the CRC functions present in lib_crc.c. * + * * + * * + * Dependencies * + * ============ * + * * + * none * + * * + * * + * Modification history * + * ==================== * + * * + * Date Version Comment * + * * + * 2005-02-14 1.12 Added CRC-CCITT with initial value 0 * + * * + * 2005-02-05 1.11 Fixed bug in CRC-DNP routine * + * * + * 2005-02-04 1.10 Added CRC-DNP routines * + * * + * 2005-01-07 1.02 Changes in tst_crc.c * + * * + * 1999-02-21 1.01 Added FALSE and TRUE mnemonics * + * * + * 1999-01-22 1.00 Initial source * + * * + *-------------------------------------------------------------------* + */ + +/*--------------------------------------------------------------------------- + * CRC library constant definitions + *--------------------------------------------------------------------------- + */ +#define CRC_VERSION "1.12" + +/*--------------------------------------------------------------------------- + * CRC library API + *--------------------------------------------------------------------------- + */ +unsigned short update_crc(unsigned short crc, unsigned char c); + +#endif /* __UTIL_UUT_LIB_CRC_H */ diff --git a/util/uut/main.c b/util/uut/main.c new file mode 100644 index 0000000000..4f54c62f29 --- /dev/null +++ b/util/uut/main.c @@ -0,0 +1,456 @@ +/* + * 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 <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 "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 + +/* Default values */ +#define DEFAULT_BAUD_RATE 115200 +#define DEFAULT_PORT_NAME "ttyS0" +#define DEFAULT_DEV_NUM 0 + +/*--------------------------------------------------------------------------- + * 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; + +/*--------------------------------------------------------------------------- + * 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(uint32_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: 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; + + 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; + opr_name[0] = '\0'; + verbose = true; + console = 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")); + sr = opr_check_sync(baudrate); + if (sr != SR_OK) { + display_color_msg(FAIL, + "Host/Device synchronization failed, error = %lu.\n", + sr); + exit_uart_app(EC_SYNC_ERR); + } + + param_check_opr_num(opr_name); + + /* Write buffer data to chosen address */ + if (strcmp(opr_name, OPR_WRITE_MEM) == 0) { + addr = strtoul(addr_str, &stop_str, 0); + + /* + * 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 */ + if (console) + size = param_get_str_size(aux_buf); + else + size = param_get_file_size(file_name); + + /* Ensure non-zero size */ + if (size == 0) + exit_uart_app(EC_FILE_ERR); + + opr_write_mem(file_name, addr, size); + } else if (strcmp(opr_name, OPR_READ_MEM) == 0) { + /* Read data to chosen address */ + + addr = strtoul(addr_str, &stop_str, 0); + size = strtoul(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 = strtoul(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 = strtoul(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'}, + {"baudrate", 1, 0, 'b'}, + {"opr", 1, 0, 'o'}, + {"port", 1, 0, 'p'}, + {"file", 1, 0, 'f'}, + {"addr", 1, 0, 'a'}, + {"size", 1, 0, 's'}, + {NULL, 0, 0, 0} +}; + +static char *short_opts = "vhqcb:o:p:f:a:s:?"; + +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 '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; + } + } +} + +/*--------------------------------------------------------------------------- + * 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", string); + 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(" --version - Print version\n"); + printf(" --help - Help menu\n"); + printf(" --quiet - Suppress verbose mode (default is " + "verbose ON)\n"); + printf(" --console - Print data to console (default is " + "print to file)\n"); + printf(" --port <name> - Serial port name (default is %s)\n", + DEFAULT_PORT_NAME); + printf(" --baudrate <num> - COM Port baud-rate (default is %d)\n", + DEFAULT_BAUD_RATE); + printf("\n"); + printf("Operation specific switches:\n"); + printf(" --opr <name> - Operation number (see list below)\n"); + printf(" --file <name> - Input/output file name\n"); + printf(" --addr <num> - Start memory address\n"); + printf(" --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(uint32_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, char *fmt, ...) +{ + va_list argptr; + + va_start(argptr, fmt); + vprintf(fmt, argptr); + va_end(argptr); +} diff --git a/util/uut/main.h b/util/uut/main.h new file mode 100644 index 0000000000..10c1391136 --- /dev/null +++ b/util/uut/main.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#ifndef __UTIL_UUT_MAIN_H +#define __UTIL_UUT_MAIN_H + +#include <stdbool.h> + +/*--------------------------------------------------------------------------- + * Constant definitions + *--------------------------------------------------------------------------- + */ +/* Maximum Read/Write data size per packet */ +#define MAX_RW_DATA_SIZE 256 + +/* Base for string conversion */ +#define BASE_DECIMAL 10 +#define BASE_HEXADECIMAL 16 + +/* Verbose control messages display */ +#define DISPLAY_MSG(msg) \ +{ \ + if (verbose) \ + printf msg; \ +} + +#define SUCCESS true +#define FAIL false + +#ifdef __cplusplus +extern "C" { +#endif + +/*-------------------------------------------------------------------------- + * Global variables + *-------------------------------------------------------------------------- + */ + +extern bool verbose; +extern bool console; + +/*-------------------------------------------------------------------------- + * Global functions + *-------------------------------------------------------------------------- + */ + +/*--------------------------------------------------------------------------- + * 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, char *fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* __UTIL_UUT_MAIN_H */ diff --git a/util/uut/opr.c b/util/uut/opr.c new file mode 100644 index 0000000000..4c79f0ba9b --- /dev/null +++ b/util/uut/opr.c @@ -0,0 +1,511 @@ +/* + * 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. + */ + +/* This file implements the UART console application operations. */ +#define _GNU_SOURCE +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "com_port.h" +#include "cmd.h" +#include "main.h" +#include "misc_util.h" +#include "opr.h" + +/*---------------------------------------------------------------------------- + * Global Variables + *--------------------------------------------------------------------------- + */ +int port_handle = INVALID_HANDLE_VALUE; + +/*---------------------------------------------------------------------------- + * Constant definitions + *--------------------------------------------------------------------------- + */ +#define MAX_PORT_NAME_SIZE 32 +#define OPR_TIMEOUT 10L /* 10 seconds */ +#define FLASH_ERASE_TIMEOUT 120L /* 120 seconds */ + +#define STS_MSG_MIN_SIZE 8 +#define STS_MSG_APP_END 0x09 +#define DUMMY_SIZE 2 + +#define MAX_SYNC_TRIALS 3 + +/*---------------------------------------------------------------------------- + * Global variables + *--------------------------------------------------------------------------- + */ +struct command_node cmd_buf[MAX_CMD_BUF_SIZE]; +uint8_t resp_buf[MAX_RESP_BUF_SIZE]; + +/*--------------------------------------------------------------------------- + * Functions prototypes + *--------------------------------------------------------------------------- + */ +static bool opr_send_cmds(struct command_node *cmd_buf, uint32_t cmd_num); + +/*---------------------------------------------------------------------------- + * Function implementation + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * Function: opr_usage + * + * Parameters: none. + * Returns: none. + * Side effects: + * Description: + * Prints the console application operation menu. + *--------------------------------------------------------------------------- + */ +void opr_usage(void) +{ + printf("Operations:\n"); + printf(" %s\t\t- Write To Memory/Flash\n", OPR_WRITE_MEM); + printf(" %s\t\t- Read From Memory/Flash\n", OPR_READ_MEM); + printf(" %s\t\t- Execute a non-return code\n", OPR_EXECUTE_EXIT); + printf(" %s\t\t- Execute a returnable code\n", OPR_EXECUTE_CONT); +} + +/*---------------------------------------------------------------------------- + * Function: opr_close_port + * + * Parameters: none + * Returns: + * Side effects: + * Description: + * This routine closes the opened COM port by the application + *--------------------------------------------------------------------------- + */ +bool opr_close_port(void) +{ + return com_port_close(port_handle); +} + +/*---------------------------------------------------------------------------- + * Function: opr_open_port + * + * Parameters: port_name - COM Port name. + * port_cfg - COM Port configuration structure. + * Returns: 1 if successful, 0 in the case of an error. + * Side effects: + * Description: + * Open a specified ComPort device. + *--------------------------------------------------------------------------- + */ +bool opr_open_port(const char *port_name, struct comport_fields port_cfg) +{ + char *full_port_name; + + if (asprintf(&full_port_name, "/dev/%s", port_name) == -1) + return false; + + if (port_handle > 0) + com_port_close(port_handle); + + port_handle = com_port_open((const char *)full_port_name, port_cfg); + + if (port_handle <= 0) { + display_color_msg(FAIL, "\nERROR: COM Port failed to open.\n"); + DISPLAY_MSG( + ("Please select the right serial port or check if " + "other serial\n")); + DISPLAY_MSG(("communication applications are opened.\n")); + return false; + } + + display_color_msg(SUCCESS, "Port %s Opened\n", full_port_name); + + return true; +} + +/*---------------------------------------------------------------------------- + * Function: opr_write_mem + * + * Parameters: input - Input (file-name/console), containing data to write. + * addr - Memory address to write to. + * size - Data size to write. + * Returns: none. + * Side effects: + * Description: + * Write data to memory, starting from a given address. + * Memory may be Flash (SPI), DRAM (DDR) or SRAM. + * The data is retrieved either from an input file or from a console. + * Data size is not limited. + * Data is sent in 256 bytes chunks (file mode) or 4 bytes chunks + * (console mode). + *--------------------------------------------------------------------------- + */ +void opr_write_mem(char *input, uint32_t addr, uint32_t size) +{ + FILE *input_file_id = NULL; + uint32_t cur_addr = addr; + uint8_t data_buf[256]; + uint32_t write_size; + uint32_t cmd_idx = 1; + char seps[] = " "; + char *token = NULL; + char *stop_str; + uint32_t block_size = (console) ? sizeof(uint32_t) : MAX_RW_DATA_SIZE; + struct command_node wr_cmd_buf; + + if (!console) { + input_file_id = fopen(input, "rb"); + + if (input_file_id == NULL) { + display_color_msg(FAIL, + "ERROR: could not open input file [%s]\n", + input); + return; + } + } + + /* Initialize response size */ + wr_cmd_buf.resp_size = 1; + + DISPLAY_MSG(("Writing [%d] bytes in [%d] packets\n", size, + ((size + (block_size - 1)) / block_size))); + + /* Read first token from string */ + if (console) + token = strtok(input, seps); + + /* Main write loop */ + while (true) { + if (console) { + /* Check if last token in string is reached */ + if (token == NULL) + break; + + /* + * Invert token to double-word and insert the value to + * data buffer + */ + (*(uint32_t *)data_buf) = + strtoul(token, &stop_str, BASE_HEXADECIMAL); + + /* Block size is fixed to a double-word */ + write_size = sizeof(uint32_t); + + /* Prepare the next iteration */ + token = strtok(NULL, seps); + } else { + /* Check if end of file is reached */ + if (feof(input_file_id)) + break; + + /* Read from file into data buffer */ + write_size = (uint32_t)fread(data_buf, 1, block_size, + input_file_id); + + /* + * In case we read the exact size of the file (e.g., + * 256 bytes), feof will return 0 because, even though + * the file pointer is at the end of the file, we have + * not attempted to read beyond the end. + * Only after trying to read additional byte will feof + * return a nonzero value + */ + if (write_size == 0) + break; + } + + cmd_create_write(cur_addr, write_size, data_buf, wr_cmd_buf.cmd, + &wr_cmd_buf.cmd_size); + if (opr_send_cmds(&wr_cmd_buf, 1) != true) + break; + + cmd_disp_write(resp_buf, write_size, cmd_idx, + ((size + (block_size - 1)) / block_size)); + + cur_addr += block_size; + cmd_idx++; + } + + DISPLAY_MSG(("\n")); + + if (!console) + fclose(input_file_id); +} + +/*---------------------------------------------------------------------------- + * Function: opr_read_mem + * + * Parameters: output - Output file name, containing data that was read. + * addr - Memory address to read from. + * size - Data size to read. + * Returns: none. + * Side effects: + * Description: + * Read data from memory, starting from a given address. + * Memory may be Flash (SPI), DRAM (DDR) or SRAM. + * The data is written into an output file, data size is limited + * as specified. + * Data is received in 256 bytes chunks. + *--------------------------------------------------------------------------- + */ +void opr_read_mem(char *output, uint32_t addr, uint32_t size) +{ + FILE *output_file_id = NULL; + uint32_t cur_addr; + uint32_t bytes_left; + uint32_t read_size; + uint32_t cmd_idx = 1; + struct command_node rd_cmd_buf; + + if (!console) { + output_file_id = fopen(output, "w+b"); + + if (output_file_id == NULL) { + display_color_msg(FAIL, + "ERROR: could not open output file [%s]\n", + output); + return; + } + } + + DISPLAY_MSG(("Reading [%d] bytes in [%d] packets\n", size, + ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE))); + + for (cur_addr = addr; cur_addr < (addr + size); + cur_addr += MAX_RW_DATA_SIZE) { + bytes_left = (uint32_t)(addr + size - cur_addr); + read_size = MIN(bytes_left, MAX_RW_DATA_SIZE); + + cmd_create_read(cur_addr, ((uint8_t)read_size - 1), + rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size); + rd_cmd_buf.resp_size = read_size + 3; + + if (opr_send_cmds(&rd_cmd_buf, 1) != true) + break; + + cmd_disp_read(resp_buf, read_size, cmd_idx, + ((size + (MAX_RW_DATA_SIZE - 1)) / MAX_RW_DATA_SIZE)); + + if (console) + cmd_disp_data((resp_buf + 1), read_size); + else + fwrite((resp_buf + 1), 1, read_size, output_file_id); + + cmd_idx++; + } + + DISPLAY_MSG(("\n")); + if (!console) + fclose(output_file_id); +} + +/*---------------------------------------------------------------------------- + * Function: opr_execute_exit + * + * Parameters: addr - Start address to execute from. + * Returns: none. + * Side effects: ROM-Code is not in UART command mode anymore. + * Description: + * Execute code starting from a given address. + * Memory address may be in Flash (SPI), DRAM (DDR) or SRAM. + * No further communication with thr ROM-Code is expected at this point. + *--------------------------------------------------------------------------- + */ +void opr_execute_exit(uint32_t addr) +{ + uint32_t cmd_num; + + cmd_build_exec_exit(addr, cmd_buf, &cmd_num); + if (opr_send_cmds(cmd_buf, cmd_num) != true) + return; + + cmd_disp_exec_exit(resp_buf); +} + +/*---------------------------------------------------------------------------- + * Function: opr_execute_return + * + * Parameters: addr - Start address to execute from. + * Returns: none. + * Side effects: + * Description: + * Execute code starting from a given address. + * Memory address may be in Flash (SPI), DRAM (DDR) or SRAM. + * The executed code should return with the execution result. + *--------------------------------------------------------------------------- + */ +void opr_execute_return(uint32_t addr) +{ + uint32_t cmd_num; + + cmd_build_exec_ret(addr, cmd_buf, &cmd_num); + if (opr_send_cmds(cmd_buf, cmd_num) != true) + return; + + cmd_disp_exec_ret(resp_buf); +} + +/*---------------------------------------------------------------------------- + * Function: opr_check_sync + * + * Parameters: + * baudrate - baud rate to check + * + * Returns: + * Side effects: + * Description: + * Checks whether the Host and the Core are synchoronized in the + * specified baud rate + *--------------------------------------------------------------------------- + */ +enum sync_result opr_check_sync(uint32_t baudrate) +{ + uint32_t cmd_num; + struct command_node *cur_cmd = cmd_buf; + uint32_t bytes_read = 0; + uint32_t i; + + port_cfg.baudrate = baudrate; + if (!com_config_uart(port_handle, port_cfg)) + return SR_ERROR; + + cmd_build_sync(cmd_buf, &cmd_num); + + if (!com_port_write_bin(port_handle, cur_cmd->cmd, cur_cmd->cmd_size)) + return SR_ERROR; + + /* Allow several SYNC trials */ + for (i = 0; i < MAX_SYNC_TRIALS; i++) { + bytes_read = com_port_read_bin(port_handle, resp_buf, 1); + + /* Quit if succeeded to read a response */ + if (bytes_read == 1) + break; + /* Otherwise give the ROM-Code time to answer */ + sleep(1); + } + + if (bytes_read == 0) + /* + * Unable to read a response from ROM-Code in a reasonable + * time + */ + return SR_TIMEOUT; + + if (resp_buf[0] != (uint8_t)(UFPP_D2H_SYNC_CMD)) + /* ROM-Code response is not as expected */ + return SR_WRONG_DATA; + + /* Good response */ + return SR_OK; +} + +/*---------------------------------------------------------------------------- + * Function: opr_scan_baudrate + * + * Parameters: none + * Returns: + * Side effects: + * Description: + * Scans the baud rate range by sending sync request to the core + * and prints the response + *--------------------------------------------------------------------------- + */ +bool opr_scan_baudrate(void) +{ + uint32_t baud = 0; + uint32_t step; + enum sync_result sr; + bool synched = false; + bool data_received = false; + + /* Scan with HUGE STEPS */ + /* BR_BIG_STEP is percents */ + step = (BR_LOW_LIMIT * BR_BIG_STEP) / 100; + for (baud = BR_LOW_LIMIT; baud < BR_HIGH_LIMIT; baud += step) { + sr = opr_check_sync(baud); + step = (baud * BR_BIG_STEP) / 100; + if (sr == SR_OK) { + printf("SR_OK: Baud rate - %d, resp_buf - 0x%x\n", + baud, resp_buf[0]); + synched = true; + step = (baud * BR_SMALL_STEP) / 100; + } else if (sr == SR_WRONG_DATA) { + printf("SR_WRONG_DATA: Baud rate - %d, resp_buf - " + "0x%x\n", baud, resp_buf[0]); + data_received = true; + step = (baud * BR_MEDIUM_STEP) / 100; + } else if (sr == SR_TIMEOUT) { + printf("SR_TIMEOUT: Baud rate - %d, resp_buf - 0x%x\n", + baud, resp_buf[0]); + + if (synched || data_received) + break; + } else if (sr == SR_ERROR) { + printf("SR_ERROR: Baud rate - %d, resp_buf - 0x%x\n", + baud, resp_buf[0]); + if (synched || data_received) + break; + } else + printf("Unknown error code: Baud rate - %d, resp_buf - " + "0x%x\n", baud, resp_buf[0]); + } + + return true; +} + +/*---------------------------------------------------------------------------- + * Function: opr_send_cmds + * + * Parameters: cmd_buf - Pointer to a Command Buffer. + * cmd_num - Number of commands to send. + * Returns: 1 if successful, 0 in the case of an error. + * Side effects: + * Description: + * Send a group of commands through COM port. + * A command is sent only after a valid response for the previous command + * was received. + *--------------------------------------------------------------------------- + */ +static bool opr_send_cmds(struct command_node *cmd_buf, uint32_t cmd_num) +{ + struct command_node *cur_cmd = cmd_buf; + uint32_t cmd; + uint32_t read; + time_t start; + double elapsed_time; + + for (cmd = 0; cmd < cmd_num; cmd++, cur_cmd++) { + if (com_port_write_bin(port_handle, cur_cmd->cmd, + cur_cmd->cmd_size) == true) { + time(&start); + + do { + read = com_port_wait_read(port_handle); + elapsed_time = difftime(time(NULL), start); + } while ((read < cur_cmd->resp_size) && + (elapsed_time <= OPR_TIMEOUT)); + com_port_read_bin(port_handle, resp_buf, + cur_cmd->resp_size); + + if (elapsed_time > OPR_TIMEOUT) + display_color_msg(FAIL, + "ERROR: [%d] bytes received for read, " + "[%d] bytes are expected\n", + read, cur_cmd->resp_size); + } else { + display_color_msg(FAIL, + "ERROR: Failed to send Command number %d\n", + cmd); + return false; + } + } + + return true; +} + diff --git a/util/uut/opr.h b/util/uut/opr.h new file mode 100644 index 0000000000..21e05b7daf --- /dev/null +++ b/util/uut/opr.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +/* This file defines the UART console application operations. */ + +#ifndef __UTIL_UUT_OPR_H +#define __UTIL_UUT_OPR_H + +/*--------------------------------------------------------------------------- + * Constant definitions + *--------------------------------------------------------------------------- + */ + +/* Baud rate scan steps: */ +#define BR_BIG_STEP 20 /* in percents from current baud rate */ +#define BR_MEDIUM_STEP 10 /* in percents from current baud rate */ +#define BR_SMALL_STEP 1 /* in percents from current baud rate */ +#define BR_MIN_STEP 5 /* in absolute baud rate units */ +#define BR_LOW_LIMIT 400 /* Automatic BR detection starts at this value */ +#define BR_HIGH_LIMIT 150000 /* Automatic BR detection ends at this value */ + +#define OPR_WRITE_MEM "wr" /* Write To Memory/Flash */ +#define OPR_READ_MEM "rd" /* Read From Memory/Flash */ +#define OPR_EXECUTE_EXIT "go" /* Execute a non-return code */ +#define OPR_EXECUTE_CONT "call" /* Execute returnable code */ + +enum sync_result { + SR_OK = 0x00, + SR_WRONG_DATA = 0x01, + SR_TIMEOUT = 0x02, + SR_ERROR = 0x03 +}; + +/*---------------------------------------------------------------------------- + * External Variables + *--------------------------------------------------------------------------- + */ +extern struct comport_fields port_cfg; + +/*--------------------------------------------------------------------------- + * Functions prototypes + *--------------------------------------------------------------------------- + */ + +void opr_usage(void); +bool opr_close_port(void); +bool opr_open_port(const char *port_name, struct comport_fields port_cfg); +void opr_write_mem(char *input, uint32_t addr, uint32_t size); +void opr_read_mem(char *output, uint32_t addr, uint32_t size); +void opr_execute_exit(uint32_t addr); +void opr_execute_return(uint32_t addr); +bool opr_scan_baudrate(void); +enum sync_result opr_check_sync(uint32_t baudrate); +#endif /* __UTIL_UUT_OPR_H */ |