aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeniy Naydanov <evgeniy.naydanov@syntacore.com>2024-05-30 19:46:03 +0300
committerEvgeniy Naydanov <evgeniy.naydanov@syntacore.com>2024-05-30 19:46:03 +0300
commit9c4a5d64ca8e4310fd81de22bbf141c2a1d62b36 (patch)
treea2d684d591b860976dd01226d7841eeb16030d80 /src
parent347981ca5533b540f187ae3d09495a8e344c4de1 (diff)
parent437dde701c13e707e5fd912ef6403e09052e4d9b (diff)
downloadriscv-openocd-9c4a5d64ca8e4310fd81de22bbf141c2a1d62b36.zip
riscv-openocd-9c4a5d64ca8e4310fd81de22bbf141c2a1d62b36.tar.gz
riscv-openocd-9c4a5d64ca8e4310fd81de22bbf141c2a1d62b36.tar.bz2
Merge up to 437dde701c13e707e5fd912ef6403e09052e4d9b from upstream
Conflict in src/rtos/FreeRTOS.c due to fbea7d5d38d0dcbdd71cb574da9bd12c78b568cf -- resolved by replacing `target->type->name` with a call to `target_type_name()`. Change-Id: I56702c6133894458903de7a4d764903004aa8b86
Diffstat (limited to 'src')
-rw-r--r--src/flash/nor/psoc6.c1
-rw-r--r--src/helper/command.h2
-rw-r--r--src/helper/log.h2
-rw-r--r--src/jtag/drivers/linuxgpiod.c18
-rw-r--r--src/rtos/FreeRTOS.c3
-rw-r--r--src/rtos/ThreadX.c3
-rw-r--r--src/rtos/chibios.c7
-rw-r--r--src/rtos/chromium-ec.c7
-rw-r--r--src/rtos/eCos.c7
-rw-r--r--src/rtos/embKernel.c5
-rw-r--r--src/rtos/hwthread.c1
-rw-r--r--src/rtos/mqx.c7
-rw-r--r--src/rtos/nuttx.c1
-rw-r--r--src/rtos/riot.c3
-rw-r--r--src/rtos/rtkernel.c3
-rw-r--r--src/rtos/uCOS-III.c5
-rw-r--r--src/rtos/zephyr.c1
-rw-r--r--src/server/gdb_server.c28
-rw-r--r--src/server/ipdbg.c13
-rw-r--r--src/target/aarch64.c2
-rw-r--r--src/target/arm_tpiu_swo.c57
-rw-r--r--src/target/armv7a.c3
-rw-r--r--src/target/armv7a.h2
-rw-r--r--src/target/armv7a_cache.c63
-rw-r--r--src/target/armv7a_cache.h4
-rw-r--r--src/target/cortex_a.c104
-rw-r--r--src/target/cortex_m.c6
-rw-r--r--src/target/semihosting_common.c4
-rw-r--r--src/target/smp.c2
-rw-r--r--src/target/startup.tcl22
-rw-r--r--src/target/target.c11
-rw-r--r--src/target/xtensa/xtensa.c89
32 files changed, 262 insertions, 224 deletions
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
index b7ba102..859b3e9 100644
--- a/src/flash/nor/psoc6.c
+++ b/src/flash/nor/psoc6.c
@@ -18,7 +18,6 @@
#include "target/target.h"
#include "target/cortex_m.h"
#include "target/breakpoints.h"
-#include "target/target_type.h"
#include "target/algorithm.h"
/**************************************************************************************************
diff --git a/src/helper/command.h b/src/helper/command.h
index dc45070..fc26dda 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -21,7 +21,7 @@
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
* used for __attribute__((format( ... ))), with GCC v4.4 or later
*/
-#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
+#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004)) && !defined(__clang__)
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
#else
#define PRINTF_ATTRIBUTE_FORMAT printf
diff --git a/src/helper/log.h b/src/helper/log.h
index 818716a..d52c05f 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -19,7 +19,7 @@
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
* used for __attribute__((format( ... ))), with GCC v4.4 or later
*/
-#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))
+#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004)) && !defined(__clang__)
#define PRINTF_ATTRIBUTE_FORMAT gnu_printf
#else
#define PRINTF_ATTRIBUTE_FORMAT printf
diff --git a/src/jtag/drivers/linuxgpiod.c b/src/jtag/drivers/linuxgpiod.c
index 2f3d644..1926ed9 100644
--- a/src/jtag/drivers/linuxgpiod.c
+++ b/src/jtag/drivers/linuxgpiod.c
@@ -378,12 +378,12 @@ static int linuxgpiod_init(void)
goto out_error;
}
- if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
- goto out_error;
+ if (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)
+ goto out_error;
}
if (transport_is_swd()) {
@@ -413,9 +413,9 @@ static int linuxgpiod_init(void)
goto out_error;
}
- if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||
- helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
- goto out_error;
+ if (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK
+ || helper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)
+ goto out_error;
return ERROR_OK;
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index ea37f7f..02409a5 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -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)) {
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
index 5bdd007..61c4926 100644
--- a/src/rtos/ThreadX.c
+++ b/src/rtos/ThreadX.c
@@ -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;
diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c
index 2037827..c1e4e84 100644
--- a/src/rtos/chibios.c
+++ b/src/rtos/chibios.c
@@ -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;
}
diff --git a/src/rtos/chromium-ec.c b/src/rtos/chromium-ec.c
index a95969e..dbfe3b3 100644
--- a/src/rtos/chromium-ec.c
+++ b/src/rtos/chromium-ec.c
@@ -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;
}
diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c
index 10ed128..7048b00 100644
--- a/src/rtos/eCos.c
+++ b/src/rtos/eCos.c
@@ -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;
diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c
index a03b039..7e6de79 100644
--- a/src/rtos/embKernel.c
+++ b/src/rtos/embKernel.c
@@ -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;
}
diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index 763a97d..f256bc2 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -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"
diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c
index d9b6942..b4a1821 100644
--- a/src/rtos/mqx.c
+++ b/src/rtos/mqx.c
@@ -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;
}
diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c
index 0616af0..9100148 100644
--- a/src/rtos/nuttx.c
+++ b/src/rtos/nuttx.c
@@ -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"
diff --git a/src/rtos/riot.c b/src/rtos/riot.c
index be5452e..b90b069 100644
--- a/src/rtos/riot.c
+++ b/src/rtos/riot.c
@@ -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) {
diff --git a/src/rtos/rtkernel.c b/src/rtos/rtkernel.c
index ba1de25..aebbf3d 100644
--- a/src/rtos/rtkernel.c
+++ b/src/rtos/rtkernel.c
@@ -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;
}
diff --git a/src/rtos/uCOS-III.c b/src/rtos/uCOS-III.c
index 4d704a4..f19d06e 100644
--- a/src/rtos/uCOS-III.c
+++ b/src/rtos/uCOS-III.c
@@ -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;
}
diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c
index a4c6090..023db60 100644
--- a/src/rtos/zephyr.c
+++ b/src/rtos/zephyr.c
@@ -20,7 +20,6 @@
#include "rtos.h"
#include "rtos_standard_stackings.h"
#include "target/target.h"
-#include "target/target_type.h"
#include "target/armv7m.h"
#include "target/arc.h"
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index a028789..dbbf027 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -128,9 +128,9 @@ static int gdb_actual_connections;
/* set if we are sending a memory map to gdb
* via qXfer:memory-map:read packet */
/* enabled by default*/
-static int gdb_use_memory_map = 1;
+static bool gdb_use_memory_map = true;
/* enabled by default*/
-static int gdb_flash_program = 1;
+static bool gdb_flash_program = true;
/* if set, data aborts cause an error to be reported in memory read packets
* see the code in gdb_read_memory_packet() for further explanations.
@@ -144,7 +144,7 @@ static int gdb_report_register_access_error;
/* set if we are sending target descriptions to gdb
* via qXfer:features:read packet */
/* enabled by default */
-static int gdb_use_target_description = 1;
+static bool gdb_use_target_description = true;
/* current processing free-run type, used by file-I/O */
static char gdb_running_type;
@@ -2656,7 +2656,7 @@ static int gdb_get_target_description_chunk(struct target *target, struct target
return ERROR_OK;
}
-static int gdb_target_description_supported(struct target *target, int *supported)
+static int gdb_target_description_supported(struct target *target, bool *supported)
{
int retval = ERROR_OK;
struct reg **reg_list = NULL;
@@ -2689,9 +2689,9 @@ static int gdb_target_description_supported(struct target *target, int *supporte
if (supported) {
if (architecture || feature_list_size)
- *supported = 1;
+ *supported = true;
else
- *supported = 0;
+ *supported = false;
}
error:
@@ -2904,7 +2904,9 @@ static int gdb_query_packet(struct connection *connection,
len = strtoul(separator + 1, NULL, 16);
+ gdb_connection->output_flag = GDB_OUTPUT_NOTIF;
retval = target_checksum_memory(target, addr, len, &checksum);
+ gdb_connection->output_flag = GDB_OUTPUT_NO;
if (retval == ERROR_OK) {
snprintf(gdb_reply, 10, "C%8.8" PRIx32 "", checksum);
@@ -2924,20 +2926,20 @@ static int gdb_query_packet(struct connection *connection,
char *buffer = NULL;
int pos = 0;
int size = 0;
- int gdb_target_desc_supported = 0;
+ bool gdb_target_desc_supported = false;
/* we need to test that the target supports target descriptions */
retval = gdb_target_description_supported(target, &gdb_target_desc_supported);
if (retval != ERROR_OK) {
LOG_INFO("Failed detecting Target Description Support, disabling");
- gdb_target_desc_supported = 0;
+ gdb_target_desc_supported = false;
}
/* support may be disabled globally */
- if (gdb_use_target_description == 0) {
+ if (!gdb_use_target_description) {
if (gdb_target_desc_supported)
LOG_WARNING("Target Descriptions Supported, but disabled");
- gdb_target_desc_supported = 0;
+ gdb_target_desc_supported = false;
}
xml_printf(&retval,
@@ -2946,8 +2948,8 @@ static int gdb_query_packet(struct connection *connection,
&size,
"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+",
GDB_BUFFER_SIZE,
- ((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',
- (gdb_target_desc_supported == 1) ? '+' : '-');
+ (gdb_use_memory_map && (flash_get_bank_count() > 0)) ? '+' : '-',
+ gdb_target_desc_supported ? '+' : '-');
if (retval != ERROR_OK) {
gdb_send_error(connection, 01);
@@ -3372,7 +3374,7 @@ static int gdb_v_packet(struct connection *connection,
/* if flash programming disabled - send a empty reply */
- if (gdb_flash_program == 0) {
+ if (!gdb_flash_program) {
gdb_put_packet(connection, "", 0);
return ERROR_OK;
}
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index e7eb96e..859fdb0 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -285,6 +285,7 @@ static struct ipdbg_hub *ipdbg_allocate_hub(uint8_t data_register_length, struct
{
struct ipdbg_hub *new_hub = calloc(1, sizeof(struct ipdbg_hub));
if (!new_hub) {
+ free(virtual_ir);
LOG_ERROR("Out of memory");
return NULL;
}
@@ -292,6 +293,7 @@ static struct ipdbg_hub *ipdbg_allocate_hub(uint8_t data_register_length, struct
new_hub->name = strdup(name);
if (!new_hub->name) {
free(new_hub);
+ free(virtual_ir);
LOG_ERROR("Out of memory");
return NULL;
}
@@ -304,8 +306,10 @@ static struct ipdbg_hub *ipdbg_allocate_hub(uint8_t data_register_length, struct
new_hub->scratch_memory.fields = calloc(IPDBG_SCRATCH_MEMORY_SIZE, sizeof(struct scan_field));
new_hub->connections = calloc(max_tools, sizeof(struct connection *));
- if (virtual_ir)
+ if (virtual_ir) {
+ new_hub->virtual_ir = virtual_ir;
new_hub->scratch_memory.vir_out_val = calloc(1, DIV_ROUND_UP(virtual_ir->length, 8));
+ }
if (!new_hub->scratch_memory.dr_out_vals || !new_hub->scratch_memory.dr_in_vals ||
!new_hub->scratch_memory.fields || (virtual_ir && !new_hub->scratch_memory.vir_out_val) ||
@@ -997,7 +1001,6 @@ static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uin
new_hub->xoff_mask = BIT(data_register_length - 2);
new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8;
new_hub->last_dn_tool = new_hub->tool_mask;
- new_hub->virtual_ir = virtual_ir;
new_hub->max_tools = ipdbg_max_tools_from_data_register_length(data_register_length);
new_hub->using_queue_size = IPDBG_SCRATCH_MEMORY_SIZE;
@@ -1123,11 +1126,7 @@ COMMAND_HANDLER(handle_ipdbg_create_hub_command)
return ERROR_FAIL;
}
- int retval = ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name, cmd);
- if (retval != ERROR_OK)
- free(virtual_ir);
-
- return retval;
+ return ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, hub_name, cmd);
}
static const struct command_registration ipdbg_config_command_handlers[] = {
diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index 2e4d0b5..6a70b2d 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -1983,7 +1983,7 @@ static int aarch64_assert_reset(struct target *target)
}
/* registers are now invalid */
- if (target_was_examined(target)) {
+ if (armv8->arm.core_cache) {
register_cache_invalidate(armv8->arm.core_cache);
register_cache_invalidate(armv8->arm.core_cache->next);
}
diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c
index 5cea682..b5a4882 100644
--- a/src/target/arm_tpiu_swo.c
+++ b/src/target/arm_tpiu_swo.c
@@ -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;
}
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index 82f4be5..dc3752e 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -473,7 +473,7 @@ int armv7a_identify_cache(struct target *target)
/* if no l2 cache initialize l1 data cache flush function function */
if (!armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache) {
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache =
- armv7a_cache_auto_flush_all_data;
+ armv7a_cache_flush_all_data;
}
armv7a->armv7a_mmu.armv7a_cache.info = 1;
@@ -525,7 +525,6 @@ int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a)
armv7a->armv7a_mmu.armv7a_cache.info = -1;
armv7a->armv7a_mmu.armv7a_cache.outer_cache = NULL;
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = NULL;
- armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = 1;
return ERROR_OK;
}
diff --git a/src/target/armv7a.h b/src/target/armv7a.h
index 6b9c2a6..8943f1c 100644
--- a/src/target/armv7a.h
+++ b/src/target/armv7a.h
@@ -65,8 +65,6 @@ struct armv7a_cache_common {
struct armv7a_arch_cache arch[6]; /* cache info, L1 - L7 */
int i_cache_enabled;
int d_u_cache_enabled;
- int auto_cache_enabled; /* openocd automatic
- * cache handling */
/* outer unified cache if some */
void *outer_cache;
int (*flush_all_data_cache)(struct target *target);
diff --git a/src/target/armv7a_cache.c b/src/target/armv7a_cache.c
index e1f0dfa..f2f1097 100644
--- a/src/target/armv7a_cache.c
+++ b/src/target/armv7a_cache.c
@@ -118,20 +118,19 @@ done:
return retval;
}
-int armv7a_cache_auto_flush_all_data(struct target *target)
+int armv7a_cache_flush_all_data(struct target *target)
{
int retval = ERROR_FAIL;
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)
- return ERROR_OK;
if (target->smp) {
struct target_list *head;
foreach_smp_target(head, target->smp_targets) {
struct target *curr = head->target;
- if (curr->state == TARGET_HALTED)
- retval = armv7a_l1_d_cache_clean_inval_all(curr);
+ if (curr->state == TARGET_HALTED) {
+ int retval1 = armv7a_l1_d_cache_clean_inval_all(curr);
+ if (retval1 != ERROR_OK)
+ retval = retval1;
+ }
}
} else
retval = armv7a_l1_d_cache_clean_inval_all(target);
@@ -391,27 +390,6 @@ int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
return ERROR_OK;
}
-/*
- * We assume that target core was chosen correctly. It means if same data
- * was handled by two cores, other core will loose the changes. Since it
- * is impossible to know (FIXME) which core has correct data, keep in mind
- * that some kind of data lost or corruption is possible.
- * Possible scenario:
- * - core1 loaded and changed data on 0x12345678
- * - we halted target and modified same data on core0
- * - data on core1 will be lost.
- */
-int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,
- uint32_t size)
-{
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)
- return ERROR_OK;
-
- return armv7a_cache_flush_virt(target, virt, size);
-}
-
COMMAND_HANDLER(arm7a_l1_cache_info_cmd)
{
struct target *target = get_current_target(CMD_CTX);
@@ -493,28 +471,6 @@ COMMAND_HANDLER(arm7a_l1_i_cache_inval_virt_cmd)
return armv7a_l1_i_cache_inval_virt(target, virt, size);
}
-COMMAND_HANDLER(arm7a_cache_disable_auto_cmd)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- if (CMD_ARGC == 0) {
- command_print(CMD, "auto cache is %s",
- armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled ? "enabled" : "disabled");
- return ERROR_OK;
- }
-
- if (CMD_ARGC == 1) {
- uint32_t set;
-
- COMMAND_PARSE_ENABLE(CMD_ARGV[0], set);
- armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = !!set;
- return ERROR_OK;
- }
-
- return ERROR_COMMAND_SYNTAX_ERROR;
-}
-
static const struct command_registration arm7a_l1_d_cache_commands[] = {
{
.name = "flush_all",
@@ -585,13 +541,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,
.help = "l1 cache command group",
diff --git a/src/target/armv7a_cache.h b/src/target/armv7a_cache.h
index 17ec5e6..c4637c5 100644
--- a/src/target/armv7a_cache.h
+++ b/src/target/armv7a_cache.h
@@ -20,9 +20,7 @@ int armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,
int armv7a_l1_i_cache_inval_all(struct target *target);
int armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,
uint32_t size);
-int armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,
- uint32_t size);
-int armv7a_cache_auto_flush_all_data(struct target *target);
+int armv7a_cache_flush_all_data(struct target *target);
int armv7a_cache_flush_virt(struct target *target, uint32_t virt,
uint32_t size);
extern const struct command_registration arm7a_cache_command_handlers[];
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 7fa0c4e..2de77c9 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -314,19 +314,6 @@ static int cortex_a_exec_opcode(struct target *target,
return retval;
}
-/* Write to memory mapped registers directly with no cache or mmu handling */
-static int cortex_a_dap_write_memap_register_u32(struct target *target,
- uint32_t address,
- uint32_t value)
-{
- int retval;
- struct armv7a_common *armv7a = target_to_armv7a(target);
-
- retval = mem_ap_write_atomic_u32(armv7a->debug_ap, address, value);
-
- return retval;
-}
-
/*
* Cortex-A implementation of Debug Programmer's Model
*
@@ -611,11 +598,11 @@ static int cortex_a_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,
LOG_DEBUG("A: bpwp enable, vr %08x cr %08x",
(unsigned) vr, (unsigned) cr);
- retval = cortex_a_dap_write_memap_register_u32(dpm->arm->target,
+ retval = mem_ap_write_atomic_u32(a->armv7a_common.debug_ap,
vr, addr);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(dpm->arm->target,
+ retval = mem_ap_write_atomic_u32(a->armv7a_common.debug_ap,
cr, control);
return retval;
}
@@ -641,7 +628,7 @@ static int cortex_a_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)
LOG_DEBUG("A: bpwp disable, cr %08x", (unsigned) cr);
/* clear control register */
- return cortex_a_dap_write_memap_register_u32(dpm->arm->target, cr, 0);
+ return mem_ap_write_atomic_u32(a->armv7a_common.debug_ap, cr, 0);
}
static int cortex_a_dpm_setup(struct cortex_a_common *a, uint32_t didr)
@@ -1323,13 +1310,13 @@ static int cortex_a_set_breakpoint(struct target *target,
brp_list[brp_i].used = true;
brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);
brp_list[brp_i].control = control;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
@@ -1362,10 +1349,8 @@ static int cortex_a_set_breakpoint(struct target *target,
return retval;
/* make sure data cache is cleaned & invalidated down to PoC */
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) {
- armv7a_cache_flush_virt(target, breakpoint->address,
+ armv7a_cache_flush_virt(target, breakpoint->address,
breakpoint->length);
- }
retval = target_write_memory(target,
breakpoint->address & 0xFFFFFFFE,
@@ -1417,13 +1402,13 @@ static int cortex_a_set_context_breakpoint(struct target *target,
brp_list[brp_i].used = true;
brp_list[brp_i].value = (breakpoint->asid);
brp_list[brp_i].control = control;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
@@ -1483,13 +1468,13 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi
brp_list[brp_1].used = true;
brp_list[brp_1].value = (breakpoint->asid);
brp_list[brp_1].control = control_ctx;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_1].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_1].brpn,
brp_list[brp_1].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_1].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_1].brpn,
brp_list[brp_1].control);
if (retval != ERROR_OK)
return retval;
@@ -1501,13 +1486,13 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi
brp_list[brp_2].used = true;
brp_list[brp_2].value = (breakpoint->address & 0xFFFFFFFC);
brp_list[brp_2].control = control_iva;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_2].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_2].brpn,
brp_list[brp_2].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_2].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_2].brpn,
brp_list[brp_2].control);
if (retval != ERROR_OK)
return retval;
@@ -1540,13 +1525,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_i].used = false;
brp_list[brp_i].value = 0;
brp_list[brp_i].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
@@ -1559,13 +1544,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_j].used = false;
brp_list[brp_j].value = 0;
brp_list[brp_j].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_j].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_j].brpn,
brp_list[brp_j].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_j].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_j].brpn,
brp_list[brp_j].value);
if (retval != ERROR_OK)
return retval;
@@ -1584,13 +1569,13 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
brp_list[brp_i].used = false;
brp_list[brp_i].value = 0;
brp_list[brp_i].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,
brp_list[brp_i].value);
if (retval != ERROR_OK)
return retval;
@@ -1600,10 +1585,8 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b
} else {
/* make sure data cache is cleaned & invalidated down to PoC */
- if (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) {
- armv7a_cache_flush_virt(target, breakpoint->address,
+ armv7a_cache_flush_virt(target, breakpoint->address,
breakpoint->length);
- }
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4) {
@@ -1787,14 +1770,14 @@ static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *wat
wrp_list[wrp_i].value = address;
wrp_list[wrp_i].control = control;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].value);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].control);
if (retval != ERROR_OK)
return retval;
@@ -1836,13 +1819,13 @@ static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *w
wrp_list[wrp_i].used = false;
wrp_list[wrp_i].value = 0;
wrp_list[wrp_i].control = 0;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].control);
if (retval != ERROR_OK)
return retval;
- retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base
- + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
+ retval = mem_ap_write_atomic_u32(armv7a->debug_ap,
+ armv7a->debug_base + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,
wrp_list[wrp_i].value);
if (retval != ERROR_OK)
return retval;
@@ -1932,7 +1915,7 @@ static int cortex_a_assert_reset(struct target *target)
}
/* registers are now invalid */
- if (target_was_examined(target))
+ if (armv7a->arm.core_cache)
register_cache_invalidate(armv7a->arm.core_cache);
target->state = TARGET_RESET;
@@ -2791,9 +2774,6 @@ static int cortex_a_write_memory(struct target *target, target_addr_t address,
LOG_DEBUG("Writing memory at address " TARGET_ADDR_FMT "; size %" PRIu32 "; count %" PRIu32,
address, size, count);
- /* memory writes bypass the caches, must flush before writing */
- armv7a_cache_auto_flush_on_write(target, address, size * count);
-
cortex_a_prep_memaccess(target, 0);
retval = cortex_a_write_cpu_memory(target, address, size, count, buffer);
cortex_a_post_memaccess(target, 0);
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 4894cab..c225b1a 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -1109,6 +1109,11 @@ static int cortex_m_halt_one(struct target *target)
int retval;
LOG_TARGET_DEBUG(target, "target->state: %s", target_state_name(target));
+ if (!target_was_examined(target)) {
+ LOG_TARGET_ERROR(target, "target non examined yet");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
if (target->state == TARGET_HALTED) {
LOG_TARGET_DEBUG(target, "target was already halted");
return ERROR_OK;
@@ -2351,6 +2356,7 @@ static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dw
r->value = state->value;
r->arch_info = state;
r->type = &dwt_reg_type;
+ r->exist = true;
}
static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c
index f7acc60..1eb1957 100644
--- a/src/target/semihosting_common.c
+++ b/src/target/semihosting_common.c
@@ -1802,10 +1802,8 @@ static int semihosting_service_input_handler(struct connection *connection)
static int semihosting_service_connection_closed_handler(struct connection *connection)
{
struct semihosting_tcp_service *service = connection->service->priv;
- if (service) {
+ if (service)
free(service->name);
- free(service);
- }
return ERROR_OK;
}
diff --git a/src/target/smp.c b/src/target/smp.c
index 50b19d0..41ca880 100644
--- a/src/target/smp.c
+++ b/src/target/smp.c
@@ -119,7 +119,7 @@ COMMAND_HANDLER(default_handle_smp_command)
head->target->smp = 0;
/* fixes the target display to the debugger */
- if (!list_empty(target->smp_targets))
+ if (!list_empty(target->smp_targets) && target->gdb_service)
target->gdb_service->target = target;
return ERROR_OK;
diff --git a/src/target/startup.tcl b/src/target/startup.tcl
index 75e0edc..e964609 100644
--- a/src/target/startup.tcl
+++ b/src/target/startup.tcl
@@ -294,3 +294,25 @@ proc "mips_m4k smp_off" {args} {
echo "DEPRECATED! use 'mips_m4k smp off' not 'mips_m4k smp_off'"
eval mips_m4k smp off $args
}
+
+lappend _telnet_autocomplete_skip _post_init_target_cortex_a_cache_auto
+proc _post_init_target_cortex_a_cache_auto {} {
+ set cortex_a_found 0
+
+ foreach t [target names] {
+ if { [$t cget -type] != "cortex_a" } { continue }
+ set cortex_a_found 1
+ lappend ::_telnet_autocomplete_skip "$t cache auto"
+ proc "$t cache auto" { enable } {
+ echo "DEPRECATED! Don't use anymore '[dict get [info frame 0] proc] $enable' as it's always enabled"
+ }
+ }
+
+ if { $cortex_a_found } {
+ lappend ::_telnet_autocomplete_skip "cache auto"
+ proc "cache auto" { enable } {
+ echo "DEPRECATED! Don't use anymore 'cache auto $enable' as it's always enabled"
+ }
+ }
+}
+lappend post_init_commands _post_init_target_cortex_a_cache_auto
diff --git a/src/target/target.c b/src/target/target.c
index 0c57292..5187006 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1504,7 +1504,7 @@ static int target_init_one(struct command_context *cmd_ctx,
*/
if (type->mmu) {
if (!type->virt2phys) {
- LOG_ERROR("type '%s' is missing virt2phys", type->name);
+ LOG_ERROR("type '%s' is missing virt2phys", target_name(target));
type->virt2phys = identity_virt2phys;
}
} else {
@@ -1513,7 +1513,7 @@ static int target_init_one(struct command_context *cmd_ctx,
* ensure that virt2phys() is always an identity mapping.
*/
if (type->write_phys_memory || type->read_phys_memory || type->virt2phys)
- LOG_WARNING("type '%s' has bad MMU hooks", type->name);
+ LOG_WARNING("type '%s' has bad MMU hooks", target_name(target));
type->mmu = no_mmu;
type->write_phys_memory = type->write_memory;
@@ -6721,6 +6721,13 @@ static const struct command_registration target_exec_command_handlers[] = {
.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,
.mode = COMMAND_ANY,
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index fb7748a..f7c82ef 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -158,6 +158,12 @@
#define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)
#define XT_INS_RFWO_RFWU_MASK(X) (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)
+/* Read Protection TLB Entry Info */
+#define XT_INS_PPTLB(X, S, T) _XT_INS_FORMAT_RRR(X, 0x500000, ((S) << 4) | (T), 0xD)
+
+#define XT_TLB1_ACC_SHIFT 8
+#define XT_TLB1_ACC_MSK 0xF
+
#define XT_WATCHPOINTS_NUM_MAX 2
/* Special register number macro for DDR, PS, WB, A3, A4 registers.
@@ -298,6 +304,27 @@ enum xtensa_mem_region_type {
XTENSA_MEM_REGS_NUM
};
+/**
+ * Types of access rights for MPU option
+ * The first block is kernel RWX ARs; the second block is user rwx ARs.
+ */
+enum xtensa_mpu_access_type {
+ XTENSA_ACC_00X_000 = 0x2,
+ XTENSA_ACC_000_00X,
+ XTENSA_ACC_R00_000,
+ XTENSA_ACC_R0X_000,
+ XTENSA_ACC_RW0_000,
+ XTENSA_ACC_RWX_000,
+ XTENSA_ACC_0W0_0W0,
+ XTENSA_ACC_RW0_RWX,
+ XTENSA_ACC_RW0_R00,
+ XTENSA_ACC_RWX_R0X,
+ XTENSA_ACC_R00_R00,
+ XTENSA_ACC_R0X_R0X,
+ XTENSA_ACC_RW0_RW0,
+ XTENSA_ACC_RWX_RWX
+};
+
/* Register definition as union for list allocation */
union xtensa_reg_val_u {
xtensa_reg_val_t val;
@@ -521,6 +548,44 @@ static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint
}
}
+/* NOTE: Assumes A3 has already been saved and marked dirty; A3 will be clobbered */
+static inline bool xtensa_region_ar_exec(struct target *target, target_addr_t start, target_addr_t end)
+{
+ struct xtensa *xtensa = target_to_xtensa(target);
+ if (xtensa->core_config->mpu.enabled) {
+ /* For cores with the MPU option, issue PPTLB on start and end addresses.
+ * Parse access rights field, and confirm both have execute permissions.
+ */
+ for (int i = 0; i <= 1; i++) {
+ uint32_t at, acc;
+ uint8_t at_buf[4];
+ bool exec_acc;
+ target_addr_t addr = i ? end : start;
+ xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addr);
+ xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_PPTLB(xtensa, XT_REG_A3, XT_REG_A3));
+ xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));
+ xtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, at_buf);
+ int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Error queuing PPTLB: %d", res);
+ res = xtensa_core_status_check(target);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target, "Error issuing PPTLB: %d", res);
+ at = buf_get_u32(at_buf, 0, 32);
+ acc = (at >> XT_TLB1_ACC_SHIFT) & XT_TLB1_ACC_MSK;
+ exec_acc = ((acc == XTENSA_ACC_00X_000) || (acc == XTENSA_ACC_R0X_000) ||
+ (acc == XTENSA_ACC_RWX_000) || (acc == XTENSA_ACC_RWX_R0X) ||
+ (acc == XTENSA_ACC_R0X_R0X) || (acc == XTENSA_ACC_RWX_RWX));
+ LOG_TARGET_DEBUG(target, "PPTLB(" TARGET_ADDR_FMT ") -> 0x%08" PRIx32 " exec_acc %d",
+ addr, at, exec_acc);
+ if (!exec_acc)
+ return false;
+ }
+ }
+ return true;
+}
+
static int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)
{
struct xtensa_debug_module *dm = &xtensa->dbg_mod;
@@ -2176,11 +2241,13 @@ int xtensa_write_memory(struct target *target,
}
} else {
/* Invalidate ICACHE, writeback DCACHE if present */
- uint32_t issue_ihi = xtensa_is_icacheable(xtensa, address);
- uint32_t issue_dhwb = xtensa_is_dcacheable(xtensa, address);
- if (issue_ihi || issue_dhwb) {
+ bool issue_ihi = xtensa_is_icacheable(xtensa, address) &&
+ xtensa_region_ar_exec(target, addrstart_al, addrend_al);
+ bool issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
+ LOG_TARGET_DEBUG(target, "Cache OPs: IHI %d, DHWBI %d", issue_ihi, issue_dhwbi);
+ if (issue_ihi || issue_dhwbi) {
uint32_t ilinesize = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
- uint32_t dlinesize = issue_dhwb ? xtensa->core_config->dcache.line_size : UINT32_MAX;
+ uint32_t dlinesize = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
uint32_t linesize = MIN(ilinesize, dlinesize);
uint32_t off = 0;
adr = addrstart_al;
@@ -2193,7 +2260,7 @@ int xtensa_write_memory(struct target *target,
}
if (issue_ihi)
xtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, off));
- if (issue_dhwb)
+ if (issue_dhwbi)
xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, off));
off += linesize;
if (off > 1020) {
@@ -2205,7 +2272,11 @@ int xtensa_write_memory(struct target *target,
/* Execute cache WB/INV instructions */
res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
- xtensa_core_status_check(target);
+ if (res != ERROR_OK)
+ LOG_TARGET_ERROR(target,
+ "Error queuing cache writeback/invaldate instruction(s): %d",
+ res);
+ res = xtensa_core_status_check(target);
if (res != ERROR_OK)
LOG_TARGET_ERROR(target,
"Error issuing cache writeback/invaldate instruction(s): %d",
@@ -2367,7 +2438,8 @@ int xtensa_poll(struct target *target)
static int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
{
struct xtensa *xtensa = target_to_xtensa(target);
- unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address);
+ unsigned int issue_ihi = xtensa_is_icacheable(xtensa, address) &&
+ xtensa_region_ar_exec(target, address, address + size);
unsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address);
uint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;
uint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;
@@ -2385,7 +2457,8 @@ static int xtensa_update_instruction(struct target *target, target_addr_t addres
/* Write start address to A3 and invalidate */
xtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);
xtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));
- LOG_TARGET_DEBUG(target, "DHWBI, IHI for address "TARGET_ADDR_FMT, address);
+ LOG_TARGET_DEBUG(target, "IHI %d, DHWBI %d for address " TARGET_ADDR_FMT,
+ issue_ihi, issue_dhwbi, address);
if (issue_dhwbi) {
xtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 0));
if (!same_dc_line) {