diff options
author | Richard Allen <rsaxvc@rsaxvc.net> | 2024-07-31 20:53:52 -0500 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2024-09-15 09:13:05 +0000 |
commit | 930ec2f439f2f7d81894a292f0df5a56f9ff0ce8 (patch) | |
tree | dd130246f77fed8bf1e7c9253f070b04e0233276 | |
parent | e5276bb945b518c7e9df5b7e069cc6bf45a96c35 (diff) | |
download | riscv-openocd-930ec2f439f2f7d81894a292f0df5a56f9ff0ce8.zip riscv-openocd-930ec2f439f2f7d81894a292f0df5a56f9ff0ce8.tar.gz riscv-openocd-930ec2f439f2f7d81894a292f0df5a56f9ff0ce8.tar.bz2 |
target/espressif: add profiling function for ESP32-S3
Use the TRAX interface DEBUGPC if available.
Otherwise use default stop-and-go profiling.
ESP32-S3, before this patch:
Internal: 8 samples/second
FT2232H: 12 samples/second
After this patch:
Internal: 18ksamples/second
FT2232H: 100ksamples/second
Change-Id: I681f0bccf4263c1e24f38be511e3b3aec8bf4d60
Signed-off-by: Richard Allen <rsaxvc@rsaxvc.net>
Reviewed-on: https://review.openocd.org/c/openocd/+/8431
Reviewed-by: Erhan Kurubas <erhan.kurubas@espressif.com>
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Ian Thompson <ianst@cadence.com>
Reviewed-by: Yurii Shutkin <yurii.shutkin@gmail.com>
-rw-r--r-- | src/target/espressif/esp32s3.c | 1 | ||||
-rw-r--r-- | src/target/espressif/esp_xtensa.c | 72 | ||||
-rw-r--r-- | src/target/espressif/esp_xtensa.h | 3 | ||||
-rw-r--r-- | src/target/xtensa/xtensa_debug_module.h | 2 |
4 files changed, 78 insertions, 0 deletions
diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c index 22e1630..2afb4b0 100644 --- a/src/target/espressif/esp32s3.c +++ b/src/target/espressif/esp32s3.c @@ -421,4 +421,5 @@ struct target_type esp32s3_target = { .deinit_target = esp_xtensa_target_deinit, .commands = esp32s3_command_handlers, + .profiling = esp_xtensa_profiling, }; diff --git a/src/target/espressif/esp_xtensa.c b/src/target/espressif/esp_xtensa.c index 11895d2..9b57f34 100644 --- a/src/target/espressif/esp_xtensa.c +++ b/src/target/espressif/esp_xtensa.c @@ -179,3 +179,75 @@ int esp_xtensa_breakpoint_remove(struct target *target, struct breakpoint *break return xtensa_breakpoint_remove(target, breakpoint); /* flash breakpoints will be handled in another patch */ } + +int esp_xtensa_profiling(struct target *target, uint32_t *samples, + uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) +{ + struct timeval timeout, now; + struct xtensa *xtensa = target_to_xtensa(target); + int retval = ERROR_OK; + int res; + + /* Vary samples per pass to avoid sampling a periodic function periodically */ + #define MIN_PASS 200 + #define MAX_PASS 1000 + + gettimeofday(&timeout, NULL); + timeval_add_time(&timeout, seconds, 0); + + uint8_t buf[sizeof(uint32_t) * MAX_PASS]; + + /* Capture one sample to verify the register is present and working */ + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DEBUGPC, buf); + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res != ERROR_OK) { + LOG_TARGET_INFO(target, "Failed to read DEBUGPC, fallback to stop-and-go"); + return target_profiling_default(target, samples, max_num_samples, num_samples, seconds); + } else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0) { + LOG_TARGET_INFO(target, "NULL DEBUGPC, fallback to stop-and-go"); + return target_profiling_default(target, samples, max_num_samples, num_samples, seconds); + } + + LOG_TARGET_INFO(target, "Starting XTENSA DEBUGPC profiling. Sampling as fast as we can..."); + + /* Make sure the target is running */ + target_poll(target); + if (target->state == TARGET_HALTED) + retval = target_resume(target, 1, 0, 0, 0); + + if (retval != ERROR_OK) { + LOG_TARGET_ERROR(target, "Error while resuming target"); + return retval; + } + + uint32_t sample_count = 0; + + for (;;) { + uint32_t remaining = max_num_samples - sample_count; + uint32_t this_pass = rand() % (MAX_PASS - MIN_PASS) + MIN_PASS; + this_pass = this_pass > remaining ? remaining : this_pass; + for (uint32_t i = 0; i < this_pass; ++i) + xtensa_queue_dbg_reg_read(xtensa, XDMREG_DEBUGPC, buf + i * sizeof(uint32_t)); + res = xtensa_dm_queue_execute(&xtensa->dbg_mod); + if (res != ERROR_OK) { + LOG_TARGET_ERROR(target, "Failed to read DEBUGPC!"); + return res; + } + + for (uint32_t i = 0; i < this_pass; ++i) { + uint32_t sample32 = buf_get_u32(buf + i * sizeof(uint32_t), 0, 32); + samples[sample_count++] = sample32; + } + gettimeofday(&now, NULL); + if (sample_count >= max_num_samples || timeval_compare(&now, &timeout) > 0) { + LOG_TARGET_INFO(target, "Profiling completed. %" PRIu32 " samples.", sample_count); + break; + } + } + + *num_samples = sample_count; + return retval; + + #undef MIN_PASS + #undef MAX_PASS +} diff --git a/src/target/espressif/esp_xtensa.h b/src/target/espressif/esp_xtensa.h index 00f67a3..56c903f 100644 --- a/src/target/espressif/esp_xtensa.h +++ b/src/target/espressif/esp_xtensa.h @@ -37,6 +37,9 @@ void esp_xtensa_queue_tdi_idle(struct target *target); int esp_xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint); int esp_xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint); int esp_xtensa_poll(struct target *target); +int esp_xtensa_profiling(struct target *target, uint32_t *samples, + uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds); + int esp_xtensa_on_halt(struct target *target); #endif /* OPENOCD_TARGET_ESP_XTENSA_H */ diff --git a/src/target/xtensa/xtensa_debug_module.h b/src/target/xtensa/xtensa_debug_module.h index 495da2a..8391a96 100644 --- a/src/target/xtensa/xtensa_debug_module.h +++ b/src/target/xtensa/xtensa_debug_module.h @@ -75,6 +75,7 @@ enum xtensa_dm_reg { XDMREG_DELAYCNT, XDMREG_MEMADDRSTART, XDMREG_MEMADDREND, + XDMREG_DEBUGPC,/*Unsupported, undocumented, may not be present*/ XDMREG_EXTTIMELO, XDMREG_EXTTIMEHI, XDMREG_TRAXRSVD48, @@ -184,6 +185,7 @@ struct xtensa_dm_reg_offsets { { .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \ { .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \ { .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \ + { .nar = 0x0f, .apb = 0x003c }, /* XDMREG_DEBUGPC */ \ { .nar = 0x10, .apb = 0x0040 }, /* XDMREG_EXTTIMELO */ \ { .nar = 0x11, .apb = 0x0044 }, /* XDMREG_EXTTIMEHI */ \ { .nar = 0x12, .apb = 0x0048 }, /* XDMREG_TRAXRSVD48 */ \ |