Subversion Repositories shark

Rev

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

Rev Author Line No. Line
40 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
 
40 pj 29
/*      Time Event routines     (one shot mode) */
30
 
1621 fabio 31
#include <arch/i386/stdlib.h>
32
#include <arch/i386/limits.h>
40 pj 33
#include <ll/i386/mem.h>
34
#include <ll/i386/pit.h>
299 giacomo 35
#include <ll/i386/apic.h>
131 giacomo 36
#include <ll/i386/advtimer.h>
304 giacomo 37
#include <ll/i386/error.h>
305 giacomo 38
#include <ll/i386/64bit.h>
131 giacomo 39
 
40 pj 40
#include <ll/sys/ll/ll-data.h>
304 giacomo 41
#include <ll/sys/ll/ll-func.h>
40 pj 42
#include <ll/sys/ll/time.h>
43
#include <ll/sys/ll/event.h>
44
 
353 giacomo 45
#include <tracer.h>
46
extern unsigned short int currCtx;
47
 
40 pj 48
FILE(EventOneShot);
49
 
50
extern int activeInt;
51
int activeEvent;
52
 
53
extern BYTE frc;
54
 
55
extern struct event eventlist[MAX_EVENT];
56
extern WORD lastTime;
57
extern struct pitspec globalCounter;
58
 
59
extern struct event *freeevents;
60
extern struct event *firstevent;
61
 
62
extern void (*evt_prol) (void);
63
extern void (*evt_epil) (void);
64
 
305 giacomo 65
extern unsigned int apic_clk_per_msec;
619 mauro 66
extern unsigned char use_tsc, use_apic;
120 giacomo 67
 
40 pj 68
/* Switched to timespec */
619 mauro 69
int oneshot_event_post(struct timespec time, void (*handler) (void *p), void *par)
40 pj 70
{
619 mauro 71
        struct event *p;
72
        struct event *p1, *t;
73
        struct timespec now, tmp;
74
        int done;
75
        DWORD tnext;
40 pj 76
 
619 mauro 77
        TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0);
353 giacomo 78
 
619 mauro 79
        if (!freeevents) {
80
                message("NO FREE EVENTS !\n");
81
                ll_abort(20);
82
                return -1;
83
        }
84
        /* Extract from the ``free events'' queue */
85
        p = freeevents;
86
        freeevents = p->next;
40 pj 87
 
619 mauro 88
        /* Fill the event fields */
89
        p->handler = handler;
90
        TIMESPEC_ASSIGN(&(p->time), &time);
91
        p->par = par;
40 pj 92
 
619 mauro 93
        /* ...And insert it in the event queue!!! */
40 pj 94
 
619 mauro 95
        t = NULL;
96
        done = 0;
97
        /* walk through list, finding spot, adjusting ticks parameter */
98
        for (p1 = firstevent; p1; p1 = t->next) {
99
                if (TIMESPEC_A_GT_B((&time), (&p1->time))) {
100
                t = p1;
101
                } else
102
                break;
103
        }
40 pj 104
 
619 mauro 105
        /* adjust next entry */
106
        if (t) {
107
                t->next = p;
108
        } else {
109
                firstevent = p;
110
                if (!activeEvent) {
111
                        if (!use_tsc) {
112
                                ll_gettime(TIME_NEW, &now);
113
                        } else {
114
                                ll_read_timespec(&now);
115
                        }
116
                        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
117
                                NULL_TIMESPEC(&tmp);
118
                        } else {
119
                                SUBTIMESPEC(&(firstevent->time), &now, &tmp);
120
                        }
121
                        tnext = TIMESPEC2USEC(&tmp);
122
                        if (!use_apic) {
123
                                mul32div32to32(tnext,1193182,1000000,tnext);
124
                                pit_setconstant(0, tnext);
125
                        } else {
126
                                mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
127
                                set_APIC_timer(tnext);
128
                        }
129
                }
40 pj 130
        }
619 mauro 131
        p->next = p1;
40 pj 132
 
619 mauro 133
        return p->index;
40 pj 134
}
135
 
136
void oneshot_wake_up(void)
619 mauro 137
{
138
        /* CHANGE the NAME, please... */
139
        struct event *p = NULL, *pp;
140
        struct timespec now, ttmp;
141
        WORD tmp;
142
        DWORD tnext;
999 trimarchi 143
        DWORD max_tnext;
40 pj 144
 
999 trimarchi 145
 
146
 
147
 
619 mauro 148
        TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0);
353 giacomo 149
 
619 mauro 150
        if (!use_tsc) {
151
                tmp = pit_read(frc);
152
                ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
153
                lastTime = tmp;
40 pj 154
 
619 mauro 155
                PITSPEC2TIMESPEC(&globalCounter, &now);
156
        } else {
157
                ll_read_timespec(&now);
158
        }
