Subversion Repositories shark

Rev

Rev 353 | Rev 502 | Go to most recent revision | 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
 
353 giacomo 76
    TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0, 0);
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
 
353 giacomo 146
    TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0, 0);
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
 
353 giacomo 227
    TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, 1, (int)currCtx, 0);
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
 
353 giacomo 238
    TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0, 0);
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
}