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); |
} |