diff --git a/Makefile.am b/Makefile.am
index 1e3e0976a..f9e0d6bbe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -116,9 +116,14 @@ TCL_PATH = tcl
TCL_FILES = find $(srcdir)/$(TCL_PATH) -name '*.cfg' -o -name '*.tcl' -o -name '*.txt' | \
sed -e 's,^$(srcdir)/$(TCL_PATH),,'
+# Without the PERL_UNICODE="IO" workaround below when running git2cl, you get several
+# "Wide character" warnings and you also risk an invalid character encoding in
+# the generated ChangeLog file. For more information, see this bug report:
+# Warning "Wide character in print"
+# https://savannah.nongnu.org/bugs/?65689
dist-hook:
if test -d $(srcdir)/.git -a \( ! -e $(distdir)/ChangeLog -o -w $(distdir)/ChangeLog \) ; then \
- git --git-dir $(srcdir)/.git log | $(srcdir)/tools/git2cl/git2cl > $(distdir)/ChangeLog ; \
+ git --git-dir $(srcdir)/.git log | PERL_UNICODE="IO" $(srcdir)/tools/git2cl/git2cl > $(distdir)/ChangeLog ; \
fi
for i in $$($(TCL_FILES)); do \
j="$(distdir)/$(TCL_PATH)/$$i" && \
diff --git a/configure.ac b/configure.ac
index 7b20d48ea..c6e02b65b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,11 @@ m4_define([PCIE_ADAPTERS],
m4_define([SERIAL_PORT_ADAPTERS],
[[[buspirate], [Bus Pirate], [BUS_PIRATE]]])
+# The word 'Adapter' in "Dummy Adapter" below must begin with a capital letter
+# because there is an M4 macro called 'adapter'.
+m4_define([DUMMY_ADAPTER],
+ [[[dummy], [Dummy Adapter], [DUMMY]]])
+
m4_define([OPTIONAL_LIBRARIES],
[[[capstone], [Use Capstone disassembly framework], []]])
@@ -235,10 +240,6 @@ AS_IF([test "x$debug_malloc" = "xyes"], [
AC_DEFINE([_DEBUG_FREE_SPACE_],[1], [Include malloc free space in logging])
])
-AC_ARG_ENABLE([dummy],
- AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]),
- [build_dummy=$enableval], [build_dummy=no])
-
AC_ARG_ENABLE([rshim],
AS_HELP_STRING([--enable-rshim], [Enable building the rshim driver]),
[build_rshim=$enableval], [build_rshim=no])
@@ -267,6 +268,8 @@ AC_ARG_ADAPTERS([
LIBJAYLINK_ADAPTERS
],[auto])
+AC_ARG_ADAPTERS([DUMMY_ADAPTER],[no])
+
AC_ARG_ENABLE([parport],
AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]),
[build_parport=$enableval], [build_parport=no])
@@ -493,11 +496,8 @@ AS_IF([test "x$build_dmem" = "xyes"], [
AC_DEFINE([BUILD_DMEM], [0], [0 if you don't want to debug via Direct Mem.])
])
-AS_IF([test "x$build_dummy" = "xyes"], [
+AS_IF([test "x$ADAPTER_VAR([dummy])" = "xyes"], [
build_bitbang=yes
- AC_DEFINE([BUILD_DUMMY], [1], [1 if you want dummy driver.])
-], [
- AC_DEFINE([BUILD_DUMMY], [0], [0 if you don't want dummy driver.])
])
AS_IF([test "x$build_ep93xx" = "xyes"], [
@@ -679,6 +679,11 @@ PKG_CHECK_MODULES([LIBGPIOD], [libgpiod < 2.0], [
PKG_CHECK_MODULES([LIBJAYLINK], [libjaylink >= 0.2],
[use_libjaylink=yes], [use_libjaylink=no])
+# Arg $1: The adapter name, used to derive option and variable names for the adapter.
+# Arg $2: Whether the adapter can be enabled, for example, because
+# its prerequisites are installed in the system.
+# Arg $3: What prerequisites are missing, to be shown in an error message
+# if the adapter was requested but cannot be enabled.
m4_define([PROCESS_ADAPTERS], [
m4_foreach([adapter], [$1], [
AS_IF([test $2], [
@@ -705,6 +710,7 @@ PROCESS_ADAPTERS([LIBFTDI_ADAPTERS], ["x$use_libftdi" = "xyes"], [libftdi])
PROCESS_ADAPTERS([LIBFTDI_USB1_ADAPTERS], ["x$use_libftdi" = "xyes" -a "x$use_libusb1" = "xyes"], [libftdi and libusb-1.x])
PROCESS_ADAPTERS([LIBGPIOD_ADAPTERS], ["x$use_libgpiod" = "xyes"], [libgpiod])
PROCESS_ADAPTERS([LIBJAYLINK_ADAPTERS], ["x$use_internal_libjaylink" = "xyes" -o "x$use_libjaylink" = "xyes"], [libjaylink-0.2])
+PROCESS_ADAPTERS([DUMMY_ADAPTER], [true], [unused])
AS_IF([test "x$enable_linuxgpiod" != "xno"], [
build_bitbang=yes
@@ -744,7 +750,6 @@ AS_IF([test "x$enable_esp_usb_jtag" != "xno"], [
AM_CONDITIONAL([RELEASE], [test "x$build_release" = "xyes"])
AM_CONDITIONAL([PARPORT], [test "x$build_parport" = "xyes"])
-AM_CONDITIONAL([DUMMY], [test "x$build_dummy" = "xyes"])
AM_CONDITIONAL([GIVEIO], [test "x$parport_use_giveio" = "xyes"])
AM_CONDITIONAL([EP93XX], [test "x$build_ep93xx" = "xyes"])
AM_CONDITIONAL([AT91RM9200], [test "x$build_at91rm9200" = "xyes"])
@@ -853,6 +858,7 @@ m4_foreach([adapter], [USB1_ADAPTERS,
LIBFTDI_USB1_ADAPTERS,
LIBGPIOD_ADAPTERS,
LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS,
+ DUMMY_ADAPTER,
OPTIONAL_LIBRARIES],
[s=m4_format(["%-40s"], ADAPTER_DESC([adapter]))
AS_CASE([$ADAPTER_VAR([adapter])],
diff --git a/doc/manual/style.txt b/doc/manual/style.txt
index 1d3ec6748..a1e6b8f01 100644
--- a/doc/manual/style.txt
+++ b/doc/manual/style.txt
@@ -97,6 +97,21 @@ OpenOCD project.
x = 0;
}
@endcode
+- on if statements where the condition is split among multiple
+ lines, increase the indentation of the condition to prevent it to match
+ to the indentation of the then block due to length of 'if ('
+ being same of the TAB width of 4 characters. Use:
+ @code
+ if (CMD_ARGC < 3
+ || CMD_ARGC > 8)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ @endcode
+ instead of:
+ @code
+ if (CMD_ARGC < 3 ||
+ CMD_ARGC > 8)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ @endcode
Finally, try to avoid lines of code that are longer than 72-80 columns:
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 47879cc54..8ffbcf307 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -399,8 +399,7 @@ to be available anymore as of April 2012.
@* Link @url{http://www.distortec.com/jtag-lock-pick-tiny-2} FT232H-based
@item @b{GW16042}
-@* Link: @url{http://shop.gateworks.com/index.php?route=product/product&path=70_80&product_id=64}
-FT2232H-based
+@* Link: @url{https://www.gateworks.com/} FT2232H-based
@end itemize
@section USB-JTAG / Altera USB-Blaster compatibles
@@ -442,7 +441,7 @@ SWD and not JTAG, thus not supported.
@itemize @bullet
@item @b{Raisonance RLink}
-@* Link: @url{http://www.mcu-raisonance.com/~rlink-debugger-programmer__@/microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html}
+@* Link: @url{https://www.raisonance.com/rlink.html}
@item @b{STM32 Primer}
@* Link: @url{http://www.stm32circle.com/resources/stm32primer.php}
@item @b{STM32 Primer2}
@@ -9220,6 +9219,18 @@ read_memory 0x20000000 32 2
@end example
@end deffn
+@deffn {Command} {debug_reason}
+Displays the current debug reason:
+@code{debug-request},
+@code{breakpoint},
+@code{watchpoint},
+@code{watchpoint-and-breakpoint},
+@code{single-step},
+@code{target-not-halted},
+@code{program-exit},
+@code{exception-catch} or @code{undefined}.
+@end deffn
+
@deffn {Command} {halt} [ms]
@deffnx {Command} {wait_halt} [ms]
The @command{halt} command first sends a halt request to the target,
@@ -9389,7 +9400,7 @@ Loads an image stored in memory by @command{fast_load_image} to the
current target. Must be preceded by fast_load_image.
@end deffn
-@deffn {Command} {fast_load_image} filename [address [@option{bin}|@option{ihex}|@option{elf}|@option{s19} [@option{min_addr} [@option{max_length}]]]]]]
+@deffn {Command} {fast_load_image} filename [address [@option{bin}|@option{ihex}|@option{elf}|@option{s19} [@option{min_addr} [@option{max_length}]]]]
Normally you should be using @command{load_image} or GDB load. However, for
testing purposes or when I/O overhead is significant(OpenOCD running on an embedded
host), storing the image in memory and uploading the image to the target
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
index b7ba1027e..859b3e9ec 100644
--- a/src/flash/nor/psoc6.c
+++ b/src/flash/nor/psoc6.c
@@ -18,7 +18,6 @@
#include "target/target.h"
#include "target/cortex_m.h"
#include "target/breakpoints.h"
-#include "target/target_type.h"
#include "target/algorithm.h"
/**************************************************************************************************
diff --git a/src/helper/command.h b/src/helper/command.h
index dc4507042..fc26dda81 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -21,7 +21,7 @@
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
* used for __attribute__((format( ... ))), with GCC v4.4 or later
*/
-#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
+#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004)) && !defined(__clang__)
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
#else
#define PRINTF_ATTRIBUTE_FORMAT printf
diff --git a/src/helper/log.h b/src/helper/log.h
index 818716a9d..d52c05f99 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -19,7 +19,7 @@
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
* used for __attribute__((format( ... ))), with GCC v4.4 or later
*/
-#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
+#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004)) && !defined(__clang__)
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
#else
#define PRINTF_ATTRIBUTE_FORMAT printf
diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c
index 2f3d64454..1926ed9ae 100644
--- a/src/jtag/drivers/linuxgpiod.c
+++ b/src/jtag/drivers/linuxgpiod.c
@@ -378,12 +378,12 @@ static int linuxgpiod_init(void)
goto out_error;
}
- if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
- goto out_error;
+ if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
+ goto out_error;
}
if (transport_is_swd()) {
@@ -413,9 +413,9 @@ static int linuxgpiod_init(void)
goto out_error;
}
- if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
- goto out_error;
+ if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
+ goto out_error;
return ERROR_OK;
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index ea37f7fe7..02409a5e4 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -12,7 +12,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
@@ -931,7 +930,7 @@ static int freertos_create(struct target *target)
{
unsigned int i = 0;
while (i < ARRAY_SIZE(freertos_params_list) &&
- strcmp(freertos_params_list[i].target_name, target->type->name) != 0) {
+ strcmp(freertos_params_list[i].target_name, target_type_name(target)) != 0) {
i++;
}
if (i >= ARRAY_SIZE(freertos_params_list)) {
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
index 5bdd007d4..61c49264e 100644
--- a/src/rtos/ThreadX.c
+++ b/src/rtos/ThreadX.c
@@ -12,7 +12,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
@@ -608,7 +607,7 @@ static int threadx_get_thread_detail(struct rtos *rtos,
static int threadx_create(struct target *target)
{
for (unsigned int i = 0; i < ARRAY_SIZE(threadx_params_list); i++)
- if (strcmp(threadx_params_list[i].target_name, target->type->name) == 0) {
+ if (strcmp(threadx_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&threadx_params_list[i];
target->rtos->current_thread = 0;
target->rtos->thread_details = NULL;
diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c
index 20378274e..c1e4e8419 100644
--- a/src/rtos/chibios.c
+++ b/src/rtos/chibios.c
@@ -15,7 +15,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "target/armv7m.h"
#include "target/cortex_m.h"
#include "rtos.h"
@@ -470,7 +469,7 @@ static int chibios_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
/* Update stacking if it can only be determined from runtime information */
if (!param->stacking_info &&
(chibios_update_stacking(rtos) != ERROR_OK)) {
- LOG_ERROR("Failed to determine exact stacking for the target type %s", rtos->target->type->name);
+ LOG_ERROR("Failed to determine exact stacking for the target type %s", target_type_name(rtos->target));
return -1;
}
@@ -518,12 +517,12 @@ static bool chibios_detect_rtos(struct target *target)
static int chibios_create(struct target *target)
{
for (unsigned int i = 0; i < ARRAY_SIZE(chibios_params_list); i++)
- if (strcmp(chibios_params_list[i].target_name, target->type->name) == 0) {
+ if (strcmp(chibios_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&chibios_params_list[i];
return 0;
}
LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility "
- "list", target->type->name);
+ "list", target_type_name(target));
return -1;
}
diff --git a/src/rtos/chromium-ec.c b/src/rtos/chromium-ec.c
index a95969e34..dbfe3b3c6 100644
--- a/src/rtos/chromium-ec.c
+++ b/src/rtos/chromium-ec.c
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include "rtos_standard_stackings.h"
@@ -120,7 +119,7 @@ static int chromium_ec_create(struct target *target)
size_t t;
for (t = 0; t < ARRAY_SIZE(chromium_ec_params_list); t++)
- if (!strcmp(chromium_ec_params_list[t].target_name, target->type->name)) {
+ if (!strcmp(chromium_ec_params_list[t].target_name, target_type_name(target))) {
params = malloc(sizeof(*params));
if (!params) {
LOG_ERROR("Chromium-EC: out of memory");
@@ -133,11 +132,11 @@ static int chromium_ec_create(struct target *target)
target->rtos->thread_details = NULL;
target->rtos->thread_count = 0;
- LOG_INFO("Chromium-EC: Using target: %s", target->type->name);
+ LOG_INFO("Chromium-EC: Using target: %s", target_type_name(target));
return ERROR_OK;
}
- LOG_ERROR("Chromium-EC: target not supported: %s", target->type->name);
+ LOG_ERROR("Chromium-EC: target not supported: %s", target_type_name(target));
return ERROR_FAIL;
}
diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c
index 10ed12809..7048b006e 100644
--- a/src/rtos/eCos.c
+++ b/src/rtos/eCos.c
@@ -10,7 +10,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "target/armv7m.h"
#include "rtos.h"
#include "helper/log.h"
@@ -1137,7 +1136,7 @@ static int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[
ARRAY_SIZE(ecos_symbol_list), sizeof(struct symbol_table_elem));
/* If the target reference was passed into this function we could limit
- * the symbols we need to lookup to the target->type->name based
+ * the symbols we need to lookup to the target_type_name(target) based
* range. For the moment we need to provide a single vector with all of
* the symbols across all of the supported architectures. */
for (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++) {
@@ -1189,8 +1188,8 @@ static int ecos_create(struct target *target)
for (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++) {
const char * const *tnames = ecos_params_list[i].target_names;
while (*tnames) {
- if (strcmp(*tnames, target->type->name) == 0) {
- /* LOG_DEBUG("eCos: matched target \"%s\"", target->type->name); */
+ if (strcmp(*tnames, target_type_name(target)) == 0) {
+ /* LOG_DEBUG("eCos: matched target \"%s\"", target_type_name(target)); */
target->rtos->rtos_specific_params = (void *)&ecos_params_list[i];
ecos_params_list[i].flush_common = true;
ecos_params_list[i].stacking_info = NULL;
diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c
index a03b039e0..7e6de7902 100644
--- a/src/rtos/embKernel.c
+++ b/src/rtos/embKernel.c
@@ -12,7 +12,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
@@ -110,12 +109,12 @@ static int embkernel_create(struct target *target)
{
size_t i = 0;
while ((i < ARRAY_SIZE(embkernel_params_list)) &&
- (strcmp(embkernel_params_list[i].target_name, target->type->name) != 0))
+ (strcmp(embkernel_params_list[i].target_name, target_type_name(target)) != 0))
i++;
if (i >= ARRAY_SIZE(embkernel_params_list)) {
LOG_WARNING("Could not find target \"%s\" in embKernel compatibility "
- "list", target->type->name);
+ "list", target_type_name(target));
return -1;
}
diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index 763a97da0..f256bc278 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -7,7 +7,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "target/register.h"
#include
#include "rtos.h"
diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c
index d9b694282..b4a182135 100644
--- a/src/rtos/mqx.c
+++ b/src/rtos/mqx.c
@@ -13,7 +13,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
@@ -249,13 +248,13 @@ static int mqx_create(
{
/* check target name against supported architectures */
for (unsigned int i = 0; i < ARRAY_SIZE(mqx_params_list); i++) {
- if (strcmp(mqx_params_list[i].target_name, target->type->name) == 0) {
+ if (strcmp(mqx_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&mqx_params_list[i];
- /* LOG_DEBUG("MQX RTOS - valid architecture: %s", target->type->name); */
+ /* LOG_DEBUG("MQX RTOS - valid architecture: %s", target_type_name(target)); */
return 0;
}
}
- LOG_ERROR("MQX RTOS - could not find target \"%s\" in MQX compatibility list", target->type->name);
+ LOG_ERROR("MQX RTOS - could not find target \"%s\" in MQX compatibility list", target_type_name(target));
return -1;
}
diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c
index 0616af0f4..910014889 100644
--- a/src/rtos/nuttx.c
+++ b/src/rtos/nuttx.c
@@ -12,7 +12,6 @@
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "target/armv7m.h"
#include "target/cortex_m.h"
#include "rtos.h"
diff --git a/src/rtos/riot.c b/src/rtos/riot.c
index be5452e9e..b90b06914 100644
--- a/src/rtos/riot.c
+++ b/src/rtos/riot.c
@@ -12,7 +12,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
@@ -391,7 +390,7 @@ static int riot_create(struct target *target)
/* lookup if target is supported by RIOT */
while ((i < RIOT_NUM_PARAMS) &&
- (strcmp(riot_params_list[i].target_name, target->type->name) != 0)) {
+ (strcmp(riot_params_list[i].target_name, target_type_name(target)) != 0)) {
i++;
}
if (i >= RIOT_NUM_PARAMS) {
diff --git a/src/rtos/rtkernel.c b/src/rtos/rtkernel.c
index ba1de2517..aebbf3d94 100644
--- a/src/rtos/rtkernel.c
+++ b/src/rtos/rtkernel.c
@@ -12,7 +12,6 @@
#include
#include
#include "target/target.h"
-#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
@@ -363,7 +362,7 @@ static bool rtkernel_detect_rtos(struct target *target)
static int rtkernel_create(struct target *target)
{
for (size_t i = 0; i < ARRAY_SIZE(rtkernel_params_list); i++) {
- if (strcmp(rtkernel_params_list[i].target_name, target->type->name) == 0) {
+ if (strcmp(rtkernel_params_list[i].target_name, target_type_name(target)) == 0) {
target->rtos->rtos_specific_params = (void *)&rtkernel_params_list[i];
return 0;
}
diff --git a/src/rtos/uCOS-III.c b/src/rtos/uCOS-III.c
index 4d704a44f..f19d06e3c 100644
--- a/src/rtos/uCOS-III.c
+++ b/src/rtos/uCOS-III.c
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include "rtos_ucos_iii_stackings.h"
@@ -253,7 +252,7 @@ static int ucos_iii_create(struct target *target)
struct ucos_iii_private *params;
for (size_t i = 0; i < ARRAY_SIZE(ucos_iii_params_list); i++)
- if (strcmp(ucos_iii_params_list[i].target_name, target->type->name) == 0) {
+ if (strcmp(ucos_iii_params_list[i].target_name, target_type_name(target)) == 0) {
params = calloc(1, sizeof(*params));
if (!params) {
LOG_ERROR("uCOS-III: out of memory");
@@ -268,7 +267,7 @@ static int ucos_iii_create(struct target *target)
return ERROR_OK;
}
- LOG_ERROR("uCOS-III: target not supported: %s", target->type->name);
+ LOG_ERROR("uCOS-III: target not supported: %s", target_type_name(target));
return ERROR_FAIL;
}
diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c
index a4c60904b..023db60c9 100644
--- a/src/rtos/zephyr.c
+++ b/src/rtos/zephyr.c
@@ -20,7 +20,6 @@
#include "rtos.h"
#include "rtos_standard_stackings.h"
#include "target/target.h"
-#include "target/target_type.h"
#include "target/armv7m.h"
#include "target/arc.h"
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index a02878950..dbbf02716 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -128,9 +128,9 @@ static int gdb_actual_connections;
/* set if we are sending a memory map to gdb
* via qXfer:memory-map:read packet */
/* enabled by default*/
-static int gdb_use_memory_map = 1;
+static bool gdb_use_memory_map = true;
/* enabled by default*/
-static int gdb_flash_program = 1;
+static bool gdb_flash_program = true;
/* if set, data aborts cause an error to be reported in memory read packets
* see the code in gdb_read_memory_packet() for further explanations.
@@ -144,7 +144,7 @@ static int gdb_report_register_access_error;
/* set if we are sending target descriptions to gdb
* via qXfer:features:read packet */
/* enabled by default */
-static int gdb_use_target_description = 1;
+static bool gdb_use_target_description = true;
/* current processing free-run type, used by file-I/O */
static char gdb_running_type;
@@ -2656,7 +2656,7 @@ static int gdb_get_target_description_chunk(struct target *target, struct target
return ERROR_OK;
}
-static int gdb_target_description_supported(struct target *target, int *supported)
+static int gdb_target_description_supported(struct target *target, bool *supported)
{
int retval = ERROR_OK;
struct reg **reg_list = NULL;
@@ -2689,9 +2689,9 @@ static int gdb_target_description_supported(struct target *target, int *supporte
if (supported) {
if (architecture || feature_list_size)
- *supported = 1;
+ *supported = true;
else
- *supported = 0;
+ *supported = false;
}
error:
@@ -2904,7 +2904,9 @@ static int gdb_query_packet(struct connection *connection,
len = strtoul(separator + 1, NULL, 16);
+ gdb_connection->output_flag = GDB_OUTPUT_NOTIF;
retval = target_checksum_memory(target, addr, len, &checksum);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
if (retval == ERROR_OK) {
snprintf(gdb_reply, 10, "C%8.8" PRIx32 "", checksum);
@@ -2924,20 +2926,20 @@ static int gdb_query_packet(struct connection *connection,
char *buffer = NULL;
int pos = 0;
int size = 0;
- int gdb_target_desc_supported = 0;
+ bool gdb_target_desc_supported = false;
/* we need to test that the target supports target descriptions */
retval = gdb_target_description_supported(target, &gdb_target_desc_supported);
if (retval != ERROR_OK) {
LOG_INFO("Failed detecting Target Description Support, disabling");
- gdb_target_desc_supported = 0;
+ gdb_target_desc_supported = false;
}
/* support may be disabled globally */
- if (gdb_use_target_description == 0) {
+ if (!gdb_use_target_description) {
if (gdb_target_desc_supported)
LOG_WARNING("Target Descriptions Supported, but disabled");
- gdb_target_desc_supported = 0;
+ gdb_target_desc_supported = false;
}
xml_printf(&retval,
@@ -2946,8 +2948,8 @@ static int gdb_query_packet(struct connection *connection,
&size,
"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+",
GDB_BUFFER_SIZE,
- ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',
- (gdb_target_desc_supported == 1) ? '+' : '-');
+ (gdb_use_memory_map && (flash_get_bank_count() > 0)) ? '+' : '-',
+ gdb_target_desc_supported ? '+' : '-');
if (retval != ERROR_OK) {
gdb_send_error(connection, 01);
@@ -3372,7 +3374,7 @@ static int gdb_v_packet(struct connection *connection,
/* if flash programming disabled - send a empty reply */
- if (gdb_flash_program == 0) {
+ if (!gdb_flash_program) {
gdb_put_packet(connection, "", 0);
return ERROR_OK;
}
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index e7eb96e13..859fdb035 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -285,6 +285,7 @@ static struct ipdbg_hub *ipdbg_allocate_hub(uint8_t data_register_length, struct
{
struct ipdbg_hub *new_hub = calloc(1, sizeof(struct ipdbg_hub));
if (!new_hub) {
+ free(virtual_ir);
LOG_ERROR("Out of memory");
return NULL;
}
@@ -292,6 +293,7 @@ static struct ipdbg_hub *ipdbg_allocate_hub(uint8_t data_register_length, struct
new_hub->name = strdup(name);
if (!new_hub->name) {
free(new_hub);
+ free(virtual_ir);
LOG_ERROR("Out of memory");
return NULL;
}
@@ -304,8 +306,10 @@ static struct ipdbg_hub *ipdbg_allocate_hub(uint8_t data_register_length, struct
new_hub->scratch_memory.fields = calloc(IPDBG_SCRATCH_MEMORY_SIZE, sizeof(struct scan_field));
new_hub->connections = calloc(max_tools, sizeof(struct connection *));
- if (virtual_ir)
+ if (virtual_ir) {
+ new_hub->virtual_ir = virtual_ir;
new_hub->scratch_memory.vir_out_val = calloc(1, DIV_ROUND_UP(virtual_ir->length, 8));
+ }
if (!new_hub->scratch_memory.dr_out_vals || !new_hub->scratch_memory.dr_in_vals ||
!new_hub->scratch_memory.fields || (virtual_ir && !new_hub->scratch_memory.vir_out_val) ||
@@ -997,7 +1001,6 @@ static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uin
new_hub->xoff_mask = BIT(data_register_length - 2);
new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8;
new_hub->last_dn_tool = new_hub->tool_mask;
- new_hub->virtual_ir = virtual_ir;
new_hub->max_tools = ipdbg_max_tools_from_data_register_length(data_register_length);
new_hub->using_queue_size = IPDBG_SCRATCH_MEMORY_SIZE;
@@ -1123,11 +1126,7 @@ COMMAND_HANDLER(handle_ipdbg_create_hub_command)
return ERROR_FAIL;
}
- int retval = ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name, cmd);
- if (retval != ERROR_OK)
- free(virtual_ir);
-
- return retval;
+ return ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name, cmd);
}
static const struct command_registration ipdbg_config_command_handlers[] = {
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 2e4d0b5c0..6a70b2ddf 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1983,7 +1983,7 @@ static int aarch64_assert_reset(struct target *target)
}
/* registers are now invalid */
- if (target_was_examined(target)) {
+ if (armv8->arm.core_cache) {
register_cache_invalidate(armv8->arm.core_cache);
register_cache_invalidate(armv8->arm.core_cache->next);
}
diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c
index 5cea682ec..b5a488201 100644
--- a/src/target/arm_tpiu_swo.c
+++ b/src/target/arm_tpiu_swo.c
@@ -40,7 +40,6 @@
/* START_DEPRECATED_TPIU */
#include
-#include
#define MSG "DEPRECATED \'tpiu config\' command: "
/* END_DEPRECATED_TPIU */
@@ -153,7 +152,7 @@ static int arm_tpiu_swo_poll_trace(void *priv)
}
}
- if (obj->out_filename && obj->out_filename[0] == ':')
+ if (obj->out_filename[0] == ':')
list_for_each_entry(c, &obj->connections, lh)
if (connection_write(c->connection, buf, size) != (int)size)
LOG_ERROR("Error writing to connection"); /* FIXME: which connection? */
@@ -161,7 +160,7 @@ static int arm_tpiu_swo_poll_trace(void *priv)
return ERROR_OK;
}
-static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_tpiu_swo_event event)
+static int arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_tpiu_swo_event event)
{
for (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) {
if (ea->event != event)
@@ -182,7 +181,7 @@ static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_
if (retval == JIM_RETURN)
retval = ea->interp->returnCode;
if (retval == JIM_OK || retval == ERROR_COMMAND_CLOSE_CONNECTION)
- return;
+ return ERROR_OK;
Jim_MakeErrorMessage(ea->interp);
LOG_USER("Error executing event %s on TPIU/SWO %s:\n%s",
@@ -191,8 +190,10 @@ static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_
Jim_GetString(Jim_GetResult(ea->interp), NULL));
/* clean both error code and stacktrace before return */
Jim_Eval(ea->interp, "error \"\" \"\"");
- return;
+ return ERROR_FAIL;
}
+
+ return ERROR_OK;
}
static void arm_tpiu_swo_close_output(struct arm_tpiu_swo_object *obj)
@@ -201,7 +202,7 @@ static void arm_tpiu_swo_close_output(struct arm_tpiu_swo_object *obj)
fclose(obj->file);
obj->file = NULL;
}
- if (obj->out_filename && obj->out_filename[0] == ':')
+ if (obj->out_filename[0] == ':')
remove_service(TCP_SERVICE_NAME, &obj->out_filename[1]);
}
@@ -475,12 +476,13 @@ static int arm_tpiu_swo_configure(struct jim_getopt_info *goi, struct arm_tpiu_s
return JIM_ERR;
}
}
- free(obj->out_filename);
- obj->out_filename = strdup(s);
- if (!obj->out_filename) {
+ char *out_filename = strdup(s);
+ if (!out_filename) {
LOG_ERROR("Out of memory");
return JIM_ERR;
}
+ free(obj->out_filename);
+ obj->out_filename = out_filename;
} else {
if (goi->argc)
goto err_no_params;
@@ -625,16 +627,25 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_enable)
return ERROR_FAIL;
}
- if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
- if (!obj->swo_pin_freq)
+ const bool output_external = !strcmp(obj->out_filename, "external");
+
+ if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) {
+ if (!obj->swo_pin_freq) {
+ if (output_external) {
+ command_print(CMD, "SWO pin frequency required when using external capturing");
+ return ERROR_FAIL;
+ }
+
LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter");
+ }
+ }
struct target *target = get_current_target(CMD_CTX);
/* START_DEPRECATED_TPIU */
if (obj->recheck_ap_cur_target) {
- if (strcmp(target->type->name, "cortex_m") &&
- strcmp(target->type->name, "hla_target")) {
+ if (strcmp(target_type_name(target), "cortex_m") &&
+ strcmp(target_type_name(target), "hla_target")) {
LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
return ERROR_FAIL;
}
@@ -664,7 +675,9 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_enable)
}
/* trigger the event before any attempt to R/W in the TPIU/SWO */
- arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
+ retval = arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
+ if (retval != ERROR_OK)
+ return retval;
retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
if (retval != ERROR_OK) {
@@ -705,7 +718,7 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_enable)
uint16_t prescaler = 1; /* dummy value */
unsigned int swo_pin_freq = obj->swo_pin_freq; /* could be replaced */
- if (obj->out_filename && strcmp(obj->out_filename, "external") && obj->out_filename[0]) {
+ if (!output_external) {
if (obj->out_filename[0] == ':') {
struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv));
if (!priv) {
@@ -790,7 +803,9 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_enable)
if (retval != ERROR_OK)
goto error_exit;
- arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_ENABLE);
+ retval = arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_ENABLE);
+ if (retval != ERROR_OK)
+ goto error_exit;
/* START_DEPRECATED_TPIU */
target_handle_event(target, TARGET_EVENT_TRACE_CONFIG);
@@ -947,6 +962,12 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const
adiv5_mem_ap_spot_init(&obj->spot);
obj->spot.base = TPIU_SWO_DEFAULT_BASE;
obj->port_width = 1;
+ obj->out_filename = strdup("external");
+ if (!obj->out_filename) {
+ LOG_ERROR("Out of memory");
+ free(obj);
+ return JIM_ERR;
+ }
Jim_Obj *n;
jim_getopt_obj(&goi, &n);
@@ -1021,8 +1042,8 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
struct arm_tpiu_swo_object *obj = NULL;
int retval;
- if (strcmp(target->type->name, "cortex_m") &&
- strcmp(target->type->name, "hla_target")) {
+ if (strcmp(target_type_name(target), "cortex_m") &&
+ strcmp(target_type_name(target), "hla_target")) {
LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
return ERROR_FAIL;
}
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index 82f4be5a0..dc3752e0b 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -473,7 +473,7 @@ int armv7a_identify_cache(struct target *target)
/* if no l2 cache initialize l1 data cache flush function function */
if (!armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache) {
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache =
- armv7a_cache_auto_flush_all_data;
+ armv7a_cache_flush_all_data;
}
armv7a->armv7a_mmu.armv7a_cache.info = 1;
@@ -525,7 +525,6 @@ int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a)
armv7a->armv7a_mmu.armv7a_cache.info = -1;
armv7a->armv7a_mmu.armv7a_cache.outer_cache = NULL;
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = NULL;
- armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = 1;
return ERROR_OK;
}
diff --git a/src/target/armv7a.h b/src/target/armv7a.h
index 6b9c2a68f..8943f1c69 100644
--- a/src/target/armv7a.h
+++ b/src/target/armv7a.h
@@ -65,8 +65,6 @@ struct armv7a_cache_common {
struct armv7a_arch_cache arch[6]; /* cache info, L1 - L7 */
int i_cache_enabled;
int d_u_cache_enabled;
- int auto_cache_enabled; /* openocd automatic
- * cache handling */
/* outer unified cache if some */
void *outer_cache;
int (*flush_all_data_cache)(struct target *target);
diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c
index e1f0dfafb..f2f1097c5 100644
--- a/src/target/armv7a_cache.c
+++ b/src/target/armv7a_cache.c
@@ -118,20 +118,19 @@ done:
return retval;
}
-int armv7a_cache_auto_flush_all_data(struct target *target)
+int armv7a_cache_flush_all_data(struct target *target)
{
int retval = ERROR_FAIL;
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)
- return ERROR_OK;
if (target->smp) {
struct target_list *head;
foreach_smp_target(head, target->smp_targets) {
struct target *curr = head->target;
- if (curr->state == TARGET_HALTED)
- retval = armv7a_l1_d_cache_clean_inval_all(curr);
+ if (curr->state == TARGET_HALTED) {
+ int retval1 = armv7a_l1_d_cache_clean_inval_all(curr);
+ if (retval1 != ERROR_OK)
+ retval = retval1;
+ }
}
} else
retval = armv7a_l1_d_cache_clean_inval_all(target);
@@ -391,27 +390,6 @@ int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
return ERROR_OK;
}
-/*
- * We assume that target core was chosen correctly. It means if same data
- * was handled by two cores, other core will loose the changes. Since it
- * is impossible to know (FIXME) which core has correct data, keep in mind
- * that some kind of data lost or corruption is possible.
- * Possible scenario:
- * - core1 loaded and changed data on 0x12345678
- * - we halted target and modified same data on core0
- * - data on core1 will be lost.
- */
-int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,
- uint32_t size)
-{
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)
- return ERROR_OK;
-
- return armv7a_cache_flush_virt(target, virt, size);
-}
-
COMMAND_HANDLER(arm7a_l1_cache_info_cmd)
{
struct target *target = get_current_target(CMD_CTX);
@@ -493,28 +471,6 @@ COMMAND_HANDLER(arm7a_l1_i_cache_inval_virt_cmd)
return armv7a_l1_i_cache_inval_virt(target, virt, size);
}
-COMMAND_HANDLER(arm7a_cache_disable_auto_cmd)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- if (CMD_ARGC == 0) {
- command_print(CMD, "auto cache is %s",
- armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled ? "enabled" : "disabled");
- return ERROR_OK;
- }
-
- if (CMD_ARGC == 1) {
- uint32_t set;
-
- COMMAND_PARSE_ENABLE(CMD_ARGV[0], set);
- armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = !!set;
- return ERROR_OK;
- }
-
- return ERROR_COMMAND_SYNTAX_ERROR;
-}
-
static const struct command_registration arm7a_l1_d_cache_commands[] = {
{
.name = "flush_all",
@@ -584,13 +540,6 @@ static const struct command_registration arm7a_l1_di_cache_group_handlers[] = {
};
static const struct command_registration arm7a_cache_group_handlers[] = {
- {
- .name = "auto",
- .handler = arm7a_cache_disable_auto_cmd,
- .mode = COMMAND_ANY,
- .help = "disable or enable automatic cache handling.",
- .usage = "(1|0)",
- },
{
.name = "l1",
.mode = COMMAND_ANY,
diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h
index 17ec5e6de..c4637c5d3 100644
--- a/src/target/armv7a_cache.h
+++ b/src/target/armv7a_cache.h
@@ -20,9 +20,7 @@ int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,
int armv7a_l1_i_cache_inval_all(struct target *target);
int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
uint32_t size);
-int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,
- uint32_t size);
-int armv7a_cache_auto_flush_all_data(struct target *target);
+int armv7a_cache_flush_all_data(struct target *target);
int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
uint32_t size);
extern const struct command_registration arm7a_cache_command_handlers[];
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 7fa0c4e8b..2de77c960 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -314,19 +314,6 @@ static int cortex_a_exec_opcode(struct target *target,
return retval;
}
-/* Write to memory mapped registers directly with no cache or mmu handling */
-static int cortex_a_dap_write_memap_register_u32(struct target *target,
- uint32_t address,
- uint32_t value)
-{
- int retval;
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap, address, value);
-
- return retval;
-}
-
/*
* Cortex-A implementation of Debug Programmer's Model
*
@@ -611,11 +598,11 @@ static int cortex_a_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,
LOG_DEBUG("A: bpwp enable, vr %08x cr %08x",
(unsigned) vr, (unsigned) cr);
- retval = cortex_a_dap_write_memap_register_u32(dpm->arm->target,
+ retval = mem_ap_write_atomic_u32(a->armv7a_common.debug_ap,
vr, addr);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(dpm->arm->target,
+ retval = mem_ap_write_atomic_u32(a->armv7a_common.debug_ap,
cr, control);
return retval;
}
@@ -641,7 +628,7 @@ static int cortex_a_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)
LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr);
/* clear control register */
- return cortex_a_dap_write_memap_register_u32(dpm->arm->target, cr, 0);
+ return mem_ap_write_atomic_u32(a->armv7a_common.debug_ap, cr, 0);
}
static int cortex_a_dpm_setup(struct cortex_a_common *a, uint32_t didr)
@@ -1323,13 +1310,13 @@ static int cortex_a_set_breakpoint(struct target *target,
brp_list[brp_i].used = true;
brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
brp_list[brp_i].control = control;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
@@ -1362,10 +1349,8 @@ static int cortex_a_set_breakpoint(struct target *target,
return retval;
/* make sure data cache is cleaned & invalidated down to PoC */
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) {
- armv7a_cache_flush_virt(target, breakpoint->address,
+ armv7a_cache_flush_virt(target, breakpoint->address,
breakpoint->length);
- }
retval = target_write_memory(target,
breakpoint->address & 0xFFFFFFFE,
@@ -1417,13 +1402,13 @@ static int cortex_a_set_context_breakpoint(struct target *target,
brp_list[brp_i].used = true;
brp_list[brp_i].value = (breakpoint->asid);
brp_list[brp_i].control = control;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
@@ -1483,13 +1468,13 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi
brp_list[brp_1].used = true;
brp_list[brp_1].value = (breakpoint->asid);
brp_list[brp_1].control = control_ctx;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_1].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_1].brpn,
brp_list[brp_1].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_1].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_1].brpn,
brp_list[brp_1].control);
if (retval != ERROR_OK)
return retval;
@@ -1501,13 +1486,13 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi
brp_list[brp_2].used = true;
brp_list[brp_2].value = (breakpoint->address & 0xFFFFFFFC);
brp_list[brp_2].control = control_iva;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_2].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_2].brpn,
brp_list[brp_2].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_2].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_2].brpn,
brp_list[brp_2].control);
if (retval != ERROR_OK)
return retval;
@@ -1540,13 +1525,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_i].used = false;
brp_list[brp_i].value = 0;
brp_list[brp_i].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
@@ -1559,13 +1544,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_j].used = false;
brp_list[brp_j].value = 0;
brp_list[brp_j].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_j].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_j].brpn,
brp_list[brp_j].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_j].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_j].brpn,
brp_list[brp_j].value);
if (retval != ERROR_OK)
return retval;
@@ -1584,13 +1569,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_i].used = false;
brp_list[brp_i].value = 0;
brp_list[brp_i].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
@@ -1600,10 +1585,8 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
} else {
/* make sure data cache is cleaned & invalidated down to PoC */
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) {
- armv7a_cache_flush_virt(target, breakpoint->address,
+ armv7a_cache_flush_virt(target, breakpoint->address,
breakpoint->length);
- }
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4) {
@@ -1787,14 +1770,14 @@ static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *wat
wrp_list[wrp_i].value = address;
wrp_list[wrp_i].control = control;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].control);
if (retval != ERROR_OK)
return retval;
@@ -1836,13 +1819,13 @@ static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *w
wrp_list[wrp_i].used = false;
wrp_list[wrp_i].value = 0;
wrp_list[wrp_i].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].value);
if (retval != ERROR_OK)
return retval;
@@ -1932,7 +1915,7 @@ static int cortex_a_assert_reset(struct target *target)
}
/* registers are now invalid */
- if (target_was_examined(target))
+ if (armv7a->arm.core_cache)
register_cache_invalidate(armv7a->arm.core_cache);
target->state = TARGET_RESET;
@@ -2791,9 +2774,6 @@ static int cortex_a_write_memory(struct target *target, target_addr_t address,
LOG_DEBUG("Writing memory at address " TARGET_ADDR_FMT "; size %" PRIu32 "; count %" PRIu32,
address, size, count);
- /* memory writes bypass the caches, must flush before writing */
- armv7a_cache_auto_flush_on_write(target, address, size * count);
-
cortex_a_prep_memaccess(target, 0);
retval = cortex_a_write_cpu_memory(target, address, size, count, buffer);
cortex_a_post_memaccess(target, 0);
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 4894cabf8..c225b1aa9 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -1109,6 +1109,11 @@ static int cortex_m_halt_one(struct target *target)
int retval;
LOG_TARGET_DEBUG(target, "target->state: %s", target_state_name(target));
+ if (!target_was_examined(target)) {
+ LOG_TARGET_ERROR(target, "target non examined yet");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
if (target->state == TARGET_HALTED) {
LOG_TARGET_DEBUG(target, "target was already halted");
return ERROR_OK;
@@ -2351,6 +2356,7 @@ static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dw
r->value = state->value;
r->arch_info = state;
r->type = &dwt_reg_type;
+ r->exist = true;
}
static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index f7acc6092..1eb195712 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -1802,10 +1802,8 @@ static int semihosting_service_input_handler(struct connection *connection)
static int semihosting_service_connection_closed_handler(struct connection *connection)
{
struct semihosting_tcp_service *service = connection->service->priv;
- if (service) {
+ if (service)
free(service->name);
- free(service);
- }
return ERROR_OK;
}
diff --git a/src/target/smp.c b/src/target/smp.c
index 50b19d01a..41ca880d4 100644
--- a/src/target/smp.c
+++ b/src/target/smp.c
@@ -119,7 +119,7 @@ COMMAND_HANDLER(default_handle_smp_command)
head->target->smp = 0;
/* fixes the target display to the debugger */
- if (!list_empty(target->smp_targets))
+ if (!list_empty(target->smp_targets) && target->gdb_service)
target->gdb_service->target = target;
return ERROR_OK;
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index 75e0edc77..e9646097f 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -294,3 +294,25 @@ proc "mips_m4k smp_off" {args} {
echo "DEPRECATED! use 'mips_m4k smp off' not 'mips_m4k smp_off'"
eval mips_m4k smp off $args
}
+
+lappend _telnet_autocomplete_skip _post_init_target_cortex_a_cache_auto
+proc _post_init_target_cortex_a_cache_auto {} {
+ set cortex_a_found 0
+
+ foreach t [target names] {
+ if { [$t cget -type] != "cortex_a" } { continue }
+ set cortex_a_found 1
+ lappend ::_telnet_autocomplete_skip "$t cache auto"
+ proc "$t cache auto" { enable } {
+ echo "DEPRECATED! Don't use anymore '[dict get [info frame 0] proc] $enable' as it's always enabled"
+ }
+ }
+
+ if { $cortex_a_found } {
+ lappend ::_telnet_autocomplete_skip "cache auto"
+ proc "cache auto" { enable } {
+ echo "DEPRECATED! Don't use anymore 'cache auto $enable' as it's always enabled"
+ }
+ }
+}
+lappend post_init_commands _post_init_target_cortex_a_cache_auto
diff --git a/src/target/target.c b/src/target/target.c
index 0c5729243..518700676 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1504,7 +1504,7 @@ static int target_init_one(struct command_context *cmd_ctx,
*/
if (type->mmu) {
if (!type->virt2phys) {
- LOG_ERROR("type '%s' is missing virt2phys", type->name);
+ LOG_ERROR("type '%s' is missing virt2phys", target_name(target));
type->virt2phys = identity_virt2phys;
}
} else {
@@ -1513,7 +1513,7 @@ static int target_init_one(struct command_context *cmd_ctx,
* ensure that virt2phys() is always an identity mapping.
*/
if (type->write_phys_memory || type->read_phys_memory || type->virt2phys)
- LOG_WARNING("type '%s' has bad MMU hooks", type->name);
+ LOG_WARNING("type '%s' has bad MMU hooks", target_name(target));
type->mmu = no_mmu;
type->write_phys_memory = type->write_memory;
@@ -6720,6 +6720,13 @@ static const struct command_registration target_exec_command_handlers[] = {
.help = "Write Tcl list of 8/16/32/64 bit numbers to target memory",
.usage = "address width data ['phys']",
},
+ {
+ .name = "debug_reason",
+ .mode = COMMAND_EXEC,
+ .handler = handle_target_debug_reason,
+ .help = "displays the debug reason of this target",
+ .usage = "",
+ },
{
.name = "reset_nag",
.handler = handle_target_reset_nag,
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index fb7748aa2..f7c82efed 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -158,6 +158,12 @@
#define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)
#define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)
+/* Read Protection TLB Entry Info */
+#define XT_INS_PPTLB(X, S, T) _XT_INS_FORMAT_RRR(X, 0x500000, ((S) << 4) | (T), 0xD)
+
+#define XT_TLB1_ACC_SHIFT 8
+#define XT_TLB1_ACC_MSK 0xF
+
#define XT_WATCHPOINTS_NUM_MAX 2
/* Special register number macro for DDR, PS, WB, A3, A4 registers.
@@ -298,6 +304,27 @@ enum xtensa_mem_region_type {
XTENSA_MEM_REGS_NUM
};
+/**
+ * Types of access rights for MPU option
+ * The first block is kernel RWX ARs; the second block is user rwx ARs.
+ */
+enum xtensa_mpu_access_type {
+ XTENSA_ACC_00X_000 = 0x2,
+ XTENSA_ACC_000_00X,
+ XTENSA_ACC_R00_000,
+ XTENSA_ACC_R0X_000,
+ XTENSA_ACC_RW0_000,
+ XTENSA_ACC_RWX_000,
+ XTENSA_ACC_0W0_0W0,
+ XTENSA_ACC_RW0_RWX,
+ XTENSA_ACC_RW0_R00,
+ XTENSA_ACC_RWX_R0X,
+ XTENSA_ACC_R00_R00,
+ XTENSA_ACC_R0X_R0X,
+ XTENSA_ACC_RW0_RW0,
+ XTENSA_ACC_RWX_RWX
+};
+
/* Register definition as union for list allocation */
union xtensa_reg_val_u {
xtensa_reg_val_t val;
@@ -521,6 +548,44 @@ static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint
}
}
+/* NOTE: Assumes A3 has already been saved and marked dirty; A3 will be clobbered */
+static inline bool xtensa_region_ar_exec(struct target *target, target_addr_t start, target_addr_t end)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ if (xtensa->core_config->mpu.enabled) {
+ /* For cores with the MPU option, issue PPTLB on start and end addresses.
+ * Parse access rights field, and confirm both have execute permissions.
+ */
+ for (int i = 0; i <= 1; i++) {
+ uint32_t at, acc;
+ uint8_t at_buf[4];
+ bool exec_acc;
+ target_addr_t addr = i ? end : start;
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addr);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_PPTLB(xtensa, XT_REG_A3, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, at_buf);
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Error queuing PPTLB: %d", res);
+ res = xtensa_core_status_check(target);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Error issuing PPTLB: %d", res);
+ at = buf_get_u32(at_buf, 0, 32);
+ acc = (at >> XT_TLB1_ACC_SHIFT) & XT_TLB1_ACC_MSK;
+ exec_acc = ((acc == XTENSA_ACC_00X_000) || (acc == XTENSA_ACC_R0X_000) ||
+ (acc == XTENSA_ACC_RWX_000) || (acc == XTENSA_ACC_RWX_R0X) ||
+ (acc == XTENSA_ACC_R0X_R0X) || (acc == XTENSA_ACC_RWX_RWX));
+ LOG_TARGET_DEBUG(target, "PPTLB(" TARGET_ADDR_FMT ") -> 0x%08" PRIx32 " exec_acc %d",
+ addr, at, exec_acc);
+ if (!exec_acc)
+ return false;
+ }
+ }
+ return true;
+}
+
static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
{
struct xtensa_debug_module *dm = &xtensa->dbg_mod;
@@ -2176,11 +2241,13 @@ int xtensa_write_memory(struct target *target,
}
} else {
/* Invalidate ICACHE, writeback DCACHE if present */
- uint32_t issue_ihi = xtensa_is_icacheable(xtensa, address);
- uint32_t issue_dhwb = xtensa_is_dcacheable(xtensa, address);
- if (issue_ihi || issue_dhwb) {
+ bool issue_ihi = xtensa_is_icacheable(xtensa, address) &&
+ xtensa_region_ar_exec(target, addrstart_al, addrend_al);
+ bool issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
+ LOG_TARGET_DEBUG(target, "Cache OPs: IHI %d, DHWBI %d", issue_ihi, issue_dhwbi);
+ if (issue_ihi || issue_dhwbi) {
uint32_t ilinesize = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
- uint32_t dlinesize = issue_dhwb ? xtensa->core_config->dcache.line_size : UINT32_MAX;
+ uint32_t dlinesize = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
uint32_t linesize = MIN(ilinesize, dlinesize);
uint32_t off = 0;
adr = addrstart_al;
@@ -2193,7 +2260,7 @@ int xtensa_write_memory(struct target *target,
}
if (issue_ihi)
xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, off));
- if (issue_dhwb)
+ if (issue_dhwbi)
xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, off));
off += linesize;
if (off > 1020) {
@@ -2205,7 +2272,11 @@ int xtensa_write_memory(struct target *target,
/* Execute cache WB/INV instructions */
res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
- xtensa_core_status_check(target);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target,
+ "Error queuing cache writeback/invaldate instruction(s): %d",
+ res);
+ res = xtensa_core_status_check(target);
if (res != ERROR_OK)
LOG_TARGET_ERROR(target,
"Error issuing cache writeback/invaldate instruction(s): %d",
@@ -2367,7 +2438,8 @@ int xtensa_poll(struct target *target)
static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
{
struct xtensa *xtensa = target_to_xtensa(target);
- unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address);
+ unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address) &&
+ xtensa_region_ar_exec(target, address, address + size);
unsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
uint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
uint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
@@ -2385,7 +2457,8 @@ static int xtensa_update_instruction(struct target *target, target_addr_t addres
/* Write start address to A3 and invalidate */
xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
- LOG_TARGET_DEBUG(target, "DHWBI, IHI for address "TARGET_ADDR_FMT, address);
+ LOG_TARGET_DEBUG(target, "IHI %d, DHWBI %d for address " TARGET_ADDR_FMT,
+ issue_ihi, issue_dhwbi, address);
if (issue_dhwbi) {
xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 0));
if (!same_dc_line) {
diff --git a/tcl/target/nrf52.cfg b/tcl/target/nrf52.cfg
index 0c82c5758..0703b1886 100644
--- a/tcl/target/nrf52.cfg
+++ b/tcl/target/nrf52.cfg
@@ -131,10 +131,29 @@ proc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname _chipname} {
0x52840 -
0x52833 -
0x52832 {
+ # Configuration values for all supported trace port speeds, see
+ # TRACECONFIG.TRACEPORTSPEED
+ set trace_port_speeds {
+ 32000000 0
+ 16000000 1
+ 8000000 2
+ 4000000 3
+ }
+
+ # Note that trace port clock stands for what is referred to as
+ # TRACECLKIN in the Arm CoreSight documentation.
+ set trace_port_clock [$_chipname.tpiu cget -traceclk]
+
+ if { ![dict exists $trace_port_speeds $trace_port_clock] } {
+ error "Trace clock speed is not supported"
+ }
+
+ # Set TRACECONFIG.TRACEPORTSPEED
+ mmw 0x4000055C [dict get $trace_port_speeds $trace_port_clock] 0x3
+
if { [$_chipname.tpiu cget -protocol] eq "sync" } {
if { [$_chipname.tpiu cget -port-width] != 4 } {
- echo "Error. Device only supports 4-bit sync traces."
- return
+ error "Device only supports 4-bit sync traces"
}
# Set TRACECONFIG.TRACEMUX to enable synchronous trace
@@ -154,12 +173,10 @@ proc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname _chipname} {
0x52811 -
0x52810 -
0x52805 {
- echo "Error: Device does not support TPIU"
- return
+ error "Device does not support TPIU"
}
default {
- echo "Error: Unknown device"
- return
+ error "Unknown device, cannot configure TPIU"
}
}
}
diff --git a/tcl/target/xilinx_zynqmp.cfg b/tcl/target/xilinx_zynqmp.cfg
index 9734a1837..e8224be04 100644
--- a/tcl/target/xilinx_zynqmp.cfg
+++ b/tcl/target/xilinx_zynqmp.cfg
@@ -104,3 +104,137 @@ proc core_up { args } {
$_TARGETNAME.$core arp_examine
}
}
+
+proc BIT {n} {
+ return [expr {1 << $n}]
+}
+
+set IPI_BASE 0xff300000
+set IPI_PMU_0_TRIG [expr {$IPI_BASE + 0x30000}]
+set IPI_PMU_0_IER [expr {$IPI_BASE + 0x30018}]
+set IPI_PMU_0 [BIT 16]
+
+set CRF_APB_BASE 0xfd1a0000
+set CRF_APB_RST_FPD_APU [expr {$CRF_APB_BASE + 0x104}]
+set CRF_APB_RST_FPD_APU_ACPU0_PWRON_RESET [BIT 10]
+set CRF_APB_RST_FPD_APU_L2_RESET [BIT 8]
+set CRF_APB_RST_FPD_APU_ACPU0_RESET [BIT 0]
+
+set APU_BASE 0xfd5c0000
+set APU_RVBARADDR_BASE [expr {$APU_BASE + 0x40}]
+
+set PMU_BASE 0xffd80000
+set PMU_GLOBAL $PMU_BASE
+set PMU_GLOBAL_MB_SLEEP [BIT 16]
+set PMU_GLOBAL_FW_IS_PRESENT [BIT 4]
+set PMU_GLOBAL_DONT_SLEEP [BIT 0]
+
+set PMU_RAM_BASE 0xffdc0000
+
+set OCM_RAM_BASE 0xfffc0000
+
+rename BIT {}
+
+add_help_text halt_pmu "Halt the PMU in preparation for loading new firmware.\
+ This should be matched with a call to resume_pmu."
+proc halt_pmu {} {
+ set axi $::_CHIPNAME.axi
+ set val [$axi read_memory $::IPI_PMU_0_IER 32 1]
+ $axi write_memory $::IPI_PMU_0_IER 32 [expr {$val | $::IPI_PMU_0}]
+
+ set val [$axi read_memory $::IPI_PMU_0_TRIG 32 1]
+ $axi write_memory $::IPI_PMU_0_TRIG 32 [expr {$val | $::IPI_PMU_0}]
+
+ set start [ms]
+ while {!([$axi read_memory $::PMU_GLOBAL 32 1] & $::PMU_GLOBAL_MB_SLEEP)} {
+ if {[ms] - $start > 1000} {
+ error "Timed out waiting for PMU to halt"
+ }
+ }
+}
+
+add_help_text resume_pmu "Resume the PMU after loading new firmware. This\
+ should be matched with a call to halt_pmu."
+proc resume_pmu {} {
+ set axi $::_CHIPNAME.axi
+ set val [$axi read_memory $::PMU_GLOBAL 32 1]
+ $axi write_memory $::PMU_GLOBAL 32 [expr {$val | $::PMU_GLOBAL_DONT_SLEEP}]
+
+ set start [ms]
+ while {!([$axi read_memory $::PMU_GLOBAL 32 1] & $::PMU_GLOBAL_FW_IS_PRESENT)} {
+ if {[ms] - $start > 5000} {
+ error "Timed out waiting for PMU firmware"
+ }
+ }
+}
+
+add_usage_text release_apu {apu}
+add_help_text release_apu "Release an APU from reset. It will start executing\
+ at RVBARADDR. You probably want resume_apu or start_apu instead."
+proc release_apu {apu} {
+ set axi $::_CHIPNAME.axi
+ set val [$axi read_memory $::CRF_APB_RST_FPD_APU 32 1]
+ set mask [expr {
+ (($::CRF_APB_RST_FPD_APU_ACPU0_PWRON_RESET | \
+ $::CRF_APB_RST_FPD_APU_ACPU0_RESET) << $apu) | \
+ $::CRF_APB_RST_FPD_APU_L2_RESET
+ }]
+ $axi write_memory $::CRF_APB_RST_FPD_APU 32 [expr {$val & ~$mask}]
+
+ core_up $apu
+ $::_TARGETNAME.$apu aarch64 dbginit
+}
+
+proc _rvbaraddr {apu} {
+ return [expr {$::APU_RVBARADDR_BASE + 8 * $apu}]
+}
+
+add_usage_text resume_apu {apu addr}
+add_help_text resume_apu "Resume an APU at a given address."
+proc resume_apu {apu addr} {
+ set addrl [expr {$addr & 0xffffffff}]
+ set addrh [expr {$addr >> 32}]
+ $::_CHIPNAME.axi write_memory [_rvbaraddr $apu] 32 [list $addrl $addrh]
+
+ release_apu $apu
+}
+
+add_usage_text start_apu {apu}
+add_help_text start_apu "Start an APU and put it into an infinite loop at\
+ RVBARADDR. This can be convenient if you just want to halt the APU\
+ (since it won't execute anything unusual)."
+proc start_apu {apu} {
+ set axi $::_CHIPNAME.axi
+ foreach {addrl addrh} [$axi read_memory [_rvbaraddr $apu] 32 2] {
+ set addr [expr {($addrh << 32) | $addrl}]
+ }
+ # write the infinite loop instruction
+ $axi write_memory $addr 32 0x14000000
+
+ release_apu $apu
+}
+
+add_usage_text boot_pmu {image}
+add_help_text boot_pmu "Boot the PMU with a given firmware image, loading it\
+ to the beginning of PMU RAM. The PMU ROM will jump to this location\
+ after we resume it."
+proc boot_pmu {image} {
+ halt_pmu
+ echo "Info : Loading PMU firmware $image to $::PMU_RAM_BASE"
+ load_image $image $::PMU_RAM_BASE
+ resume_pmu
+}
+
+add_usage_text boot_apu "image \[apu=0 \[addr=$OCM_RAM_BASE\]\]"
+add_help_text boot_apu "Boot an APU with a given firmware image. The default\
+ address is the beginning of OCM RAM. Upon success, the default target\
+ will be changed to the (running) apu."
+proc boot_apu [list image {apu 0} [list addr $OCM_RAM_BASE]] {
+ start_apu $apu
+ targets $::_TARGETNAME.$apu
+ halt
+
+ echo "Info : Loading APU$apu firmware $image to $addr"
+ load_image $image $addr
+ resume $addr
+}