Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 618 → Rev 619

/shark/trunk/oslib/kl/event.c
77,268 → 77,255
extern void (*evt_epil) (void);
 
extern unsigned int apic_clk_per_msec;
extern unsigned char use_apic, use_tsc;
 
void event_setlasthandler(void *p)
{
last_handler = p;
last_handler = p;
}
 
void event_setprologue(void *p)
{
evt_prol = p;
evt_prol = p;
}
 
void event_setepilogue(void *p)
{
evt_epil = p;
evt_epil = p;
}
 
/* Switched to timespec */
int periodic_event_post(struct timespec time, void (*handler) (void *p),
void *par)
int periodic_event_post(struct timespec time, void (*handler) (void *p), void *par)
{
struct event *p;
struct event *p1, *t;
struct event *p;
struct event *p1, *t;
 
TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0);
TRACER_LOGEVENT(FTrace_EVT_timer_post, 0, 0);
 
if (!freeevents) {
message("NO FREE EVENTS !\n");
ll_abort(20);
return -1;
}
if (!freeevents) {
message("NO FREE EVENTS !\n");
ll_abort(20);
return -1;
}
 
/* Extract from the ``free events'' queue */
p = freeevents;
freeevents = p->next;
/* Extract from the ``free events'' queue */
p = freeevents;
freeevents = p->next;
 
/* Fill the event fields */
p->handler = handler;
TIMESPEC_ASSIGN(&(p->time), &time);
p->par = par;
/* Fill the event fields */
p->handler = handler;
TIMESPEC_ASSIGN(&(p->time), &time);
p->par = par;
 
/* ...And insert it in the event queue!!! */
/* ...And insert it in the event queue!!! */
 
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; p1; p1 = t->next) {
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; p1; p1 = t->next) {
/*
SUBTIMESPEC(&time, &(p1->time), &tmp);
if ((tmp.tv_sec > 0) && (tmp.tv_nsec > 0)) {
*/
if (TIMESPEC_A_GT_B(&time, &p1->time))
t = p1;
else
break;
}
if (TIMESPEC_A_GT_B(&time, &p1->time))
t = p1;
else
break;
}
 
/* adjust next entry */
if (t) {
t->next = p;
} else {
firstevent = p;
}
p->next = p1;
/* adjust next entry */
if (t) {
t->next = p;
} else {
firstevent = p;
}
p->next = p1;
 
return p->index;
return p->index;
}
 
int periodic_event_delete(int index)
{
struct event *p1, *t;
struct event *p1, *t;
 
TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
 
if (index == -1)
return -1;
if (index == -1)
return -1;
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
t = p1;
}
t = NULL;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
t = p1;
}
 
if (p1 == NULL) {
return -1;
}
if (p1 == NULL) {
return -1;
}
 
if (t == NULL) {
firstevent = p1->next;
} else {
t->next = p1->next;
}
p1->next = freeevents;
freeevents = p1;
if (t == NULL) {
firstevent = p1->next;
} else {
t->next = p1->next;
}
p1->next = freeevents;
freeevents = p1;
 
return 1;
return 1;
}
 
void periodic_wake_up(void)
{ /* CHANGE the NAME, please... */
struct event *p, *pp;
#ifndef __TSC__
WORD tmp;
#endif
{
/* CHANGE the NAME, please... */
struct event *p, *pp;
WORD tmp;
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0);
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_start, 0, 0);
 
#ifndef __TSC__
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
#endif
activeInt++;
if (activeInt == 1 && evt_prol != NULL) {
evt_prol();
}
if (use_tsc) {
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
}
 
#ifndef __TSC__
ADDNANO2TIMESPEC(nts, &actTime);
#else
ll_read_timespec(&actTime);
#endif
activeInt++;
if (activeInt == 1 && evt_prol != NULL) {
evt_prol();
}
 
if (use_tsc)
ll_read_timespec(&actTime);
else
ADDNANO2TIMESPEC(nts, &actTime);
for (p = firstevent; p != NULL; p = pp) {
/*
for (p = firstevent; p != NULL; p = pp) {
/*
SUBTIMESPEC(&(p->time), &actTime, &tmp);
if ((tmp.tv_sec > 0) && (tmp.tv_nsec > 0)) {
break;
} */
if ((p->time.tv_sec > actTime.tv_sec) ||
((p->time.tv_sec == actTime.tv_sec)
&& (p->time.tv_nsec > actTime.tv_nsec))) {
break;
if ((p->time.tv_sec > actTime.tv_sec) ||
((p->time.tv_sec == actTime.tv_sec)
&& (p->time.tv_nsec > actTime.tv_nsec))) {
break;
}
pp = p->next;
p->next = freeevents;
freeevents = p;
firstevent = pp;
p->handler(p->par);
}
pp = p->next;
p->next = freeevents;
freeevents = p;
firstevent = pp;
p->handler(p->par);
}
 
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
}
 
