diff options
author | Aaron Durbin <adurbin@chromium.org> | 2015-08-30 21:19:55 -0500 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2015-08-31 13:55:28 +0000 |
commit | c49014e7507b02c5f5ca249e7ab86a65394d12b0 (patch) | |
tree | 537a90aaf5ecdbd57532305bf02545f692f40e55 /util | |
parent | 60391b65fdaca3a365cb16d891f0541c74e866b4 (diff) |
timestamp: add tick frequency to exported table
Add the timestamp tick frequency within the timestamp table so
the cbmem utility doesn't try to figure it out on its own. Those
paths still exist for x86 systems which don't provide tsc_freq_mhz().
All other non-x86 systems use the monotonic timer which has a 1us
granularity or 1MHz.
One of the main reasons is that Linux is reporting
/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq as the true
turbo frequency on turbo enables machines. This change also fixes
the p-state values honored in cpufreq for turbo machines in that
turbo p-pstates were reported as 100MHz greater than nominal.
BUG=chrome-os-partner:44669
BRANCH=firmware-strago-7287.B
TEST=Built and booted on glados. Confirmed table frequency honored.
Change-Id: I763fe2d9a7b01d0ef5556e5abff36032062f5801
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11470
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'util')
-rw-r--r-- | util/cbmem/cbmem.c | 57 |
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]); |