aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2022-04-12 09:52:47 -0700
committerGitHub <noreply@github.com>2022-04-12 09:52:47 -0700
commit31812cd13f35ab28011615cce1aac7298dfe35c7 (patch)
tree7b6d08fa3c348a92e0a4e1cd7ecb2656807ee69c
parent78b56e25c217338519d51818dce663742c783da9 (diff)
parentb7fdcd5e85eb4a9f69347ce7e6d1d1011078481e (diff)
downloadriscv-openocd-31812cd13f35ab28011615cce1aac7298dfe35c7.zip
riscv-openocd-31812cd13f35ab28011615cce1aac7298dfe35c7.tar.gz
riscv-openocd-31812cd13f35ab28011615cce1aac7298dfe35c7.tar.bz2
Merge pull request #691 from riscv/from_upstream
From upstream
-rw-r--r--config_subdir.m42
-rw-r--r--configure.ac11
-rwxr-xr-xcontrib/rpc_examples/ocd_rpc_example.py18
-rw-r--r--doc/openocd.texi184
-rw-r--r--src/flash/nor/efm32.c18
-rw-r--r--src/flash/nor/sim3x.c2
-rw-r--r--src/flash/nor/stm32f1x.c5
-rw-r--r--src/flash/nor/stm32f2x.c5
-rw-r--r--src/flash/nor/stm32h7x.c3
-rw-r--r--src/flash/nor/stm32l4x.c15
-rw-r--r--src/helper/bits.h4
-rw-r--r--src/helper/jim-nvp.c4
-rw-r--r--src/helper/log.c42
-rw-r--r--src/jtag/drivers/cmsis_dap.c17
-rw-r--r--src/jtag/drivers/jtag_vpi.c41
-rw-r--r--src/jtag/drivers/libusb_helper.h14
-rw-r--r--src/jtag/drivers/nulink_usb.c4
-rw-r--r--src/jtag/drivers/rlink.c30
-rw-r--r--src/jtag/drivers/stlink_usb.c33
-rw-r--r--src/jtag/drivers/ti_icdi_usb.c4
-rw-r--r--src/jtag/drivers/ulink.c11
-rw-r--r--src/rtos/chromium-ec.c6
-rw-r--r--src/rtt/rtt.c4
-rw-r--r--src/rtt/tcl.c4
-rw-r--r--src/server/gdb_server.c122
-rw-r--r--src/server/ipdbg.c12
-rw-r--r--src/server/rtt_server.c16
-rw-r--r--src/server/server.c31
-rw-r--r--src/server/server.h38
-rw-r--r--src/server/tcl_server.c13
-rw-r--r--src/server/telnet_server.c12
-rw-r--r--src/target/aarch64.c48
-rw-r--r--src/target/arc.c38
-rw-r--r--src/target/arm7_9_common.c49
-rw-r--r--src/target/arm_dpm.c6
-rw-r--r--src/target/arm_tpiu_swo.c39
-rw-r--r--src/target/armv8_dpm.c6
-rw-r--r--src/target/breakpoints.c6
-rw-r--r--src/target/breakpoints.h18
-rw-r--r--src/target/cortex_a.c48
-rw-r--r--src/target/cortex_m.c246
-rw-r--r--src/target/esirisc.c16
-rw-r--r--src/target/lakemont.c4
-rw-r--r--src/target/mips_m4k.c34
-rw-r--r--src/target/mips_mips64.c33
-rw-r--r--src/target/nds32.c2
-rw-r--r--src/target/nds32_v3_common.c6
-rw-r--r--src/target/openrisc/jsp_server.c17
-rw-r--r--src/target/openrisc/or1k.c8
-rw-r--r--src/target/riscv/riscv.c14
-rw-r--r--src/target/rtt.c4
-rw-r--r--src/target/semihosting_common.c353
-rw-r--r--src/target/semihosting_common.h17
-rw-r--r--src/target/startup.tcl26
-rw-r--r--src/target/stm8.c34
-rw-r--r--src/target/target.c545
-rw-r--r--src/target/x86_32_common.c30
-rw-r--r--src/target/xscale.c42
-rw-r--r--tcl/board/at91cap7a-stk-sdram.cfg3
-rw-r--r--tcl/board/at91sam9g20-ek.cfg4
-rw-r--r--tcl/board/embedded-artists_lpc2478-32.cfg4
-rw-r--r--tcl/board/hilscher_nxhx10.cfg4
-rw-r--r--tcl/board/icnova_sam9g45_sodimm.cfg4
-rw-r--r--tcl/board/lemaker_hikey.cfg2
-rw-r--r--tcl/board/nxp_frdm-k64f.cfg15
-rw-r--r--tcl/board/nxp_rdb-ls1046a.cfg17
-rw-r--r--tcl/board/ti_am625evm.cfg25
-rw-r--r--tcl/board/ti_j721s2evm.cfg25
-rw-r--r--tcl/board/tocoding_poplar.cfg2
-rw-r--r--tcl/chip/atmel/at91/aic.tcl20
-rw-r--r--tcl/cpu/arc/common.tcl5
-rw-r--r--tcl/mem_helper.tcl12
-rw-r--r--tcl/memory.tcl60
-rw-r--r--tcl/target/bluefield.cfg2
-rw-r--r--tcl/target/c100helper.tcl24
-rw-r--r--tcl/target/hilscher_netx500.cfg4
-rw-r--r--tcl/target/ls1046a.cfg56
-rw-r--r--tcl/target/psoc4.cfg18
-rw-r--r--tcl/target/stm32h7x.cfg4
-rw-r--r--tcl/target/stm32l5x.cfg162
-rw-r--r--tcl/target/stm32mp15x.cfg4
-rw-r--r--tcl/target/stm32u5x.cfg184
-rw-r--r--tcl/target/stm32wlx.cfg4
-rw-r--r--tcl/target/stm32x5x_common.cfg154
-rw-r--r--tcl/target/ti_cc3220sf.cfg8
-rw-r--r--tcl/target/ti_k3.cfg229
-rw-r--r--tcl/target/xilinx_zynqmp.cfg2
-rw-r--r--tcl/tools/test_cpu_speed.tcl50
-rw-r--r--testing/examples/cortex/cm3-ftest.cfg2
89 files changed, 2347 insertions, 1176 deletions
diff --git a/config_subdir.m4 b/config_subdir.m4
index 45a1c6c..2be590e 100644
--- a/config_subdir.m4
+++ b/config_subdir.m4
@@ -7,6 +7,6 @@ AC_DEFUN([AX_CONFIG_SUBDIR_OPTION],
AC_CONFIG_SUBDIRS([$1])
m4_ifblank([$2], [rm -f $srcdir/$1/configure.gnu],
-[echo -e '#!/bin/sh\nexec "`dirname "'\$'0"`/configure" $2 "'\$'@"' > "$srcdir/$1/configure.gnu"
+[echo -e '#!/bin/sh\nexec "`dirname "'\$'0"`/configure" '"$2"' "'\$'@"' > "$srcdir/$1/configure.gnu"
])
])
diff --git a/configure.ac b/configure.ac
index f70dc2f..066c14b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -355,6 +355,10 @@ AC_ARG_ENABLE([internal-jimtcl],
AS_HELP_STRING([--disable-internal-jimtcl], [Disable building internal jimtcl]),
[use_internal_jimtcl=$enableval], [use_internal_jimtcl=yes])
+AC_ARG_ENABLE([jimtcl-maintainer],
+ AS_HELP_STRING([--enable-jimtcl-maintainer], [Enable maintainer mode when building internal jimtcl]),
+ [use_internal_jimtcl_maintainer=$enableval], [use_internal_jimtcl_maintainer=no])
+
AC_ARG_ENABLE([internal-libjaylink],
AS_HELP_STRING([--disable-internal-libjaylink],
[Disable building internal libjaylink]),
@@ -551,7 +555,12 @@ AS_IF([test "x$enable_buspirate" != "xno"], [
AS_IF([test "x$use_internal_jimtcl" = "xyes"], [
AS_IF([test -f "$srcdir/jimtcl/configure.ac"], [
- AX_CONFIG_SUBDIR_OPTION([jimtcl], [--disable-install-jim])
+ AS_IF([test "x$use_internal_jimtcl_maintainer" = "xyes"], [
+ jimtcl_config_options="--disable-install-jim --maintainer"
+ ], [
+ jimtcl_config_options="--disable-install-jim"
+ ])
+ AX_CONFIG_SUBDIR_OPTION([jimtcl], [$jimtcl_config_options])
], [
AC_MSG_ERROR([jimtcl not found, run git submodule init and git submodule update.])
])
diff --git a/contrib/rpc_examples/ocd_rpc_example.py b/contrib/rpc_examples/ocd_rpc_example.py
index 3470d84..e6146f6 100755
--- a/contrib/rpc_examples/ocd_rpc_example.py
+++ b/contrib/rpc_examples/ocd_rpc_example.py
@@ -95,24 +95,16 @@ class OpenOcd:
return None if (len(raw) < 2) else strToHex(raw[1])
def readMemory(self, wordLen, address, n):
- self.send("array unset output") # better to clear the array before
- self.send("mem2array output %d 0x%x %d" % (wordLen, address, n))
-
- output = [*map(int, self.send("return $output").split(" "))]
- d = dict([tuple(output[i:i + 2]) for i in range(0, len(output), 2)])
-
- return [d[k] for k in sorted(d.keys())]
+ output = self.send("read_memory 0x%x %d %d" % (address, wordLen, n))
+ return [*map(lambda x: int(x, 16), output.split(" "))]
def writeVariable(self, address, value):
assert value is not None
self.send("mww 0x%x 0x%x" % (address, value))
- def writeMemory(self, wordLen, address, n, data):
- array = " ".join(["%d 0x%x" % (a, b) for a, b in enumerate(data)])
-
- self.send("array unset 1986ве1т") # better to clear the array before
- self.send("array set 1986ве1т { %s }" % array)
- self.send("array2mem 1986ве1т 0x%x %s %d" % (wordLen, address, n))
+ def writeMemory(self, wordLen, address, data):
+ data = "{" + ' '.join(['0x%x' % x for x in data]) + "}"
+ self.send("write_memory 0x%x %d %s" % (address, wordLen, data))
if __name__ == "__main__":
diff --git a/doc/openocd.texi b/doc/openocd.texi
index f826a0b..a4fa684 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -4980,27 +4980,76 @@ use these to deal with specific reset cases.
They are not otherwise documented here.
@end deffn
-@deffn {Command} {$target_name array2mem} arrayname width address count
-@deffnx {Command} {$target_name mem2array} arrayname width address count
-These provide an efficient script-oriented interface to memory.
-The @code{array2mem} primitive writes bytes, halfwords, words
-or double-words; while @code{mem2array} reads them.
-In both cases, the TCL side uses an array, and
-the target side uses raw memory.
-
-The efficiency comes from enabling the use of
-bulk JTAG data transfer operations.
-The script orientation comes from working with data
-values that are packaged for use by TCL scripts;
-@command{mdw} type primitives only print data they retrieve,
-and neither store nor return those values.
+@deffn {Command} {$target_name set_reg} dict
+Set register values of the target.
@itemize
-@item @var{arrayname} ... is the name of an array variable
-@item @var{width} ... is 8/16/32/64 - indicating the memory access size
-@item @var{address} ... is the target memory address
-@item @var{count} ... is the number of elements to process
+@item @var{dict} ... Tcl dictionary with pairs of register names and values.
@end itemize
+
+For example, the following command sets the value 0 to the program counter (pc)
+register and 0x1000 to the stack pointer (sp) register:
+
+@example
+set_reg @{pc 0 sp 0x1000@}
+@end example
+@end deffn
+
+@deffn {Command} {$target_name get_reg} [-force] list
+Get register values from the target and return them as Tcl dictionary with pairs
+of register names and values.
+If option "-force" is set, the register values are read directly from the
+target, bypassing any caching.
+
+@itemize
+@item @var{list} ... List of register names
+@end itemize
+
+For example, the following command retrieves the values from the program
+counter (pc) and stack pointer (sp) register:
+
+@example
+get_reg @{pc sp@}
+@end example
+@end deffn
+
+@deffn {Command} {$target_name write_memory} address width data ['phys']
+This function provides an efficient way to write to the target memory from a Tcl
+script.
+
+@itemize
+@item @var{address} ... target memory address
+@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64
+@item @var{data} ... Tcl list with the elements to write
+@item ['phys'] ... treat the memory address as physical instead of virtual address
+@end itemize
+
+For example, the following command writes two 32 bit words into the target
+memory at address 0x20000000:
+
+@example
+write_memory 0x20000000 32 @{0xdeadbeef 0x00230500@}
+@end example
+@end deffn
+
+@deffn {Command} {$target_name read_memory} address width count ['phys']
+This function provides an efficient way to read the target memory from a Tcl
+script.
+A Tcl list containing the requested memory elements is returned by this function.
+
+@itemize
+@item @var{address} ... target memory address
+@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64
+@item @var{count} ... number of elements to read
+@item ['phys'] ... treat the memory address as physical instead of virtual address
+@end itemize
+
+For example, the following command reads two 32 bit words from the target
+memory at address 0x20000000:
+
+@example
+read_memory 0x20000000 32 2
+@end example
@end deffn
@deffn {Command} {$target_name cget} queryparm
@@ -5070,8 +5119,8 @@ When the current target has an MMU which is present and active,
Otherwise, or if the optional @var{phys} flag is specified,
@var{addr} is interpreted as a physical address.
If @var{count} is specified, displays that many units.
-(If you want to manipulate the data instead of displaying it,
-see the @code{mem2array} primitives.)
+(If you want to process the data instead of displaying it,
+see the @code{read_memory} primitives.)
@end deffn
@deffn {Command} {$target_name mwd} [phys] addr doubleword [count]
@@ -8491,6 +8540,78 @@ Debug and trace infrastructure:
@end example
@end deffn
+@deffn {Command} {set_reg} dict
+Set register values of the target.
+
+@itemize
+@item @var{dict} ... Tcl dictionary with pairs of register names and values.
+@end itemize
+
+For example, the following command sets the value 0 to the program counter (pc)
+register and 0x1000 to the stack pointer (sp) register:
+
+@example
+set_reg @{pc 0 sp 0x1000@}
+@end example
+@end deffn
+
+@deffn {Command} {get_reg} [-force] list
+Get register values from the target and return them as Tcl dictionary with pairs
+of register names and values.
+If option "-force" is set, the register values are read directly from the
+target, bypassing any caching.
+
+@itemize
+@item @var{list} ... List of register names
+@end itemize
+
+For example, the following command retrieves the values from the program
+counter (pc) and stack pointer (sp) register:
+
+@example
+get_reg @{pc sp@}
+@end example
+@end deffn
+
+@deffn {Command} {write_memory} address width data ['phys']
+This function provides an efficient way to write to the target memory from a Tcl
+script.
+
+@itemize
+@item @var{address} ... target memory address
+@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64
+@item @var{data} ... Tcl list with the elements to write
+@item ['phys'] ... treat the memory address as physical instead of virtual address
+@end itemize
+
+For example, the following command writes two 32 bit words into the target
+memory at address 0x20000000:
+
+@example
+write_memory 0x20000000 32 @{0xdeadbeef 0x00230500@}
+@end example
+@end deffn
+
+@deffn {Command} {read_memory} address width count ['phys']
+This function provides an efficient way to read the target memory from a Tcl
+script.
+A Tcl list containing the requested memory elements is returned by this function.
+
+@itemize
+@item @var{address} ... target memory address
+@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64
+@item @var{count} ... number of elements to read
+@item ['phys'] ... treat the memory address as physical instead of virtual address
+@end itemize
+
+For example, the following command reads two 32 bit words from the target
+memory at address 0x20000000:
+
+@example
+read_memory 0x20000000 32 2
+@end example
+@end deffn
+
@deffn {Command} {halt} [ms]
@deffnx {Command} {wait_halt} [ms]
The @command{halt} command first sends a halt request to the target,
@@ -8628,8 +8749,8 @@ When the current target has an MMU which is present and active,
Otherwise, or if the optional @var{phys} flag is specified,
@var{addr} is interpreted as a physical address.
If @var{count} is specified, displays that many units.
-(If you want to manipulate the data instead of displaying it,
-see the @code{mem2array} primitives.)
+(If you want to process the data instead of displaying it,
+see the @code{read_memory} primitives.)
@end deffn
@deffn {Command} {mwd} [phys] addr doubleword [count]
@@ -9249,6 +9370,17 @@ requests by using a special SVC instruction that is trapped at the
Supervisor Call vector by OpenOCD.
@end deffn
+@deffn {Command} {arm semihosting_redirect} (@option{disable} | @option{tcp} <port>
+[@option{debug}|@option{stdio}|@option{all})
+@cindex ARM semihosting
+Redirect semihosting messages to a specified TCP port.
+
+This command redirects debug (READC, WRITEC and WRITE0) and stdio (READ, WRITE)
+semihosting operations to the specified TCP port.
+The command allows to select which type of operations to redirect (debug, stdio, all (default)).
+Note: for stdio operations, only I/O from/to ':tt' file descriptors are redirected.
+@end deffn
+
@deffn {Command} {arm semihosting_cmdline} [@option{enable}|@option{disable}]
@cindex ARM semihosting
Set the command line to be passed to the debugger.
@@ -11584,13 +11716,7 @@ should be passed in to the proc in question.
By "low-level", we mean commands that a human would typically not
invoke directly.
-@itemize @bullet
-@item @b{mem2array} <@var{varname}> <@var{width}> <@var{addr}> <@var{nelems}>
-
-Read memory and return as a Tcl array for script processing
-@item @b{array2mem} <@var{varname}> <@var{width}> <@var{addr}> <@var{nelems}>
-
-Convert a Tcl array to memory locations and write the values
+@itemize
@item @b{flash banks} <@var{driver}> <@var{base}> <@var{size}> <@var{chip_width}> <@var{bus_width}> <@var{target}> [@option{driver options} ...]
Return information about the flash banks
diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c
index 653878a..2c5a502 100644
--- a/src/flash/nor/efm32.c
+++ b/src/flash/nor/efm32.c
@@ -257,23 +257,19 @@ static int efm32x_write_reg_u32(struct flash_bank *bank, target_addr_t offset,
static int efm32x_read_info(struct flash_bank *bank)
{
int ret;
- uint32_t cpuid = 0;
struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
struct efm32_info *efm32_info = &(efm32x_info->info);
memset(efm32_info, 0, sizeof(struct efm32_info));
- ret = target_read_u32(bank->target, CPUID, &cpuid);
- if (ret != ERROR_OK)
- return ret;
+ const struct cortex_m_common *cortex_m = target_to_cm(bank->target);
- if (((cpuid >> 4) & 0xfff) == 0xc23) {
- /* Cortex-M3 device */
- } else if (((cpuid >> 4) & 0xfff) == 0xc24) {
- /* Cortex-M4 device (WONDER GECKO) */
- } else if (((cpuid >> 4) & 0xfff) == 0xc60) {
- /* Cortex-M0+ device */
- } else {
+ switch (cortex_m->core_info->partno) {
+ case CORTEX_M3_PARTNO:
+ case CORTEX_M4_PARTNO:
+ case CORTEX_M0P_PARTNO:
+ break;
+ default:
LOG_ERROR("Target is not Cortex-Mx Device");
return ERROR_FAIL;
}
diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c
index 2938ed1..8913838 100644
--- a/src/flash/nor/sim3x.c
+++ b/src/flash/nor/sim3x.c
@@ -983,7 +983,7 @@ COMMAND_HANDLER(sim3x_lock)
if (!dap) {
/* Used debug interface doesn't support direct DAP access */
- LOG_INFO("Target can't by unlocked by this debug interface");
+ LOG_INFO("Target can't be unlocked by this debug interface");
/* Core check */
ret = target_read_u32(target, CPUID, &val);
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
index 29a3b7e..6972bae 100644
--- a/src/flash/nor/stm32f1x.c
+++ b/src/flash/nor/stm32f1x.c
@@ -592,10 +592,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
while (words_remaining > 0) {
- uint16_t value;
- memcpy(&value, buffer, sizeof(uint16_t));
-
- retval = target_write_u16(target, bank->base + offset, value);
+ retval = target_write_memory(target, bank->base + offset, 2, 1, buffer);
if (retval != ERROR_OK)
goto reset_pg_and_lock;
diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c
index 58edca7..622ef34 100644
--- a/src/flash/nor/stm32f2x.c
+++ b/src/flash/nor/stm32f2x.c
@@ -856,15 +856,12 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
Wait for the BSY bit to be cleared
*/
while (words_remaining > 0) {
- uint16_t value;
- memcpy(&value, buffer + bytes_written, sizeof(uint16_t));
-
retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
FLASH_PG | FLASH_PSIZE_16);
if (retval != ERROR_OK)
return retval;
- retval = target_write_u16(target, address, value);
+ retval = target_write_memory(target, address, 2, 1, buffer + bytes_written);
if (retval != ERROR_OK)
return retval;
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index 6d3149f..d2914eb 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -531,6 +531,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
unsigned int last)
{
struct target *target = bank->target;
+ struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
uint32_t protection;
if (target->state != TARGET_HALTED) {
@@ -553,7 +554,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
}
/* apply WRPSN mask */
- protection &= 0xff;
+ protection &= stm32x_info->part_info->wps_mask;
LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%" PRIx32, protection);
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index fd03388..7b35a06 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -1757,7 +1757,7 @@ static int stm32l4_probe(struct flash_bank *bank)
* Ask the flash infrastructure to ensure required alignment */
bank->write_start_alignment = bank->write_end_alignment = stm32l4_info->data_width;
- /* initialise the flash registers layout */
+ /* Initialize the flash registers layout */
if (part_info->flags & F_HAS_L5_FLASH_REGS)
stm32l4_info->flash_regs = stm32l5_ns_flash_regs;
else
@@ -1770,7 +1770,7 @@ static int stm32l4_probe(struct flash_bank *bank)
stm32l4_sync_rdp_tzen(bank);
- /* for devices with trustzone, use flash secure registers when TZEN=1 and RDP is LEVEL_0 */
+ /* for devices with TrustZone, use flash secure registers when TZEN=1 and RDP is LEVEL_0 */
if (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {
if (part_info->flags & F_HAS_L5_FLASH_REGS) {
stm32l4_info->flash_regs_base |= STM32L5_REGS_SEC_OFFSET;
@@ -2046,8 +2046,19 @@ static int stm32l4_auto_probe(struct flash_bank *bank)
if (stm32l4_info->probed) {
uint32_t optr_cur;
+ /* save flash_regs_base */
+ uint32_t saved_flash_regs_base = stm32l4_info->flash_regs_base;
+
+ /* for devices with TrustZone, use NS flash registers to read OPTR */
+ if (stm32l4_info->part_info->flags & F_HAS_L5_FLASH_REGS)
+ stm32l4_info->flash_regs_base &= ~STM32L5_REGS_SEC_OFFSET;
+
/* read flash option register and re-probe if optr value is changed */
int retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &optr_cur);
+
+ /* restore saved flash_regs_base */
+ stm32l4_info->flash_regs_base = saved_flash_regs_base;
+
if (retval != ERROR_OK)
return retval;
diff --git a/src/helper/bits.h b/src/helper/bits.h
index 00d3c02..6151b33 100644
--- a/src/helper/bits.h
+++ b/src/helper/bits.h
@@ -28,8 +28,12 @@
#include <helper/types.h>
#define BIT(nr) (1UL << (nr))
+#define BIT_ULL(nr) (1ULL << (nr))
#define BITS_PER_BYTE 8
#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
+#define BITS_PER_LONG_LONG (BITS_PER_BYTE * sizeof(long long))
+#define GENMASK(h, l) (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+#define GENMASK_ULL(h, l) (((~0ULL) - (1ULL << (l)) + 1) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c
index 738ed79..0409a83 100644
--- a/src/helper/jim-nvp.c
+++ b/src/helper/jim-nvp.c
@@ -41,6 +41,10 @@
* official policies, either expressed or implied, of the Jim Tcl Project.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "jim-nvp.h"
#include <string.h>
diff --git a/src/helper/log.c b/src/helper/log.c
index 6865607..106d228 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -30,6 +30,7 @@
#include "command.h"
#include "replacements.h"
#include "time_support.h"
+#include <server/server.h>
#include <stdarg.h>
@@ -47,7 +48,6 @@ static FILE *log_output;
static struct log_callback *log_callbacks;
static int64_t last_time;
-static int64_t current_time;
static int64_t start;
@@ -111,32 +111,27 @@ static void log_puts(enum log_levels level,
if (f)
file = f + 1;
- if (strlen(string) > 0) {
- if (debug_level >= LOG_LVL_DEBUG) {
- /* print with count and time information */
- int64_t t = timeval_ms() - start;
+ if (debug_level >= LOG_LVL_DEBUG) {
+ /* print with count and time information */
+ int64_t t = timeval_ms() - start;
#ifdef _DEBUG_FREE_SPACE_
- struct mallinfo info;
- info = mallinfo();
+ struct mallinfo info;
+ info = mallinfo();
#endif
- fprintf(log_output, "%s%d %" PRId64 " %s:%d %s()"
+ fprintf(log_output, "%s%d %" PRId64 " %s:%d %s()"
#ifdef _DEBUG_FREE_SPACE_
- " %d"
+ " %d"
#endif
- ": %s", log_strings[level + 1], count, t, file, line, function,
+ ": %s", log_strings[level + 1], count, t, file, line, function,
#ifdef _DEBUG_FREE_SPACE_
- info.fordblks,
+ info.fordblks,
#endif
- string);
- } else {
- /* if we are using gdb through pipes then we do not want any output
- * to the pipe otherwise we get repeated strings */
- fprintf(log_output, "%s%s",
- (level > LOG_LVL_USER) ? log_strings[level + 1] : "", string);
- }
+ string);
} else {
- /* Empty strings are sent to log callbacks to keep e.g. gdbserver alive, here we do
- *nothing. */
+ /* if we are using gdb through pipes then we do not want any output
+ * to the pipe otherwise we get repeated strings */
+ fprintf(log_output, "%s%s",
+ (level > LOG_LVL_USER) ? log_strings[level + 1] : "", string);
}
fflush(log_output);
@@ -440,8 +435,7 @@ static void gdb_timeout_warning(int64_t delta_time)
void keep_alive(void)
{
- current_time = timeval_ms();
-
+ int64_t current_time = timeval_ms();
int64_t delta_time = current_time - last_time;
if (delta_time > KEEP_ALIVE_TIMEOUT_MS) {
@@ -454,7 +448,7 @@ void keep_alive(void)
last_time = current_time;
/* this will keep the GDB connection alive */
- LOG_USER_N("%s", "");
+ server_keep_clients_alive();
/* DANGER!!!! do not add code to invoke e.g. target event processing,
* jim timer processing, etc. it can cause infinite recursion +
@@ -469,7 +463,7 @@ void keep_alive(void)
/* reset keep alive timer without sending message */
void kept_alive(void)
{
- current_time = timeval_ms();
+ int64_t current_time = timeval_ms();
int64_t delta_time = current_time - last_time;
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index e7562d0..63407be 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -48,6 +48,7 @@
#include <target/cortex_m.h>
#include "cmsis_dap.h"
+#include "libusb_helper.h"
static const struct cmsis_dap_backend *const cmsis_dap_backends[] = {
#if BUILD_CMSIS_DAP_USB == 1
@@ -79,8 +80,6 @@ static uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };
static int cmsis_dap_backend = -1;
static bool swd_mode;
-#define USB_TIMEOUT 1000
-
/* CMSIS-DAP General Commands */
#define CMD_DAP_INFO 0x00
#define CMD_DAP_LED 0x01
@@ -210,7 +209,7 @@ static bool swd_mode;
* None as yet... */
static const char * const info_caps_str[INFO_CAPS__NUM_CAPS] = {
- "SWD supported",
+ "SWD supported",
"JTAG supported",
"SWO-UART supported",
"SWO-MANCHESTER supported",
@@ -360,12 +359,12 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
}
uint8_t current_cmd = cmsis_dap_handle->command[0];
- int retval = dap->backend->write(dap, txlen, USB_TIMEOUT);
+ int retval = dap->backend->write(dap, txlen, LIBUSB_TIMEOUT_MS);
if (retval < 0)
return retval;
/* get reply */
- retval = dap->backend->read(dap, USB_TIMEOUT);
+ retval = dap->backend->read(dap, LIBUSB_TIMEOUT_MS);
if (retval < 0)
return retval;
@@ -826,7 +825,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
}
}
- int retval = dap->backend->write(dap, idx, USB_TIMEOUT);
+ int retval = dap->backend->write(dap, idx, LIBUSB_TIMEOUT_MS);
if (retval < 0) {
queued_retval = retval;
goto skip;
@@ -854,7 +853,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)
/* get reply */
int retval = dap->backend->read(dap, timeout_ms);
- if (retval == ERROR_TIMEOUT_REACHED && timeout_ms < USB_TIMEOUT)
+ if (retval == ERROR_TIMEOUT_REACHED && timeout_ms < LIBUSB_TIMEOUT_MS)
return;
if (retval <= 0) {
@@ -929,7 +928,7 @@ static int cmsis_dap_swd_run_queue(void)
cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
while (pending_fifo_block_count)
- cmsis_dap_swd_read_process(cmsis_dap_handle, USB_TIMEOUT);
+ cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS);
pending_fifo_put_idx = 0;
pending_fifo_get_idx = 0;
@@ -953,7 +952,7 @@ static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
cmsis_dap_swd_write_from_queue(cmsis_dap_handle);
if (pending_fifo_block_count >= cmsis_dap_handle->packet_count)
- cmsis_dap_swd_read_process(cmsis_dap_handle, USB_TIMEOUT);
+ cmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS);
}
if (queued_retval != ERROR_OK)
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index 0fc688e..eb53a5b 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -38,8 +38,8 @@
#define NO_TAP_SHIFT 0
#define TAP_SHIFT 1
-#define SERVER_ADDRESS "127.0.0.1"
-#define SERVER_PORT 5555
+#define DEFAULT_SERVER_ADDRESS "127.0.0.1"
+#define DEFAULT_SERVER_PORT 5555
#define XFERT_MAX_SIZE 512
@@ -50,7 +50,7 @@
#define CMD_STOP_SIMU 4
/* jtag_vpi server port and address to connect to */
-static int server_port = SERVER_PORT;
+static int server_port = DEFAULT_SERVER_PORT;
static char *server_address;
/* Send CMD_STOP_SIMU to server when OpenOCD exits? */
@@ -551,7 +551,7 @@ static int jtag_vpi_init(void)
serv_addr.sin_port = htons(server_port);
if (!server_address)
- server_address = strdup(SERVER_ADDRESS);
+ server_address = strdup(DEFAULT_SERVER_ADDRESS);
serv_addr.sin_addr.s_addr = inet_addr(server_address);
@@ -604,27 +604,28 @@ static int jtag_vpi_quit(void)
COMMAND_HANDLER(jtag_vpi_set_port)
{
- if (CMD_ARGC == 0)
- LOG_WARNING("You need to set a port number");
- else
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], server_port);
+ if (CMD_ARGC == 0) {
+ LOG_ERROR("Command \"jtag_vpi set_port\" expects 1 argument (TCP port number)");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
- LOG_INFO("Set server port to %u", server_port);
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], server_port);
+ LOG_INFO("jtag_vpi: server port set to %u", server_port);
return ERROR_OK;
}
COMMAND_HANDLER(jtag_vpi_set_address)
{
- free(server_address);
if (CMD_ARGC == 0) {
- LOG_WARNING("You need to set an address");
- server_address = strdup(SERVER_ADDRESS);
- } else
- server_address = strdup(CMD_ARGV[0]);
+ LOG_ERROR("Command \"jtag_vpi set_address\" expects 1 argument (IP address)");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
- LOG_INFO("Set server address to %s", server_address);
+ free(server_address);
+ server_address = strdup(CMD_ARGV[0]);
+ LOG_INFO("jtag_vpi: server address set to %s", server_address);
return ERROR_OK;
}
@@ -632,11 +633,11 @@ COMMAND_HANDLER(jtag_vpi_set_address)
COMMAND_HANDLER(jtag_vpi_stop_sim_on_exit_handler)
{
if (CMD_ARGC != 1) {
- LOG_ERROR("jtag_vpi_stop_sim_on_exit expects 1 argument (on|off)");
+ LOG_ERROR("Command \"jtag_vpi stop_sim_on_exit\" expects 1 argument (on|off)");
return ERROR_COMMAND_SYNTAX_ERROR;
- } else {
- COMMAND_PARSE_ON_OFF(CMD_ARGV[0], stop_sim_on_exit);
}
+
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], stop_sim_on_exit);
return ERROR_OK;
}
@@ -645,14 +646,14 @@ static const struct command_registration jtag_vpi_subcommand_handlers[] = {
.name = "set_port",
.handler = &jtag_vpi_set_port,
.mode = COMMAND_CONFIG,
- .help = "set the port of the VPI server",
+ .help = "set the TCP port number of the jtag_vpi server (default: 5555)",
.usage = "tcp_port_num",
},
{
.name = "set_address",
.handler = &jtag_vpi_set_address,
.mode = COMMAND_CONFIG,
- .help = "set the address of the VPI server",
+ .help = "set the IP address of the jtag_vpi server (default: 127.0.0.1)",
.usage = "ipv4_addr",
},
{
diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h
index 2ddb246..9d51464 100644
--- a/src/jtag/drivers/libusb_helper.h
+++ b/src/jtag/drivers/libusb_helper.h
@@ -22,6 +22,20 @@
#include <libusb.h>
+/* When we debug a target that works as a USB device, halting the target causes the
+ * USB communication with the USB host to become unresponsive. The host will try
+ * to reconnect/reset/setup the unresponsive device during which communication
+ * with other devices on the same USB bus can get stalled for several seconds.
+ * If the JTAG adapter is on the same bus, we need to make sure openOCD will wait
+ * for packets at least as long as the host USB stack. Otherwise the USB stack
+ * might deliver a valid packet, but openOCD would ignore it due to the timeout.
+ * The xHCI spec uses 5 sec timeouts, so let's use that in openOCD with some margin.
+ *
+ * Use this value in all libusb calls. HID API might have a libusb backend and
+ * would probably be victim to the same bug, so it should use this timeout, too.
+ */
+#define LIBUSB_TIMEOUT_MS (6000)
+
/* this callback should return a non NULL value only when the serial could not
* be retrieved by the standard 'libusb_get_string_descriptor_ascii' */
typedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *device,
diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c
index d4b8b53..84a4420 100644
--- a/src/jtag/drivers/nulink_usb.c
+++ b/src/jtag/drivers/nulink_usb.c
@@ -33,7 +33,9 @@
#include <hidapi.h>
-#define NULINK_READ_TIMEOUT 1000
+#include "libusb_helper.h"
+
+#define NULINK_READ_TIMEOUT LIBUSB_TIMEOUT_MS
#define NULINK_HID_MAX_SIZE (64)
#define NULINK2_HID_MAX_SIZE (1024)
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index 73be3c5..0cf9dbb 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -59,8 +59,6 @@
#define USB_EP2IN_SIZE (USB_EP2OUT_SIZE)
#define USB_EP2BANK_SIZE (512)
-#define USB_TIMEOUT_MS (3 * 1000)
-
#define DTC_STATUS_POLL_BYTE (ST7_USB_BUF_EP0OUT + 0xff)
#define ST7_PD_NBUSY_LED ST7_PD0
@@ -133,7 +131,7 @@ static int ep1_generic_commandl(struct libusb_device_handle *hdev_param, size_t
hdev_param,
USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -176,7 +174,7 @@ static ssize_t ep1_memory_read(
usb_ret = jtag_libusb_bulk_write(
hdev_param, USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -186,7 +184,7 @@ static ssize_t ep1_memory_read(
usb_ret = jtag_libusb_bulk_read(
hdev_param, USB_EP1IN_ADDR,
(char *)buffer, length,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -241,7 +239,7 @@ static ssize_t ep1_memory_write(struct libusb_device_handle *hdev_param, uint16_
usb_ret = jtag_libusb_bulk_write(
hdev_param, USB_EP1OUT_ADDR,
(char *)usb_buffer, sizeof(usb_buffer),
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -432,7 +430,7 @@ static int dtc_start_download(void)
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&ep2txr, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK)
@@ -462,7 +460,7 @@ static int dtc_start_download(void)
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&ep2txr, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -488,7 +486,7 @@ static int dtc_run_download(
hdev_param,
USB_EP2OUT_ADDR,
(char *)command_buffer, USB_EP2BANK_SIZE,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err < 0)
@@ -512,7 +510,7 @@ static int dtc_run_download(
hdev_param,
USB_EP1IN_ADDR,
&dtc_status, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err < 0)
@@ -533,7 +531,7 @@ static int dtc_run_download(
hdev_param,
USB_EP2IN_ADDR,
(char *)reply_buffer, reply_buffer_size,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -954,7 +952,7 @@ static void rlink_reset(int trst, int srst)
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&bitmap, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK || transferred < 1) {
@@ -990,7 +988,7 @@ static void rlink_reset(int trst, int srst)
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&bitmap, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK || transferred < 1) {
@@ -1021,7 +1019,7 @@ static void rlink_reset(int trst, int srst)
usb_err = jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)&bitmap, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
if (usb_err != ERROR_OK || transferred < 1) {
@@ -1576,7 +1574,7 @@ static int rlink_init(void)
jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)reply_buffer, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
@@ -1601,7 +1599,7 @@ static int rlink_init(void)
jtag_libusb_bulk_read(
hdev, USB_EP1IN_ADDR,
(char *)reply_buffer, 1,
- USB_TIMEOUT_MS,
+ LIBUSB_TIMEOUT_MS,
&transferred
);
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index 2f61bf9..2785d9b 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -71,8 +71,8 @@
#define ENDPOINT_IN 0x80
#define ENDPOINT_OUT 0x00
-#define STLINK_WRITE_TIMEOUT 1000
-#define STLINK_READ_TIMEOUT 1000
+#define STLINK_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS)
+#define STLINK_READ_TIMEOUT (LIBUSB_TIMEOUT_MS)
#define STLINK_RX_EP (1|ENDPOINT_IN)
#define STLINK_TX_EP (2|ENDPOINT_OUT)
@@ -156,6 +156,13 @@ struct stlink_usb_priv_s {
struct libusb_transfer *trans;
};
+struct stlink_tcp_version {
+ uint32_t api;
+ uint32_t major;
+ uint32_t minor;
+ uint32_t build;
+};
+
struct stlink_tcp_priv_s {
/** */
int fd;
@@ -169,6 +176,8 @@ struct stlink_tcp_priv_s {
uint8_t *send_buf;
/** */
uint8_t *recv_buf;
+ /** */
+ struct stlink_tcp_version version;
};
struct stlink_backend_s {
@@ -3532,16 +3541,19 @@ static int stlink_tcp_open(void *handle, struct hl_interface_param_s *param)
return ERROR_FAIL;
}
- uint32_t api_ver = le_to_h_u32(&h->tcp_backend_priv.recv_buf[0]);
- uint32_t ver_major = le_to_h_u32(&h->tcp_backend_priv.recv_buf[4]);
- uint32_t ver_minor = le_to_h_u32(&h->tcp_backend_priv.recv_buf[8]);
- uint32_t ver_build = le_to_h_u32(&h->tcp_backend_priv.recv_buf[12]);
+ h->tcp_backend_priv.version.api = le_to_h_u32(&h->tcp_backend_priv.recv_buf[0]);
+ h->tcp_backend_priv.version.major = le_to_h_u32(&h->tcp_backend_priv.recv_buf[4]);
+ h->tcp_backend_priv.version.minor = le_to_h_u32(&h->tcp_backend_priv.recv_buf[8]);
+ h->tcp_backend_priv.version.build = le_to_h_u32(&h->tcp_backend_priv.recv_buf[12]);
LOG_INFO("stlink-server API v%d, version %d.%d.%d",
- api_ver, ver_major, ver_minor, ver_build);
+ h->tcp_backend_priv.version.api,
+ h->tcp_backend_priv.version.major,
+ h->tcp_backend_priv.version.minor,
+ h->tcp_backend_priv.version.build);
/* in stlink-server API v1 sending more than 1428 bytes will cause stlink-server
* to crash in windows: select a safe default value (1K) */
- if (api_ver < 2)
+ if (h->tcp_backend_priv.version.api < 2)
h->max_mem_packet = (1 << 10);
/* refresh stlink list (re-enumerate) */
@@ -4468,11 +4480,12 @@ static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue *
if (!(h->version.flags & STLINK_F_HAS_RW_MISC))
return 0;
/*
- * RW_MISC sequence doesn't lock the st-link, so are not safe in shared mode.
+ * Before stlink-server API v3, RW_MISC sequence doesn't lock the st-link,
+ * so are not safe in shared mode.
* Don't use it with TCP backend to prevent any issue in case of sharing.
* This further degrades the performance, on top of TCP server overhead.
*/
- if (h->backend == &stlink_tcp_backend)
+ if (h->backend == &stlink_tcp_backend && h->tcp_backend_priv.version.api < 3)
return 0;
for (i = 0; i < len; i++) {
diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c
index c94a110..e48d0e2 100644
--- a/src/jtag/drivers/ti_icdi_usb.c
+++ b/src/jtag/drivers/ti_icdi_usb.c
@@ -37,8 +37,8 @@
#define ICDI_WRITE_ENDPOINT 0x02
#define ICDI_READ_ENDPOINT 0x83
-#define ICDI_WRITE_TIMEOUT 1000
-#define ICDI_READ_TIMEOUT 1000
+#define ICDI_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS)
+#define ICDI_READ_TIMEOUT (LIBUSB_TIMEOUT_MS)
#define ICDI_PACKET_SIZE 2048
#define PACKET_START "$"
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index 20a036a..50609a6 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -56,9 +56,6 @@
/** USB interface number */
#define USB_INTERFACE 0
-/** libusb timeout in ms */
-#define USB_TIMEOUT 5000
-
/** Delay (in microseconds) to wait while EZ-USB performs ReNumeration. */
#define ULINK_RENUMERATION_DELAY 1500000
@@ -335,7 +332,7 @@ static int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit)
ret = libusb_control_transfer(device->usb_device_handle,
(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
- REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, USB_TIMEOUT);
+ REQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, LIBUSB_TIMEOUT_MS);
/* usb_control_msg() returns the number of bytes transferred during the
* DATA stage of the control transfer - must be exactly 1 in this case! */
@@ -478,7 +475,7 @@ static int ulink_write_firmware_section(struct ulink *device,
ret = libusb_control_transfer(device->usb_device_handle,
(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),
REQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (unsigned char *)data_ptr,
- chunk_size, USB_TIMEOUT);
+ chunk_size, LIBUSB_TIMEOUT_MS);
if (ret != (int)chunk_size) {
/* Abort if libusb sent less data than requested */
@@ -662,7 +659,7 @@ static int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd)
if ((newsize_out > 64) || (newsize_in > 64)) {
/* New command does not fit. Execute all commands in queue before starting
* new queue with the current command as first entry. */
- ret = ulink_execute_queued_commands(device, USB_TIMEOUT);
+ ret = ulink_execute_queued_commands(device, LIBUSB_TIMEOUT_MS);
if (ret == ERROR_OK)
ret = ulink_post_process_queue(device);
@@ -1960,7 +1957,7 @@ static int ulink_execute_queue(void)
}
if (ulink_handle->commands_in_queue > 0) {
- ret = ulink_execute_queued_commands(ulink_handle, USB_TIMEOUT);
+ ret = ulink_execute_queued_commands(ulink_handle, LIBUSB_TIMEOUT_MS);
if (ret != ERROR_OK)
return ret;
diff --git a/src/rtos/chromium-ec.c b/src/rtos/chromium-ec.c
index 1c8f4e3..95a228d 100644
--- a/src/rtos/chromium-ec.c
+++ b/src/rtos/chromium-ec.c
@@ -7,6 +7,11 @@
* Chromium-EC RTOS Task Awareness
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <helper/bits.h>
#include <rtos/rtos.h>
#include <target/target.h>
#include <target/target_type.h>
@@ -16,7 +21,6 @@
#define CROS_EC_MAX_TASKS 32
#define CROS_EC_MAX_NAME 200
#define CROS_EC_IDLE_STRING "<< idle >>"
-#define BIT(x) (1 << (x))
struct chromium_ec_params {
const char *target_name;
diff --git a/src/rtt/rtt.c b/src/rtt/rtt.c
index bf3cca5..3da3cce 100644
--- a/src/rtt/rtt.c
+++ b/src/rtt/rtt.c
@@ -15,6 +15,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/rtt/tcl.c b/src/rtt/tcl.c
index f5abf2e..4a34d8b 100644
--- a/src/rtt/tcl.c
+++ b/src/rtt/tcl.c
@@ -15,6 +15,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <helper/log.h>
#include <target/rtt.h>
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 4db305c..07dfaec 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -61,6 +61,13 @@
* found in most modern embedded processors.
*/
+enum gdb_output_flag {
+ /* GDB doesn't accept 'O' packets */
+ GDB_OUTPUT_NO,
+ /* GDB accepts 'O' packets */
+ GDB_OUTPUT_ALL,
+};
+
struct target_desc_format {
char *tdesc;
uint32_t tdesc_length;
@@ -97,6 +104,8 @@ struct gdb_connection {
struct target_desc_format target_desc;
/* temporarily used for thread list support */
char *thread_list;
+ /* flag to mask the output from gdb_log_callback() */
+ enum gdb_output_flag output_flag;
};
#if 0
@@ -362,11 +371,13 @@ static int gdb_write(struct connection *connection, void *data, int len)
return ERROR_SERVER_REMOTE_CLOSED;
}
-static void gdb_log_incoming_packet(char *packet)
+static void gdb_log_incoming_packet(struct connection *connection, char *packet)
{
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
return;
+ struct target *target = get_target_from_connection(connection);
+
/* Avoid dumping non-printable characters to the terminal */
const unsigned packet_len = strlen(packet);
const char *nonprint = find_nonprint_char(packet, packet_len);
@@ -380,25 +391,31 @@ static void gdb_log_incoming_packet(char *packet)
if (packet_prefix_printable) {
const unsigned int prefix_len = colon - packet + 1; /* + 1 to include the ':' */
const unsigned int payload_len = packet_len - prefix_len;
- LOG_DEBUG("received packet: %.*s<binary-data-%u-bytes>", prefix_len, packet, payload_len);
+ LOG_TARGET_DEBUG(target, "received packet: %.*s<binary-data-%u-bytes>", prefix_len,
+ packet, payload_len);
} else {
- LOG_DEBUG("received packet: <binary-data-%u-bytes>", packet_len);
+ LOG_TARGET_DEBUG(target, "received packet: <binary-data-%u-bytes>", packet_len);
}
} else {
/* All chars printable, dump the packet as is */
- LOG_DEBUG("received packet: %s", packet);
+ LOG_TARGET_DEBUG(target, "received packet: %s", packet);
}
}
-static void gdb_log_outgoing_packet(char *packet_buf, unsigned int packet_len, unsigned char checksum)
+static void gdb_log_outgoing_packet(struct connection *connection, char *packet_buf,
+ unsigned int packet_len, unsigned char checksum)
{
if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
return;
+ struct target *target = get_target_from_connection(connection);
+
if (find_nonprint_char(packet_buf, packet_len))
- LOG_DEBUG("sending packet: $<binary-data-%u-bytes>#%2.2x", packet_len, checksum);
+ LOG_TARGET_DEBUG(target, "sending packet: $<binary-data-%u-bytes>#%2.2x",
+ packet_len, checksum);
else
- LOG_DEBUG("sending packet: $%.*s#%2.2x'", packet_len, packet_buf, checksum);
+ LOG_TARGET_DEBUG(target, "sending packet: $%.*s#%2.2x", packet_len, packet_buf,
+ checksum);
}
static int gdb_put_packet_inner(struct connection *connection,
@@ -443,7 +460,7 @@ static int gdb_put_packet_inner(struct connection *connection,
#endif
while (1) {
- gdb_log_outgoing_packet(buffer, len, my_checksum);
+ gdb_log_outgoing_packet(connection, buffer, len, my_checksum);
char local_buffer[1024];
local_buffer[0] = '$';
@@ -476,22 +493,27 @@ static int gdb_put_packet_inner(struct connection *connection,
if (retval != ERROR_OK)
return retval;
- if (reply == '+')
+ if (reply == '+') {
+ gdb_log_incoming_packet(connection, "+");
break;
- else if (reply == '-') {
+ } else if (reply == '-') {
/* Stop sending output packets for now */
- log_remove_callback(gdb_log_callback, connection);
+ gdb_con->output_flag = GDB_OUTPUT_NO;
+ gdb_log_incoming_packet(connection, "-");
LOG_WARNING("negative reply, retrying");
} else if (reply == 0x3) {
gdb_con->ctrl_c = true;
+ gdb_log_incoming_packet(connection, "<Ctrl-C>");
retval = gdb_get_char(connection, &reply);
if (retval != ERROR_OK)
return retval;
- if (reply == '+')
+ if (reply == '+') {
+ gdb_log_incoming_packet(connection, "+");
break;
- else if (reply == '-') {
+ } else if (reply == '-') {
/* Stop sending output packets for now */
- log_remove_callback(gdb_log_callback, connection);
+ gdb_con->output_flag = GDB_OUTPUT_NO;
+ gdb_log_incoming_packet(connection, "-");
LOG_WARNING("negative reply, retrying");
} else if (reply == '$') {
LOG_ERROR("GDB missing ack(1) - assumed good");
@@ -668,6 +690,7 @@ static int gdb_get_packet_inner(struct connection *connection,
case '$':
break;
case '+':
+ gdb_log_incoming_packet(connection, "+");
/* According to the GDB documentation
* (https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html):
* "gdb sends a final `+` acknowledgment of the stub's `OK`
@@ -685,9 +708,11 @@ static int gdb_get_packet_inner(struct connection *connection,
}
break;
case '-':
+ gdb_log_incoming_packet(connection, "-");
LOG_WARNING("negative acknowledgment, but no packet pending");
break;
case 0x3:
+ gdb_log_incoming_packet(connection, "<Ctrl-C>");
gdb_con->ctrl_c = true;
*len = 0;
return ERROR_OK;
@@ -937,7 +962,7 @@ static void gdb_frontend_halted(struct target *target, struct connection *connec
*/
if (gdb_connection->frontend_state == TARGET_RUNNING) {
/* stop forwarding log packets! */
- log_remove_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
/* check fileio first */
if (target_get_gdb_fileio_info(target, target->fileio_info) == ERROR_OK)
@@ -997,6 +1022,7 @@ static int gdb_new_connection(struct connection *connection)
gdb_connection->target_desc.tdesc = NULL;
gdb_connection->target_desc.tdesc_length = 0;
gdb_connection->thread_list = NULL;
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
/* send ACK to GDB for debug request */
gdb_write(connection, "+", 1);
@@ -1081,6 +1107,8 @@ static int gdb_new_connection(struct connection *connection)
* register callback to be informed about target events */
target_register_event_callback(gdb_target_callback_event_handler, connection);
+ log_add_callback(gdb_log_callback, connection);
+
return ERROR_OK;
}
@@ -2735,7 +2763,7 @@ static int gdb_query_packet(struct connection *connection,
LOG_DEBUG("qRcmd: %s", cmd);
/* We want to print all debug output to GDB connection */
- log_add_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_ALL;
target_call_timer_callbacks_now();
/* some commands need to know the GDB connection, make note of current
* GDB connection. */
@@ -2743,7 +2771,7 @@ static int gdb_query_packet(struct connection *connection,
command_run_line(cmd_ctx, cmd);
current_gdb_connection = NULL;
target_call_timer_callbacks_now();
- log_remove_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
free(cmd);
}
gdb_put_packet(connection, "OK", 2);
@@ -2924,7 +2952,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
if (parse[0] == 'c') {
gdb_running_type = 'c';
LOG_DEBUG("target %s continue", target_name(target));
- log_add_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_ALL;
retval = target_resume(target, 1, 0, 0, 0);
if (retval == ERROR_TARGET_NOT_HALTED)
LOG_INFO("target %s was not halted when resume was requested", target_name(target));
@@ -3028,7 +3056,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
}
LOG_DEBUG("target %s single-step thread %"PRIx64, target_name(ct), thread_id);
- log_add_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_ALL;
target_call_event_callbacks(ct, TARGET_EVENT_GDB_START);
if (fake_step) {
@@ -3045,7 +3073,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
"T05thread:%016"PRIx64";", thread_id);
gdb_put_packet(connection, sig_reply, sig_reply_len);
- log_remove_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
return true;
}
@@ -3057,7 +3085,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
LOG_DEBUG("stepi ignored. GDB will now fetch the register state "
"from the target.");
gdb_sig_halted(connection);
- log_remove_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
} else
gdb_connection->frontend_state = TARGET_RUNNING;
return true;
@@ -3075,7 +3103,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p
/* send back signal information */
gdb_signal_reply(ct, connection);
/* stop forwarding log packets! */
- log_remove_callback(gdb_log_callback, connection);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
} else
gdb_connection->frontend_state = TARGET_RUNNING;
} else {
@@ -3410,6 +3438,10 @@ static void gdb_log_callback(void *priv, const char *file, unsigned line,
struct connection *connection = priv;
struct gdb_connection *gdb_con = connection->priv;
+ if (gdb_con->output_flag == GDB_OUTPUT_NO)
+ /* No out allowed */
+ return;
+
if (gdb_con->busy) {
/* do not reply this using the O packet */
return;
@@ -3459,9 +3491,10 @@ static int gdb_input_inner(struct connection *connection)
/* terminate with zero */
gdb_packet_buffer[packet_size] = '\0';
- gdb_log_incoming_packet(gdb_packet_buffer);
-
if (packet_size > 0) {
+
+ gdb_log_incoming_packet(connection, gdb_packet_buffer);
+
retval = ERROR_OK;
switch (packet[0]) {
case 'T': /* Is thread alive? */
@@ -3512,7 +3545,7 @@ static int gdb_input_inner(struct connection *connection)
case 's':
{
gdb_thread_packet(connection, packet, packet_size);
- log_add_callback(gdb_log_callback, connection);
+ gdb_con->output_flag = GDB_OUTPUT_ALL;
if (gdb_con->mem_write_error) {
LOG_ERROR("Memory write failure!");
@@ -3555,7 +3588,7 @@ static int gdb_input_inner(struct connection *connection)
gdb_sig_halted(connection);
/* stop forwarding log packets! */
- log_remove_callback(gdb_log_callback, connection);
+ gdb_con->output_flag = GDB_OUTPUT_NO;
} else {
/* We're running/stepping, in which case we can
* forward log output until the target is halted
@@ -3627,7 +3660,7 @@ static int gdb_input_inner(struct connection *connection)
* Fretcode,errno,Ctrl-C flag;call-specific attachment
*/
gdb_con->frontend_state = TARGET_RUNNING;
- log_add_callback(gdb_log_callback, connection);
+ gdb_con->output_flag = GDB_OUTPUT_ALL;
gdb_fileio_response_packet(connection, packet, packet_size);
break;
@@ -3680,6 +3713,37 @@ static int gdb_input(struct connection *connection)
return ERROR_OK;
}
+static void gdb_keep_client_alive(struct connection *connection)
+{
+ struct gdb_connection *gdb_con = connection->priv;
+
+ if (gdb_con->busy) {
+ /* do not send packets, retry asap */
+ return;
+ }
+
+ switch (gdb_con->output_flag) {
+ case GDB_OUTPUT_NO:
+ /* no need for keep-alive */
+ break;
+ case GDB_OUTPUT_ALL:
+ /* send an empty O packet */
+ gdb_output_con(connection, "");
+ break;
+ default:
+ break;
+ }
+}
+
+static const struct service_driver gdb_service_driver = {
+ .name = "gdb",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = gdb_new_connection,
+ .input_handler = gdb_input,
+ .connection_closed_handler = gdb_connection_closed,
+ .keep_client_alive_handler = gdb_keep_client_alive,
+};
+
static int gdb_target_start(struct target *target, const char *port)
{
struct gdb_service *gdb_service;
@@ -3696,9 +3760,7 @@ static int gdb_target_start(struct target *target, const char *port)
gdb_service->core[1] = -1;
target->gdb_service = gdb_service;
- ret = add_service("gdb",
- port, target->gdb_max_connections, &gdb_new_connection, &gdb_input,
- &gdb_connection_closed, gdb_service);
+ ret = add_service(&gdb_service_driver, port, target->gdb_max_connections, gdb_service);
/* initialize all targets gdb service with the same pointer */
{
struct target_list *head;
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index ec2fae8..3bbcf07 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -587,6 +587,15 @@ static int ipdbg_on_connection_closed(struct connection *connection)
return ipdbg_stop_polling(connection->service->priv);
}
+static const struct service_driver ipdbg_service_driver = {
+ .name = "ipdbg",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = ipdbg_on_new_connection,
+ .input_handler = ipdbg_on_connection_input,
+ .connection_closed_handler = ipdbg_on_connection_closed,
+ .keep_client_alive_handler = NULL,
+};
+
static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instruction,
uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)
{
@@ -618,8 +627,7 @@ static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instru
char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];
snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port);
- retval = add_service("ipdbg", port_str_buffer, 1, &ipdbg_on_new_connection,
- &ipdbg_on_connection_input, &ipdbg_on_connection_closed, service);
+ retval = add_service(&ipdbg_service_driver, port_str_buffer, 1, service);
if (retval == ERROR_OK) {
ipdbg_add_service(service);
if (hub->active_services == 0 && hub->active_connections == 0)
diff --git a/src/server/rtt_server.c b/src/server/rtt_server.c
index d49e4d0..3850c26 100644
--- a/src/server/rtt_server.c
+++ b/src/server/rtt_server.c
@@ -15,6 +15,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdint.h>
#include <rtt/rtt.h>
@@ -110,6 +114,15 @@ static int rtt_input(struct connection *connection)
return ERROR_OK;
}
+static const struct service_driver rtt_service_driver = {
+ .name = "rtt",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = rtt_new_connection,
+ .input_handler = rtt_input,
+ .connection_closed_handler = rtt_connection_closed,
+ .keep_client_alive_handler = NULL,
+};
+
COMMAND_HANDLER(handle_rtt_start_command)
{
int ret;
@@ -125,8 +138,7 @@ COMMAND_HANDLER(handle_rtt_start_command)
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);
- ret = add_service("rtt", CMD_ARGV[0], CONNECTION_LIMIT_UNLIMITED,
- rtt_new_connection, rtt_input, rtt_connection_closed, service);
+ ret = add_service(&rtt_service_driver, CMD_ARGV[0], CONNECTION_LIMIT_UNLIMITED, service);
if (ret != ERROR_OK) {
free(service);
diff --git a/src/server/server.c b/src/server/server.c
index 1569f5a..7b0004d 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -205,13 +205,8 @@ static void free_service(struct service *c)
free(c);
}
-int add_service(char *name,
- const char *port,
- int max_connections,
- new_connection_handler_t new_connection_handler,
- input_handler_t input_handler,
- connection_closed_handler_t connection_closed_handler,
- void *priv)
+int add_service(const struct service_driver *driver, const char *port,
+ int max_connections, void *priv)
{
struct service *c, **p;
struct hostent *hp;
@@ -219,14 +214,16 @@ int add_service(char *name,
c = malloc(sizeof(struct service));
- c->name = strdup(name);
+ c->name = strdup(driver->name);
c->port = strdup(port);
c->max_connections = 1; /* Only TCP/IP ports can support more than one connection */
c->fd = -1;
c->connections = NULL;
- c->new_connection = new_connection_handler;
- c->input = input_handler;
- c->connection_closed = connection_closed_handler;
+ c->new_connection_during_keep_alive = driver->new_connection_during_keep_alive_handler;
+ c->new_connection = driver->new_connection_handler;
+ c->input = driver->input_handler;
+ c->connection_closed = driver->connection_closed_handler;
+ c->keep_client_alive = driver->keep_client_alive_handler;
c->priv = priv;
c->next = NULL;
long portnumber;
@@ -278,7 +275,7 @@ int add_service(char *name,
c->sin.sin_port = htons(c->portnumber);
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
- LOG_ERROR("couldn't bind %s to socket on port %d: %s", name, c->portnumber, strerror(errno));
+ LOG_ERROR("couldn't bind %s to socket on port %d: %s", c->name, c->portnumber, strerror(errno));
close_socket(c->fd);
free_service(c);
return ERROR_FAIL;
@@ -309,7 +306,7 @@ int add_service(char *name,
socklen_t addr_in_size = sizeof(addr_in);
if (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)
LOG_INFO("Listening on port %hu for %s connections",
- ntohs(addr_in.sin_port), name);
+ ntohs(addr_in.sin_port), c->name);
} else if (c->type == CONNECTION_STDINOUT) {
c->fd = fileno(stdin);
@@ -424,6 +421,14 @@ static int remove_services(void)
return ERROR_OK;
}
+void server_keep_clients_alive(void)
+{
+ for (struct service *s = services; s; s = s->next)
+ if (s->keep_client_alive)
+ for (struct connection *c = s->connections; c; c = c->next)
+ s->keep_client_alive(c);
+}
+
int server_loop(struct command_context *command_context)
{
struct service *service;
diff --git a/src/server/server.h b/src/server/server.h
index bacd111..a6b1963 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -55,9 +55,25 @@ struct connection {
struct connection *next;
};
-typedef int (*new_connection_handler_t)(struct connection *connection);
-typedef int (*input_handler_t)(struct connection *connection);
-typedef int (*connection_closed_handler_t)(struct connection *connection);
+struct service_driver {
+ /** the name of the server */
+ const char *name;
+ /** optional minimal setup to accept a connection during keep-alive */
+ int (*new_connection_during_keep_alive_handler)(struct connection *connection);
+ /**
+ * complete code to accept a new connection.
+ * If 'new_connection_during_keep_alive_handler' above is present, this can be
+ * either called alone during the server_loop, or after the function above.
+ * Check the implementation in gdb_server.
+ * */
+ int (*new_connection_handler)(struct connection *connection);
+ /** callback to handle incoming data */
+ int (*input_handler)(struct connection *connection);
+ /** callback to tear down the connection */
+ int (*connection_closed_handler)(struct connection *connection);
+ /** called periodically to send keep-alive messages on the connection */
+ void (*keep_client_alive_handler)(struct connection *connection);
+};
struct service {
char *name;
@@ -68,17 +84,17 @@ struct service {
struct sockaddr_in sin;
int max_connections;
struct connection *connections;
- new_connection_handler_t new_connection;
- input_handler_t input;
- connection_closed_handler_t connection_closed;
+ int (*new_connection_during_keep_alive)(struct connection *connection);
+ int (*new_connection)(struct connection *connection);
+ int (*input)(struct connection *connection);
+ int (*connection_closed)(struct connection *connection);
+ void (*keep_client_alive)(struct connection *connection);
void *priv;
struct service *next;
};
-int add_service(char *name, const char *port,
- int max_connections, new_connection_handler_t new_connection_handler,
- input_handler_t in_handler, connection_closed_handler_t close_handler,
- void *priv);
+int add_service(const struct service_driver *driver, const char *port,
+ int max_connections, void *priv);
int remove_service(const char *name, const char *port);
int server_host_os_entry(void);
@@ -90,6 +106,8 @@ int server_quit(void);
void server_free(void);
void exit_on_signal(int sig);
+void server_keep_clients_alive(void);
+
int server_loop(struct command_context *command_context);
int server_register_commands(struct command_context *context);
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index e088232..458d7ea 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -276,6 +276,15 @@ static int tcl_closed(struct connection *connection)
return ERROR_OK;
}
+static const struct service_driver tcl_service_driver = {
+ .name = "tcl",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = tcl_new_connection,
+ .input_handler = tcl_input,
+ .connection_closed_handler = tcl_closed,
+ .keep_client_alive_handler = NULL,
+};
+
int tcl_init(void)
{
if (strcmp(tcl_port, "disabled") == 0) {
@@ -283,9 +292,7 @@ int tcl_init(void)
return ERROR_OK;
}
- return add_service("tcl", tcl_port, CONNECTION_LIMIT_UNLIMITED,
- &tcl_new_connection, &tcl_input,
- &tcl_closed, NULL);
+ return add_service(&tcl_service_driver, tcl_port, CONNECTION_LIMIT_UNLIMITED, NULL);
}
COMMAND_HANDLER(handle_tcl_port_command)
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 2ebcff1..791a1a5 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -946,6 +946,15 @@ static int telnet_connection_closed(struct connection *connection)
return ERROR_OK;
}
+static const struct service_driver telnet_service_driver = {
+ .name = "telnet",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = telnet_new_connection,
+ .input_handler = telnet_input,
+ .connection_closed_handler = telnet_connection_closed,
+ .keep_client_alive_handler = NULL,
+};
+
int telnet_init(char *banner)
{
if (strcmp(telnet_port, "disabled") == 0) {
@@ -963,8 +972,7 @@ int telnet_init(char *banner)
telnet_service->banner = banner;
- int ret = add_service("telnet", telnet_port, CONNECTION_LIMIT_UNLIMITED,
- telnet_new_connection, telnet_input, telnet_connection_closed,
+ int ret = add_service(&telnet_service_driver, telnet_port, CONNECTION_LIMIT_UNLIMITED,
telnet_service);
if (ret != ERROR_OK) {
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index a45322d..8838da9 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1236,7 +1236,7 @@ static int aarch64_set_breakpoint(struct target *target,
struct armv8_common *armv8 = &aarch64->armv8_common;
struct aarch64_brp *brp_list = aarch64->brp_list;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -1249,7 +1249,7 @@ static int aarch64_set_breakpoint(struct target *target,
LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = brp_i + 1;
+ breakpoint_hw_set(breakpoint, brp_i);
if (breakpoint->length == 2)
byte_addr_select = (3 << (breakpoint->address & 0x02));
control = ((matchmode & 0x7) << 20)
@@ -1333,7 +1333,7 @@ static int aarch64_set_breakpoint(struct target *target,
breakpoint->address & 0xFFFFFFFFFFFFFFFE,
breakpoint->length);
- breakpoint->set = 0x11; /* Any nice value but 0 */
+ breakpoint->is_set = true;
}
/* Ensure that halting debug mode is enable */
@@ -1357,7 +1357,7 @@ static int aarch64_set_context_breakpoint(struct target *target,
struct armv8_common *armv8 = &aarch64->armv8_common;
struct aarch64_brp *brp_list = aarch64->brp_list;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return retval;
}
@@ -1371,7 +1371,7 @@ static int aarch64_set_context_breakpoint(struct target *target,
return ERROR_FAIL;
}
- breakpoint->set = brp_i + 1;
+ breakpoint_hw_set(breakpoint, brp_i);
control = ((matchmode & 0x7) << 20)
| (1 << 13)
| (byte_addr_select << 5)
@@ -1410,7 +1410,7 @@ static int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoin
struct armv8_common *armv8 = &aarch64->armv8_common;
struct aarch64_brp *brp_list = aarch64->brp_list;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return retval;
}
@@ -1435,7 +1435,7 @@ static int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoin
return ERROR_FAIL;
}
- breakpoint->set = brp_1 + 1;
+ breakpoint_hw_set(breakpoint, brp_1);
breakpoint->linked_brp = brp_2;
control_ctx = ((ctx_machmode & 0x7) << 20)
| (brp_2 << 16)
@@ -1490,16 +1490,16 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
struct armv8_common *armv8 = &aarch64->armv8_common;
struct aarch64_brp *brp_list = aarch64->brp_list;
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
- int brp_i = breakpoint->set - 1;
+ int brp_i = breakpoint->number;
int brp_j = breakpoint->linked_brp;
- if ((brp_i < 0) || (brp_i >= aarch64->brp_num)) {
+ if (brp_i >= aarch64->brp_num) {
LOG_DEBUG("Invalid BRP number in breakpoint");
return ERROR_OK;
}
@@ -1549,12 +1549,12 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
return retval;
breakpoint->linked_brp = 0;
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
} else {
- int brp_i = breakpoint->set - 1;
- if ((brp_i < 0) || (brp_i >= aarch64->brp_num)) {
+ int brp_i = breakpoint->number;
+ if (brp_i >= aarch64->brp_num) {
LOG_DEBUG("Invalid BRP number in breakpoint");
return ERROR_OK;
}
@@ -1579,7 +1579,7 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
(uint32_t)brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
} else {
@@ -1611,7 +1611,7 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
breakpoint->address & 0xFFFFFFFFFFFFFFFE,
breakpoint->length);
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -1676,7 +1676,7 @@ static int aarch64_remove_breakpoint(struct target *target, struct breakpoint *b
}
#endif
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
aarch64_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
aarch64->brp_num_available++;
@@ -1696,7 +1696,7 @@ static int aarch64_set_watchpoint(struct target *target,
struct armv8_common *armv8 = &aarch64->armv8_common;
struct aarch64_brp *wp_list = aarch64->wp_list;
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}
@@ -1764,7 +1764,7 @@ static int aarch64_set_watchpoint(struct target *target,
}
wp_list[wp_i].used = 1;
- watchpoint->set = wp_i + 1;
+ watchpoint_set(watchpoint, wp_i);
return ERROR_OK;
}
@@ -1773,18 +1773,18 @@ static int aarch64_set_watchpoint(struct target *target,
static int aarch64_unset_watchpoint(struct target *target,
struct watchpoint *watchpoint)
{
- int retval, wp_i;
+ int retval;
struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = &aarch64->armv8_common;
struct aarch64_brp *wp_list = aarch64->wp_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- wp_i = watchpoint->set - 1;
- if ((wp_i < 0) || (wp_i >= aarch64->wp_num)) {
+ int wp_i = watchpoint->number;
+ if (wp_i >= aarch64->wp_num) {
LOG_DEBUG("Invalid WP number in watchpoint");
return ERROR_OK;
}
@@ -1809,7 +1809,7 @@ static int aarch64_unset_watchpoint(struct target *target,
(uint32_t)wp_list[wp_i].value);
if (retval != ERROR_OK)
return retval;
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -1837,7 +1837,7 @@ static int aarch64_remove_watchpoint(struct target *target,
{
struct aarch64_common *aarch64 = target_to_aarch64(target);
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
aarch64_unset_watchpoint(target, watchpoint);
aarch64->wp_num_available++;
}
diff --git a/src/target/arc.c b/src/target/arc.c
index 4b546c3..471f16a 100644
--- a/src/target/arc.c
+++ b/src/target/arc.c
@@ -1500,7 +1500,7 @@ static int arc_configure_actionpoint(struct target *target, uint32_t ap_num,
static int arc_set_breakpoint(struct target *target,
struct breakpoint *breakpoint)
{
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -1542,7 +1542,7 @@ static int arc_set_breakpoint(struct target *target,
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- breakpoint->set = 64; /* Any nice value but 0 */
+ breakpoint->is_set = true;
} else if (breakpoint->type == BKPT_HARD) {
struct arc_common *arc = target_to_arc(target);
struct arc_actionpoint *ap_list = arc->actionpoints_list;
@@ -1563,7 +1563,7 @@ static int arc_set_breakpoint(struct target *target,
breakpoint->address, AP_AC_TT_READWRITE, AP_AC_AT_INST_ADDR);
if (retval == ERROR_OK) {
- breakpoint->set = bp_num + 1;
+ breakpoint_hw_set(breakpoint, bp_num);
ap_list[bp_num].used = 1;
ap_list[bp_num].bp_value = breakpoint->address;
ap_list[bp_num].type = ARC_AP_BREAKPOINT;
@@ -1588,7 +1588,7 @@ static int arc_unset_breakpoint(struct target *target,
{
int retval = ERROR_OK;
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
@@ -1633,14 +1633,14 @@ static int arc_unset_breakpoint(struct target *target,
LOG_ERROR("Invalid breakpoint length: target supports only 2 or 4");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
} else if (breakpoint->type == BKPT_HARD) {
struct arc_common *arc = target_to_arc(target);
struct arc_actionpoint *ap_list = arc->actionpoints_list;
- unsigned int bp_num = breakpoint->set - 1;
+ unsigned int bp_num = breakpoint->number;
- if ((breakpoint->set == 0) || (bp_num >= arc->actionpoints_num)) {
+ if (bp_num >= arc->actionpoints_num) {
LOG_DEBUG("Invalid actionpoint ID: %u in breakpoint: %" PRIu32,
bp_num, breakpoint->unique_id);
return ERROR_OK;
@@ -1650,11 +1650,11 @@ static int arc_unset_breakpoint(struct target *target,
breakpoint->address, AP_AC_TT_DISABLE, AP_AC_AT_INST_ADDR);
if (retval == ERROR_OK) {
- breakpoint->set = 0;
+ breakpoint->is_set = false;
ap_list[bp_num].used = 0;
ap_list[bp_num].bp_value = 0;
- LOG_DEBUG("bpid: %" PRIu32 " - released actionpoint ID: %i",
+ LOG_DEBUG("bpid: %" PRIu32 " - released actionpoint ID: %u",
breakpoint->unique_id, bp_num);
}
} else {
@@ -1684,7 +1684,7 @@ static int arc_remove_breakpoint(struct target *target,
struct breakpoint *breakpoint)
{
if (target->state == TARGET_HALTED) {
- if (breakpoint->set)
+ if (breakpoint->is_set)
CHECK_RETVAL(arc_unset_breakpoint(target, breakpoint));
} else {
LOG_WARNING("target not halted");
@@ -1818,7 +1818,7 @@ static int arc_set_watchpoint(struct target *target,
struct arc_common *arc = target_to_arc(target);
struct arc_actionpoint *ap_list = arc->actionpoints_list;
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}
@@ -1859,7 +1859,7 @@ static int arc_set_watchpoint(struct target *target,
watchpoint->address, enable, AP_AC_AT_MEMORY_ADDR);
if (retval == ERROR_OK) {
- watchpoint->set = wp_num + 1;
+ watchpoint_set(watchpoint, wp_num);
ap_list[wp_num].used = 1;
ap_list[wp_num].bp_value = watchpoint->address;
ap_list[wp_num].type = ARC_AP_WATCHPOINT;
@@ -1878,13 +1878,13 @@ static int arc_unset_watchpoint(struct target *target,
struct arc_common *arc = target_to_arc(target);
struct arc_actionpoint *ap_list = arc->actionpoints_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- unsigned int wp_num = watchpoint->set - 1;
- if ((watchpoint->set == 0) || (wp_num >= arc->actionpoints_num)) {
+ unsigned int wp_num = watchpoint->number;
+ if (wp_num >= arc->actionpoints_num) {
LOG_DEBUG("Invalid actionpoint ID: %u in watchpoint: %" PRIu32,
wp_num, watchpoint->unique_id);
return ERROR_OK;
@@ -1894,7 +1894,7 @@ static int arc_unset_watchpoint(struct target *target,
watchpoint->address, AP_AC_TT_DISABLE, AP_AC_AT_MEMORY_ADDR);
if (retval == ERROR_OK) {
- watchpoint->set = 0;
+ watchpoint->is_set = false;
ap_list[wp_num].used = 0;
ap_list[wp_num].bp_value = 0;
@@ -1926,7 +1926,7 @@ static int arc_remove_watchpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
CHECK_RETVAL(arc_unset_watchpoint(target, watchpoint));
return ERROR_OK;
@@ -1953,8 +1953,8 @@ static int arc_hit_watchpoint(struct target *target, struct watchpoint **hit_wat
watchpoint = watchpoint->next) {
if (actionpoint->bp_value == watchpoint->address) {
*hit_watchpoint = watchpoint;
- LOG_DEBUG("Hit watchpoint, wpid: %" PRIu32 ", watchpoint num: %i",
- watchpoint->unique_id, watchpoint->set - 1);
+ LOG_DEBUG("Hit watchpoint, wpid: %" PRIu32 ", watchpoint num: %u",
+ watchpoint->unique_id, watchpoint->number);
return ERROR_OK;
}
}
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index cf77a81..da047c3 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -93,19 +93,20 @@ static void arm7_9_assign_wp(struct arm7_9_common *arm7_9, struct breakpoint *br
{
if (!arm7_9->wp0_used) {
arm7_9->wp0_used = 1;
- breakpoint->set = 1;
+ breakpoint_hw_set(breakpoint, 0);
arm7_9->wp_available--;
} else if (!arm7_9->wp1_used) {
arm7_9->wp1_used = 1;
- breakpoint->set = 2;
+ breakpoint_hw_set(breakpoint, 1);
arm7_9->wp_available--;
- } else
+ } else {
LOG_ERROR("BUG: no hardware comparator available");
+ }
- LOG_DEBUG("BPID: %" PRIu32 " (0x%08" TARGET_PRIxADDR ") using hw wp: %d",
+ LOG_DEBUG("BPID: %" PRIu32 " (0x%08" TARGET_PRIxADDR ") using hw wp: %u",
breakpoint->unique_id,
breakpoint->address,
- breakpoint->set);
+ breakpoint->number);
}
/**
@@ -203,16 +204,16 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break
uint32_t mask = (breakpoint->length == 4) ? 0x3u : 0x1u;
/* reassign a hw breakpoint */
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
arm7_9_assign_wp(arm7_9, breakpoint);
- if (breakpoint->set == 1) {
+ if (breakpoint->number == 0) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], breakpoint->address);
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffffu);
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_NOPC & 0xff);
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);
- } else if (breakpoint->set == 2) {
+ } else if (breakpoint->number == 1) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], breakpoint->address);
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffffu);
@@ -226,7 +227,7 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break
retval = jtag_execute_queue();
} else if (breakpoint->type == BKPT_SOFT) {
/* did we already set this breakpoint? */
- if (breakpoint->set)
+ if (breakpoint->is_set)
return ERROR_OK;
if (breakpoint->length == 4) {
@@ -277,7 +278,7 @@ static int arm7_9_set_breakpoint(struct target *target, struct breakpoint *break
arm7_9->sw_breakpoint_count++;
- breakpoint->set = 1;
+ breakpoint->is_set = true;
}
return retval;
@@ -304,7 +305,7 @@ static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *bre
breakpoint->unique_id,
breakpoint->address);
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
@@ -312,18 +313,18 @@ static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *bre
if (breakpoint->type == BKPT_HARD) {
LOG_DEBUG("BPID: %" PRIu32 " Releasing hw wp: %d",
breakpoint->unique_id,
- breakpoint->set);
- if (breakpoint->set == 1) {
+ breakpoint->is_set);
+ if (breakpoint->number == 0) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
arm7_9->wp0_used = 0;
arm7_9->wp_available++;
- } else if (breakpoint->set == 2) {
+ } else if (breakpoint->number == 1) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
arm7_9->wp1_used = 0;
arm7_9->wp_available++;
}
retval = jtag_execute_queue();
- breakpoint->set = 0;
+ breakpoint->is_set = false;
} else {
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4) {
@@ -368,7 +369,7 @@ static int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *bre
EICE_W1_CONTROL_VALUE], 0);
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
}
return retval;
@@ -491,7 +492,7 @@ static int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watch
retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval;
- watchpoint->set = 1;
+ watchpoint_set(watchpoint, 1);
arm7_9->wp0_used = 2;
} else if (!arm7_9->wp1_used) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE],
@@ -510,7 +511,7 @@ static int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watch
retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval;
- watchpoint->set = 2;
+ watchpoint_set(watchpoint, 2);
arm7_9->wp1_used = 2;
} else {
LOG_ERROR("BUG: no hardware comparator available");
@@ -538,25 +539,25 @@ static int arm7_9_unset_watchpoint(struct target *target, struct watchpoint *wat
return ERROR_TARGET_NOT_HALTED;
}
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
- if (watchpoint->set == 1) {
+ if (watchpoint->number == 1) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);
retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval;
arm7_9->wp0_used = 0;
- } else if (watchpoint->set == 2) {
+ } else if (watchpoint->number == 2) {
embeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);
retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval;
arm7_9->wp1_used = 0;
}
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -597,7 +598,7 @@ int arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoin
int retval = ERROR_OK;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
retval = arm7_9_unset_watchpoint(target, watchpoint);
if (retval != ERROR_OK)
return retval;
@@ -1684,7 +1685,7 @@ static void arm7_9_enable_watchpoints(struct target *target)
struct watchpoint *watchpoint = target->watchpoints;
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
arm7_9_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c
index 3e55e2e..e60ef22 100644
--- a/src/target/arm_dpm.c
+++ b/src/target/arm_dpm.c
@@ -398,7 +398,7 @@ fail:
* or running debugger code.
*/
static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
- struct dpm_bpwp *xp, int *set_p)
+ struct dpm_bpwp *xp, bool *set_p)
{
int retval = ERROR_OK;
bool disable;
@@ -473,7 +473,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
struct breakpoint *bp = dbp->bp;
retval = dpm_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,
- bp ? &bp->set : NULL);
+ bp ? &bp->is_set : NULL);
if (retval != ERROR_OK)
goto done;
}
@@ -485,7 +485,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
struct watchpoint *wp = dwp->wp;
retval = dpm_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,
- wp ? &wp->set : NULL);
+ wp ? &wp->is_set : NULL);
if (retval != ERROR_OK)
goto done;
}
diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c
index 0245213..fba3fec 100644
--- a/src/target/arm_tpiu_swo.c
+++ b/src/target/arm_tpiu_swo.c
@@ -582,6 +582,15 @@ static int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap,
return mem_ap_read_atomic_u32(tpiu_ap, address, value);
}
+static const struct service_driver arm_tpiu_swo_service_driver = {
+ .name = "tpiu_swo_trace",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = arm_tpiu_swo_service_new_connection,
+ .input_handler = arm_tpiu_swo_service_input,
+ .connection_closed_handler = arm_tpiu_swo_service_connection_closed,
+ .keep_client_alive_handler = NULL,
+};
+
static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct command *c = jim_to_command(interp);
@@ -616,10 +625,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
}
if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
- if (!obj->swo_pin_freq) {
- LOG_ERROR("SWO pin frequency not set");
- return JIM_ERR;
- }
+ if (!obj->swo_pin_freq)
+ LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter");
struct target *target = get_current_target(cmd_ctx);
@@ -700,10 +707,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
}
priv->obj = obj;
LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]);
- retval = add_service("tpiu_swo_trace", &obj->out_filename[1],
- CONNECTION_LIMIT_UNLIMITED, arm_tpiu_swo_service_new_connection,
- arm_tpiu_swo_service_input, arm_tpiu_swo_service_connection_closed,
- priv);
+ retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1],
+ CONNECTION_LIMIT_UNLIMITED, priv);
if (retval != ERROR_OK) {
LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]);
return JIM_ERR;
@@ -724,6 +729,17 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
return JIM_ERR;
}
+ if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
+ if (!swo_pin_freq) {
+ if (obj->swo_pin_freq)
+ LOG_ERROR("Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq);
+ else
+ LOG_ERROR("Adapter does not support auto-detection of SWO pin frequency nor a default value");
+
+ arm_tpiu_swo_close_output(obj);
+ return JIM_ERR;
+ }
+
if (obj->swo_pin_freq != swo_pin_freq)
LOG_INFO("SWO pin data rate adjusted by adapter to %d Hz", swo_pin_freq);
obj->swo_pin_freq = swo_pin_freq;
@@ -886,7 +902,8 @@ static int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *o
/* does this command exist? */
cmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, obj->name, -1), JIM_NONE);
if (cmd) {
- Jim_SetResultFormatted(interp, "Command: %s Exists", obj->name);
+ Jim_SetResultFormatted(interp, "cannot create TPIU object because a command with name '%s' already exists",
+ obj->name);
return JIM_ERR;
}
@@ -915,7 +932,7 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const
struct jim_getopt_info goi;
jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
if (goi.argc < 1) {
- Jim_WrongNumArgs(goi.interp, 1, goi.argv, "?name? ..options...");
+ Jim_WrongNumArgs(interp, 1, argv, "name ?option option ...?");
return JIM_ERR;
}
@@ -1160,7 +1177,7 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = {
.name = "create",
.mode = COMMAND_ANY,
.jim_handler = jim_arm_tpiu_swo_create,
- .usage = "name [-dap dap] [-ap-num num] [-address baseaddr]",
+ .usage = "name [-dap dap] [-ap-num num] [-baseaddr baseaddr]",
.help = "Creates a new TPIU or SWO object",
},
{
diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c
index 188e588..765f1b7 100644
--- a/src/target/armv8_dpm.c
+++ b/src/target/armv8_dpm.c
@@ -818,7 +818,7 @@ fail:
* or running debugger code.
*/
static int dpmv8_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
- struct dpm_bpwp *xp, int *set_p)
+ struct dpm_bpwp *xp, bool *set_p)
{
int retval = ERROR_OK;
bool disable;
@@ -892,7 +892,7 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
struct breakpoint *bp = dbp->bp;
retval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,
- bp ? &bp->set : NULL);
+ bp ? &bp->is_set : NULL);
if (retval != ERROR_OK)
goto done;
}
@@ -904,7 +904,7 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
struct watchpoint *wp = dwp->wp;
retval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,
- wp ? &wp->set : NULL);
+ wp ? &wp->is_set : NULL);
if (retval != ERROR_OK)
goto done;
}
diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c
index 44c7a2c..3bfdbde 100644
--- a/src/target/breakpoints.c
+++ b/src/target/breakpoints.c
@@ -72,7 +72,7 @@ static int breakpoint_add_internal(struct target *target,
(*breakpoint_p)->asid = 0;
(*breakpoint_p)->length = length;
(*breakpoint_p)->type = type;
- (*breakpoint_p)->set = 0;
+ (*breakpoint_p)->is_set = false;
(*breakpoint_p)->orig_instr = malloc(length);
(*breakpoint_p)->next = NULL;
(*breakpoint_p)->unique_id = bpwp_unique_id++;
@@ -135,7 +135,7 @@ static int context_breakpoint_add_internal(struct target *target,
(*breakpoint_p)->asid = asid;
(*breakpoint_p)->length = length;
(*breakpoint_p)->type = type;
- (*breakpoint_p)->set = 0;
+ (*breakpoint_p)->is_set = false;
(*breakpoint_p)->orig_instr = malloc(length);
(*breakpoint_p)->next = NULL;
(*breakpoint_p)->unique_id = bpwp_unique_id++;
@@ -189,7 +189,7 @@ static int hybrid_breakpoint_add_internal(struct target *target,
(*breakpoint_p)->asid = asid;
(*breakpoint_p)->length = length;
(*breakpoint_p)->type = type;
- (*breakpoint_p)->set = 0;
+ (*breakpoint_p)->is_set = false;
(*breakpoint_p)->orig_instr = malloc(length);
(*breakpoint_p)->next = NULL;
(*breakpoint_p)->unique_id = bpwp_unique_id++;
diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h
index b4a3511..0a59495 100644
--- a/src/target/breakpoints.h
+++ b/src/target/breakpoints.h
@@ -39,7 +39,8 @@ struct breakpoint {
uint32_t asid;
int length;
enum breakpoint_type type;
- int set;
+ bool is_set;
+ unsigned int number;
uint8_t *orig_instr;
struct breakpoint *next;
uint32_t unique_id;
@@ -52,7 +53,8 @@ struct watchpoint {
uint32_t mask;
uint32_t value;
enum watchpoint_rw rw;
- int set;
+ bool is_set;
+ unsigned int number;
struct watchpoint *next;
int unique_id;
};
@@ -69,6 +71,12 @@ void breakpoint_remove_all(struct target *target);
struct breakpoint *breakpoint_find(struct target *target, target_addr_t address);
+static inline void breakpoint_hw_set(struct breakpoint *breakpoint, unsigned int hw_number)
+{
+ breakpoint->is_set = true;
+ breakpoint->number = hw_number;
+}
+
void watchpoint_clear_target(struct target *target);
int watchpoint_add(struct target *target,
target_addr_t address, uint32_t length,
@@ -79,4 +87,10 @@ void watchpoint_remove(struct target *target, target_addr_t address);
int watchpoint_hit(struct target *target, enum watchpoint_rw *rw,
target_addr_t *address);
+static inline void watchpoint_set(struct watchpoint *watchpoint, unsigned int number)
+{
+ watchpoint->is_set = true;
+ watchpoint->number = number;
+}
+
#endif /* OPENOCD_TARGET_BREAKPOINTS_H */
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 2724113..2dc1091 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -1185,7 +1185,7 @@ static int cortex_a_step(struct target *target, int current, target_addr_t addre
stepbreakpoint.length = (arm->core_state == ARM_STATE_THUMB)
? 2 : 4;
stepbreakpoint.type = BKPT_HARD;
- stepbreakpoint.set = 0;
+ stepbreakpoint.is_set = false;
/* Disable interrupts during single step if requested */
if (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {
@@ -1265,7 +1265,7 @@ static int cortex_a_set_breakpoint(struct target *target,
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct cortex_a_brp *brp_list = cortex_a->brp_list;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -1277,7 +1277,7 @@ static int cortex_a_set_breakpoint(struct target *target,
LOG_ERROR("ERROR Can not find free Breakpoint Register Pair");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = brp_i + 1;
+ breakpoint_hw_set(breakpoint, brp_i);
if (breakpoint->length == 2)
byte_addr_select = (3 << (breakpoint->address & 0x02));
control = ((matchmode & 0x7) << 20)
@@ -1342,7 +1342,7 @@ static int cortex_a_set_breakpoint(struct target *target,
armv7a_l1_i_cache_inval_virt(target, breakpoint->address,
breakpoint->length);
- breakpoint->set = 0x11; /* Any nice value but 0 */
+ breakpoint->is_set = true;
}
return ERROR_OK;
@@ -1359,7 +1359,7 @@ static int cortex_a_set_context_breakpoint(struct target *target,
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct cortex_a_brp *brp_list = cortex_a->brp_list;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return retval;
}
@@ -1373,7 +1373,7 @@ static int cortex_a_set_context_breakpoint(struct target *target,
return ERROR_FAIL;
}
- breakpoint->set = brp_i + 1;
+ breakpoint_hw_set(breakpoint, brp_i);
control = ((matchmode & 0x7) << 20)
| (byte_addr_select << 5)
| (3 << 1) | 1;
@@ -1411,7 +1411,7 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct cortex_a_brp *brp_list = cortex_a->brp_list;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return retval;
}
@@ -1436,7 +1436,7 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi
return ERROR_FAIL;
}
- breakpoint->set = brp_1 + 1;
+ breakpoint_hw_set(breakpoint, brp_1);
breakpoint->linked_brp = brp_2;
control_ctx = ((ctx_machmode & 0x7) << 20)
| (brp_2 << 16)
@@ -1485,16 +1485,16 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct cortex_a_brp *brp_list = cortex_a->brp_list;
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
- int brp_i = breakpoint->set - 1;
+ int brp_i = breakpoint->number;
int brp_j = breakpoint->linked_brp;
- if ((brp_i < 0) || (brp_i >= cortex_a->brp_num)) {
+ if (brp_i >= cortex_a->brp_num) {
LOG_DEBUG("Invalid BRP number in breakpoint");
return ERROR_OK;
}
@@ -1533,12 +1533,12 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
if (retval != ERROR_OK)
return retval;
breakpoint->linked_brp = 0;
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
} else {
- int brp_i = breakpoint->set - 1;
- if ((brp_i < 0) || (brp_i >= cortex_a->brp_num)) {
+ int brp_i = breakpoint->number;
+ if (brp_i >= cortex_a->brp_num) {
LOG_DEBUG("Invalid BRP number in breakpoint");
return ERROR_OK;
}
@@ -1557,7 +1557,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
} else {
@@ -1589,7 +1589,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
armv7a_l1_i_cache_inval_virt(target, breakpoint->address,
breakpoint->length);
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -1655,7 +1655,7 @@ static int cortex_a_remove_breakpoint(struct target *target, struct breakpoint *
}
#endif
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
cortex_a_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
cortex_a->brp_num_available++;
@@ -1688,7 +1688,7 @@ static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *wat
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct cortex_a_wrp *wrp_list = cortex_a->wrp_list;
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return retval;
}
@@ -1741,7 +1741,7 @@ static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *wat
break;
}
- watchpoint->set = wrp_i + 1;
+ watchpoint_set(watchpoint, wrp_i);
control = (address_mask << 24) |
(byte_address_select << 5) |
(load_store_access_control << 3) |
@@ -1784,13 +1784,13 @@ static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *w
struct armv7a_common *armv7a = &cortex_a->armv7a_common;
struct cortex_a_wrp *wrp_list = cortex_a->wrp_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- int wrp_i = watchpoint->set - 1;
- if (wrp_i < 0 || wrp_i >= cortex_a->wrp_num) {
+ int wrp_i = watchpoint->number;
+ if (wrp_i >= cortex_a->wrp_num) {
LOG_DEBUG("Invalid WRP number in watchpoint");
return ERROR_OK;
}
@@ -1809,7 +1809,7 @@ static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *w
wrp_list[wrp_i].value);
if (retval != ERROR_OK)
return retval;
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -1851,7 +1851,7 @@ static int cortex_a_remove_watchpoint(struct target *target, struct watchpoint *
{
struct cortex_a_common *cortex_a = target_to_cortex_a(target);
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
cortex_a->wrp_num_available++;
cortex_a_unset_watchpoint(target, watchpoint);
}
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 7125e9e..344cfcf 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -185,7 +185,7 @@ static int cortex_m_load_core_reg_u32(struct target *target,
break;
cortex_m->slow_register_read = true; /* Polling (still) needed. */
if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) {
- LOG_ERROR("Timeout waiting for DCRDR transfer ready");
+ LOG_TARGET_ERROR(target, "Timeout waiting for DCRDR transfer ready");
return ERROR_TIMEOUT_REACHED;
}
keep_alive();
@@ -223,7 +223,7 @@ static int cortex_m_slow_read_all_regs(struct target *target)
}
if (!cortex_m->slow_register_read)
- LOG_DEBUG("Switching back to fast register reads");
+ LOG_TARGET_DEBUG(target, "Switching back to fast register reads");
return ERROR_OK;
}
@@ -319,7 +319,7 @@ static int cortex_m_fast_read_all_regs(struct target *target)
for (unsigned int i = 0; i < wi; i++) {
if ((dhcsr[i] & S_REGRDY) == 0) {
not_ready = true;
- LOG_DEBUG("Register %u was not ready during fast read", i);
+ LOG_TARGET_DEBUG(target, "Register %u was not ready during fast read", i);
}
cortex_m_cumulate_dhcsr_sticky(cortex_m, dhcsr[i]);
}
@@ -330,7 +330,7 @@ static int cortex_m_fast_read_all_regs(struct target *target)
return ERROR_TIMEOUT_REACHED;
}
- LOG_DEBUG("read %u 32-bit registers", wi);
+ LOG_TARGET_DEBUG(target, "read %u 32-bit registers", wi);
unsigned int ri = 0; /* read index from r_vals array */
for (reg_id = 0; reg_id < num_regs; reg_id++) {
@@ -403,7 +403,7 @@ static int cortex_m_store_core_reg_u32(struct target *target,
if (cortex_m->dcb_dhcsr & S_REGRDY)
break;
if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) {
- LOG_ERROR("Timeout waiting for DCRDR transfer ready");
+ LOG_TARGET_ERROR(target, "Timeout waiting for DCRDR transfer ready");
return ERROR_TIMEOUT_REACHED;
}
keep_alive();
@@ -528,7 +528,7 @@ static int cortex_m_clear_halt(struct target *target)
retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_DFSR, cortex_m->nvic_dfsr);
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m->nvic_dfsr);
+ LOG_TARGET_DEBUG(target, "NVIC_DFSR 0x%" PRIx32 "", cortex_m->nvic_dfsr);
return ERROR_OK;
}
@@ -550,7 +550,7 @@ static int cortex_m_single_step_core(struct target *target)
retval = cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG(" ");
+ LOG_TARGET_DEBUG(target, "single step");
/* restore dhcsr reg */
cortex_m_clear_halt(target);
@@ -590,7 +590,7 @@ static int cortex_m_endreset_event(struct target *target)
retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &dcb_demcr);
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "", dcb_demcr);
+ LOG_TARGET_DEBUG(target, "DCB_DEMCR = 0x%8.8" PRIx32 "", dcb_demcr);
/* this register is used for emulated dcc channel */
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
@@ -629,7 +629,7 @@ static int cortex_m_endreset_event(struct target *target)
/* Enable FPB */
retval = cortex_m_enable_fpb(target);
if (retval != ERROR_OK) {
- LOG_ERROR("Failed to enable the FPB");
+ LOG_TARGET_ERROR(target, "Failed to enable the FPB");
return retval;
}
@@ -766,7 +766,7 @@ static int cortex_m_examine_exception_reason(struct target *target)
}
retval = dap_run(swjdp);
if (retval == ERROR_OK)
- LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32
+ LOG_TARGET_DEBUG(target, "%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32
", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32,
armv7m_exception_string(armv7m->exception_number),
shcsr, except_sr, cfsr, except_ar);
@@ -782,7 +782,7 @@ static int cortex_m_debug_entry(struct target *target)
struct arm *arm = &armv7m->arm;
struct reg *r;
- LOG_DEBUG(" ");
+ LOG_TARGET_DEBUG(target, " ");
/* Do this really early to minimize the window where the MASKINTS erratum
* can pile up pending interrupts. */
@@ -815,7 +815,7 @@ static int cortex_m_debug_entry(struct target *target)
retval = cortex_m_fast_read_all_regs(target);
if (retval == ERROR_TIMEOUT_REACHED) {
cortex_m->slow_register_read = true;
- LOG_DEBUG("Switched to slow register read");
+ LOG_TARGET_DEBUG(target, "Switched to slow register read");
}
}
@@ -855,7 +855,8 @@ static int cortex_m_debug_entry(struct target *target)
if (armv7m->exception_number)
cortex_m_examine_exception_reason(target);
- LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", cpu in %s state, target->state: %s",
+ 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),
buf_get_u32(arm->pc->value, 0, 32),
secure_state ? "Secure" : "Non-Secure",
@@ -889,8 +890,7 @@ static int cortex_m_poll(struct target *target)
* section B1.5.15 "Unrecoverable exception cases".
*/
if (cortex_m->dcb_dhcsr & S_LOCKUP) {
- LOG_ERROR("%s -- clearing lockup after double fault",
- target_name(target));
+ LOG_TARGET_ERROR(target, "clearing lockup after double fault");
cortex_m_write_debug_halt_mask(target, C_HALT, 0);
target->debug_reason = DBG_REASON_DBGRQ;
@@ -909,7 +909,7 @@ static int cortex_m_poll(struct target *target)
cortex_m->dcb_dhcsr_cumulated_sticky &= ~S_RESET_ST;
if (target->state != TARGET_RESET) {
target->state = TARGET_RESET;
- LOG_INFO("%s: external reset detected", target_name(target));
+ LOG_TARGET_INFO(target, "external reset detected");
}
return ERROR_OK;
}
@@ -918,7 +918,7 @@ static int cortex_m_poll(struct target *target)
/* Cannot switch context while running so endreset is
* called with target->state == TARGET_RESET
*/
- LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32,
+ LOG_TARGET_DEBUG(target, "Exit from reset with dcb_dhcsr 0x%" PRIx32,
cortex_m->dcb_dhcsr);
retval = cortex_m_endreset_event(target);
if (retval != ERROR_OK) {
@@ -943,7 +943,6 @@ static int cortex_m_poll(struct target *target)
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
}
if (prev_target_state == TARGET_DEBUG_RUNNING) {
- LOG_DEBUG(" ");
retval = cortex_m_debug_entry(target);
if (retval != ERROR_OK)
return retval;
@@ -971,7 +970,7 @@ static int cortex_m_poll(struct target *target)
register_cache_invalidate(armv7m->arm.core_cache);
target->state = TARGET_RUNNING;
- LOG_WARNING("%s: external resume detected", target_name(target));
+ LOG_TARGET_WARNING(target, "external resume detected");
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
retval = ERROR_OK;
}
@@ -984,20 +983,19 @@ static int cortex_m_poll(struct target *target)
static int cortex_m_halt(struct target *target)
{
- LOG_DEBUG("target->state: %s",
- target_state_name(target));
+ LOG_TARGET_DEBUG(target, "target->state: %s", target_state_name(target));
if (target->state == TARGET_HALTED) {
- LOG_DEBUG("target was already halted");
+ LOG_TARGET_DEBUG(target, "target was already halted");
return ERROR_OK;
}
if (target->state == TARGET_UNKNOWN)
- LOG_WARNING("target was in unknown state when halt was requested");
+ LOG_TARGET_WARNING(target, "target was in unknown state when halt was requested");
if (target->state == TARGET_RESET) {
if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
- LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
+ LOG_TARGET_ERROR(target, "can't request a halt while in reset if nSRST pulls nTRST");
return ERROR_TARGET_FAILURE;
} else {
/* we came here in a reset_halt or reset_init sequence
@@ -1031,10 +1029,10 @@ static int cortex_m_soft_reset_halt(struct target *target)
* can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.
* As this reset only uses VC_CORERESET it would only ever reset the cortex_m
* core, not the peripherals */
- LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
+ LOG_TARGET_DEBUG(target, "soft_reset_halt is discouraged, please use 'reset halt' instead.");
if (!cortex_m->vectreset_supported) {
- LOG_ERROR("VECTRESET is not supported on this Cortex-M core");
+ LOG_TARGET_ERROR(target, "VECTRESET is not supported on this Cortex-M core");
return ERROR_FAIL;
}
@@ -1068,15 +1066,16 @@ static int cortex_m_soft_reset_halt(struct target *target)
return retval;
if ((cortex_m->dcb_dhcsr & S_HALT)
&& (cortex_m->nvic_dfsr & DFSR_VCATCH)) {
- LOG_DEBUG("system reset-halted, DHCSR 0x%08" PRIx32 ", DFSR 0x%08" PRIx32,
- cortex_m->dcb_dhcsr, cortex_m->nvic_dfsr);
+ LOG_TARGET_DEBUG(target, "system reset-halted, DHCSR 0x%08" PRIx32 ", DFSR 0x%08" PRIx32,
+ cortex_m->dcb_dhcsr, cortex_m->nvic_dfsr);
cortex_m_poll(target);
/* FIXME restore user's vector catch config */
return ERROR_OK;
- } else
- LOG_DEBUG("waiting for system reset-halt, "
+ } else {
+ LOG_TARGET_DEBUG(target, "waiting for system reset-halt, "
"DHCSR 0x%08" PRIx32 ", %d ms",
cortex_m->dcb_dhcsr, timeout);
+ }
}
timeout++;
alive_sleep(1);
@@ -1091,7 +1090,7 @@ void cortex_m_enable_breakpoints(struct target *target)
/* set any pending breakpoints */
while (breakpoint) {
- if (!breakpoint->set)
+ if (!breakpoint->is_set)
cortex_m_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
}
@@ -1106,7 +1105,7 @@ static int cortex_m_resume(struct target *target, int current,
struct reg *r;
if (target->state != TARGET_HALTED) {
- LOG_WARNING("target not halted");
+ LOG_TARGET_WARNING(target, "target not halted");
return ERROR_TARGET_NOT_HALTED;
}
@@ -1170,7 +1169,7 @@ static int cortex_m_resume(struct target *target, int current,
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
+ LOG_TARGET_DEBUG(target, "unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
breakpoint->address,
breakpoint->unique_id);
cortex_m_unset_breakpoint(target, breakpoint);
@@ -1191,11 +1190,11 @@ static int cortex_m_resume(struct target *target, int current,
if (!debug_execution) {
target->state = TARGET_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
- LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
+ LOG_TARGET_DEBUG(target, "target resumed at 0x%" PRIx32 "", resume_pc);
} else {
target->state = TARGET_DEBUG_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
- LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
+ LOG_TARGET_DEBUG(target, "target debug resumed at 0x%" PRIx32 "", resume_pc);
}
return ERROR_OK;
@@ -1214,7 +1213,7 @@ static int cortex_m_step(struct target *target, int current,
bool isr_timed_out = false;
if (target->state != TARGET_HALTED) {
- LOG_WARNING("target not halted");
+ LOG_TARGET_WARNING(target, "target not halted");
return ERROR_TARGET_NOT_HALTED;
}
@@ -1287,7 +1286,7 @@ static int cortex_m_step(struct target *target, int current,
*
*/
if ((pc_value & 0x02) && breakpoint_find(target, pc_value & ~0x03)) {
- LOG_DEBUG("Stepping over next instruction with interrupts disabled");
+ LOG_TARGET_DEBUG(target, "Stepping over next instruction with interrupts disabled");
cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
/* Re-enable interrupts if appropriate */
@@ -1318,7 +1317,7 @@ static int cortex_m_step(struct target *target, int current,
cortex_m_set_maskints_for_halt(target);
} else {
/* Start the core */
- LOG_DEBUG("Starting core to serve pending interrupts");
+ LOG_TARGET_DEBUG(target, "Starting core to serve pending interrupts");
int64_t t_start = timeval_ms();
cortex_m_set_maskints_for_run(target);
cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP);
@@ -1342,7 +1341,7 @@ static int cortex_m_step(struct target *target, int current,
}
if (isr_timed_out) {
- LOG_DEBUG("Interrupt handlers didn't complete within time, "
+ LOG_TARGET_DEBUG(target, "Interrupt handlers didn't complete within time, "
"leaving target running");
} else {
/* Step over next instruction with interrupts disabled */
@@ -1377,7 +1376,7 @@ static int cortex_m_step(struct target *target, int current,
return ERROR_OK;
}
- LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
+ LOG_TARGET_DEBUG(target, "target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32,
cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
@@ -1386,7 +1385,7 @@ static int cortex_m_step(struct target *target, int current,
return retval;
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
- LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
+ LOG_TARGET_DEBUG(target, "target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32,
cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
@@ -1399,7 +1398,7 @@ static int cortex_m_assert_reset(struct target *target)
struct armv7m_common *armv7m = &cortex_m->armv7m;
enum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config;
- LOG_DEBUG("target->state: %s",
+ LOG_TARGET_DEBUG(target, "target->state: %s",
target_state_name(target));
enum reset_types jtag_reset_config = jtag_get_reset_config();
@@ -1423,10 +1422,10 @@ static int cortex_m_assert_reset(struct target *target)
if (jtag_reset_config & RESET_HAS_SRST) {
adapter_assert_reset();
if (target->reset_halt)
- LOG_ERROR("Target not examined, will not halt after reset!");
+ LOG_TARGET_ERROR(target, "Target not examined, will not halt after reset!");
return ERROR_OK;
} else {
- LOG_ERROR("Target not examined, reset NOT asserted!");
+ LOG_TARGET_ERROR(target, "Target not examined, reset NOT asserted!");
return ERROR_FAIL;
}
}
@@ -1473,7 +1472,7 @@ static int cortex_m_assert_reset(struct target *target)
retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
if (retval != ERROR_OK || retval2 != ERROR_OK)
- LOG_INFO("AP write error, reset will not halt");
+ LOG_TARGET_INFO(target, "AP write error, reset will not halt");
}
if (jtag_reset_config & RESET_HAS_SRST) {
@@ -1493,15 +1492,15 @@ static int cortex_m_assert_reset(struct target *target)
if (!cortex_m->vectreset_supported
&& reset_config == CORTEX_M_RESET_VECTRESET) {
reset_config = CORTEX_M_RESET_SYSRESETREQ;
- LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
- LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
+ LOG_TARGET_WARNING(target, "VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
+ LOG_TARGET_WARNING(target, "Set 'cortex_m reset_config sysresetreq'.");
}
- LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ)
+ LOG_TARGET_DEBUG(target, "Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ)
? "SYSRESETREQ" : "VECTRESET");
if (reset_config == CORTEX_M_RESET_VECTRESET) {
- LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
+ LOG_TARGET_WARNING(target, "Only resetting the Cortex-M core, use a reset-init event "
"handler to reset any peripherals or configure hardware srst support.");
}
@@ -1510,11 +1509,11 @@ static int cortex_m_assert_reset(struct target *target)
AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)
? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
if (retval3 != ERROR_OK)
- LOG_DEBUG("Ignoring AP write error right after reset");
+ LOG_TARGET_DEBUG(target, "Ignoring AP write error right after reset");
retval3 = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
if (retval3 != ERROR_OK) {
- LOG_ERROR("DP initialisation failed");
+ LOG_TARGET_ERROR(target, "DP initialisation failed");
/* The error return value must not be propagated in this case.
* SYSRESETREQ or VECTRESET have been possibly triggered
* so reset processing should continue */
@@ -1550,7 +1549,7 @@ static int cortex_m_deassert_reset(struct target *target)
{
struct armv7m_common *armv7m = &target_to_cm(target)->armv7m;
- LOG_DEBUG("target->state: %s",
+ LOG_TARGET_DEBUG(target, "target->state: %s",
target_state_name(target));
/* deassert reset lines */
@@ -1564,7 +1563,7 @@ static int cortex_m_deassert_reset(struct target *target)
int retval = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
if (retval != ERROR_OK) {
- LOG_ERROR("DP initialisation failed");
+ LOG_TARGET_ERROR(target, "DP initialisation failed");
return retval;
}
}
@@ -1579,8 +1578,8 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
struct cortex_m_common *cortex_m = target_to_cm(target);
struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
- if (breakpoint->set) {
- LOG_WARNING("breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id);
+ if (breakpoint->is_set) {
+ LOG_TARGET_WARNING(target, "breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id);
return ERROR_OK;
}
@@ -1589,35 +1588,36 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))
fp_num++;
if (fp_num >= cortex_m->fp_num_code) {
- LOG_ERROR("Can not find free FPB Comparator!");
+ LOG_TARGET_ERROR(target, "Can not find free FPB Comparator!");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = fp_num + 1;
+ breakpoint_hw_set(breakpoint, fp_num);
fpcr_value = breakpoint->address | 1;
if (cortex_m->fp_rev == 0) {
if (breakpoint->address > 0x1FFFFFFF) {
- LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
+ LOG_TARGET_ERROR(target, "Cortex-M Flash Patch Breakpoint rev.1 "
+ "cannot handle HW breakpoint above address 0x1FFFFFFE");
return ERROR_FAIL;
}
uint32_t hilo;
hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
fpcr_value = (fpcr_value & 0x1FFFFFFC) | hilo | 1;
} else if (cortex_m->fp_rev > 1) {
- LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
+ LOG_TARGET_ERROR(target, "Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
return ERROR_FAIL;
}
comparator_list[fp_num].used = true;
comparator_list[fp_num].fpcr_value = fpcr_value;
target_write_u32(target, comparator_list[fp_num].fpcr_address,
comparator_list[fp_num].fpcr_value);
- LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "",
+ LOG_TARGET_DEBUG(target, "fpc_num %i fpcr_value 0x%" PRIx32 "",
fp_num,
comparator_list[fp_num].fpcr_value);
if (!cortex_m->fpb_enabled) {
- LOG_DEBUG("FPB wasn't enabled, do it now");
+ LOG_TARGET_DEBUG(target, "FPB wasn't enabled, do it now");
retval = cortex_m_enable_fpb(target);
if (retval != ERROR_OK) {
- LOG_ERROR("Failed to enable the FPB");
+ LOG_TARGET_ERROR(target, "Failed to enable the FPB");
return retval;
}
@@ -1643,15 +1643,15 @@ int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint
code);
if (retval != ERROR_OK)
return retval;
- breakpoint->set = true;
+ breakpoint->is_set = true;
}
- LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
+ LOG_TARGET_DEBUG(target, "BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (n=%u)",
breakpoint->unique_id,
(int)(breakpoint->type),
breakpoint->address,
breakpoint->length,
- breakpoint->set);
+ (breakpoint->type == BKPT_SOFT) ? 0 : breakpoint->number);
return ERROR_OK;
}
@@ -1662,22 +1662,22 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
struct cortex_m_common *cortex_m = target_to_cm(target);
struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
- if (breakpoint->set <= 0) {
- LOG_WARNING("breakpoint not set");
+ if (!breakpoint->is_set) {
+ LOG_TARGET_WARNING(target, "breakpoint not set");
return ERROR_OK;
}
- LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
+ LOG_TARGET_DEBUG(target, "BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (n=%u)",
breakpoint->unique_id,
(int)(breakpoint->type),
breakpoint->address,
breakpoint->length,
- breakpoint->set);
+ (breakpoint->type == BKPT_SOFT) ? 0 : breakpoint->number);
if (breakpoint->type == BKPT_HARD) {
- unsigned int fp_num = breakpoint->set - 1;
+ unsigned int fp_num = breakpoint->number;
if (fp_num >= cortex_m->fp_num_code) {
- LOG_DEBUG("Invalid FP Comparator number in breakpoint");
+ LOG_TARGET_DEBUG(target, "Invalid FP Comparator number in breakpoint");
return ERROR_OK;
}
comparator_list[fp_num].used = false;
@@ -1692,7 +1692,7 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
if (retval != ERROR_OK)
return retval;
}
- breakpoint->set = false;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -1700,12 +1700,12 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi
int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
{
if (breakpoint->length == 3) {
- LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
+ LOG_TARGET_DEBUG(target, "Using a two byte breakpoint for 32bit Thumb-2 request");
breakpoint->length = 2;
}
if ((breakpoint->length != 2)) {
- LOG_INFO("only breakpoints of two bytes length supported");
+ LOG_TARGET_INFO(target, "only breakpoints of two bytes length supported");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
@@ -1714,7 +1714,7 @@ int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint
int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
{
- if (!breakpoint->set)
+ if (!breakpoint->is_set)
return ERROR_OK;
return cortex_m_unset_breakpoint(target, breakpoint);
@@ -1737,11 +1737,11 @@ static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *wat
comparator++, dwt_num++)
continue;
if (dwt_num >= cortex_m->dwt_num_comp) {
- LOG_ERROR("Can not find free DWT Comparator");
+ LOG_TARGET_ERROR(target, "Can not find free DWT Comparator");
return ERROR_FAIL;
}
comparator->used = true;
- watchpoint->set = dwt_num + 1;
+ watchpoint_set(watchpoint, dwt_num);
comparator->comp = watchpoint->address;
target_write_u32(target, comparator->dwt_comparator_address + 0,
@@ -1795,7 +1795,7 @@ static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *wat
target_write_u32(target, comparator->dwt_comparator_address + 8,
comparator->function);
- LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
+ LOG_TARGET_DEBUG(target, "Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
watchpoint->unique_id, dwt_num,
(unsigned) comparator->comp,
(unsigned) comparator->mask,
@@ -1808,20 +1808,20 @@ static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *w
struct cortex_m_common *cortex_m = target_to_cm(target);
struct cortex_m_dwt_comparator *comparator;
- if (watchpoint->set <= 0) {
- LOG_WARNING("watchpoint (wpid: %d) not set",
+ if (!watchpoint->is_set) {
+ LOG_TARGET_WARNING(target, "watchpoint (wpid: %d) not set",
watchpoint->unique_id);
return ERROR_OK;
}
- unsigned int dwt_num = watchpoint->set - 1;
+ unsigned int dwt_num = watchpoint->number;
- LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
+ LOG_TARGET_DEBUG(target, "Watchpoint (ID %d) DWT%u address: 0x%08x clear",
watchpoint->unique_id, dwt_num,
(unsigned) watchpoint->address);
if (dwt_num >= cortex_m->dwt_num_comp) {
- LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
+ LOG_TARGET_DEBUG(target, "Invalid DWT Comparator number in watchpoint");
return ERROR_OK;
}
@@ -1831,7 +1831,7 @@ static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *w
target_write_u32(target, comparator->dwt_comparator_address + 8,
comparator->function);
- watchpoint->set = false;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -1841,13 +1841,13 @@ int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint
struct cortex_m_common *cortex_m = target_to_cm(target);
if (cortex_m->dwt_comp_available < 1) {
- LOG_DEBUG("no comparators?");
+ LOG_TARGET_DEBUG(target, "no comparators?");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
/* hardware doesn't support data value masking */
if (watchpoint->mask != ~(uint32_t)0) {
- LOG_DEBUG("watchpoint value masks not supported");
+ LOG_TARGET_DEBUG(target, "watchpoint value masks not supported");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
@@ -1859,11 +1859,11 @@ int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint
break;
}
if (mask == 16) {
- LOG_DEBUG("unsupported watchpoint length");
+ LOG_TARGET_DEBUG(target, "unsupported watchpoint length");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
if (watchpoint->address & ((1 << mask) - 1)) {
- LOG_DEBUG("watchpoint address is unaligned");
+ LOG_TARGET_DEBUG(target, "watchpoint address is unaligned");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
@@ -1875,12 +1875,12 @@ int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint
* the data, and another comparator (DATAVADDR0) matching addr.
*/
if (watchpoint->value) {
- LOG_DEBUG("data value watchpoint not YET supported");
+ LOG_TARGET_DEBUG(target, "data value watchpoint not YET supported");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
cortex_m->dwt_comp_available--;
- LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available);
+ LOG_TARGET_DEBUG(target, "dwt_comp_available: %d", cortex_m->dwt_comp_available);
return ERROR_OK;
}
@@ -1891,15 +1891,15 @@ int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpo
/* REVISIT why check? DWT can be updated with core running ... */
if (target->state != TARGET_HALTED) {
- LOG_WARNING("target not halted");
+ LOG_TARGET_WARNING(target, "target not halted");
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
cortex_m_unset_watchpoint(target, watchpoint);
cortex_m->dwt_comp_available++;
- LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available);
+ LOG_TARGET_DEBUG(target, "dwt_comp_available: %d", cortex_m->dwt_comp_available);
return ERROR_OK;
}
@@ -1912,10 +1912,10 @@ int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watch
struct cortex_m_common *cortex_m = target_to_cm(target);
for (struct watchpoint *wp = target->watchpoints; wp; wp = wp->next) {
- if (!wp->set)
+ if (!wp->is_set)
continue;
- unsigned int dwt_num = wp->set - 1;
+ unsigned int dwt_num = wp->number;
struct cortex_m_dwt_comparator *comparator = cortex_m->dwt_comparator_list + dwt_num;
uint32_t dwt_function;
@@ -1939,7 +1939,7 @@ void cortex_m_enable_watchpoints(struct target *target)
/* set any pending watchpoints */
while (watchpoint) {
- if (!watchpoint->set)
+ if (!watchpoint->is_set)
cortex_m_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
@@ -2004,18 +2004,18 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
retval = target_read_u32(target, DWT_PCSR, &reg_value);
if (retval != ERROR_OK) {
- LOG_ERROR("Error while reading PCSR");
+ LOG_TARGET_ERROR(target, "Error while reading PCSR");
return retval;
}
if (reg_value == 0) {
- LOG_INFO("PCSR sampling not supported on this processor.");
+ LOG_TARGET_INFO(target, "PCSR sampling not supported on this processor.");
return target_profiling_default(target, samples, max_num_samples, num_samples, seconds);
}
gettimeofday(&timeout, NULL);
timeval_add_time(&timeout, seconds, 0);
- LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
+ LOG_TARGET_INFO(target, "Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
/* Make sure the target is running */
target_poll(target);
@@ -2023,7 +2023,7 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
retval = target_resume(target, 1, 0, 0, 0);
if (retval != ERROR_OK) {
- LOG_ERROR("Error while resuming target");
+ LOG_TARGET_ERROR(target, "Error while resuming target");
return retval;
}
@@ -2044,14 +2044,14 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
}
if (retval != ERROR_OK) {
- LOG_ERROR("Error while reading PCSR");
+ LOG_TARGET_ERROR(target, "Error while reading PCSR");
return retval;
}
gettimeofday(&now, NULL);
if (sample_count >= max_num_samples || timeval_compare(&now, &timeout) > 0) {
- LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
+ LOG_TARGET_INFO(target, "Profiling completed. %" PRIu32 " samples.", sample_count);
break;
}
}
@@ -2162,14 +2162,14 @@ static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target
int reg;
target_read_u32(target, DWT_CTRL, &dwtcr);
- LOG_DEBUG("DWT_CTRL: 0x%" PRIx32, dwtcr);
+ LOG_TARGET_DEBUG(target, "DWT_CTRL: 0x%" PRIx32, dwtcr);
if (!dwtcr) {
- LOG_DEBUG("no DWT");
+ LOG_TARGET_DEBUG(target, "no DWT");
return;
}
target_read_u32(target, DWT_DEVARCH, &cm->dwt_devarch);
- LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32, cm->dwt_devarch);
+ LOG_TARGET_DEBUG(target, "DWT_DEVARCH: 0x%" PRIx32, cm->dwt_devarch);
cm->dwt_num_comp = (dwtcr >> 28) & 0xF;
cm->dwt_comp_available = cm->dwt_num_comp;
@@ -2178,7 +2178,7 @@ static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target
if (!cm->dwt_comparator_list) {
fail0:
cm->dwt_num_comp = 0;
- LOG_ERROR("out of mem");
+ LOG_TARGET_ERROR(target, "out of mem");
return;
}
@@ -2216,7 +2216,7 @@ fail1:
*register_get_last_cache_p(&target->reg_cache) = cache;
cm->dwt_cache = cache;
- LOG_DEBUG("DWT dwtcr 0x%" PRIx32 ", comp %d, watch%s",
+ LOG_TARGET_DEBUG(target, "DWT dwtcr 0x%" PRIx32 ", comp %d, watch%s",
dwtcr, cm->dwt_num_comp,
(dwtcr & (0xf << 24)) ? " only" : "/trigger");
@@ -2283,7 +2283,7 @@ int cortex_m_examine(struct target *target)
/* Search for the MEM-AP */
retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
if (retval != ERROR_OK) {
- LOG_ERROR("Could not find MEM-AP to control the core");
+ LOG_TARGET_ERROR(target, "Could not find MEM-AP to control the core");
return retval;
}
} else {
@@ -2316,14 +2316,13 @@ int cortex_m_examine(struct target *target)
}
if (!cortex_m->core_info) {
- LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno);
+ LOG_TARGET_ERROR(target, "Cortex-M PARTNO 0x%x is unrecognized", core_partno);
return ERROR_FAIL;
}
armv7m->arm.arch = cortex_m->core_info->arch;
- LOG_INFO("%s: %s r%" PRId8 "p%" PRId8 " processor detected",
- target_name(target),
+ LOG_TARGET_INFO(target, "%s r%" PRId8 "p%" PRId8 " processor detected",
cortex_m->core_info->name,
(uint8_t)((cpuid >> 20) & 0xf),
(uint8_t)((cpuid >> 0) & 0xf));
@@ -2334,11 +2333,11 @@ int cortex_m_examine(struct target *target)
rev = (cpuid >> 20) & 0xf;
patch = (cpuid >> 0) & 0xf;
if ((rev == 0) && (patch < 2)) {
- LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
+ LOG_TARGET_WARNING(target, "Silicon bug: single stepping may enter pending exception handler!");
cortex_m->maskints_erratum = true;
}
}
- LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
+ LOG_TARGET_DEBUG(target, "cpuid: 0x%8.8" PRIx32 "", cpuid);
if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) {
target_read_u32(target, MVFR0, &mvfr0);
@@ -2346,7 +2345,7 @@ int cortex_m_examine(struct target *target)
/* test for floating point feature on Cortex-M4 */
if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
- LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m->core_info->name);
+ LOG_TARGET_DEBUG(target, "%s floating point feature FPv4_SP found", cortex_m->core_info->name);
armv7m->fp_feature = FPV4_SP;
}
} else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) {
@@ -2355,10 +2354,10 @@ int cortex_m_examine(struct target *target)
/* test for floating point features on Cortex-M7 */
if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
- LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m->core_info->name);
+ LOG_TARGET_DEBUG(target, "%s floating point feature FPv5_SP found", cortex_m->core_info->name);
armv7m->fp_feature = FPV5_SP;
} else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
- LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m->core_info->name);
+ LOG_TARGET_DEBUG(target, "%s floating point feature FPv5_DP found", cortex_m->core_info->name);
armv7m->fp_feature = FPV5_DP;
}
}
@@ -2428,7 +2427,7 @@ int cortex_m_examine(struct target *target)
/* make sure we clear any breakpoints enabled on the target */
target_write_u32(target, cortex_m->fp_comparator_list[i].fpcr_address, 0);
}
- LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i",
+ LOG_TARGET_DEBUG(target, "FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i",
fpcr,
cortex_m->fp_num_code,
cortex_m->fp_num_lit);
@@ -2438,8 +2437,7 @@ int cortex_m_examine(struct target *target)
cortex_m_dwt_setup(cortex_m, target);
/* These hardware breakpoints only work for code in flash! */
- LOG_INFO("%s: target has %d breakpoints, %d watchpoints",
- target_name(target),
+ LOG_TARGET_INFO(target, "target has %d breakpoints, %d watchpoints",
cortex_m->fp_num_code,
cortex_m->dwt_num_comp);
}
@@ -2462,7 +2460,7 @@ static int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctr
*ctrl = (uint8_t)dcrdr;
*value = (uint8_t)(dcrdr >> 8);
- LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
+ LOG_TARGET_DEBUG(target, "data 0x%x ctrl 0x%x", *value, *ctrl);
/* write ack back to software dcc register
* signify we have read data */
@@ -2569,7 +2567,7 @@ static int cortex_m_target_create(struct target *target, Jim_Interp *interp)
struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
if (!cortex_m) {
- LOG_ERROR("No memory creating target");
+ LOG_TARGET_ERROR(target, "No memory creating target");
return ERROR_FAIL;
}
@@ -2626,7 +2624,7 @@ COMMAND_HANDLER(handle_cortex_m_vector_catch_command)
return retval;
if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
+ LOG_TARGET_ERROR(target, "Target not examined yet");
return ERROR_FAIL;
}
@@ -2655,7 +2653,7 @@ COMMAND_HANDLER(handle_cortex_m_vector_catch_command)
break;
}
if (i == ARRAY_SIZE(vec_ids)) {
- LOG_ERROR("No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]);
+ LOG_TARGET_ERROR(target, "No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]);
return ERROR_COMMAND_SYNTAX_ERROR;
}
}
@@ -2745,7 +2743,7 @@ COMMAND_HANDLER(handle_cortex_m_reset_config_command)
else if (strcmp(*CMD_ARGV, "vectreset") == 0) {
if (target_was_examined(target)
&& !cortex_m->vectreset_supported)
- LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
+ LOG_TARGET_WARNING(target, "VECTRESET is not supported on your Cortex-M core!");
else
cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
diff --git a/src/target/esirisc.c b/src/target/esirisc.c
index e49f5f6..aadd111 100644
--- a/src/target/esirisc.c
+++ b/src/target/esirisc.c
@@ -504,7 +504,7 @@ static int esirisc_add_breakpoint(struct target *target, struct breakpoint *brea
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = bp_index + 1;
+ breakpoint_hw_set(breakpoint, bp_index);
esirisc->breakpoints_p[bp_index] = breakpoint;
/* specify instruction breakpoint address */
@@ -540,7 +540,7 @@ static int esirisc_add_breakpoints(struct target *target)
LOG_DEBUG("-");
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
esirisc_add_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
@@ -553,7 +553,7 @@ static int esirisc_remove_breakpoint(struct target *target, struct breakpoint *b
{
struct esirisc_common *esirisc = target_to_esirisc(target);
struct esirisc_jtag *jtag_info = &esirisc->jtag_info;
- int bp_index = breakpoint->set - 1;
+ unsigned int bp_index = breakpoint->number;
uint32_t ibc;
int retval;
@@ -575,7 +575,7 @@ static int esirisc_remove_breakpoint(struct target *target, struct breakpoint *b
}
esirisc->breakpoints_p[bp_index] = NULL;
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -630,7 +630,7 @@ static int esirisc_add_watchpoint(struct target *target, struct watchpoint *watc
return ERROR_FAIL;
}
- watchpoint->set = wp_index + 1;
+ watchpoint_set(watchpoint, wp_index);
esirisc->watchpoints_p[wp_index] = watchpoint;
/* specify data breakpoint address */
@@ -724,7 +724,7 @@ static int esirisc_add_watchpoints(struct target *target)
LOG_DEBUG("-");
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
esirisc_add_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
@@ -737,7 +737,7 @@ static int esirisc_remove_watchpoint(struct target *target, struct watchpoint *w
{
struct esirisc_common *esirisc = target_to_esirisc(target);
struct esirisc_jtag *jtag_info = &esirisc->jtag_info;
- int wp_index = watchpoint->set - 1;
+ unsigned int wp_index = watchpoint->number;
uint32_t dbc;
int retval;
@@ -759,7 +759,7 @@ static int esirisc_remove_watchpoint(struct target *target, struct watchpoint *w
}
esirisc->watchpoints_p[wp_index] = NULL;
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
diff --git a/src/target/lakemont.c b/src/target/lakemont.c
index e46ee5c..230f53f 100644
--- a/src/target/lakemont.c
+++ b/src/target/lakemont.c
@@ -1024,10 +1024,10 @@ int lakemont_resume(struct target *t, int current, target_addr_t address,
/* if breakpoints are enabled, we need to redirect these into probe mode */
struct breakpoint *activeswbp = t->breakpoints;
- while (activeswbp && activeswbp->set == 0)
+ while (activeswbp && !activeswbp->is_set)
activeswbp = activeswbp->next;
struct watchpoint *activehwbp = t->watchpoints;
- while (activehwbp && activehwbp->set == 0)
+ while (activehwbp && !activehwbp->is_set)
activehwbp = activehwbp->next;
if (activeswbp || activehwbp)
buf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1);
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 8627bce..8601193 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -593,7 +593,7 @@ static void mips_m4k_enable_breakpoints(struct target *target)
/* set any pending breakpoints */
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
mips_m4k_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
}
@@ -607,7 +607,7 @@ static int mips_m4k_set_breakpoint(struct target *target,
struct mips32_comparator *comparator_list = mips32->inst_break_list;
int retval;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -622,7 +622,7 @@ static int mips_m4k_set_breakpoint(struct target *target,
breakpoint->unique_id);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = bp_num + 1;
+ breakpoint_hw_set(breakpoint, bp_num);
comparator_list[bp_num].used = 1;
comparator_list[bp_num].bp_value = breakpoint->address;
@@ -724,7 +724,7 @@ static int mips_m4k_set_breakpoint(struct target *target,
}
}
- breakpoint->set = 20; /* Any nice value but 0 */
+ breakpoint->is_set = true;
}
return ERROR_OK;
@@ -739,14 +739,14 @@ static int mips_m4k_unset_breakpoint(struct target *target,
struct mips32_comparator *comparator_list = mips32->inst_break_list;
int retval;
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
- int bp_num = breakpoint->set - 1;
- if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints)) {
+ int bp_num = breakpoint->number;
+ if (bp_num >= mips32->num_inst_bpoints) {
LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32 ")",
breakpoint->unique_id);
return ERROR_OK;
@@ -813,7 +813,7 @@ static int mips_m4k_unset_breakpoint(struct target *target,
}
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -851,7 +851,7 @@ static int mips_m4k_remove_breakpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (breakpoint->set)
+ if (breakpoint->is_set)
mips_m4k_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
@@ -875,7 +875,7 @@ static int mips_m4k_set_watchpoint(struct target *target,
int enable = EJTAG_DBCN_NOSB | EJTAG_DBCN_NOLB | EJTAG_DBCN_BE |
(0xff << EJTAG_DBCN_BLM_SHIFT);
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}
@@ -911,7 +911,7 @@ static int mips_m4k_set_watchpoint(struct target *target,
LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
}
- watchpoint->set = wp_num + 1;
+ watchpoint->number = wp_num;
comparator_list[wp_num].used = 1;
comparator_list[wp_num].bp_value = watchpoint->address;
@@ -946,13 +946,13 @@ static int mips_m4k_unset_watchpoint(struct target *target,
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
struct mips32_comparator *comparator_list = mips32->data_break_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- int wp_num = watchpoint->set - 1;
- if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints)) {
+ int wp_num = watchpoint->number;
+ if (wp_num >= mips32->num_data_bpoints) {
LOG_DEBUG("Invalid FP Comparator number in watchpoint");
return ERROR_OK;
}
@@ -960,7 +960,7 @@ static int mips_m4k_unset_watchpoint(struct target *target,
comparator_list[wp_num].bp_value = 0;
target_write_u32(target, comparator_list[wp_num].reg_address +
ejtag_info->ejtag_dbc_offs, 0);
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -991,7 +991,7 @@ static int mips_m4k_remove_watchpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
mips_m4k_unset_watchpoint(target, watchpoint);
mips32->num_data_bpoints_avail++;
@@ -1005,7 +1005,7 @@ static void mips_m4k_enable_watchpoints(struct target *target)
/* set any pending watchpoints */
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
mips_m4k_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c
index 56b0194..5d821d7 100644
--- a/src/target/mips_mips64.c
+++ b/src/target/mips_mips64.c
@@ -346,7 +346,7 @@ static int mips_mips64_set_breakpoint(struct target *target,
{
int retval;
- if (bp->set) {
+ if (bp->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -373,7 +373,7 @@ static int mips_mips64_set_breakpoint(struct target *target,
return retval;
}
- bp->set = true;
+ bp->is_set = true;
return ERROR_OK;
}
@@ -385,7 +385,7 @@ static int mips_mips64_enable_breakpoints(struct target *target)
/* set any pending breakpoints */
while (bp) {
- if (!bp->set) {
+ if (!bp->is_set) {
retval = mips_mips64_set_breakpoint(target, bp);
if (retval != ERROR_OK)
return retval;
@@ -413,7 +413,7 @@ static int mips_mips64_set_watchpoint(struct target *target,
int enable = EJTAG_DBCN_NOSB | EJTAG_DBCN_NOLB | EJTAG_DBCN_BE
| (0xff << EJTAG_DBCN_BLM_SHIFT);
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}
@@ -451,7 +451,7 @@ static int mips_mips64_set_watchpoint(struct target *target,
}
c = &cl[wp_num];
- watchpoint->set = wp_num + 1;
+ watchpoint_set(watchpoint, wp_num);
c->used = true;
c->bp_value = watchpoint->address;
@@ -491,7 +491,7 @@ static int mips_mips64_enable_watchpoints(struct target *target)
/* set any pending watchpoints */
while (watchpoint) {
- if (watchpoint->set == 0) {
+ if (!watchpoint->is_set) {
retval = mips_mips64_set_watchpoint(target, watchpoint);
if (retval != ERROR_OK)
return retval;
@@ -506,11 +506,10 @@ static int mips_mips64_unset_hwbp(struct target *target, struct breakpoint *bp)
{
struct mips64_common *mips64 = target->arch_info;
struct mips64_comparator *comparator_list = mips64->inst_break_list;
- int bp_num;
- bp_num = bp->set - 1;
+ int bp_num = bp->number;
- if ((bp_num < 0) || (bp_num >= mips64->num_inst_bpoints)) {
+ if (bp_num >= mips64->num_inst_bpoints) {
LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32 ")",
bp->unique_id);
return ERROR_OK;
@@ -568,7 +567,7 @@ static int mips_mips64_unset_breakpoint(struct target *target,
/* get pointers to arch-specific information */
int retval;
- if (!bp->set) {
+ if (!bp->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
@@ -594,7 +593,7 @@ static int mips_mips64_unset_breakpoint(struct target *target,
return retval;
}
- bp->set = false;
+ bp->is_set = false;
return ERROR_OK;
}
@@ -815,7 +814,7 @@ static int mips_mips64_remove_breakpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (bp->set)
+ if (bp->is_set)
retval = mips_mips64_unset_breakpoint(target, bp);
if (bp->type == BKPT_HARD)
@@ -831,20 +830,20 @@ static int mips_mips64_unset_watchpoint(struct target *target,
struct mips64_common *mips64 = target->arch_info;
struct mips64_comparator *comparator_list = mips64->data_break_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- int wp_num = watchpoint->set - 1;
- if ((wp_num < 0) || (wp_num >= mips64->num_data_bpoints)) {
+ int wp_num = watchpoint->number;
+ if (wp_num >= mips64->num_data_bpoints) {
LOG_DEBUG("Invalid FP Comparator number in watchpoint");
return ERROR_OK;
}
comparator_list[wp_num].used = false;
comparator_list[wp_num].bp_value = 0;
target_write_u64(target, comparator_list[wp_num].reg_address + 0x18, 0);
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -876,7 +875,7 @@ static int mips_mips64_remove_watchpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
retval = mips_mips64_unset_watchpoint(target, watchpoint);
mips64->num_data_bpoints_avail++;
diff --git a/src/target/nds32.c b/src/target/nds32.c
index 12340ac..f0fb74d 100644
--- a/src/target/nds32.c
+++ b/src/target/nds32.c
@@ -1653,7 +1653,7 @@ int nds32_init_arch_info(struct target *target, struct nds32 *nds32)
nds32->syscall_break.asid = 0;
nds32->syscall_break.length = 4;
- nds32->syscall_break.set = 0;
+ nds32->syscall_break.is_set = false;
nds32->syscall_break.orig_instr = NULL;
nds32->syscall_break.next = NULL;
nds32->syscall_break.unique_id = 0x515CAll + target->target_number;
diff --git a/src/target/nds32_v3_common.c b/src/target/nds32_v3_common.c
index b0c3de6..8ff8e30 100644
--- a/src/target/nds32_v3_common.c
+++ b/src/target/nds32_v3_common.c
@@ -78,12 +78,12 @@ static int nds32_v3_debug_entry(struct nds32 *nds32, bool enable_watchpoint)
struct breakpoint *syscall_break = &(nds32->syscall_break);
if (nds32->virtual_hosting) {
- if (syscall_break->set) {
+ if (syscall_break->is_set) {
/** disable virtual hosting */
/* remove breakpoint at syscall entry */
target_remove_breakpoint(nds32->target, syscall_break);
- syscall_break->set = 0;
+ syscall_break->is_set = false;
uint32_t value_pc;
nds32_get_mapped_reg(nds32, PC, &value_pc);
@@ -209,7 +209,7 @@ static int nds32_v3_leave_debug_state(struct nds32 *nds32, bool enable_watchpoin
syscall_break->address = syscall_address;
syscall_break->type = BKPT_SOFT;
- syscall_break->set = 1;
+ syscall_break->is_set = true;
target_add_breakpoint(target, syscall_break);
}
diff --git a/src/target/openrisc/jsp_server.c b/src/target/openrisc/jsp_server.c
index e0a4475..54c9694 100644
--- a/src/target/openrisc/jsp_server.c
+++ b/src/target/openrisc/jsp_server.c
@@ -195,19 +195,22 @@ static int jsp_connection_closed(struct connection *connection)
return ERROR_OK;
}
+static const struct service_driver jsp_service_driver = {
+ .name = "jsp",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = jsp_new_connection,
+ .input_handler = jsp_input,
+ .connection_closed_handler = jsp_connection_closed,
+ .keep_client_alive_handler = NULL,
+};
+
int jsp_init(struct or1k_jtag *jtag_info, char *banner)
{
struct jsp_service *jsp_service = malloc(sizeof(struct jsp_service));
jsp_service->banner = banner;
jsp_service->jtag_info = jtag_info;
- return add_service("jsp",
- jsp_port,
- 1,
- jsp_new_connection,
- jsp_input,
- jsp_connection_closed,
- jsp_service);
+ return add_service(&jsp_service_driver, jsp_port, 1, jsp_service);
}
COMMAND_HANDLER(handle_jsp_port_command)
diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c
index 8fbcd96..77fa15d 100644
--- a/src/target/openrisc/or1k.c
+++ b/src/target/openrisc/or1k.c
@@ -923,9 +923,9 @@ static int or1k_add_breakpoint(struct target *target,
struct or1k_du *du_core = or1k_to_du(or1k);
uint8_t data;
- LOG_DEBUG("Adding breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, set: %d, id: %" PRIu32,
+ LOG_DEBUG("Adding breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, id: %" PRIu32,
breakpoint->address, breakpoint->length, breakpoint->type,
- breakpoint->set, breakpoint->unique_id);
+ breakpoint->unique_id);
/* Only support SW breakpoints for now. */
if (breakpoint->type == BKPT_HARD)
@@ -981,9 +981,9 @@ static int or1k_remove_breakpoint(struct target *target,
struct or1k_common *or1k = target_to_or1k(target);
struct or1k_du *du_core = or1k_to_du(or1k);
- LOG_DEBUG("Removing breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, set: %d, id: %" PRIu32,
+ LOG_DEBUG("Removing breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, id: %" PRIu32,
breakpoint->address, breakpoint->length, breakpoint->type,
- breakpoint->set, breakpoint->unique_id);
+ breakpoint->unique_id);
/* Only support SW breakpoints for now. */
if (breakpoint->type == BKPT_HARD)
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index cc38bd4..484db74 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -909,7 +909,7 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = true;
+ breakpoint->is_set = true;
return ERROR_OK;
}
@@ -969,7 +969,7 @@ int riscv_remove_breakpoint(struct target *target,
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = false;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -996,7 +996,7 @@ int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
int result = add_trigger(target, &trigger);
if (result != ERROR_OK)
return result;
- watchpoint->set = true;
+ watchpoint->is_set = true;
return ERROR_OK;
}
@@ -1012,7 +1012,7 @@ int riscv_remove_watchpoint(struct target *target,
int result = remove_trigger(target, &trigger);
if (result != ERROR_OK)
return result;
- watchpoint->set = false;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -1381,9 +1381,9 @@ static int disable_triggers(struct target *target, riscv_reg_t *state)
struct watchpoint *watchpoint = target->watchpoints;
int i = 0;
while (watchpoint) {
- LOG_DEBUG("watchpoint %d: set=%d", i, watchpoint->set);
- state[i] = watchpoint->set;
- if (watchpoint->set) {
+ LOG_DEBUG("watchpoint %d: set=%d", i, watchpoint->is_set);
+ state[i] = watchpoint->is_set;
+ if (watchpoint->is_set) {
if (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)
return ERROR_FAIL;
}
diff --git a/src/target/rtt.c b/src/target/rtt.c
index 7e556e1..4183021 100644
--- a/src/target/rtt.c
+++ b/src/target/rtt.c
@@ -15,6 +15,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stddef.h>
#include <stdint.h>
#include <helper/log.h>
diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index 9e60de5..bc1f417 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -68,7 +68,7 @@ enum {
};
/* GDB remote protocol does not differentiate between text and binary open modes. */
-static const int open_modeflags[12] = {
+static const int open_gdb_modeflags[12] = {
TARGET_O_RDONLY,
TARGET_O_RDONLY,
TARGET_O_RDWR,
@@ -83,6 +83,21 @@ static const int open_modeflags[12] = {
TARGET_O_RDWR | TARGET_O_CREAT | TARGET_O_APPEND
};
+static const int open_host_modeflags[12] = {
+ O_RDONLY,
+ O_RDONLY | O_BINARY,
+ O_RDWR,
+ O_RDWR | O_BINARY,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ O_RDWR | O_CREAT | O_TRUNC,
+ O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
+ O_WRONLY | O_CREAT | O_APPEND,
+ O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
+ O_RDWR | O_CREAT | O_APPEND,
+ O_RDWR | O_CREAT | O_APPEND | O_BINARY
+};
+
static int semihosting_common_fileio_info(struct target *target,
struct gdb_fileio_info *fileio_info);
static int semihosting_common_fileio_end(struct target *target, int result,
@@ -129,6 +144,11 @@ int semihosting_common_init(struct target *target, void *setup,
}
semihosting->is_active = false;
+ semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
+ semihosting->tcp_connection = NULL;
+ semihosting->stdin_fd = -1;
+ semihosting->stdout_fd = -1;
+ semihosting->stderr_fd = -1;
semihosting->is_fileio = false;
semihosting->hit_fileio = false;
semihosting->is_resumable = false;
@@ -154,6 +174,141 @@ int semihosting_common_init(struct target *target, void *setup,
return ERROR_OK;
}
+struct semihosting_tcp_service {
+ struct semihosting *semihosting;
+ char *name;
+ int error;
+};
+
+static bool semihosting_is_redirected(struct semihosting *semihosting, int fd)
+{
+ if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_NONE)
+ return false;
+
+ bool is_read_op = false;
+
+ switch (semihosting->op) {
+ /* check debug semihosting operations: READC, WRITEC and WRITE0 */
+ case SEMIHOSTING_SYS_READC:
+ is_read_op = true;
+ /* fall through */
+ case SEMIHOSTING_SYS_WRITEC:
+ case SEMIHOSTING_SYS_WRITE0:
+ /* debug operations are redirected when CFG is either DEBUG or ALL */
+ if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_STDIO)
+ return false;
+ break;
+
+ /* check stdio semihosting operations: READ and WRITE */
+ case SEMIHOSTING_SYS_READ:
+ is_read_op = true;
+ /* fall through */
+ case SEMIHOSTING_SYS_WRITE:
+ /* stdio operations are redirected when CFG is either STDIO or ALL */
+ if (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_DEBUG)
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+
+ if (is_read_op)
+ return fd == semihosting->stdin_fd;
+
+ /* write operation */
+ return fd == semihosting->stdout_fd || fd == semihosting->stderr_fd;
+}
+
+static ssize_t semihosting_redirect_write(struct semihosting *semihosting, void *buf, int size)
+{
+ if (!semihosting->tcp_connection) {
+ LOG_ERROR("No connected TCP client for semihosting");
+ semihosting->sys_errno = EBADF; /* Bad file number */
+ return -1;
+ }
+
+ struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
+
+ int retval = connection_write(semihosting->tcp_connection, buf, size);
+
+ if (retval < 0)
+ log_socket_error(service->name);
+
+ return retval;
+}
+
+static ssize_t semihosting_write(struct semihosting *semihosting, int fd, void *buf, int size)
+{
+ if (semihosting_is_redirected(semihosting, fd))
+ return semihosting_redirect_write(semihosting, buf, size);
+
+ /* default write */
+ return write(fd, buf, size);
+}
+
+static ssize_t semihosting_redirect_read(struct semihosting *semihosting, void *buf, int size)
+{
+ if (!semihosting->tcp_connection) {
+ LOG_ERROR("No connected TCP client for semihosting");
+ semihosting->sys_errno = EBADF; /* Bad file number */
+ return -1;
+ }
+
+ struct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;
+
+ service->error = ERROR_OK;
+ semihosting->tcp_connection->input_pending = true;
+
+ int retval = connection_read(semihosting->tcp_connection, buf, size);
+
+ if (retval <= 0)
+ service->error = ERROR_SERVER_REMOTE_CLOSED;
+
+ if (retval < 0)
+ log_socket_error(service->name);
+
+ semihosting->tcp_connection->input_pending = false;
+
+ return retval;
+}
+
+static inline int semihosting_putchar(struct semihosting *semihosting, int fd, int c)
+{
+ if (semihosting_is_redirected(semihosting, fd))
+ return semihosting_redirect_write(semihosting, &c, 1);
+
+ /* default putchar */
+ return putchar(c);
+}
+
+static inline ssize_t semihosting_read(struct semihosting *semihosting, int fd, void *buf, int size)
+{
+ if (semihosting_is_redirected(semihosting, fd))
+ return semihosting_redirect_read(semihosting, buf, size);
+
+ /* default read */
+ ssize_t result = read(fd, buf, size);
+ semihosting->sys_errno = errno;
+
+ return result;
+}
+
+static inline int semihosting_getchar(struct semihosting *semihosting, int fd)
+{
+ if (semihosting_is_redirected(semihosting, fd)) {
+ unsigned char c;
+
+ if (semihosting_redirect_read(semihosting, &c, 1) > 0)
+ return c;
+
+ return EOF;
+ }
+
+ /* default getchar */
+ return getchar();
+}
+
/**
* User operation parameter string storage buffer. Contains valid data when the
* TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
@@ -746,7 +901,7 @@ int semihosting_common(struct target *target)
fileio_info->identifier = "open";
fileio_info->param_1 = addr;
fileio_info->param_2 = len;
- fileio_info->param_3 = open_modeflags[mode];
+ fileio_info->param_3 = open_gdb_modeflags[mode];
fileio_info->param_4 = 0644;
}
} else {
@@ -756,20 +911,23 @@ int semihosting_common(struct target *target)
* - 4-7 ("w") for stdout,
* - 8-11 ("a") for stderr */
if (mode < 4) {
- semihosting->result = dup(
- STDIN_FILENO);
+ int fd = dup(STDIN_FILENO);
+ semihosting->result = fd;
+ semihosting->stdin_fd = fd;
semihosting->sys_errno = errno;
LOG_DEBUG("dup(STDIN)=%d",
(int)semihosting->result);
} else if (mode < 8) {
- semihosting->result = dup(
- STDOUT_FILENO);
+ int fd = dup(STDOUT_FILENO);
+ semihosting->result = fd;
+ semihosting->stdout_fd = fd;
semihosting->sys_errno = errno;
LOG_DEBUG("dup(STDOUT)=%d",
(int)semihosting->result);
} else {
- semihosting->result = dup(
- STDERR_FILENO);
+ int fd = dup(STDERR_FILENO);
+ semihosting->result = fd;
+ semihosting->stderr_fd = fd;
semihosting->sys_errno = errno;
LOG_DEBUG("dup(STDERR)=%d",
(int)semihosting->result);
@@ -779,7 +937,7 @@ int semihosting_common(struct target *target)
* otherwise it will fail to reopen a previously
* written file */
semihosting->result = open((char *)fn,
- open_modeflags[mode],
+ open_host_modeflags[mode],
0644);
semihosting->sys_errno = errno;
LOG_DEBUG("open('%s')=%d", fn,
@@ -845,8 +1003,7 @@ int semihosting_common(struct target *target)
semihosting->result = -1;
semihosting->sys_errno = ENOMEM;
} else {
- semihosting->result = read(fd, buf, len);
- semihosting->sys_errno = errno;
+ semihosting->result = semihosting_read(semihosting, fd, buf, len);
LOG_DEBUG("read(%d, 0x%" PRIx64 ", %zu)=%d",
fd,
addr,
@@ -886,7 +1043,7 @@ int semihosting_common(struct target *target)
LOG_ERROR("SYS_READC not supported by semihosting fileio");
return ERROR_FAIL;
}
- semihosting->result = getchar();
+ semihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd);
LOG_DEBUG("getchar()=%d", (int)semihosting->result);
break;
@@ -1189,7 +1346,7 @@ int semihosting_common(struct target *target)
free(buf);
return retval;
}
- semihosting->result = write(fd, buf, len);
+ semihosting->result = semihosting_write(semihosting, fd, buf, len);
semihosting->sys_errno = errno;
LOG_DEBUG("write(%d, 0x%" PRIx64 ", %zu)=%d",
fd,
@@ -1234,7 +1391,7 @@ int semihosting_common(struct target *target)
retval = target_read_memory(target, addr, 1, 1, &c);
if (retval != ERROR_OK)
return retval;
- putchar(c);
+ semihosting_putchar(semihosting, semihosting->stdout_fd, c);
semihosting->result = 0;
}
break;
@@ -1278,7 +1435,7 @@ int semihosting_common(struct target *target)
return retval;
if (!c)
break;
- putchar(c);
+ semihosting_putchar(semihosting, semihosting->stdout_fd, c);
} while (1);
semihosting->result = 0;
}
@@ -1557,6 +1714,70 @@ static void semihosting_set_field(struct target *target, uint64_t value,
target_buffer_set_u32(target, fields + (index * 4), value);
}
+/* -------------------------------------------------------------------------
+ * Semihosting redirect over TCP structs and functions */
+
+static int semihosting_service_new_connection_handler(struct connection *connection)
+{
+ struct semihosting_tcp_service *service = connection->service->priv;
+ service->semihosting->tcp_connection = connection;
+
+ return ERROR_OK;
+}
+
+static int semihosting_service_input_handler(struct connection *connection)
+{
+ struct semihosting_tcp_service *service = connection->service->priv;
+
+ if (!connection->input_pending) {
+ /* consume received data, not for semihosting IO */
+ const int buf_len = 100;
+ char buf[buf_len];
+ int bytes_read = connection_read(connection, buf, buf_len);
+
+ if (bytes_read == 0) {
+ return ERROR_SERVER_REMOTE_CLOSED;
+ } else if (bytes_read == -1) {
+ LOG_ERROR("error during read: %s", strerror(errno));
+ return ERROR_SERVER_REMOTE_CLOSED;
+ }
+ } else if (service->error != ERROR_OK) {
+ return ERROR_SERVER_REMOTE_CLOSED;
+ }
+
+ return ERROR_OK;
+}
+
+static int semihosting_service_connection_closed_handler(struct connection *connection)
+{
+ struct semihosting_tcp_service *service = connection->service->priv;
+ if (service) {
+ free(service->name);
+ free(service);
+ }
+
+ return ERROR_OK;
+}
+
+static void semihosting_tcp_close_cnx(struct semihosting *semihosting)
+{
+ if (!semihosting->tcp_connection)
+ return;
+
+ struct service *service = semihosting->tcp_connection->service;
+ remove_service(service->name, service->port);
+ semihosting->tcp_connection = NULL;
+
+}
+
+static const struct service_driver semihosting_service_driver = {
+ .name = "semihosting",
+ .new_connection_during_keep_alive_handler = NULL,
+ .new_connection_handler = semihosting_service_new_connection_handler,
+ .input_handler = semihosting_service_input_handler,
+ .connection_closed_handler = semihosting_service_connection_closed_handler,
+ .keep_client_alive_handler = NULL,
+};
/* -------------------------------------------------------------------------
* Common semihosting commands handlers. */
@@ -1602,6 +1823,91 @@ COMMAND_HANDLER(handle_common_semihosting_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_common_semihosting_redirect_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (target == NULL) {
+ LOG_ERROR("No target selected");
+ return ERROR_FAIL;
+ }
+
+ struct semihosting *semihosting = target->semihosting;
+ if (!semihosting) {
+ command_print(CMD, "semihosting not supported for current target");
+ return ERROR_FAIL;
+ }
+
+ if (!semihosting->is_active) {
+ command_print(CMD, "semihosting not yet enabled for current target");
+ return ERROR_FAIL;
+ }
+
+ enum semihosting_redirect_config cfg;
+ const char *port;
+
+ if (CMD_ARGC < 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (strcmp(CMD_ARGV[0], "disable") == 0) {
+ cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
+ if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ } else if (strcmp(CMD_ARGV[0], "tcp") == 0) {
+ if (CMD_ARGC < 2 || CMD_ARGC > 3)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ port = CMD_ARGV[1];
+
+ cfg = SEMIHOSTING_REDIRECT_CFG_ALL;
+ if (CMD_ARGC == 3) {
+ if (strcmp(CMD_ARGV[2], "debug") == 0)
+ cfg = SEMIHOSTING_REDIRECT_CFG_DEBUG;
+ else if (strcmp(CMD_ARGV[2], "stdio") == 0)
+ cfg = SEMIHOSTING_REDIRECT_CFG_STDIO;
+ else if (strcmp(CMD_ARGV[2], "all") != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ } else {
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ semihosting_tcp_close_cnx(semihosting);
+ semihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;
+
+ if (cfg != SEMIHOSTING_REDIRECT_CFG_NONE) {
+ struct semihosting_tcp_service *service =
+ calloc(1, sizeof(struct semihosting_tcp_service));
+ if (!service) {
+ LOG_ERROR("Failed to allocate semihosting TCP service.");
+ return ERROR_FAIL;
+ }
+
+ service->semihosting = semihosting;
+
+ service->name = alloc_printf("%s semihosting service", target_name(target));
+ if (!service->name) {
+ LOG_ERROR("Out of memory");
+ free(service);
+ return ERROR_FAIL;
+ }
+
+ int ret = add_service(&semihosting_service_driver,
+ port, 1, service);
+
+ if (ret != ERROR_OK) {
+ LOG_ERROR("failed to initialize %s", service->name);
+ free(service->name);
+ free(service);
+ return ERROR_FAIL;
+ }
+ }
+
+ semihosting->redirect_cfg = cfg;
+
+ return ERROR_OK;
+}
+
COMMAND_HANDLER(handle_common_semihosting_fileio_command)
{
struct target *target = get_current_target(CMD_CTX);
@@ -1721,35 +2027,42 @@ COMMAND_HANDLER(handle_common_semihosting_read_user_param_command)
const struct command_registration semihosting_common_handlers[] = {
{
- "semihosting",
+ .name = "semihosting",
.handler = handle_common_semihosting_command,
.mode = COMMAND_EXEC,
.usage = "['enable'|'disable']",
.help = "activate support for semihosting operations",
},
{
- "semihosting_cmdline",
+ .name = "semihosting_redirect",
+ .handler = handle_common_semihosting_redirect_command,
+ .mode = COMMAND_EXEC,
+ .usage = "(disable | tcp <port> ['debug'|'stdio'|'all'])",
+ .help = "redirect semihosting IO",
+ },
+ {
+ .name = "semihosting_cmdline",
.handler = handle_common_semihosting_cmdline,
.mode = COMMAND_EXEC,
.usage = "arguments",
.help = "command line arguments to be passed to program",
},
{
- "semihosting_fileio",
+ .name = "semihosting_fileio",
.handler = handle_common_semihosting_fileio_command,
.mode = COMMAND_EXEC,
.usage = "['enable'|'disable']",
.help = "activate support for semihosting fileio operations",
},
{
- "semihosting_resexit",
+ .name = "semihosting_resexit",
.handler = handle_common_semihosting_resumable_exit_command,
.mode = COMMAND_EXEC,
.usage = "['enable'|'disable']",
.help = "activate support for semihosting resumable exit",
},
{
- "semihosting_read_user_param",
+ .name = "semihosting_read_user_param",
.handler = handle_common_semihosting_read_user_param_command,
.mode = COMMAND_EXEC,
.usage = "",
diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h
index 6eb9ca2..459faf6 100644
--- a/src/target/semihosting_common.h
+++ b/src/target/semihosting_common.h
@@ -26,6 +26,7 @@
#include <stdbool.h>
#include <time.h>
#include "helper/replacements.h"
+#include <server/server.h>
/*
* According to:
@@ -95,6 +96,13 @@ enum semihosting_reported_exceptions {
ADP_STOPPED_RUN_TIME_ERROR = ((2 << 16) + 35),
};
+enum semihosting_redirect_config {
+ SEMIHOSTING_REDIRECT_CFG_NONE,
+ SEMIHOSTING_REDIRECT_CFG_DEBUG,
+ SEMIHOSTING_REDIRECT_CFG_STDIO,
+ SEMIHOSTING_REDIRECT_CFG_ALL,
+};
+
struct target;
/*
@@ -105,6 +113,15 @@ struct semihosting {
/** A flag reporting whether semihosting is active. */
bool is_active;
+ /** Semihosting STDIO file descriptors */
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ /** redirection configuration, NONE by default */
+ enum semihosting_redirect_config redirect_cfg;
+
+ /** Handle to redirect semihosting print via tcp */
+ struct connection *tcp_connection;
+
/** A flag reporting whether semihosting fileio is active. */
bool is_fileio;
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index cd98d68..0e46992 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -206,6 +206,32 @@ proc init_target_events {} {
proc init_board {} {
}
+proc mem2array {arrayname bitwidth address count {phys ""}} {
+ echo "DEPRECATED! use 'read_memory' not 'mem2array'"
+
+ upvar $arrayname $arrayname
+ set $arrayname ""
+ set i 0
+
+ foreach elem [read_memory $address $bitwidth $count {*}$phys] {
+ set ${arrayname}($i) $elem
+ incr i
+ }
+}
+
+proc array2mem {arrayname bitwidth address count {phys ""}} {
+ echo "DEPRECATED! use 'write_memory' not 'array2mem'"
+
+ upvar $arrayname $arrayname
+ set data ""
+
+ for {set i 0} {$i < $count} {incr i} {
+ lappend data [expr $${arrayname}($i)]
+ }
+
+ write_memory $address $bitwidth $data {*}$phys
+}
+
# smp_on/smp_off were already DEPRECATED in v0.11.0 through http://openocd.zylin.com/4615
lappend _telnet_autocomplete_skip "aarch64 smp_on"
proc "aarch64 smp_on" {args} {
diff --git a/src/target/stm8.c b/src/target/stm8.c
index 21fc8c5..4102082 100644
--- a/src/target/stm8.c
+++ b/src/target/stm8.c
@@ -1370,7 +1370,7 @@ static void stm8_enable_breakpoints(struct target *target)
/* set any pending breakpoints */
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
stm8_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
}
@@ -1383,7 +1383,7 @@ static int stm8_set_breakpoint(struct target *target,
struct stm8_comparator *comparator_list = stm8->hw_break_list;
int retval;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -1398,7 +1398,7 @@ static int stm8_set_breakpoint(struct target *target,
breakpoint->unique_id);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = bp_num + 1;
+ breakpoint_hw_set(breakpoint, bp_num);
comparator_list[bp_num].used = true;
comparator_list[bp_num].bp_value = breakpoint->address;
comparator_list[bp_num].type = HWBRK_EXEC;
@@ -1435,7 +1435,7 @@ static int stm8_set_breakpoint(struct target *target,
} else {
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = 1; /* Any nice value but 0 */
+ breakpoint->is_set = true;
}
return ERROR_OK;
@@ -1476,14 +1476,14 @@ static int stm8_unset_breakpoint(struct target *target,
struct stm8_comparator *comparator_list = stm8->hw_break_list;
int retval;
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
- int bp_num = breakpoint->set - 1;
- if ((bp_num < 0) || (bp_num >= stm8->num_hw_bpoints)) {
+ int bp_num = breakpoint->number;
+ if (bp_num >= stm8->num_hw_bpoints) {
LOG_DEBUG("Invalid comparator number in breakpoint (bpid: %" PRIu32 ")",
breakpoint->unique_id);
return ERROR_OK;
@@ -1517,7 +1517,7 @@ static int stm8_unset_breakpoint(struct target *target,
} else
return ERROR_FAIL;
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
return ERROR_OK;
}
@@ -1533,7 +1533,7 @@ static int stm8_remove_breakpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (breakpoint->set)
+ if (breakpoint->is_set)
stm8_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
@@ -1550,7 +1550,7 @@ static int stm8_set_watchpoint(struct target *target,
int wp_num = 0;
int ret;
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}
@@ -1593,7 +1593,7 @@ static int stm8_set_watchpoint(struct target *target,
return ret;
}
- watchpoint->set = wp_num + 1;
+ watchpoint_set(watchpoint, wp_num);
LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "",
wp_num,
@@ -1627,7 +1627,7 @@ static void stm8_enable_watchpoints(struct target *target)
/* set any pending watchpoints */
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
stm8_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
@@ -1640,18 +1640,18 @@ static int stm8_unset_watchpoint(struct target *target,
struct stm8_common *stm8 = target_to_stm8(target);
struct stm8_comparator *comparator_list = stm8->hw_break_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- int wp_num = watchpoint->set - 1;
- if ((wp_num < 0) || (wp_num >= stm8->num_hw_bpoints)) {
+ int wp_num = watchpoint->number;
+ if (wp_num >= stm8->num_hw_bpoints) {
LOG_DEBUG("Invalid hw comparator number in watchpoint");
return ERROR_OK;
}
comparator_list[wp_num].used = false;
- watchpoint->set = 0;
+ watchpoint->is_set = false;
stm8_set_hwbreak(target, comparator_list);
@@ -1669,7 +1669,7 @@ static int stm8_remove_watchpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
stm8_unset_watchpoint(target, watchpoint);
stm8->num_hw_bpoints_avail++;
diff --git a/src/target/target.c b/src/target/target.c
index 1959bbe..6cbfc6e 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -3972,26 +3972,26 @@ static int handle_bp_command_list(struct command_invocation *cmd)
if (breakpoint->type == BKPT_SOFT) {
char *buf = buf_to_hex_str(breakpoint->orig_instr,
breakpoint->length);
- command_print(cmd, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, %i, 0x%s",
+ command_print(cmd, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, 0x%s",
breakpoint->address,
breakpoint->length,
- breakpoint->set, buf);
+ buf);
free(buf);
} else {
if ((breakpoint->address == 0) && (breakpoint->asid != 0))
- command_print(cmd, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %i",
+ command_print(cmd, "Context breakpoint: 0x%8.8" PRIx32 ", 0x%x, %u",
breakpoint->asid,
- breakpoint->length, breakpoint->set);
+ breakpoint->length, breakpoint->number);
else if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {
- command_print(cmd, "Hybrid breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i",
+ command_print(cmd, "Hybrid breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %u",
breakpoint->address,
- breakpoint->length, breakpoint->set);
+ breakpoint->length, breakpoint->number);
command_print(cmd, "\t|--->linked with ContextID: 0x%8.8" PRIx32,
breakpoint->asid);
} else
- command_print(cmd, "Breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %i",
+ command_print(cmd, "Breakpoint(IVA): " TARGET_ADDR_FMT ", 0x%x, %u",
breakpoint->address,
- breakpoint->length, breakpoint->set);
+ breakpoint->length, breakpoint->number);
}
breakpoint = breakpoint->next;
@@ -4436,27 +4436,12 @@ static int new_u64_array_element(Jim_Interp *interp, const char *varname, int id
return result;
}
-static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- struct command_context *context;
- struct target *target;
-
- context = current_command_context(interp);
- assert(context);
-
- target = get_current_target(context);
- if (!target) {
- LOG_ERROR("mem2array: no current target");
- return JIM_ERR;
- }
-
- return target_mem2array(interp, target, argc - 1, argv + 1);
-}
-
static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv)
{
int e;
+ LOG_WARNING("DEPRECATED! use 'read_memory' not 'mem2array'");
+
/* argv[0] = name of array to receive the data
* argv[1] = desired element width in bits
* argv[2] = memory address
@@ -4609,6 +4594,161 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc,
return e;
}
+static int target_jim_read_memory(Jim_Interp *interp, int argc,
+ Jim_Obj * const *argv)
+{
+ /*
+ * argv[1] = memory address
+ * argv[2] = desired element width in bits
+ * argv[3] = number of elements to read
+ * argv[4] = optional "phys"
+ */
+
+ if (argc < 4 || argc > 5) {
+ Jim_WrongNumArgs(interp, 1, argv, "address width count ['phys']");
+ return JIM_ERR;
+ }
+
+ /* Arg 1: Memory address. */
+ jim_wide wide_addr;
+ int e;
+ e = Jim_GetWide(interp, argv[1], &wide_addr);
+
+ if (e != JIM_OK)
+ return e;
+
+ target_addr_t addr = (target_addr_t)wide_addr;
+
+ /* Arg 2: Bit width of one element. */
+ long l;
+ e = Jim_GetLong(interp, argv[2], &l);
+
+ if (e != JIM_OK)
+ return e;
+
+ const unsigned int width_bits = l;
+
+ /* Arg 3: Number of elements to read. */
+ e = Jim_GetLong(interp, argv[3], &l);
+
+ if (e != JIM_OK)
+ return e;
+
+ size_t count = l;
+
+ /* Arg 4: Optional 'phys'. */
+ bool is_phys = false;
+
+ if (argc > 4) {
+ const char *phys = Jim_GetString(argv[4], NULL);
+
+ if (strcmp(phys, "phys")) {
+ Jim_SetResultFormatted(interp, "invalid argument '%s', must be 'phys'", phys);
+ return JIM_ERR;
+ }
+
+ is_phys = true;
+ }
+
+ switch (width_bits) {
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ break;
+ default:
+ Jim_SetResultString(interp, "invalid width, must be 8, 16, 32 or 64", -1);
+ return JIM_ERR;
+ }
+
+ const unsigned int width = width_bits / 8;
+
+ if ((addr + (count * width)) < addr) {
+ Jim_SetResultString(interp, "read_memory: addr + count wraps to zero", -1);
+ return JIM_ERR;
+ }
+
+ if (count > 65536) {
+ Jim_SetResultString(interp, "read_memory: too large read request, exeeds 64K elements", -1);
+ return JIM_ERR;
+ }
+
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx != NULL);
+ struct target *target = get_current_target(cmd_ctx);
+
+ const size_t buffersize = 4096;
+ uint8_t *buffer = malloc(buffersize);
+
+ if (!buffer) {
+ LOG_ERROR("Failed to allocate memory");
+ return JIM_ERR;
+ }
+
+ Jim_Obj *result_list = Jim_NewListObj(interp, NULL, 0);
+ Jim_IncrRefCount(result_list);
+
+ while (count > 0) {
+ const unsigned int max_chunk_len = buffersize / width;
+ const size_t chunk_len = MIN(count, max_chunk_len);
+
+ int retval;
+
+ if (is_phys)
+ retval = target_read_phys_memory(target, addr, width, chunk_len, buffer);
+ else
+ retval = target_read_memory(target, addr, width, chunk_len, buffer);
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed",
+ addr, width_bits, chunk_len);
+ Jim_SetResultString(interp, "read_memory: failed to read memory", -1);
+ e = JIM_ERR;
+ break;
+ }
+
+ for (size_t i = 0; i < chunk_len ; i++) {
+ uint64_t v = 0;
+
+ switch (width) {
+ case 8:
+ v = target_buffer_get_u64(target, &buffer[i * width]);
+ break;
+ case 4:
+ v = target_buffer_get_u32(target, &buffer[i * width]);
+ break;
+ case 2:
+ v = target_buffer_get_u16(target, &buffer[i * width]);
+ break;
+ case 1:
+ v = buffer[i];
+ break;
+ }
+
+ char value_buf[11];
+ snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v);
+
+ Jim_ListAppendElement(interp, result_list,
+ Jim_NewStringObj(interp, value_buf, -1));
+ }
+
+ count -= chunk_len;
+ addr += chunk_len * width;
+ }
+
+ free(buffer);
+
+ if (e != JIM_OK) {
+ Jim_DecrRefCount(interp, result_list);
+ return e;
+ }
+
+ Jim_SetResult(interp, result_list);
+ Jim_DecrRefCount(interp, result_list);
+
+ return JIM_OK;
+}
+
static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val)
{
char *namebuf = alloc_printf("%s(%zu)", varname, idx);
@@ -4634,28 +4774,13 @@ static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t
return result;
}
-static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- struct command_context *context;
- struct target *target;
-
- context = current_command_context(interp);
- assert(context);
-
- target = get_current_target(context);
- if (!target) {
- LOG_ERROR("array2mem: no current target");
- return JIM_ERR;
- }
-
- return target_array2mem(interp, target, argc-1, argv + 1);
-}
-
static int target_array2mem(Jim_Interp *interp, struct target *target,
int argc, Jim_Obj *const *argv)
{
int e;
+ LOG_WARNING("DEPRECATED! use 'write_memory' not 'array2mem'");
+
/* argv[0] = name of array from which to read the data
* argv[1] = desired element width in bits
* argv[2] = memory address
@@ -4819,6 +4944,144 @@ static int target_array2mem(Jim_Interp *interp, struct target *target,
return e;
}
+static int target_jim_write_memory(Jim_Interp *interp, int argc,
+ Jim_Obj * const *argv)
+{
+ /*
+ * argv[1] = memory address
+ * argv[2] = desired element width in bits
+ * argv[3] = list of data to write
+ * argv[4] = optional "phys"
+ */
+
+ if (argc < 4 || argc > 5) {
+ Jim_WrongNumArgs(interp, 1, argv, "address width data ['phys']");
+ return JIM_ERR;
+ }
+
+ /* Arg 1: Memory address. */
+ int e;
+ jim_wide wide_addr;
+ e = Jim_GetWide(interp, argv[1], &wide_addr);
+
+ if (e != JIM_OK)
+ return e;
+
+ target_addr_t addr = (target_addr_t)wide_addr;
+
+ /* Arg 2: Bit width of one element. */
+ long l;
+ e = Jim_GetLong(interp, argv[2], &l);
+
+ if (e != JIM_OK)
+ return e;
+
+ const unsigned int width_bits = l;
+ size_t count = Jim_ListLength(interp, argv[3]);
+
+ /* Arg 4: Optional 'phys'. */
+ bool is_phys = false;
+
+ if (argc > 4) {
+ const char *phys = Jim_GetString(argv[4], NULL);
+
+ if (strcmp(phys, "phys")) {
+ Jim_SetResultFormatted(interp, "invalid argument '%s', must be 'phys'", phys);
+ return JIM_ERR;
+ }
+
+ is_phys = true;
+ }
+
+ switch (width_bits) {
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ break;
+ default:
+ Jim_SetResultString(interp, "invalid width, must be 8, 16, 32 or 64", -1);
+ return JIM_ERR;
+ }
+
+ const unsigned int width = width_bits / 8;
+
+ if ((addr + (count * width)) < addr) {
+ Jim_SetResultString(interp, "write_memory: addr + len wraps to zero", -1);
+ return JIM_ERR;
+ }
+
+ if (count > 65536) {
+ Jim_SetResultString(interp, "write_memory: too large memory write request, exceeds 64K elements", -1);
+ return JIM_ERR;
+ }
+
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx != NULL);
+ struct target *target = get_current_target(cmd_ctx);
+
+ const size_t buffersize = 4096;
+ uint8_t *buffer = malloc(buffersize);
+
+ if (!buffer) {
+ LOG_ERROR("Failed to allocate memory");
+ return JIM_ERR;
+ }
+
+ size_t j = 0;
+
+ while (count > 0) {
+ const unsigned int max_chunk_len = buffersize / width;
+ const size_t chunk_len = MIN(count, max_chunk_len);
+
+ for (size_t i = 0; i < chunk_len; i++, j++) {
+ Jim_Obj *tmp = Jim_ListGetIndex(interp, argv[3], j);
+ jim_wide element_wide;
+ Jim_GetWide(interp, tmp, &element_wide);
+
+ const uint64_t v = element_wide;
+
+ switch (width) {
+ case 8:
+ target_buffer_set_u64(target, &buffer[i * width], v);
+ break;
+ case 4:
+ target_buffer_set_u32(target, &buffer[i * width], v);
+ break;
+ case 2:
+ target_buffer_set_u16(target, &buffer[i * width], v);
+ break;
+ case 1:
+ buffer[i] = v & 0x0ff;
+ break;
+ }
+ }
+
+ count -= chunk_len;
+
+ int retval;
+
+ if (is_phys)
+ retval = target_write_phys_memory(target, addr, width, chunk_len, buffer);
+ else
+ retval = target_write_memory(target, addr, width, chunk_len, buffer);
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("write_memory: write at " TARGET_ADDR_FMT " with width=%u and count=%zu failed",
+ addr, width_bits, chunk_len);
+ Jim_SetResultString(interp, "write_memory: failed to write memory", -1);
+ e = JIM_ERR;
+ break;
+ }
+
+ addr += chunk_len * width;
+ }
+
+ free(buffer);
+
+ return e;
+}
+
/* FIX? should we propagate errors here rather than printing them
* and continuing?
*/
@@ -4868,6 +5131,144 @@ void target_handle_event(struct target *target, enum target_event e)
}
}
+static int target_jim_get_reg(Jim_Interp *interp, int argc,
+ Jim_Obj * const *argv)
+{
+ bool force = false;
+
+ if (argc == 3) {
+ const char *option = Jim_GetString(argv[1], NULL);
+
+ if (!strcmp(option, "-force")) {
+ argc--;
+ argv++;
+ force = true;
+ } else {
+ Jim_SetResultFormatted(interp, "invalid option '%s'", option);
+ return JIM_ERR;
+ }
+ }
+
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "[-force] list");
+ return JIM_ERR;
+ }
+
+ const int length = Jim_ListLength(interp, argv[1]);
+
+ Jim_Obj *result_dict = Jim_NewDictObj(interp, NULL, 0);
+
+ if (!result_dict)
+ return JIM_ERR;
+
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx != NULL);
+ const struct target *target = get_current_target(cmd_ctx);
+
+ for (int i = 0; i < length; i++) {
+ Jim_Obj *elem = Jim_ListGetIndex(interp, argv[1], i);
+
+ if (!elem)
+ return JIM_ERR;
+
+ const char *reg_name = Jim_String(elem);
+
+ struct reg *reg = register_get_by_name(target->reg_cache, reg_name,
+ false);
+
+ if (!reg || !reg->exist) {
+ Jim_SetResultFormatted(interp, "unknown register '%s'", reg_name);
+ return JIM_ERR;
+ }
+
+ if (force) {
+ int retval = reg->type->get(reg);
+
+ if (retval != ERROR_OK) {
+ Jim_SetResultFormatted(interp, "failed to read register '%s'",
+ reg_name);
+ return JIM_ERR;
+ }
+ }
+
+ char *reg_value = buf_to_hex_str(reg->value, reg->size);
+
+ if (!reg_value) {
+ LOG_ERROR("Failed to allocate memory");
+ return JIM_ERR;
+ }
+
+ char *tmp = alloc_printf("0x%s", reg_value);
+
+ free(reg_value);
+
+ if (!tmp) {
+ LOG_ERROR("Failed to allocate memory");
+ return JIM_ERR;
+ }
+
+ Jim_DictAddElement(interp, result_dict, elem,
+ Jim_NewStringObj(interp, tmp, -1));
+
+ free(tmp);
+ }
+
+ Jim_SetResult(interp, result_dict);
+
+ return JIM_OK;
+}
+
+static int target_jim_set_reg(Jim_Interp *interp, int argc,
+ Jim_Obj * const *argv)
+{
+ if (argc != 2) {
+ Jim_WrongNumArgs(interp, 1, argv, "dict");
+ return JIM_ERR;
+ }
+
+ int tmp;
+ Jim_Obj **dict = Jim_DictPairs(interp, argv[1], &tmp);
+
+ if (!dict)
+ return JIM_ERR;
+
+ const unsigned int length = tmp;
+ struct command_context *cmd_ctx = current_command_context(interp);
+ assert(cmd_ctx);
+ const struct target *target = get_current_target(cmd_ctx);
+
+ for (unsigned int i = 0; i < length; i += 2) {
+ const char *reg_name = Jim_String(dict[i]);
+ const char *reg_value = Jim_String(dict[i + 1]);
+ struct reg *reg = register_get_by_name(target->reg_cache, reg_name,
+ false);
+
+ if (!reg || !reg->exist) {
+ Jim_SetResultFormatted(interp, "unknown register '%s'", reg_name);
+ return JIM_ERR;
+ }
+
+ uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
+
+ if (!buf) {
+ LOG_ERROR("Failed to allocate memory");
+ return JIM_ERR;
+ }
+
+ str_to_buf(reg_value, strlen(reg_value), buf, reg->size, 0);
+ int retval = reg->type->set(reg, buf);
+ free(buf);
+
+ if (retval != ERROR_OK) {
+ Jim_SetResultFormatted(interp, "failed to set '%s' to register '%s'",
+ reg_value, reg_name);
+ return JIM_ERR;
+ }
+ }
+
+ return JIM_OK;
+}
+
/**
* Returns true only if the target has a handler for the specified event.
*/
@@ -5651,6 +6052,34 @@ static const struct command_registration target_instance_command_handlers[] = {
.usage = "arrayname bitwidth address count",
},
{
+ .name = "get_reg",
+ .mode = COMMAND_EXEC,
+ .jim_handler = target_jim_get_reg,
+ .help = "Get register values from the target",
+ .usage = "list",
+ },
+ {
+ .name = "set_reg",
+ .mode = COMMAND_EXEC,
+ .jim_handler = target_jim_set_reg,
+ .help = "Set target register values",
+ .usage = "dict",
+ },
+ {
+ .name = "read_memory",
+ .mode = COMMAND_EXEC,
+ .jim_handler = target_jim_read_memory,
+ .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory",
+ .usage = "address width count ['phys']",
+ },
+ {
+ .name = "write_memory",
+ .mode = COMMAND_EXEC,
+ .jim_handler = target_jim_write_memory,
+ .help = "Write Tcl list of 8/16/32/64 bit numbers to target memory",
+ .usage = "address width data ['phys']",
+ },
+ {
.name = "eventlist",
.handler = handle_target_event_list,
.mode = COMMAND_EXEC,
@@ -6720,20 +7149,32 @@ static const struct command_registration target_exec_command_handlers[] = {
.usage = "filename [offset [type]]",
},
{
- .name = "mem2array",
+ .name = "get_reg",
.mode = COMMAND_EXEC,
- .jim_handler = jim_mem2array,
- .help = "read 8/16/32 bit memory and return as a TCL array "
- "for script processing",
- .usage = "arrayname bitwidth address count",
+ .jim_handler = target_jim_get_reg,
+ .help = "Get register values from the target",
+ .usage = "list",
},
{
- .name = "array2mem",
+ .name = "set_reg",
.mode = COMMAND_EXEC,
- .jim_handler = jim_array2mem,
- .help = "convert a TCL array to memory locations "
- "and write the 8/16/32 bit values",
- .usage = "arrayname bitwidth address count",
+ .jim_handler = target_jim_set_reg,
+ .help = "Set target register values",
+ .usage = "dict",
+ },
+ {
+ .name = "read_memory",
+ .mode = COMMAND_EXEC,
+ .jim_handler = target_jim_read_memory,
+ .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory",
+ .usage = "address width count ['phys']",
+ },
+ {
+ .name = "write_memory",
+ .mode = COMMAND_EXEC,
+ .jim_handler = target_jim_write_memory,
+ .help = "Write Tcl list of 8/16/32/64 bit numbers to target memory",
+ .usage = "address width data ['phys']",
},
{
.name = "reset_nag",
diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c
index a009bfe..d119be1 100644
--- a/src/target/x86_32_common.c
+++ b/src/target/x86_32_common.c
@@ -862,7 +862,7 @@ int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp)
{
if (check_not_halted(t))
return ERROR_TARGET_NOT_HALTED;
- if (wp->set)
+ if (wp->is_set)
unset_watchpoint(t, wp);
return ERROR_OK;
}
@@ -883,7 +883,7 @@ int x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp)
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
if (check_not_halted(t))
return ERROR_TARGET_NOT_HALTED;
- if (bp->set)
+ if (bp->is_set)
unset_breakpoint(t, bp);
return ERROR_OK;
@@ -995,7 +995,7 @@ static int set_hwbp(struct target *t, struct breakpoint *bp)
}
if (set_debug_regs(t, bp->address, hwbp_num, DR7_BP_EXECUTE, 1) != ERROR_OK)
return ERROR_FAIL;
- bp->set = hwbp_num + 1;
+ breakpoint_hw_set(bp, hwbp_num);
debug_reg_list[hwbp_num].used = 1;
debug_reg_list[hwbp_num].bp_value = bp->address;
LOG_USER("%s hardware breakpoint %" PRIu32 " set at 0x%08" PRIx32 " (hwreg=%" PRIu8 ")", __func__,
@@ -1007,9 +1007,9 @@ static int unset_hwbp(struct target *t, struct breakpoint *bp)
{
struct x86_32_common *x86_32 = target_to_x86_32(t);
struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;
- int hwbp_num = bp->set - 1;
+ int hwbp_num = bp->number;
- if ((hwbp_num < 0) || (hwbp_num >= x86_32->num_hw_bpoints)) {
+ if (hwbp_num >= x86_32->num_hw_bpoints) {
LOG_ERROR("%s invalid breakpoint number=%d, bpid=%" PRIu32,
__func__, hwbp_num, bp->unique_id);
return ERROR_OK;
@@ -1055,7 +1055,7 @@ static int set_swbp(struct target *t, struct breakpoint *bp)
__func__, readback, *bp->orig_instr);
return ERROR_FAIL;
}
- bp->set = SW_BP_OPCODE; /* just non 0 */
+ bp->is_set = true;
/* add the memory patch */
struct swbp_mem_patch *new_patch = malloc(sizeof(struct swbp_mem_patch));
@@ -1134,7 +1134,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
int error = ERROR_OK;
struct x86_32_common *x86_32 = target_to_x86_32(t);
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
- if (bp->set) {
+ if (bp->is_set) {
LOG_ERROR("breakpoint already set");
return error;
}
@@ -1164,7 +1164,7 @@ static int set_breakpoint(struct target *t, struct breakpoint *bp)
static int unset_breakpoint(struct target *t, struct breakpoint *bp)
{
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, bp->type, bp->address);
- if (!bp->set) {
+ if (!bp->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
@@ -1182,7 +1182,7 @@ static int unset_breakpoint(struct target *t, struct breakpoint *bp)
return ERROR_FAIL;
}
}
- bp->set = 0;
+ bp->is_set = false;
return ERROR_OK;
}
@@ -1193,7 +1193,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp)
int wp_num = 0;
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, wp->rw, wp->address);
- if (wp->set) {
+ if (wp->is_set) {
LOG_ERROR("%s watchpoint already set", __func__);
return ERROR_OK;
}
@@ -1233,7 +1233,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp)
LOG_ERROR("%s only 'access' or 'write' watchpoints are supported", __func__);
break;
}
- wp->set = wp_num + 1;
+ watchpoint_set(wp, wp_num);
debug_reg_list[wp_num].used = 1;
debug_reg_list[wp_num].bp_value = wp->address;
LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)",
@@ -1248,13 +1248,13 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp)
struct x86_32_common *x86_32 = target_to_x86_32(t);
struct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;
LOG_DEBUG("type=%d, addr=" TARGET_ADDR_FMT, wp->rw, wp->address);
- if (!wp->set) {
+ if (!wp->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- int wp_num = wp->set - 1;
- if ((wp_num < 0) || (wp_num >= x86_32->num_hw_bpoints)) {
+ int wp_num = wp->number;
+ if (wp_num >= x86_32->num_hw_bpoints) {
LOG_DEBUG("Invalid FP Comparator number in watchpoint");
return ERROR_OK;
}
@@ -1263,7 +1263,7 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp)
debug_reg_list[wp_num].used = 0;
debug_reg_list[wp_num].bp_value = 0;
- wp->set = 0;
+ wp->is_set = false;
LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)",
wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ?
diff --git a/src/target/xscale.c b/src/target/xscale.c
index dd383b6..78bd099 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -1087,7 +1087,7 @@ static void xscale_enable_watchpoints(struct target *target)
struct watchpoint *watchpoint = target->watchpoints;
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
xscale_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
@@ -1099,7 +1099,7 @@ static void xscale_enable_breakpoints(struct target *target)
/* set any pending breakpoints */
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
xscale_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
}
@@ -1506,7 +1506,7 @@ static int xscale_deassert_reset(struct target *target)
/* mark all hardware breakpoints as unset */
while (breakpoint) {
if (breakpoint->type == BKPT_HARD)
- breakpoint->set = 0;
+ breakpoint->is_set = false;
breakpoint = breakpoint->next;
}
@@ -2088,7 +2088,7 @@ static int xscale_set_breakpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
@@ -2098,11 +2098,13 @@ static int xscale_set_breakpoint(struct target *target,
if (!xscale->ibcr0_used) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
xscale->ibcr0_used = 1;
- breakpoint->set = 1; /* breakpoint set on first breakpoint register */
+ /* breakpoint set on first breakpoint register */
+ breakpoint_hw_set(breakpoint, 0);
} else if (!xscale->ibcr1_used) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
xscale->ibcr1_used = 1;
- breakpoint->set = 2; /* breakpoint set on second breakpoint register */
+ /* breakpoint set on second breakpoint register */
+ breakpoint_hw_set(breakpoint, 1);
} else {/* bug: availability previously verified in xscale_add_breakpoint() */
LOG_ERROR("BUG: no hardware comparator available");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@@ -2133,7 +2135,7 @@ static int xscale_set_breakpoint(struct target *target,
if (retval != ERROR_OK)
return retval;
}
- breakpoint->set = 1;
+ breakpoint->is_set = true;
xscale_send_u32(target, 0x50); /* clean dcache */
xscale_send_u32(target, xscale->cache_clean_address);
@@ -2176,20 +2178,20 @@ static int xscale_unset_breakpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
- if (breakpoint->set == 1) {
+ if (breakpoint->number == 0) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
xscale->ibcr0_used = 0;
- } else if (breakpoint->set == 2) {
+ } else if (breakpoint->number == 1) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
xscale->ibcr1_used = 0;
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
} else {
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4) {
@@ -2203,7 +2205,7 @@ static int xscale_unset_breakpoint(struct target *target,
if (retval != ERROR_OK)
return retval;
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
xscale_send_u32(target, 0x50); /* clean dcache */
xscale_send_u32(target, xscale->cache_clean_address);
@@ -2223,7 +2225,7 @@ static int xscale_remove_breakpoint(struct target *target, struct breakpoint *br
return ERROR_TARGET_NOT_HALTED;
}
- if (breakpoint->set)
+ if (breakpoint->is_set)
xscale_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
@@ -2279,13 +2281,13 @@ static int xscale_set_watchpoint(struct target *target,
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
dbcon_value |= enable;
xscale_set_reg_u32(dbcon, dbcon_value);
- watchpoint->set = 1;
+ watchpoint_set(watchpoint, 0);
xscale->dbr0_used = 1;
} else if (!xscale->dbr1_used) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
dbcon_value |= enable << 2;
xscale_set_reg_u32(dbcon, dbcon_value);
- watchpoint->set = 2;
+ watchpoint_set(watchpoint, 1);
xscale->dbr1_used = 1;
} else {
LOG_ERROR("BUG: no hardware comparator available");
@@ -2349,12 +2351,12 @@ static int xscale_unset_watchpoint(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
- if (watchpoint->set == 1) {
+ if (watchpoint->number == 0) {
if (watchpoint->length > 4) {
dbcon_value &= ~0x103; /* clear DBCON[M] as well */
xscale->dbr1_used = 0; /* DBR1 was used for mask */
@@ -2363,12 +2365,12 @@ static int xscale_unset_watchpoint(struct target *target,
xscale_set_reg_u32(dbcon, dbcon_value);
xscale->dbr0_used = 0;
- } else if (watchpoint->set == 2) {
+ } else if (watchpoint->number == 1) {
dbcon_value &= ~0xc;
xscale_set_reg_u32(dbcon, dbcon_value);
xscale->dbr1_used = 0;
}
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
@@ -2382,7 +2384,7 @@ static int xscale_remove_watchpoint(struct target *target, struct watchpoint *wa
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
xscale_unset_watchpoint(target, watchpoint);
if (watchpoint->length > 4)
diff --git a/tcl/board/at91cap7a-stk-sdram.cfg b/tcl/board/at91cap7a-stk-sdram.cfg
index 8a371e0..182a406 100644
--- a/tcl/board/at91cap7a-stk-sdram.cfg
+++ b/tcl/board/at91cap7a-stk-sdram.cfg
@@ -32,8 +32,7 @@ $_TARGETNAME configure -event reset-start {
}
proc peek32 {address} {
- mem2array t 32 $address 1
- return $t(0)
+ return [read_memory $address 32 1]
}
# Wait for an expression to be true with a timeout
diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg
index e1cbb91..04d9a19 100644
--- a/tcl/board/at91sam9g20-ek.cfg
+++ b/tcl/board/at91sam9g20-ek.cfg
@@ -40,9 +40,7 @@ at91sam9 rdy_busy 0 0xfffff800 13
at91sam9 ce 0 0xfffff800 14
proc read_register {register} {
- set result ""
- mem2array result 32 $register 1
- return $result(0)
+ return [read_memory $register 32 1]
}
proc at91sam9g20_reset_start { } {
diff --git a/tcl/board/embedded-artists_lpc2478-32.cfg b/tcl/board/embedded-artists_lpc2478-32.cfg
index 38f5e1b..a73d832 100644
--- a/tcl/board/embedded-artists_lpc2478-32.cfg
+++ b/tcl/board/embedded-artists_lpc2478-32.cfg
@@ -8,9 +8,7 @@ source [find target/lpc2478.cfg]
# Helper
#
proc read_register {register} {
- set result ""
- mem2array result 32 $register 1
- return $result(0)
+ return [read_memory $register 32 1]
}
proc init_board {} {
diff --git a/tcl/board/hilscher_nxhx10.cfg b/tcl/board/hilscher_nxhx10.cfg
index 1875dac..6e2eba7 100644
--- a/tcl/board/hilscher_nxhx10.cfg
+++ b/tcl/board/hilscher_nxhx10.cfg
@@ -26,9 +26,7 @@ proc flash_init { } {
}
proc mread32 {addr} {
- set value(0) 0
- mem2array value 32 $addr 1
- return $value(0)
+ return [read_memory $addr 32 1]
}
proc init_clocks { } {
diff --git a/tcl/board/icnova_sam9g45_sodimm.cfg b/tcl/board/icnova_sam9g45_sodimm.cfg
index 8a0736b..91e0107 100644
--- a/tcl/board/icnova_sam9g45_sodimm.cfg
+++ b/tcl/board/icnova_sam9g45_sodimm.cfg
@@ -43,9 +43,7 @@ flash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME
proc read_register {register} {
- set result ""
- mem2array result 32 $register 1
- return $result(0)
+ return [read_memory $register 32 1]
}
proc at91sam9g45_start { } {
diff --git a/tcl/board/lemaker_hikey.cfg b/tcl/board/lemaker_hikey.cfg
index ee677c3..325b6fd 100644
--- a/tcl/board/lemaker_hikey.cfg
+++ b/tcl/board/lemaker_hikey.cfg
@@ -17,7 +17,7 @@ proc core_up { args } {
global _TARGETNAME
# examine remaining cores
- foreach _core [set args] {
+ foreach _core $args {
${_TARGETNAME}$_core arp_examine
}
}
diff --git a/tcl/board/nxp_frdm-k64f.cfg b/tcl/board/nxp_frdm-k64f.cfg
new file mode 100644
index 0000000..1581c95
--- /dev/null
+++ b/tcl/board/nxp_frdm-k64f.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# This is an NXP Freedom eval board with a single MK64FN1M0VLL12 chip.
+# https://www.nxp.com/design/development-boards/freedom-development-boards/mcu-boards/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F
+#
+
+source [find interface/cmsis-dap.cfg]
+
+# Set working area to 16 KiB
+set WORKAREASIZE 0x4000
+
+set CHIPNAME k64f
+reset_config srst_only
+
+source [find target/kx.cfg]
diff --git a/tcl/board/nxp_rdb-ls1046a.cfg b/tcl/board/nxp_rdb-ls1046a.cfg
new file mode 100644
index 0000000..fde1829
--- /dev/null
+++ b/tcl/board/nxp_rdb-ls1046a.cfg
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# NXP LS1046ARDB (Reference Design Board)
+# This is for the "console" USB port on the front panel
+# You must ensure that SW4-7 is in the "off" position
+
+# NXP K20
+# The firmware implements the old CMSIS-DAP v1 USB HID interface
+# You must pass --enable-cmsis-dap to ./configure to enable it
+source [find interface/cmsis-dap.cfg]
+
+transport select jtag
+reset_config srst_only
+
+source [find target/ls1046a.cfg]
+
+# The adapter can't handle 10MHz
+adapter speed 5000
diff --git a/tcl/board/ti_am625evm.cfg b/tcl/board/ti_am625evm.cfg
new file mode 100644
index 0000000..4906fd0
--- /dev/null
+++ b/tcl/board/ti_am625evm.cfg
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2021-2022 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments am625 EVM/SK
+# Link: https://www.ti.com/lit/zip/sprr448
+#
+
+# AM625 EVM has an xds110 onboard.
+source [find interface/xds110.cfg]
+
+transport select jtag
+
+# default JTAG configuration has only SRST and no TRST
+reset_config srst_only srst_push_pull
+
+# delay after SRST goes inactive
+adapter srst delay 20
+
+if { ![info exists SOC] } {
+ set SOC am625
+}
+
+source [find target/ti_k3.cfg]
+
+adapter speed 2500
diff --git a/tcl/board/ti_j721s2evm.cfg b/tcl/board/ti_j721s2evm.cfg
new file mode 100644
index 0000000..72418b5
--- /dev/null
+++ b/tcl/board/ti_j721s2evm.cfg
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments J721s2 EVM
+# Link(SoM): https://www.ti.com/lit/zip/sprr439
+#
+
+# J721s2 EVM has an xds110 onboard.
+source [find interface/xds110.cfg]
+
+transport select jtag
+
+# default JTAG configuration has only SRST and no TRST
+reset_config srst_only srst_push_pull
+
+# delay after SRST goes inactive
+adapter srst delay 20
+
+if { ![info exists SOC] } {
+ set SOC j721s2
+}
+
+source [find target/ti_k3.cfg]
+
+adapter speed 2500
diff --git a/tcl/board/tocoding_poplar.cfg b/tcl/board/tocoding_poplar.cfg
index 6d2e635..36d5aec 100644
--- a/tcl/board/tocoding_poplar.cfg
+++ b/tcl/board/tocoding_poplar.cfg
@@ -19,7 +19,7 @@ proc core_up { args } {
global _TARGETNAME
# examine remaining cores
- foreach _core [set args] {
+ foreach _core $args {
${_TARGETNAME}$_core arp_examine
}
}
diff --git a/tcl/chip/atmel/at91/aic.tcl b/tcl/chip/atmel/at91/aic.tcl
index b0b1002..8b8a48f 100644
--- a/tcl/chip/atmel/at91/aic.tcl
+++ b/tcl/chip/atmel/at91/aic.tcl
@@ -54,36 +54,36 @@ proc show_AIC_IMR_helper { NAME ADDR VAL } {
proc show_AIC { } {
global AIC_SMR
- if [catch { mem2array aaa 32 $AIC_SMR [expr {32 * 4}] } msg ] {
+ if [catch { set aaa [read_memory $AIC_SMR 32 [expr {32 * 4}]] } msg ] {
error [format "%s (%s)" $msg AIC_SMR]
}
echo "AIC_SMR: Mode & Type"
global AT91C_ID
for { set x 0 } { $x < 32 } { } {
echo -n " "
- echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+ echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
- echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+ echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
- echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+ echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
- echo [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) $aaa($x)]
+ echo [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
}
global AIC_SVR
- if [catch { mem2array aaa 32 $AIC_SVR [expr {32 * 4}] } msg ] {
+ if [catch { set aaa [read_memory $AIC_SVR 32 [expr {32 * 4}]] } msg ] {
error [format "%s (%s)" $msg AIC_SVR]
}
echo "AIC_SVR: Vectors"
for { set x 0 } { $x < 32 } { } {
echo -n " "
- echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+ echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
- echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+ echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
- echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+ echo -n [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
- echo [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) $aaa($x)]
+ echo [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) [lindex $aaa $x]]
incr x
}
diff --git a/tcl/cpu/arc/common.tcl b/tcl/cpu/arc/common.tcl
index e9a9157..b31e31a 100644
--- a/tcl/cpu/arc/common.tcl
+++ b/tcl/cpu/arc/common.tcl
@@ -29,9 +29,8 @@ proc arc_common_reset { {target ""} } {
# vector located at the interrupt vector base address, which is the first
# entry (offset 0x00) in the vector table.
set int_vector_base [arc jtag get-aux-reg 0x25]
- set start_pc ""
- mem2array start_pc 32 $int_vector_base 1
- arc jtag set-aux-reg 0x6 $start_pc(0)
+ set start_pc [read_memory $int_vector_base 32 1]
+ arc jtag set-aux-reg 0x6 $start_pc
# It is OK to do uncached writes - register cache will be invalidated by
# the reset_assert() function.
diff --git a/tcl/mem_helper.tcl b/tcl/mem_helper.tcl
index 9ea285a..1c86011 100644
--- a/tcl/mem_helper.tcl
+++ b/tcl/mem_helper.tcl
@@ -2,9 +2,7 @@
# mrw: "memory read word", returns value of $reg
proc mrw {reg} {
- set value ""
- mem2array value 32 $reg 1
- return $value(0)
+ return [read_memory $reg 32 1]
}
add_usage_text mrw "address"
@@ -12,9 +10,7 @@ add_help_text mrw "Returns value of word in memory."
# mrh: "memory read halfword", returns value of $reg
proc mrh {reg} {
- set value ""
- mem2array value 16 $reg 1
- return $value(0)
+ return [read_memory $reg 16 1]
}
add_usage_text mrh "address"
@@ -22,9 +18,7 @@ add_help_text mrh "Returns value of halfword in memory."
# mrb: "memory read byte", returns value of $reg
proc mrb {reg} {
- set value ""
- mem2array value 8 $reg 1
- return $value(0)
+ return [read_memory $reg 8 1]
}
add_usage_text mrb "address"
diff --git a/tcl/memory.tcl b/tcl/memory.tcl
index 8d50ba8..ac27345 100644
--- a/tcl/memory.tcl
+++ b/tcl/memory.tcl
@@ -79,108 +79,96 @@ proc address_info { ADDRESS } {
}
proc memread32 {ADDR} {
- set foo(0) 0
- if ![ catch { mem2array foo 32 $ADDR 1 } msg ] {
- return $foo(0)
+ if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {
+ return $foo
} else {
error "memread32: $msg"
}
}
proc memread16 {ADDR} {
- set foo(0) 0
- if ![ catch { mem2array foo 16 $ADDR 1 } msg ] {
- return $foo(0)
+ if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {
+ return $foo
} else {
error "memread16: $msg"
}
}
proc memread8 {ADDR} {
- set foo(0) 0
- if ![ catch { mem2array foo 8 $ADDR 1 } msg ] {
- return $foo(0)
+ if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {
+ return $foo
} else {
error "memread8: $msg"
}
}
proc memwrite32 {ADDR DATA} {
- set foo(0) $DATA
- if ![ catch { array2mem foo 32 $ADDR 1 } msg ] {
- return $foo(0)
+ if ![ catch { write_memory $ADDR 32 $DATA } msg ] {
+ return $DATA
} else {
error "memwrite32: $msg"
}
}
proc memwrite16 {ADDR DATA} {
- set foo(0) $DATA
- if ![ catch { array2mem foo 16 $ADDR 1 } msg ] {
- return $foo(0)
+ if ![ catch { write_memory $ADDR 16 $DATA } msg ] {
+ return $DATA
} else {
error "memwrite16: $msg"
}
}
proc memwrite8 {ADDR DATA} {
- set foo(0) $DATA
- if ![ catch { array2mem foo 8 $ADDR 1 } msg ] {
- return $foo(0)
+ if ![ catch { write_memory $ADDR 8 $DATA } msg ] {
+ return $DATA
} else {
error "memwrite8: $msg"
}
}
proc memread32_phys {ADDR} {
- set foo(0) 0
- if ![ catch { mem2array foo 32 $ADDR 1 phys } msg ] {
- return $foo(0)
+ if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {
+ return $foo
} else {
error "memread32: $msg"
}
}
proc memread16_phys {ADDR} {
- set foo(0) 0
- if ![ catch { mem2array foo 16 $ADDR 1 phys } msg ] {
- return $foo(0)
+ if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {
+ return $foo
} else {
error "memread16: $msg"
}
}
proc memread8_phys {ADDR} {
- set foo(0) 0
- if ![ catch { mem2array foo 8 $ADDR 1 phys } msg ] {
- return $foo(0)
+ if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {
+ return $foo
} else {
error "memread8: $msg"
}
}
proc memwrite32_phys {ADDR DATA} {
- set foo(0) $DATA
- if ![ catch { array2mem foo 32 $ADDR 1 phys } msg ] {
- return $foo(0)
+ if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {
+ return $DATA
} else {
error "memwrite32: $msg"
}
}
proc memwrite16_phys {ADDR DATA} {
- set foo(0) $DATA
- if ![ catch { array2mem foo 16 $ADDR 1 phys } msg ] {
- return $foo(0)
+ if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {
+ return $DATA
} else {
error "memwrite16: $msg"
}
}
proc memwrite8_phys {ADDR DATA} {
- set foo(0) $DATA
- if ![ catch { array2mem foo 8 $ADDR 1 phys } msg ] {
- return $foo(0)
+ if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {
+ return $DATA
} else {
error "memwrite8: $msg"
}
diff --git a/tcl/target/bluefield.cfg b/tcl/target/bluefield.cfg
index 62b1e31..dcebb2f 100644
--- a/tcl/target/bluefield.cfg
+++ b/tcl/target/bluefield.cfg
@@ -72,7 +72,7 @@ proc core_up { args } {
global _TARGETNAME
# Examine remaining cores
- foreach _core [set args] {
+ foreach _core $args {
${_TARGETNAME}$_core arp_examine
}
}
diff --git a/tcl/target/c100helper.tcl b/tcl/target/c100helper.tcl
index bdcfd8c..ecd7edf 100644
--- a/tcl/target/c100helper.tcl
+++ b/tcl/target/c100helper.tcl
@@ -29,9 +29,7 @@ source [find mem_helper.tcl]
# read a 64-bit register (memory mapped)
proc mr64bit {reg} {
- set value ""
- mem2array value 32 $reg 2
- return $value
+ return [read_memory $reg 32 2]
}
@@ -117,19 +115,19 @@ proc showAmbaClk {} {
set PLL_CLK_BYPASS [regs PLL_CLK_BYPASS]
echo [format "CLKCORE_AHB_CLK_CNTRL (0x%x): 0x%x" $CLKCORE_AHB_CLK_CNTRL [mrw $CLKCORE_AHB_CLK_CNTRL]]
- mem2array value 32 $CLKCORE_AHB_CLK_CNTRL 1
+ set value [read_memory $CLKCORE_AHB_CLK_CNTRL 32 1]
# see if the PLL is in bypass mode
- set bypass [expr {($value(0) & $PLL_CLK_BYPASS) >> 24}]
+ set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]
echo [format "PLL bypass bit: %d" $bypass]
if {$bypass == 1} {
echo [format "Amba Clk is set to REFCLK: %d (MHz)" [expr {$CFG_REFCLKFREQ/1000000}]]
} else {
# nope, extract x,y,w and compute the PLL output freq.
- set x [expr {($value(0) & 0x0001F0000) >> 16}]
+ set x [expr {($value & 0x0001F0000) >> 16}]
echo [format "x: %d" $x]
- set y [expr {($value(0) & 0x00000007F)}]
+ set y [expr {($value & 0x00000007F)}]
echo [format "y: %d" $y]
- set w [expr {($value(0) & 0x000000300) >> 8}]
+ set w [expr {($value & 0x000000300) >> 8}]
echo [format "w: %d" $w]
echo [format "Amba PLL Clk: %d (MHz)" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]
}
@@ -192,19 +190,19 @@ proc showArmClk {} {
set PLL_CLK_BYPASS [regs PLL_CLK_BYPASS]
echo [format "CLKCORE_ARM_CLK_CNTRL (0x%x): 0x%x" $CLKCORE_ARM_CLK_CNTRL [mrw $CLKCORE_ARM_CLK_CNTRL]]
- mem2array value 32 $CLKCORE_ARM_CLK_CNTRL 1
+ set value [read_memory $CLKCORE_ARM_CLK_CNTRL 32 1]
# see if the PLL is in bypass mode
- set bypass [expr {($value(0) & $PLL_CLK_BYPASS) >> 24}]
+ set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]
echo [format "PLL bypass bit: %d" $bypass]
if {$bypass == 1} {
echo [format "Amba Clk is set to REFCLK: %d (MHz)" [expr {$CFG_REFCLKFREQ/1000000}]]
} else {
# nope, extract x,y,w and compute the PLL output freq.
- set x [expr {($value(0) & 0x0001F0000) >> 16}]
+ set x [expr {($value & 0x0001F0000) >> 16}]
echo [format "x: %d" $x]
- set y [expr {($value(0) & 0x00000007F)}]
+ set y [expr {($value & 0x00000007F)}]
echo [format "y: %d" $y]
- set w [expr {($value(0) & 0x000000300) >> 8}]
+ set w [expr {($value & 0x000000300) >> 8}]
echo [format "w: %d" $w]
echo [format "Arm PLL Clk: %d (MHz)" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]
}
diff --git a/tcl/target/hilscher_netx500.cfg b/tcl/target/hilscher_netx500.cfg
index 6d919f9..131bef2 100644
--- a/tcl/target/hilscher_netx500.cfg
+++ b/tcl/target/hilscher_netx500.cfg
@@ -26,9 +26,7 @@ set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME
proc mread32 {addr} {
- set value(0) 0
- mem2array value 32 $addr 1
- return $value(0)
+ return [read_memory $addr 32 1]
}
# This function must be called on netX100/500 right after halt
diff --git a/tcl/target/ls1046a.cfg b/tcl/target/ls1046a.cfg
new file mode 100644
index 0000000..3d96a99
--- /dev/null
+++ b/tcl/target/ls1046a.cfg
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# NXP LS1046A
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME ls1046a
+}
+
+if { [info exists DAP_TAPID] } {
+ set _DAP_TAPID $DAP_TAPID
+} else {
+ set _DAP_TAPID 0x5ba00477
+}
+
+if { [info exists SAP_TAPID] } {
+ set _SAP_TAPID $SAP_TAPID
+} else {
+ set _SAP_TAPID 0x06b3001d
+}
+
+jtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap
+
+target create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0
+
+set _CPU_BASE 0x80400000
+set _CPU_STRIDE 0x100000
+set _CPU_DBGOFF 0x10000
+set _CPU_CTIOFF 0x20000
+
+set _TARGETS {}
+for {set i 0} {$i < 4} {incr i} {
+ set _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]
+ cti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 1 \
+ -baseaddr [expr {$_BASE + $_CPU_CTIOFF}]
+ target create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \
+ -cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \
+ -coreid $i {*}[expr {$i ? {-defer-examine} : {-rtos hwthread} }]
+ lappend _TARGETS $_CHIPNAME.cpu$i
+}
+
+target smp {*}$_TARGETS
+
+jtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID
+target create $_CHIPNAME.sap ls1_sap -chain-position $_CHIPNAME.sap -endian big
+
+proc core_up { args } {
+ foreach core $args {
+ $::_CHIPNAME.cpu$core arp_examine
+ }
+}
+
+targets $_CHIPNAME.cpu0
+
+adapter speed 10000
diff --git a/tcl/target/psoc4.cfg b/tcl/target/psoc4.cfg
index cffcbc7..40f2fca 100644
--- a/tcl/target/psoc4.cfg
+++ b/tcl/target/psoc4.cfg
@@ -74,22 +74,22 @@ if {![using_hla]} {
}
proc psoc4_get_family_id {} {
- set err [catch "mem2array romtable_pid 32 0xF0000FE0 3"]
+ set err [catch {set romtable_pid [read_memory 0xF0000FE0 32 3]}]
if { $err } {
return 0
}
- if { [expr {$romtable_pid(0) & 0xffffff00 }]
- || [expr {$romtable_pid(1) & 0xffffff00 }]
- || [expr {$romtable_pid(2) & 0xffffff00 }] } {
+ if { [expr {[lindex $romtable_pid 0] & 0xffffff00 }]
+ || [expr {[lindex $romtable_pid 1] & 0xffffff00 }]
+ || [expr {[lindex $romtable_pid 2] & 0xffffff00 }] } {
echo "Unexpected data in ROMTABLE"
return 0
}
- set designer_id [expr {(( $romtable_pid(1) & 0xf0 ) >> 4) | (( $romtable_pid(2) & 0xf ) << 4 ) }]
+ set designer_id [expr {(( [lindex $romtable_pid 1] & 0xf0 ) >> 4) | (( [lindex $romtable_pid 2] & 0xf ) << 4 ) }]
if { $designer_id != 0xb4 } {
echo [format "ROMTABLE Designer ID 0x%02x is not Cypress" $designer_id]
return 0
}
- set family_id [expr {( $romtable_pid(0) & 0xff ) | (( $romtable_pid(1) & 0xf ) << 8 ) }]
+ set family_id [expr {( [lindex $romtable_pid 0] & 0xff ) | (( [lindex $romtable_pid 1] & 0xf ) << 8 ) }]
return $family_id
}
@@ -193,9 +193,9 @@ proc ocd_process_reset_inner { MODE } {
}
# Set registers to reset vector values
- mem2array value 32 0 2
- reg pc [expr {$value(1) & 0xfffffffe} ]
- reg msp $value(0)
+ set value [read_memory 0x0 32 2]
+ reg pc [expr {[lindex $value 1] & 0xfffffffe}]
+ reg msp [lindex $value 0]
if { $PSOC4_TEST_MODE_WORKAROUND } {
catch { mww $TEST_MODE 0 }
diff --git a/tcl/target/stm32h7x.cfg b/tcl/target/stm32h7x.cfg
index f2a5c42..ca685c2 100644
--- a/tcl/target/stm32h7x.cfg
+++ b/tcl/target/stm32h7x.cfg
@@ -232,9 +232,7 @@ if {[set $_CHIPNAME.DUAL_CORE]} {
# like mrw, but with target selection
proc stm32h7x_mrw {used_target reg} {
- set value ""
- $used_target mem2array value 32 $reg 1
- return $value(0)
+ return [$used_target read_memory $reg 32 1]
}
# like mmw, but with target selection
diff --git a/tcl/target/stm32l5x.cfg b/tcl/target/stm32l5x.cfg
index 0616df1..c43b699 100644
--- a/tcl/target/stm32l5x.cfg
+++ b/tcl/target/stm32l5x.cfg
@@ -1,10 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# script for stm32l5x family
+# stm32l5x devices support both JTAG and SWD transports.
-#
-# stm32l5 devices support both JTAG and SWD transports.
-#
source [find target/swj-dp.tcl]
source [find mem_helper.tcl]
@@ -14,78 +12,10 @@ if { [info exists CHIPNAME] } {
set _CHIPNAME stm32l5x
}
-set _ENDIAN little
+source [find target/stm32x5x_common.cfg]
-# Work-area is a space in RAM used for flash programming
-# By default use 64kB
-if { [info exists WORKAREASIZE] } {
- set _WORKAREASIZE $WORKAREASIZE
-} else {
- set _WORKAREASIZE 0x10000
-}
-
-#jtag scan chain
-if { [info exists CPUTAPID] } {
- set _CPUTAPID $CPUTAPID
-} else {
- if { [using_jtag] } {
- # See STM Document RM0438
- # RM0438 Rev5, Section 52.2.8 JTAG debug port - Table 425. JTAG-DP data registers
- # Corresponds to Cortex®-M33 JTAG debug port ID code
- set _CPUTAPID 0x0ba04477
- } {
- # SWD IDCODE (single drop, arm)
- set _CPUTAPID 0x0be12477
- }
-}
-
-swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
-dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
-
-if {[using_jtag]} {
- jtag newtap $_CHIPNAME bs -irlen 5
-}
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap
-
-# use non-secure RAM by default
-$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
-
-# create sec/ns flash and otp memories (sizes will be probed)
-flash bank $_CHIPNAME.flash_ns stm32l4x 0x08000000 0 0 0 $_TARGETNAME
-flash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME
-flash bank $_CHIPNAME.otp stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME
-
-# Common knowledges tells JTAG speed should be <= F_CPU/6.
-# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
-# the safe side.
-#
-# Note that there is a pretty wide band where things are
-# more or less stable, see http://openocd.zylin.com/#/c/3366/
-adapter speed 500
-
-adapter srst delay 100
-if {[using_jtag]} {
- jtag_ntrst_delay 100
-}
-
-reset_config srst_nogate
-
-if {![using_hla]} {
- # if srst is not fitted use SYSRESETREQ to
- # perform a soft reset
- cortex_m reset_config sysresetreq
-}
-
-proc is_secure {} {
- # read Debug Security Control and Status Regsiter (DSCSR) and check CDS (bit 16)
- set DSCSR [mrw 0xE000EE08]
- return [expr {($DSCSR & (1 << 16)) != 0}]
-}
-
-proc clock_config_110_mhz {} {
- set offset [expr {[is_secure] ? 0x10000000 : 0}]
+proc stm32l5x_clock_config {} {
+ set offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]
# MCU clock is MSI (4MHz) after reset, set MCU freq at 110 MHz with PLL
# RCC_APB1ENR1 = PWREN
mww [expr {0x40021058 + $offset}] 0x10000000
@@ -111,90 +41,8 @@ proc clock_config_110_mhz {} {
while {([mrw [expr {0x40021008 + $offset}]] & 0x0C) != 0x0C} {}
}
-proc ahb_ap_non_secure_access {} {
- # SPROT=1=Non Secure access, Priv=1
- [[target current] cget -dap] apcsw 0x4B000000 0x4F000000
-}
-
-proc ahb_ap_secure_access {} {
- # SPROT=0=Secure access, Priv=1
- [[target current] cget -dap] apcsw 0x0B000000 0x4F000000
-}
-
$_TARGETNAME configure -event reset-init {
- clock_config_110_mhz
+ stm32l5x_clock_config
# Boost JTAG frequency
adapter speed 4000
}
-
-$_TARGETNAME configure -event reset-start {
- # Reset clock is MSI (4 MHz)
- adapter speed 480
-}
-
-$_TARGETNAME configure -event examine-end {
- # DBGMCU_CR |= DBG_STANDBY | DBG_STOP
- mmw 0xE0044004 0x00000006 0
-
- # Stop watchdog counters during halt
- # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP
- mmw 0xE0044008 0x00001800 0
-}
-
-$_TARGETNAME configure -event halted {
- set secure [is_secure]
-
- if {$secure} {
- set secure_str "Secure"
- ahb_ap_secure_access
- } else {
- set secure_str "Non-Secure"
- ahb_ap_non_secure_access
- }
-
- # print the secure state only when it changes
- set _TARGETNAME [target current]
- global $_TARGETNAME.secure
-
- if {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {
- echo "CPU in $secure_str state"
- # update saved security state
- set $_TARGETNAME.secure $secure
- }
-}
-
-$_TARGETNAME configure -event gdb-flash-erase-start {
- set use_secure_workarea 0
- # check if FLASH_OPTR.TZEN is enabled
- set FLASH_OPTR [mrw 0x40022040]
- if {[expr {$FLASH_OPTR & 0x80000000}] == 0} {
- echo "TZEN option bit disabled"
- ahb_ap_non_secure_access
- } {
- ahb_ap_secure_access
- echo "TZEN option bit enabled"
-
- # check if FLASH_OPTR.RDP is not Level 0.5
- if {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {
- set use_secure_workarea 1
- }
- }
-
- set workarea_addr [$_TARGETNAME cget -work-area-phys]
- echo "workarea_addr $workarea_addr"
-
- if {$use_secure_workarea} {
- set workarea_addr [expr {$workarea_addr | 0x10000000}]
- } {
- set workarea_addr [expr {$workarea_addr & ~0x10000000}]
- }
-
- $_TARGETNAME configure -work-area-phys $workarea_addr
-}
-
-$_TARGETNAME configure -event trace-config {
- # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
- # change this value accordingly to configure trace pins
- # assignment
- mmw 0xE0044004 0x00000020 0
-}
diff --git a/tcl/target/stm32mp15x.cfg b/tcl/target/stm32mp15x.cfg
index 639fbab..afd5d24 100644
--- a/tcl/target/stm32mp15x.cfg
+++ b/tcl/target/stm32mp15x.cfg
@@ -109,8 +109,8 @@ proc toggle_cpu0_dbg_claim0 {} {
}
proc detect_cpu1 {} {
- $::_CHIPNAME.ap1 mem2array cpu1_prsr 32 0xE00D2314 1
- set dual_core [expr {$cpu1_prsr(0) & 1}]
+ set cpu1_prsr [$::_CHIPNAME.ap1 read_memory 0xE00D2314 32 1]
+ set dual_core [expr {$cpu1_prsr & 1}]
if {! $dual_core} {$::_CHIPNAME.cpu1 configure -defer-examine}
}
diff --git a/tcl/target/stm32u5x.cfg b/tcl/target/stm32u5x.cfg
index 2c2c0e0..44b51e2 100644
--- a/tcl/target/stm32u5x.cfg
+++ b/tcl/target/stm32u5x.cfg
@@ -1,10 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# script for stm32u5x family
+# stm32u5x devices support both JTAG and SWD transports.
-#
-# stm32u5 devices support both JTAG and SWD transports.
-#
source [find target/swj-dp.tcl]
source [find mem_helper.tcl]
@@ -14,99 +12,34 @@ if { [info exists CHIPNAME] } {
set _CHIPNAME stm32u5x
}
-set _ENDIAN little
+source [find target/stm32x5x_common.cfg]
-# Work-area is a space in RAM used for flash programming
-# By default use 64kB
-if { [info exists WORKAREASIZE] } {
- set _WORKAREASIZE $WORKAREASIZE
-} else {
- set _WORKAREASIZE 0x10000
-}
-
-#jtag scan chain
-if { [info exists CPUTAPID] } {
- set _CPUTAPID $CPUTAPID
-} else {
- if { [using_jtag] } {
- # See STM Document RM0438
- # RM0456 Rev1, Section 65.2.8 JTAG debug port - Table 661. JTAG-DP data registers
- # Corresponds to Cortex®-M33 JTAG debug port ID code
- set _CPUTAPID 0x0ba04477
- } {
- # SWD IDCODE (single drop, arm)
- set _CPUTAPID 0x0be12477
- }
-}
-
-swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
-dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
-
-if {[using_jtag]} {
- jtag newtap $_CHIPNAME bs -irlen 5
-}
-
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap
-
-# use non-secure RAM by default
-$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
-
-# create sec/ns flash and otp memories (sizes will be probed)
-flash bank $_CHIPNAME.flash_ns stm32l4x 0x08000000 0 0 0 $_TARGETNAME
-flash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME
-flash bank $_CHIPNAME.otp stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME
-
-# Common knowledges tells JTAG speed should be <= F_CPU/6.
-# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
-# the safe side.
-#
-# Note that there is a pretty wide band where things are
-# more or less stable, see http://openocd.zylin.com/#/c/3366/
-adapter speed 500
-
-adapter srst delay 100
-if {[using_jtag]} {
- jtag_ntrst_delay 100
-}
-
-reset_config srst_nogate
-
-if {![using_hla]} {
- # if srst is not fitted use SYSRESETREQ to
- # perform a soft reset
- cortex_m reset_config sysresetreq
-}
-
-proc is_secure {} {
- # read Debug Security Control and Status Regsiter (DSCSR) and check CDS (bit 16)
- set DSCSR [mrw 0xE000EE08]
- return [expr {($DSCSR & (1 << 16)) != 0}]
-}
-
-proc clock_config_160_mhz {} {
- set offset [expr {[is_secure] ? 0x10000000 : 0}]
+proc stm32u5x_clock_config {} {
+ set offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]
# MCU clock is at MSI 4MHz after reset, set MCU freq at 160 MHz with PLL
# Enable voltage range 1 for frequency above 100 Mhz
# RCC_AHB3ENR = PWREN
mww [expr {0x46020C94 + $offset}] 0x00000004
# delay for register clock enable (read back reg)
- mrw [expr {0x56020C94 + $offset}]
+ mrw [expr {0x46020C94 + $offset}]
# PWR_VOSR : VOS Range 1
- mww [expr {0x4602080C + $offset}] 0x00030000
- # delay for register write (read back reg)
- mrw [expr {0x4602080C + $offset}]
+ mmw [expr {0x4602080C + $offset}] 0x00030000 0
+ # while !(PWR_VOSR & VOSRDY)
+ while {!([mrw [expr {0x4602080C + $offset}]] & 0x00008000)} {}
# FLASH_ACR : 4 WS for 160 MHz HCLK
mww [expr {0x40022000 + $offset}] 0x00000004
- # RCC_PLL1CFGR => PLL1M=0000=/1, PLL1SRC=MSI 4MHz
- mww [expr {0x46020C28 + $offset}] 0x00000001
+ # RCC_PLL1CFGR => PLL1MBOOST=0, PLL1M=0=/1, PLL1FRACEN=0, PLL1SRC=MSI 4MHz
+ # PLL1REN=1, PLL1RGE => VCOInputRange=PLLInputRange_4_8
+ mww [expr {0x46020C28 + $offset}] 0x00040009
+ # Enable EPOD Booster
+ mmw [expr {0x4602080C + $offset}] 0x00040000 0
+ # while !(PWR_VOSR & BOOSTRDY)
+ while {!([mrw [expr {0x4602080C + $offset}]] & 0x00004000)} {}
# RCC_PLL1DIVR => PLL1P=PLL1Q=PLL1R=000001=/2, PLL1N=0x4F=80
# fVCO = 4 x 80 /1 = 320
# SYSCLOCK = fVCO/PLL1R = 320/2 = 160 MHz
- mmw [expr {0x46020C34 + $offset}] 0x0000004F 0
- # RCC_PLL1CFGR => PLL1REN=1
- mmw [expr {0x46020C28 + $offset}] 0x00040000 0
+ mww [expr {0x46020C34 + $offset}] 0x0101024F
# RCC_CR |= PLL1ON
mmw [expr {0x46020C00 + $offset}] 0x01000000 0
# while !(RCC_CR & PLL1RDY)
@@ -117,91 +50,8 @@ proc clock_config_160_mhz {} {
while {([mrw [expr {0x46020C1C + $offset}]] & 0x0C) != 0x0C} {}
}
-proc ahb_ap_non_secure_access {} {
- # SPROT=1=Non Secure access, Priv=1
- [[target current] cget -dap] apcsw 0x4B000000 0x4F000000
-}
-
-proc ahb_ap_secure_access {} {
- # SPROT=0=Secure access, Priv=1
- [[target current] cget -dap] apcsw 0x0B000000 0x4F000000
-}
-
$_TARGETNAME configure -event reset-init {
- clock_config_160_mhz
+ stm32u5x_clock_config
# Boost JTAG frequency
adapter speed 4000
}
-
-$_TARGETNAME configure -event reset-start {
- # Reset clock is MSI (4 MHz)
- adapter speed 480
-}
-
-$_TARGETNAME configure -event examine-end {
- # DBGMCU_CR |= DBG_STANDBY | DBG_STOP
- mmw 0xE0044004 0x00000006 0
-
- # Stop watchdog counters during halt
- # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP
- mmw 0xE0044008 0x00001800 0
-}
-
-$_TARGETNAME configure -event halted {
- set secure [is_secure]
-
- if {$secure} {
- set secure_str "Secure"
- ahb_ap_secure_access
- } else {
- set secure_str "Non-Secure"
- ahb_ap_non_secure_access
- }
-
- # print the secure state only when it changes
- set _TARGETNAME [target current]
- global $_TARGETNAME.secure
-
- if {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {
- echo "CPU in $secure_str state"
- # update saved security state
- set $_TARGETNAME.secure $secure
- }
-}
-
-$_TARGETNAME configure -event gdb-flash-erase-start {
- set use_secure_workarea 0
- # check if FLASH_OPTR.TZEN is enabled
- set FLASH_OPTR [mrw 0x40022040]
- if {[expr {$FLASH_OPTR & 0x80000000}] == 0} {
- echo "TZEN option bit disabled"
- ahb_ap_non_secure_access
- } else {
- ahb_ap_secure_access
- echo "TZEN option bit enabled"
-
- # check if FLASH_OPTR.RDP is not Level 0.5
- if {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {
- set use_secure_workarea 1
- }
- }
-
- set _TARGETNAME [target current]
- set workarea_addr [$_TARGETNAME cget -work-area-phys]
- echo "workarea_addr $workarea_addr"
-
- if {$use_secure_workarea} {
- set workarea_addr [expr {$workarea_addr | 0x10000000}]
- } else {
- set workarea_addr [expr {$workarea_addr & ~0x10000000}]
- }
-
- $_TARGETNAME configure -work-area-phys $workarea_addr
-}
-
-$_TARGETNAME configure -event trace-config {
- # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
- # change this value accordingly to configure trace pins
- # assignment
- mmw 0xE0044004 0x00000020 0
-}
diff --git a/tcl/target/stm32wlx.cfg b/tcl/target/stm32wlx.cfg
index fafe9bc..75f6f02 100644
--- a/tcl/target/stm32wlx.cfg
+++ b/tcl/target/stm32wlx.cfg
@@ -156,9 +156,7 @@ proc stm32wlx_get_chipname {} {
# like mrw, but with target selection
proc stm32wlx_mrw {used_target reg} {
- set value ""
- $used_target mem2array value 32 $reg 1
- return $value(0)
+ return [$used_target read_memory $reg 32 1]
}
# like mmw, but with target selection
diff --git a/tcl/target/stm32x5x_common.cfg b/tcl/target/stm32x5x_common.cfg
new file mode 100644
index 0000000..276d0cc
--- /dev/null
+++ b/tcl/target/stm32x5x_common.cfg
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# common script for stm32l5x and stm32u5x families
+
+# Work-area is a space in RAM used for flash programming
+# By default use 64kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x10000
+}
+
+#jtag scan chain
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ if { [using_jtag] } {
+ # STM32L5x: RM0438 Rev5, Section 52.2.8 JTAG debug port - Table 425. JTAG-DP data registers
+ # STM32U5x: RM0456 Rev1, Section 65.2.8 JTAG debug port - Table 661. JTAG-DP data registers
+ # Corresponds to Cortex®-M33 JTAG debug port ID code
+ set _CPUTAPID 0x0ba04477
+ } {
+ # SWD IDCODE (single drop, arm)
+ set _CPUTAPID 0x0be12477
+ }
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
+
+if {[using_jtag]} {
+ jtag newtap $_CHIPNAME bs -irlen 5
+}
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap
+
+# use non-secure RAM by default
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+# create sec/ns flash and otp memories (sizes will be probed)
+flash bank $_CHIPNAME.flash_ns stm32l4x 0x08000000 0 0 0 $_TARGETNAME
+flash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME
+flash bank $_CHIPNAME.otp stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME
+
+# Common knowledge tells JTAG speed should be <= F_CPU/6.
+# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
+# the safe side.
+#
+# Note that there is a pretty wide band where things are
+# more or less stable, see http://review.openocd.org/3366
+adapter speed 500
+
+adapter srst delay 100
+if {[using_jtag]} {
+ jtag_ntrst_delay 100
+}
+
+reset_config srst_nogate
+
+if {![using_hla]} {
+ # if srst is not fitted use SYSRESETREQ to
+ # perform a soft reset
+ cortex_m reset_config sysresetreq
+}
+
+proc stm32x5x_is_secure {} {
+ # read Debug Security Control and Status Register (DSCSR) and check CDS (bit 16)
+ set DSCSR [mrw 0xE000EE08]
+ return [expr {($DSCSR & (1 << 16)) != 0}]
+}
+
+proc stm32x5x_ahb_ap_non_secure_access {} {
+ # SPROT=1=Non Secure access, Priv=1
+ [[target current] cget -dap] apcsw 0x4B000000 0x4F000000
+}
+
+proc stm32x5x_ahb_ap_secure_access {} {
+ # SPROT=0=Secure access, Priv=1
+ [[target current] cget -dap] apcsw 0x0B000000 0x4F000000
+}
+
+$_TARGETNAME configure -event reset-start {
+ # Reset clock is MSI (4 MHz)
+ adapter speed 480
+}
+
+$_TARGETNAME configure -event examine-end {
+ # DBGMCU_CR |= DBG_STANDBY | DBG_STOP
+ mmw 0xE0044004 0x00000006 0
+
+ # Stop watchdog counters during halt
+ # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP
+ mmw 0xE0044008 0x00001800 0
+}
+
+$_TARGETNAME configure -event halted {
+ set secure [stm32x5x_is_secure]
+
+ if {$secure} {
+ set secure_str "Secure"
+ stm32x5x_ahb_ap_secure_access
+ } else {
+ set secure_str "Non-Secure"
+ stm32x5x_ahb_ap_non_secure_access
+ }
+
+ # print the secure state only when it changes
+ set _TARGETNAME [target current]
+ global $_TARGETNAME.secure
+
+ if {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {
+ echo "CPU in $secure_str state"
+ # update saved security state
+ set $_TARGETNAME.secure $secure
+ }
+}
+
+$_TARGETNAME configure -event gdb-flash-erase-start {
+ set use_secure_workarea 0
+ # check if FLASH_OPTR.TZEN is enabled
+ set FLASH_OPTR [mrw 0x40022040]
+ if {[expr {$FLASH_OPTR & 0x80000000}] == 0} {
+ echo "TZEN option bit disabled"
+ stm32x5x_ahb_ap_non_secure_access
+ } else {
+ stm32x5x_ahb_ap_secure_access
+ echo "TZEN option bit enabled"
+
+ # check if FLASH_OPTR.RDP is not Level 0.5
+ if {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {
+ set use_secure_workarea 1
+ }
+ }
+
+ set _TARGETNAME [target current]
+ set workarea_addr [$_TARGETNAME cget -work-area-phys]
+ echo "workarea_addr $workarea_addr"
+
+ if {$use_secure_workarea} {
+ set workarea_addr [expr {$workarea_addr | 0x10000000}]
+ } else {
+ set workarea_addr [expr {$workarea_addr & ~0x10000000}]
+ }
+
+ $_TARGETNAME configure -work-area-phys $workarea_addr
+}
+
+$_TARGETNAME configure -event trace-config {
+ # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
+ # change this value accordingly to configure trace pins
+ # assignment
+ mmw 0xE0044004 0x00000020 0
+}
diff --git a/tcl/target/ti_cc3220sf.cfg b/tcl/target/ti_cc3220sf.cfg
index 74269aa..c0a7b56 100644
--- a/tcl/target/ti_cc3220sf.cfg
+++ b/tcl/target/ti_cc3220sf.cfg
@@ -26,11 +26,11 @@ proc ocd_process_reset_inner { MODE } {
soft_reset_halt
# Initialize MSP, PSP, and PC from vector table at flash 0x01000800
- mem2array boot 32 0x01000800 2
+ set boot [read_memory 0x01000800 32 2]
- reg msp $boot(0)
- reg psp $boot(0)
- reg pc $boot(1)
+ reg msp [lindex $boot 0]
+ reg psp [lindex $boot 0]
+ reg pc [lindex $boot 1]
if { 0 == [string compare $MODE run ] } {
resume
diff --git a/tcl/target/ti_k3.cfg b/tcl/target/ti_k3.cfg
index d2aa531..254bb69 100644
--- a/tcl/target/ti_k3.cfg
+++ b/tcl/target/ti_k3.cfg
@@ -27,11 +27,11 @@ if { [info exists V8_SMP_DEBUG] } {
# Common Definitions
-# CM3 the very first processor - all current SoCs have it.
+# System Controller is the very first processor - all current SoCs have it.
set CM3_CTIBASE {0x3C016000}
-# M3 power-ap unlock offsets
-set _m3_ap_unlock_offsets {0xf0 0x44}
+# sysctrl power-ap unlock offsets
+set _sysctrl_ap_unlock_offsets {0xf0 0x44}
# All the ARMV8s are the next processors.
# CL0,CORE0 CL0,CORE1 CL1,CORE0 CL1,CORE1
@@ -42,14 +42,15 @@ set ARMV8_CTIBASE {0x90420000 0x90520000 0x90820000 0x90920000}
# (0)MCU 0 (1)MCU 1 (2)MAIN_0_0 (3)MAIN_0_1 (4)MAIN_1_0 (5)MAIN_1_1
set R5_DBGBASE {0x9d010000 0x9d012000 0x9d410000 0x9d412000 0x9d510000 0x9d512000}
set R5_CTIBASE {0x9d018000 0x9d019000 0x9d418000 0x9d419000 0x9d518000 0x9d519000}
+set R5_NAMES {mcu_r5.0 mcu_r5.1 main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}
-# Finally an M4F
+# Finally an General Purpose(GP) MCU
set CM4_CTIBASE {0x20001000}
-# M4 may be present on some very few SoCs
-set _mcu_m4_cores 0
-# M4 power-ap unlock offsets
-set _m4_ap_unlock_offsets {0xf0 0x60}
+# General Purpose MCU (M4) may be present on some very few SoCs
+set _gp_mcu_cores 0
+# General Purpose MCU power-ap unlock offsets
+set _gp_mcu_ap_unlock_offsets {0xf0 0x60}
# Set configuration overrides for each SOC
switch $_soc {
@@ -63,15 +64,10 @@ switch $_soc {
# AM654 has 1 cluster of 2 R5s cores.
set _r5_cores 2
- set _mcu_r5_cores 2
- set _mcu_base_core_id 0
- set _main0_r5_cores 0
- set _main0_base_core_id 0
- set _main1_r5_cores 0
- set _main1_base_core_id 0
-
- # M3 power-ap unlock offsets
- set _m3_ap_unlock_offsets {0xf0 0x50}
+ set R5_NAMES {mcu_r5.0 mcu_r5.1}
+
+ # Sysctrl power-ap unlock offsets
+ set _sysctrl_ap_unlock_offsets {0xf0 0x50}
}
am642 {
set _CHIPNAME am642
@@ -85,17 +81,37 @@ switch $_soc {
# AM642 has 2 cluster of 2 R5s cores.
set _r5_cores 4
- set _mcu_r5_cores 0
- set _mcu_base_core_id 0
- set _main0_r5_cores 2
- set _main0_base_core_id 0
- set _main1_r5_cores 2
- set _main1_base_core_id 2
+ set R5_NAMES {main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}
set R5_DBGBASE {0x9d410000 0x9d412000 0x9d510000 0x9d512000}
set R5_CTIBASE {0x9d418000 0x9d419000 0x9d518000 0x9d519000}
# M4 processor
- set _mcu_m4_cores 1
+ set _gp_mcu_cores 1
+ }
+ am625 {
+ set _CHIPNAME am625
+ set _K3_DAP_TAPID 0x0bb7e02f
+
+ # AM625 has 1 clusters of 4 A53 cores.
+ set _armv8_cpu_name a53
+ set _armv8_cores 4
+ set ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}
+ set ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}
+
+ # AM625 has 1 cluster of 1 R5s core.
+ set _r5_cores 1
+ set R5_NAMES {main0_r5.0}
+ set R5_DBGBASE {0x9d410000}
+ set R5_CTIBASE {0x9d418000}
+
+ # sysctrl CTI base
+ set CM3_CTIBASE {0x20001000}
+ # Sysctrl power-ap unlock offsets
+ set _sysctrl_ap_unlock_offsets {0xf0 0x78}
+
+ # M4 processor
+ set _gp_mcu_cores 1
+ set _gp_mcu_ap_unlock_offsets {0xf0 0x7c}
}
j721e {
set _CHIPNAME j721e
@@ -106,12 +122,6 @@ switch $_soc {
# J721E has 3 clusters of 2 R5 cores each.
set _r5_cores 6
- set _mcu_r5_cores 2
- set _mcu_base_core_id 0
- set _main0_r5_cores 2
- set _main0_base_core_id 2
- set _main1_r5_cores 2
- set _main1_base_core_id 4
}
j7200 {
set _CHIPNAME j7200
@@ -123,18 +133,32 @@ switch $_soc {
# J7200 has 2 clusters of 2 R5 cores each.
set _r5_cores 4
- set _mcu_r5_cores 2
- set _mcu_base_core_id 0
- set _main0_r5_cores 2
- set _main0_base_core_id 2
- set _main1_r5_cores 0
- set _main1_base_core_id 0
set R5_DBGBASE {0x9d010000 0x9d012000 0x9d110000 0x9d112000}
set R5_CTIBASE {0x9d018000 0x9d019000 0x9d118000 0x9d119000}
# M3 CTI base
set CM3_CTIBASE {0x20001000}
}
+ j721s2 {
+ set _CHIPNAME j721s2
+ set _K3_DAP_TAPID 0x0bb7502f
+
+ # J721s2 has 1 cluster of 2 A72 cores.
+ set _armv8_cpu_name a72
+ set _armv8_cores 2
+
+ # J721s2 has 3 clusters of 2 R5 cores each.
+ set _r5_cores 6
+
+ # sysctrl CTI base
+ set CM3_CTIBASE {0x20001000}
+ # Sysctrl power-ap unlock offsets
+ set _sysctrl_ap_unlock_offsets {0xf0 0x78}
+
+ # M4 processor
+ set _gp_mcu_cores 1
+ set _gp_mcu_ap_unlock_offsets {0xf0 0x7c}
+ }
default {
echo "'$_soc' is invalid!"
}
@@ -147,18 +171,42 @@ set _TARGETNAME $_CHIPNAME.cpu
set _CTINAME $_CHIPNAME.cti
-# M3 is always present
-cti create $_CTINAME.m3 -dap $_CHIPNAME.dap -ap-num 7 -baseaddr [lindex $CM3_CTIBASE 0]
-target create $_TARGETNAME.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 7 -defer-examine
-$_TARGETNAME.m3 configure -event reset-assert { }
+# sysctrl is always present
+cti create $_CTINAME.sysctrl -dap $_CHIPNAME.dap -ap-num 7 -baseaddr [lindex $CM3_CTIBASE 0]
+target create $_TARGETNAME.sysctrl cortex_m -dap $_CHIPNAME.dap -ap-num 7 -defer-examine
+$_TARGETNAME.sysctrl configure -event reset-assert { }
-proc m3_up { args } {
- # To access M3, we need to enable the JTAG access for the same.
+proc sysctrl_up {} {
+ # To access sysctrl, we need to enable the JTAG access for the same.
# Ensure Power-AP unlocked
- $::_CHIPNAME.dap apreg 3 [lindex $::_m3_ap_unlock_offsets 0] 0x00190000
- $::_CHIPNAME.dap apreg 3 [lindex $::_m3_ap_unlock_offsets 1] 0x00102098
+ $::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 0] 0x00190000
+ $::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 1] 0x00102098
+
+ $::_TARGETNAME.sysctrl arp_examine
+}
- $::_TARGETNAME.m3 arp_examine
+$_TARGETNAME.sysctrl configure -event gdb-attach {
+ sysctrl_up
+ # gdb-attach default rule
+ halt 1000
+}
+
+proc _cpu_no_smp_up {} {
+ set _current_target [target current]
+ set _current_type [$_current_target cget -type]
+
+ $_current_target arp_examine
+ $_current_target $_current_type dbginit
+}
+
+proc _armv8_smp_up {} {
+ for { set _core 0 } { $_core < $::_armv8_cores } { incr _core } {
+ $::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine
+ $::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit
+ $::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 smp on
+ }
+ # Set Default target as core 0
+ targets $::_TARGETNAME.$::_armv8_cpu_name.0
}
set _v8_smp_targets ""
@@ -172,6 +220,20 @@ for { set _core 0 } { $_core < $_armv8_cores } { incr _core } {
-dbgbase [lindex $ARMV8_DBGBASE $_core] -cti $_CTINAME.$_armv8_cpu_name.$_core -defer-examine
set _v8_smp_targets "$_v8_smp_targets $_TARGETNAME.$_armv8_cpu_name.$_core"
+
+ if { $_v8_smp_debug == 0 } {
+ $_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {
+ _cpu_no_smp_up
+ # gdb-attach default rule
+ halt 1000
+ }
+ } else {
+ $_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {
+ _armv8_smp_up
+ # gdb-attach default rule
+ halt 1000
+ }
+ }
}
# Setup ARMV8 proc commands based on CPU to prevent people confusing SoCs
@@ -181,76 +243,59 @@ set _armv8_smp_cmd "$_armv8_cpu_name"_smp
if { $_v8_smp_debug == 0 } {
proc $_armv8_up_cmd { args } {
- foreach { _core } [set args] {
- $::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine
- $::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit
+ foreach _core $args {
+ targets $_core
+ _cpu_no_smp_up
}
}
} else {
proc $_armv8_smp_cmd { args } {
- for { set _core 0 } { $_core < $::_armv8_cores } { incr _core } {
- $::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine
- $::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit
- $::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 smp on
- }
- # Set Default target are core 0
- targets $::_TARGETNAME.$::_armv8_cpu_name.0
+ _armv8_smp_up
}
-
# Declare SMP
target smp $:::_v8_smp_targets
}
for { set _core 0 } { $_core < $_r5_cores } { incr _core } {
- cti create $_CTINAME.r5.$_core -dap $_CHIPNAME.dap -ap-num 1 \
+ set _r5_name [lindex $R5_NAMES $_core]
+ cti create $_CTINAME.$_r5_name -dap $_CHIPNAME.dap -ap-num 1 \
-baseaddr [lindex $R5_CTIBASE $_core]
# inactive core examination will fail - wait till startup of additional core
- target create $_TARGETNAME.r5.$_core cortex_r4 -dap $_CHIPNAME.dap \
+ target create $_TARGETNAME.$_r5_name cortex_r4 -dap $_CHIPNAME.dap \
-dbgbase [lindex $R5_DBGBASE $_core] -ap-num 1 -defer-examine
-}
-
-if { $_mcu_r5_cores != 0 } {
- proc mcu_r5_up { args } {
- foreach { _core } [set args] {
- set _core [expr {$_core + $::_mcu_base_core_id}]
- $::_TARGETNAME.r5.$_core arp_examine
- $::_TARGETNAME.r5.$_core cortex_r4 dbginit
- }
- }
-}
-if { $_main0_r5_cores != 0 } {
- proc main0_r5_up { args } {
- foreach { _core } [set args] {
- set _core [expr {$_core + $::_main0_base_core_id}]
- $::_TARGETNAME.r5.$_core arp_examine
- $::_TARGETNAME.r5.$_core cortex_r4 dbginit
- }
+ $_TARGETNAME.$_r5_name configure -event gdb-attach {
+ _cpu_no_smp_up
+ # gdb-attach default rule
+ halt 1000
}
}
-if { $_main1_r5_cores != 0 } {
- proc main1_r5_up { args } {
- foreach { _core } [set args] {
- set _core [expr {$_core + $::_main1_base_core_id}]
- $::_TARGETNAME.r5.$_core arp_examine
- $::_TARGETNAME.r5.$_core cortex_r4 dbginit
- }
+proc r5_up { args } {
+ foreach _core $args {
+ targets $_core
+ _cpu_no_smp_up
}
}
-if { $_mcu_m4_cores != 0 } {
- cti create $_CTINAME.m4 -dap $_CHIPNAME.dap -ap-num 8 -baseaddr [lindex $CM4_CTIBASE 0]
- target create $_TARGETNAME.m4 cortex_m -dap $_CHIPNAME.dap -ap-num 8 -defer-examine
- $_TARGETNAME.m4 configure -event reset-assert { }
+if { $_gp_mcu_cores != 0 } {
+ cti create $_CTINAME.gp_mcu -dap $_CHIPNAME.dap -ap-num 8 -baseaddr [lindex $CM4_CTIBASE 0]
+ target create $_TARGETNAME.gp_mcu cortex_m -dap $_CHIPNAME.dap -ap-num 8 -defer-examine
+ $_TARGETNAME.gp_mcu configure -event reset-assert { }
- proc m4_up { args } {
- # To access M4, we need to enable the JTAG access for the same.
+ proc gp_mcu_up {} {
+ # To access GP MCU, we need to enable the JTAG access for the same.
# Ensure Power-AP unlocked
- $::_CHIPNAME.dap apreg 3 [lindex $::_m4_ap_unlock_offsets 0] 0x00190000
- $::_CHIPNAME.dap apreg 3 [lindex $::_m4_ap_unlock_offsets 1] 0x00102098
+ $::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 0] 0x00190000
+ $::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 1] 0x00102098
+
+ $::_TARGETNAME.gp_mcu arp_examine
+ }
- $::_TARGETNAME.m4 arp_examine
+ $_TARGETNAME.gp_mcu configure -event gdb-attach {
+ gp_mcu_up
+ # gdb-attach default rule
+ halt 1000
}
}
diff --git a/tcl/target/xilinx_zynqmp.cfg b/tcl/target/xilinx_zynqmp.cfg
index e66289a..2df7a4f 100644
--- a/tcl/target/xilinx_zynqmp.cfg
+++ b/tcl/target/xilinx_zynqmp.cfg
@@ -99,7 +99,7 @@ targets $_TARGETNAME.0
proc core_up { args } {
global _TARGETNAME
- foreach { core } [set args] {
+ foreach core $args {
$_TARGETNAME.$core arp_examine
}
}
diff --git a/tcl/tools/test_cpu_speed.tcl b/tcl/tools/test_cpu_speed.tcl
new file mode 100644
index 0000000..cef2bbb
--- /dev/null
+++ b/tcl/tools/test_cpu_speed.tcl
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Description:
+# Measure the CPU clock frequency of an ARM Cortex-M based device.
+#
+# Return:
+# The CPU clock frequency in Hz. A negative value indicates that the loop
+# counter was saturated.
+#
+# Note:
+# You may need to adapt the number of cycles for your device.
+#
+add_help_text cortex_m_test_cpu_speed "Measure the CPU clock frequency of an ARM Cortex-M based device"
+add_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}
+proc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {
+ set loop_counter_start 0xffffffff
+
+ halt
+
+ # Backup registers and memory.
+ set backup_regs [get_reg -force {pc r0 xPSR}]
+ set backup_mem [read_memory $address 16 3]
+
+ # We place the following code at the given address to measure the
+ # CPU clock frequency:
+ #
+ # 3801: subs r0, #1
+ # d1fd: bne #-2
+ # e7fe: b #-4
+ write_memory $address 16 {0x3801 0xd1fd 0xe7fe}
+
+ set_reg "pc $address r0 $loop_counter_start"
+ resume
+ sleep $timeout
+ halt
+
+ # Get the loop counter value from register r0.
+ set loop_counter_end [dict values [get_reg r0]]
+ set loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]
+
+ # Restore registers and memory.
+ set_reg $backup_regs
+ write_memory $address 16 $backup_mem
+
+ if { [expr {$loop_counter_end == 0}] } {
+ return -1
+ }
+
+ return [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]
+}
diff --git a/testing/examples/cortex/cm3-ftest.cfg b/testing/examples/cortex/cm3-ftest.cfg
index 6f3fa5c..02c8da1 100644
--- a/testing/examples/cortex/cm3-ftest.cfg
+++ b/testing/examples/cortex/cm3-ftest.cfg
@@ -50,7 +50,7 @@ proc load_and_run { name halfwords n_instr } {
echo "# code to trigger $name vector"
set addr 0x20000000
- # array2mem should be faster, though we'd need to
+ # write_memory should be faster, though we'd need to
# compute the resulting $addr ourselves
foreach opcode $halfwords {
mwh $addr $opcode