target/cortex_m: reduce duplication in profiling
The Cortex-M implementation of profiling contains a bunch of conditionals and checks to handle both chips which have PCSR and chips which do not. However, the net effect of the non-PCSR branches is actually exactly the same as what target_profiling_default does. Rather than duplicating this code, just detect the situation where PCSR isn’t available and delegate to target_profiling_default. Change-Id: I1be57ac77f983816ab6bf644a3cfca77b67d6f70 Signed-off-by: Christopher Head <chead@zaber.com> Reviewed-on: http://openocd.zylin.com/5236 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
parent
a7502ee8b9
commit
d3aa2d3536
|
@ -1835,28 +1835,23 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
|
||||||
struct timeval timeout, now;
|
struct timeval timeout, now;
|
||||||
struct armv7m_common *armv7m = target_to_armv7m(target);
|
struct armv7m_common *armv7m = target_to_armv7m(target);
|
||||||
uint32_t reg_value;
|
uint32_t reg_value;
|
||||||
bool use_pcsr = false;
|
int retval;
|
||||||
int retval = ERROR_OK;
|
|
||||||
struct reg *reg;
|
|
||||||
|
|
||||||
gettimeofday(&timeout, NULL);
|
|
||||||
timeval_add_time(&timeout, seconds, 0);
|
|
||||||
|
|
||||||
retval = target_read_u32(target, DWT_PCSR, ®_value);
|
retval = target_read_u32(target, DWT_PCSR, ®_value);
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("Error while reading PCSR");
|
LOG_ERROR("Error while reading PCSR");
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
if (reg_value == 0) {
|
||||||
if (reg_value != 0) {
|
LOG_INFO("PCSR sampling not supported on this processor.");
|
||||||
use_pcsr = true;
|
return target_profiling_default(target, samples, max_num_samples, num_samples, seconds);
|
||||||
LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
|
|
||||||
} else {
|
|
||||||
LOG_INFO("Starting profiling. Halting and resuming the"
|
|
||||||
" target as often as we can...");
|
|
||||||
reg = register_get_by_name(target->reg_cache, "pc", 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gettimeofday(&timeout, NULL);
|
||||||
|
timeval_add_time(&timeout, seconds, 0);
|
||||||
|
|
||||||
|
LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
|
||||||
|
|
||||||
/* Make sure the target is running */
|
/* Make sure the target is running */
|
||||||
target_poll(target);
|
target_poll(target);
|
||||||
if (target->state == TARGET_HALTED)
|
if (target->state == TARGET_HALTED)
|
||||||
|
@ -1870,40 +1865,21 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
|
||||||
uint32_t sample_count = 0;
|
uint32_t sample_count = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (use_pcsr) {
|
if (armv7m && armv7m->debug_ap) {
|
||||||
if (armv7m && armv7m->debug_ap) {
|
uint32_t read_count = max_num_samples - sample_count;
|
||||||
uint32_t read_count = max_num_samples - sample_count;
|
if (read_count > 1024)
|
||||||
if (read_count > 1024)
|
read_count = 1024;
|
||||||
read_count = 1024;
|
|
||||||
|
|
||||||
retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
|
retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
|
||||||
(void *)&samples[sample_count],
|
(void *)&samples[sample_count],
|
||||||
4, read_count, DWT_PCSR);
|
4, read_count, DWT_PCSR);
|
||||||
sample_count += read_count;
|
sample_count += read_count;
|
||||||
} else {
|
|
||||||
target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
target_poll(target);
|
target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
|
||||||
if (target->state == TARGET_HALTED) {
|
|
||||||
reg_value = buf_get_u32(reg->value, 0, 32);
|
|
||||||
/* current pc, addr = 0, do not handle breakpoints, not debugging */
|
|
||||||
retval = target_resume(target, 1, 0, 0, 0);
|
|
||||||
samples[sample_count++] = reg_value;
|
|
||||||
target_poll(target);
|
|
||||||
alive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */
|
|
||||||
} else if (target->state == TARGET_RUNNING) {
|
|
||||||
/* We want to quickly sample the PC. */
|
|
||||||
retval = target_halt(target);
|
|
||||||
} else {
|
|
||||||
LOG_INFO("Target not halted or running");
|
|
||||||
retval = ERROR_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("Error while reading %s", use_pcsr ? "PCSR" : "target pc");
|
LOG_ERROR("Error while reading PCSR");
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,6 @@ static int target_get_gdb_fileio_info_default(struct target *target,
|
||||||
struct gdb_fileio_info *fileio_info);
|
struct gdb_fileio_info *fileio_info);
|
||||||
static int target_gdb_fileio_end_default(struct target *target, int retcode,
|
static int target_gdb_fileio_end_default(struct target *target, int retcode,
|
||||||
int fileio_errno, bool ctrl_c);
|
int fileio_errno, bool ctrl_c);
|
||||||
static int target_profiling_default(struct target *target, uint32_t *samples,
|
|
||||||
uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
|
|
||||||
|
|
||||||
/* targets */
|
/* targets */
|
||||||
extern struct target_type arm7tdmi_target;
|
extern struct target_type arm7tdmi_target;
|
||||||
|
@ -2137,7 +2135,7 @@ static int target_gdb_fileio_end_default(struct target *target,
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int target_profiling_default(struct target *target, uint32_t *samples,
|
int target_profiling_default(struct target *target, uint32_t *samples,
|
||||||
uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
|
uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
|
||||||
{
|
{
|
||||||
struct timeval timeout, now;
|
struct timeval timeout, now;
|
||||||
|
|
|
@ -748,6 +748,9 @@ void target_handle_md_output(struct command_invocation *cmd,
|
||||||
struct target *target, target_addr_t address, unsigned size,
|
struct target *target, target_addr_t address, unsigned size,
|
||||||
unsigned count, const uint8_t *buffer);
|
unsigned count, const uint8_t *buffer);
|
||||||
|
|
||||||
|
int target_profiling_default(struct target *target, uint32_t *samples, uint32_t
|
||||||
|
max_num_samples, uint32_t *num_samples, uint32_t seconds);
|
||||||
|
|
||||||
#define ERROR_TARGET_INVALID (-300)
|
#define ERROR_TARGET_INVALID (-300)
|
||||||
#define ERROR_TARGET_INIT_FAILED (-301)
|
#define ERROR_TARGET_INIT_FAILED (-301)
|
||||||
#define ERROR_TARGET_TIMEOUT (-302)
|
#define ERROR_TARGET_TIMEOUT (-302)
|
||||||
|
|
Loading…
Reference in New Issue