Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 618 → Rev 619

/shark/trunk/oslib/kl/time.c
48,6 → 48,7
extern struct pitspec globalCounter; /* From event.c */
extern BYTE frc;
extern int activeEvent;
extern BYTE use_tsc;
 
FILE(Time);
 
54,105 → 55,97
TIME ll_gettime(int mode, struct timespec *tsres)
{
#ifndef __TSC__
if (!use_tsc) {
 
DWORD res, tc;
BYTE isr;
struct timespec tmp;
DWORD res, tc;
BYTE isr;
struct timespec tmp;
 
#if 1
if (activeEvent) {
if (tsres != NULL) {
PITSPEC2TIMESPEC(&globalCounter, tsres);
} else {
struct timespec tmp;
if (activeEvent) {
if (tsres != NULL) {
PITSPEC2TIMESPEC(&globalCounter, tsres);
} else {
struct timespec tmp;
 
PITSPEC2TIMESPEC(&globalCounter, &tmp);
return TIMESPEC2USEC(&tmp);
}
return TIMESPEC2USEC(tsres);
}
PITSPEC2TIMESPEC(&globalCounter, &tmp);
return TIMESPEC2USEC(&tmp);
}
return TIMESPEC2USEC(tsres);
}
#endif
if (mode == TIME_PTICK) {
if (timermode != LL_PERIODIC) {
return 0;
if (mode == TIME_PTICK) {
if (timermode != LL_PERIODIC) {
return 0;
}
res = TIMESPEC2USEC(&actTime);
if (tsres != NULL) {
memcpy(tsres, &actTime, sizeof(struct timespec));
}
return res;
}
res = TIMESPEC2USEC(&actTime);
if (tsres != NULL) {
memcpy(tsres, &actTime, sizeof(struct timespec));
}
return res;
}
 
if (mode == TIME_NEW) {
WORD tmp;
if (mode == TIME_NEW) {
WORD tmp;
tmp = pit_read(frc);
ADDPITSPEC((WORD)(lastTime - tmp), &globalCounter);
lastTime = tmp;
if (tsres != NULL) {
PITSPEC2TIMESPEC(&globalCounter, tsres);
}
return (PITSPEC2USEC(&globalCounter));
}
 
if (mode == TIME_EXACT) {
if (timermode == LL_PERIODIC) {
memcpy(&tmp, &actTime, sizeof(struct timespec));
/* How much time has elapsed
* from the last Tick Boundary?
*/
tc = pit_read(0);
if (tc > pit_time_const) {
error("LL Time Panic!!!\n");
ll_abort(1);
tmp = pit_read(frc);
ADDPITSPEC((WORD)(lastTime - tmp), &globalCounter);
lastTime = tmp;
if (tsres != NULL) {
PITSPEC2TIMESPEC(&globalCounter, tsres);
}
res = pit_time_const - tc;
res *= ticksize;
res /= pit_time_const;
return (PITSPEC2USEC(&globalCounter));
}
 
/* Detect tick boundary and adjust the time... */
outp(0x20, 0x0A);
isr = inp(0x20);
if ((isr & 1) && res < ((8*ticksize)/10)){
/*
res += ticksize;
ADDNANO2TIMESPEC(ticksize * 1000, &tmp);
*/
res = ticksize;
}
if (mode == TIME_EXACT) {
if (timermode == LL_PERIODIC) {
memcpy(&tmp, &actTime, sizeof(struct timespec));
/* How much time has elapsed
* from the last Tick Boundary?
*/
tc = pit_read(0);
if (tc > pit_time_const) {
error("LL Time Panic!!!\n");
ll_abort(1);
}
res = pit_time_const - tc;
res *= ticksize;
res /= pit_time_const;
 
/* Sum the Tick time... */
ADDNANO2TIMESPEC(res * 1000, &tmp);
res += TIMESPEC2USEC(&actTime);
/* Detect tick boundary and adjust the time... */
outp(0x20, 0x0A);
isr = inp(0x20);
if ((isr & 1) && res < ((8*ticksize)/10)){
/*
res += ticksize;
ADDNANO2TIMESPEC(ticksize * 1000, &tmp);
*/
res = ticksize;
}
 
if (tsres != NULL) {
memcpy(tsres, &tmp, sizeof(struct timespec));
/* Sum the Tick time... */
ADDNANO2TIMESPEC(res * 1000, &tmp);
res += TIMESPEC2USEC(&actTime);
 
if (tsres != NULL) {
memcpy(tsres, &tmp, sizeof(struct timespec));
}
return res;
} else {
return 0;
}
return res;
}
return 0;
} else {
if (tsres != NULL) {
ll_read_timespec(tsres);
return TIMESPEC2USEC(tsres);
} else {
return 0;
struct timespec tmp;
ll_read_timespec(&tmp);
return TIMESPEC2USEC(&tmp);
}
}
return 0;
 
#else
 
if (tsres != NULL) {
ll_read_timespec(tsres);
return TIMESPEC2USEC(tsres);
 
} else {
 
struct timespec tmp;
ll_read_timespec(&tmp);
return TIMESPEC2USEC(&tmp);
}
 
#endif
}
/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);
}
/shark/trunk/oslib/kl/event1.c
62,233 → 62,217
extern void (*evt_epil) (void);
 
extern unsigned int apic_clk_per_msec;
extern unsigned char use_tsc, use_apic;
 
/* Switched to timespec */
int oneshot_event_post(struct timespec time, void (*handler) (void *p),
void *par)
int oneshot_event_post(struct timespec time, void (*handler) (void *p), void *par)
{
struct event *p;
struct event *p1, *t;
struct timespec now, tmp;
int done;
DWORD tnext;
struct event *p;
struct event *p1, *t;
struct timespec now, tmp;
int done;
DWORD tnext;
 
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;
}
/* Extract from the ``free events'' queue */
p = freeevents;
freeevents = p->next;
if (!freeevents) {
message("NO FREE EVENTS !\n");
ll_abort(20);
return -1;
}
/* 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;
done = 0;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; p1; p1 = t->next) {
if (TIMESPEC_A_GT_B((&time), (&p1->time))) {
t = p1;
} else
break;
}
t = NULL;
done = 0;
/* walk through list, finding spot, adjusting ticks parameter */
for (p1 = firstevent; p1; p1 = t->next) {
if (TIMESPEC_A_GT_B((&time), (&p1->time))) {
t = p1;
} else
break;
}
 
/* adjust next entry */
if (t) {
t->next = p;
} else {
firstevent = p;
if (!activeEvent) {
#ifndef __TSC__
ll_gettime(TIME_NEW, &now);
#else
ll_read_timespec(&now);
#endif
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&tmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &tmp);
}
tnext = TIMESPEC2USEC(&tmp);
#ifndef __APIC__
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
#else
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
#endif
/* adjust next entry */
if (t) {
t->next = p;
} else {
firstevent = p;
if (!activeEvent) {
if (!use_tsc) {
ll_gettime(TIME_NEW, &now);
} else {
ll_read_timespec(&now);
}
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&tmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &tmp);
}
tnext = TIMESPEC2USEC(&tmp);
if (!use_apic) {
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
} else {
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
}
}
}
}
p->next = p1;
p->next = p1;
 
