aboutsummaryrefslogtreecommitdiff
path: root/util/cbmem/cbmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/cbmem/cbmem.c')
-rw-r--r--util/cbmem/cbmem.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c
index 6526384eed..0e2f125080 100644
--- a/util/cbmem/cbmem.c
+++ b/util/cbmem/cbmem.c
@@ -304,7 +304,7 @@ static int parse_cbtable(u64 address, size_t table_size)
* read CPU frequency from a sysfs file, return an frequency in Kilohertz as
* an int or exit on any error.
*/
-static u64 get_cpu_freq_KHz(void)
+static unsigned long arch_tick_frequency(void)
{
FILE *cpuf;
char freqs[100];
@@ -338,44 +338,49 @@ static u64 get_cpu_freq_KHz(void)
freqs, freq_file);
exit(1);
}
-
-/* On x86 platforms timestamps are stored
- * in CPU cycles (from rdtsc). Hence the
- * timestamp divider is the CPU frequency
- * in MHz.
- */
-u64 arch_convert_raw_ts_entry(u64 ts)
-{
- static u64 cpu_freq_mhz = 0;
-
- if (!cpu_freq_mhz)
- cpu_freq_mhz = get_cpu_freq_KHz() / 1000;
-
- return ts / cpu_freq_mhz;
-}
-
#elif defined(__OpenBSD__) && (defined(__i386__) || defined(__x86_64__))
-u64 arch_convert_raw_ts_entry(u64 ts)
+static unsigned long arch_tick_frequency(void)
{
int mib[2] = { CTL_HW, HW_CPUSPEED };
static int value = 0;
size_t value_len = sizeof(value);
+ /* Return 1 MHz when sysctl fails. */
if ((value == 0) && (sysctl(mib, 2, &value, &value_len, NULL, 0) == -1))
- return ts;
+ return 1;
- return ts / value;
+ return value;
}
#else
+static unsigned long arch_tick_frequency(void)
+{
+ /* 1 MHz = 1us. */
+ return 1;
+}
+#endif
+
+static unsigned long tick_freq_mhz;
+
+static void timestamp_set_tick_freq(unsigned long table_tick_freq_mhz)
+{
+ tick_freq_mhz = table_tick_freq_mhz;
+
+ /* Honor table frequency. */
+ if (tick_freq_mhz)
+ return;
+
+ tick_freq_mhz = arch_tick_frequency();
+
+ if (!tick_freq_mhz) {
+ fprintf(stderr, "Cannot determine timestamp tick frequency.\n");
+ exit(1);
+ }
+}
-/* On non-x86 platforms the timestamp entries
- * are not in clock cycles but in usecs
- */
u64 arch_convert_raw_ts_entry(u64 ts)
{
- return ts;
+ return ts / tick_freq_mhz;
}
-#endif
/*
* Print an integer in 'normalized' form - with commas separating every three
@@ -521,6 +526,8 @@ static void dump_timestamps(void)
size = sizeof(*tst_p);
tst_p = map_memory_size((unsigned long)timestamps.cbmem_addr, size);
+ timestamp_set_tick_freq(tst_p->tick_freq_mhz);
+
printf("%d entries total:\n\n", tst_p->num_entries);
size += tst_p->num_entries * sizeof(tst_p->entries[0]);