Subversion Repositories shark

Rev

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

Rev Author Line No. Line
2 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
 
22
/*      Time management code: ll_getttime()     */
23
 
120 giacomo 24
/* Added Advanced Timer Code
25
 *
26
 * Date:   8.4.2003
27
 * Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
28
 *
29
 */
30
 
2 pj 31
#include <ll/i386/pit.h>
32
#include <ll/i386/stdlib.h>
33
#include <ll/i386/error.h>
34
#include <ll/i386/mem.h>
35
#include <ll/sys/ll/ll-data.h>
36
#include <ll/sys/ll/ll-func.h>
37
#include <ll/sys/ll/time.h>
38
 
39
/* These are for the EXECT and TICK modes */
40 pj 40
extern DWORD ticksize;          /* From init.c  */
41
extern struct timespec actTime; /* From event.c */
42
extern WORD  pit_time_const;    /* From init.c  */
43
extern DWORD  timermode;        /* From init.c  */
2 pj 44
 
45
/* These two are for the NEW algorithm */
40 pj 46
extern WORD lastTime;                /* From event.c */
47
extern struct pitspec globalCounter; /* From event.c */
2 pj 48
extern BYTE frc;
49
extern int activeEvent;
50
 
120 giacomo 51
extern unsigned char use_tsc;
52
 
2 pj 53
FILE(Time);
54
 
55
TIME ll_gettime(int mode, struct timespec *tsres)
56
{
40 pj 57
        DWORD res, tc;
58
        BYTE isr;
59
        struct timespec tmp;
2 pj 60
 
120 giacomo 61
   if (!use_tsc) {
62
 
40 pj 63
#if 1
64
        if (activeEvent) {
65
          if (tsres != NULL) {
66
            PITSPEC2TIMESPEC(&globalCounter, tsres);
67
          } else {
68
            struct timespec tmp;
2 pj 69
 
40 pj 70
            PITSPEC2TIMESPEC(&globalCounter, &tmp);
71
            return TIMESPEC2USEC(&tmp);
72
          }
73
          return TIMESPEC2USEC(tsres);
2 pj 74
        }
40 pj 75
#endif
76
 
77
        if (mode == TIME_PTICK) {
78
                if (timermode != LL_PERIODIC) {
79
                        return 0;
80
                }
81
                res = TIMESPEC2USEC(&actTime);
82
                if (tsres != NULL) {
83
                        memcpy(tsres, &actTime, sizeof(struct timespec));
84
                }
85
                return res;
2 pj 86
        }
87
 
40 pj 88
        if (mode == TIME_NEW) {
89
          WORD tmp;
90
 
91
          tmp = pit_read(frc);
92
          ADDPITSPEC((WORD)(lastTime - tmp), &globalCounter);
93
          lastTime = tmp;
94
          if (tsres != NULL) {
2 pj 95
            PITSPEC2TIMESPEC(&globalCounter, tsres);
40 pj 96
          }
97
          return (PITSPEC2USEC(&globalCounter));
2 pj 98
        }
99
 
40 pj 100
        if (mode == TIME_EXACT) {
101
                if (timermode == LL_PERIODIC) {
102
                        memcpy(&tmp, &actTime, sizeof(struct timespec));
103
                        /* How much time has elapsed
104
                         * from the last Tick Boundary?
105
                         */
106
                        tc = pit_read(0);
107
                        if (tc > pit_time_const) {
108
                            error("LL Time Panic!!!\n");
109
                            ll_abort(1);
110
                        }
111
                        res = pit_time_const - tc;
112
                        res *= ticksize;
113
                        res /= pit_time_const;
2 pj 114
 
40 pj 115
                        /* Detect tick boundary and adjust the time... */
116
                        outp(0x20, 0x0A);
117
                        isr = inp(0x20);
118
                        if ((isr & 1) && res < ((8*ticksize)/10)){
119
                              /*
120
                                res += ticksize;
121
                                ADDNANO2TIMESPEC(ticksize * 1000, &tmp);
122
                              */
123
                              res = ticksize;
124
                        }
2 pj 125
 
40 pj 126
                        /* Sum the Tick time... */
127
                        ADDNANO2TIMESPEC(res * 1000, &tmp);
128
                        res += TIMESPEC2USEC(&actTime);
2 pj 129
 
40 pj 130
                        if (tsres != NULL) {
131
                                memcpy(tsres, &tmp, sizeof(struct timespec));
132
                        }
133
                        return res;
134
                } else {
135
                        return 0;
136
                }
2 pj 137
        }
40 pj 138
        return 0;
120 giacomo 139
 
140
    } else {
141
 
142
#if 1
143
        if (activeEvent) {
144
          if (tsres != NULL) {
145
            read_timespec(tsres);
146
          } else {
147
            struct timespec tmp;
148
 
149
            read_timespec(&tmp);
150
            return TIMESPEC2USEC(&tmp);
151
          }
152
          return TIMESPEC2USEC(tsres);
153
        }
154
#endif
155
 
156
        if (mode == TIME_PTICK) {
157
                if (timermode != LL_PERIODIC) {
158
                        return 0;
159
                }
160
 
161
                if(tsres != NULL) {
162
                        read_timespec(tsres);
163
                } else {
164
                        struct timespec tmp;
165
 
166
                        read_timespec(&tmp);
167
                        return TIMESPEC2USEC(&tmp);
168
                }
169
                return TIMESPEC2USEC(tsres);
170
        }
171
 
172
        if (mode == TIME_NEW) {
173
          if (tsres != NULL) {
174
            read_timespec(tsres);
175
            return TIMESPEC2USEC(tsres);
176
          } else {
177
            struct timespec tmp;
178
 
179
            read_timespec(&tmp);
180
            return TIMESPEC2USEC(&tmp);
181
          }
182
        }
183
 
184
        if (mode == TIME_EXACT) {
185
                if (timermode == LL_PERIODIC) {
186
                        if (tsres != NULL) {
187
                                read_timespec(tsres);
188
                        } else {
189
                                struct timespec tmp;
190
 
191
                                read_timespec(&tmp);
192
                                return TIMESPEC2USEC(&tmp);
193
                        }
194
                        return TIMESPEC2USEC(tsres);
195
                } else {
196
                        return 0;
197
                }
198
        }
199
 
200
        return 0;
201
 
202
    }
203
 
2 pj 204
}