return p->index;
return p->index;
}
 
 
 
void oneshot_wake_up(void)
{ /* CHANGE the NAME, please... */
struct event *p = NULL, *pp;
struct timespec now, ttmp;
#ifndef __TSC__
WORD tmp;
#endif
DWORD tnext;
{
/* CHANGE the NAME, please... */
struct event *p = NULL, *pp;
struct timespec now, ttmp;
WORD tmp;
DWORD tnext;
 
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;
if (!use_tsc) {
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
 
PITSPEC2TIMESPEC(&globalCounter, &now);
PITSPEC2TIMESPEC(&globalCounter, &now);
} else {
ll_read_timespec(&now);
}
 
#else
if (firstevent != NULL) {
activeEvent = 1;
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
if (!activeInt && evt_prol != NULL) {
evt_prol();
}
activeInt++;
 
ll_read_timespec(&now);
for (p = firstevent; p != NULL; p = pp) {
if ((p->time.tv_sec > now.tv_sec) ||
((p->time.tv_sec == now.tv_sec)
&& (p->time.tv_nsec > now.tv_nsec))) {
break;
}
pp = p->next;
p->next = freeevents;
freeevents = p;
firstevent = pp;
p->handler(p->par);
}
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
}
 
#endif
if (!use_tsc) {
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
PITSPEC2TIMESPEC(&globalCounter, &now);
} else {
ll_read_timespec(&now);
}
 
if (firstevent != NULL) {
activeEvent = 1;
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
if (!activeInt && evt_prol != NULL) {
evt_prol();
}
activeInt++;
 
for (p = firstevent; p != NULL; p = pp) {
if ((p->time.tv_sec > now.tv_sec) ||
((p->time.tv_sec == now.tv_sec)
&& (p->time.tv_nsec > now.tv_nsec))) {
break;
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&ttmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
}
pp = p->next;
p->next = freeevents;
freeevents = p;
firstevent = pp;
p->handler(p->par);
}
 
if (activeInt == 1 && evt_epil != NULL) {
evt_epil();
}
activeInt--;
}
 
#ifndef __TSC__
tmp = pit_read(frc);
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
lastTime = tmp;
 
PITSPEC2TIMESPEC(&globalCounter, &now);
 
#else
 
ll_read_timespec(&now);
 
#endif
 
 
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&ttmp);
/* SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
tnext = TIMESPEC2USEC(&ttmp);
if (!use_apic) {
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
} else {
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
}
activeEvent = 0;
} else {
SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
if (!use_apic)
pit_setconstant(0, 0xFFFF);
else
set_APIC_timer(0xFFFFFFFF);
}
/* SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
tnext = TIMESPEC2USEC(&ttmp);
#ifndef __APIC__
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
#else
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
#endif
activeEvent = 0;
} else {
#ifndef __APIC__
pit_setconstant(0, 0xFFFF);
#else
set_APIC_timer(0xFFFFFFFF);
#endif
}
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
 
TRACER_LOGEVENT(FTrace_EVT_timer_wakeup_end, (unsigned short int)currCtx, 0);
}
 
int oneshot_event_delete(int index)
{
struct event *p1, *t;
struct timespec tmp, now;
DWORD tnext;
int firstdeleted = FALSE;
struct event *p1, *t;
struct timespec tmp, now;
DWORD tnext;
int firstdeleted = FALSE;
 
TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
TRACER_LOGEVENT(FTrace_EVT_timer_delete, 0, 0);
 
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;
}
 
if (p1 == NULL) {
return -1;
}
if (t == NULL) {
firstevent = p1->next;
firstdeleted = TRUE;
} else {
t->next = p1->next;
}
 
p1->next = freeevents;
freeevents = p1;
 
if (!activeEvent) {
if (firstevent == NULL) {
#ifndef __APIC__
pit_setconstant(0, 0xFFFF);
#else
set_APIC_timer(0xFFFFFFFF);
#endif
} else {
if (firstdeleted) {
#ifndef __TSC__
ll_gettime(TIME_NEW, &now);
#else
ll_read_timespec(&now);
#endif
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&tmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &tmp);
}
/*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
tnext = TIMESPEC2USEC(&tmp);
#ifndef __APIC__
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
#else
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
#endif
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;
}
}
}
return 1;
if (p1 == NULL) {
return -1;
}
if (t == NULL) {
firstevent = p1->next;
firstdeleted = TRUE;
} else {
t->next = p1->next;
}
p1->next = freeevents;
freeevents = p1;
if (!activeEvent) {
if (firstevent == NULL) {
if (!use_apic)
pit_setconstant(0, 0xFFFF);
else
set_APIC_timer(0xFFFFFFFF);
} else {
if (firstdeleted) {
if (!use_tsc)
ll_gettime(TIME_NEW, &now);
else
ll_read_timespec(&now);
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
NULL_TIMESPEC(&tmp);
} else {
SUBTIMESPEC(&(firstevent->time), &now, &tmp);
}
/*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
tnext = TIMESPEC2USEC(&tmp);
if (!use_apic) {
mul32div32to32(tnext,1193182,1000000,tnext);
pit_setconstant(0, tnext);
} else {
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext);
set_APIC_timer(tnext);
}
}
}
}
return 1;
}
/shark/trunk/oslib/kl/advtimer.c
58,6 → 58,11
unsigned char save_CMOS_regA;
unsigned char save_CMOS_regB;
 
unsigned char X86_tsc = 0;
unsigned char X86_apic = 0;
unsigned char use_tsc = 0;
unsigned char use_apic = 0;
 
#ifdef CONFIG_MELAN
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
#else
84,36 → 89,34
outp(0x42,0xFF); /* LSB of count */
outp(0x42,0xFF); /* MSB of count */
barrier();
rdtscll(start);
barrier();
outp(0x43,0x00);
barrier();
rdtscll(start);
barrier();
outp(0x43,0x00);
start_8253 = inp(0x42);
start_8253 |= inp(0x42) << 8;
barrier();
rdtscll(start);
barrier();
barrier();
rdtscll(start);
barrier();
do {
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
 
} while (end_8253 > COUNTER_END);
 
barrier();
rdtscll(end);
barrier();
barrier();
rdtscll(end);
barrier();
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
barrier();
rdtscll(end);
barrier();
barrier();
rdtscll(end);
barrier();
 
//Delta TSC
dtsc = end - start;
dtsc = end - start;
 
//Delta PIT
delta_8253 = start_8253 - end_8253;
130,7 → 133,6
clk_per_msec = dtsc * CLOCK_TICK_RATE / delta_8253 / 1000;
message("Calibrated Clk_per_msec = %10d\n",clk_per_msec);
 
}
 
