Subversion Repositories shark

Rev

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