Subversion Repositories shark

Rev

Rev 648 | 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;
330 giacomo 71
 
652 mauro 72
        if (clk_opt_1 == 0) {
73
                NULL_TIMESPEC(tspec);
74
                return;
75
        }
330 giacomo 76
 
652 mauro 77
        __asm__("rdtsc\n\t"
78
                "subl (%%edi),%%eax\n\t"
79
                "sbbl 4(%%edi),%%edx\n\t"
80
                "divl %%ebx\n\t"
81
                "movl %%eax,%%ebx\n\t"
82
                "xorl %%eax,%%eax\n\t"
83
                "divl %%ecx\n\t"
84
                : "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
85
                : "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_2)
86
                : "edx" );
87
 
88
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
89
                __asm__("divl %%ecx\n\t"
90
                        "addl %%ebx,%%eax\n\t"
91
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
92
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
93
        };
94
 
330 giacomo 95
}
96
 
97
//Low level time read function: Optimized for CPU < 2 GHz
98
extern __inline__ void ll_read_timespec_2000(struct timespec *tspec)
99
{
652 mauro 100
        extern unsigned int clk_opt_1,clk_opt_3;
101
        extern unsigned long long *ptr_init_tsc;
330 giacomo 102
 
652 mauro 103
        if (clk_opt_1 == 0) {
104
                NULL_TIMESPEC(tspec);
105
                return;
106
        }
330 giacomo 107
 
652 mauro 108
        __asm__("rdtsc\n\t"
109
                "subl (%%edi),%%eax\n\t"
110
                "sbbl 4(%%edi),%%edx\n\t"
111
                "divl %%ebx\n\t"
112
                "movl %%eax,%%ebx\n\t"
113
                "xorl %%eax,%%eax\n\t"
114
                "shrdl $1,%%edx,%%eax\n\t"
115
                "shrl %%edx\n\t"
116
                "divl %%ecx\n\t"
117
                : "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
118
                : "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_3)
119
                : "edx" );
120
 
121
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
122
                __asm__("divl %%ecx\n\t"
123
                        "addl %%ebx,%%eax\n\t"
124
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
125
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
126
        };
127
 
330 giacomo 128
}
129
 
130
//Low level time read function: Optimized for CPU < 4 GHz
131
extern __inline__ void ll_read_timespec_4000(struct timespec *tspec)
132
{
652 mauro 133
        extern unsigned int clk_opt_1,clk_opt_4;
134
        extern unsigned long long *ptr_init_tsc;
330 giacomo 135
 
652 mauro 136
        if (clk_opt_1 == 0) {
137
                NULL_TIMESPEC(tspec);
138
                return;
139
        }
330 giacomo 140
 
652 mauro 141
        __asm__("rdtsc\n\t"
142
                "subl (%%edi),%%eax\n\t"
143
                "sbbl 4(%%edi),%%edx\n\t"
144
                "divl %%ebx\n\t"
145
                "movl %%eax,%%ebx\n\t"
146
                "xorl %%eax,%%eax\n\t"
147
                "shrdl $2,%%edx,%%eax\n\t"
148
                "shrl $2,%%edx\n\t"
149
                "divl %%ecx\n\t"
150
                : "=a" (tspec->tv_nsec), "=b" (tspec->tv_sec)
151
                : "D" (ptr_init_tsc) , "b" (clk_opt_1), "c" (clk_opt_4)
152
                : "edx" );
153
 
154
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
155
                __asm__("divl %%ecx\n\t"
156
                        "addl %%ebx,%%eax\n\t"
157
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
158
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
159
        };
160
 
330 giacomo 161
}
162
 
305 giacomo 163
//Low level time read function
336 giacomo 164
extern __inline__ void ll_read_timespec_8000(struct timespec *tspec)
305 giacomo 165
{
648 mauro 166
        extern unsigned int clk_opt_0,clk_opt_5;
167
        extern unsigned long long *ptr_init_tsc;
168
        extern struct timespec init_time;
169
 
170
        if (clk_opt_0 == 0) {
171
                NULL_TIMESPEC(tspec);
172
                return;
173
        }
305 giacomo 174
 
648 mauro 175
        __asm__("rdtsc\n\t"
176
                "subl (%%edi),%%eax\n\t"
177
                "sbbl 4(%%edi),%%edx\n\t"
178
                "shrdl $1,%%edx,%%eax\n\t"
179
                "shrl %%edx\n\t"
180
                "divl %%ebx\n\t"
181
                "movl %%eax,%%ebx\n\t"
182
                "xorl %%eax,%%eax\n\t"
183
                "shrdl $2,%%edx,%%eax\n\t"
184
                "shrl $2,%%edx\n\t"
185
                "divl %%ecx\n\t"
186
                : "=b" (tspec->tv_sec), "=a" (tspec->tv_nsec)
187
                : "D" (ptr_init_tsc), "b" (clk_opt_0), "c" (clk_opt_5)
188
                : "edx");
189
 
190
        if (init_time.tv_sec != 0 || init_time.tv_nsec != 0) {
191
                __asm__("divl %%ecx\n\t"
192
                        "addl %%ebx,%%eax\n\t"
193
                        :"=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
652 mauro 194
                        :"a" (init_time.tv_nsec+tspec->tv_nsec), "b" (tspec->tv_sec+init_time.tv_sec), "c" (1000000000), "d" (0));
648 mauro 195
        };
196
 
305 giacomo 197
}
198
 
299 giacomo 199
#define rdmsr(msr,val1,val2) \
648 mauro 200
        __asm__ __volatile__("rdmsr" \
201
                             : "=a" (val1), "=d" (val2) \
202
                             : "c" (msr))
299 giacomo 203
 
204
#define wrmsr(msr,val1,val2) \
648 mauro 205
        __asm__ __volatile__("wrmsr" \
206
                             : /* no outputs */ \
207
                             : "c" (msr), "a" (val1), "d" (val2))
299 giacomo 208
 
120 giacomo 209
/* RTC */
210
 
211
#define RTC_PORT(x)     (0x70 + (x))
212
 
213
#define CMOS_READ(addr,val)     \
214
{                               \
215
outp(RTC_PORT(0),(addr));       \
216
val = inp(RTC_PORT(1));         \
217
}
218
 
219
#define CMOS_WRITE(addr,val)    \
220
{                               \
221
outp(RTC_PORT(0),(addr));       \
222
outp(RTC_PORT(1),(val));        \
223
}
224
 
225
#define RTC_IRQ 8
226
 
131 giacomo 227
void ll_init_advtimer(void);
301 giacomo 228
void ll_restore_adv(void);
646 mauro 229
void ll_scale_advtimer(unsigned int old_f, unsigned int new_f);
131 giacomo 230
 
120 giacomo 231
END_DEF
232
#endif