File: rtl_time.h

package info (click to toggle)
rtlinux 3.1pre3-2
  • links: PTS
  • area: non-free
  • in suites: sarge, woody
  • size: 4,892 kB
  • ctags: 4,228
  • sloc: ansic: 26,204; sh: 2,069; makefile: 1,414; perl: 855; tcl: 489; asm: 380; cpp: 42
file content (139 lines) | stat: -rw-r--r-- 2,688 bytes parent folder | download | duplicates (2)
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