You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(75) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(70) |
Feb
(20) |
Mar
(52) |
Apr
(149) |
May
(387) |
Jun
(466) |
Jul
(133) |
Aug
(87) |
Sep
(122) |
Oct
(140) |
Nov
(185) |
Dec
(105) |
2010 |
Jan
(85) |
Feb
(45) |
Mar
(75) |
Apr
(17) |
May
(41) |
Jun
(52) |
Jul
(33) |
Aug
(29) |
Sep
(36) |
Oct
(15) |
Nov
(26) |
Dec
(34) |
2011 |
Jan
(26) |
Feb
(25) |
Mar
(26) |
Apr
(29) |
May
(20) |
Jun
(27) |
Jul
(15) |
Aug
(32) |
Sep
(13) |
Oct
(64) |
Nov
(60) |
Dec
(10) |
2012 |
Jan
(64) |
Feb
(63) |
Mar
(39) |
Apr
(43) |
May
(54) |
Jun
(11) |
Jul
(30) |
Aug
(45) |
Sep
(11) |
Oct
(70) |
Nov
(24) |
Dec
(23) |
2013 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(40) |
May
(20) |
Jun
(24) |
Jul
(36) |
Aug
(25) |
Sep
(42) |
Oct
(40) |
Nov
(9) |
Dec
(21) |
2014 |
Jan
(29) |
Feb
(24) |
Mar
(60) |
Apr
(22) |
May
(22) |
Jun
(46) |
Jul
(11) |
Aug
(23) |
Sep
(26) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
2015 |
Jan
(28) |
Feb
(47) |
Mar
(33) |
Apr
(58) |
May
(5) |
Jun
(1) |
Jul
|
Aug
(8) |
Sep
(12) |
Oct
(25) |
Nov
(58) |
Dec
(21) |
2016 |
Jan
(12) |
Feb
(40) |
Mar
(2) |
Apr
(1) |
May
(67) |
Jun
(2) |
Jul
(5) |
Aug
(36) |
Sep
|
Oct
(24) |
Nov
(17) |
Dec
(50) |
2017 |
Jan
(14) |
Feb
(16) |
Mar
(2) |
Apr
(35) |
May
(14) |
Jun
(16) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
(19) |
Nov
|
Dec
(16) |
2018 |
Jan
(55) |
Feb
(11) |
Mar
(34) |
Apr
(14) |
May
(4) |
Jun
(20) |
Jul
(39) |
Aug
(16) |
Sep
(17) |
Oct
(16) |
Nov
(20) |
Dec
(30) |
2019 |
Jan
(29) |
Feb
(24) |
Mar
(37) |
Apr
(26) |
May
(19) |
Jun
(21) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(12) |
Nov
(12) |
Dec
(12) |
2020 |
Jan
(47) |
Feb
(36) |
Mar
(54) |
Apr
(44) |
May
(37) |
Jun
(19) |
Jul
(32) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(32) |
Dec
(11) |
2021 |
Jan
(14) |
Feb
(5) |
Mar
(40) |
Apr
(32) |
May
(42) |
Jun
(31) |
Jul
(29) |
Aug
(47) |
Sep
(38) |
Oct
(17) |
Nov
(74) |
Dec
(33) |
2022 |
Jan
(11) |
Feb
(15) |
Mar
(40) |
Apr
(21) |
May
(39) |
Jun
(44) |
Jul
(19) |
Aug
(46) |
Sep
(79) |
Oct
(35) |
Nov
(21) |
Dec
(15) |
2023 |
Jan
(56) |
Feb
(13) |
Mar
(43) |
Apr
(28) |
May
(60) |
Jun
(15) |
Jul
(29) |
Aug
(28) |
Sep
(32) |
Oct
(21) |
Nov
(42) |
Dec
(39) |
2024 |
Jan
(35) |
Feb
(17) |
Mar
(28) |
Apr
(7) |
May
(14) |
Jun
(35) |
Jul
(30) |
Aug
(35) |
Sep
(30) |
Oct
(28) |
Nov
(38) |
Dec
(18) |
2025 |
Jan
(21) |
Feb
(28) |
Mar
(36) |
Apr
(35) |
May
(34) |
Jun
(58) |
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: openocd-gerrit <ope...@us...> - 2023-07-01 17:59:30
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 56fd04832abc0ebadc21ee6127be4be9c7b46e15 (commit) from 6ef75352f1e4a86f66bf98e1792a68345c77f9a7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 56fd04832abc0ebadc21ee6127be4be9c7b46e15 Author: Marek Vrbka <mar...@co...> Date: Thu Jun 1 12:42:03 2023 +0200 semihosting: fix handling of errno This patch fixes the handling of errno by setting the sys_errn only if error has actually occurred during the semihosting call. It also fixes few issues where error was not set in the first place. Change-Id: I2fbe562f3ec5e6220b800de04cd33aa1f409c7a0 Signed-off-by: Marek Vrbka <mar...@co...> Reviewed-on: https://review.openocd.org/c/openocd/+/7730 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Jan Matyas <jan...@co...> diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 107b6d3ed..f7acc6092 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -223,7 +223,10 @@ static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void * return semihosting_redirect_write(semihosting, buf, size); /* default write */ - return write(fd, buf, size); + int result = write(fd, buf, size); + if (result == -1) + semihosting->sys_errno = errno; + return result; } static ssize_t semihosting_redirect_read(struct semihosting *semihosting, void *buf, int size) @@ -268,7 +271,8 @@ static inline ssize_t semihosting_read(struct semihosting *semihosting, int fd, /* default read */ ssize_t result = read(fd, buf, size); - semihosting->sys_errno = errno; + if (result == -1) + semihosting->sys_errno = errno; return result; } @@ -449,12 +453,7 @@ int semihosting_common(struct target *target) (fd == 0) ? "stdin" : (fd == 1) ? "stdout" : "stderr"); /* Just pretend success */ - if (semihosting->is_fileio) { - semihosting->result = 0; - } else { - semihosting->result = 0; - semihosting->sys_errno = 0; - } + semihosting->result = 0; break; } /* Close the descriptor */ @@ -464,7 +463,8 @@ int semihosting_common(struct target *target) fileio_info->param_1 = fd; } else { semihosting->result = close(fd); - semihosting->sys_errno = errno; + if (semihosting->result == -1) + semihosting->sys_errno = errno; LOG_DEBUG("close(%d)=%" PRId64, fd, semihosting->result); } } @@ -842,7 +842,8 @@ int semihosting_common(struct target *target) int fd = semihosting_get_field(target, 0, fields); // isatty() on Windows may return any non-zero value if fd is a terminal semihosting->result = isatty(fd) ? 1 : 0; - semihosting->sys_errno = errno; + if (semihosting->result == 0) + semihosting->sys_errno = errno; LOG_DEBUG("isatty(%d)=%" PRId64, fd, semihosting->result); } break; @@ -934,14 +935,16 @@ int semihosting_common(struct target *target) semihosting->result = -1; semihosting->sys_errno = EINVAL; } else if (strcmp((char *)fn, ":tt") == 0) { - if (mode == 0) + if (mode == 0) { semihosting->result = 0; - else if (mode == 4) + } else if (mode == 4) { semihosting->result = 1; - else if (mode == 8) + } else if (mode == 8) { semihosting->result = 2; - else + } else { semihosting->result = -1; + semihosting->sys_errno = EINVAL; + } } else { semihosting->hit_fileio = true; fileio_info->identifier = "open"; @@ -956,25 +959,23 @@ int semihosting_common(struct target *target) * - 0-3 ("r") for stdin, * - 4-7 ("w") for stdout, * - 8-11 ("a") for stderr */ + int fd; if (mode < 4) { - int fd = dup(STDIN_FILENO); - semihosting->result = fd; + fd = dup(STDIN_FILENO); semihosting->stdin_fd = fd; - semihosting->sys_errno = errno; - LOG_DEBUG("dup(STDIN)=%" PRId64, semihosting->result); + LOG_DEBUG("dup(STDIN)=%d", fd); } else if (mode < 8) { - int fd = dup(STDOUT_FILENO); - semihosting->result = fd; + fd = dup(STDOUT_FILENO); semihosting->stdout_fd = fd; - semihosting->sys_errno = errno; - LOG_DEBUG("dup(STDOUT)=%" PRId64, semihosting->result); + LOG_DEBUG("dup(STDOUT)=%d", fd); } else { - int fd = dup(STDERR_FILENO); - semihosting->result = fd; + fd = dup(STDERR_FILENO); semihosting->stderr_fd = fd; - semihosting->sys_errno = errno; - LOG_DEBUG("dup(STDERR)=%" PRId64, semihosting->result); + LOG_DEBUG("dup(STDERR)=%d", fd); } + semihosting->result = fd; + if (fd == -1) + semihosting->sys_errno = errno; } else { /* cygwin requires the permission setting * otherwise it will fail to reopen a previously @@ -982,7 +983,8 @@ int semihosting_common(struct target *target) semihosting->result = open((char *)fn, open_host_modeflags[mode], 0644); - semihosting->sys_errno = errno; + if (semihosting->result == -1) + semihosting->sys_errno = errno; LOG_DEBUG("open('%s')=%" PRId64, fn, semihosting->result); } } @@ -1131,7 +1133,8 @@ int semihosting_common(struct target *target) } fn[len] = 0; semihosting->result = remove((char *)fn); - semihosting->sys_errno = errno; + if (semihosting->result == -1) + semihosting->sys_errno = errno; LOG_DEBUG("remove('%s')=%" PRId64, fn, semihosting->result); free(fn); @@ -1200,7 +1203,9 @@ int semihosting_common(struct target *target) fn2[len2] = 0; semihosting->result = rename((char *)fn1, (char *)fn2); - semihosting->sys_errno = errno; + // rename() on Windows returns nonzero on error + if (semihosting->result != 0) + semihosting->sys_errno = errno; LOG_DEBUG("rename('%s', '%s')=%" PRId64 " %d", fn1, fn2, semihosting->result, errno); free(fn1); free(fn2); @@ -1245,7 +1250,8 @@ int semihosting_common(struct target *target) fileio_info->param_3 = SEEK_SET; } else { semihosting->result = lseek(fd, pos, SEEK_SET); - semihosting->sys_errno = errno; + if (semihosting->result == -1) + semihosting->sys_errno = errno; LOG_DEBUG("lseek(%d, %d)=%" PRId64, fd, (int)pos, semihosting->result); if (semihosting->result == pos) semihosting->result = 0; @@ -1383,7 +1389,6 @@ int semihosting_common(struct target *target) return retval; } semihosting->result = semihosting_write(semihosting, fd, buf, len); - semihosting->sys_errno = errno; LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%" PRId64, fd, addr, @@ -1671,7 +1676,6 @@ static int semihosting_common_fileio_end(struct target *target, int result, semihosting->hit_fileio = false; semihosting->result = result; - semihosting->sys_errno = fileio_errno; /* * Some fileio results do not match up with what the semihosting @@ -1693,6 +1697,17 @@ static int semihosting_common_fileio_end(struct target *target, int result, break; } + bool fileio_failed = false; + if (semihosting->op == SEMIHOSTING_SYS_ISTTY) + fileio_failed = (semihosting->result == 0); + else if (semihosting->op == SEMIHOSTING_SYS_RENAME) + fileio_failed = (semihosting->result != 0); + else + fileio_failed = (semihosting->result == -1); + + if (fileio_failed) + semihosting->sys_errno = fileio_errno; + return semihosting->post_result(target); } ----------------------------------------------------------------------- Summary of changes: src/target/semihosting_common.c | 79 ++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 32 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-07-01 15:04:40
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 6ef75352f1e4a86f66bf98e1792a68345c77f9a7 (commit) from eebcf3cff16afbce2c57cf2dba6f562e17713093 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6ef75352f1e4a86f66bf98e1792a68345c77f9a7 Author: Marek Vrbka <mar...@co...> Date: Tue May 30 15:36:12 2023 +0200 semihosting: improve semihosting opcode debug messages This patch introduces function semihosting_opcode_to_str() which converts semihosting opcodes to strings. This function is then used in debug messages to improve log analysis and troubleshooting. Change-Id: Iffea49dae13d6a626ae0db40d379cba3c9ea5bd3 Signed-off-by: Marek Vrbka <mar...@co...> Reviewed-on: https://review.openocd.org/c/openocd/+/7726 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Jan Matyas <jan...@co...> diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 6c91876c7..107b6d3ed 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -294,6 +294,66 @@ static inline int semihosting_getchar(struct semihosting *semihosting, int fd) */ static char *semihosting_user_op_params; +const char *semihosting_opcode_to_str(const uint64_t opcode) +{ + switch (opcode) { + case SEMIHOSTING_SYS_CLOSE: + return "CLOSE"; + case SEMIHOSTING_SYS_CLOCK: + return "CLOCK"; + case SEMIHOSTING_SYS_ELAPSED: + return "ELAPSED"; + case SEMIHOSTING_SYS_ERRNO: + return "ERRNO"; + case SEMIHOSTING_SYS_EXIT: + return "EXIT"; + case SEMIHOSTING_SYS_EXIT_EXTENDED: + return "EXIT_EXTENDED"; + case SEMIHOSTING_SYS_FLEN: + return "FLEN"; + case SEMIHOSTING_SYS_GET_CMDLINE: + return "GET_CMDLINE"; + case SEMIHOSTING_SYS_HEAPINFO: + return "HEAPINFO"; + case SEMIHOSTING_SYS_ISERROR: + return "ISERROR"; + case SEMIHOSTING_SYS_ISTTY: + return "ISTTY"; + case SEMIHOSTING_SYS_OPEN: + return "OPEN"; + case SEMIHOSTING_SYS_READ: + return "READ"; + case SEMIHOSTING_SYS_READC: + return "READC"; + case SEMIHOSTING_SYS_REMOVE: + return "REMOVE"; + case SEMIHOSTING_SYS_RENAME: + return "RENAME"; + case SEMIHOSTING_SYS_SEEK: + return "SEEK"; + case SEMIHOSTING_SYS_SYSTEM: + return "SYSTEM"; + case SEMIHOSTING_SYS_TICKFREQ: + return "TICKFREQ"; + case SEMIHOSTING_SYS_TIME: + return "TIME"; + case SEMIHOSTING_SYS_TMPNAM: + return "TMPNAM"; + case SEMIHOSTING_SYS_WRITE: + return "WRITE"; + case SEMIHOSTING_SYS_WRITEC: + return "WRITEC"; + case SEMIHOSTING_SYS_WRITE0: + return "WRITE0"; + case SEMIHOSTING_USER_CMD_0X100 ... SEMIHOSTING_USER_CMD_0X1FF: + return "USER_CMD"; + case SEMIHOSTING_ARM_RESERVED_START ... SEMIHOSTING_ARM_RESERVED_END: + return "ARM_RESERVED_CMD"; + default: + return "<unknown>"; + } +} + /** * Portable implementation of ARM semihosting calls. * Performs the currently pending semihosting operation @@ -323,8 +383,9 @@ int semihosting_common(struct target *target) /* Enough space to hold 4 long words. */ uint8_t fields[4*8]; - LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op, - semihosting->param); + LOG_DEBUG("op=0x%x (%s), param=0x%" PRIx64, semihosting->op, + semihosting_opcode_to_str(semihosting->op), + semihosting->param); switch (semihosting->op) { @@ -1470,8 +1531,9 @@ int semihosting_common(struct target *target) retval = target_read_buffer(target, addr, len, (uint8_t *)(semihosting_user_op_params)); if (retval != ERROR_OK) { - LOG_ERROR("Failed to read from target, semihosting op=0x%x", - semihosting->op); + LOG_ERROR("Failed to read from target, semihosting op=0x%x (%s)", + semihosting->op, + semihosting_opcode_to_str(semihosting->op)); free(semihosting_user_op_params); semihosting_user_op_params = NULL; return retval; diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h index 7c5f748f4..a1848b488 100644 --- a/src/target/semihosting_common.h +++ b/src/target/semihosting_common.h @@ -65,6 +65,8 @@ enum semihosting_operation_numbers { SEMIHOSTING_SYS_WRITE = 0x05, SEMIHOSTING_SYS_WRITEC = 0x03, SEMIHOSTING_SYS_WRITE0 = 0x04, + SEMIHOSTING_ARM_RESERVED_START = 0x32, + SEMIHOSTING_ARM_RESERVED_END = 0xFF, SEMIHOSTING_USER_CMD_0X100 = 0x100, /* First user cmd op code */ SEMIHOSTING_USER_CMD_0X107 = 0x107, /* Last supported user cmd op code */ SEMIHOSTING_USER_CMD_0X1FF = 0x1FF, /* Last user cmd op code */ @@ -186,6 +188,13 @@ struct semihosting { int (*post_result)(struct target *target); }; +/** + * @brief Convert the syscall opcode to a human-readable string + * @param[in] opcode Syscall opcode + * @return String representation of syscall opcode + */ +const char *semihosting_opcode_to_str(uint64_t opcode); + int semihosting_common_init(struct target *target, void *setup, void *post_result); int semihosting_common(struct target *target); ----------------------------------------------------------------------- Summary of changes: src/target/semihosting_common.c | 70 ++++++++++++++++++++++++++++++++++++++--- src/target/semihosting_common.h | 9 ++++++ 2 files changed, 75 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-16 22:12:38
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via eebcf3cff16afbce2c57cf2dba6f562e17713093 (commit) from 63f4e7c72a27fb828fe1be3003be6a94519e1c12 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eebcf3cff16afbce2c57cf2dba6f562e17713093 Author: Marek Vrbka <mar...@co...> Date: Mon Jun 5 08:35:09 2023 +0200 riscv/semihosting: Fix ebreak skip on fileio mode This patch fixes skipping the semihosting sequence if the fileio mode is enabled on riscv. This change was tested by me and is in the riscv-openocd fork for a year now. Original merge request: https://github.com/riscv/riscv-openocd/pull/699 Original author: Wu Zhigang zhi...@st... https://github.com/wzgpeter Change-Id: Iadaa0a48d1f82d3a7ca168f8a6b656ff6ab78e03 Signed-off-by: Marek Vrbka <mar...@co...> Reviewed-on: https://review.openocd.org/c/openocd/+/7729 Tested-by: jenkins Reviewed-by: Tim Newsome <ti...@si...> diff --git a/src/target/riscv/riscv_semihosting.c b/src/target/riscv/riscv_semihosting.c index 1bc4e1a16..da237ef33 100644 --- a/src/target/riscv/riscv_semihosting.c +++ b/src/target/riscv/riscv_semihosting.c @@ -141,16 +141,16 @@ enum semihosting_result riscv_semihosting(struct target *target, int *retval) } } + /* Resume right after the EBREAK 4 bytes instruction. */ + *retval = riscv_set_register(target, GDB_REGNO_PC, pc + 4); + if (*retval != ERROR_OK) + return SEMIHOSTING_ERROR; + /* * Resume target if we are not waiting on a fileio * operation to complete. */ if (semihosting->is_resumable && !semihosting->hit_fileio) { - /* Resume right after the EBREAK 4 bytes instruction. */ - *retval = riscv_set_register(target, GDB_REGNO_PC, pc + 4); - if (*retval != ERROR_OK) - return SEMIHOSTING_ERROR; - LOG_DEBUG(" -> HANDLED"); return SEMIHOSTING_HANDLED; } ----------------------------------------------------------------------- Summary of changes: src/target/riscv/riscv_semihosting.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-10 17:12:13
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 63f4e7c72a27fb828fe1be3003be6a94519e1c12 (commit) from d8c9f66d25cde09570e4f87e354216470b72de7e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 63f4e7c72a27fb828fe1be3003be6a94519e1c12 Author: Lorenz Brun <lorenz@brun.one> Date: Sat Dec 24 03:56:22 2022 +0100 target/ti-cjtag: make switching to JTAG more reliable The current cJTAG to JTAG switching commands for TI chips are not particularly reliable, especially on chips with accurate timing. On a Raspberry Pi the existing sequence has (depending on cabling and chip) a ~50% chance of working, on a much better-behaved FT2232H it doesn't manage to enable full JTAG at all. This change runs a bunch of test-idle cycles before actually attempting to switch to full JTAG. This makes the switch reliable even at high clock speeds (>100kHz) and from precise sources like the FT2232H. Change-Id: I9293e884bf3e9606d529756ae4483b844d3c39db Reported-by: Phil Wiggum <p1m...@ma...> Fixes: https://sourceforge.net/p/openocd/tickets/375/ Signed-off-by: Lorenz Brun <lorenz@brun.one> Reviewed-on: https://review.openocd.org/c/openocd/+/7419 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/tcl/target/ti-cjtag.cfg b/tcl/target/ti-cjtag.cfg index d5e13e269..97111f1cc 100644 --- a/tcl/target/ti-cjtag.cfg +++ b/tcl/target/ti-cjtag.cfg @@ -5,6 +5,7 @@ # Read section 6.3 in http://www.ti.com/lit/pdf/swru319 for more information. proc ti_cjtag_to_4pin_jtag {jrc} { # Bypass + runtest 20 irscan $jrc 0x3f -endstate RUN/IDLE # Two zero bit scans and a one bit drshift pathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE ----------------------------------------------------------------------- Summary of changes: tcl/target/ti-cjtag.cfg | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-10 17:11:48
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via d8c9f66d25cde09570e4f87e354216470b72de7e (commit) from 9f23a1d7c1e27c556ef9787b9d3f263f5c1ecf24 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d8c9f66d25cde09570e4f87e354216470b72de7e Author: Antonio Borneo <bor...@gm...> Date: Thu Jun 1 10:50:50 2023 +0200 jep106: update to revision JEP106BG May 2023 The original document from Jedec does not report the entry for "21 NXP (Philips)", replaced by "c". It's clearly a typo. Keep the line from JEP106BF.01 for "NXP (Philips)". Change-Id: I30215c4ff08d5f112305cde6ab7a3176cdcef948 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7727 Tested-by: jenkins diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc index cb67b926a..6c8196765 100644 --- a/src/helper/jep106.inc +++ b/src/helper/jep106.inc @@ -8,7 +8,9 @@ * identification code list, please visit the JEDEC website at www.jedec.org . */ -/* This file is aligned to revision JEP106BF.01 October 2022. */ +/* This file is aligned to revision JEP106BG May 2023. */ + +/* "NXP (Philips)" is reported below, while missing in JEP106BG */ [0][0x01 - 1] = "AMD", [0][0x02 - 1] = "AMI", @@ -86,7 +88,7 @@ [0][0x4a - 1] = "Compaq", [0][0x4b - 1] = "Protocol Engines", [0][0x4c - 1] = "SCI", -[0][0x4d - 1] = "Seiko Instruments", +[0][0x4d - 1] = "ABLIC", [0][0x4e - 1] = "Samsung", [0][0x4f - 1] = "I3 Design System", [0][0x50 - 1] = "Klic", @@ -972,7 +974,7 @@ [7][0x4e - 1] = "Mustang", [7][0x4f - 1] = "Orca Systems", [7][0x50 - 1] = "Passif Semiconductor", -[7][0x51 - 1] = "GigaDevice Semiconductor (Beijing) Inc", +[7][0x51 - 1] = "GigaDevice Semiconductor (Beijing)", [7][0x52 - 1] = "Memphis Electronic", [7][0x53 - 1] = "Beckhoff Automation GmbH", [7][0x54 - 1] = "Harmony Semiconductor Corp", @@ -1786,4 +1788,57 @@ [14][0x0a - 1] = "UltraRISC Technology (Shanghai) Co Ltd", [14][0x0b - 1] = "Shenzhen Jing Da Kang Technology Co Ltd", [14][0x0c - 1] = "Hangzhou Hongjun Microelectronics Co Ltd", +[14][0x0d - 1] = "Pliops Ltd", +[14][0x0e - 1] = "Cix Technology (Shanghai) Co Ltd", +[14][0x0f - 1] = "TeraDevices Inc", +[14][0x10 - 1] = "SpacemiT (Hangzhou)Technology Co Ltd", +[14][0x11 - 1] = "InnoPhase loT Inc", +[14][0x12 - 1] = "InnoPhase loT Inc", +[14][0x13 - 1] = "Yunhight Microelectronics", +[14][0x14 - 1] = "Samnix", +[14][0x15 - 1] = "HKC Storage Co Ltd", +[14][0x16 - 1] = "Chiplego Technology (Shanghai) Co Ltd", +[14][0x17 - 1] = "StoreSkill", +[14][0x18 - 1] = "Shenzhen Astou Technology Company", +[14][0x19 - 1] = "Guangdong LeafFive Technology Limited", +[14][0x1a - 1] = "Jin JuQuan", +[14][0x1b - 1] = "Huaxuan Technology (Shenzhen) Co Ltd", +[14][0x1c - 1] = "Gigastone Corporation", +[14][0x1d - 1] = "Kinsotin", +[14][0x1e - 1] = "PengYing", +[14][0x1f - 1] = "Shenzhen Xunhi Technology Co Ltd", +[14][0x20 - 1] = "FOXX Storage Inc", +[14][0x21 - 1] = "Shanghai Belling Corporation Ltd", +[14][0x22 - 1] = "Glenfy Tech Co Ltd", +[14][0x23 - 1] = "Sahasra Semiconductors Pvt Ltd", +[14][0x24 - 1] = "Chongqing SeekWave Technology Co Ltd", +[14][0x25 - 1] = "Shenzhen Zhixing Intelligent Manufacturing", +[14][0x26 - 1] = "Ethernovia", +[14][0x27 - 1] = "Shenzhen Xinrongda Technology Co Ltd", +[14][0x28 - 1] = "Hangzhou Clounix Technology Limited", +[14][0x29 - 1] = "JGINYUE", +[14][0x2a - 1] = "Shenzhen Xinwei Semiconductor Co Ltd", +[14][0x2b - 1] = "COLORFIRE Technology Co Ltd", +[14][0x2c - 1] = "B LKE", +[14][0x2d - 1] = "ZHUDIAN", +[14][0x2e - 1] = "REECHO", +[14][0x2f - 1] = "Enphase Energy Inc", +[14][0x30 - 1] = "Shenzhen Yingrui Storage Technology Co Ltd", +[14][0x31 - 1] = "Shenzhen Sinomos Semiconductor Technology", +[14][0x32 - 1] = "O2micro International Limited", +[14][0x33 - 1] = "Axelera AI BV", +[14][0x34 - 1] = "Silicon Legend Technology (Suzhou) Co Ltd", +[14][0x35 - 1] = "Suzhou Novosense Microelectronics Co Ltd", +[14][0x36 - 1] = "Pirateman", +[14][0x37 - 1] = "Yangtze MasonSemi", +[14][0x38 - 1] = "Shanghai Yunsilicon Technology Co Ltd", +[14][0x39 - 1] = "Rayson", +[14][0x3a - 1] = "Alphawave IP", +[14][0x3b - 1] = "Shenzhen Visions Chip Electronic Technology", +[14][0x3c - 1] = "KYO Group", +[14][0x3d - 1] = "Shenzhen Aboison Technology Co Ltd", +[14][0x3e - 1] = "Shenzhen JingSheng Semiconducto Co Ltd", +[14][0x3f - 1] = "Shenzhen Dingsheng Technology Co Ltd", +[14][0x40 - 1] = "EVAS Intelligence Co Ltd", +[14][0x41 - 1] = "Kaibright Electronic Technologies", /* EOF */ ----------------------------------------------------------------------- Summary of changes: src/helper/jep106.inc | 61 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-10 17:10:45
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 9f23a1d7c1e27c556ef9787b9d3f263f5c1ecf24 (commit) via 71180e67537117f841ff5dd7c359e3678d861e2b (commit) from 0854c83076749196603bebdb47ec93f50a454f79 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9f23a1d7c1e27c556ef9787b9d3f263f5c1ecf24 Author: Marek Vrbka <mar...@co...> Date: Tue May 30 14:16:38 2023 +0200 semihosting: fix non-zero value on Windows isatty() On Windows, isatty() can return any non-zero value if it's an interactive device. Which diverges from the ARM semihosting specification. This patch introduces a fix to make the SYS_ISTTY operation conform to spec. Change-Id: I9bc4f3cb82370812825d52419851910b3e3f35cc Signed-off-by: Marek Vrbka <mar...@co...> Reviewed-on: https://review.openocd.org/c/openocd/+/7725 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins Reviewed-by: Jan Matyas <jan...@co...> diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 3ed112ba9..6c91876c7 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -779,7 +779,8 @@ int semihosting_common(struct target *target) if (retval != ERROR_OK) return retval; int fd = semihosting_get_field(target, 0, fields); - semihosting->result = isatty(fd); + // isatty() on Windows may return any non-zero value if fd is a terminal + semihosting->result = isatty(fd) ? 1 : 0; semihosting->sys_errno = errno; LOG_DEBUG("isatty(%d)=%" PRId64, fd, semihosting->result); } commit 71180e67537117f841ff5dd7c359e3678d861e2b Author: Marek Vrbka <mar...@co...> Date: Tue May 30 10:07:18 2023 +0200 gdb_server: refactor and unify function gdb_get_char_inner The old implementation of gdb socket error handling in the gdb_get_char_inner() differs between Windows and *nix platforms. This patch simplifies it by using an existing function log_socket_error() which handles most of the platform specific things. It also provides better error messages. Change-Id: Iec871c4965b116dc7cfb03c3565bab66c8b41958 Signed-off-by: Marek Vrbka <mar...@co...> Reviewed-on: https://review.openocd.org/c/openocd/+/7724 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 0baf7553b..702dbef49 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -235,39 +235,20 @@ static int gdb_get_char_inner(struct connection *connection, int *next_char) } #ifdef _WIN32 - errno = WSAGetLastError(); - - switch (errno) { - case WSAEWOULDBLOCK: - usleep(1000); - break; - case WSAECONNABORTED: - gdb_con->closed = true; - return ERROR_SERVER_REMOTE_CLOSED; - case WSAECONNRESET: - gdb_con->closed = true; - return ERROR_SERVER_REMOTE_CLOSED; - default: - LOG_ERROR("read: %d", errno); - exit(-1); - } + bool retry = (WSAGetLastError() == WSAEWOULDBLOCK); #else - switch (errno) { - case EAGAIN: - usleep(1000); - break; - case ECONNABORTED: - gdb_con->closed = true; - return ERROR_SERVER_REMOTE_CLOSED; - case ECONNRESET: - gdb_con->closed = true; - return ERROR_SERVER_REMOTE_CLOSED; - default: - LOG_ERROR("read: %s", strerror(errno)); - gdb_con->closed = true; - return ERROR_SERVER_REMOTE_CLOSED; - } + bool retry = (errno == EAGAIN); #endif + + if (retry) { + // Try again after a delay + usleep(1000); + } else { + // Print error and close the socket + log_socket_error("GDB"); + gdb_con->closed = true; + return ERROR_SERVER_REMOTE_CLOSED; + } } #ifdef _DEBUG_GDB_IO_ ----------------------------------------------------------------------- Summary of changes: src/server/gdb_server.c | 43 ++++++++++++----------------------------- src/target/semihosting_common.c | 3 ++- 2 files changed, 14 insertions(+), 32 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-10 17:09:41
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 0854c83076749196603bebdb47ec93f50a454f79 (commit) from 370bf43fb1a89d4bf3887cba63318e5e1711478b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0854c83076749196603bebdb47ec93f50a454f79 Author: Marek Vrbka <mar...@co...> Date: Mon May 29 14:41:34 2023 +0200 gdb_server: add debug signal reason prints Added debug prints to show what is the target debug reason. Also added debug print for Ctrl-C response. This is useful for troubleshooting and log analysis. Change-Id: I055936257d989efe7255656198a8d73a367fcd15 Signed-off-by: Marek Vrbka <mar...@co...> Reviewed-on: https://review.openocd.org/c/openocd/+/7720 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 943fe4008..0baf7553b 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -145,6 +145,9 @@ static char gdb_running_type; static int gdb_last_signal(struct target *target) { + LOG_TARGET_DEBUG(target, "Debug reason is: %s", + target_debug_reason_str(target->debug_reason)); + switch (target->debug_reason) { case DBG_REASON_DBGRQ: return 0x2; /* SIGINT */ @@ -159,8 +162,9 @@ static int gdb_last_signal(struct target *target) case DBG_REASON_NOTHALTED: return 0x0; /* no signal... shouldn't happen */ default: - LOG_USER("undefined debug reason %d - target needs reset", - target->debug_reason); + LOG_USER("undefined debug reason %d (%s) - target needs reset", + target->debug_reason, + target_debug_reason_str(target->debug_reason)); return 0x0; } } @@ -798,6 +802,7 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio } if (gdb_connection->ctrl_c) { + LOG_TARGET_DEBUG(target, "Responding with signal 2 (SIGINT) to debugger due to Ctrl-C"); signal_var = 0x2; } else signal_var = gdb_last_signal(ct); diff --git a/src/target/target.c b/src/target/target.c index 009929211..5858aa573 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -7147,3 +7147,29 @@ static int target_register_user_commands(struct command_context *cmd_ctx) return register_commands(cmd_ctx, NULL, target_exec_command_handlers); } + +const char *target_debug_reason_str(enum target_debug_reason reason) +{ + switch (reason) { + case DBG_REASON_DBGRQ: + return "DBGRQ"; + case DBG_REASON_BREAKPOINT: + return "BREAKPOINT"; + case DBG_REASON_WATCHPOINT: + return "WATCHPOINT"; + case DBG_REASON_WPTANDBKPT: + return "WPTANDBKPT"; + case DBG_REASON_SINGLESTEP: + return "SINGLESTEP"; + case DBG_REASON_NOTHALTED: + return "NOTHALTED"; + case DBG_REASON_EXIT: + return "EXIT"; + case DBG_REASON_EXC_CATCH: + return "EXC_CATCH"; + case DBG_REASON_UNDEFINED: + return "UNDEFINED"; + default: + return "UNKNOWN!"; + } +} diff --git a/src/target/target.h b/src/target/target.h index 2a2f5315f..abeb8ed51 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -803,4 +803,6 @@ extern bool get_target_reset_nag(void); #define TARGET_DEFAULT_POLLING_INTERVAL 100 +const char *target_debug_reason_str(enum target_debug_reason reason); + #endif /* OPENOCD_TARGET_TARGET_H */ ----------------------------------------------------------------------- Summary of changes: src/server/gdb_server.c | 9 +++++++-- src/target/target.c | 26 ++++++++++++++++++++++++++ src/target/target.h | 2 ++ 3 files changed, 35 insertions(+), 2 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-10 17:00:06
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 370bf43fb1a89d4bf3887cba63318e5e1711478b (commit) from 24b656bff5889350b0c95d791d47e479d9fbd7f9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 370bf43fb1a89d4bf3887cba63318e5e1711478b Author: iosabi <io...@pr...> Date: Thu Apr 9 22:00:58 2020 +0000 flash/nor: add support for NXP QN908x This patch adds support for the NXP QN908x family of Bluetooth microcontrollers, such as the QN9080. This chip features a Cortex-M4F with 512 KiB of flash on all the available versions, although the documentation suggests that there might be 256 kB versions as well. The initial support allows to read, erase and write the whole user flash area. Three new sub-commands under the new "qn908x" command are added in this patch as well: disable_wdog to disabled the watchdog, mass_erase to perform a mass erase and allow_brick to allow programming images that disable the SWD interface. Disabling the watchdog is required after a "reset halt" in order to run the CRC algorithm from RAM when verifying the chip. However, this is not done automatically on probing or other initialization since disabling the watchdog might interfere with debugging real applications. The "mass_erase" command allows to erase the whole flash without probing it, since in some scenarios the chip can be locked such that no flash or ram can be accessed from the SWD interface, allowing only to run a mass_erase to be able to flash the program. The flashing process allows to compute a checksum, similar to the lpc2000 driver "calc_checksum" but done over a different region of the memory. This checksum is required to be present for the QN908x bootloader ROM to boot, and otherwise is useless. As with the lpc2000 design, verification when using "calc_checksum" is expected to fail if the checksum was not valid in the image being verified. This was manually tested on a QN9080, including the scan-view, AddressSanitizer/UBSan and test coverage configurations. Change-Id: Ibd6d8f3608654294795085fcaaffb448b77cc58b Co-developed-by: Marian Buschsieweke <mar...@ov...> Signed-off-by: Marian Buschsieweke <mar...@ov...> Signed-off-by: iosabi <io...@pr...> Reviewed-on: https://review.openocd.org/c/openocd/+/5584 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 9b485c5e1..832047f0e 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7341,6 +7341,116 @@ Note: only Main and Work flash regions support Erase operation. @end deffn @end deffn +@deffn {Flash Driver} {qn908x} +The NXP QN908x microcontrollers feature a Cortex-M4F with integrated Bluetooth +LE 5 support and an internal flash of up to 512 KiB. These chips only support +the SWD interface. + +The @var{qn908x} driver uses the internal "Flash Memory Controller" block via +SWD to erase, program and read the internal flash. This driver does not +support the ISP (In-System Programming) mode which is an alternate way to +program the flash via UART, SPI or USB. + +The internal flash is 512 KiB in size in all released chips and it starts at +the address 0x01000000, although it can be mapped to address 0 and it is +aliased to other addresses. This driver only recognizes the bank starting at +address 0x01000000. + +The internal bootloader stored in ROM is in charge of loading and verifying +the image from flash, or enter ISP mode. The programmed image must start at +the beginning of the flash and contain a valid header and a matching CRC32 +checksum. Additionally, the image header contains a "Code Read Protection" +(CRP) word which indicates whether SWD access is enabled, as well as whether +ISP mode is enabled. Therefore, it is possible to program an image that +disables SWD and ISP making it impossible to program another image in the +future through these interfaces, or even debug the current image. While this is +a valid use case for production deployments where the chips are locked down, by +default this driver doesn't allow such images that disable the SWD interface. +To program such images see the @command{qn908x allow_brick} command. + +Apart from the CRP field which is located in the image header, the last page +of the flash memory contains a "Flash lock and protect" descriptor which allows +to individually protect each 2 KiB page, as well as disabling SWD access to the +flash and RAM. If this access is disabled it is not possible to read, erase or +program individual pages from the SWD interface or even access the read-only +"Flash information page" with information about the bootloader version and +flash size. However when this protection is in place, it is still possible to +mass erase the whole chip and then program a new image, for which you can use +the @command{qn908x mass_erase}. + +Example: +@example +flash bank $FLASHNAME qn908x 0x01000000 0 0 0 $TARGETNAME calc_checksum +@end example + +Parameters: +@itemize +@item @option{calc_checksum} optional parameter to compute the required +checksum of the first bytes in the vector table. +@quotation Note +If the checksum in the header of your image is invalid and you don't provide the +@option{calc_checksum} option the boot ROM will not boot your image and it may +render the flash inaccessible. On the other hand, if you use this option to +compute the checksum keep in mind that @command{verify_image} will fail on +those four bytes of the checksum since those bytes in the flash will have the +updated checksum. +@end quotation +@end itemize + +@deffn {Command} {qn908x allow_brick} +Allow the qn908x driver to program images with a "Code Read Protection" byte +that disables the SWD access. Programming such image will cause OpenOCD to +not be able to reach the target over SWD anymore after the new image is +programmed and its configuration takes effect, e.g. after a reboot. After +executing @command{qn908x allow_brick} these images will be allowed to be +programmed when writing to the flash. +@end deffn + +@deffn {Command} {qn908x disable_wdog} +Disable the watchdog timer (WDT) by resetting its CTRL field. The WDT starts +enabled after a @command{reset halt} and it doesn't run while the target is +halted. However, the verification process in this driver uses the generic +Cortex-M verification process which executes a payload in RAM and thus +requires the watchdog to be disabled before running @command{verify_image} +after a reset halt or any other condition where the watchdog is running. +Note that this is not done automatically and you must run this command in +those scenarios. +@end deffn + +@deffn {Command} {qn908x mass_erase} +Erases the complete flash using the mass_erase method. Mass erase is only +allowed if enabled in the Lock Status Register 8 (LOCK_STAT_8) which is read +from the last sector of the flash on boot. However, this mass_erase lock +protection can be bypassed and this command does so automatically. + +In the same LOCK_STAT_8 the flash and RAM access from SWD can be disabled by +setting two bits in this register. After a mass_erase, all the bits of the +flash would be set, making it the default to restrict SWD access to the flash +and RAM regions. This new after erase LOCK_STAT_8 value only takes effect after +being read from flash on the next reboot for example. After a mass_erase the +LOCK_STAT_8 register is changed by the hardware to allow access to flash and +RAM regardless of the value on flash, but only right after a mass_erase and +until the next boot. Therefore it is possible to perform a mass_erase, program +a new image, verify it and then reboot to a valid image that's locked from the +SWD access. + +The @command{qn908x mass_erase} command clears the bits that would be loaded +from the flash into LOCK_STAT_8 after erasing the whole chip to allow SWD +access for debugging or re-flashing an image without a mass_erase by default. +If the image being programmed also programs the last page of the flash with its +own settings, this mass_erase behavior will interfere with that write since a +new erase of at least the last page would need to be performed before writing +to it again. For this reason the optional @option{keep_lock} argument can be +used to leave the flash and RAM lock set. For development environments, the +default behavior is desired. + +The mass erase locking mechanism is independent from the individual page +locking bits, so it is possible that you can't erase a given page that is +locked and you can't unprotect that page because the locking bits are also +locked, but can still mass erase the whole flash. +@end deffn +@end deffn + @deffn {Flash Driver} {rp2040} Supports RP2040 "Raspberry Pi Pico" microcontroller. RP2040 is a dual-core device with two CM0+ cores. Both cores share the same diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index f04f0d206..534a7a804 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -54,6 +54,7 @@ NOR_DRIVERS = \ %D%/psoc4.c \ %D%/psoc5lp.c \ %D%/psoc6.c \ + %D%/qn908x.c \ %D%/renesas_rpchf.c \ %D%/rp2040.c \ %D%/rsl10.c \ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 889a811e3..a63b72c8f 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -284,6 +284,7 @@ extern const struct flash_driver psoc5lp_eeprom_flash; extern const struct flash_driver psoc5lp_flash; extern const struct flash_driver psoc5lp_nvl_flash; extern const struct flash_driver psoc6_flash; +extern const struct flash_driver qn908x_flash; extern const struct flash_driver renesas_rpchf_flash; extern const struct flash_driver rp2040_flash; extern const struct flash_driver rsl10_flash; diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 92476987e..3157bd329 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -61,6 +61,7 @@ static const struct flash_driver * const flash_drivers[] = { &psoc5lp_eeprom_flash, &psoc5lp_nvl_flash, &psoc6_flash, + &qn908x_flash, &renesas_rpchf_flash, &rp2040_flash, &sh_qspi_flash, diff --git a/src/flash/nor/qn908x.c b/src/flash/nor/qn908x.c new file mode 100644 index 000000000..8cd7a2f04 --- /dev/null +++ b/src/flash/nor/qn908x.c @@ -0,0 +1,1197 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/*************************************************************************** + * Copyright (C) 2020 iosabi * + * iosabi <io...@pr...> * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" + +#include <helper/binarybuffer.h> +#include <helper/bits.h> +#include <helper/crc32.h> +#include <helper/time_support.h> +#include <helper/types.h> + +/* The QN908x has two flash regions, one is the main flash region holding the + * user code and the second one is a small (0x800 bytes) "Flash information + * page" that can't be written to by the user. This page contains information + * programmed at the factory. + * + * The main flash region is normally 512 KiB, there's a field in the "Flash + * information page" that allows to specify for 256 KiB size chips. However, at + * the time of writing, none of the variants in the market have 256 KiB. + * + * The flash is divided into blocks of 256 KiB each, therefore containing two + * blocks. A block is subdivided into pages, of 2048 bytes. A page is the + * smallest region that can be erased or protected independently, although it + * is also possible to erase a whole block or both blocks. A page is subdivided + * into 8 rows of 64 words (32-bit words). The word subdivision is only + * relevant because DMA can write multiple words in the same row in the same + * flash program operation. + * + * For the Flash information page we are only interested in the last + * 0x100 bytes which contain a CRC-32 checksum of that 0x100 bytes long region + * and a field stating the size of the flash. This is also a good check that + * we are dealing with the right chip/flash configuration and is used in the + * probe() function. + */ +#define QN908X_FLASH_BASE 0x01000000 + +#define QN908X_FLASH_PAGE_SIZE 2048 +#define QN908X_FLASH_PAGES_PER_BLOCK 128 +#define QN908X_FLASH_MAX_BLOCKS 2 +#define QN908X_FLASH_BLOCK_SIZE \ + (QN908X_FLASH_PAGES_PER_BLOCK * QN908X_FLASH_PAGE_SIZE) +#define QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS 0x1c +#define QN908X_FLASH_IRQ_VECTOR_CHECKSUM_SIZE 4 +#define QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END \ + (QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_SIZE) + + +/* Flash information page memory fields. */ +#define QN908X_INFO_PAGE_BASE 0x210b0000u +#define QN908X_INFO_PAGE_CRC32 (QN908X_INFO_PAGE_BASE + 0x700) +#define QN908X_INFO_PAGE_CRC_START (QN908X_INFO_PAGE_BASE + 0x704) +#define QN908X_INFO_PAGE_BOOTLOADER_VER (QN908X_INFO_PAGE_BASE + 0x704) +#define QN908X_INFO_PAGE_FLASH_SIZE (QN908X_INFO_PAGE_BASE + 0x708) +#define QN908X_INFO_PAGE_BLUETOOTH_ADDR (QN908X_INFO_PAGE_BASE + 0x7fa) +#define QN908X_INFO_PAGE_CRC_END (QN908X_INFO_PAGE_BASE + 0x800) + + +/* Possible values of the QN908X_INFO_PAGE_FLASH_SIZE field. */ +enum qn908x_info_page_flash_size { + QN908X_FLASH_SIZE_512K = 0xfffff0ff, + QN908X_FLASH_SIZE_256K = 0xffffe0ff, +}; + +/* QN908x "Flash memory controller", described in section 28 of the user + * manual. In the NXP SDK this peripheral is called "FLASH", however we use the + * name "FMC" (Flash Memory Controller) here when referring to the controller + * to avoid confusion with other "flash" terms in OpenOCD. */ +#define QN908X_FMC_BASE 0x40081000u +#define QN908X_FMC_INI_RD_EN (QN908X_FMC_BASE + 0x00) +#define QN908X_FMC_ERASE_CTRL (QN908X_FMC_BASE + 0x04) +#define QN908X_FMC_ERASE_TIME (QN908X_FMC_BASE + 0x08) +#define QN908X_FMC_TIME_CTRL (QN908X_FMC_BASE + 0x0c) +#define QN908X_FMC_SMART_CTRL (QN908X_FMC_BASE + 0x10) +#define QN908X_FMC_INT_STAT (QN908X_FMC_BASE + 0x18) +#define QN908X_FMC_LOCK_STAT_0 (QN908X_FMC_BASE + 0x20) +#define QN908X_FMC_LOCK_STAT_1 (QN908X_FMC_BASE + 0x24) +#define QN908X_FMC_LOCK_STAT_2 (QN908X_FMC_BASE + 0x28) +#define QN908X_FMC_LOCK_STAT_3 (QN908X_FMC_BASE + 0x2c) +#define QN908X_FMC_LOCK_STAT_4 (QN908X_FMC_BASE + 0x30) +#define QN908X_FMC_LOCK_STAT_5 (QN908X_FMC_BASE + 0x34) +#define QN908X_FMC_LOCK_STAT_6 (QN908X_FMC_BASE + 0x38) +#define QN908X_FMC_LOCK_STAT_7 (QN908X_FMC_BASE + 0x3c) +#define QN908X_FMC_LOCK_STAT_8 (QN908X_FMC_BASE + 0x40) +#define QN908X_FMC_STATUS1 (QN908X_FMC_BASE + 0x48) +#define QN908X_FMC_DEBUG_PASSWORD (QN908X_FMC_BASE + 0xa8) +#define QN908X_FMC_ERASE_PASSWORD (QN908X_FMC_BASE + 0xac) + +#define QN908X_FMC_INI_RD_EN_INI_RD_EN_MASK BIT(0) + +#define QN908X_FMC_STATUS1_FSH_ERA_BUSY_L_MASK BIT(9) +#define QN908X_FMC_STATUS1_FSH_WR_BUSY_L_MASK BIT(10) +#define QN908X_FMC_STATUS1_FSH_ERA_BUSY_H_MASK BIT(12) +#define QN908X_FMC_STATUS1_FSH_WR_BUSY_H_MASK BIT(13) +#define QN908X_FMC_STATUS1_INI_RD_DONE_MASK BIT(15) +#define QN908X_FMC_STATUS1_FSH_STA_MASK BIT(26) + +#define QN908X_FMC_ERASE_CTRL_PAGE_IDXL_SHIFT 0 +#define QN908X_FMC_ERASE_CTRL_PAGE_IDXH_SHIFT 8 +#define QN908X_FMC_ERASE_CTRL_HALF_ERASEL_EN_SHIFT 28 +#define QN908X_FMC_ERASE_CTRL_HALF_ERASEH_EN_SHIFT 29 +#define QN908X_FMC_ERASE_CTRL_PAGE_ERASEL_EN_SHIFT 30 +#define QN908X_FMC_ERASE_CTRL_PAGE_ERASEH_EN_SHIFT 31 + +#define QN908X_FMC_INT_STAT_AHBL_INT_MASK BIT(0) +#define QN908X_FMC_INT_STAT_LOCKL_INT_MASK BIT(1) +#define QN908X_FMC_INT_STAT_ERASEL_INT_MASK BIT(2) +#define QN908X_FMC_INT_STAT_WRITEL_INT_MASK BIT(3) +#define QN908X_FMC_INT_STAT_WR_BUFL_INT_MASK BIT(4) +#define QN908X_FMC_INT_STAT_WRITE_FAIL_L_INT_MASK BIT(5) +#define QN908X_FMC_INT_STAT_ERASE_FAIL_L_INT_MASK BIT(6) +#define QN908X_FMC_INT_STAT_AHBH_INT_MASK BIT(8) +#define QN908X_FMC_INT_STAT_LOCKH_INT_MASK BIT(9) +#define QN908X_FMC_INT_STAT_ERASEH_INT_MASK BIT(10) +#define QN908X_FMC_INT_STAT_WRITEH_INT_MASK BIT(11) +#define QN908X_FMC_INT_STAT_WR_BUFH_INT_MASK BIT(12) +#define QN908X_FMC_INT_STAT_WRITE_FAIL_H_INT_MASK BIT(13) +#define QN908X_FMC_INT_STAT_ERASE_FAIL_H_INT_MASK BIT(14) + +#define QN908X_FMC_SMART_CTRL_PRGML_EN_MASK BIT(0) +#define QN908X_FMC_SMART_CTRL_PRGMH_EN_MASK BIT(1) +#define QN908X_FMC_SMART_CTRL_SMART_WRITEL_EN_MASK BIT(2) +#define QN908X_FMC_SMART_CTRL_SMART_WRITEH_EN_MASK BIT(3) +#define QN908X_FMC_SMART_CTRL_SMART_ERASEL_EN_MASK BIT(4) +#define QN908X_FMC_SMART_CTRL_SMART_ERASEH_EN_MASK BIT(5) +#define QN908X_FMC_SMART_CTRL_MAX_WRITE_MASK 0xf00u +#define QN908X_FMC_SMART_CTRL_MAX_WRITE_SHIFT 8u +#define QN908X_FMC_SMART_CTRL_MAX_WRITE(x) \ + (((uint32_t)(((uint32_t)(x)) << QN908X_FMC_SMART_CTRL_MAX_WRITE_SHIFT)) \ + & QN908X_FMC_SMART_CTRL_MAX_WRITE_MASK) +#define QN908X_FMC_SMART_CTRL_MAX_ERASE_MASK 0x3f000u +#define QN908X_FMC_SMART_CTRL_MAX_ERASE_SHIFT 12u +#define QN908X_FMC_SMART_CTRL_MAX_ERASE(x) \ + (((uint32_t)(((uint32_t)(x)) << QN908X_FMC_SMART_CTRL_MAX_ERASE_SHIFT)) \ + & QN908X_FMC_SMART_CTRL_MAX_ERASE_MASK) + +#define QN908X_FMC_SMART_CTRL_MAX_ERASE_RETRIES 9 +#define QN908X_FMC_SMART_CTRL_MAX_WRITE_RETRIES 9 + +#define QN908X_FMC_TIME_CTRL_PRGM_CYCLE_MASK 0xfffu +#define QN908X_FMC_TIME_CTRL_PRGM_CYCLE_SHIFT 0u +#define QN908X_FMC_TIME_CTRL_PRGM_CYCLE(x) \ + (((uint32_t)(((uint32_t)(x)) << QN908X_FMC_TIME_CTRL_PRGM_CYCLE_SHIFT)) \ + & QN908X_FMC_TIME_CTRL_PRGM_CYCLE_MASK) +#define QN908X_FMC_TIME_CTRL_TIME_BASE_MASK 0xff000u +#define QN908X_FMC_TIME_CTRL_TIME_BASE_SHIFT 12u +#define QN908X_FMC_TIME_CTRL_TIME_BASE(x) \ + (((uint32_t)(((uint32_t)(x)) << QN908X_FMC_TIME_CTRL_TIME_BASE_SHIFT)) \ + & QN908X_FMC_TIME_CTRL_TIME_BASE_MASK) + +#define QN908X_FMC_LOCK_STAT_8_MASS_ERASE_LOCK_EN BIT(0) +#define QN908X_FMC_LOCK_STAT_8_FSH_PROTECT_EN BIT(1) +#define QN908X_FMC_LOCK_STAT_8_MEM_PROTECT_EN BIT(2) +#define QN908X_FMC_LOCK_STAT_8_PROTECT_ANY (BIT(1) | BIT(2)) + +/* See Table 418 "Flash lock and protect description" in the user manual */ +#define QN908X_FLASH_LOCK_ADDR (QN908X_FLASH_BASE + 0x7f820) +/* Allow mass erase */ +#define QN908X_FLASH_LOCK_ENABLE_MASS_ERASE BIT(0) +/* disallow flash access from SWD */ +#define QN908X_FLASH_LOCK_ENABLE_FLASH_PROTECTION BIT(1) +/* disallow SRAM access from SWD */ +#define QN908X_FLASH_LOCK_ENABLE_MEMORY_PROTECTION BIT(2) + +/* Page lock information located at the beginning of the last page. */ +struct qn908x_flash_page_lock { + uint8_t bits[QN908X_FLASH_MAX_BLOCKS * QN908X_FLASH_PAGES_PER_BLOCK / 8]; + uint8_t protection; + uint8_t _reserved[3]; + /* nvds_size is unused here, but we need to preserve it across erases + * when locking and unlocking pages. */ + uint8_t nvds_size[4]; +} __attribute__ ((packed)); + +/* Clock configuration is stored in the SYSCON. */ +#define QN908X_SYSCON_BASE 0x40000000u +#define QN908X_SYSCON_CLK_EN (QN908X_SYSCON_BASE + 0x00cu) +#define QN908X_SYSCON_CLK_CTRL (QN908X_SYSCON_BASE + 0x010u) +#define QN908X_SYSCON_CHIP_ID (QN908X_SYSCON_BASE + 0x108u) +#define QN908X_SYSCON_XTAL_CTRL (QN908X_SYSCON_BASE + 0x180u) + +/* Internal 16MHz / 8MHz clock used by the erase operation. */ +#define QN908X_SYSCON_CLK_EN_CLK_DP_EN_MASK BIT(21) + +#define SYSCON_XTAL_CTRL_XTAL_DIV_MASK BIT(31) + +#define SYSCON_CLK_CTRL_AHB_DIV_MASK 0x1FFF0u +#define SYSCON_CLK_CTRL_AHB_DIV_SHIFT 4u +#define SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK BIT(19) +#define SYSCON_CLK_CTRL_CLK_OSC32M_DIV_MASK BIT(20) +#define SYSCON_CLK_CTRL_SYS_CLK_SEL_MASK 0xC0000000u +#define SYSCON_CLK_CTRL_SYS_CLK_SEL_SHIFT 30u + +#define CLOCK_16MHZ 16000000u +#define CLOCK_32MHZ 32000000u +#define CLOCK_32KHZ 32000u + +/* Watchdog block registers */ +#define QN908X_WDT_BASE 0x40001000u +#define QN908X_WDT_CTRL (QN908X_WDT_BASE + 0x08u) +#define QN908X_WDT_LOCK (QN908X_WDT_BASE + 0x20u) + +struct qn908x_flash_bank { + /* The number of flash blocks. Initially set to zero until the flash + * is probed. This determines the size of the flash. */ + unsigned int num_blocks; + + unsigned int user_bank_size; + bool calc_checksum; + + /* Whether we allow to flash an image that disables SWD access, potentially + * bricking the device since the image can't be reflashed from SWD. */ + bool allow_swd_disabled; + + bool page_lock_loaded; + struct qn908x_flash_page_lock page_lock; +}; + +/* 500 ms timeout. */ +#define QN908X_DEFAULT_TIMEOUT_MS 500 + +/* Forward declaration of commands. */ +static int qn908x_probe(struct flash_bank *bank); +static int qn908x_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count); + +/* Update the value of a register with a mask. This helper allows to read a + * register, modify a subset of the bits and write back the value, which is a + * common operation when modifying only a bit filed in a register. */ +static int qn908x_update_reg(struct target *target, target_addr_t reg, + uint32_t mask, uint32_t value) +{ + uint32_t orig_value = 0; + uint32_t new_value; + int retval; + if (mask != 0xffffffff) { + /* No need to read the old value if we request a mask of 32 bits. */ + retval = target_read_u32(target, reg, &orig_value); + if (retval != ERROR_OK) { + LOG_DEBUG("Error reading reg at " TARGET_ADDR_FMT + ": %d", reg, retval); + return retval; + } + } + new_value = (orig_value & ~mask) | (value & mask); + retval = target_write_u32(target, reg, new_value); + if (retval != ERROR_OK) { + LOG_DEBUG("Error writing reg at " TARGET_ADDR_FMT " with 0x%08" + PRIx32 ": %d", reg, new_value, retval); + return retval; + } + if (mask == 0xffffffff) { + LOG_DEBUG("Updated reg at " TARGET_ADDR_FMT ": ?? -> 0x%.08" + PRIx32 "", reg, new_value); + } else { + LOG_DEBUG("Updated reg at " TARGET_ADDR_FMT ": 0x%.08" PRIx32 + " -> 0x%.08" PRIx32, reg, orig_value, new_value); + } + return ERROR_OK; +} + +/* Load lock bit and protection bit and load redundancy page info. + * This populates the LOCK_STAT_n registers with the values from the lock page, + * making protection bit changes to the last page effective. */ +static int qn908x_load_lock_stat(struct target *target) +{ + int retval = target_write_u32(target, QN908X_FMC_INI_RD_EN, + QN908X_FMC_INI_RD_EN_INI_RD_EN_MASK); + if (retval != ERROR_OK) + return retval; + + uint32_t status1; + const uint32_t status_mask = QN908X_FMC_STATUS1_FSH_STA_MASK + | QN908X_FMC_STATUS1_INI_RD_DONE_MASK; + do { + retval = target_read_u32(target, QN908X_FMC_STATUS1, &status1); + if (retval != ERROR_OK) + return retval; + } while ((status1 & status_mask) != QN908X_FMC_STATUS1_INI_RD_DONE_MASK); + + for (int i = 0; i <= 8; i++) { + uint32_t addr = QN908X_FMC_LOCK_STAT_0 + i * 4; + uint32_t lock_stat; + if (target_read_u32(target, addr, &lock_stat) == ERROR_OK) + LOG_DEBUG("LOCK_STAT_%d = 0x%08" PRIx32, i, lock_stat); + } + return ERROR_OK; +} + +/* Initializes the FMC controller registers for allowing writing. */ +static int qn908x_init_flash(struct target *target) +{ + /* Determine the current clock configuration. */ + uint32_t clk_ctrl; + int retval = target_read_u32(target, QN908X_SYSCON_CLK_CTRL, &clk_ctrl); + if (retval != ERROR_OK) + return retval; + + uint32_t clk_sel = (clk_ctrl & SYSCON_CLK_CTRL_SYS_CLK_SEL_MASK) + >> SYSCON_CLK_CTRL_SYS_CLK_SEL_SHIFT; + LOG_DEBUG("Clock clk_sel=0x%08" PRIu32, clk_sel); + + /* Core clock frequency. */ + uint32_t core_freq = 0; + switch (clk_sel) { + case 0: /* RCO 32 MHz */ + core_freq = (clk_ctrl & SYSCON_CLK_CTRL_CLK_OSC32M_DIV_MASK) ? + CLOCK_16MHZ : CLOCK_32MHZ; + break; + case 1: /* Xin frequency */ + { + uint32_t clk_xtal; + retval = target_read_u32(target, QN908X_SYSCON_XTAL_CTRL, &clk_xtal); + if (retval != ERROR_OK) + return retval; + core_freq = (clk_ctrl & SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK) + && (clk_xtal & SYSCON_XTAL_CTRL_XTAL_DIV_MASK) + ? CLOCK_32MHZ : CLOCK_16MHZ; + } + break; + case 2: /* 32 Kz */ + core_freq = CLOCK_32KHZ; + break; + default: + return ERROR_FAIL; + } + + uint32_t ahb_div = (clk_ctrl & SYSCON_CLK_CTRL_AHB_DIV_MASK) + >> SYSCON_CLK_CTRL_AHB_DIV_SHIFT; + uint32_t ahb_freq = core_freq / (ahb_div + 1); + + LOG_DEBUG("Core freq: %" PRIu32 " Hz | AHB freq: %" PRIu32 " Hz", + core_freq, ahb_freq); + + /* TIME_BASE is 2uS at the current AHB clock speed. */ + retval = target_write_u32(target, QN908X_FMC_TIME_CTRL, + QN908X_FMC_TIME_CTRL_TIME_BASE(2 * ahb_freq / 1000000) | + QN908X_FMC_TIME_CTRL_PRGM_CYCLE(30)); + if (retval != ERROR_OK) + return retval; + + return qn908x_load_lock_stat(target); +} + +/* flash bank qn908x <base> <size> 0 0 <target#> [calc_checksum] */ +FLASH_BANK_COMMAND_HANDLER(qn908x_flash_bank_command) +{ + struct qn908x_flash_bank *qn908x_info; + + if (CMD_ARGC < 6 || CMD_ARGC > 7) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (bank->base != QN908X_FLASH_BASE) { + LOG_ERROR("Address " TARGET_ADDR_FMT + " is an invalid bank address (try 0x%08" PRIx32 ")", + bank->base, QN908X_FLASH_BASE); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + qn908x_info = malloc(sizeof(struct qn908x_flash_bank)); + + if (!qn908x_info) + return ERROR_FAIL; + + bank->driver_priv = qn908x_info; + qn908x_info->num_blocks = 0; + qn908x_info->user_bank_size = bank->size; + qn908x_info->page_lock_loaded = false; + qn908x_info->allow_swd_disabled = false; + + qn908x_info->calc_checksum = false; + if (CMD_ARGC == 7) { + if (strcmp(CMD_ARGV[6], "calc_checksum")) { + free(qn908x_info); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + qn908x_info->calc_checksum = true; + } + + return ERROR_OK; +} + +static int qn908x_read_page_lock(struct flash_bank *bank) +{ + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* The last page of the flash contains the "Flash lock and protect" + * information. It is not clear where this is located on chips with only + * one block. */ + uint32_t prot_offset = qn908x_info->num_blocks * QN908X_FLASH_BLOCK_SIZE + - QN908X_FLASH_PAGE_SIZE; + + int retval = target_read_memory(bank->target, bank->base + prot_offset, 4, + sizeof(qn908x_info->page_lock) / 4, + (void *)(&qn908x_info->page_lock)); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("Flash protection = 0x%02" PRIx8, + qn908x_info->page_lock.protection); + + qn908x_info->page_lock_loaded = true; + return ERROR_OK; +} + +static int qn908x_busy_check(struct target *target) +{ + uint32_t status1; + int retval = target_read_u32(target, QN908X_FMC_STATUS1, &status1); + if (retval != ERROR_OK) + return retval; + + if ((status1 & (QN908X_FMC_STATUS1_FSH_ERA_BUSY_L_MASK + | QN908X_FMC_STATUS1_FSH_WR_BUSY_L_MASK + | QN908X_FMC_STATUS1_FSH_ERA_BUSY_H_MASK + | QN908X_FMC_STATUS1_FSH_WR_BUSY_H_MASK))) + return ERROR_FLASH_BUSY; + return ERROR_OK; +} + +static int qn908x_status_check(struct target *target) +{ + uint32_t int_stat; + int retval = target_read_u32(target, QN908X_FMC_INT_STAT, &int_stat); + if (retval != ERROR_OK) + return retval; + + /* The error bits for block 0 and block 1 have the exact same layout, only + * that block 1 error bits are shifted by 8 bits. We use this fact to + * loop over the blocks */ + for (unsigned int block = 0; block <= 1; block++) { + unsigned int shift = (block) ? 8 : 0; + if (int_stat & (QN908X_FMC_INT_STAT_AHBL_INT_MASK << shift)) { + LOG_ERROR("AHB error on block %u", block); + return ERROR_FAIL; + } + + if (int_stat & (QN908X_FMC_INT_STAT_LOCKL_INT_MASK << shift)) { + LOG_ERROR("Locked page being accessed error on block %u", block); + return ERROR_FAIL; + } + + if (int_stat & (QN908X_FMC_INT_STAT_WRITE_FAIL_L_INT_MASK << shift)) { + LOG_ERROR("Smart write on block %u failed", block); + return ERROR_FAIL; + } + + if ((int_stat & (QN908X_FMC_INT_STAT_ERASE_FAIL_L_INT_MASK << shift)) + || (int_stat & (QN908X_FMC_INT_STAT_ERASE_FAIL_H_INT_MASK << shift))) { + LOG_ERROR("Smart erase on block %u failed", block); + return ERROR_FAIL; + } + } + + return ERROR_OK; +} + +static int qn908x_wait_for_idle(struct target *target, int64_t timeout_ms) +{ + int64_t ms_start = timeval_ms(); + + int busy = ERROR_FLASH_BUSY; + while (busy != ERROR_OK) { + busy = qn908x_busy_check(target); + if (busy != ERROR_OK && busy != ERROR_FLASH_BUSY) + return busy; + if (timeval_ms() - ms_start > timeout_ms) { + LOG_ERROR("Timeout waiting to be idle."); + return ERROR_TIMEOUT_REACHED; + } + } + return ERROR_OK; +} + +/* Set up the chip to perform an erase (page or block) operation. */ +static int qn908x_setup_erase(struct target *target) +{ + int retval; + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* Enable 8MHz clock. */ + retval = qn908x_update_reg(target, QN908X_SYSCON_CLK_EN, + QN908X_SYSCON_CLK_EN_CLK_DP_EN_MASK, + QN908X_SYSCON_CLK_EN_CLK_DP_EN_MASK); + if (retval != ERROR_OK) + return retval; + + /* Set ERASE_TIME to 2ms for smart erase. */ + retval = qn908x_update_reg(target, QN908X_FMC_ERASE_TIME, + (1u << 20) - 1, + 2000 * 8); /* 2000 uS * 8 MHz = x cycles */ + if (retval != ERROR_OK) + return retval; + + /* Set up smart erase. SWD can only perform smart erase. */ + uint32_t ctrl_val = QN908X_FMC_SMART_CTRL_SMART_ERASEH_EN_MASK + | QN908X_FMC_SMART_CTRL_SMART_ERASEL_EN_MASK + | QN908X_FMC_SMART_CTRL_MAX_ERASE(QN908X_FMC_SMART_CTRL_MAX_ERASE_RETRIES) + | QN908X_FMC_SMART_CTRL_MAX_WRITE(QN908X_FMC_SMART_CTRL_MAX_WRITE_RETRIES); + retval = target_write_u32(target, QN908X_FMC_SMART_CTRL, ctrl_val); + if (retval != ERROR_OK) + return retval; + + retval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + +static int qn908x_erase(struct flash_bank *bank, unsigned int first, + unsigned int last) +{ + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + int retval = ERROR_OK; + + if (!qn908x_info->num_blocks) { + if (qn908x_probe(bank) != ERROR_OK) + return ERROR_FLASH_BANK_NOT_PROBED; + } + + retval = qn908x_setup_erase(bank->target); + if (retval != ERROR_OK) + return retval; + + for (unsigned int i = first; i <= last; i++) { + if (i >= bank->num_sectors) + return ERROR_FLASH_SECTOR_INVALID; + uint32_t block_idx = i / QN908X_FLASH_PAGES_PER_BLOCK; + uint32_t page_idx = i % QN908X_FLASH_PAGES_PER_BLOCK; + if (block_idx >= qn908x_info->num_blocks) + return ERROR_FLASH_SECTOR_INVALID; + + LOG_DEBUG("Erasing page %" PRIu32 " of block %" PRIu32, + page_idx, block_idx); + + /* Depending on the block the page we are erasing is located we + * need to use a different set of bits in the registers. */ + uint32_t ctrl_page_idx_shift = block_idx ? + QN908X_FMC_ERASE_CTRL_PAGE_IDXH_SHIFT : + QN908X_FMC_ERASE_CTRL_PAGE_IDXL_SHIFT; + uint32_t ctrl_erase_en_shift = block_idx ? + QN908X_FMC_ERASE_CTRL_PAGE_ERASEH_EN_SHIFT : + QN908X_FMC_ERASE_CTRL_PAGE_ERASEL_EN_SHIFT; + + retval = target_write_u32(bank->target, QN908X_FMC_ERASE_CTRL, + BIT(ctrl_erase_en_shift) | (page_idx << ctrl_page_idx_shift)); + if (retval != ERROR_OK) + return retval; + + retval = qn908x_wait_for_idle(bank->target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + retval = qn908x_status_check(bank->target); + if (retval != ERROR_OK) + return retval; + } + + return retval; +} + +static int qn908x_protect(struct flash_bank *bank, int set, unsigned int first, + unsigned int last) +{ + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (!qn908x_info->page_lock_loaded) { + int retval = qn908x_read_page_lock(bank); + if (retval != ERROR_OK) + return retval; + } + + /* Use [first, last) interval open on the right side from now on. */ + last++; + /* We use sectors as prot_blocks. */ + bool needs_update = false; + for (unsigned int i = first; i < last; i++) { + if (set != (((qn908x_info->page_lock.bits[i / 8] >> (i % 8)) & 1) ^ 1)) + needs_update = true; + } + + /* Check that flash protection still allows SWD access to flash and RAM, + * otherwise we won't be able to re-flash this chip from SWD unless we do a + * mass erase. */ + if (qn908x_info->page_lock.protection & QN908X_FMC_LOCK_STAT_8_PROTECT_ANY) { + LOG_WARNING("SWD flash/RAM access disabled in the Flash lock and " + "protect descriptor. You might need to issue a mass_erase to " + "regain SWD access to this chip after reboot."); + } + + if (!needs_update) + return ERROR_OK; + + int last_page = qn908x_info->num_blocks * QN908X_FLASH_PAGES_PER_BLOCK - 1; + int retval; + + if (qn908x_info->page_lock.bits[sizeof(qn908x_info->page_lock.bits) - 1] & 0x80) { + /* A bit 1 in the MSB in the page_lock.bits array means that the last + * page is unlocked, so we can just erase it. */ + retval = qn908x_erase(bank, last_page, last_page); + if (retval != ERROR_OK) + return retval; + } else { + /* TODO: The last page is locked and we can't erase unless we use the + * ERASE_PASSWORD from code running on the device. For this we need to + * copy a little program to RAM and execute the erase command from + * there since there's no way to override the page protection from + * SWD. */ + LOG_ERROR("Unprotecting the last page is not supported. Issue a " + "\"qn908x mass_erase\" command to erase the whole flash, " + "including the last page and its protection."); + return ERROR_FAIL; + } + + for (unsigned int i = first / 8; i < (last + 7) / 8; i++) { + /* first_mask contains a bit set if the bit corresponds to a block id + * that is larger or equal than first. This is basically 0xff in all + * cases except potentially the first iteration. */ + uint8_t first_mask = (first <= i * 8) + ? 0xff : 0xff ^ ((1u << (first - i * 8)) - 1); + /* Similar to first_mask, this contains a bit set if the corresponding + * is smaller than last. */ + uint8_t last_mask = (i * 8 + 8 <= last) + ? 0xff : ((1u << (last - i * 8)) - 1); + + uint8_t mask = first_mask & last_mask; + LOG_DEBUG("protect set=%d bits[%d] with mask=0x%02x", set, i, mask); + /* To "set" the protection bit means to clear the bit in the page_lock + * bit array. */ + if (set) + qn908x_info->page_lock.bits[i] &= ~mask; + else + qn908x_info->page_lock.bits[i] |= mask; + } + + retval = qn908x_write(bank, (void *)(&qn908x_info->page_lock), + last_page * QN908X_FLASH_PAGE_SIZE, sizeof(qn908x_info->page_lock)); + if (retval != ERROR_OK) + return retval; + + /* Reload the lock_stat to make the changes effective. */ + retval = qn908x_load_lock_stat(bank->target); + if (retval != ERROR_OK) + return retval; + + for (unsigned int i = first; i < last; i++) + bank->sectors[i].is_protected = set; + + return ERROR_OK; +} + +static int qn908x_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + int retval = ERROR_OK; + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* The flash infrastructure was requested to align writes to 32 bit */ + assert(((offset % 4) == 0) && ((count % 4) == 0)); + + /* Compute the calc_checksum even if it wasn't requested. */ + uint32_t checksum = 0; + if (offset == 0 && count >= 0x20) { + for (int i = 0; i < 7; i++) + checksum += buf_get_u32(buffer + (i * 4), 0, 32); + checksum = 0 - checksum; + LOG_DEBUG("computed image checksum: 0x%8.8" PRIx32, checksum); + uint32_t stored_checksum = buf_get_u32(buffer + 7 * 4, 0, 32); + if (checksum != stored_checksum) { + LOG_WARNING("Image vector table checksum mismatch: expected 0x%08" + PRIx32 " but found 0x%08" PRIx32, + checksum, stored_checksum); + if (!qn908x_info->calc_checksum) + LOG_WARNING("This device will not boot, use calc_checksum in " + "the flash bank."); + else + LOG_WARNING("Updating checksum, verification will fail."); + } + } + + /* Check the Code Read Protection (CRP) word for invalid values or not + * allowed ones. */ + if (offset <= 0x20 && offset + count >= 0x24) { + uint32_t crp = buf_get_u32(buffer + 0x20 - offset, 0, 32); + /* 2-bit fields at bits 10, 12, 14, 16 and 18 must not be 00 or 11. */ + for (int i = 10; i <= 18; i += 2) { + uint32_t field = (crp >> i) & 3; + if (field == 0 || field == 3) { + LOG_DEBUG("Code Read Protection = 0x%08" PRIx32, crp); + LOG_ERROR("The Code Read Protection (CRP) field at bit %d is " + "invalid (%" PRIu32 "). An invalid value could make " + "the flash inaccessible.", i, field); + return ERROR_FAIL; + } + } + + uint32_t swd_allowed = (crp >> 18) & 3; + if (swd_allowed != 2) { + LOG_WARNING("The Code Read Protection (CRP) in this image " + "(0x%08" PRIx32 ") is disabling the SWD access, which is " + "currently used by OpenOCD to flash this device. After " + "reboot, this device will not be accessible to OpenOCD " + "anymore.", crp); + if (!qn908x_info->allow_swd_disabled) { + LOG_ERROR("Disabling SWD is not allowed, run " + "\"qn908x allow_brick\" before if you really want to " + "disable SWD. You won't be able to access this chip " + "anymore from OpenOCD."); + return ERROR_FAIL; + } + } + } + + retval = qn908x_wait_for_idle(bank->target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + uint32_t smart_ctrl = QN908X_FMC_SMART_CTRL_SMART_WRITEL_EN_MASK + | QN908X_FMC_SMART_CTRL_PRGML_EN_MASK + | QN908X_FMC_SMART_CTRL_MAX_WRITE(QN908X_FMC_SMART_CTRL_MAX_WRITE_RETRIES); + if (qn908x_info->num_blocks > 1) { + smart_ctrl |= QN908X_FMC_SMART_CTRL_SMART_WRITEH_EN_MASK + | QN908X_FMC_SMART_CTRL_PRGMH_EN_MASK; + } + retval = target_write_u32(bank->target, QN908X_FMC_SMART_CTRL, smart_ctrl); + if (retval != ERROR_OK) + return retval; + + /* Write data page-wise, as suggested in the examples in section + * 28.5.2 "Flash write" of user manual UM11023 in revision 1.1 + * (February 2018). */ + while (count > 0) { + uint32_t next_offset = (offset & ~(QN908X_FLASH_PAGE_SIZE - 1)) + QN908X_FLASH_PAGE_SIZE; + uint32_t chunk_len = next_offset - offset; + if (chunk_len > count) + chunk_len = count; + + if (offset == 0 + && chunk_len >= QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END + && qn908x_info->calc_checksum) { + /* write data prior to checksum */ + retval = target_write_buffer(bank->target, bank->base, + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS, buffer); + if (retval != ERROR_OK) + return retval; + + /* write computed crc checksum instead of provided data */ + retval = target_write_u32(bank->target, bank->base + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS, checksum); + if (retval != ERROR_OK) + return retval; + + retval = target_write_buffer(bank->target, + bank->base + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END, + chunk_len - QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END, + buffer + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END); + } else { + retval = target_write_buffer(bank->target, bank->base + offset, + chunk_len, buffer); + } + + if (retval != ERROR_OK) + return retval; + + keep_alive(); + buffer += chunk_len; + count -= chunk_len; + offset = next_offset; + + /* Wait for FMC to complete write */ + retval = qn908x_wait_for_idle(bank->target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + /* Check if FMC reported any errors */ + retval = qn908x_status_check(bank->target); + if (retval != ERROR_OK) + return retval; + } + + return retval; +} + +static int is_flash_protected(struct flash_bank *bank, bool *is_protected) +{ + int retval; + uint32_t lock_stat; + retval = target_read_u32(bank->target, QN908X_FMC_LOCK_STAT_8, &lock_stat); + if (retval) + return retval; + + *is_protected = false; + if (lock_stat & QN908X_FMC_LOCK_STAT_8_PROTECT_ANY) + *is_protected = true; + + return ERROR_OK; +} + +static int qn908x_probe(struct flash_bank *bank) +{ + int retval; + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + uint8_t info_page[QN908X_INFO_PAGE_CRC_END - QN908X_INFO_PAGE_CRC_START]; + qn908x_info->num_blocks = 0; + + /* When the SWD access to the RAM is locked by the LOCK_STAT_8 register we + * can't access the info page to verify the chip/bank version and it will + * read all zeros. This situation prevents the bank from being initialized + * at all so no other operation can be performed. The only option to + * re-flash the chip is to perform a mass_erase from SWD, which can be + * performed even if the mass_erase operation is locked as well. + * We attempt to read the info page and redirect the user to perform a + * mass_erase if we detect this situation. */ + retval = target_read_memory(bank->target, QN908X_INFO_PAGE_CRC_START, + sizeof(uint32_t), sizeof(info_page) / sizeof(uint32_t), + info_page); + if (retval != ERROR_OK) + return retval; + + const uint32_t crc_seed = 0xffffffff; + /* The QN908x uses the standard little endian CRC32 polynomial and all ones + * as seed. The CRC32 is however finalized by one last xor operation that + * is not part of the common CRC32 implementation, so we do that by hand */ + uint32_t computed_crc = crc32_le(CRC32_POLY_LE, crc_seed, + info_page, sizeof(info_page)); + computed_crc ^= crc_seed; + uint32_t read_crc; + retval = target_read_u32(bank->target, QN908X_INFO_PAGE_CRC32, &read_crc); + if (retval != ERROR_OK) + return retval; + + if (computed_crc != read_crc) { + uint32_t info_page_or = 0; + for (unsigned int i = 0; i < sizeof(info_page); i++) + info_page_or |= info_page[i]; + bool is_protected; + retval = is_flash_protected(bank, &is_protected); + if (retval != ERROR_OK) + return retval; + + if (info_page_or == 0 && is_protected) { + LOG_ERROR("The flash or memory in this chip is protected and " + "cannot be accessed from the SWD interface. However, a " + "\"qn908x mass_erase\" can erase the device and lift this " + "protection."); + return ERROR_FAIL; + } + + LOG_ERROR("Flash information page CRC32 mismatch, found 0x%08" + PRIx32 " but computed 0x%08" PRIx32 ". Flash size unknown", + read_crc, computed_crc); + return ERROR_FAIL; + } + + uint32_t flash_size_fld = target_buffer_get_u32(bank->target, + info_page + (QN908X_INFO_PAGE_FLASH_SIZE - QN908X_INFO_PAGE_CRC_START)); + + switch (flash_size_fld) { + case QN908X_FLASH_SIZE_512K: + qn908x_info->num_blocks = 2; + break; + case QN908X_FLASH_SIZE_256K: + qn908x_info->num_blocks = 1; + break; + default: + LOG_ERROR("Unknown Flash size field: 0x%08" PRIx32, + flash_size_fld); + return ERROR_FAIL; + } + + bank->size = qn908x_info->num_blocks * QN908X_FLASH_BLOCK_SIZE; + bank->write_start_alignment = 4; + bank->write_end_alignment = 4; + + /* The flash supports erasing and protecting individual pages. */ + bank->num_sectors = qn908x_info->num_blocks * + QN908X_FLASH_PAGES_PER_BLOCK; + bank->sectors = alloc_block_array(0, QN908X_FLASH_PAGE_SIZE, + bank->num_sectors); + if (!bank->sectors) + return ERROR_FAIL; + + retval = qn908x_init_flash(bank->target); + if (retval != ERROR_OK) + return retval; + + LOG_INFO("Detected flash size: %d KiB", bank->size / 1024); + + return ERROR_OK; +} + +static int qn908x_auto_probe(struct flash_bank *bank) +{ + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + if (qn908x_info->num_blocks != 0) + return ERROR_OK; + LOG_DEBUG("auto_probe"); + return qn908x_probe(bank); +} + +static int qn908x_protect_check(struct flash_bank *bank) +{ + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + + int retval = qn908x_read_page_lock(bank); + if (retval != ERROR_OK) + return retval; + + for (uint32_t i = 0; + i < qn908x_info->num_blocks * QN908X_FLASH_PAGES_PER_BLOCK; + i++) { + /* A bit 0 in page_lock means page is locked. */ + bank->sectors[i].is_protected = + ((qn908x_info->page_lock.bits[i / 8] >> (i % 8)) & 1) ^ 1; + } + return ERROR_OK; +} + +static int qn908x_get_info(struct flash_bank *bank, + struct command_invocation *cmd) +{ + uint32_t bootloader_version; + uint32_t chip_id; + uint8_t bluetooth[6]; + int retval; + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + + retval = target_read_u32(bank->target, QN908X_SYSCON_CHIP_ID, &chip_id); + if (retval != ERROR_OK) { + command_print_sameline(cmd, "Cannot read QN908x chip ID."); + return retval; + } + retval = target_read_u32(bank->target, QN908X_INFO_PAGE_BOOTLOADER_VER, + &bootloader_version); + if (retval != ERROR_OK) { + command_print_sameline(cmd, "Cannot read from QN908x info page."); + return retval; + } + + retval = target_read_memory(bank->target, QN908X_INFO_PAGE_BLUETOOTH_ADDR, + 1, sizeof(bluetooth), bluetooth); + if (retval != ERROR_OK) { + command_print_sameline(cmd, "Cannot read QN908x bluetooth L2 address."); + return retval; + } + + command_print_sameline(cmd, "qn908x: chip id: 0x%" PRIx32, chip_id); + + command_print_sameline(cmd, " bdaddr: " + "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 + ":%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8, + bluetooth[0], bluetooth[1], bluetooth[2], + bluetooth[3], bluetooth[4], bluetooth[5]); + + command_print_sameline(cmd, " bootloader: %08" PRIx32, bootloader_version); + + command_print_sameline(cmd, " blocks: %" PRIu32, qn908x_info->num_blocks); + + return ERROR_OK; +} + +COMMAND_HANDLER(qn908x_handle_allow_brick_command) +{ + int retval; + + struct target *target = get_current_target(CMD_CTX); + struct flash_bank *bank = NULL; + + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + retval = get_flash_bank_by_addr(target, QN908X_FLASH_BASE, true, &bank); + if (retval != ERROR_OK) + return retval; + + /* If get_flash_bank_by_addr() did not find the flash bank, it should have + * returned and error code instead of ERROR_OK */ + assert(bank); + struct qn908x_flash_bank *qn908x_info = bank->driver_priv; + + LOG_WARNING("Flashing images that disable SWD in qn908x is now allowed."); + qn908x_info->allow_swd_disabled = true; + + return ERROR_OK; +} + +COMMAND_HANDLER(qn908x_handle_disable_wdog_command) +{ + int retval; + struct target *target = get_current_target(CMD_CTX); + + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (target->state != TARGET_HALTED) { + command_print(CMD, "Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* To change any value in the watchdog block (WDT) we need to first write + * 0x1ACCE551 to the LOCK register, and we can then set it back to any other + * value to prevent accidental changes to the watchdog. */ + retval = target_write_u32(target, QN908X_WDT_LOCK, 0x1ACCE551); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, QN908X_WDT_CTRL, 0); + if (retval != ERROR_OK) + return retval; + + return target_write_u32(target, QN908X_WDT_LOCK, 0); +} + +COMMAND_HANDLER(qn908x_handle_mass_erase_command) +{ + int retval; + bool keep_lock = false; + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + if (CMD_ARGC == 1) { + if (strcmp("keep_lock", CMD_ARGV[0])) + return ERROR_COMMAND_ARGUMENT_INVALID; + keep_lock = true; + } + + /* This operation can be performed without probing the bank since it is the + * only way to unlock a chip when the flash and ram have been locked. */ + struct target *target = get_current_target(CMD_CTX); + + retval = qn908x_setup_erase(target); + if (retval != ERROR_OK) + return retval; + + /* Check the mass-erase locking status for information purposes only. This + * lock applies to both the SWD and the code running in the core but can be + * bypassed in either case. */ + uint32_t lock_stat_8; + retval = target_read_u32(target, QN908X_FMC_LOCK_STAT_8, &lock_stat_8); + LOG_DEBUG("LOCK_STAT_8 before erasing: 0x%" PRIx32, lock_stat_8); + if (retval != ERROR_OK) + return retval; + if ((lock_stat_8 & QN908X_FMC_LOCK_STAT_8_MASS_ERASE_LOCK_EN) == 0) { + LOG_INFO("mass_erase disabled by Flash lock and protection, forcing " + "mass_erase."); + } + /* Set the DEBUG_PASSWORD so we can force the mass erase from the SWD. We do + * this regardless of the lock status. */ + retval = target_write_u32(target, QN908X_FMC_DEBUG_PASSWORD, 0xCA1E093F); + if (retval != ERROR_OK) + return retval; + + /* Erase both halves of the flash at the same time. These are actually done + * sequentially but we need to send the command to erase both blocks since + * doing so in a locked flash will change the LOCK_STAT_8 register to 0x01, + * allowing us to access the (now erase) flash an memory. Erasing only one + * block at a time does not reset the LOCK_STAT_8 register and therefore + * will not grant access to program the chip. */ + uint32_t erase_cmd = (1u << QN908X_FMC_ERASE_CTRL_HALF_ERASEH_EN_SHIFT) | + (1u << QN908X_FMC_ERASE_CTRL_HALF_ERASEL_EN_SHIFT); + LOG_DEBUG("Erasing both blocks with command 0x%" PRIx32, erase_cmd); + + retval = target_write_u32(target, QN908X_FMC_ERASE_CTRL, erase_cmd); + if (retval != ERROR_OK) + return retval; + + retval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + retval = qn908x_status_check(target); + if (retval != ERROR_OK) + return retval; + + /* Set the debug password back to 0 to avoid accidental mass_erase. */ + retval = target_write_u32(target, QN908X_FMC_DEBUG_PASSWORD, 0); + if (retval != ERROR_OK) + return retval; + + /* At this point the flash is erased and we are able to write to the flash + * since the LOCK_STAT_8 gets updated to 0x01 after the mass_erase. However, + * after a hard reboot this value will be realoaded from flash which after + * an erase is 0xff. This means that after flashing an image that doesn't + * set the protection bits we end up with a chip that we can't debug. We + * update this value to 0x01 unless "keep_lock" is passed to allow the SWD + * interface to debug the flash and RAM after a hard reset. */ + if (keep_lock) + return retval; + + retval = qn908x_init_flash(target); + if (retval != ERROR_OK) + return retval; + + /* Unlock access to RAM and FLASH in the last page of the flash and + * reloading */ + retval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + uint32_t smart_ctrl = QN908X_FMC_SMART_CTRL_SMART_WRITEH_EN_MASK | + QN908X_FMC_SMART_CTRL_PRGMH_EN_MASK; + retval = target_write_u32(target, QN908X_FMC_SMART_CTRL, smart_ctrl); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, QN908X_FLASH_LOCK_ADDR, + QN908X_FLASH_LOCK_ENABLE_MASS_ERASE); + if (retval != ERROR_OK) + return retval; + + retval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS); + if (retval != ERROR_OK) + return retval; + + /* Force a page_lock reload after the mass_erase . */ + retval = qn908x_load_lock_stat(target); + if (retval != ERROR_OK) + return retval; + + return retval; +} + +static const struct command_registration qn908x_exec_command_handlers[] = { + { + .name = "allow_brick", + .handler = qn908x_handle_allow_brick_command, + .mode = COMMAND_EXEC, + .help = "Allow writing images that disable SWD access in their " + "Code Read Protection (CRP) word. Warning: This can make your " + "chip inaccessible from OpenOCD or any other SWD debugger.", + .usage = "", + }, + { + .name = "disable_wdog", + .handler = qn908x_handle_disable_wdog_command, + .mode = COMMAND_EXEC, + .help = "Disabled the watchdog (WDT).", + .usage = "", + }, + { + .name = "mass_erase", + .handler = qn908x_handle_mass_erase_command, + .mode = COMMAND_EXEC, + .help = "Erase the whole flash chip.", + .usage = "[keep_lock]", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration qn908x_command_handlers[] = { + { + .name = "qn908x", + .mode = COMMAND_ANY, + .help = "qn908x flash controller commands", + .usage = "", + .chain = qn908x_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +const struct flash_driver qn908x_flash = { + .name = "qn908x", + .commands = qn908x_command_handlers, + .flash_bank_command = qn908x_flash_bank_command, + .info = qn908x_get_info, + .erase = qn908x_erase, + .protect = qn908x_protect, + .write = qn908x_write, + .read = default_flash_read, + .probe = qn908x_probe, + .auto_probe = qn908x_auto_probe, + .erase_check = default_flash_blank_check, + .protect_check = qn908x_protect_check, + .free_driver_priv = default_flash_free_driver_priv, +}; diff --git a/tcl/target/qn908x.cfg b/tcl/target/qn908x.cfg new file mode 100644 index 000000000..ac3e06b69 --- /dev/null +++ b/tcl/target/qn908x.cfg @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# NXP QN908x Cortex-M4F with 128 KiB SRAM + +source [find target/swj-dp.tcl] + +set CHIPNAME qn908x +set CHIPSERIES qn9080 +if { ![info exists WORKAREASIZE] } { + set WORKAREASIZE 0x20000 +} + +# SWD IDCODE (Cortex M4). +set CPUTAPID 0x2ba01477 + +swj_newdap $CHIPNAME cpu -irlen 4 -expected-id $CPUTAPID +dap create $CHIPNAME.dap -chain-position $CHIPNAME.cpu + +set TARGETNAME $CHIPNAME.cpu +target create $TARGETNAME cortex_m -dap $CHIPNAME.dap + +# SRAM is mapped at 0x04000000. +$TARGETNAME configure -work-area-phys 0x04000000 -work-area-size $WORKAREASIZE + +# flash bank <name> qn908x <base> <size> 0 0 <target#> [calc_checksum] +# The base must be set as 0x01000000, and the size parameter is unused. +set FLASHNAME $CHIPNAME.flash +flash bank $FLASHNAME qn908x 0x01000000 0 0 0 $TARGETNAME calc_checksum + +# We write directly to flash memory over this adapter interface. For debugging +# this could in theory be faster (the Core clock on reset is normally at 32MHz), +# but for flashing 1MHz is more reliable. +adapter speed 1000 + +# Delay on reset line. +adapter srst delay 200 + +cortex_m reset_config sysresetreq ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 110 +++++ src/flash/nor/Makefile.am | 1 + src/flash/nor/driver.h | 1 + src/flash/nor/drivers.c | 1 + src/flash/nor/qn908x.c | 1197 +++++++++++++++++++++++++++++++++++++++++++++ tcl/target/qn908x.cfg | 38 ++ 6 files changed, 1348 insertions(+) create mode 100644 src/flash/nor/qn908x.c create mode 100644 tcl/target/qn908x.cfg hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 21:05:07
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 24b656bff5889350b0c95d791d47e479d9fbd7f9 (commit) from 146fec5820beb8e6bd3f9091443954904f377589 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 24b656bff5889350b0c95d791d47e479d9fbd7f9 Author: Jacek Wuwer <jac...@gm...> Date: Mon May 29 19:00:27 2023 +0200 jtag/vdebug: adding xtensa config This change adds the extensa sample target and board configurations. it removes the obsoleted vd_xtensa_jtag.cfg from targets. Change-Id: I9d4d25abde46c0b15e5211a973012447872cb405 Signed-off-by: Jacek Wuwer <jac...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7723 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/tcl/board/vd_xt8_jtag.cfg b/tcl/board/vd_xt8_jtag.cfg new file mode 100644 index 000000000..867b9e76e --- /dev/null +++ b/tcl/board/vd_xt8_jtag.cfg @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Cadence virtual debug interface +# Xtensa xt8 through JTAG + +source [find interface/vdebug.cfg] + +set CHIPNAME xt8 +set CPUTAPID 0x120034e5 + +# vdebug select transport +transport select jtag + +# JTAG reset config, frequency and reset delay +reset_config trst_and_srst +adapter speed 50000 +adapter srst delay 5 + +# BFM hierarchical path and input clk period +vdebug bfm_path Testbench.u_vd_jtag_bfm 10ns + +# DMA Memories to access backdoor, the values come from generated xtensa-core-xt8.cfg +#vdebug mem_path Testbench.Xtsubsystem.Core0.iram0.iram0.mem.dataArray 0x40000000 0x100000 +#vdebug mem_path Testbench.Xtsubsystem.Core0.dram0.dram0.mem.dataArray 0x3ff00000 0x40000 + +# Create Xtensa target first +source [find target/xtensa.cfg] +# Generate [xtensa-core-XXX.cfg] via "xt-gdb --dump-oocd-config" +source [find target/xtensa-core-xt8.cfg] diff --git a/tcl/target/vd_xtensa_jtag.cfg b/tcl/target/vd_xtensa_jtag.cfg deleted file mode 100644 index 88f5bcc07..000000000 --- a/tcl/target/vd_xtensa_jtag.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# Cadence virtual debug interface -# for Palladium emulation systems -# - -# TODO: Enable backdoor memory access -# set _MEMSTART 0x00000000 -# set _MEMSIZE 0x100000 - -# BFM hierarchical path and input clk period -vdebug bfm_path dut_top.JTAG 10ns -# DMA Memories to access backdoor (up to 4) -# vdebug mem_path tbench.u_mcu.u_sys.u_itcm_ram.Mem $_MEMSTART $_MEMSIZE - -# Create Xtensa target first -source [find target/xtensa.cfg] - -# Configure Xtensa core parameters next -# Generate [xtensa-core-XXX.cfg] via "xt-gdb --dump-oocd-config" - -# register target -proc vdebug_examine_end {} { -# vdebug register_target -} - -# Default hooks -$_TARGETNAME configure -event examine-end { vdebug_examine_end } diff --git a/tcl/target/xtensa-core-xt8.cfg b/tcl/target/xtensa-core-xt8.cfg new file mode 100644 index 000000000..e544d7854 --- /dev/null +++ b/tcl/target/xtensa-core-xt8.cfg @@ -0,0 +1,166 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# OpenOCD configuration file for Xtensa xt8 target + +# Core definition and ABI +xtensa xtdef LX +xtensa xtopt arnum 32 +xtensa xtopt windowed 1 + + +# Exception/Interrupt Options +xtensa xtopt exceptions 1 +xtensa xtopt hipriints 1 +xtensa xtopt intlevels 3 +xtensa xtopt excmlevel 1 + + +# Cache Options +xtensa xtmem icache 16 1024 1 +xtensa xtmem dcache 16 1024 1 1 + + +# Memory Options +xtensa xtmem iram 0x40000000 1048576 +xtensa xtmem dram 0x3ff00000 262144 +xtensa xtmem srom 0x50000000 131072 +xtensa xtmem sram 0x60000000 4194304 + + +# Memory Protection/Translation Options + + +# Debug Options +xtensa xtopt debuglevel 3 +xtensa xtopt ibreaknum 2 +xtensa xtopt dbreaknum 2 + + +# Core Registers +xtensa xtregs 127 +xtensa xtreg a0 0x0000 +xtensa xtreg a1 0x0001 +xtensa xtreg a2 0x0002 +xtensa xtreg a3 0x0003 +xtensa xtreg a4 0x0004 +xtensa xtreg a5 0x0005 +xtensa xtreg a6 0x0006 +xtensa xtreg a7 0x0007 +xtensa xtreg a8 0x0008 +xtensa xtreg a9 0x0009 +xtensa xtreg a10 0x000a +xtensa xtreg a11 0x000b +xtensa xtreg a12 0x000c +xtensa xtreg a13 0x000d +xtensa xtreg a14 0x000e +xtensa xtreg a15 0x000f +xtensa xtreg pc 0x0020 +xtensa xtreg ar0 0x0100 +xtensa xtreg ar1 0x0101 +xtensa xtreg ar2 0x0102 +xtensa xtreg ar3 0x0103 +xtensa xtreg ar4 0x0104 +xtensa xtreg ar5 0x0105 +xtensa xtreg ar6 0x0106 +xtensa xtreg ar7 0x0107 +xtensa xtreg ar8 0x0108 +xtensa xtreg ar9 0x0109 +xtensa xtreg ar10 0x010a +xtensa xtreg ar11 0x010b +xtensa xtreg ar12 0x010c +xtensa xtreg ar13 0x010d +xtensa xtreg ar14 0x010e +xtensa xtreg ar15 0x010f +xtensa xtreg ar16 0x0110 +xtensa xtreg ar17 0x0111 +xtensa xtreg ar18 0x0112 +xtensa xtreg ar19 0x0113 +xtensa xtreg ar20 0x0114 +xtensa xtreg ar21 0x0115 +xtensa xtreg ar22 0x0116 +xtensa xtreg ar23 0x0117 +xtensa xtreg ar24 0x0118 +xtensa xtreg ar25 0x0119 +xtensa xtreg ar26 0x011a +xtensa xtreg ar27 0x011b +xtensa xtreg ar28 0x011c +xtensa xtreg ar29 0x011d +xtensa xtreg ar30 0x011e +xtensa xtreg ar31 0x011f +xtensa xtreg lbeg 0x0200 +xtensa xtreg lend 0x0201 +xtensa xtreg lcount 0x0202 +xtensa xtreg sar 0x0203 +xtensa xtreg windowbase 0x0248 +xtensa xtreg windowstart 0x0249 +xtensa xtreg configid0 0x02b0 +xtensa xtreg configid1 0x02d0 +xtensa xtreg ps 0x02e6 +xtensa xtreg expstate 0x03e6 +xtensa xtreg mmid 0x0259 +xtensa xtreg ibreakenable 0x0260 +xtensa xtreg ddr 0x0268 +xtensa xtreg ibreaka0 0x0280 +xtensa xtreg ibreaka1 0x0281 +xtensa xtreg dbreaka0 0x0290 +xtensa xtreg dbreaka1 0x0291 +xtensa xtreg dbreakc0 0x02a0 +xtensa xtreg dbreakc1 0x02a1 +xtensa xtreg epc1 0x02b1 +xtensa xtreg epc2 0x02b2 +xtensa xtreg epc3 0x02b3 +xtensa xtreg depc 0x02c0 +xtensa xtreg eps2 0x02c2 +xtensa xtreg eps3 0x02c3 +xtensa xtreg excsave1 0x02d1 +xtensa xtreg excsave2 0x02d2 +xtensa xtreg excsave3 0x02d3 +xtensa xtreg interrupt 0x02e2 +xtensa xtreg intset 0x02e2 +xtensa xtreg intclear 0x02e3 +xtensa xtreg intenable 0x02e4 +xtensa xtreg exccause 0x02e8 +xtensa xtreg debugcause 0x02e9 +xtensa xtreg ccount 0x02ea +xtensa xtreg icount 0x02ec +xtensa xtreg icountlevel 0x02ed +xtensa xtreg excvaddr 0x02ee +xtensa xtreg ccompare0 0x02f0 +xtensa xtreg ccompare1 0x02f1 +xtensa xtreg pwrctl 0x200f +xtensa xtreg pwrstat 0x2010 +xtensa xtreg eristat 0x2011 +xtensa xtreg cs_itctrl 0x2012 +xtensa xtreg cs_claimset 0x2013 +xtensa xtreg cs_claimclr 0x2014 +xtensa xtreg cs_lockaccess 0x2015 +xtensa xtreg cs_lockstatus 0x2016 +xtensa xtreg cs_authstatus 0x2017 +xtensa xtreg fault_info 0x2026 +xtensa xtreg trax_id 0x2027 +xtensa xtreg trax_control 0x2028 +xtensa xtreg trax_status 0x2029 +xtensa xtreg trax_data 0x202a +xtensa xtreg trax_address 0x202b +xtensa xtreg trax_pctrigger 0x202c +xtensa xtreg trax_pcmatch 0x202d +xtensa xtreg trax_delay 0x202e +xtensa xtreg trax_memstart 0x202f +xtensa xtreg trax_memend 0x2030 +xtensa xtreg pmg 0x203e +xtensa xtreg pmpc 0x203f +xtensa xtreg pm0 0x2040 +xtensa xtreg pm1 0x2041 +xtensa xtreg pmctrl0 0x2042 +xtensa xtreg pmctrl1 0x2043 +xtensa xtreg pmstat0 0x2044 +xtensa xtreg pmstat1 0x2045 +xtensa xtreg ocdid 0x2046 +xtensa xtreg ocd_dcrclr 0x2047 +xtensa xtreg ocd_dcrset 0x2048 +xtensa xtreg ocd_dsr 0x2049 +xtensa xtreg psintlevel 0x2003 +xtensa xtreg psum 0x2004 +xtensa xtreg pswoe 0x2005 +xtensa xtreg psexcm 0x2006 +xtensa xtreg pscallinc 0x2007 +xtensa xtreg psowb 0x2008 ----------------------------------------------------------------------- Summary of changes: tcl/board/vd_xt8_jtag.cfg | 28 +++++++ tcl/target/vd_xtensa_jtag.cfg | 27 ------- tcl/target/xtensa-core-xt8.cfg | 166 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 27 deletions(-) create mode 100644 tcl/board/vd_xt8_jtag.cfg delete mode 100644 tcl/target/vd_xtensa_jtag.cfg create mode 100644 tcl/target/xtensa-core-xt8.cfg hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 21:04:45
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 146fec5820beb8e6bd3f9091443954904f377589 (commit) from 81cf948bf4be9a05b364737a1283def1becfdb71 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 146fec5820beb8e6bd3f9091443954904f377589 Author: Jacek Wuwer <jac...@gm...> Date: Mon May 29 18:38:44 2023 +0200 jtag/vdebug: using tap_state This change implements the predefined type tap_state instead of generic uint8_t in the driver Change-Id: I3478e8d7b40b961f3ba77711179016cdcc35cd32 Signed-off-by: Jacek Wuwer <jac...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7722 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c index 4187c9876..f6d99c6c1 100644 --- a/src/jtag/drivers/vdebug.c +++ b/src/jtag/drivers/vdebug.c @@ -53,7 +53,7 @@ #include "helper/log.h" #include "helper/list.h" -#define VD_VERSION 44 +#define VD_VERSION 46 #define VD_BUFFER_LEN 4024 #define VD_CHEADER_LEN 24 #define VD_SHEADER_LEN 16 @@ -942,10 +942,10 @@ static int vdebug_jtag_tlr(tap_state_t state, uint8_t f_flush) { int rc = ERROR_OK; - uint8_t cur = tap_get_state(); + tap_state_t cur = tap_get_state(); uint8_t tms_pre = tap_get_tms_path(cur, state); uint8_t num_pre = tap_get_tms_path_len(cur, state); - LOG_INFO("tlr from %" PRIx8 " to %" PRIx8, cur, state); + LOG_INFO("tlr from %x to %x", cur, state); if (cur != state) { rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, 0, NULL, 0, 0, NULL, f_flush); tap_set_state(state); @@ -958,7 +958,7 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush) { int rc = ERROR_OK; - uint8_t cur = tap_get_state(); + tap_state_t cur = tap_get_state(); uint8_t state = cmd->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT; uint8_t tms_pre = tap_get_tms_path(cur, state); uint8_t num_pre = tap_get_tms_path_len(cur, state); @@ -988,7 +988,7 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush) static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush) { - uint8_t cur = tap_get_state(); + tap_state_t cur = tap_get_state(); uint8_t tms_pre = tap_get_tms_path(cur, state); uint8_t num_pre = tap_get_tms_path_len(cur, state); LOG_DEBUG("idle len:%d state cur:%x end:%x", cycles, cur, state); ----------------------------------------------------------------------- Summary of changes: src/jtag/drivers/vdebug.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 21:03:54
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 81cf948bf4be9a05b364737a1283def1becfdb71 (commit) from 4dc4280555e69fd33b4ebe265dca876c07425d1c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 81cf948bf4be9a05b364737a1283def1becfdb71 Author: Jacek Wuwer <jac...@gm...> Date: Mon May 29 17:46:08 2023 +0200 jtag/vdebug: fix endianness support This change fixes endianness support in the driver. Change-Id: Ida360bb58e988cea0a66fdc79e1610b528846fc4 Signed-off-by: Jacek Wuwer <jac...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7721 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c index 9223be23f..4187c9876 100644 --- a/src/jtag/drivers/vdebug.c +++ b/src/jtag/drivers/vdebug.c @@ -272,7 +272,7 @@ static int vdebug_socket_open(char *server_addr, uint32_t port) LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr, vdebug_socket_error()); rc = VD_ERR_SOC_ADDR; } else { - buf_set_u32((uint8_t *)ainfo->ai_addr->sa_data, 0, 16, htons(port)); + h_u16_to_be((uint8_t *)ainfo->ai_addr->sa_data, port); if (connect(hsock, ainfo->ai_addr, sizeof(struct sockaddr)) < 0) { LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr, port, vdebug_socket_error()); rc = VD_ERR_SOC_CONN; @@ -1125,7 +1125,7 @@ static int vdebug_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) static int vdebug_dap_run(struct adiv5_dap *dap) { - if (pbuf->waddr) + if (le_to_h_u16(pbuf->waddr)) return vdebug_run_reg_queue(vdc.hsocket, pbuf, le_to_h_u16(pbuf->waddr)); return ERROR_OK; ----------------------------------------------------------------------- Summary of changes: src/jtag/drivers/vdebug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 21:01:03
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 4dc4280555e69fd33b4ebe265dca876c07425d1c (commit) from b02cbafcc987a629c9ae30cb2fbe7af1654745e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4dc4280555e69fd33b4ebe265dca876c07425d1c Author: Erhan Kurubas <erh...@es...> Date: Sun May 28 14:56:56 2023 +0300 target/espressif: fix clang scan-build warning Clang reports that 3rd function call argument is an uninitialized value file esp32_apptrace.c line:1270 Signed-off-by: Erhan Kurubas <erh...@es...> Change-Id: I73e254d4eb0c6b3152229717d8827d334784ab92 Reviewed-on: https://review.openocd.org/c/openocd/+/7719 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/target/espressif/esp32_apptrace.c b/src/target/espressif/esp32_apptrace.c index 427f01170..884224116 100644 --- a/src/target/espressif/esp32_apptrace.c +++ b/src/target/espressif/esp32_apptrace.c @@ -1252,7 +1252,7 @@ static int esp32_sysview_start(struct esp32_apptrace_cmd_ctx *ctx) { uint8_t cmds[] = { SEGGER_SYSVIEW_COMMAND_ID_START }; uint32_t fired_target_num = 0; - struct esp32_apptrace_target_state target_state[ESP32_APPTRACE_MAX_CORES_NUM]; + struct esp32_apptrace_target_state target_state[ESP32_APPTRACE_MAX_CORES_NUM] = {0}; struct esp32_sysview_cmd_data *cmd_data = ctx->cmd_priv; /* get current block id */ ----------------------------------------------------------------------- Summary of changes: src/target/espressif/esp32_apptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 21:00:25
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via b02cbafcc987a629c9ae30cb2fbe7af1654745e6 (commit) from 00cbf7bd318c840d9ec3893a3809dd9d0c2e3fa7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b02cbafcc987a629c9ae30cb2fbe7af1654745e6 Author: Wolfram Sang <ws...@ke...> Date: Tue Mar 28 21:28:35 2023 +0200 tcl/board/calao-usb-a9g20-c01: add proper initialization Initialize clocks to max speed and setup SDRAM. NAND support is still incomplete. Originally found at: elinux.org/index.php?title=Calao_Atmel_AT91_development_board&oldid=73933 Updated the code from 2011 and improved it a bit. Signed-off-by: Wolfram Sang <ws...@ke...> Change-Id: I83474e07c8de8cc3b5d058029551935549693ef9 Reviewed-on: https://review.openocd.org/c/openocd/+/7578 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/tcl/board/calao-usb-a9g20-c01.cfg b/tcl/board/calao-usb-a9g20-c01.cfg index 6c4bd40fe..d2017864a 100644 --- a/tcl/board/calao-usb-a9g20-c01.cfg +++ b/tcl/board/calao-usb-a9g20-c01.cfg @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later # CALAO Systems USB-A9G20-C01 +# Authors: Gregory Hermant, Jean-Christophe PLAGNIOL-VILLARD, Wolfram Sang adapter driver ftdi ftdi device_desc "USB-A9G20" @@ -12,3 +13,160 @@ ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 transport select jtag source [find target/at91sam9g20.cfg] +source [find mem_helper.tcl] + +proc at91sam9g20_reset_start { } { + + # Make sure that the jtag is running slow, since there are a number of different ways the board + # can be configured coming into this state that can cause communication problems with the jtag + # adapter. Also since this call can be made following a "reset init" where fast memory accesses + # are enabled, Need to temporarily shut this down so that the RSTC_MR register can be written at slower + # jtag speed without causing GDB keep alive problem. + + arm7_9 fast_memory_access disable + adapter speed 2 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow. + halt 0 ;# Make sure processor is halted, or error will result in following steps. + wait_halt 10000 + # RSTC_MR : enable user reset, MMU may be enabled... use physical address + mww phys 0xfffffd08 0xa5000501 +} + +proc at91sam9g20_reset_init { } { + + # At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz). To shift over to a normal clock requires + # a number of steps that must be carefully performed. The process outline below follows the + # recommended procedure outlined in the AT91SAM9G20 technical manual. + # + # Several key and very important things to keep in mind: + # The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts. This + # means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur. The processor + # core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly. + + mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog. + + # Set oscillator bypass bit (12.00 MHz external oscillator) in CKGR_MOR register. + + mww 0xfffffc20 0x00000002 + + # Set PLLA Register for 798.000 MHz (divider: bypass, multiplier: 132). + # Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable. + + mww 0xfffffc28 0x20843F02 + while { [expr { [mrw 0xfffffc68] & 0x02 } ] != 2 } { sleep 1 } + + # Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR. + # Wait for MCKRDY signal from PMC_SR to assert. + + mww 0xfffffc30 0x00001300 + while { [expr { [mrw 0xfffffc68] & 0x08 } ] != 8 } { sleep 1 } + + # Now change PMC_MCKR register to select PLLA. + # Wait for MCKRDY signal from PMC_SR to assert. + + mww 0xfffffc30 0x00001302 + while { [expr { [mrw 0xfffffc68] & 0x08 } ] != 8 } { sleep 1 } + + # Processor and master clocks are now operating and stable at maximum frequency possible: + # -> MCLK = 133.000 MHz + # -> PCLK = 400.000 MHz + + # Switch to fast JTAG speed + + adapter speed 9500 + + # Enable faster DCC downloads. + + arm7_9 dcc_downloads enable + arm7_9 fast_memory_access enable + + # To be able to use external SDRAM, several peripheral configuration registers must + # be modified. The first change is made to PIO_ASR to select peripheral functions + # for D15 through D31. The second change is made to the PIO_PDR register to disable + # this for D15 through D31. + + mww 0xfffff870 0xffff0000 + mww 0xfffff804 0xffff0000 + + # The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller + # using CS1. Additionally we want CS3 assigned to NandFlash. Also VDDIO is connected physically on + # the board to the 1.8V VDC power supply so set the appropriate register bit to notify the micrcontroller. + + mww 0xffffef1c 0x000000a + + # The USB-A9G20 Embedded computer has built-in NandFlash. The exact physical timing characteristics + # for the memory type used on the current board (MT29F2G08AACWP) can be established by setting + # four registers in order: SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3. + + mww 0xffffec30 0x00020002 + mww 0xffffec34 0x04040404 + mww 0xffffec38 0x00070007 + mww 0xffffec3c 0x00030003 + + # Now setup SDRAM. This is tricky and configuration is very important for reliability! The current calculations + # are based on 2 x Micron LPSDRAM MT48H16M16LFBF-75 memory (4 M x 16 bit x 4 banks). If you use this file as a reference + # for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted + # into the SDRAM_CR register. Using the memory datasheet for the -75 grade part and assuming a master clock + # of 133.000 MHz then the SDCLK period is equal to 7.6 ns. This means the device requires: + # + # CAS latency = 3 cycles + # TXSR = 10 cycles + # TRAS = 6 cycles + # TRCD = 3 cycles + # TRP = 3 cycles + # TRC = 9 cycles + # TWR = 2 cycles + # 9 column, 13 row, 4 banks + # refresh equal to or less then 7.8 us for commercial/industrial rated devices + # + # Thus SDRAM_CR = 0xa6339279 + + mww 0xffffea08 0xa6339279 + + # Memory Device Type: SDRAM (low-power would be 0x1) + mww 0xffffea24 0x00000000 + + # Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into + # the starting memory location for the SDRAM. + + mww 0xffffea00 0x00000001 + mww 0x20000000 0 + + # Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero + # value into the starting memory location for the SDRAM. + + mww 0xffffea00 0x00000002 + mww 0x20000000 0 + + # Now issue an 'Auto-Refresh' command through the SDRAMC_MR register. Follow this operation by writing + # zero values eight times into the starting memory location for the SDRAM. + + mww 0xffffea00 0x4 + mww 0x20000000 0 + mww 0x20000000 0 + mww 0x20000000 0 + mww 0x20000000 0 + mww 0x20000000 0 + mww 0x20000000 0 + mww 0x20000000 0 + mww 0x20000000 0 + + # Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the + # the starting memory location for the SDRAM. + + mww 0xffffea00 0x3 + mww 0x20000000 0 + + # Signal normal mode using the SDRAMC_MR register and follow with a zero value write the starting + # memory location for the SDRAM. + + mww 0xffffea00 0x0 + mww 0x20000000 0 + + # Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles). + + mww 0xffffea04 0x0000039c +} + +$_TARGETNAME configure -event gdb-attach { reset init } +$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start} +$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init} ----------------------------------------------------------------------- Summary of changes: tcl/board/calao-usb-a9g20-c01.cfg | 158 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 21:00:04
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 00cbf7bd318c840d9ec3893a3809dd9d0c2e3fa7 (commit) from 0e526314a155c73e5eac2dc6bdea0235738ca1a2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 00cbf7bd318c840d9ec3893a3809dd9d0c2e3fa7 Author: Dominik Wernberger <dom...@gm...> Date: Thu May 18 16:51:55 2023 +0200 Add/Correct STM8L15xx2/3/4/6/8 devices Change-Id: I83fe1e50821ec15e1853aca96ebb32fe1ff5328f Signed-off-by: Dominik Wernberger <dom...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7690 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/tcl/board/st_nucleo_8l152r8.cfg b/tcl/board/st_nucleo_8l152r8.cfg index f06d74981..7cb8bcecd 100644 --- a/tcl/board/st_nucleo_8l152r8.cfg +++ b/tcl/board/st_nucleo_8l152r8.cfg @@ -7,6 +7,6 @@ source [find interface/stlink-dap.cfg] transport select swim -source [find target/stm8l152.cfg] +source [find target/stm8l15xx8.cfg] reset_config srst_only diff --git a/tcl/target/stm8l151x2.cfg b/tcl/target/stm8l151x2.cfg new file mode 100644 index 000000000..db88c715b --- /dev/null +++ b/tcl/target/stm8l151x2.cfg @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config script for STM8L151x2 +# Supported Devices: +# STM8L151C2 +# STM8L151F2 +# STM8L151G2 +# STM8L151K2 + +# 1kB RAM +# Start 0x0000 +# End 0x03ff +set WORKAREASIZE 1024 + +# 4kB Flash +set FLASHSTART 0x8000 +set FLASHEND 0x8fff + +# 256B EEPROM +set EEPROMSTART 0x1000 +set EEPROMEND 0x10ff + +set OPTIONSTART 0x4800 +set OPTIONEND 0x487f + +proc stm8_reset_rop {} { + mwb 0x4800 0xaa + mwb 0x4800 0xaa + reset halt +} + +source [find target/stm8l.cfg] diff --git a/tcl/target/stm8l151x3.cfg b/tcl/target/stm8l151x3.cfg new file mode 100644 index 000000000..fe904b4f2 --- /dev/null +++ b/tcl/target/stm8l151x3.cfg @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config script for STM8L151x3 +# Supported Devices: +# STM8L151C3 +# STM8L151F3 +# STM8L151G3 +# STM8L151K3 + +# 1kB RAM +# Start 0x0000 +# End 0x03ff +set WORKAREASIZE 1024 + +# 8kB Flash +set FLASHSTART 0x8000 +set FLASHEND 0x9fff + +# 256B EEPROM +set EEPROMSTART 0x1000 +set EEPROMEND 0x10ff + +set OPTIONSTART 0x4800 +set OPTIONEND 0x487f + +proc stm8_reset_rop {} { + mwb 0x4800 0xaa + mwb 0x4800 0xaa + reset halt +} + +source [find target/stm8l.cfg] diff --git a/tcl/target/stm8l152.cfg b/tcl/target/stm8l152.cfg index b716ce18e..033b826d8 100644 --- a/tcl/target/stm8l152.cfg +++ b/tcl/target/stm8l152.cfg @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later -#config script for STM8L152 +echo 'DEPRECATED: choose between stm8l15xx4.cfg, stm8l15xx6.cfg and stm8l15xx8.cfg instead of stm8l152.cfg' +echo ' using stm8l152.cfg for backwards compatability' set EEPROMSTART 0x1000 set EEPROMEND 0x13ff diff --git a/tcl/target/stm8l15xx4.cfg b/tcl/target/stm8l15xx4.cfg new file mode 100644 index 000000000..443819357 --- /dev/null +++ b/tcl/target/stm8l15xx4.cfg @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config script for STM8L151x4/STM8L152x4 +# Supported Devices: +# STM8L151C4 +# STM8L151G4 +# STM8L151K4 +# STM8L152C4 +# STM8L152K4 + +# 2kB RAM +# Start 0x0000 +# End 0x07ff +set WORKAREASIZE 2048 + +# 16kB Flash +set FLASHSTART 0x8000 +set FLASHEND 0xbfff + +# 1kB EEPROM +set EEPROMSTART 0x1000 +set EEPROMEND 0x13ff + +set OPTIONSTART 0x4800 +set OPTIONEND 0x48ff + +proc stm8_reset_rop {} { + mwb 0x4800 0xaa + mwb 0x4800 0xaa + reset halt +} + +source [find target/stm8l.cfg] diff --git a/tcl/target/stm8l15xx6.cfg b/tcl/target/stm8l15xx6.cfg new file mode 100644 index 000000000..524329517 --- /dev/null +++ b/tcl/target/stm8l15xx6.cfg @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config script for STM8L151x6/STM8L152x6 +# Supported Devices: +# STM8L151C6 +# STM8L151G6 +# STM8L151K6 +# STM8L151R6 +# STM8L152C6 +# STM8L152K6 +# STM8L152R6 + +# 2kB RAM +# Start 0x0000 +# End 0x07ff +set WORKAREASIZE 2048 + +# 32kB Flash +set FLASHSTART 0x8000 +set FLASHEND 0xffff + +# 1kB EEPROM +set EEPROMSTART 0x1000 +set EEPROMEND 0x13ff + +set OPTIONSTART 0x4800 +set OPTIONEND 0x48ff + +proc stm8_reset_rop {} { + mwb 0x4800 0xaa + mwb 0x4800 0xaa + reset halt +} + +source [find target/stm8l.cfg] diff --git a/tcl/target/stm8l15xx8.cfg b/tcl/target/stm8l15xx8.cfg new file mode 100644 index 000000000..e35482737 --- /dev/null +++ b/tcl/target/stm8l15xx8.cfg @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config script for STM8L151x8/STM8L152x8 +# Supported Devices: +# STM8L151C8 +# STM8L151M8 +# STM8L151R8 +# STM8L152C8 +# STM8L152K8 +# STM8L152M8 +# STM8L152R8 + +# 4kB RAM +# Start 0x0000 +# End 0x0fff +set WORKAREASIZE 4096 + +# 64kB Flash +set FLASHSTART 0x08000 +set FLASHEND 0x17fff + +# 2kB EEPROM +set EEPROMSTART 0x1000 +set EEPROMEND 0x17ff + +set OPTIONSTART 0x4800 +set OPTIONEND 0x48ff + +proc stm8_reset_rop {} { + mwb 0x4800 0xaa + mwb 0x4800 0xaa + reset halt +} + +source [find target/stm8l.cfg] ----------------------------------------------------------------------- Summary of changes: tcl/board/st_nucleo_8l152r8.cfg | 2 +- tcl/target/stm8l151x2.cfg | 32 ++++++++++++++++++++++++++++++++ tcl/target/stm8l151x3.cfg | 32 ++++++++++++++++++++++++++++++++ tcl/target/stm8l152.cfg | 3 ++- tcl/target/stm8l15xx4.cfg | 33 +++++++++++++++++++++++++++++++++ tcl/target/stm8l15xx6.cfg | 35 +++++++++++++++++++++++++++++++++++ tcl/target/stm8l15xx8.cfg | 35 +++++++++++++++++++++++++++++++++++ 7 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 tcl/target/stm8l151x2.cfg create mode 100644 tcl/target/stm8l151x3.cfg create mode 100644 tcl/target/stm8l15xx4.cfg create mode 100644 tcl/target/stm8l15xx6.cfg create mode 100644 tcl/target/stm8l15xx8.cfg hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 20:59:12
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 0e526314a155c73e5eac2dc6bdea0235738ca1a2 (commit) via 00603bf15638347256b1c330bafbeaef0d4d8287 (commit) from 72131e05e9337f1f950f604f5e07683e887ce3ab (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0e526314a155c73e5eac2dc6bdea0235738ca1a2 Author: Antonio Borneo <bor...@gm...> Date: Sat May 27 17:01:58 2023 +0200 flash: jtagspi: fix clang build warning Clang is unable to fully track the content of the array write_buffer[] and incorrectly complains that it could contain some uninitialized value. To help clang to track the execution flow, rewrite the handling of the buffer by using simpler indexing and by moving away cmd_byte from the first buffer's element to the variable cmd_byte. While there: - fix the error codes returned while parsing the command line and - use directly command_print_sameline() instead of passing through intermediate buffers. Change-Id: I1969e896887ea3a4abebee057cc04c03005fa57c Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7718 Tested-by: jenkins diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index 866548a7e..6bb3af9b7 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -301,24 +301,18 @@ COMMAND_HANDLER(jtagspi_handle_set) COMMAND_HANDLER(jtagspi_handle_cmd) { struct flash_bank *bank; - unsigned int index = 1; - const int max = 21; - uint8_t num_write, num_read, write_buffer[max], read_buffer[1 << CHAR_BIT]; - uint8_t data, *ptr; - char temp[4], output[(2 + max + (1 << CHAR_BIT)) * 3 + 8]; - int retval; + const unsigned int max = 20; + uint8_t cmd_byte, num_read, write_buffer[max], read_buffer[1 << CHAR_BIT]; LOG_DEBUG("%s", __func__); - if (CMD_ARGC < 3) { - command_print(CMD, "jtagspi: not enough arguments"); + if (CMD_ARGC < 3) return ERROR_COMMAND_SYNTAX_ERROR; - } - num_write = CMD_ARGC - 2; + uint8_t num_write = CMD_ARGC - 3; if (num_write > max) { - LOG_ERROR("at most %d bytes may be send", max); - return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "at most %d bytes may be send", max); + return ERROR_COMMAND_ARGUMENT_INVALID; } /* calling flash_command_get_bank without probing because we like to be @@ -326,33 +320,31 @@ COMMAND_HANDLER(jtagspi_handle_cmd) "release from power down" is needed before probing when flash is in power down mode. */ - retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, &bank, false); - if (ERROR_OK != retval) + if (retval != ERROR_OK) return retval; - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], num_read); + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], num_read); + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[2], cmd_byte); - snprintf(output, sizeof(output), "spi: "); - for (ptr = &write_buffer[0] ; index < CMD_ARGC; index++) { - COMMAND_PARSE_NUMBER(u8, CMD_ARGV[index], data); - *ptr++ = data; - snprintf(temp, sizeof(temp), "%02" PRIx8 " ", data); - strncat(output, temp, sizeof(output) - strlen(output) - 1); - } - strncat(output, "-> ", sizeof(output) - strlen(output) - 1); + for (unsigned int i = 0; i < num_write; i++) + COMMAND_PARSE_NUMBER(u8, CMD_ARGV[i + 3], write_buffer[i]); /* process command */ - ptr = &read_buffer[0]; - retval = jtagspi_cmd(bank, write_buffer[0], &write_buffer[1], num_write - 1, ptr, -num_read); + retval = jtagspi_cmd(bank, cmd_byte, write_buffer, num_write, read_buffer, -num_read); if (retval != ERROR_OK) return retval; - for ( ; num_read > 0; num_read--) { - snprintf(temp, sizeof(temp), "%02" PRIx8 " ", *ptr++); - strncat(output, temp, sizeof(output) - strlen(output) - 1); - } - command_print(CMD, "%s", output); + command_print_sameline(CMD, "spi: %02" PRIx8, cmd_byte); + + for (unsigned int i = 0; i < num_write; i++) + command_print_sameline(CMD, " %02" PRIx8, write_buffer[i]); + + command_print_sameline(CMD, " ->"); + + for (unsigned int i = 0; i < num_read; i++) + command_print_sameline(CMD, " %02" PRIx8, read_buffer[i]); return ERROR_OK; } commit 00603bf15638347256b1c330bafbeaef0d4d8287 Author: Antonio Borneo <bor...@gm...> Date: Sat May 27 15:56:44 2023 +0200 flash: psoc4: fix clang error Clang 15.0.7 complains about snprintf output truncation due to output between 13 and 22 bytes into a destination of size 20. Increase the size of the buffer. Change-Id: I0369255ca1bc02a0cf494f765e91a608c960a0d6 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7717 Tested-by: jenkins diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c index fb462c1e5..1064fa93d 100644 --- a/src/flash/nor/psoc4.c +++ b/src/flash/nor/psoc4.c @@ -779,7 +779,7 @@ static int psoc4_probe(struct flash_bank *bank) flash_size_in_kb = psoc4_info->user_bank_size / 1024; } - char macros_txt[20] = ""; + char macros_txt[22] = ""; if (num_macros > 1) snprintf(macros_txt, sizeof(macros_txt), " in %" PRIu32 " macros", num_macros); ----------------------------------------------------------------------- Summary of changes: src/flash/nor/jtagspi.c | 52 +++++++++++++++++++++---------------------------- src/flash/nor/psoc4.c | 2 +- 2 files changed, 23 insertions(+), 31 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 20:58:28
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 72131e05e9337f1f950f604f5e07683e887ce3ab (commit) from 4a57f3ebb21db6b89b0ceb9df34d32157731ead2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 72131e05e9337f1f950f604f5e07683e887ce3ab Author: Bohdan Tymkiv <boh...@gm...> Date: Tue May 23 14:40:11 2023 +0300 cortex_m: fix reading of DCB_DSCSR register Value in the 'dscsr' variable is garbage until the DAP queue is run. Postpone evaluation of the 'secure_state' variable. Reading the core registers in between will execute the DAP queue. Change-Id: I44959e882dbafb1b9779e813c3d13f3b3dbcd47f Signed-off-by: Bohdan Tymkiv <boh...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7693 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 8e55014f9..ebc3bac99 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -801,15 +801,11 @@ static int cortex_m_debug_entry(struct target *target) return retval; /* examine PE security state */ - bool secure_state = false; + uint32_t dscsr = 0; if (armv7m->arm.arch == ARM_ARCH_V8M) { - uint32_t dscsr; - retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DSCSR, &dscsr); if (retval != ERROR_OK) return retval; - - secure_state = (dscsr & DSCSR_CDS) == DSCSR_CDS; } /* Load all registers to arm.core_cache */ @@ -857,6 +853,7 @@ static int cortex_m_debug_entry(struct target *target) if (armv7m->exception_number) cortex_m_examine_exception_reason(target); + bool secure_state = (dscsr & DSCSR_CDS) == DSCSR_CDS; LOG_TARGET_DEBUG(target, "entered debug state in core mode: %s at PC 0x%" PRIx32 ", cpu in %s state, target->state: %s", arm_mode_name(arm->core_mode), ----------------------------------------------------------------------- Summary of changes: src/target/cortex_m.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-06-02 20:58:10
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 4a57f3ebb21db6b89b0ceb9df34d32157731ead2 (commit) from 78688fea984b69d1986b6b730ff2935668cc9208 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4a57f3ebb21db6b89b0ceb9df34d32157731ead2 Author: Antonio Borneo <bor...@gm...> Date: Thu May 25 10:49:20 2023 +0200 target: armv8: fix support of pointer authentication The registers pauth_dmask and pauth_cmask are not accessible in AARCH32 mode. Tagging them as 'hidden' is not enough and triggers error: Failed to read pauth_dmask register while halting the core. Tag the pauth registers as not existing, unless required by user. Note: for non existing registers there should be no need to allocate their register cache. Let's keep this for a further improvement. Change-Id: Iaa0d006a3d8ee611ee93333ed49a8615a6c94276 Signed-off-by: Antonio Borneo <bor...@gm...> Fixes: d0436b0cdabb ("armv8: Add support of pointer authentication") Reviewed-on: https://review.openocd.org/c/openocd/+/7712 Tested-by: jenkins Reviewed-by: Koudai Iwahori <ko...@go...> diff --git a/src/target/armv8.c b/src/target/armv8.c index ffed263a9..e647c3b4c 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1682,7 +1682,7 @@ struct reg_cache *armv8_build_reg_cache(struct target *target) LOG_ERROR("unable to allocate reg type list"); if (i == ARMV8_PAUTH_CMASK || i == ARMV8_PAUTH_DMASK) - reg_list[i].hidden = !armv8->enable_pauth; + reg_list[i].exist = armv8->enable_pauth; } arm->cpsr = reg_list + ARMV8_XPSR; ----------------------------------------------------------------------- Summary of changes: src/target/armv8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:50:03
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 78688fea984b69d1986b6b730ff2935668cc9208 (commit) from 2dd34cbe0b6d8d485a63b039058085b7ceec70e6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 78688fea984b69d1986b6b730ff2935668cc9208 Author: Daniel Anselmi <dan...@gm...> Date: Tue Mar 21 23:23:12 2023 +0100 flash/jtagspi: sending command and setting parameters without probing. Change-Id: I6b9d90265ca5112b9ab2aae97bb4c6cf3ebc4112 Signed-off-by: Daniel Anselmi <dan...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7432 Reviewed-by: Antonio Borneo <bor...@gm...> Reviewed-by: Tomas Vanek <va...@fb...> Tested-by: jenkins diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index 8c26ba012..80911f799 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -252,6 +252,19 @@ int get_flash_bank_by_num(unsigned int num, struct flash_bank **bank); */ COMMAND_HELPER(flash_command_get_bank, unsigned name_index, struct flash_bank **bank); +/** + * Retrieves @a bank from a command argument, reporting errors parsing + * the bank identifier or retrieving the specified bank. The bank + * may be identified by its bank number or by @c name.instance, where + * @a instance is driver-specific. + * @param name_index The index to the string in args containing the + * bank identifier. + * @param bank On output, contains a pointer to the bank or NULL. + * @param do_probe Does auto-probing when set, otherwise without probing. + * @returns ERROR_OK on success, or an error indicating the problem. + */ +COMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index, + struct flash_bank **bank, bool do_probe); /** * Returns the flash bank like get_flash_bank_by_num(), without probing. * @param num The flash bank number. diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index 0047d22bb..866548a7e 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -41,7 +41,11 @@ FLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command) bank->sectors = NULL; bank->driver_priv = info; - info->tap = NULL; + if (!bank->target->tap) { + LOG_ERROR("Target has no JTAG tap"); + return ERROR_FAIL; + } + info->tap = bank->target->tap; info->probed = false; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], info->ir); @@ -161,7 +165,12 @@ COMMAND_HANDLER(jtagspi_handle_set) return ERROR_COMMAND_SYNTAX_ERROR; } - retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + /* calling flash_command_get_bank without probing because handle_set is used + to set device parameters if not autodetected. So probing would fail + anyhow. + */ + retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, + &bank, false); if (ERROR_OK != retval) return retval; info = bank->driver_priv; @@ -312,7 +321,13 @@ COMMAND_HANDLER(jtagspi_handle_cmd) return ERROR_COMMAND_SYNTAX_ERROR; } - retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + /* calling flash_command_get_bank without probing because we like to be + able to send commands before auto-probing occurred. For example sending + "release from power down" is needed before probing when flash is in + power down mode. + */ + retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, + &bank, false); if (ERROR_OK != retval) return retval; @@ -381,12 +396,6 @@ static int jtagspi_probe(struct flash_bank *bank) } info->probed = false; - if (!bank->target->tap) { - LOG_ERROR("Target has no JTAG tap"); - return ERROR_FAIL; - } - info->tap = bank->target->tap; - jtagspi_cmd(bank, SPIFLASH_READ_ID, NULL, 0, in_buf, -3); /* the table in spi.c has the manufacturer byte (first) as the lsb */ id = le_to_h_u24(in_buf); diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 22c1710ad..720fb60a1 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -19,7 +19,7 @@ * Implements Tcl commands used to access NOR flash facilities. */ -static COMMAND_HELPER(flash_command_get_bank_maybe_probe, unsigned name_index, +COMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index, struct flash_bank **bank, bool do_probe) { const char *name = CMD_ARGV[name_index]; @@ -51,7 +51,7 @@ static COMMAND_HELPER(flash_command_get_bank_maybe_probe, unsigned name_index, COMMAND_HELPER(flash_command_get_bank, unsigned name_index, struct flash_bank **bank) { - return CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe, + return CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, name_index, bank, true); } @@ -157,7 +157,7 @@ COMMAND_HANDLER(handle_flash_probe_command) if (CMD_ARGC != 1) return ERROR_COMMAND_SYNTAX_ERROR; - retval = CALL_COMMAND_HANDLER(flash_command_get_bank_maybe_probe, 0, &p, false); + retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, &p, false); if (retval != ERROR_OK) return retval; diff --git a/tcl/cpld/jtagspi.cfg b/tcl/cpld/jtagspi.cfg index 7071e5e34..4c84792fe 100644 --- a/tcl/cpld/jtagspi.cfg +++ b/tcl/cpld/jtagspi.cfg @@ -23,11 +23,21 @@ if { [info exists FLASHNAME] } { target create $_TARGETNAME testee -chain-position $_CHIPNAME.tap flash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR -proc jtagspi_init {chain_id proxy_bit} { +# initialize jtagspi flash +# chain_id: identifier of pld (you can get a list with 'pld devices') +# proxy_bit: file with bitstream connecting JTAG and SPI interface in the PLD. +# release_from_pwr_down_cmd: optional, command sent to spi flash before probing. +# ex: 0xAB to release from power-dowm. +# Just omit it to not send a command. + +proc jtagspi_init {chain_id proxy_bit {release_from_pwr_down_cmd -1}} { # load proxy bitstream $proxy_bit and probe spi flash global _FLASHNAME pld load $chain_id $proxy_bit reset halt + if {$release_from_pwr_down_cmd != -1} { + jtagspi cmd $_FLASHNAME 0 $release_from_pwr_down_cmd + } flash probe $_FLASHNAME } ----------------------------------------------------------------------- Summary of changes: src/flash/nor/core.h | 13 +++++++++++++ src/flash/nor/jtagspi.c | 27 ++++++++++++++++++--------- src/flash/nor/tcl.c | 6 +++--- tcl/cpld/jtagspi.cfg | 12 +++++++++++- 4 files changed, 45 insertions(+), 13 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:44:28
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2dd34cbe0b6d8d485a63b039058085b7ceec70e6 (commit) from df12552b5b4b510f96a2fe5d5b1cc49e2d91413f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2dd34cbe0b6d8d485a63b039058085b7ceec70e6 Author: Ian Thompson <ia...@ca...> Date: Thu Mar 23 17:30:53 2023 -0700 target/xtensa: add file-IO support - Manual integration of File-IO support from xt0.2 release - Verified with applications linked using gdbio LSP - No new clang static analysis warnings Signed-off-by: Ian Thompson <ia...@ca...> Change-Id: Iedc5f885b2548097ef4f11ae1a675b5944f5fdf0 Reviewed-on: https://review.openocd.org/c/openocd/+/7550 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/xtensa/Makefile.am b/src/target/xtensa/Makefile.am index 94c7c4a85..22504e78b 100644 --- a/src/target/xtensa/Makefile.am +++ b/src/target/xtensa/Makefile.am @@ -8,4 +8,6 @@ noinst_LTLIBRARIES += %D%/libxtensa.la %D%/xtensa_chip.h \ %D%/xtensa_debug_module.c \ %D%/xtensa_debug_module.h \ + %D%/xtensa_fileio.c \ + %D%/xtensa_fileio.h \ %D%/xtensa_regs.h diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index 5880637f4..431c36a24 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -1544,6 +1544,7 @@ int xtensa_prepare_resume(struct target *target, LOG_TARGET_WARNING(target, "target not halted"); return ERROR_TARGET_NOT_HALTED; } + xtensa->halt_request = false; if (address && !current) { xtensa_reg_set(target, XT_REG_IDX_PC, address); diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c index c62992f62..668aa3acc 100644 --- a/src/target/xtensa/xtensa_chip.c +++ b/src/target/xtensa/xtensa_chip.c @@ -15,6 +15,7 @@ #include <target/arm_adi_v5.h> #include <rtos/rtos.h> #include "xtensa_chip.h" +#include "xtensa_fileio.h" int xtensa_chip_init_arch_info(struct target *target, void *arch_info, struct xtensa_debug_module_config *dm_cfg) @@ -30,7 +31,10 @@ int xtensa_chip_init_arch_info(struct target *target, void *arch_info, int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target) { - return xtensa_target_init(cmd_ctx, target); + int ret = xtensa_target_init(cmd_ctx, target); + if (ret != ERROR_OK) + return ret; + return xtensa_fileio_init(target); } int xtensa_chip_arch_state(struct target *target) @@ -45,10 +49,12 @@ static int xtensa_chip_poll(struct target *target) if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) { /*Call any event callbacks that are applicable */ - if (old_state == TARGET_DEBUG_RUNNING) + if (old_state == TARGET_DEBUG_RUNNING) { target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); - else + } else { + xtensa_fileio_detect_proc(target); target_call_event_callbacks(target, TARGET_EVENT_HALTED); + } } return ret; @@ -193,4 +199,7 @@ struct target_type xtensa_chip_target = { .gdb_query_custom = xtensa_gdb_query_custom, .commands = xtensa_command_handlers, + + .get_gdb_fileio_info = xtensa_get_gdb_fileio_info, + .gdb_fileio_end = xtensa_gdb_fileio_end, }; diff --git a/src/target/xtensa/xtensa_fileio.c b/src/target/xtensa/xtensa_fileio.c new file mode 100644 index 000000000..7628fbe31 --- /dev/null +++ b/src/target/xtensa/xtensa_fileio.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Xtensa Target File-I/O Support for OpenOCD * + * Copyright (C) 2020-2023 Cadence Design Systems, Inc. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xtensa_chip.h" +#include "xtensa_fileio.h" +#include "xtensa.h" + +#define XTENSA_SYSCALL(x) XT_INS_BREAK(x, 1, 14) +#define XTENSA_SYSCALL_SZ 3 +#define XTENSA_SYSCALL_LEN_MAX 255 + + +int xtensa_fileio_init(struct target *target) +{ + char *idmem = malloc(XTENSA_SYSCALL_LEN_MAX + 1); + target->fileio_info = malloc(sizeof(struct gdb_fileio_info)); + if (!idmem || !target->fileio_info) { + LOG_TARGET_ERROR(target, "Out of memory!"); + free(idmem); + free(target->fileio_info); + return ERROR_FAIL; + } + target->fileio_info->identifier = idmem; + return ERROR_OK; +} + +/** + * Checks for and processes an Xtensa File-IO request. + * + * Return ERROR_OK if request was found and handled; or + * return ERROR_FAIL if no request was detected. + */ +int xtensa_fileio_detect_proc(struct target *target) +{ + struct xtensa *xtensa = target_to_xtensa(target); + int retval; + + xtensa_reg_val_t dbg_cause = xtensa_cause_get(target); + if ((dbg_cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) == 0 || xtensa->halt_request) + return ERROR_FAIL; + + uint8_t brk_insn_buf[sizeof(uint32_t)] = {0}; + xtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC); + retval = target_read_memory(target, + pc, + XTENSA_SYSCALL_SZ, + 1, + (uint8_t *)brk_insn_buf); + if (retval != ERROR_OK) { + LOG_ERROR("Failed to read break instruction!"); + return ERROR_FAIL; + } + if (buf_get_u32(brk_insn_buf, 0, 32) != XTENSA_SYSCALL(xtensa)) + return ERROR_FAIL; + + LOG_TARGET_DEBUG(target, "File-I/O: syscall breakpoint found at 0x%x", pc); + xtensa->proc_syscall = true; + return ERROR_OK; +} + +int xtensa_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) +{ + /* fill syscall parameters to file-I/O info */ + if (!fileio_info) { + LOG_ERROR("File-I/O data structure uninitialized"); + return ERROR_FAIL; + } + + struct xtensa *xtensa = target_to_xtensa(target); + if (!xtensa->proc_syscall) + return ERROR_FAIL; + + xtensa_reg_val_t syscall = xtensa_reg_get(target, XTENSA_SYSCALL_OP_REG); + xtensa_reg_val_t arg0 = xtensa_reg_get(target, XT_REG_IDX_A6); + xtensa_reg_val_t arg1 = xtensa_reg_get(target, XT_REG_IDX_A3); + xtensa_reg_val_t arg2 = xtensa_reg_get(target, XT_REG_IDX_A4); + xtensa_reg_val_t arg3 = xtensa_reg_get(target, XT_REG_IDX_A5); + int retval = ERROR_OK; + + LOG_TARGET_DEBUG(target, "File-I/O: syscall 0x%x 0x%x 0x%x 0x%x 0x%x", + syscall, arg0, arg1, arg2, arg3); + + switch (syscall) { + case XTENSA_SYSCALL_OPEN: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "open"); + fileio_info->param_1 = arg0; // pathp + fileio_info->param_2 = arg3; // len + fileio_info->param_3 = arg1; // flags + fileio_info->param_4 = arg2; // mode + break; + case XTENSA_SYSCALL_CLOSE: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "close"); + fileio_info->param_1 = arg0; // fd + break; + case XTENSA_SYSCALL_READ: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "read"); + fileio_info->param_1 = arg0; // fd + fileio_info->param_2 = arg1; // bufp + fileio_info->param_3 = arg2; // count + break; + case XTENSA_SYSCALL_WRITE: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "write"); + fileio_info->param_1 = arg0; // fd + fileio_info->param_2 = arg1; // bufp + fileio_info->param_3 = arg2; // count + break; + case XTENSA_SYSCALL_LSEEK: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "lseek"); + fileio_info->param_1 = arg0; // fd + fileio_info->param_2 = arg1; // offset + fileio_info->param_3 = arg2; // flags + break; + case XTENSA_SYSCALL_RENAME: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "rename"); + fileio_info->param_1 = arg0; // old pathp + fileio_info->param_2 = arg3; // old len + fileio_info->param_3 = arg1; // new pathp + fileio_info->param_4 = arg2; // new len + break; + case XTENSA_SYSCALL_UNLINK: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "unlink"); + fileio_info->param_1 = arg0; // pathnamep + fileio_info->param_2 = arg1; // len + break; + case XTENSA_SYSCALL_STAT: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "stat"); + fileio_info->param_1 = arg0; // pathnamep + fileio_info->param_2 = arg2; // len + fileio_info->param_3 = arg1; // bufp + break; + case XTENSA_SYSCALL_FSTAT: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "fstat"); + fileio_info->param_1 = arg0; // fd + fileio_info->param_2 = arg1; // bufp + break; + case XTENSA_SYSCALL_GETTIMEOFDAY: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "gettimeofday"); + fileio_info->param_1 = arg0; // tvp + fileio_info->param_2 = arg1; // tzp + break; + case XTENSA_SYSCALL_ISATTY: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "isatty"); + fileio_info->param_1 = arg0; // fd + break; + case XTENSA_SYSCALL_SYSTEM: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "system"); + fileio_info->param_1 = arg0; // cmdp + fileio_info->param_2 = arg1; // len + break; + default: + snprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, "unknown"); + LOG_TARGET_DEBUG(target, "File-I/O: syscall unknown (%d), pc=0x%08X", + syscall, xtensa_reg_get(target, XT_REG_IDX_PC)); + LOG_INFO("File-I/O: syscall unknown (%d), pc=0x%08X", + syscall, xtensa_reg_get(target, XT_REG_IDX_PC)); + retval = ERROR_FAIL; + break; + } + + return retval; +} + +int xtensa_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c) +{ + struct xtensa *xtensa = target_to_xtensa(target); + if (!xtensa->proc_syscall) + return ERROR_FAIL; + + LOG_TARGET_DEBUG(target, "File-I/O: syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s", + retcode, fileio_errno, ctrl_c ? "true" : "false"); + + /* If interrupt was requested before FIO completion (ERRNO==4), halt and repeat + * syscall. Otherwise, set File-I/O Ax and underlying ARx registers, increment PC. + * NOTE: sporadic cases of ((ERRNO==4) && !ctrl_c) were observed; most have ctrl_c. + */ + if (fileio_errno != 4) { + xtensa_reg_set_deep_relgen(target, XTENSA_SYSCALL_RETVAL_REG, retcode); + xtensa_reg_set_deep_relgen(target, XTENSA_SYSCALL_ERRNO_REG, fileio_errno); + + xtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC); + xtensa_reg_set(target, XT_REG_IDX_PC, pc + XTENSA_SYSCALL_SZ); + } + + xtensa->proc_syscall = false; + xtensa->halt_request = true; + return ctrl_c ? ERROR_FAIL : ERROR_OK; +} diff --git a/src/target/xtensa/xtensa_fileio.h b/src/target/xtensa/xtensa_fileio.h new file mode 100644 index 000000000..5e1af5f86 --- /dev/null +++ b/src/target/xtensa/xtensa_fileio.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Xtensa Target File-I/O Support for OpenOCD * + * Copyright (C) 2020-2023 Cadence Design Systems, Inc. * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_XTENSA_FILEIO_H +#define OPENOCD_TARGET_XTENSA_FILEIO_H + +#include <target/target.h> +#include <helper/command.h> +#include "xtensa.h" + +#define XTENSA_SYSCALL_OP_REG XT_REG_IDX_A2 +#define XTENSA_SYSCALL_RETVAL_REG XT_REG_IDX_A2 +#define XTENSA_SYSCALL_ERRNO_REG XT_REG_IDX_A3 + +#define XTENSA_SYSCALL_OPEN (-2) +#define XTENSA_SYSCALL_CLOSE (-3) +#define XTENSA_SYSCALL_READ (-4) +#define XTENSA_SYSCALL_WRITE (-5) +#define XTENSA_SYSCALL_LSEEK (-6) +#define XTENSA_SYSCALL_RENAME (-7) +#define XTENSA_SYSCALL_UNLINK (-8) +#define XTENSA_SYSCALL_STAT (-9) +#define XTENSA_SYSCALL_FSTAT (-10) +#define XTENSA_SYSCALL_GETTIMEOFDAY (-11) +#define XTENSA_SYSCALL_ISATTY (-12) +#define XTENSA_SYSCALL_SYSTEM (-13) + +int xtensa_fileio_init(struct target *target); +int xtensa_fileio_detect_proc(struct target *target); +int xtensa_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info); +int xtensa_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c); + +#endif /* OPENOCD_TARGET_XTENSA_FILEIO_H */ ----------------------------------------------------------------------- Summary of changes: src/target/xtensa/Makefile.am | 2 + src/target/xtensa/xtensa.c | 1 + src/target/xtensa/xtensa_chip.c | 15 ++- src/target/xtensa/xtensa_fileio.c | 195 ++++++++++++++++++++++++++++++++++++++ src/target/xtensa/xtensa_fileio.h | 37 ++++++++ 5 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 src/target/xtensa/xtensa_fileio.c create mode 100644 src/target/xtensa/xtensa_fileio.h hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:44:01
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via df12552b5b4b510f96a2fe5d5b1cc49e2d91413f (commit) from 8297836170ae1970c452dd4808cc0f6cd06fed3c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit df12552b5b4b510f96a2fe5d5b1cc49e2d91413f Author: Jan Matyas <jan...@co...> Date: Mon May 15 10:27:59 2023 +0200 jtag/adapter: Removed unused include of strings.h Removed an unused include from src/jtag/adapter.c. Signed-off-by: Jan Matyas <jan...@co...> Change-Id: Ia5ea0acdfa1c011d7c88decd0f63e8032aafd699 Reviewed-on: https://review.openocd.org/c/openocd/+/7687 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 76a6620be..e70f4a1e8 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -18,10 +18,6 @@ #include "interfaces.h" #include <transport/transport.h> -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - /** * @file * Holds support for configuring debug adapters from TCl scripts. ----------------------------------------------------------------------- Summary of changes: src/jtag/adapter.c | 4 ---- 1 file changed, 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:43:25
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 8297836170ae1970c452dd4808cc0f6cd06fed3c (commit) from 5dd047fbbe6c550afe8491ade0eae0d61397e496 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8297836170ae1970c452dd4808cc0f6cd06fed3c Author: Antonio Borneo <bor...@gm...> Date: Mon Jan 2 17:12:04 2023 +0100 jtag: rewrite jim_jtag_tap_enabler() as COMMAND_HANDLER The function is used for commands: - jtag tapisenabled - jtag tapenable - jtag tapdisable While there, add the missing .help and .usage fields and fix the incorrect check in jtag_tap_enable() and jtag_tap_disable(). Change-Id: I0e1c9f0b8d9fbad19d09610a97498bec8003c27e Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7554 Tested-by: jenkins diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index 72d1edc6d..08ee18f36 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -97,12 +97,18 @@ static const struct command_registration hl_transport_jtag_subcommand_handlers[] { .name = "tapisenabled", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, + .help = "Returns a Tcl boolean (0/1) indicating whether " + "the TAP is enabled (1) or not (0).", + .usage = "tap_name", }, { .name = "tapenable", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, + .help = "Try to enable the specified TAP using the " + "'tap-enable' TAP event.", + .usage = "tap_name", }, { .name = "tapdisable", diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 700772ea4..85a66aaf6 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -604,7 +604,7 @@ COMMAND_HANDLER(handle_jtag_arp_init_reset) static bool jtag_tap_enable(struct jtag_tap *t) { if (t->enabled) - return false; + return true; jtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE); if (!t->enabled) return false; @@ -619,7 +619,7 @@ static bool jtag_tap_enable(struct jtag_tap *t) static bool jtag_tap_disable(struct jtag_tap *t) { if (!t->enabled) - return false; + return true; jtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE); if (t->enabled) return false; @@ -632,42 +632,36 @@ static bool jtag_tap_disable(struct jtag_tap *t) return true; } -int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +__COMMAND_HANDLER(handle_jtag_tap_enabler) { - struct command *c = jim_to_command(interp); - const char *cmd_name = c->name; - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 1) { - Jim_SetResultFormatted(goi.interp, "usage: %s <name>", cmd_name); - return JIM_ERR; - } - - struct jtag_tap *t; + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; - t = jtag_tap_by_jim_obj(goi.interp, goi.argv[0]); - if (!t) - return JIM_ERR; + struct jtag_tap *t = jtag_tap_by_string(CMD_ARGV[0]); + if (!t) { + command_print(CMD, "Tap '%s' could not be found", CMD_ARGV[0]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } - if (strcasecmp(cmd_name, "tapisenabled") == 0) { + if (strcmp(CMD_NAME, "tapisenabled") == 0) { /* do nothing, just return the value */ - } else if (strcasecmp(cmd_name, "tapenable") == 0) { + } else if (strcmp(CMD_NAME, "tapenable") == 0) { if (!jtag_tap_enable(t)) { - LOG_WARNING("failed to enable tap %s", t->dotted_name); - return JIM_ERR; + command_print(CMD, "failed to enable tap %s", t->dotted_name); + return ERROR_FAIL; } - } else if (strcasecmp(cmd_name, "tapdisable") == 0) { + } else if (strcmp(CMD_NAME, "tapdisable") == 0) { if (!jtag_tap_disable(t)) { - LOG_WARNING("failed to disable tap %s", t->dotted_name); - return JIM_ERR; + command_print(CMD, "failed to disable tap %s", t->dotted_name); + return ERROR_FAIL; } } else { - LOG_ERROR("command '%s' unknown", cmd_name); - return JIM_ERR; + command_print(CMD, "command '%s' unknown", CMD_NAME); + return ERROR_FAIL; } - bool e = t->enabled; - Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, e)); - return JIM_OK; + + command_print(CMD, "%d", t->enabled ? 1 : 0); + return ERROR_OK; } int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -763,7 +757,7 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "tapisenabled", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, .help = "Returns a Tcl boolean (0/1) indicating whether " "the TAP is enabled (1) or not (0).", .usage = "tap_name", @@ -771,7 +765,7 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "tapenable", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, .help = "Try to enable the specified TAP using the " "'tap-enable' TAP event.", .usage = "tap_name", @@ -779,7 +773,7 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "tapdisable", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, .help = "Try to disable the specified TAP using the " "'tap-disable' TAP event.", .usage = "tap_name", diff --git a/src/jtag/tcl.h b/src/jtag/tcl.h index d67c085e5..66867ab0f 100644 --- a/src/jtag/tcl.h +++ b/src/jtag/tcl.h @@ -18,9 +18,10 @@ #ifndef OPENOCD_JTAG_TCL_H #define OPENOCD_JTAG_TCL_H +#include <helper/command.h> + int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv); -int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, - Jim_Obj * const *argv); +__COMMAND_HANDLER(handle_jtag_tap_enabler); #endif /* OPENOCD_JTAG_TCL_H */ diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c index 6b492e6ab..575092cbf 100644 --- a/src/target/adi_v5_dapdirect.c +++ b/src/target/adi_v5_dapdirect.c @@ -89,12 +89,18 @@ static const struct command_registration dapdirect_jtag_subcommand_handlers[] = { .name = "tapisenabled", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, + .help = "Returns a Tcl boolean (0/1) indicating whether " + "the TAP is enabled (1) or not (0).", + .usage = "tap_name", }, { .name = "tapenable", .mode = COMMAND_EXEC, - .jim_handler = jim_jtag_tap_enabler, + .handler = handle_jtag_tap_enabler, + .help = "Try to enable the specified TAP using the " + "'tap-enable' TAP event.", + .usage = "tap_name", }, { .name = "tapdisable", ----------------------------------------------------------------------- Summary of changes: src/jtag/hla/hla_transport.c | 10 ++++++-- src/jtag/tcl.c | 56 +++++++++++++++++++------------------------ src/jtag/tcl.h | 5 ++-- src/target/adi_v5_dapdirect.c | 10 ++++++-- 4 files changed, 44 insertions(+), 37 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:42:28
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5dd047fbbe6c550afe8491ade0eae0d61397e496 (commit) from da76f8f0b4b98c2b7f04b5fe94f721aed7b2cfab (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5dd047fbbe6c550afe8491ade0eae0d61397e496 Author: Antonio Borneo <bor...@gm...> Date: Mon Jan 2 01:11:44 2023 +0100 jtag: rewrite commands 'jtag newtap' and 'swd newdap' as COMMAND_HANDLER While there: - fix memory leak in case of error on values tap->chip, tap->tapname, tap->expected_ids; - check for out of memory error; - fix minor coding style issue; - add the missing .usage field; - remove functions not in use anymore. Change-Id: I1c8c3ffeb324e9eacb919c7e0d94fd72122c9a81 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7431 Tested-by: jenkins diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index 004e9f0c5..72d1edc6d 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -37,8 +37,15 @@ static const struct command_registration hl_swd_transport_subcommand_handlers[] { .name = "newdap", .mode = COMMAND_CONFIG, - .jim_handler = jim_jtag_newtap, + .handler = handle_jtag_newtap, .help = "declare a new SWD DAP", + .usage = "basename dap_type ['-irlen' count] " + "['-enable'|'-disable'] " + "['-expected_id' number] " + "['-ignore-version'] " + "['-ignore-bypass'] " + "['-ircapture' number] " + "['-mask' number]", }, COMMAND_REGISTRATION_DONE }; @@ -58,11 +65,16 @@ static const struct command_registration hl_transport_jtag_subcommand_handlers[] { .name = "newtap", .mode = COMMAND_CONFIG, - .jim_handler = jim_jtag_newtap, + .handler = handle_jtag_newtap, .help = "Create a new TAP instance named basename.tap_type, " "and appends it to the scan chain.", .usage = "basename tap_type '-irlen' count " - "['-expected_id' number]", + "['-enable'|'-disable'] " + "['-expected_id' number] " + "['-ignore-version'] " + "['-ignore-bypass'] " + "['-ircapture' number] " + "['-mask' number]", }, { .name = "init", diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 4f94e9913..04d1b4a2b 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -12,6 +12,7 @@ #define OPENOCD_JTAG_JTAG_H #include <helper/binarybuffer.h> +#include <helper/command.h> #include <helper/log.h> #include <helper/replacements.h> @@ -602,6 +603,6 @@ void jtag_poll_unmask(bool saved); #include <jtag/minidriver.h> -int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +__COMMAND_HANDLER(handle_jtag_newtap); #endif /* OPENOCD_JTAG_JTAG_H */ diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 934b60352..700772ea4 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -31,6 +31,8 @@ #include <strings.h> #endif +#include <helper/command.h> +#include <helper/nvp.h> #include <helper/time_support.h> #include "transport/transport.h" @@ -376,39 +378,6 @@ static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap * return JIM_OK; } -static int is_bad_irval(int ir_length, jim_wide w) -{ - jim_wide v = 1; - - v <<= ir_length; - v -= 1; - v = ~v; - return (w & v) != 0; -} - -static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, - struct jtag_tap *tap) -{ - jim_wide w; - int e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name); - return e; - } - - uint32_t *p = realloc(tap->expected_ids, - (tap->expected_ids_cnt + 1) * sizeof(uint32_t)); - if (!p) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } - - tap->expected_ids = p; - tap->expected_ids[tap->expected_ids_cnt++] = w; - - return JIM_OK; -} - #define NTAP_OPT_IRLEN 0 #define NTAP_OPT_IRMASK 1 #define NTAP_OPT_IRCAPTURE 2 @@ -418,166 +387,155 @@ static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi #define NTAP_OPT_VERSION 6 #define NTAP_OPT_BYPASS 7 -static int jim_newtap_ir_param(struct jim_nvp *n, struct jim_getopt_info *goi, - struct jtag_tap *tap) -{ - jim_wide w; - int e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) { - Jim_SetResultFormatted(goi->interp, - "option: %s bad parameter", n->name); - return e; - } - switch (n->value) { - case NTAP_OPT_IRLEN: - if (w > (jim_wide) (8 * sizeof(tap->ir_capture_value))) { - LOG_WARNING("%s: huge IR length %d", - tap->dotted_name, (int) w); - } - tap->ir_length = w; - break; - case NTAP_OPT_IRMASK: - if (is_bad_irval(tap->ir_length, w)) { - LOG_ERROR("%s: IR mask %x too big", - tap->dotted_name, - (int) w); - return JIM_ERR; - } - if ((w & 3) != 3) - LOG_WARNING("%s: nonstandard IR mask", tap->dotted_name); - tap->ir_capture_mask = w; - break; - case NTAP_OPT_IRCAPTURE: - if (is_bad_irval(tap->ir_length, w)) { - LOG_ERROR("%s: IR capture %x too big", - tap->dotted_name, (int) w); - return JIM_ERR; - } - if ((w & 3) != 1) - LOG_WARNING("%s: nonstandard IR value", - tap->dotted_name); - tap->ir_capture_value = w; - break; - default: - return JIM_ERR; - } - return JIM_OK; -} +static const struct nvp jtag_newtap_opts[] = { + { .name = "-irlen", .value = NTAP_OPT_IRLEN }, + { .name = "-irmask", .value = NTAP_OPT_IRMASK }, + { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, + { .name = "-enable", .value = NTAP_OPT_ENABLED }, + { .name = "-disable", .value = NTAP_OPT_DISABLED }, + { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, + { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, + { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS }, + { .name = NULL, .value = -1 }, +}; -static int jim_newtap_cmd(struct jim_getopt_info *goi) +static COMMAND_HELPER(handle_jtag_newtap_args, struct jtag_tap *tap) { - struct jtag_tap *tap; - int x; - int e; - struct jim_nvp *n; - char *cp; - const struct jim_nvp opts[] = { - { .name = "-irlen", .value = NTAP_OPT_IRLEN }, - { .name = "-irmask", .value = NTAP_OPT_IRMASK }, - { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, - { .name = "-enable", .value = NTAP_OPT_ENABLED }, - { .name = "-disable", .value = NTAP_OPT_DISABLED }, - { .name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID }, - { .name = "-ignore-version", .value = NTAP_OPT_VERSION }, - { .name = "-ignore-bypass", .value = NTAP_OPT_BYPASS }, - { .name = NULL, .value = -1 }, - }; - - tap = calloc(1, sizeof(struct jtag_tap)); - if (!tap) { - Jim_SetResultFormatted(goi->interp, "no memory"); - return JIM_ERR; - } + /* we expect CHIP + TAP + OPTIONS */ + if (CMD_ARGC < 2) + return ERROR_COMMAND_SYNTAX_ERROR; - /* - * we expect CHIP + TAP + OPTIONS - * */ - if (goi->argc < 3) { - Jim_SetResultFormatted(goi->interp, "Missing CHIP TAP OPTIONS ...."); - free(tap); - return JIM_ERR; + tap->chip = strdup(CMD_ARGV[0]); + tap->tapname = strdup(CMD_ARGV[1]); + tap->dotted_name = alloc_printf("%s.%s", CMD_ARGV[0], CMD_ARGV[1]); + if (!tap->chip || !tap->tapname || !tap->dotted_name) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; } - - const char *tmp; - jim_getopt_string(goi, &tmp, NULL); - tap->chip = strdup(tmp); - - jim_getopt_string(goi, &tmp, NULL); - tap->tapname = strdup(tmp); - - /* name + dot + name + null */ - x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1; - cp = malloc(x); - sprintf(cp, "%s.%s", tap->chip, tap->tapname); - tap->dotted_name = cp; + CMD_ARGC -= 2; + CMD_ARGV += 2; LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params", - tap->chip, tap->tapname, tap->dotted_name, goi->argc); + tap->chip, tap->tapname, tap->dotted_name, CMD_ARGC); - /* IEEE specifies that the two LSBs of an IR scan are 01, so make + /* + * IEEE specifies that the two LSBs of an IR scan are 01, so make * that the default. The "-ircapture" and "-irmask" options are only * needed to cope with nonstandard TAPs, or to specify more bits. */ tap->ir_capture_mask = 0x03; tap->ir_capture_value = 0x01; - while (goi->argc) { - e = jim_getopt_nvp(goi, opts, &n); - if (e != JIM_OK) { - jim_getopt_nvp_unknown(goi, opts, 0); - free(cp); - free(tap); - return e; - } - LOG_DEBUG("Processing option: %s", n->name); + while (CMD_ARGC) { + const struct nvp *n = nvp_name2value(jtag_newtap_opts, CMD_ARGV[0]); + CMD_ARGC--; + CMD_ARGV++; switch (n->value) { - case NTAP_OPT_ENABLED: - tap->disabled_after_reset = false; - break; - case NTAP_OPT_DISABLED: - tap->disabled_after_reset = true; - break; - case NTAP_OPT_EXPECTED_ID: - e = jim_newtap_expected_id(n, goi, tap); - if (e != JIM_OK) { - free(cp); - free(tap); - return e; - } - break; - case NTAP_OPT_IRLEN: - case NTAP_OPT_IRMASK: - case NTAP_OPT_IRCAPTURE: - e = jim_newtap_ir_param(n, goi, tap); - if (e != JIM_OK) { - free(cp); - free(tap); - return e; - } - break; - case NTAP_OPT_VERSION: - tap->ignore_version = true; - break; - case NTAP_OPT_BYPASS: - tap->ignore_bypass = true; - break; - } /* switch (n->value) */ - } /* while (goi->argc) */ + case NTAP_OPT_ENABLED: + tap->disabled_after_reset = false; + break; + + case NTAP_OPT_DISABLED: + tap->disabled_after_reset = true; + break; + + case NTAP_OPT_EXPECTED_ID: + if (!CMD_ARGC) + return ERROR_COMMAND_ARGUMENT_INVALID; + + tap->expected_ids = realloc(tap->expected_ids, + (tap->expected_ids_cnt + 1) * sizeof(uint32_t)); + if (!tap->expected_ids) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + uint32_t id; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], id); + CMD_ARGC--; + CMD_ARGV++; + tap->expected_ids[tap->expected_ids_cnt++] = id; + + break; + + case NTAP_OPT_IRLEN: + if (!CMD_ARGC) + return ERROR_COMMAND_ARGUMENT_INVALID; + + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tap->ir_length); + CMD_ARGC--; + CMD_ARGV++; + if (tap->ir_length > (int)(8 * sizeof(tap->ir_capture_value))) + LOG_WARNING("%s: huge IR length %d", tap->dotted_name, tap->ir_length); + break; + + case NTAP_OPT_IRMASK: + if (!CMD_ARGC) + return ERROR_COMMAND_ARGUMENT_INVALID; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tap->ir_capture_mask); + CMD_ARGC--; + CMD_ARGV++; + if ((tap->ir_capture_mask & 3) != 3) + LOG_WARNING("%s: nonstandard IR mask", tap->dotted_name); + break; + + case NTAP_OPT_IRCAPTURE: + if (!CMD_ARGC) + return ERROR_COMMAND_ARGUMENT_INVALID; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tap->ir_capture_value); + CMD_ARGC--; + CMD_ARGV++; + if ((tap->ir_capture_value & 3) != 1) + LOG_WARNING("%s: nonstandard IR value", tap->dotted_name); + break; + + case NTAP_OPT_VERSION: + tap->ignore_version = true; + break; + + case NTAP_OPT_BYPASS: + tap->ignore_bypass = true; + break; + + default: + nvp_unknown_command_print(CMD, jtag_newtap_opts, NULL, CMD_ARGV[-1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + } /* default is enabled-after-reset */ tap->enabled = !tap->disabled_after_reset; - /* Did all the required option bits get cleared? */ - if (!transport_is_jtag() || tap->ir_length != 0) { - jtag_tap_init(tap); - return JIM_OK; + if (transport_is_jtag() && tap->ir_length == 0) { + command_print(CMD, "newtap: %s missing IR length", tap->dotted_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + return ERROR_OK; +} + +__COMMAND_HANDLER(handle_jtag_newtap) +{ + struct jtag_tap *tap = calloc(1, sizeof(struct jtag_tap)); + if (!tap) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + int retval = CALL_COMMAND_HANDLER(handle_jtag_newtap_args, tap); + if (retval != ERROR_OK) { + free(tap->chip); + free(tap->tapname); + free(tap->dotted_name); + free(tap->expected_ids); + free(tap); + return retval; } - Jim_SetResultFormatted(goi->interp, - "newtap: %s missing IR length", - tap->dotted_name); - jtag_tap_free(tap); - return JIM_ERR; + jtag_tap_init(tap); + return ERROR_OK; } static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) @@ -643,13 +601,6 @@ COMMAND_HANDLER(handle_jtag_arp_init_reset) return ERROR_OK; } -int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) -{ - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - return jim_newtap_cmd(&goi); -} - static bool jtag_tap_enable(struct jtag_tap *t) { if (t->enabled) @@ -798,7 +749,7 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "newtap", .mode = COMMAND_CONFIG, - .jim_handler = jim_jtag_newtap, + .handler = handle_jtag_newtap, .help = "Create a new TAP instance named basename.tap_type, " "and appends it to the scan chain.", .usage = "basename tap_type '-irlen' count " diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c index e1c00b706..6b492e6ab 100644 --- a/src/target/adi_v5_dapdirect.c +++ b/src/target/adi_v5_dapdirect.c @@ -58,8 +58,15 @@ static const struct command_registration dapdirect_jtag_subcommand_handlers[] = { .name = "newtap", .mode = COMMAND_CONFIG, - .jim_handler = jim_jtag_newtap, - .help = "declare a new TAP" + .handler = handle_jtag_newtap, + .help = "declare a new TAP", + .usage = "basename tap_type '-irlen' count " + "['-enable'|'-disable'] " + "['-expected_id' number] " + "['-ignore-version'] " + "['-ignore-bypass'] " + "['-ircapture' number] " + "['-mask' number]", }, { .name = "init", @@ -135,8 +142,15 @@ static const struct command_registration dapdirect_swd_subcommand_handlers[] = { { .name = "newdap", .mode = COMMAND_CONFIG, - .jim_handler = jim_jtag_newtap, + .handler = handle_jtag_newtap, .help = "declare a new SWD DAP", + .usage = "basename dap_type ['-irlen' count] " + "['-enable'|'-disable'] " + "['-expected_id' number] " + "['-ignore-version'] " + "['-ignore-bypass'] " + "['-ircapture' number] " + "['-mask' number]", }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 653f91f13..275a50128 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -657,9 +657,16 @@ static const struct command_registration swd_commands[] = { * REVISIT can we verify "just one SWD DAP" here/early? */ .name = "newdap", - .jim_handler = jim_jtag_newtap, + .handler = handle_jtag_newtap, .mode = COMMAND_CONFIG, - .help = "declare a new SWD DAP" + .help = "declare a new SWD DAP", + .usage = "basename dap_type ['-irlen' count] " + "['-enable'|'-disable'] " + "['-expected_id' number] " + "['-ignore-version'] " + "['-ignore-bypass'] " + "['-ircapture' number] " + "['-mask' number]", }, COMMAND_REGISTRATION_DONE }; ----------------------------------------------------------------------- Summary of changes: src/jtag/hla/hla_transport.c | 18 ++- src/jtag/jtag.h | 3 +- src/jtag/tcl.c | 313 ++++++++++++++++++------------------------ src/target/adi_v5_dapdirect.c | 20 ++- src/target/adi_v5_swd.c | 11 +- 5 files changed, 175 insertions(+), 190 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:41:44
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via da76f8f0b4b98c2b7f04b5fe94f721aed7b2cfab (commit) from fe6befbd80fa806749b81d5d2deafdb4b8bf0cd8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit da76f8f0b4b98c2b7f04b5fe94f721aed7b2cfab Author: Antonio Borneo <bor...@gm...> Date: Mon Mar 27 13:01:20 2023 +0200 target: use unsigned int for timeout_ms Change the prototype of functions: - target_run_algorithm() - target_wait_algorithm() - target_wait_state() - struct target_type::run_algorithm() - struct target_type::wait_algorithm() to use unsigned int for timeout_ms instead of int. Change accordingly the variables passed as parameter. Change-Id: I0b8d6e691bb3c749eeb2911dc5a86c38cc0cb65d Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7562 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 6c18c7b28..b2ebd9c49 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -91,7 +91,7 @@ static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16 } static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv, - uint16_t func_offset, uint32_t argdata[], unsigned int n_args, int timeout_ms) + uint16_t func_offset, uint32_t argdata[], unsigned int n_args, unsigned int timeout_ms) { char *regnames[4] = { "r0", "r1", "r2", "r3" }; @@ -312,7 +312,7 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig an optional larger "block" (size and command provided in args). */ - int timeout_ms = 2000 * (last - first) + 1000; + unsigned int timeout_ms = 2000 * (last - first) + 1000; err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args), timeout_ms); diff --git a/src/target/arm.h b/src/target/arm.h index de46ffb4b..fd61d5f51 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -292,14 +292,14 @@ int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info); + unsigned int timeout_ms, void *arch_info); int armv4_5_run_algorithm_inner(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, - int timeout_ms, void *arch_info, + unsigned int timeout_ms, void *arch_info, int (*run_it)(struct target *target, uint32_t exit_point, - int timeout_ms, void *arch_info)); + unsigned int timeout_ms, void *arch_info)); int arm_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum); diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 0632290d9..f60777dbe 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2518,7 +2518,7 @@ static const uint8_t *dcc_buffer; static int arm7_9_dcc_completion(struct target *target, uint32_t exit_point, - int timeout_ms, + unsigned int timeout_ms, void *arch_info) { int retval = ERROR_OK; diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 9586adc97..f35d67a57 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1252,7 +1252,7 @@ int arm_get_gdb_reg_list(struct target *target, /* wait for execution to complete and check exit point */ static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, - int timeout_ms, + unsigned int timeout_ms, void *arch_info) { int retval; @@ -1286,9 +1286,9 @@ int armv4_5_run_algorithm_inner(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, - int timeout_ms, void *arch_info, + unsigned int timeout_ms, void *arch_info, int (*run_it)(struct target *target, uint32_t exit_point, - int timeout_ms, void *arch_info)) + unsigned int timeout_ms, void *arch_info)) { struct arm *arm = target_to_arm(target); struct arm_algorithm *arm_algorithm_info = arch_info; @@ -1474,7 +1474,7 @@ int armv4_5_run_algorithm(struct target *target, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, + unsigned int timeout_ms, void *arch_info) { return armv4_5_run_algorithm_inner(target, @@ -1535,7 +1535,7 @@ int arm_checksum_memory(struct target *target, buf_set_u32(reg_params[1].value, 0, 32, count); /* 20 second timeout/megabyte */ - int timeout = 20000 * (1 + (count / (1024 * 1024))); + unsigned int timeout = 20000 * (1 + (count / (1024 * 1024))); /* armv4 must exit using a hardware breakpoint */ if (arm->arch == ARM_ARCH_V4) diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 5745681d4..8c9ff902e 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -484,7 +484,7 @@ int armv7m_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info) + unsigned int timeout_ms, void *arch_info) { int retval; @@ -622,7 +622,7 @@ int armv7m_start_algorithm(struct target *target, int armv7m_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - target_addr_t exit_point, int timeout_ms, + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { struct armv7m_common *armv7m = target_to_armv7m(target); @@ -909,7 +909,7 @@ int armv7m_checksum_memory(struct target *target, buf_set_u32(reg_params[0].value, 0, 32, address); buf_set_u32(reg_params[1].value, 0, 32, count); - int timeout = 20000 * (1 + (count / (1024 * 1024))); + unsigned int timeout = 20000 * (1 + (count / (1024 * 1024))); retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, crc_algorithm->address + (sizeof(cortex_m_crc_code) - 6), @@ -1016,7 +1016,7 @@ int armv7m_blank_check_memory(struct target *target, buf_set_u32(reg_params[1].value, 0, 32, erased_word); /* assume CPU clk at least 1 MHz */ - int timeout = (timed_out ? 30000 : 2000) + total_size * 3 / 1000; + unsigned int timeout = (timed_out ? 30000 : 2000) + total_size * 3 / 1000; retval = target_run_algorithm(target, 0, NULL, diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 188bd5652..8693404d2 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -314,7 +314,7 @@ int armv7m_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info); + unsigned int timeout_ms, void *arch_info); int armv7m_start_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, @@ -325,7 +325,7 @@ int armv7m_start_algorithm(struct target *target, int armv7m_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - target_addr_t exit_point, int timeout_ms, + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info); int armv7m_invalidate_core_regs(struct target *target); diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 36ee85371..8ea2cb613 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -1374,7 +1374,7 @@ static int dsp563xx_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info) + unsigned int timeout_ms, void *arch_info) { int i; int retval = ERROR_OK; diff --git a/src/target/mips32.c b/src/target/mips32.c index f593b5ff5..1a34f737e 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -384,7 +384,7 @@ int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, s /* run to exit point. return error if exit point was not reached. */ static int mips32_run_and_wait(struct target *target, target_addr_t entry_point, - int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32) + unsigned int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32) { uint32_t pc; int retval; @@ -418,7 +418,7 @@ static int mips32_run_and_wait(struct target *target, target_addr_t entry_point, int mips32_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, - target_addr_t exit_point, int timeout_ms, void *arch_info) + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { struct mips32_common *mips32 = target_to_mips32(target); struct mips32_algorithm *mips32_algorithm_info = arch_info; @@ -803,7 +803,7 @@ int mips32_checksum_memory(struct target *target, target_addr_t address, init_reg_param(®_params[1], "r5", 32, PARAM_OUT); buf_set_u32(reg_params[1].value, 0, 32, count); - int timeout = 20000 * (1 + (count / (1024 * 1024))); + unsigned int timeout = 20000 * (1 + (count / (1024 * 1024))); retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout, &mips32_info); diff --git a/src/target/mips32.h b/src/target/mips32.h index 8837da1d0..81b6d649d 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -400,7 +400,7 @@ int mips32_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info); + unsigned int timeout_ms, void *arch_info); int mips32_configure_break_unit(struct target *target); diff --git a/src/target/mips64.c b/src/target/mips64.c index 773b92d73..37f36855c 100644 --- a/src/target/mips64.c +++ b/src/target/mips64.c @@ -459,7 +459,7 @@ int mips64_init_arch_info(struct target *target, struct mips64_common *mips64, int mips64_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, - target_addr_t exit_point, int timeout_ms, void *arch_info) + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { /* TODO */ return ERROR_OK; diff --git a/src/target/mips64.h b/src/target/mips64.h index 9079c8013..ae0811c54 100644 --- a/src/target/mips64.h +++ b/src/target/mips64.h @@ -213,7 +213,7 @@ int mips64_build_reg_cache(struct target *target); int mips64_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info); + unsigned int timeout_ms, void *arch_info); int mips64_configure_break_unit(struct target *target); int mips64_enable_interrupts(struct target *target, bool enable); int mips64_examine(struct target *target); diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 865abd080..48391786d 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1830,7 +1830,7 @@ static int riscv_arch_state(struct target *target) static int riscv_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, - target_addr_t exit_point, int timeout_ms, void *arch_info) + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { RISCV_INFO(info); @@ -2052,7 +2052,7 @@ static int riscv_checksum_memory(struct target *target, buf_set_u64(reg_params[1].value, 0, xlen, count); /* 20 second timeout/megabyte */ - int timeout = 20000 * (1 + (count / (1024 * 1024))); + unsigned int timeout = 20000 * (1 + (count / (1024 * 1024))); retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, diff --git a/src/target/stm8.c b/src/target/stm8.c index 9fd65091c..91a59d79c 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1784,7 +1784,7 @@ static int stm8_checksum_memory(struct target *target, target_addr_t address, /* run to exit point. return error if exit point was not reached. */ static int stm8_run_and_wait(struct target *target, uint32_t entry_point, - int timeout_ms, uint32_t exit_point, struct stm8_common *stm8) + unsigned int timeout_ms, uint32_t exit_point, struct stm8_common *stm8) { uint32_t pc; int retval; @@ -1819,7 +1819,7 @@ static int stm8_run_and_wait(struct target *target, uint32_t entry_point, static int stm8_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, target_addr_t entry_point, - target_addr_t exit_point, int timeout_ms, void *arch_info) + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { struct stm8_common *stm8 = target_to_stm8(target); diff --git a/src/target/target.c b/src/target/target.c index 12cfeb528..009929211 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -809,7 +809,7 @@ int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info) + unsigned int timeout_ms, void *arch_info) { int retval = ERROR_FAIL; @@ -893,7 +893,7 @@ done: int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - target_addr_t exit_point, int timeout_ms, + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info) { int retval = ERROR_FAIL; @@ -3229,7 +3229,7 @@ COMMAND_HANDLER(handle_wait_halt_command) * * After 500ms, keep_alive() is invoked */ -int target_wait_state(struct target *target, enum target_state state, int ms) +int target_wait_state(struct target *target, enum target_state state, unsigned int ms) { int retval; int64_t then = 0, cur; @@ -5785,8 +5785,8 @@ COMMAND_HANDLER(handle_target_wait_state) return ERROR_COMMAND_ARGUMENT_INVALID; } - int a; - COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], a); + unsigned int a; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], a); struct target *target = get_current_target(CMD_CTX); if (!target->tap->enabled) { diff --git a/src/target/target.h b/src/target/target.h index 00bf43c58..2a2f5315f 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -547,7 +547,7 @@ int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, - int timeout_ms, void *arch_info); + unsigned int timeout_ms, void *arch_info); /** * Starts an algorithm in the background on the @a target given. @@ -568,7 +568,7 @@ int target_start_algorithm(struct target *target, int target_wait_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, - target_addr_t exit_point, int timeout_ms, + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info); /** @@ -660,7 +660,7 @@ int target_checksum_memory(struct target *target, int target_blank_check_memory(struct target *target, struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value); -int target_wait_state(struct target *target, enum target_state state, int ms); +int target_wait_state(struct target *target, enum target_state state, unsigned int ms); /** * Obtain file-I/O information from target for GDB to do syscall. diff --git a/src/target/target_type.h b/src/target/target_type.h index 5186e9c19..678ce0f46 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -181,7 +181,7 @@ struct target_type { int (*run_algorithm)(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, - target_addr_t exit_point, int timeout_ms, void *arch_info); + target_addr_t exit_point, unsigned int timeout_ms, void *arch_info); int (*start_algorithm)(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, @@ -189,7 +189,7 @@ struct target_type { int (*wait_algorithm)(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t exit_point, - int timeout_ms, void *arch_info); + unsigned int timeout_ms, void *arch_info); const struct command_registration *commands; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 4 ++-- src/target/arm.h | 6 +++--- src/target/arm7_9_common.c | 2 +- src/target/armv4_5.c | 10 +++++----- src/target/armv7m.c | 8 ++++---- src/target/armv7m.h | 4 ++-- src/target/dsp563xx.c | 2 +- src/target/mips32.c | 6 +++--- src/target/mips32.h | 2 +- src/target/mips64.c | 2 +- src/target/mips64.h | 2 +- src/target/riscv/riscv.c | 4 ++-- src/target/stm8.c | 4 ++-- src/target/target.c | 10 +++++----- src/target/target.h | 6 +++--- src/target/target_type.h | 4 ++-- 16 files changed, 38 insertions(+), 38 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:41:17
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via fe6befbd80fa806749b81d5d2deafdb4b8bf0cd8 (commit) from 22ababc12e5d25934a281b62b5ff66e66c965e21 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fe6befbd80fa806749b81d5d2deafdb4b8bf0cd8 Author: Antonio Borneo <bor...@gm...> Date: Mon Mar 27 12:03:13 2023 +0200 target: rewrite command 'arp_waitstate' as COMMAND_HANDLER While there, add the missing .usage field and remove the now unused function jim_target_tap_disabled(). Change-Id: I79afcc5097643fc264354c6c3957786a55f40498 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7561 Tested-by: jenkins diff --git a/src/target/target.c b/src/target/target.c index 785d7651a..12cfeb528 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -210,7 +210,7 @@ static const struct jim_nvp nvp_target_event[] = { { .name = NULL, .value = -1 } }; -static const struct jim_nvp nvp_target_state[] = { +static const struct nvp nvp_target_state[] = { { .name = "unknown", .value = TARGET_UNKNOWN }, { .name = "running", .value = TARGET_RUNNING }, { .name = "halted", .value = TARGET_HALTED }, @@ -264,7 +264,7 @@ const char *debug_reason_name(struct target *t) const char *target_state_name(struct target *t) { const char *cp; - cp = jim_nvp_value2name_simple(nvp_target_state, t->state)->name; + cp = nvp_value2name(nvp_target_state, t->state)->name; if (!cp) { LOG_ERROR("Invalid target state: %d", (int)(t->state)); cp = "(*BUG*unknown*BUG*)"; @@ -3246,7 +3246,7 @@ int target_wait_state(struct target *target, enum target_state state, int ms) once = false; then = timeval_ms(); LOG_DEBUG("waiting for target %s...", - jim_nvp_value2name_simple(nvp_target_state, state)->name); + nvp_value2name(nvp_target_state, state)->name); } if (cur-then > 500) @@ -3254,7 +3254,7 @@ int target_wait_state(struct target *target, enum target_state state, int ms) if ((cur-then) > ms) { LOG_ERROR("timed out while waiting for target %s", - jim_nvp_value2name_simple(nvp_target_state, state)->name); + nvp_value2name(nvp_target_state, state)->name); return ERROR_FAIL; } } @@ -5633,12 +5633,6 @@ static int jim_target_array2mem(Jim_Interp *interp, return target_array2mem(interp, target, argc - 1, argv + 1); } -static int jim_target_tap_disabled(Jim_Interp *interp) -{ - Jim_SetResultFormatted(interp, "[TAP is disabled]"); - return JIM_ERR; -} - COMMAND_HANDLER(handle_target_examine) { bool allow_defer = false; @@ -5780,45 +5774,35 @@ COMMAND_HANDLER(handle_target_halt) return target->type->halt(target); } -static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_wait_state) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; - /* params: <name> statename timeoutmsecs */ - if (goi.argc != 2) { - const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_SetResultFormatted(goi.interp, - "%s <state_name> <timeout_in_msec>", cmd_name); - return JIM_ERR; + const struct nvp *n = nvp_name2value(nvp_target_state, CMD_ARGV[0]); + if (!n->name) { + nvp_unknown_command_print(CMD, nvp_target_state, NULL, CMD_ARGV[0]); + return ERROR_COMMAND_ARGUMENT_INVALID; } - struct jim_nvp *n; - int e = jim_getopt_nvp(&goi, nvp_target_state, &n); - if (e != JIM_OK) { - jim_getopt_nvp_unknown(&goi, nvp_target_state, 1); - return e; + int a; + COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], a); + + struct target *target = get_current_target(CMD_CTX); + if (!target->tap->enabled) { + command_print(CMD, "[TAP is disabled]"); + return ERROR_FAIL; } - jim_wide a; - e = jim_getopt_wide(&goi, &a); - if (e != JIM_OK) - return e; - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - if (!target->tap->enabled) - return jim_target_tap_disabled(interp); - e = target_wait_state(target, n->value, a); - if (e != ERROR_OK) { - Jim_Obj *obj = Jim_NewIntObj(interp, e); - Jim_SetResultFormatted(goi.interp, - "target: %s wait %s fails (%#s) %s", + int retval = target_wait_state(target, n->value, a); + if (retval != ERROR_OK) { + command_print(CMD, + "target: %s wait %s fails (%d) %s", target_name(target), n->name, - obj, target_strerror_safe(e)); - return JIM_ERR; + retval, target_strerror_safe(retval)); + return retval; } - return JIM_OK; + return ERROR_OK; } /* List for human, Events defined for this target. * scripts/programs should use 'name cget -event NAME' @@ -6059,8 +6043,9 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "arp_waitstate", .mode = COMMAND_EXEC, - .jim_handler = jim_target_wait_state, + .handler = handle_target_wait_state, .help = "used internally for reset processing", + .usage = "statename timeoutmsecs", }, { .name = "invoke-event", ----------------------------------------------------------------------- Summary of changes: src/target/target.c | 69 +++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 42 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2023-05-27 06:40:43
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 22ababc12e5d25934a281b62b5ff66e66c965e21 (commit) from 0f0a4b1452198160ae38be3d26ebd555224e3fbc (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 22ababc12e5d25934a281b62b5ff66e66c965e21 Author: Antonio Borneo <bor...@gm...> Date: Mon Mar 27 11:38:35 2023 +0200 target: rewrite command 'arp_examine' as COMMAND_HANDLER Change-Id: I8f227b219ca39f198e1e39847ddd36bb9880a328 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/7560 Tested-by: jenkins diff --git a/src/target/target.c b/src/target/target.c index fee9583ae..785d7651a 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5639,49 +5639,40 @@ static int jim_target_tap_disabled(Jim_Interp *interp) return JIM_ERR; } -static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_examine) { bool allow_defer = false; - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - if (goi.argc > 1) { - const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_SetResultFormatted(goi.interp, - "usage: %s ['allow-defer']", cmd_name); - return JIM_ERR; - } - if (goi.argc > 0 && - strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) { - /* consume it */ - Jim_Obj *obj; - int e = jim_getopt_obj(&goi, &obj); - if (e != JIM_OK) - return e; + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 1) { + if (strcmp(CMD_ARGV[0], "allow-defer")) + return ERROR_COMMAND_ARGUMENT_INVALID; allow_defer = true; } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - if (!target->tap->enabled) - return jim_target_tap_disabled(interp); + struct target *target = get_current_target(CMD_CTX); + if (!target->tap->enabled) { + command_print(CMD, "[TAP is disabled]"); + return ERROR_FAIL; + } if (allow_defer && target->defer_examine) { LOG_INFO("Deferring arp_examine of %s", target_name(target)); LOG_INFO("Use arp_examine command to examine it manually!"); - return JIM_OK; + return ERROR_OK; } - int e = target->type->examine(target); - if (e != ERROR_OK) { + int retval = target->type->examine(target); + if (retval != ERROR_OK) { target_reset_examined(target); - return JIM_ERR; + return retval; } target_set_examined(target); - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_target_was_examined) @@ -6019,7 +6010,7 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "arp_examine", .mode = COMMAND_EXEC, - .jim_handler = jim_target_examine, + .handler = handle_target_examine, .help = "used internally for reset processing", .usage = "['allow-defer']", }, ----------------------------------------------------------------------- Summary of changes: src/target/target.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) hooks/post-receive -- Main OpenOCD repository |