aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Allen <rsaxvc@rsaxvc.net>2024-07-31 20:53:52 -0500
committerAntonio Borneo <borneo.antonio@gmail.com>2024-09-15 09:13:05 +0000
commit930ec2f439f2f7d81894a292f0df5a56f9ff0ce8 (patch)
treedd130246f77fed8bf1e7c9253f070b04e0233276
parente5276bb945b518c7e9df5b7e069cc6bf45a96c35 (diff)
downloadriscv-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.c1
-rw-r--r--src/target/espressif/esp_xtensa.c72
-rw-r--r--src/target/espressif/esp_xtensa.h3
-rw-r--r--src/target/xtensa/xtensa_debug_module.h2
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 */ \