Merge pull request #1075 from en-sc/en-sc/from_upstream
Merge up to 437dde701c
from upstream
This commit is contained in:
commit
40cda81e8b
|
@ -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" && \
|
||||
|
|
24
configure.ac
24
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])],
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
/**************************************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -378,11 +378,11 @@ 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)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -413,8 +413,8 @@ 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)
|
||||
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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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,
|
||||
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,
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue