summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2017-07-15 20:42:20 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2017-07-27 06:55:03 +0000
commit806ea08bb2868f44c5c2227dd2ace49dbe6af6a3 (patch)
treee911f078ee58e5bbcd716a5281a74bae69defb1b
parent01ea8f1fcc6e9e144de97e18afac3fb69676ba1c (diff)
downloadcoreboot-806ea08bb2868f44c5c2227dd2ace49dbe6af6a3.tar.xz
timestamp: Apply factor to recorded stamps
If we dont have a constant TSC rate, timestamp table has odd leaps and may appear to run backwards. Add functionality to apply a factor such that all stamps are in the same timebase. Change-Id: Idab9c2c00e117c4d247db8cc9a2897640fa01edd Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/19330 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/include/timestamp.h5
-rw-r--r--src/lib/timestamp.c28
2 files changed, 33 insertions, 0 deletions
diff --git a/src/include/timestamp.h b/src/include/timestamp.h
index d0735294df..95470f53d6 100644
--- a/src/include/timestamp.h
+++ b/src/include/timestamp.h
@@ -36,10 +36,15 @@ void timestamp_init(uint64_t base);
void timestamp_add(enum timestamp_id id, uint64_t ts_time);
/* Calls timestamp_add with current timestamp. */
void timestamp_add_now(enum timestamp_id id);
+
+/* Apply a factor of N/M to all timestamps recorded so far. */
+void timestamp_rescale_table(uint16_t N, uint16_t M);
+
#else
#define timestamp_init(base)
#define timestamp_add(id, time)
#define timestamp_add_now(id)
+#define timestamp_rescale_table(N, M)
#endif
/* Implemented by the architecture code */
diff --git a/src/lib/timestamp.c b/src/lib/timestamp.c
index 816f28fd85..30f7c13fb8 100644
--- a/src/lib/timestamp.c
+++ b/src/lib/timestamp.c
@@ -299,6 +299,34 @@ static void timestamp_sync_cache_to_cbmem(int is_recovery)
ts_cache->cache_state = TIMESTAMP_CACHE_NOT_NEEDED;
}
+void timestamp_rescale_table(uint16_t N, uint16_t M)
+{
+ uint32_t i;
+ struct timestamp_table *ts_table;
+
+ if (!timestamp_should_run())
+ return;
+
+ if (N == 0 || M == 0)
+ return;
+
+ ts_table = timestamp_table_get();
+
+ /* No timestamp table found */
+ if (ts_table == NULL) {
+ printk(BIOS_ERR, "ERROR: No timestamp table found\n");
+ return;
+ }
+
+ ts_table->base_time /= M;
+ ts_table->base_time *= N;
+ for (i = 0; i < ts_table->num_entries; i++) {
+ struct timestamp_entry *tse = &ts_table->entries[i];
+ tse->entry_stamp /= M;
+ tse->entry_stamp *= N;
+ }
+}
+
ROMSTAGE_CBMEM_INIT_HOOK(timestamp_sync_cache_to_cbmem)
RAMSTAGE_CBMEM_INIT_HOOK(timestamp_sync_cache_to_cbmem)