summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-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);