diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index 10f14221d..32b48a7c5 100644 --- a/src/target/armv7m_trace.c +++ b/src/target/armv7m_trace.c @@ -24,6 +24,7 @@ #include #include #include +#include #define TRACE_BUF_SIZE 4096 @@ -162,6 +163,33 @@ int armv7m_trace_itm_config(struct target *target) if (retval != ERROR_OK) return retval; + /* pg315 of CoreSight Components + * It is recommended that the ITMEn bit is cleared and waits for the + * ITMBusy bit to be cleared, before changing any fields in the + * Control Register, otherwise the behavior can be unpredictable. + */ + uint32_t itm_tcr; + retval = target_read_u32(target, ITM_TCR, &itm_tcr); + if (retval != ERROR_OK) + return retval; + retval = target_write_u32(target, + ITM_TCR, + itm_tcr & ~ITM_TCR_ITMENA_BIT + ); + if (retval != ERROR_OK) + return retval; + + int64_t then = timeval_ms() + 1000; + do { + retval = target_read_u32(target, ITM_TCR, &itm_tcr); + if (retval != ERROR_OK) + return retval; + if (timeval_ms() > then) { + LOG_ERROR("timeout waiting for ITM_TCR_BUSY_BIT"); + return ERROR_FAIL; + } + } while (itm_tcr & ITM_TCR_BUSY_BIT); + /* Enable ITM, TXENA, set TraceBusID and other parameters */ retval = target_write_u32(target, ITM_TCR, (1 << 0) | (1 << 3) | (trace_config->itm_diff_timestamps << 1) | diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index b470fbd70..1e2197b1a 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -35,6 +35,8 @@ #define ITM_TER0 0xE0000E00 #define ITM_TPR 0xE0000E40 #define ITM_TCR 0xE0000E80 +#define ITM_TCR_ITMENA_BIT BIT(0) +#define ITM_TCR_BUSY_BIT BIT(23) #define ITM_LAR 0xE0000FB0 #define ITM_LAR_KEY 0xC5ACCE55