Subversion Repositories shark

Rev

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