40 pj 159
 
619 mauro 160
        if (firstevent != NULL) {
161
                activeEvent = 1;
162
                if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
163
                        if (!activeInt && evt_prol != NULL) {
164
                                evt_prol();
165
                        }
166
                        activeInt++;
120 giacomo 167
 
619 mauro 168
                        for (p = firstevent; p != NULL; p = pp) {
169
                                if ((p->time.tv_sec > now.tv_sec) ||
170
                                   ((p->time.tv_sec == now.tv_sec)
171
                                   && (p->time.tv_nsec > now.tv_nsec))) {
172
                                        break;
173
                                }
174
                                pp = p->next;
175
                                p->next = freeevents;
176
                                freeevents = p;
177
                                firstevent = pp;
178
                                p->handler(p->par);
179
                        }
180
 
181
                        if (activeInt == 1 && evt_epil != NULL) {
182
                                evt_epil();
183
                        }
184
                        activeInt--;
185
                }
120 giacomo 186
 
619 mauro 187
                if (!use_tsc) {
188
                        tmp = pit_read(frc);
189
                        ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
190
                        lastTime = tmp;
191
 
192
                        PITSPEC2TIMESPEC(&globalCounter, &now);
193
                } else {
194
                        ll_read_timespec(&now);
195
                }
120 giacomo 196
 
999 trimarchi 197
                if (firstevent) {
198
                  if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
199
                    NULL_TIMESPEC(&ttmp);
200
                  } else {
201
                    SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
202
                  }
203
                  /*  SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
204
                  tnext = TIMESPEC2USEC(&ttmp);
205
 
206
                  if (!use_apic) {
207
                    mul32div32to32(INT_MAX,1000000,1193182,max_tnext);                 
208
                  } else {
209
                    mul32div32to32(INT_MAX,1000,apic_clk_per_msec,max_tnext);                  
210
                  }
211
                  if (tnext>max_tnext) {
212
                    message("(************TIME IN THE FUTURE************)");
213
                  }
214
 
215
                  if (!use_apic) {
216
                    mul32div32to32(tnext,1193182,1000000,tnext);
217
                    pit_setconstant(0, tnext);
218
                  } else {
619 mauro 219
                        mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
220
                        set_APIC_timer(tnext);
999 trimarchi 221
                  }
222
                } else {
223
                  if (!use_apic)
224
                    pit_setconstant(0, 0xFFFF);
225
                  else
226
                    set_APIC_timer(0xFFFFFFFF);          
619 mauro 227
                }
999 trimarchi 228
                  activeEvent = 0;
40 pj 229
        } else {
619 mauro 230
                if (!use_apic)
231
                        pit_setconstant(0, 0xFFFF);
232
                else
233
                        set_APIC_timer(0xFFFFFFFF);
40 pj 234
        }
304 giacomo 235
 
619 mauro 236
        TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
40 pj 237
}
238
 
239
int oneshot_event_delete(int index)
240
{
619 mauro 241
        struct event *p1, *t;
242
        struct timespec tmp, now;
243
        DWORD tnext;
244
        int firstdeleted = FALSE;
40 pj 245
 
619 mauro 246
        TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
353 giacomo 247
 
619 mauro 248
        if (index == -1)
249
                return -1;
250
        t = NULL;
251
        /* walk through list, finding spot, adjusting ticks parameter */
252
 
253
        for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
254
                t = p1;
40 pj 255
        }
619 mauro 256
 
257
        if (p1 == NULL) {
258
                return -1;
259
        }
260
        if (t == NULL) {
261
                firstevent = p1->next;
262
                firstdeleted = TRUE;
263
        } else {
264
                t->next = p1->next;
265
        }
266
 
267
        p1->next = freeevents;
268
        freeevents = p1;
269
 
270
        if (!activeEvent) {
271
                if (firstevent == NULL) {
272
                        if (!use_apic)
273
                                pit_setconstant(0, 0xFFFF);
274
                        else
275
                                set_APIC_timer(0xFFFFFFFF);
276
                } else {
277
                        if (firstdeleted) {
278
                                if (!use_tsc)
279
                                        ll_gettime(TIME_NEW, &now);
280
                                else
281
                                        ll_read_timespec(&now);
282
                                if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
283
                                        NULL_TIMESPEC(&tmp);
284
                                } else {
285
                                        SUBTIMESPEC(&(firstevent->time), &now, &tmp);
286
                                }
287
                                /*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
288
                                tnext = TIMESPEC2USEC(&tmp);
289
                                if (!use_apic) {
290
                                        mul32div32to32(tnext,1193182,1000000,tnext);
291
                                        pit_setconstant(0, tnext);
292
                                } else {
293
                                        mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
294
                                        set_APIC_timer(tnext);
295
                                }
296
                        }
297
                }
298
        }
299
        return 1;
40 pj 300
}