Merge up to 437dde701c from upstream

Conflict in src/rtos/FreeRTOS.c due to
fbea7d5d38 -- resolved by replacing
`target->type->name` with a call to `target_type_name()`.

Change-Id: I56702c6133894458903de7a4d764903004aa8b86
This commit is contained in:
Evgeniy Naydanov 2024-05-30 19:46:03 +03:00
commit 9c4a5d64ca
38 changed files with 470 additions and 244 deletions

View File

@ -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" && \

View File

@ -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])],

View File

@ -97,6 +97,21 @@ OpenOCD project.
x = 0;
}
@endcode
- on <tt> if </tt> 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 <tt> then </tt> 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:

View File

@ -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

View File

@ -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"
/**************************************************************************************************

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -12,7 +12,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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)) {

View File

@ -12,7 +12,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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;

View File

@ -15,7 +15,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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;
}

View File

@ -14,7 +14,6 @@
#include <helper/bits.h>
#include <rtos/rtos.h>
#include <target/target.h>
#include <target/target_type.h>
#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;
}

View File

@ -10,7 +10,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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;

View File

@ -12,7 +12,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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;
}

View File

@ -7,7 +7,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#include "target/target.h"
#include "target/target_type.h"
#include "target/register.h"
#include <target/smp.h>
#include "rtos.h"

View File

@ -13,7 +13,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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;
}

View File

@ -12,7 +12,6 @@
#include <jtag/jtag.h>
#include "target/target.h"
#include "target/target_type.h"
#include "target/armv7m.h"
#include "target/cortex_m.h"
#include "rtos.h"

View File

@ -12,7 +12,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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) {

View File

@ -12,7 +12,6 @@
#include <helper/time_support.h>
#include <jtag/jtag.h>
#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;
}

View File

@ -14,7 +14,6 @@
#include <helper/types.h>
#include <rtos/rtos.h>
#include <target/target.h>
#include <target/target_type.h>
#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;
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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[] = {

View File

@ -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);
}

View File

@ -40,7 +40,6 @@
/* START_DEPRECATED_TPIU */
#include <target/cortex_m.h>
#include <target/target_type.h>
#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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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[];

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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) {

View File

@ -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"
}
}
}

View File

@ -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
}