1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#ifndef __RTL_ARCH_TIME_H__
#define __RTL_ARCH_TIME_H__
/*
* rtl_time.h
*
* x86 hardware clock interface
*
* Copyright (C) 1999 Michael Barabanov
* Released under the terms of the GPL
*
*/
/* begin of what each arch should declare */
typedef long long hrtime_t; /* high-resolution time type (signed 64-bit) */
extern inline hrtime_t timespec_to_ns (const struct timespec *ts)
{
long long t;
__asm__("imull %%edx\n"
"add %%ebx, %%eax\n\t"
"adc $0, %%edx\n\t"
:"=A" (t)
: "a" (ts->tv_sec), "d" (NSECS_PER_SEC), "b" (ts->tv_nsec)
);
return t;
}
extern inline struct timespec timespec_from_ns (hrtime_t t)
{
struct timespec ts;
__asm__("idivl %%ecx\n\t"
:"=a" (ts.tv_sec), "=d" (ts.tv_nsec)
: "A" (t), "c" (NSECS_PER_SEC)
);
if (ts.tv_nsec < 0) {
ts.tv_nsec += NSECS_PER_SEC;
ts.tv_sec --;
}
return ts;
}
#ifdef __KERNEL__
#include <linux/time.h>
#include <rtl_core.h>
#include <asm/ptrace.h>
extern inline hrtime_t hrt_to_8254 (hrtime_t t)
{
__asm__("mov %%eax, %%ecx\n\t"
"mov %%edx, %%eax\n\t"
"xorl %%edx, %%edx\n\t"
"idivl %%ebx\n\t"
"xchg %%eax, %%ecx\n\t"
"divl %%ebx\n\t"
"mov %%ecx, %%edx\n\t"
:"=A" (t) :"0" (t), "b" (838)
:"cx");
return t;
}
extern inline hrtime_t _8254_to_hrt (hrtime_t t)
{
__asm__(
"mov %%eax, %%ecx\n\t"
"mov %%edx, %%eax\n\t"
"mul %%ebx\n\t"
"xchg %%eax, %%ecx\n\t"
"mul %%ebx\n\t"
"add %%ecx, %%edx\n\t"
:"=A" (t) : "b" (838), "0" (t): "cx");
return t;
}
#define HRT_FROM_8254(x) (_8254_to_hrt(x))
#define HRT_TO_8254(x) (hrt_to_8254(x))
extern hrtime_t gethrtime(void); /* time in nanoseconds since bootup */
extern hrtime_t gethrtimeres(void); /* resolution of gethrtime() in ns */
struct rtl_clock_arch {
int istimerset;
int count_irqs;
int apic_cpu;
hrtime_t linux_time;
};
#define RTL_CLOCK_ARCH_INITIALIZER { 0, 0, 0, 0 }
/* end of public arch declarations */
extern struct rtl_clock _i8254_clock __attribute__ ((aligned (64)));
#define CLOCK_8254 (&_i8254_clock)
#ifdef CONFIG_X86_LOCAL_APIC
extern struct rtl_clock _apic_clock[NR_CPUS] __attribute__ ((aligned (64)));
#define CLOCK_APIC (&_apic_clock[rtl_getcpuid()])
#endif
/* TODO
extern clockid_t CLOCK_RTC;
*/
#include <linux/delay.h>
extern __inline__ unsigned long muldiv(unsigned long a, unsigned long mul, unsigned long div)
{
int temp;
__asm__("mull %2 ; divl %3"
:"=a" (a), "=d" (temp)
:"1" (mul),
"c" (div),
"0" (a)
);
return a;
}
static inline void rtl_delay(long delay)
{
hrtime_t t = gethrtime() + delay;
while (gethrtime() < t);
}
extern int I8253_channel2_free(void);
#endif
#endif
|