Subversion Repositories shark

Rev

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

Rev Author Line No. Line
120 giacomo 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
 
22
/*      Advanced Timer
23
 *      Date: 8.4.2003
24
 *      Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
25
 *
26
 */
27
 
28
#ifndef __ADVTIMER_H__
29
#define __ADVTIMER_H__
30
 
31
#include <ll/i386/defs.h>
32
BEGIN_DEF
33
 
305 giacomo 34
#include <ll/sys/ll/time.h>
35
 
120 giacomo 36
/* TSC */
37
 
38
#define rdtsc(low,high) \
648 mauro 39
        __asm__ __volatile__("xorl %%eax,%%eax\n\t" \
40
                             "cpuid\n\t"            \
41
                             "rdtsc\n\t"            \
42
                             : "=a" (low), "=d" (high) \
43
                             :: "ebx", "ecx")
120 giacomo 44
 
45
#define rdtscll(val) \
648 mauro 46
        __asm__ __volatile__("xorl %%eax,%%eax\n\t" \
47
                             "cpuid\n\t"            \
48
                             "rdtsc\n\t"            \
49
                             : "=A" (val)           \
50
                             :: "ebx","ecx")
120 giacomo 51
 
330 giacomo 52
#ifdef __O1000__
648 mauro 53
        #define ll_read_timespec ll_read_timespec_1000
330 giacomo 54
#else 
648 mauro 55
        #ifdef __02000__
56
                #define ll_read_timespec ll_read_timespec_2000
57
        #else
58
                #ifdef __O4000__
59
                        #define ll_read_timespec ll_read_timespec_4000
60
                #else
61
                        #define ll_read_timespec ll_read_timespec_8000
62
                #endif
63
        #endif
330 giacomo 64
#endif
65
 
66
//Low level time read function: Optimized for CPU < 1 GHz
67
extern __inline__ void ll_read_timespec_1000(struct timespec *tspec)
68
{
652 mauro 69
        extern unsigned int clk_opt_1,clk_opt_2;
70
        extern unsigned long long *ptr_init_tsc;
653 mauro 71
        extern struct timespec init_time;
330 giacomo 72
 
652 mauro 73
        if (clk_opt_1 == 0) {
74
                NULL_TIMESPEC(tspec);
75
                return;
76
        }
330 giacomo 77
 
652 mauro 78
        __asm__("rdtsc\n\t"
79
                "subl (%%edi),%%eax\n\t"
80
                "sbbl 4(%%edi),%%edx\n\t"
81
                "divl %%ebx\n\t"
82
                "movl %%eax,%%ebx\n\t"
83
                "xorl %%eax,%%eax\n\t"
84
                "divl %%ecx\n\t"
85
                : "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
86
                : "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_2)
87
                : "edx" );
88
 
89
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
90
                __asm__("divl %%ecx\n\t"
91
                        "addl %%ebx,%%eax\n\t"
92
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
93
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
94
        };
95
 
330 giacomo 96
}
97
 
98
//Low level time read function: Optimized for CPU < 2 GHz
99
extern __inline__ void ll_read_timespec_2000(struct timespec *tspec)
100
{
652 mauro 101
        extern unsigned int clk_opt_1,clk_opt_3;
102
        extern unsigned long long *ptr_init_tsc;
653 mauro 103
        extern struct timespec init_time;
330 giacomo 104
 
652 mauro 105
        if (clk_opt_1 == 0) {
106
                NULL_TIMESPEC(tspec);
107
                return;
108
        }
330 giacomo 109
 
652 mauro 110
        __asm__("rdtsc\n\t"
111
                "subl (%%edi),%%eax\n\t"
112
                "sbbl 4(%%edi),%%edx\n\t"
113
                "divl %%ebx\n\t"
114
                "movl %%eax,%%ebx\n\t"
115
                "xorl %%eax,%%eax\n\t"
116
                "shrdl $1,%%edx,%%eax\n\t"
117
                "shrl %%edx\n\t"
118
                "divl %%ecx\n\t"
119
                : "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
120
                : "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_3)
121
                : "edx" );
122
 
123
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
124
                __asm__("divl %%ecx\n\t"
125
                        "addl %%ebx,%%eax\n\t"
126
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
127
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
128
        };
129
 
330 giacomo 130
}
131
 
