Add before/after timestamps to memory sampling. (#550)

This lets a user see exactly what period of time was sampled, without
having to guess how much time the target was ignored in between bursts.

Change-Id: I5c0639528636bf1a88f249be3ba59bec28c001e2
Signed-off-by: Tim Newsome <tim@sifive.com>
This commit is contained in:
Tim Newsome 2020-10-21 12:21:05 -07:00 committed by GitHub
parent ccb21ab5ac
commit 3cf46af271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 12 deletions

View File

@ -2207,7 +2207,7 @@ static int sample_memory_bus_v1(struct target *target,
for (unsigned n = 0; n < repeat; n++) {
for (unsigned i = 0; i < DIM(config->bucket); i++) {
if (config->bucket[i].enabled) {
assert(i < RISCV_SAMPLE_BUF_TIMESTAMP);
assert(i < RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE);
uint64_t value = 0;
if (config->bucket[i].size_bytes > 4)
value = ((uint64_t) riscv_batch_get_dmi_read_data(batch, read++)) << 32;

View File

@ -256,18 +256,19 @@ virt2phys_info_t sv48 = {
.pa_ppn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ffff},
};
void riscv_sample_buf_maybe_add_timestamp(struct target *target)
void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before)
{
RISCV_INFO(r);
uint32_t now = timeval_ms() & 0xffffffff;
if (r->sample_buf.used + 5 < r->sample_buf.size &&
(r->sample_buf.used == 0 || r->sample_buf.last_timestamp != now)) {
r->sample_buf.buf[r->sample_buf.used++] = RISCV_SAMPLE_BUF_TIMESTAMP;
if (r->sample_buf.used + 5 < r->sample_buf.size) {
if (before)
r->sample_buf.buf[r->sample_buf.used++] = RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE;
else
r->sample_buf.buf[r->sample_buf.used++] = RISCV_SAMPLE_BUF_TIMESTAMP_AFTER;
r->sample_buf.buf[r->sample_buf.used++] = now & 0xff;
r->sample_buf.buf[r->sample_buf.used++] = (now >> 8) & 0xff;
r->sample_buf.buf[r->sample_buf.used++] = (now >> 16) & 0xff;
r->sample_buf.buf[r->sample_buf.used++] = (now >> 24) & 0xff;
r->sample_buf.last_timestamp = now;
}
}
@ -2149,7 +2150,7 @@ int sample_memory(struct target *target)
LOG_DEBUG("buf used/size: %d/%d", r->sample_buf.used, r->sample_buf.size);
uint64_t start = timeval_ms();
riscv_sample_buf_maybe_add_timestamp(target);
riscv_sample_buf_maybe_add_timestamp(target, true);
int result = ERROR_OK;
if (r->sample_memory) {
result = r->sample_memory(target, &r->sample_buf, &r->sample_config,
@ -2163,7 +2164,7 @@ int sample_memory(struct target *target)
for (unsigned i = 0; i < DIM(r->sample_config.bucket); i++) {
if (r->sample_config.bucket[i].enabled &&
r->sample_buf.used + 1 + r->sample_config.bucket[i].size_bytes < r->sample_buf.size) {
assert(i < RISCV_SAMPLE_BUF_TIMESTAMP);
assert(i < RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE);
r->sample_buf.buf[r->sample_buf.used] = i;
result = riscv_read_phys_memory(
target, r->sample_config.bucket[i].address,
@ -2178,6 +2179,7 @@ int sample_memory(struct target *target)
}
exit:
riscv_sample_buf_maybe_add_timestamp(target, false);
if (result != ERROR_OK) {
LOG_INFO("Turning off memory sampling because it failed.");
r->sample_config.enabled = false;
@ -3092,10 +3094,14 @@ COMMAND_HANDLER(handle_dump_sample_buf_command)
unsigned i = 0;
while (i < r->sample_buf.used) {
uint8_t command = r->sample_buf.buf[i++];
if (command == RISCV_SAMPLE_BUF_TIMESTAMP) {
if (command == RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE) {
uint32_t timestamp = buf_get_u32(r->sample_buf.buf + i, 0, 32);
i += 4;
command_print(CMD, "timestamp: %u", timestamp);
command_print(CMD, "timestamp before: %u", timestamp);
} else if (command == RISCV_SAMPLE_BUF_TIMESTAMP_AFTER) {
uint32_t timestamp = buf_get_u32(r->sample_buf.buf + i, 0, 32);
i += 4;
command_print(CMD, "timestamp after: %u", timestamp);
} else if (command < DIM(r->sample_config.bucket)) {
command_print_sameline(CMD, "0x%" TARGET_PRIxADDR ": ",
r->sample_config.bucket[command].address);

View File

@ -60,12 +60,12 @@ typedef struct {
unsigned custom_number;
} riscv_reg_info_t;
#define RISCV_SAMPLE_BUF_TIMESTAMP 0x80
#define RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE 0x80
#define RISCV_SAMPLE_BUF_TIMESTAMP_AFTER 0x81
typedef struct {
uint8_t *buf;
unsigned used;
unsigned size;
uint32_t last_timestamp;
} riscv_sample_buf_t;
typedef struct {