Subversion Repositories shark

Rev

Rev 42 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
120 giacomo 22
/* Added Advanced Timer Code
23
 *
24
 * Date:   8.4.2003
25
 * Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
26
 *
27
 */
28
 
42 pj 29
/*      Inline functions for managing timespec structures.
30
        All timespec values are pointers!!!
31
        This file defines these functions:
32
                TIMESPEC2NANOSEC(t)
33
                converts a timespec value to a nanosec value, and return
34
                        it, no checks
35
                TIMESPEC2USEC(t)
36
                converts a timespec value to a nanosec value, and return
37
                it, no checks
38
                NULL_TIMESPEC(t)
39
                the timespec value is set to the Epoch (=0)
40
                ADDNANO2TIMESPEC(n, t)
41
                t = t + n
42
                ADDUSEC2TIMESPEC(m, t)
43
                t = t + m
44
                SUBTIMESPEC(s1, s2, d)
45
                d = s1 - s2
46
                ADDTIMESPEC(s1, s2, d)
47
                d = s1 + s2
48
                TIMESPEC_A_LT_B(a,b)
49
                a < b
50
                TIMESPEC_A_GT_B(a,b)
51
                a > b
52
                TIMESPEC_A_EQ_B(a,b)
53
                a == b
54
                TIMESPEC_A_NEQ_B(a,b)
55
                a != b
56
                TIMESPEC_ASSIGN(t1,t2)
57
                t1 = t2 */
58
 
120 giacomo 59
/* Advanced Timer Support
60
 * Giacomo Guidi <giacomo@gandalf.sssup.it>
61
 */
62
 
42 pj 63
#ifndef __LL_SYS_LL_TIME_H__
64
#define __LL_SYS_LL_TIME_H__
65
 
66
#include <ll/i386/defs.h>
67
BEGIN_DEF
68
 
120 giacomo 69
extern signed long long clk_per_msec;
70
extern signed long long init_tsc;
71
 
72
extern unsigned char use_tsc;
73
 
42 pj 74
struct timespec {
120 giacomo 75
        long            tv_sec;         /* Seconds */
76
        long            tv_nsec;        /* Nanoseconds */
77
        long long       tsc;            /* 64 bit TSC */
42 pj 78
};
79
 
120 giacomo 80
extern __inline__ void UNSIGNED_TSC2NSEC(unsigned long long tsc, unsigned long long *n)
81
{
82
 
83
        unsigned long nl,nh;
84
 
85
        nl = *n & 0xFFFFFFFF;
86
        nh = *n >> 32;
87
 
88
        __asm__("mull %%ecx\n\t"
89
                "movl %%eax,%%esi\n\t"
90
                "movl %%edx,%%edi\n\t"
91
                "xorl %%edx,%%edx\n\t"
92
                "movl %6,%%eax\n\t"
93
                "mull %%ecx\n\t"
94
                "addl %%edi,%%eax\n\t"
95
                "adcl $0,%%edx\n\t"
96
                "movl %5,%%ecx\n\t"
97
                "divl %%ecx\n\t"
98
                "xchgl %%eax,%%esi\n\t"
99
                "divl %%ecx\n\t"
100
                : "=a" (nl), "=S" (nh)
101
                : "c" (1000000), "a" ((unsigned long)(tsc & 0xFFFFFFFF)), "d" (0),
102
                  "m" ((unsigned long)(clk_per_msec)), "m" ((unsigned long)(tsc >> 32)),
103
                  "S" (0), "D" (0));
104
 
105
        *n = nh;
106
        *n <<= 32;
107
        *n |= nl;
108
 
109
}
110
 
111
extern __inline__ void ADJUST_TIMESPEC(struct timespec *t)
112
{
113
 
114
        signed long long dt,dn;
115
 
116
        dt = t->tsc - init_tsc;
117
 
118
        if (dt >= 0) UNSIGNED_TSC2NSEC(dt,&dn);
119
                else {
120
                  UNSIGNED_TSC2NSEC(-dt,&dn);
121
                  dn -= dn;
122
                }
123
 
124
        t->tv_sec = dn / 1000000000;
125
        t->tv_nsec = dn % 1000000000;
126
 
127
}
128
 
42 pj 129
/*
130
 * these macros come from the Utah Flux oskit...
131
 */
132
 
133
#define TIMESPEC2NANOSEC(t)     ((t)->tv_sec * 1000000000 + (t)->tv_nsec)
134
#define TIMESPEC2USEC(t)     ((t)->tv_sec * 1000000 + (t)->tv_nsec / 1000)
120 giacomo 135
#define NULL_TIMESPEC(t)        ((t)->tv_sec = (t)->tv_nsec = 0, (t)->tsc = 0)
42 pj 136
 
120 giacomo 137
extern __inline__ void ADDNANO2TIMESPEC(const signed long n, struct timespec *t)  
138
{
139
        t->tv_nsec += n;
140
        t->tv_sec += t->tv_nsec / 1000000000;
141
        t->tv_nsec %= 1000000000;
42 pj 142
 
120 giacomo 143
        if (use_tsc) t->tsc += clk_per_msec * n / 1000000;
144
 
145
}
146
 