132
//Low level time read function: Optimized for CPU < 4 GHz
133
extern __inline__ void ll_read_timespec_4000(struct timespec *tspec)
134
{
652 mauro 135
        extern unsigned int clk_opt_1,clk_opt_4;
136
        extern unsigned long long *ptr_init_tsc;
653 mauro 137
        extern struct timespec init_time;
330 giacomo 138
 
652 mauro 139
        if (clk_opt_1 == 0) {
140
                NULL_TIMESPEC(tspec);
141
                return;
142
        }
330 giacomo 143
 
652 mauro 144
        __asm__("rdtsc\n\t"
145
                "subl (%%edi),%%eax\n\t"
146
                "sbbl 4(%%edi),%%edx\n\t"
147
                "divl %%ebx\n\t"
148
                "movl %%eax,%%ebx\n\t"
149
                "xorl %%eax,%%eax\n\t"
150
                "shrdl $2,%%edx,%%eax\n\t"
151
                "shrl $2,%%edx\n\t"
152
                "divl %%ecx\n\t"
153
                : "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
154
                : "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_4)
155
                : "edx" );
156
 
157
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
158
                __asm__("divl %%ecx\n\t"
159
                        "addl %%ebx,%%eax\n\t"
160
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
161
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
162
        };
163
 
330 giacomo 164
}
165
 
305 giacomo 166
//Low level time read function
336 giacomo 167
extern __inline__ void ll_read_timespec_8000(struct timespec *tspec)
305 giacomo 168
{
648 mauro 169
        extern unsigned int clk_opt_0,clk_opt_5;
170
        extern unsigned long long *ptr_init_tsc;
171
        extern struct timespec init_time;
172
 
173
        if (clk_opt_0 == 0) {
174
                NULL_TIMESPEC(tspec);
175
                return;
176
        }
305 giacomo 177
 
648 mauro 178
        __asm__("rdtsc\n\t"
179
                "subl (%%edi),%%eax\n\t"
180
                "sbbl 4(%%edi),%%edx\n\t"
181
                "shrdl $1,%%edx,%%eax\n\t"
182
                "shrl %%edx\n\t"
183
                "divl %%ebx\n\t"
184
                "movl %%eax,%%ebx\n\t"
185
                "xorl %%eax,%%eax\n\t"
186
                "shrdl $2,%%edx,%%eax\n\t"
187
                "shrl $2,%%edx\n\t"
188
                "divl %%ecx\n\t"
189
                : "=b" (tspec->tv_sec), "=a" (tspec->tv_nsec)
190
                : "D" (ptr_init_tsc), "b" (clk_opt_0), "c" (clk_opt_5)
191
                : "edx");
192
 
193
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
194
                __asm__("divl %%ecx\n\t"
195
                        "addl %%ebx,%%eax\n\t"
196
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
652 mauro 197
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
648 mauro 198
        };
199
 
305 giacomo 200
}
201
 
299 giacomo 202
#define rdmsr(msr,val1,val2) \
648 mauro 203
        __asm__ __volatile__("rdmsr" \
204
                             : "=a" (val1), "=d" (val2) \
205
                             : "c" (msr))
299 giacomo 206
 
207
#define wrmsr(msr,val1,val2) \
648 mauro 208
        __asm__ __volatile__("wrmsr" \
209
                             : /* no outputs */ \
210
                             : "c" (msr), "a" (val1), "d" (val2))
299 giacomo 211
 
120 giacomo 212
/* RTC */
213
 
214
#define RTC_PORT(x)     (0x70 + (x))
215
 
216
#define CMOS_READ(addr,val)     \
217
{                               \
218
outp(RTC_PORT(0),(addr));       \
219
val = inp(RTC_PORT(1));         \
220
}
221
 
222
#define CMOS_WRITE(addr,val)    \
223
{                               \
224
outp(RTC_PORT(0),(addr));       \
225
outp(RTC_PORT(1),(val));        \
226
}
227
 
228
#define RTC_IRQ 8
229
 
131 giacomo 230
void ll_init_advtimer(void);
301 giacomo 231
void ll_restore_adv(void);
646 mauro 232
void ll_scale_advtimer(unsigned int old_f, unsigned int new_f);
131 giacomo 233
 
120 giacomo 234
END_DEF
235
#endif