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>
67 lines
1.3 KiB
C
67 lines
1.3 KiB
C
#ifndef CPU_X86_TSC_H
|
|
#define CPU_X86_TSC_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#if CONFIG_TSC_SYNC_MFENCE
|
|
#define TSC_SYNC "mfence\n"
|
|
#elif CONFIG_TSC_SYNC_LFENCE
|
|
#define TSC_SYNC "lfence\n"
|
|
#else
|
|
#define TSC_SYNC
|
|
#endif
|
|
|
|
struct tsc_struct {
|
|
unsigned lo;
|
|
unsigned hi;
|
|
};
|
|
typedef struct tsc_struct tsc_t;
|
|
|
|
static inline tsc_t rdtsc(void)
|
|
{
|
|
tsc_t res;
|
|
asm volatile (
|
|
TSC_SYNC
|
|
"rdtsc"
|
|
: "=a" (res.lo), "=d"(res.hi) /* outputs */
|
|
);
|
|
return res;
|
|
}
|
|
|
|
#if !defined(__ROMCC__)
|
|
/* Simple 32- to 64-bit multiplication. Uses 16-bit words to avoid overflow.
|
|
* This code is used to prevent use of libgcc's umoddi3.
|
|
*/
|
|
static inline void multiply_to_tsc(tsc_t *const tsc, const u32 a, const u32 b)
|
|
{
|
|
tsc->lo = (a & 0xffff) * (b & 0xffff);
|
|
tsc->hi = ((tsc->lo >> 16)
|
|
+ ((a & 0xffff) * (b >> 16))
|
|
+ ((b & 0xffff) * (a >> 16)));
|
|
tsc->lo = ((tsc->hi & 0xffff) << 16) | (tsc->lo & 0xffff);
|
|
tsc->hi = ((a >> 16) * (b >> 16)) + (tsc->hi >> 16);
|
|
}
|
|
|
|
/* Too many registers for ROMCC */
|
|
static inline unsigned long long rdtscll(void)
|
|
{
|
|
unsigned long long val;
|
|
asm volatile (
|
|
TSC_SYNC
|
|
"rdtsc"
|
|
: "=A" (val)
|
|
);
|
|
return val;
|
|
}
|
|
|
|
static inline uint64_t tsc_to_uint64(tsc_t tstamp)
|
|
{
|
|
return (((uint64_t)tstamp.hi) << 32) + tstamp.lo;
|
|
}
|
|
#endif
|
|
|
|
/* Provided by CPU/chipset code for the TSC rate in MHz. */
|
|
unsigned long tsc_freq_mhz(void);
|
|
|
|
#endif /* CPU_X86_TSC_H */
|