Subversion Repositories shark

Rev

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