cbmem: Sort timestamp entries

If the timestamp entries are added out of order, the duration
calculation will be wrong.

AGESA collects timestamp data through all the stages. Then in AmdInitPost
it asks for a buffer to write TP_Perf_STRUCT into. agesawrapper will then
take the data and call timestamp_add on each entry. This results in
the entries being out of order.

TEST=Built firmware for grunt that manually added entries and then ran
cbmem -t/-T to verify the entries were in the correct order.

Change-Id: I6946a844b71d714141b3372e4c43807cfe3528ad
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Reviewed-on: https://review.coreboot.org/26168
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Reviewed-by: Martin Roth <martinroth@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Raul E Rangel 2018-05-11 11:08:07 -06:00 committed by Philipp Deppenwiese
parent 7f268eab78
commit d4fec689fd
1 changed files with 21 additions and 3 deletions

View File

@ -584,11 +584,20 @@ uint64_t timestamp_print_entry(uint32_t id, uint64_t stamp, uint64_t prev_stamp)
return step_time; return step_time;
} }
static int compare_timestamp_entries(const void *a, const void *b)
{
const struct timestamp_entry *tse_a = (struct timestamp_entry *)a;
const struct timestamp_entry *tse_b = (struct timestamp_entry *)b;
return tse_a->entry_stamp - tse_b->entry_stamp;
}
/* dump the timestamp table */ /* dump the timestamp table */
static void dump_timestamps(int mach_readable) static void dump_timestamps(int mach_readable)
{ {
int i; int i;
const struct timestamp_table *tst_p; const struct timestamp_table *tst_p;
struct timestamp_table *sorted_tst_p;
size_t size; size_t size;
uint64_t prev_stamp; uint64_t prev_stamp;
uint64_t total_time; uint64_t total_time;
@ -625,13 +634,21 @@ static void dump_timestamps(int mach_readable)
timestamp_print_entry(0, tst_p->base_time, prev_stamp); timestamp_print_entry(0, tst_p->base_time, prev_stamp);
prev_stamp = tst_p->base_time; prev_stamp = tst_p->base_time;
sorted_tst_p = malloc(size);
if (!sorted_tst_p)
die("Failed to allocate memory");
memcpy(sorted_tst_p, tst_p, size);
qsort(&sorted_tst_p->entries[0], sorted_tst_p->num_entries,
sizeof(struct timestamp_entry), compare_timestamp_entries);
total_time = 0; total_time = 0;
for (i = 0; i < tst_p->num_entries; i++) { for (i = 0; i < sorted_tst_p->num_entries; i++) {
uint64_t stamp; uint64_t stamp;
const struct timestamp_entry *tse = &tst_p->entries[i]; const struct timestamp_entry *tse = &sorted_tst_p->entries[i];
/* Make all timestamps absolute. */ /* Make all timestamps absolute. */
stamp = tse->entry_stamp + tst_p->base_time; stamp = tse->entry_stamp + sorted_tst_p->base_time;
if (mach_readable) if (mach_readable)
total_time += total_time +=
timestamp_print_parseable_entry(tse->entry_id, timestamp_print_parseable_entry(tse->entry_id,
@ -649,6 +666,7 @@ static void dump_timestamps(int mach_readable)
} }
unmap_memory(&timestamp_mapping); unmap_memory(&timestamp_mapping);
free(sorted_tst_p);
} }
struct cbmem_console { struct cbmem_console {