summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCHLin <CHLIN56@nuvoton.com>2019-08-21 18:34:53 +0800
committerCommit Bot <commit-bot@chromium.org>2019-08-26 04:50:05 +0000
commitc2a4febcdcd069ec60245fdeeb248899b4dc1b9f (patch)
tree4a422c11ab9370077ed7df71be5338b985d61954
parent54215f3637f4483b671282bc83f2763229710217 (diff)
downloadchrome-ec-c2a4febcdcd069ec60245fdeeb248899b4dc1b9f.tar.gz
util: UartUpdateTool: support "--read-flash" flag
This patch creates a table to map the chip/device ID to the size of the internal flash. When the "--read-flash" flag is given, uut will read the device ID and chip ID registers and use them to look up the table to get the flash size. Afterward, uut will read the flash content from flash according to the size and write it to the file specified by the "--file" flag. BUG=b:139752920 BRANCH=none TEST=manually ran the following commands on yorp and grunt. dut-control --port=9999 ec_ec3po_interp_connect:off dut-control --port=9999 ccd_keepalive_en:on dut-control --port=9999 ccd_ec_boot_mode_uut:on dut-control --port=9999 cold_reset:on dut-control --port=9999 cold_reset:off dut-control --port=9999 ccd_ec_boot_mode_uut:off ./build/${BOARD}/util/uartupdatetool --port=pts/15 --baudrate=115200 --read-flash --file=<file_name> diff ./build/yorp/ec.bin <file_name> Change-Id: If802c76e1690af2d84edea950d3755fa87347159 Signed-off-by: CHLin <CHLIN56@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1763888 Reviewed-by: Namyoon Woo <namyoon@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: CH Lin <chlin56@nuvoton.com> Tested-by: CH Lin <chlin56@nuvoton.com>
-rw-r--r--util/uut/main.c120
-rw-r--r--util/uut/opr.c36
-rw-r--r--util/uut/opr.h1
3 files changed, 144 insertions, 13 deletions
diff --git a/util/uut/main.c b/util/uut/main.c
index cde439ba17..ff3a3066fd 100644
--- a/util/uut/main.c
+++ b/util/uut/main.c
@@ -14,6 +14,7 @@
#include <sys/stat.h>
#include "com_port.h"
+#include "compile_time_macros.h"
#include "main.h"
#include "misc_util.h"
#include "opr.h"
@@ -44,6 +45,12 @@
#define FIRMWARE_START_ADDR 0x10090000
/* Divide the ec firmware image into 4K byte */
#define FIRMWARE_SEGMENT 0x1000
+/* Register address for chip ID */
+#define NPCX_SRID_CR 0x400C101C
+/* Register address for device ID */
+#define NPCX_DEVICE_ID_CR 0x400C1022
+#define NPCX_FLASH_BASE_ADDR 0x64000000
+
/*---------------------------------------------------------------------------
* Global variables
*---------------------------------------------------------------------------
@@ -69,7 +76,50 @@ static uint32_t baudrate;
static uint32_t dev_num;
static uint32_t flash_offset;
static bool auto_mode;
+static bool read_flash_flag;
+
+struct npcx_chip_info {
+ uint8_t device_id;
+ uint8_t chip_id;
+ uint32_t flash_size;
+};
+const static struct npcx_chip_info chip_info[] = {
+ {
+ /* NPCX796FA */
+ .device_id = 0x21,
+ .chip_id = 0x06,
+ .flash_size = 1024 * 1024,
+ },
+
+ {
+ /* NPCX796FB */
+ .device_id = 0x21,
+ .chip_id = 0x07,
+ .flash_size = 1024 * 1024,
+ },
+
+ {
+ /* NPCX797WB */
+ .device_id = 0x24,
+ .chip_id = 0x07,
+ .flash_size = 1024 * 1024,
+ },
+
+ {
+ /* NPCX796FC */
+ .device_id = 0x29,
+ .chip_id = 0x07,
+ .flash_size = 512 * 1024,
+ },
+
+ {
+ /* NPCX797WC */
+ .device_id = 0x2C,
+ .chip_id = 0x07,
+ .flash_size = 512 * 1024,
+ },
+};
/*---------------------------------------------------------------------------
* Functions prototypes
*---------------------------------------------------------------------------
@@ -198,6 +248,29 @@ static bool image_auto_write(uint32_t offset, uint8_t *buffer,
return true;
}
+static bool get_flash_size(uint32_t *flash_size)
+{
+ uint8_t dev_id, chip_id, i;
+
+ if (opr_read_chunk(&dev_id, NPCX_DEVICE_ID_CR, 1) != true)
+ return false;
+
+ if (opr_read_chunk(&chip_id, NPCX_SRID_CR, 1) != true)
+ return false;
+
+ for (i = 0; i < ARRAY_SIZE(chip_info); i++) {
+ if (chip_info[i].device_id == dev_id &&
+ chip_info[i].chip_id == chip_id) {
+ *flash_size = chip_info[i].flash_size;
+ return true;
+ }
+ }
+ printf("Unknown NPCX device ID:0x%02x chip ID:0x%02x\n",
+ dev_id, chip_id);
+
+ return false;
+}
+
/*---------------------------------------------------------------------------
* Function: read_input_file
*
@@ -269,6 +342,7 @@ int main(int argc, char *argv[])
verbose = true;
console = false;
auto_mode = false;
+ read_flash_flag = false;
param_parse_cmd_line(argc, argv);
@@ -328,6 +402,20 @@ int main(int argc, char *argv[])
exit_uart_app(-1);
}
+ if (read_flash_flag) {
+ uint32_t flash_size;
+
+ if (get_flash_size(&flash_size)) {
+ printf("Read %d bytes from flash...\n", flash_size);
+ opr_read_mem(file_name, NPCX_FLASH_BASE_ADDR,
+ flash_size);
+ exit_uart_app(EC_OK);
+ }
+
+ printf("Fail to read the flash size\n");
+ exit_uart_app(-1);
+ }
+
param_check_opr_num(opr_name);
/* Write buffer data to chosen address */
@@ -397,22 +485,23 @@ int main(int argc, char *argv[])
*/
static const struct option long_opts[] = {
- {"version", 0, 0, 'v'},
- {"help", 0, 0, 'h'},
- {"quiet", 0, 0, 'q'},
- {"console", 0, 0, 'c'},
- {"auto", 0, 0, 'A'},
- {"baudrate", 1, 0, 'b'},
- {"opr", 1, 0, 'o'},
- {"port", 1, 0, 'p'},
- {"file", 1, 0, 'f'},
- {"addr", 1, 0, 'a'},
- {"size", 1, 0, 's'},
- {"offset", 1, 0, 'O'},
+ {"version", 0, 0, 'v'},
+ {"help", 0, 0, 'h'},
+ {"quiet", 0, 0, 'q'},
+ {"console", 0, 0, 'c'},
+ {"auto", 0, 0, 'A'},
+ {"read-flash", 0, 0, 'r'},
+ {"baudrate", 1, 0, 'b'},
+ {"opr", 1, 0, 'o'},
+ {"port", 1, 0, 'p'},
+ {"file", 1, 0, 'f'},
+ {"addr", 1, 0, 'a'},
+ {"size", 1, 0, 's'},
+ {"offset", 1, 0, 'O'},
{NULL, 0, 0, 0}
};
-static char *short_opts = "vhqcAb:o:p:f:a:s:O:?";
+static char *short_opts = "vhqcArb:o:p:f:a:s:O:?";
static void param_parse_cmd_line(int argc, char *argv[])
{
@@ -439,6 +528,9 @@ static void param_parse_cmd_line(int argc, char *argv[])
case 'A':
auto_mode = true;
break;
+ case 'r':
+ read_flash_flag = true;
+ break;
case 'b':
if (sscanf(optarg, "%du", &baudrate) == 0)
exit(EC_BAUDRATE_ERR);
@@ -585,6 +677,8 @@ static void tool_usage(void)
printf(" -A, --auto - Enable auto mode. (default is off)\n");
printf(" -O, --offset <num> - With --auto, assign the offset of");
printf(" flash where the image to be written.\n");
+ printf(" -r, --read-flash - With --file=<file>, Read the whole"
+ " flash content and write it to <file>.\n");
printf("\n");
printf("Operation specific switches:\n");
printf(" -o, --opr <name> - Operation number (see list below)\n");
diff --git a/util/uut/opr.c b/util/uut/opr.c
index 27f4c3463d..81a711cf75 100644
--- a/util/uut/opr.c
+++ b/util/uut/opr.c
@@ -156,6 +156,42 @@ bool opr_write_chunk(uint8_t *buffer, uint32_t addr, uint32_t size)
wr_cmd_buf.cmd, &wr_cmd_buf.cmd_size);
return opr_send_cmds(&wr_cmd_buf, 1);
}
+
+/*----------------------------------------------------------------------------
+ * Function: opr_read_chunk
+ *
+ * Parameters:
+ * buffer - Data read buffer.
+ * addr - Memory address to read from.
+ * size - Data size to read.
+ * Returns: true if successful, false in the case of an error.
+ * Side effects:
+ * Description:
+ * Read data from RAM, starting from the given address (addr).
+ * Data size is limited to the max chunk size (256 bytes).
+ *---------------------------------------------------------------------------
+ */
+bool opr_read_chunk(uint8_t *buffer, uint32_t addr, uint32_t size)
+{
+ struct command_node rd_cmd_buf;
+
+ if (size > MAX_RW_DATA_SIZE) {
+ display_color_msg(FAIL,
+ "ERROR: Block cannot exceed %d\n", MAX_RW_DATA_SIZE);
+ return false;
+ }
+
+ cmd_create_read(addr, ((uint8_t)size - 1),
+ rd_cmd_buf.cmd, &rd_cmd_buf.cmd_size);
+ rd_cmd_buf.resp_size = size + 3;
+ if (opr_send_cmds(&rd_cmd_buf, 1)) {
+ if (resp_buf[0] == (uint8_t)(UFPP_READ_CMD)) {
+ memcpy(buffer, &resp_buf[1], size);
+ return true;
+ }
+ }
+ return false;
+}
/*----------------------------------------------------------------------------
* Function: opr_write_mem
*
diff --git a/util/uut/opr.h b/util/uut/opr.h
index f3d630ceb4..3b166f0c7e 100644
--- a/util/uut/opr.h
+++ b/util/uut/opr.h
@@ -49,6 +49,7 @@ void opr_usage(void);
bool opr_close_port(void);
bool opr_open_port(const char *port_name, struct comport_fields port_cfg);
bool opr_write_chunk(uint8_t *buffer, uint32_t addr, uint32_t size);
+bool opr_read_chunk(uint8_t *buffer, uint32_t addr, uint32_t size);
void opr_write_mem(uint8_t *buffer, 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);