147
extern __inline__ void ADDUSEC2TIMESPEC(const signed long m, struct timespec *t)  
148
{      
149
 
150
        t->tv_nsec += m * 1000;
151
        t->tv_sec += t->tv_nsec / 1000000000;
152
        t->tv_nsec %= 1000000000;
42 pj 153
 
120 giacomo 154
        if (use_tsc) t->tsc += clk_per_msec * m / 1000;
155
 
156
}
157
 
158
extern __inline__ void SUBTIMESPEC(const struct timespec *s1,
159
                                   const struct timespec *s2,
160
                                   struct timespec *d)
161
{
162
        if (s1->tv_nsec >= s2->tv_nsec) {      
163
          d->tv_sec = s1->tv_sec - s2->tv_sec;  
164
          d->tv_nsec = s1->tv_nsec - s2->tv_nsec;            
165
        } else {                                
166
          d->tv_sec = s1->tv_sec - s2->tv_sec - 1;
167
          d->tv_nsec = 1000000000 + s1->tv_nsec - s2->tv_nsec;
168
        }
169
 
170
        if (use_tsc) d->tsc = s1->tsc - s2->tsc + init_tsc;
171
 
172
}
173
 
42 pj 174
extern __inline__ void ADDTIMESPEC(const struct timespec *s1,
175
                                   const struct timespec *s2,
176
                                   struct timespec *d)
177
{
120 giacomo 178
 
179
        d->tv_sec  = s1->tv_sec + s2->tv_sec;
180
        d->tv_nsec = s1->tv_nsec + s2->tv_nsec;
42 pj 181
 
120 giacomo 182
        if (d->tv_nsec < 0) {
183
          d->tv_sec--;
184
          d->tv_nsec += 1000000000;
185
        } else if (d->tv_nsec >= 1000000000) {
186
          d->tv_sec++;
187
          d->tv_nsec -= 1000000000;
188
        }
42 pj 189
 
120 giacomo 190
        if (use_tsc) d->tsc = s1->tsc + s2->tsc - init_tsc;
42 pj 191
 
120 giacomo 192
}
42 pj 193
 
194
#define TIMESPEC_A_LT_B(a,b)                                            \
195
        (                                                               \
196
        ((a)->tv_sec <  (b)->tv_sec) ||                                 \
120 giacomo 197
        ((a)->tv_sec == (b)->tv_sec && (a)->tv_nsec < (b)->tv_nsec)     \
42 pj 198
        )
199
 
200
#define TIMESPEC_A_GT_B(a,b)                                            \
201
        (                                                               \
202
        ((a)->tv_sec >  (b)->tv_sec) ||                                 \
120 giacomo 203
        ((a)->tv_sec == (b)->tv_sec && (a)->tv_nsec > (b)->tv_nsec)     \
42 pj 204
        )
205
 
206
#define TIMESPEC_A_EQ_B(a,b)                                            \
207
        ((a)->tv_sec == (b)->tv_sec && (a)->tv_nsec == (b)->tv_nsec)
208
 
120 giacomo 209
#define TIMESPEC_A_NEQ_B(a,b)                                           \
42 pj 210
        ((a)->tv_sec != (b)->tv_sec || (a)->tv_nsec != (b)->tv_nsec)
211
 
212
#define TIMESPEC_ASSIGN(t1,t2) \
120 giacomo 213
        ((t1)->tv_sec = (t2)->tv_sec, (t1)->tv_nsec = (t2)->tv_nsec, (t1)->tsc = (t2)->tsc)
42 pj 214
 
215
#if 0
216
#define PITSPEC2TIMESPEC(a,b) \
217
     ((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197) * 1000, \
218
        (b)->tv_sec = ((a)->gigas * 1197) / 1000) /*, \
219
        (b)->tv_sec += (b)->tv_nsec / 1000000000, \
220
        (b)->tv_nsec %= 1000000000)     */
221
#else
222
/*#define PITSPEC2TIMESPEC(a,b) \
223
     ((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197) * 1000, \
224
        (b)->tv_nsec += (((a)->gigas * 1197) % 1000) * 1000000, \
225
        (b)->tv_sec = ((a)->gigas * 1197) / 1000 , \
226
        (b)->tv_sec += (b)->tv_nsec / 1000000000, \
227
        (b)->tv_nsec %= 1000000000)*/
228
#define PITSPEC2TIMESPEC(a,b) \
229
     ((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197), \
230
        (b)->tv_nsec += (((a)->gigas * 1197) % 1000) * 1000, \
231
        (b)->tv_sec = ((a)->gigas * 1197) / 1000 , \
232
        (b)->tv_sec += (b)->tv_nsec / 1000000, \
233
        (b)->tv_nsec %= 1000000, \
234
        (b)->tv_nsec *= 1000)
235
#endif
236
 
237
TIME ll_gettime(int mode, struct timespec *tsres);
238
 
120 giacomo 239
//Advanced Timer (advtimer.c)
240
void read_timespec(struct timespec *tspec);
241
void ll_init_advtimer(void);
242
void restore_CMOS(void);
243
 
42 pj 244
#define TIME_PTICK      1
245
#define TIME_EXACT      2
246
#define TIME_NEW        3
247
 
248
END_DEF
249
#endif