summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.rules4
-rw-r--r--util/build.mk4
-rwxr-xr-xutil/flash_ec22
-rw-r--r--util/uut/cmd.c482
-rw-r--r--util/uut/cmd.h69
-rw-r--r--util/uut/com_port.h149
-rw-r--r--util/uut/l_com_port.c388
-rw-r--r--util/uut/lib_crc.c109
-rw-r--r--util/uut/lib_crc.h68
-rw-r--r--util/uut/main.c456
-rw-r--r--util/uut/main.h74
-rw-r--r--util/uut/opr.c511
-rw-r--r--util/uut/opr.h57
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 */