#define CMOS_INIT 0
144,98 → 146,94
 
void calibrate_tsc_IRQ8(void *p)
{
unsigned char set;
 
unsigned char set;
CMOS_READ(0x0C,set);
 
CMOS_READ(0x0C,set);
barrier();
rdtscll(irq8_end);
barrier();
 
barrier();
rdtscll(irq8_end);
barrier();
if (cmos_calibrate_status == CMOS_START) {
cmos_calibrate_status = CMOS_END;
}
 
if (cmos_calibrate_status == CMOS_START) {
cmos_calibrate_status = CMOS_END;
}
if (cmos_calibrate_status == CMOS_BEGIN) {
irq8_start = irq8_end;
cmos_calibrate_status = CMOS_START;
}
 
if (cmos_calibrate_status == CMOS_BEGIN) {
irq8_start = irq8_end;
cmos_calibrate_status = CMOS_START;
}
 
if (cmos_calibrate_status == CMOS_INIT) {
cmos_calibrate_status = CMOS_BEGIN;
}
if (cmos_calibrate_status == CMOS_INIT) {
cmos_calibrate_status = CMOS_BEGIN;
}
}
 
//TSC Calibration using RTC
void ll_calibrate_tsc_cmos(void)
{
unsigned long long dtsc;
 
unsigned long long dtsc;
irq_bind(8, calibrate_tsc_IRQ8, INT_FORCE);
 
irq_bind(8, calibrate_tsc_IRQ8, INT_FORCE);
CMOS_READ(0x0A,save_CMOS_regA);
CMOS_READ(0x0B,save_CMOS_regB);
CMOS_WRITE(0x0A,0x2F); // Set 2 Hz Periodic Interrupt
CMOS_WRITE(0x0B,0x42); // Enable Interrupt
 
CMOS_READ(0x0A,save_CMOS_regA);
CMOS_READ(0x0B,save_CMOS_regB);
CMOS_WRITE(0x0A,0x2F); // Set 2 Hz Periodic Interrupt
CMOS_WRITE(0x0B,0x42); // Enable Interrupt
 
irq_unmask(8);
irq_unmask(8);
sti();
sti();
 
while (cmos_calibrate_status != CMOS_END) {
barrier();
}
while (cmos_calibrate_status != CMOS_END) {
barrier();
}
cli();
cli();
 
dtsc = irq8_end - irq8_start;
dtsc = irq8_end - irq8_start;
 
clk_per_msec = dtsc / 500;
clk_opt_0 = (unsigned int)(dtsc);
clk_opt_1 = (unsigned int)((unsigned long long)(dtsc << 1));
clk_opt_2 = (unsigned int)((unsigned long long)(dtsc << 33) / 1000000000L);
clk_opt_3 = (unsigned int)((unsigned long long)(dtsc << 32) / 1000000000L);
clk_opt_4 = (unsigned int)((unsigned long long)(dtsc << 31) / 1000000000L);
clk_opt_5 = (unsigned int)((unsigned long long)(dtsc << 30) / 1000000000L);
clk_per_msec = dtsc / 500;
clk_opt_0 = (unsigned int)(dtsc);
clk_opt_1 = (unsigned int)((unsigned long long)(dtsc << 1));
clk_opt_2 = (unsigned int)((unsigned long long)(dtsc << 33) / 1000000000L);
clk_opt_3 = (unsigned int)((unsigned long long)(dtsc << 32) / 1000000000L);
clk_opt_4 = (unsigned int)((unsigned long long)(dtsc << 31) / 1000000000L);
clk_opt_5 = (unsigned int)((unsigned long long)(dtsc << 30) / 1000000000L);
 
message("Calibrated CPU Clk/msec = %10u\n",clk_per_msec);
message("Calibrated CPU Clk/msec = %10u\n",clk_per_msec);
 
#ifdef __O1000__
if (clk_per_msec < 1000000) {
message("Timer Optimization CPU < 1 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
#ifdef __O1000__
if (clk_per_msec < 1000000) {
message("Timer Optimization CPU < 1 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
 
#ifdef __O2000__
if (clk_per_msec < 2000000 && clk_per_msec >= 1000000) {
message("Timer Optimization 1 GHz < CPU < 2 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
#ifdef __O2000__
if (clk_per_msec < 2000000 && clk_per_msec >= 1000000) {
message("Timer Optimization 1 GHz < CPU < 2 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
 
#ifdef __O4000__
if (clk_per_msec < 4000000 && clk_per_msec >= 2000000) {
message("Timer Optimization 2 GHz < CPU < 4 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
#ifdef __O4000__
if (clk_per_msec < 4000000 && clk_per_msec >= 2000000) {
message("Timer Optimization 2 GHz < CPU < 4 GHz\n");
} else {
message("Bad Timer Optimization\n");
ll_abort(66);
}
#endif
 
irq_mask(8);
irq_mask(8);
 
CMOS_WRITE(0x0A,save_CMOS_regA);
CMOS_WRITE(0x0B,save_CMOS_regB);
 
CMOS_WRITE(0x0A,save_CMOS_regA);
CMOS_WRITE(0x0B,save_CMOS_regB);
}
 
int apic_get_maxlvt(void)
323,41 → 321,38
unsigned long value;
 
/* Pound the ESR really hard over the head with a big hammer - mbligh */
 
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
 
value = APIC_SPIV_FOCUS_DISABLED | APIC_SPIV_APIC_ENABLED | SPURIOUS_APIC_VECTOR;
apic_write_around(APIC_SPIV, value);
 
value = APIC_DM_EXTINT | APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT0, value);
value = APIC_DM_EXTINT | APIC_LVT_LEVEL_TRIGGER;
apic_write_around(APIC_LVT0, value);
 
value = APIC_DM_NMI;
apic_write_around(APIC_LVT1, value);
value = APIC_DM_NMI;
apic_write_around(APIC_LVT1, value);
 
apic_write(APIC_ESR, 0);
 
apic_write(APIC_ESR, 0);
}
 
void disable_APIC_timer(void)
{
unsigned long v;
unsigned long v;
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
}
void enable_APIC_timer(void)
{
unsigned long v;
unsigned long v;
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
v = apic_read(APIC_LVTT);
apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
}
 
#define LOCAL_TIMER_VECTOR 0x39
365,20 → 360,20
/* Set APIC Timer... from Linux kernel */
void setup_APIC_timer()
{
unsigned int lvtt1_value;
lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
apic_write_around(APIC_LVTT, lvtt1_value);
/*
* Divide PICLK by 1
*/
apic_write_around(APIC_TDCR, APIC_TDR_DIV_1);
unsigned int lvtt1_value;
 
apic_write_around(APIC_TMICT, MAX_DWORD);
lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
apic_write_around(APIC_LVTT, lvtt1_value);
 
disable_APIC_timer();
/*
* Divide PICLK by 1
*/
apic_write_around(APIC_TDCR, APIC_TDR_DIV_1);
 
apic_write_around(APIC_TMICT, MAX_DWORD);
 
disable_APIC_timer();
}
 
#define APIC_LIMIT 0xFF000000
386,89 → 381,89
 
void ll_calibrate_apic(void)
{
unsigned int apic_start = 0, apic_end = 0, dapic;
unsigned long long tsc_start = 0, tsc_end = 0, dtsc;
unsigned int tmp_value;
 
unsigned int apic_start = 0, apic_end = 0, dapic;
unsigned long long tsc_start = 0, tsc_end = 0, dtsc;
unsigned int tmp_value;
tmp_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | LOCAL_TIMER_VECTOR;
apic_write_around(APIC_LVTT, tmp_value);
 
tmp_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | LOCAL_TIMER_VECTOR;
apic_write_around(APIC_LVTT, tmp_value);
apic_write_around(APIC_TDCR, APIC_TDR_DIV_1);
 
apic_write_around(APIC_TDCR, APIC_TDR_DIV_1);
apic_write(APIC_TMICT, MAX_DWORD);
 
apic_write(APIC_TMICT, MAX_DWORD);
enable_APIC_timer();
 
enable_APIC_timer();
barrier();
rdtscll(tsc_start);
barrier();
apic_start = apic_read(APIC_TMCCT);
barrier();
 
barrier();
rdtscll(tsc_start);
barrier();
apic_start = apic_read(APIC_TMCCT);
barrier();
while (apic_read(APIC_TMCCT) > APIC_LIMIT) {
barrier();
rdtscll(tsc_end);
}
while (apic_read(APIC_TMCCT) > APIC_LIMIT) {
barrier();
rdtscll(tsc_end);
}
 
barrier();
rdtscll(tsc_end);
barrier();
apic_end = apic_read(APIC_TMCCT);
barrier();
barrier();
rdtscll(tsc_end);
barrier();
apic_end = apic_read(APIC_TMCCT);
barrier();
 
disable_APIC_timer();
disable_APIC_timer();
 
dtsc = tsc_end - tsc_start;
dapic = apic_start - apic_end;
dtsc = tsc_end - tsc_start;
dapic = apic_start - apic_end;
apic_clk_per_msec = (unsigned long long)(clk_per_msec) * (unsigned long long)(dapic) / dtsc;
apic_set_limit = ((apic_clk_per_msec / 100) != 0) ? (apic_clk_per_msec/100) : APIC_SET_LIMIT;
 
apic_clk_per_msec = (unsigned long long)(clk_per_msec) * (unsigned long long)(dapic) / dtsc;
apic_set_limit = ((apic_clk_per_msec / 100) != 0) ? (apic_clk_per_msec/100) : APIC_SET_LIMIT;
message("Calibrated APIC Clk/msec = %10d\n",apic_clk_per_msec);
message("Calibrated APIC Clk/msec = %10d\n",apic_clk_per_msec);
}
 
void ll_init_advtimer()
{
#ifdef __APIC__
unsigned long msr_low_orig, tmp;
#endif
unsigned long msr_low_orig, tmp;
 
#ifdef __TSC__
#ifdef __APIC__
use_apic = X86_apic;
#endif
 
#ifdef __TSC__
use_tsc = X86_tsc;
#endif
 
if (use_tsc) {
#ifdef CALIBRATE_USING_CMOS
ll_calibrate_tsc_cmos();
#else
ll_calibrate_tsc();
#endif
#ifdef CALIBRATE_USING_CMOS
ll_calibrate_tsc_cmos();
#else
ll_calibrate_tsc();
#endif
 
rdtscll(init_tsc); // Read start TSC
init_nsec = 0;
rdtscll(init_tsc); // Read start TSC
init_nsec = 0;
 
#ifdef __APIC__
if (use_apic) {
rdmsr(APIC_BASE_MSR, msr_low_orig, tmp);
wrmsr(APIC_BASE_MSR, msr_low_orig|(1<<11), 0);
 
rdmsr(APIC_BASE_MSR, msr_low_orig, tmp);
wrmsr(APIC_BASE_MSR, msr_low_orig|(1<<11), 0);
clear_local_APIC();
 
clear_local_APIC();
ll_calibrate_apic();
 
ll_calibrate_apic();
 
setup_local_APIC();
setup_local_APIC();
setup_APIC_timer();
 
#endif
 
#endif
 
setup_APIC_timer();
}
}
}
 
void ll_restore_adv()
{
/* Disable APIC */
#ifdef __APIC__
if (use_apic) {
unsigned int msr_low_orig, tmp;
 
cli();
479,7 → 474,5
wrmsr(APIC_BASE_MSR, msr_low_orig&~(1<<11), 0);
 
sti();
 
#endif
}
}
/shark/trunk/oslib/xlib/vm86.c
51,6 → 51,7
#define VM86_STACK_SIZE 8192
 
extern DWORD ll_irq_table[256];
extern BYTE use_apic, use_tsc;
 
/* TSS optional section */
static BYTE vm86_stack0[VM86_STACK_SIZE];
180,11 → 181,8
LIN_ADDR vm86_stackPtr;
DWORD *IRQTable_entry;
BYTE p1,p2;
DWORD msr1 = 0,msr2 = 0;
 
#ifdef __APIC__
DWORD msr1 = 0,msr2 = 0;
#endif
 
SYS_FLAGS f;
 
if (service < 0x10 || in == NULL) return -1;
229,10 → 227,10
outp(0x21,0xFF);
outp(0xA1,0xFF);
 
#ifdef __APIC__
if (use_apic) {
rdmsr(APIC_BASE_MSR,msr1,msr2);
disable_APIC_timer();
#endif
}
 
vm86_TSS.t.back_link = ll_context_save();
VM86_ret_ctx = vm86_TSS.t.back_link
240,10 → 238,10
ll_context_load(X_VM86_TSS);
cli();
 
#ifdef __APIC__
if (use_apic) {
wrmsr(APIC_BASE_MSR,msr1,msr2);
enable_APIC_timer();
#endif
}
 
outp(0x21,p1);
outp(0xA1,p2);
285,10 → 283,10
outp(0x21,0xFF);
outp(0xA1,0xFF);
 
#ifdef __APIC__
if (use_apic) {
rdmsr(APIC_BASE_MSR,msr1,msr2);
disable_APIC_timer();
#endif
}
 
vm86_TSS.t.back_link = ll_context_save();
VM86_ret_ctx = vm86_TSS.t.back_link;
296,10 → 294,10
ll_context_load(X_VM86_TSS);
cli();
 
#ifdef __APIC__
if (use_apic) {
wrmsr(APIC_BASE_MSR,msr1,msr2);
enable_APIC_timer();
#endif
}
 
outp(0x21,p1);
outp(0xA1,p2);
/shark/trunk/oslib/xlib/xbios.c
37,28 → 37,27
void X_callBIOS(int service,X_REGS16 *in,X_REGS16 *out,X_SREGS16 *s)
{
/* Assembler gate JMP instruction */
extern BYTE use_tsc, use_apic;
extern void _x_callBIOS(void);
X_CALLBIOS *xbc = x_bios_address();
#ifdef __APIC__
DWORD msr1 = 0,msr2 = 0;
#endif
DWORD msr1 = 0,msr2 = 0;
 
/* Send interrupt request & register through the X_Info structure */
xbc->_irqno = service;
memcpy(&(xbc->_ir),in,sizeof(X_REGS16));
memcpy(&(xbc->_sr),s,sizeof(X_SREGS16));
#ifdef __APIC__
if (use_apic) {
rdmsr(APIC_BASE_MSR,msr1,msr2);
disable_APIC_timer();
#endif
}
/* Back to RM to execute the BIOS routine */
_x_callBIOS();
 
/* Get the return register values */
#ifdef __APIC__
if (use_apic) {
wrmsr(APIC_BASE_MSR,msr1,msr2);
enable_APIC_timer();
#endif
}
memcpy(out,&(xbc->_or),sizeof(X_REGS16));
memcpy(s,&(xbc->_sr),sizeof(X_SREGS16));
}
/shark/trunk/oslib/xlib/xinit.c
73,9 → 73,10
{
register int i;
struct ll_cpuInfo cpuInfo;
extern BYTE X86_apic;
extern BYTE X86_tsc;
extern BYTE X86_fpu;
LIN_ADDR b;
LIN_ADDR b;
for(i = 0; i < 256; i++) {
ll_irq_table[i] = (DWORD)dummyfun;
88,6 → 89,9
ll_arch.x86.fpu = X86_fpu;
memcpy(&(ll_arch.x86.vendor), &(cpuInfo.X86_vendor_1), 12);
X86_apic = cpuInfo.X86_StandardFeature & (1<<4);
X86_tsc = cpuInfo.X86_StandardFeature & (1<<9);
/* TODO! Need to map featuresXXX & Signature onto ll_arch! */
/* TODO! Need to check for CPU bugs!! */
99,8 → 103,10
message("Features #1: 0x%lx\n", cpuInfo.X86_IntelFeature_1);
message("Features #2: 0x%lx\n", cpuInfo.X86_IntelFeature_2);
message("Features #3: 0x%lx\n", cpuInfo.X86_StandardFeature);
message("Has APIC: %s\n", X86_apic);
message("Has TSC: %s\n", X86_tsc);
#endif /* __LL_DEBUG__ */
IDT_init();
 
/* Init coprocessor & assign it to main() */