]> git.gag.com Git - fw/openocd/commitdiff
target/cortex_m: reduce duplication in profiling
authorChristopher Head <chead@zaber.com>
Fri, 14 Jun 2019 22:25:26 +0000 (15:25 -0700)
committerAntonio Borneo <borneo.antonio@gmail.com>
Fri, 30 Oct 2020 22:00:57 +0000 (22:00 +0000)
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>
src/target/cortex_m.c
src/target/target.c
src/target/target.h

index abc377f0dc31b699999dadba8a285e6e863c7171..503995a5db2068d70914c2491b50bbd953911ebd 100644 (file)
@@ -1835,28 +1835,23 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
        struct timeval timeout, now;
        struct armv7m_common *armv7m = target_to_armv7m(target);
        uint32_t reg_value;
-       bool use_pcsr = false;
-       int retval = ERROR_OK;
-       struct reg *reg;
-
-       gettimeofday(&timeout, NULL);
-       timeval_add_time(&timeout, seconds, 0);
+       int retval;
 
        retval = target_read_u32(target, DWT_PCSR, &reg_value);
        if (retval != ERROR_OK) {
                LOG_ERROR("Error while reading PCSR");
                return retval;
        }
-
-       if (reg_value != 0) {
-               use_pcsr = true;
-               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);
+       if (reg_value == 0) {
+               LOG_INFO("PCSR sampling not supported on this processor.");
+               return target_profiling_default(target, samples, max_num_samples, num_samples, seconds);
        }
 
+       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 */
        target_poll(target);
        if (target->state == TARGET_HALTED)
@@ -1870,40 +1865,21 @@ int cortex_m_profiling(struct target *target, uint32_t *samples,
        uint32_t sample_count = 0;
 
        for (;;) {
-               if (use_pcsr) {
-                       if (armv7m && armv7m->debug_ap) {
-                               uint32_t read_count = max_num_samples - sample_count;
-                               if (read_count > 1024)
-                                       read_count = 1024;
-
-                               retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
-                                                       (void *)&samples[sample_count],
-                                                       4, read_count, DWT_PCSR);
-                               sample_count += read_count;
-                       } else {
-                               target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
-                       }
+               if (armv7m && armv7m->debug_ap) {
+                       uint32_t read_count = max_num_samples - sample_count;
+                       if (read_count > 1024)
+                               read_count = 1024;
+
+                       retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
+                                               (void *)&samples[sample_count],
+                                               4, read_count, DWT_PCSR);
+                       sample_count += read_count;
                } else {
-                       target_poll(target);
-                       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;
-                       }
+                       target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
                }
 
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Error while reading %s", use_pcsr ? "PCSR" : "target pc");
+                       LOG_ERROR("Error while reading PCSR");
                        return retval;
                }
 
index d1399eddfe82c72e3e5932d4cba2930686f99176..e64004fe56d3f228c2282418f0fae9f202e7f267 100644 (file)
@@ -72,8 +72,6 @@ static int target_get_gdb_fileio_info_default(struct target *target,
                struct gdb_fileio_info *fileio_info);
 static int target_gdb_fileio_end_default(struct target *target, int retcode,
                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 */
 extern struct target_type arm7tdmi_target;
@@ -2137,7 +2135,7 @@ static int target_gdb_fileio_end_default(struct target *target,
        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)
 {
        struct timeval timeout, now;
index c69aa934a60898dd2e7c0a393824bb1bf5d4163f..9589b535ad2a9d6500090917e830600c9baf9c79 100644 (file)
@@ -748,6 +748,9 @@ void target_handle_md_output(struct command_invocation *cmd,
        struct target *target, target_addr_t address, unsigned size,
        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_INIT_FAILED (-301)
 #define ERROR_TARGET_TIMEOUT   (-302)