/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() */ |