void event_init(struct ll_initparms *l)
{
extern void ll_timer(void);
extern void ll_apic_timer(void);
int i;
BYTE mask;
TIME t;
#ifdef __APIC__
DWORD apic_clk;
#endif
extern void ll_timer(void);
extern void ll_apic_timer(void);
int i;
BYTE mask;
TIME t;
DWORD apic_clk;
 
#ifdef __TSC__
ll_init_advtimer();
#endif
if (use_tsc)
ll_init_advtimer();
 
#ifndef __APIC__
IDT_place(0x40,ll_timer);
#else
IDT_place(0x39,ll_apic_timer);
#endif
if (use_apic)
IDT_place(0x39,ll_apic_timer);
else
IDT_place(0x40,ll_timer);
 
if (l->mode != LL_PERIODIC) {
message("One-shot mode\n");
t = 0;
#ifndef __APIC__
/* Mode: Binary/Mode 4/16 bit Time_const/Counter 0 */
pit_init(0, TMR_MD4, 0xFFFF); /* Timer 0, Mode 4, constant 0xFFFF */
#else
set_APIC_timer(0xFFFFFFFF);
enable_APIC_timer();
#endif
} else {
t = l->tick;
if (l->mode != LL_PERIODIC) {
message("One-shot mode\n");
t = 0;
if (use_apic) {
set_APIC_timer(0xFFFFFFFF);
enable_APIC_timer();
} else {
/* Mode: Binary/Mode 4/16 bit Time_const/Counter 0 */
pit_init(0, TMR_MD4, 0xFFFF); /* Timer 0, Mode 4, constant 0xFFFF */
}
} else {
t = l->tick;
/* Translate the tick value in usec into a suitable time constant */
/* for 8254 timer chip; the chip is driven with a 1.19718 MHz */
/* frequency; then the effective frequency is given by the base */
/* frequency divided for the time constant; the tick is the inverse */
/* of this effective frequency (in usec!) */
/* Time-Constant = f_base (MHz) * tick (usec) */
/* If T-C == 0 -> T-C = 65536 (Max available) */
ticksize = t;
/* Translate the tick value in usec into a suitable time constant */
/* for 8254 timer chip; the chip is driven with a 1.19718 MHz */
/* frequency; then the effective frequency is given by the base */
/* frequency divided for the time constant; the tick is the inverse */
/* of this effective frequency (in usec!) */
/* Time-Constant = f_base (MHz) * tick (usec) */
/* If T-C == 0 -> T-C = 65536 (Max available) */
ticksize = t;
 
#ifndef __APIC__
if (use_apic) {
mul32div32to32(t,apic_clk_per_msec,1000,apic_clk);
set_APIC_timer(apic_clk);
enable_APIC_timer();
} else {
mul32div32to32(t,1193182,1000000,t);
 
mul32div32to32(t,1193182,1000000,t);
 
/* Only for security! This should cause timer overrun */
/* While 0 would set maximum period on timer */
if (t == 0)
t = 1;
pit_time_const = (WORD) (t & 0xFFFF);
/* Mode: Binary/Mode 2/16 bit Time_const/Counter 0 */
pit_init(0, TMR_MD2, t); /* Timer 0, Mode 2, Time constant t */
#else
 
mul32div32to32(t,apic_clk_per_msec,1000,apic_clk);
set_APIC_timer(apic_clk);
enable_APIC_timer();
 
#endif
}
timermode = l->mode;
/* Only for security! This should cause timer overrun */
/* While 0 would set maximum period on timer */
if (t == 0)
t = 1;
pit_time_const = (WORD) (t & 0xFFFF);
/* Mode: Binary/Mode 2/16 bit Time_const/Counter 0 */
pit_init(0, TMR_MD2, t); /* Timer 0, Mode 2, Time constant t */
}
}
timermode = l->mode;
#ifndef __APIC__
if (ll_arch.x86.cpu > 4) {
/* Timer1: mode 0, time const 0... */
pit_init(1, TMR_MD0, 0);
frc = 1;
} else {
frc = 2;
pit_init(2, TMR_MD0, 0);
outp(0x61, 3);
}
#endif
if (!use_apic) {
if (ll_arch.x86.cpu > 4) {
/* Timer1: mode 0, time const 0... */
pit_init(1, TMR_MD0, 0);
frc = 1;
} else {
frc = 2;
pit_init(2, TMR_MD0, 0);
outp(0x61, 3);
}
}
 
mask = ll_in(0x21);
mask &= 0xFE; /* 0xFE = ~0x01 */
ll_out(0x21, mask);
mask = ll_in(0x21);
mask &= 0xFE; /* 0xFE = ~0x01 */
ll_out(0x21, mask);
 
/* Init the event list... */
for (i = 0; i < MAX_EVENT; i++) {
if (i < MAX_EVENT - 1) {
eventlist[i].next = &(eventlist[i + 1]);
/* Init the event list... */
for (i = 0; i < MAX_EVENT; i++) {
if (i < MAX_EVENT - 1) {
eventlist[i].next = &(eventlist[i + 1]);
}
eventlist[i].index = i;
}
eventlist[i].index = i;
}
eventlist[MAX_EVENT - 1].next = NULL;
freeevents = &(eventlist[0]);
eventlist[MAX_EVENT - 1].next = NULL;
freeevents = &(eventlist[0]);
 
evt_prol = NULL;
evt_epil = NULL;
evt_prol = NULL;
evt_epil = NULL;
 
/* Initialization of the time variables for periodic mode */
nts = ticksize * 1000;
NULL_TIMESPEC(&actTime);
/* Initialization of the time variables for periodic mode */
nts = ticksize * 1000;
NULL_TIMESPEC(&actTime);
/* Initialization of the general time variables */
NULLPITSPEC(&globalCounter);
lastTime = 0;
/* Initialization of the general time variables */
NULLPITSPEC(&globalCounter);
lastTime = 0;
 
if (timermode == LL_PERIODIC) {
event_post = periodic_event_post;
event_delete = periodic_event_delete;
} else {
event_post = oneshot_event_post;
event_delete = oneshot_event_delete;
}
if (timermode == LL_PERIODIC) {
event_post = periodic_event_post;
event_delete = periodic_event_delete;
} else {
event_post = oneshot_event_post;
event_delete = oneshot_event_delete;
}
 
/* Last but not least... */
#ifndef __APIC__
irq_unmask(0);
#endif
 
/* Last but not least... */
if (!use_apic)
irq_unmask(0);
}