Subversion Repositories shark

Rev

Rev 496 | 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;
120 giacomo 65
 
40 pj 66
/* Switched to timespec */
67
int oneshot_event_post(struct timespec time, void (*handler) (void *p),
68
                       void *par)
69
{
70
    struct event *p;
71
    struct event *p1, *t;
72
    struct timespec now, tmp;
73
    int done;
74
    DWORD tnext;
75
 
502 giacomo 76
    TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0);
353 giacomo 77
 
40 pj 78
    if (!freeevents) {
304 giacomo 79
        message("NO FREE EVENTS !\n");
80
        ll_abort(20);
40 pj 81
        return -1;
82
    }
83
    /* Extract from the ``free events'' queue */
84
    p = freeevents;
85
    freeevents = p->next;
86
 
87
    /* Fill the event fields */
88
    p->handler = handler;
89
    TIMESPEC_ASSIGN(&(p->time), &time);
90
    p->par = par;
91
 
92
    /* ...And insert it in the event queue!!! */
93
 
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
    }
103
 
104
    /* adjust next entry */
105
    if (t) {
106
        t->next = p;
107
    } else {
108
        firstevent = p;
109
        if (!activeEvent) {
305 giacomo 110
          #ifndef __TSC__
111
             ll_gettime(TIME_NEW, &now);
112
          #else
113
             ll_read_timespec(&now);
114
          #endif
40 pj 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);
305 giacomo 121
          #ifndef __APIC__
329 giacomo 122
            mul32div32to32(tnext,1193182,1000000,tnext);
305 giacomo 123
            pit_setconstant(0, tnext);
124
          #else
125
            mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
303 giacomo 126
            set_APIC_timer(tnext);
305 giacomo 127
          #endif
40 pj 128
        }
129
    }
130
    p->next = p1;
131
 
132
    return p->index;
133
}
134
 
135
 
136
 
137
void oneshot_wake_up(void)
138
{                               /* CHANGE the NAME, please... */
139
    struct event *p = NULL, *pp;
140
    struct timespec now, ttmp;
305 giacomo 141
    #ifndef __TSC__    
142
      WORD tmp;
143
    #endif
40 pj 144
    DWORD tnext;
145
 
502 giacomo 146
    TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0);
353 giacomo 147
 
305 giacomo 148
    #ifndef __TSC__
120 giacomo 149
 
150
        tmp = pit_read(frc);
151
        ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
152
        lastTime = tmp;
40 pj 153
 
120 giacomo 154
        PITSPEC2TIMESPEC(&globalCounter, &now);
40 pj 155
 
305 giacomo 156
    #else
120 giacomo 157
 
131 giacomo 158
        ll_read_timespec(&now);
120 giacomo 159
 
305 giacomo 160
    #endif
120 giacomo 161
 
40 pj 162
    if (firstevent != NULL) {
163
        activeEvent = 1;
164
        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
165
            if (!activeInt && evt_prol != NULL) {
166
                evt_prol();
167
            }
168
            activeInt++;
169
 
170
            for (p = firstevent; p != NULL; p = pp) {
171
                if ((p->time.tv_sec > now.tv_sec) ||
172
                    ((p->time.tv_sec == now.tv_sec)
173
                     && (p->time.tv_nsec > now.tv_nsec))) {
174
                    break;
175
                }
176
                pp = p->next;
177
                p->next = freeevents;
178
                freeevents = p;
179
                firstevent = pp;
180
                p->handler(p->par);
181
            }
182
 
183
            if (activeInt == 1 && evt_epil != NULL) {
184
                evt_epil();
185
            }
186
            activeInt--;
187
        }
188
 
305 giacomo 189
        #ifndef __TSC__
120 giacomo 190
 
191
            tmp = pit_read(frc);
192
            ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
193
            lastTime = tmp;
40 pj 194
 
120 giacomo 195
            PITSPEC2TIMESPEC(&globalCounter, &now);
40 pj 196
 
305 giacomo 197
        #else
120 giacomo 198
 
131 giacomo 199
            ll_read_timespec(&now);
120 giacomo 200
 
305 giacomo 201
        #endif
120 giacomo 202
 
203
 
40 pj 204
        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
205
            NULL_TIMESPEC(&ttmp);
206
        } else {
207
            SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
208
        }
209
        /*  SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
210
        tnext = TIMESPEC2USEC(&ttmp);
305 giacomo 211
        #ifndef __APIC__
329 giacomo 212
          mul32div32to32(tnext,1193182,1000000,tnext);
299 giacomo 213
          pit_setconstant(0, tnext);
305 giacomo 214
        #else
215
          mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
303 giacomo 216
          set_APIC_timer(tnext);
305 giacomo 217
        #endif
40 pj 218
        activeEvent = 0;
219
    } else {
305 giacomo 220
        #ifndef __APIC__
299 giacomo 221
          pit_setconstant(0, 0xFFFF);
305 giacomo 222
        #else
303 giacomo 223
          set_APIC_timer(0xFFFFFFFF);
305 giacomo 224
        #endif
40 pj 225
    }
304 giacomo 226
 
502 giacomo 227
    TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
353 giacomo 228
 
40 pj 229
}
230
 
231
int oneshot_event_delete(int index)
232
{
233
    struct event *p1, *t;
234
    struct timespec tmp, now;
235
    DWORD tnext;
236
    int firstdeleted = FALSE;
237
 
502 giacomo 238
    TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
353 giacomo 239
 
496 giacomo 240
    if (index == -1)
241
        return -1;
40 pj 242
    t = NULL;
243
    /* walk through list, finding spot, adjusting ticks parameter */
244
 
245
    for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
246
        t = p1;
247
    }
248
 
249
    if (p1 == NULL) {
250
        return -1;
251
    }
252
    if (t == NULL) {
253
        firstevent = p1->next;
254
        firstdeleted = TRUE;
255
    } else {
256
        t->next = p1->next;
257
    }
258
 
259
    p1->next = freeevents;
260
    freeevents = p1;
261
 
262
    if (!activeEvent) {
263
      if (firstevent == NULL) {
305 giacomo 264
        #ifndef __APIC__
299 giacomo 265
          pit_setconstant(0, 0xFFFF);
305 giacomo 266
        #else
303 giacomo 267
          set_APIC_timer(0xFFFFFFFF);
305 giacomo 268
        #endif
40 pj 269
      } else {
270
        if (firstdeleted) {
305 giacomo 271
          #ifndef __TSC__
272
             ll_gettime(TIME_NEW, &now);
273
          #else
274
             ll_read_timespec(&now);
275
          #endif
40 pj 276
          if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
277
            NULL_TIMESPEC(&tmp);
278
          } else {
279
            SUBTIMESPEC(&(firstevent->time), &now, &tmp);
280
          }
281
          /*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
282
          tnext = TIMESPEC2USEC(&tmp);
305 giacomo 283
          #ifndef __APIC__
329 giacomo 284
            mul32div32to32(tnext,1193182,1000000,tnext);
299 giacomo 285
            pit_setconstant(0, tnext);
305 giacomo 286
          #else
287
            mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
303 giacomo 288
            set_APIC_timer(tnext);
305 giacomo 289
          #endif
40 pj 290
        }
291
      }
292
    }
293
    return 1;
294
}