mirror of
https://github.com/xcat2/xNBA.git
synced 2025-03-28 02:56:20 +00:00
Use plain C in timer_rdtsc for division instead of inline asssembly.
This also fixes a bug in rdtsc_currticks when the result did not fix in %eax Signed-off-by: Alexey Zaytsev <zaytsev.a@protei.ru>
This commit is contained in:
parent
4704abbc50
commit
8de54ef9aa
@ -14,54 +14,32 @@
|
||||
#define rdtscll(val) \
|
||||
__asm__ __volatile__ ("rdtsc" : "=A" (val))
|
||||
|
||||
static unsigned long long calibrate_tsc(void)
|
||||
|
||||
/* Measure how many clocks we get in one microsecond */
|
||||
static inline uint64_t calibrate_tsc(void)
|
||||
{
|
||||
uint32_t startlow, starthigh;
|
||||
uint32_t endlow, endhigh;
|
||||
|
||||
rdtsc(startlow,starthigh);
|
||||
i386_timer2_udelay(USECS_IN_MSEC/2);
|
||||
rdtsc(endlow,endhigh);
|
||||
uint64_t rdtsc_start;
|
||||
uint64_t rdtsc_end;
|
||||
|
||||
/* 64-bit subtract - gcc just messes up with long longs */
|
||||
/* XXX ORLY? Check it. */
|
||||
__asm__("subl %2,%0\n\t"
|
||||
"sbbl %3,%1"
|
||||
:"=a" (endlow), "=d" (endhigh)
|
||||
:"g" (startlow), "g" (starthigh),
|
||||
"0" (endlow), "1" (endhigh));
|
||||
|
||||
/* Error: ECPUTOOFAST */
|
||||
if (endhigh)
|
||||
goto bad_ctc;
|
||||
|
||||
endlow *= MSECS_IN_SEC*2;
|
||||
return endlow;
|
||||
|
||||
/*
|
||||
* The CTC wasn't reliable: we got a hit on the very first read,
|
||||
* or the CPU was so fast/slow that the quotient wouldn't fit in
|
||||
* 32 bits..
|
||||
*/
|
||||
bad_ctc:
|
||||
return 0;
|
||||
rdtscll(rdtsc_start);
|
||||
i386_timer2_udelay(USECS_IN_MSEC);
|
||||
rdtscll(rdtsc_end);
|
||||
|
||||
return (rdtsc_end - rdtsc_start) / USECS_IN_MSEC;
|
||||
}
|
||||
static uint32_t clocks_per_second = 0;
|
||||
|
||||
static uint32_t clocks_per_usec = 0;
|
||||
|
||||
/* We measure time in microseconds. */
|
||||
static tick_t rdtsc_currticks(void)
|
||||
{
|
||||
uint32_t clocks_high, clocks_low;
|
||||
uint32_t currticks;
|
||||
uint64_t clocks;
|
||||
|
||||
/* Read the Time Stamp Counter */
|
||||
rdtsc(clocks_low, clocks_high);
|
||||
rdtscll(clocks);
|
||||
|
||||
/* currticks = clocks / clocks_per_tick; */
|
||||
__asm__("divl %1"
|
||||
:"=a" (currticks)
|
||||
:"r" (clocks_per_second/USECS_IN_SEC), "0" (clocks_low), "d" (clocks_high));
|
||||
|
||||
return currticks;
|
||||
return clocks / clocks_per_usec;
|
||||
}
|
||||
|
||||
static int rdtsc_ts_init(void)
|
||||
@ -71,10 +49,10 @@ static int rdtsc_ts_init(void)
|
||||
|
||||
get_cpuinfo(&cpu_info);
|
||||
if (cpu_info.features & X86_FEATURE_TSC) {
|
||||
clocks_per_second = calibrate_tsc();
|
||||
if (clocks_per_second) {
|
||||
clocks_per_usec= calibrate_tsc();
|
||||
if (clocks_per_usec) {
|
||||
DBG("RDTSC ticksource installed. CPU running at %ld Mhz\n",
|
||||
clocks_per_second/(1000*1000));
|
||||
clocks_per_usec);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user