aboutsummaryrefslogtreecommitdiff
path: root/src/target/openrisc/or1k.c
diff options
context:
space:
mode:
authorFranck Jullien <franck.jullien@gmail.com>2015-01-23 14:09:14 +0100
committerPaul Fertser <fercerpav@gmail.com>2015-03-09 06:38:15 +0000
commitb4b1976e4e01bdc0b33312cda593d7593bae30a9 (patch)
treee11f456f64a6a02b4b9476086644780388f7a8b0 /src/target/openrisc/or1k.c
parent217403ce096627fec035b79f9464e5bfc09e8f06 (diff)
downloadriscv-openocd-b4b1976e4e01bdc0b33312cda593d7593bae30a9.zip
riscv-openocd-b4b1976e4e01bdc0b33312cda593d7593bae30a9.tar.gz
riscv-openocd-b4b1976e4e01bdc0b33312cda593d7593bae30a9.tar.bz2
openrisc: add profiling function
Change-Id: Ifee89b289069590e6086a4713b165989578e29ec Signed-off-by: Franck Jullien <franck.jullien@gmail.com> Reviewed-on: http://openocd.zylin.com/2494 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src/target/openrisc/or1k.c')
-rw-r--r--src/target/openrisc/or1k.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c
index cb18075..33de63e 100644
--- a/src/target/openrisc/or1k.c
+++ b/src/target/openrisc/or1k.c
@@ -29,6 +29,7 @@
#include <target/target.h>
#include <target/breakpoints.h>
#include <target/target_type.h>
+#include <helper/time_support.h>
#include <helper/fileio.h>
#include "or1k_tap.h"
#include "or1k.h"
@@ -1205,6 +1206,53 @@ static int or1k_checksum_memory(struct target *target, uint32_t address,
return ERROR_FAIL;
}
+static int or1k_profiling(struct target *target, uint32_t *samples,
+ uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
+{
+ struct timeval timeout, now;
+ struct or1k_common *or1k = target_to_or1k(target);
+ struct or1k_du *du_core = or1k_to_du(or1k);
+ int retval = ERROR_OK;
+
+ gettimeofday(&timeout, NULL);
+ timeval_add_time(&timeout, seconds, 0);
+
+ LOG_INFO("Starting or1k profiling. Sampling npc 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_ERROR("Error while resuming target");
+ return retval;
+ }
+
+ uint32_t sample_count = 0;
+
+ for (;;) {
+ uint32_t reg_value;
+ retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, GROUP0 + 16 /* NPC */, 1, &reg_value);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Error while reading NPC");
+ return retval;
+ }
+
+ samples[sample_count++] = reg_value;
+
+ gettimeofday(&now, NULL);
+ if ((sample_count >= max_num_samples) ||
+ ((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) {
+ LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
+ break;
+ }
+ }
+
+ *num_samples = sample_count;
+ return retval;
+}
+
COMMAND_HANDLER(or1k_tap_select_command_handler)
{
struct target *target = get_current_target(CMD_CTX);
@@ -1406,4 +1454,6 @@ struct target_type or1k_target = {
.examine = or1k_examine,
.get_gdb_fileio_info = or1k_get_gdb_fileio_info,
+
+ .profiling = or1k_profiling,
};