/shark/trunk/oslib/kl/event.c |
---|
36,7 → 36,6 |
#include <ll/i386/pit.h> |
#include <ll/i386/apic.h> |
#include <ll/i386/advtimer.h> |
#include <ll/i386/64bit.h> |
#include <ll/sys/ll/ll-data.h> |
#include <ll/sys/ll/ll-instr.h> |
73,7 → 72,9 |
extern void (*evt_prol) (void); |
extern void (*evt_epil) (void); |
extern unsigned int apic_clk_per_msec; |
extern unsigned char use_tsc; |
extern unsigned char use_apic; |
extern signed long long apic_clk_per_msec; |
void event_setlasthandler(void *p) |
{ |
166,15 → 167,13 |
void periodic_wake_up(void) |
{ /* CHANGE the NAME, please... */ |
struct event *p, *pp; |
#ifndef __TSC__ |
WORD tmp; |
#endif |
#ifndef __TSC__ |
if(!use_tsc) { |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
#endif |
} |
activeInt++; |
if (activeInt == 1 && evt_prol != NULL) { |
181,11 → 180,11 |
evt_prol(); |
} |
#ifndef __TSC__ |
if (!use_tsc) { |
ADDNANO2TIMESPEC(nts, &actTime); |
#else |
} else { |
ll_read_timespec(&actTime); |
#endif |
} |
for (p = firstevent; p != NULL; p = pp) { |
/* |
218,30 → 217,25 |
int i; |
BYTE mask; |
TIME t; |
#ifdef __APIC__ |
DWORD apic_clk; |
#endif |
#ifdef __TSC__ |
ll_init_advtimer(); |
#endif |
if (use_tsc) ll_init_advtimer(); |
#ifndef __APIC__ |
if (!use_apic) |
IDT_place(0x40,ll_timer); |
#else |
else |
IDT_place(0x39,ll_apic_timer); |
#endif |
if (l->mode != LL_PERIODIC) { |
message("One-shot mode\n"); |
t = 0; |
#ifndef __APIC__ |
if (!use_apic) { |
/* Mode: Binary/Mode 4/16 bit Time_const/Counter 0 */ |
pit_init(0, TMR_MD4, 0xFFFF); /* Timer 0, Mode 4, constant 0xFFFF */ |
#else |
} else { |
set_APIC_timer(0xFFFFFFFF); |
enable_APIC_timer(); |
#endif |
} |
} else { |
t = l->tick; |
254,9 → 248,9 |
/* If T-C == 0 -> T-C = 65536 (Max available) */ |
ticksize = t; |
#ifndef __APIC__ |
if (!use_apic) { |
mul32div32to32(t,1197,1000,t); |
t = (signed long long)(t) * 1193182 / 1000000; |
/* Only for security! This should cause timer overrun */ |
/* While 0 would set maximum period on timer */ |
266,17 → 260,17 |
/* Mode: Binary/Mode 2/16 bit Time_const/Counter 0 */ |
pit_init(0, TMR_MD2, t); /* Timer 0, Mode 2, Time constant t */ |
#else |
} else { |
mul32div32to32(t,apic_clk_per_msec,1000,apic_clk); |
apic_clk = (signed long long)(t) * apic_clk_per_msec / 1000; |
set_APIC_timer(apic_clk); |
enable_APIC_timer(); |
#endif |
} |
} |
timermode = l->mode; |
#ifndef __APIC__ |
if (!use_apic) { |
if (ll_arch.x86.cpu > 4) { |
/* Timer1: mode 0, time const 0... */ |
pit_init(1, TMR_MD0, 0); |
286,7 → 280,7 |
pit_init(2, TMR_MD0, 0); |
outp(0x61, 3); |
} |
#endif |
} |
mask = ll_in(0x21); |
mask &= 0xFE; /* 0xFE = ~0x01 */ |
322,8 → 316,6 |
} |
/* Last but not least... */ |
#ifndef __APIC__ |
irq_unmask(0); |
#endif |
if (!use_apic) irq_unmask(0); |
} |
/shark/trunk/oslib/kl/event1.c |
---|
34,7 → 34,6 |
#include <ll/i386/apic.h> |
#include <ll/i386/advtimer.h> |
#include <ll/i386/error.h> |
#include <ll/i386/64bit.h> |
#include <ll/sys/ll/ll-data.h> |
#include <ll/sys/ll/ll-func.h> |
58,8 → 57,12 |
extern void (*evt_prol) (void); |
extern void (*evt_epil) (void); |
extern unsigned int apic_clk_per_msec; |
extern unsigned char use_tsc; |
extern unsigned char use_apic; |
extern unsigned long long apic_clk_per_msec; |
#define barrier() __asm__ __volatile__("" ::: "memory"); |
/* Switched to timespec */ |
int oneshot_event_post(struct timespec time, void (*handler) (void *p), |
void *par) |
102,11 → 105,7 |
} 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 { |
113,15 → 112,15 |
SUBTIMESPEC(&(firstevent->time), &now, &tmp); |
} |
tnext = TIMESPEC2USEC(&tmp); |
#ifndef __APIC__ |
mul32div32to32(tnext,1197,1000,tnext); |
if (!use_apic) { |
tnext = (signed long long)(tnext) * 1193182 / 1000000; |
pit_setconstant(0, tnext); |
#else |
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext); |
} else { |
tnext = (signed long long)(tnext) * apic_clk_per_msec / 1000; |
set_APIC_timer(tnext); |
#endif |
} |
} |
} |
p->next = p1; |
return p->index; |
133,12 → 132,10 |
{ /* CHANGE the NAME, please... */ |
struct event *p = NULL, *pp; |
struct timespec now, ttmp; |
#ifndef __TSC__ |
WORD tmp; |
#endif |
DWORD tnext; |
#ifndef __TSC__ |
if (!use_tsc) { |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
146,11 → 143,11 |
PITSPEC2TIMESPEC(&globalCounter, &now); |
#else |
} else { |
ll_read_timespec(&now); |
#endif |
} |
if (firstevent != NULL) { |
activeEvent = 1; |
179,8 → 176,10 |
activeInt--; |
} |
#ifndef __TSC__ |
barrier(); |
if (!use_tsc) { |
tmp = pit_read(frc); |
ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter); |
lastTime = tmp; |
187,11 → 186,11 |
PITSPEC2TIMESPEC(&globalCounter, &now); |
#else |
} else { |
ll_read_timespec(&now); |
#endif |
} |
if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) { |
201,21 → 200,21 |
} |
/* SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */ |
tnext = TIMESPEC2USEC(&ttmp); |
#ifndef __APIC__ |
mul32div32to32(tnext,1197,1000,tnext); |
if (!use_apic) { |
tnext = (signed long long)(tnext) * 1193182 / 1000000; |
pit_setconstant(0, tnext); |
#else |
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext); |
} else { |
tnext = (signed long long)(tnext) * apic_clk_per_msec / 1000; |
set_APIC_timer(tnext); |
#endif |
} |
activeEvent = 0; |
} else { |
#ifndef __APIC__ |
if (!use_apic) { |
pit_setconstant(0, 0xFFFF); |
#else |
} else { |
set_APIC_timer(0xFFFFFFFF); |
#endif |
} |
} |
} |
248,18 → 247,14 |
if (!activeEvent) { |
if (firstevent == NULL) { |
#ifndef __APIC__ |
if (!use_apic) { |
pit_setconstant(0, 0xFFFF); |
#else |
} 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 { |
267,15 → 262,15 |
} |
/*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */ |
tnext = TIMESPEC2USEC(&tmp); |
#ifndef __APIC__ |
mul32div32to32(tnext,1197,1000,tnext); |
if (!use_apic) { |
tnext = (signed long long)(tnext) * 1193182 / 1000000; |
pit_setconstant(0, tnext); |
#else |
mul32div32to32(tnext,apic_clk_per_msec,1000,tnext); |
} else { |
tnext = (signed long long)(tnext) * apic_clk_per_msec / 1000; |
set_APIC_timer(tnext); |
#endif |
} |
} |
} |
} |
return 1; |
} |
/shark/trunk/oslib/kl/advtimer.c |
---|
25,30 → 25,145 |
#include <ll/i386/stdlib.h> |
#include <ll/i386/error.h> |
#include <ll/i386/advtimer.h> |
#include <ll/sys/ll/ll-data.h> |
#include <ll/sys/ll/ll-func.h> |
#include <ll/i386/pic.h> |
#include <ll/i386/apic.h> |
#include <ll/i386/64bit.h> |
#include <ll/sys/ll/event.h> |
#include <ll/sys/ll/time.h> |
#include <ll/i386/advtimer.h> |
#define CALIBRATE_USING_CMOS |
unsigned long long init_tsc; |
unsigned long long * ptr_init_tsc = &init_tsc; |
unsigned char use_tsc = 1; //Enable the TSC counter mode |
unsigned char use_cmos = 0; //Enable the RTC correction |
unsigned char use_apic = 0; //Enable the APIC for P6 only |
unsigned long long init_nsec; //Wraparound 292 years |
unsigned long long * ptr_init_nsec = &init_nsec; |
//Max single delta_clk_per_msec increment = clk_per_msec / MAX_DIV_INK; |
#define MAX_DIV_INK 30000 |
unsigned int clk_per_msec = 0; |
unsigned int apic_clk_per_msec = 0; |
unsigned int apic_set_limit = 0; |
signed long long init_tsc; |
signed long long * ptr_init_tsc = &init_tsc; |
signed long long init_nsec; //Wraparound 292 years |
signed long long * ptr_init_nsec = &init_nsec; |
signed long long clk_per_msec; |
signed long long * ptr_clk_per_msec = &clk_per_msec; |
signed long long apic_clk_per_msec; |
unsigned int apic_set_limit; |
signed long last_delta_clk_per_msec; |
signed long total_delta_clk_per_msec; |
unsigned char save_CMOS_regA; |
unsigned char save_CMOS_regB; |
//#define IRQ8_DEBUG |
void HandlerIRQ8(void *p) |
{ |
unsigned char set; |
static unsigned long Mconst = 1000000; |
static unsigned long init_step = 0; |
signed long max_dcms = clk_per_msec / MAX_DIV_INK; |
static signed long long dn; |
static signed long long * ptr_dn = &dn; |
signed long delta_clk_per_msec; |
cli(); |
#ifdef IRQ8_DEBUG |
message("(IRQ8"); |
#endif |
CMOS_READ(0x0C,set); |
__asm__("xorl %%eax,%%eax\n\t" |
"cpuid\n\t" |
"rdtsc\n\t" |
"pushl %%eax\n\t" |
"pushl %%edx\n\t" |
"pushl %%eax\n\t" |
"pushl %%edx\n\t" |
"xorl %%eax,%%eax\n\t" |
"cpuid\n\t" |
"popl %%edx\n\t" |
"popl %%eax\n\t" |
"subl (%%edi),%%eax\n\t" |
"sbbl 4(%%edi),%%edx\n\t" |
"popl 4(%%edi)\n\t" |
"popl (%%edi)\n\t" |
"movl %%edx,%%ecx\n\t" |
"mull %4\n\t" |
"pushl %%eax\n\t" |
"movl %%ecx,%%eax\n\t" |
"movl %%edx,%%ecx\n\t" |
"mull %4\n\t" |
"addl %%ecx,%%eax\n\t" |
"adcl $0,%%edx\n\t" |
"movl %7,%%ebx\n\t" |
"divl (%%ebx)\n\t" |
"movl %%eax,4(%%esi)\n\t" |
"popl %%eax\n\t" |
"divl (%%ebx)\n\t" |
"movl %%eax,(%%esi)\n\t" |
: |
: "D" (ptr_init_tsc), "S" (ptr_dn), "b" (0), |
"c" (0), "m" (Mconst), "a" (0), "d" (0), "m" (ptr_clk_per_msec)); |
//Offset |
init_nsec += dn; |
if (init_step < 5) { |
init_step++; |
#ifdef IRQ8_DEBUG |
message(")"); |
#endif |
sti(); |
return; |
} |
dn = dn % 1000000000 - 500000000; |
//Delta clk/msec |
delta_clk_per_msec = dn * clk_per_msec / (500000000 - dn); |
//clk_per_msec adjustment |
if (delta_clk_per_msec < 0) { |
if (delta_clk_per_msec > -max_dcms) |
clk_per_msec += delta_clk_per_msec; |
else |
clk_per_msec -= max_dcms; |
} else { |
if (delta_clk_per_msec < max_dcms) |
clk_per_msec += delta_clk_per_msec; |
else |
clk_per_msec += max_dcms; |
} |
last_delta_clk_per_msec = delta_clk_per_msec; |
total_delta_clk_per_msec += delta_clk_per_msec; |
#ifdef IRQ8_DEBUG |
message(")"); |
#endif |
sti(); |
} |
#ifdef CONFIG_MELAN |
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ |
#else |
63,11 → 178,11 |
void ll_calibrate_tsc(void) |
{ |
unsigned long long start; |
unsigned long long end; |
unsigned long long dtsc; |
signed long long start; |
signed long long end; |
signed long long dtsc; |
unsigned int start_8253, end_8253, delta_8253; |
signed long start_8253, end_8253, delta_8253; |
cli(); |
116,13 → 231,13 |
ll_abort(10); |
} |
message("Delta TSC = %10d\n",(int)dtsc); |
message("Delta TSC = %10ld\n",(long)dtsc); |
message("Delta PIT = %10d\n",delta_8253); |
message("Delta PIT = %10ld\n",(long)delta_8253); |
clk_per_msec = dtsc * CLOCK_TICK_RATE / delta_8253 / 1000; |
message("Calibrated Clk_per_msec = %10d\n",clk_per_msec); |
message("Calibrated Clk_per_msec = %10ld\n",(long)clk_per_msec); |
sti(); |
134,8 → 249,8 |
#define CMOS_END 3 |
int cmos_calibrate_status = CMOS_INIT; |
unsigned long long irq8_start; |
unsigned long long irq8_end; |
signed long long irq8_start; |
signed long long irq8_end; |
void calibrate_tsc_IRQ8(void *p) |
{ |
171,7 → 286,7 |
void ll_calibrate_tsc_cmos(void) |
{ |
unsigned long long dtsc; |
signed long long dtsc; |
cli(); |
195,7 → 310,7 |
clk_per_msec = dtsc / 500; |
message("Calibrated CPU Clk/msec = %10d\n",clk_per_msec); |
message("Calibrated CPU Clk/msec = %10ld\n",(long)clk_per_msec); |
cli(); |
208,6 → 323,53 |
} |
//Low level time read function |
void ll_read_timespec(struct timespec *tspec) |
{ |
static unsigned long Gconst = 1000000000; |
static unsigned long Mconst = 1000000; |
if (clk_per_msec <= 0) { |
NULL_TIMESPEC(tspec); |
return; |
} |
__asm__("xorl %%eax,%%eax\n\t" |
"cpuid\n\t" |
"rdtsc\n\t" |
"pushl %%eax\n\t" |
"pushl %%edx\n\t" |
"xorl %%eax,%%eax\n\t" |
"cpuid\n\t" |
"popl %%edx\n\t" |
"popl %%eax\n\t" |
"subl (%%edi),%%eax\n\t" |
"sbbl 4(%%edi),%%edx\n\t" |
"movl %%edx,%%ecx\n\t" |
"mull %6\n\t" |
"pushl %%eax\n\t" |
"movl %%ecx,%%eax\n\t" |
"movl %%edx,%%ecx\n\t" |
"mull %6\n\t" |
"addl %%ecx,%%eax\n\t" |
"adcl $0,%%edx\n\t" |
"movl %8,%%ebx\n\t" |
"divl (%%ebx)\n\t" |
"movl %%eax,%%ecx\n\t" |
"popl %%eax\n\t" |
"divl (%%ebx)\n\t" |
"movl %%ecx,%%edx\n\t" |
"addl (%%esi),%%eax\n\t" |
"adcl 4(%%esi),%%edx\n\t" |
"divl %7\n\t" |
: "=a" (tspec->tv_sec), "=d" (tspec->tv_nsec) |
: "D" (ptr_init_tsc), "S" (ptr_init_nsec), "b" (0), |
"c" (0), "m" (Mconst), "m" (Gconst), "m" (ptr_clk_per_msec)); |
} |
int apic_get_maxlvt(void) |
{ |
unsigned int v, ver, maxlvt; |
361,7 → 523,7 |
{ |
unsigned int apic_start = 0, apic_end = 0, dapic; |
unsigned long long tsc_start = 0, tsc_end = 0, dtsc; |
signed long long tsc_start = 0, tsc_end = 0, dtsc; |
unsigned int tmp_value; |
cli(); |
395,20 → 557,17 |
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_clk_per_msec = clk_per_msec * (signed 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 = %10ld\n",(long)apic_clk_per_msec); |
} |
void ll_init_advtimer() |
{ |
#ifdef __APIC__ |
unsigned long msr_low_orig, tmp; |
#endif |
#ifdef __TSC__ |
if (use_tsc) { |
#ifdef CALIBRATE_USING_CMOS |
ll_calibrate_tsc_cmos(); |
416,10 → 575,14 |
ll_calibrate_tsc(); |
#endif |
last_delta_clk_per_msec = 0; |
total_delta_clk_per_msec = 0; |
rdtscll(init_tsc); // Read start TSC |
init_nsec = 0; |
#ifdef __APIC__ |
if (use_apic) { |
unsigned long msr_low_orig, tmp; |
rdmsr(APIC_BASE_MSR, msr_low_orig, tmp); |
wrmsr(APIC_BASE_MSR, msr_low_orig|(1<<11), 0); |
432,16 → 595,52 |
setup_APIC_timer(); |
#endif |
} |
#endif |
if (use_cmos) { |
message("CMOS adjustement enabled\n"); |
cli(); |
irq_bind(8, HandlerIRQ8, 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 |
irq_unmask(8); |
sti(); |
} |
} else { |
use_cmos = 0; |
} |
} |
void ll_restore_adv() |
{ |
/* Restore CMOS setting */ |
if (use_cmos) { |
cli(); |
irq_mask(8); |
CMOS_WRITE(0x0A,save_CMOS_regA); |
CMOS_WRITE(0x0B,save_CMOS_regB); |
sti(); |
} |
/* Disable APIC */ |
#ifdef __APIC__ |
if (use_apic) { |
unsigned int msr_low_orig, tmp; |
cli(); |
453,6 → 652,6 |
sti(); |
#endif |
} |
} |
/shark/trunk/oslib/kl/timeint.s |
---|
58,16 → 58,14 |
pushw %fs |
pushw %gs |
cli |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%ds |
movw %ax,%es |
/* Send ACK to APIC */ |
/* Send EOI to APIC */ |
movl $0xFEE000B0,%ebx |
movl $0,(%ebx) |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%ds |
movw %ax,%es |
/* Call wake_up(actual_context) */ |
movl SYMBOL_NAME(ll_clock),%eax |
133,9 → 131,6 |
movl SYMBOL_NAME(last_handler), %ebx |
call *%ebx |
apic_nohandler: |
sti |
popw %gs |
popw %fs |
popw %es |
158,17 → 153,16 |
pushw %fs |
pushw %gs |
cli |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%ds |
movw %ax,%es |
/* Send ACK to master PIC */ |
/* Send EOI to master PIC */ |
/* to perform later the overrun test */ |
movb $0x20,%al |
movl $0x20,%edx |
outb %al,%dx |
movw $(X_FLATDATA_SEL),%ax |
movw %ax,%ds |
movw %ax,%es |
/* Call wake_up(actual_context) */ |
movl SYMBOL_NAME(ll_clock),%eax |
249,9 → 243,6 |
movl SYMBOL_NAME(last_handler), %ebx |
call *%ebx |
nohandler: |
sti |
popw %gs |
popw %fs |
popw %es |
/shark/trunk/oslib/kl/time.c |
---|
49,17 → 49,18 |
extern BYTE frc; |
extern int activeEvent; |
extern unsigned char use_tsc; |
FILE(Time); |
TIME ll_gettime(int mode, struct timespec *tsres) |
{ |
#ifndef __TSC__ |
DWORD res, tc; |
BYTE isr; |
struct timespec tmp; |
if (!use_tsc) { |
#if 1 |
if (activeEvent) { |
if (tsres != NULL) { |
137,22 → 138,68 |
} |
return 0; |
#else |
} else { |
#if 1 |
if (activeEvent) { |
if (tsres != NULL) { |
ll_read_timespec(tsres); |
} else { |
struct timespec tmp; |
ll_read_timespec(&tmp); |
return TIMESPEC2USEC(&tmp); |
} |
return TIMESPEC2USEC(tsres); |
} |
#endif |
if (mode == TIME_PTICK) { |
if (timermode != LL_PERIODIC) { |
return 0; |
} |
if(tsres != NULL) { |
ll_read_timespec(tsres); |
} else { |
struct timespec tmp; |
ll_read_timespec(&tmp); |
return TIMESPEC2USEC(&tmp); |
} |
return TIMESPEC2USEC(tsres); |
} |
if (mode == TIME_NEW) { |
if (tsres != NULL) { |
ll_read_timespec(tsres); |
return TIMESPEC2USEC(tsres); |
} else { |
struct timespec tmp; |
ll_read_timespec(&tmp); |
return TIMESPEC2USEC(&tmp); |
} |
} |
if (mode == TIME_EXACT) { |
if (timermode == LL_PERIODIC) { |
if (tsres != NULL) { |
ll_read_timespec(tsres); |
} else { |
struct timespec tmp; |
ll_read_timespec(&tmp); |
return TIMESPEC2USEC(&tmp); |
} |
return TIMESPEC2USEC(tsres); |
} else { |
return 0; |
} |
} |
#endif |
return 0; |
} |
} |
/shark/trunk/oslib/ll/i386/advtimer.h |
---|
31,8 → 31,6 |
#include <ll/i386/defs.h> |
BEGIN_DEF |
#include <ll/sys/ll/time.h> |
/* TSC */ |
#define rdtsc(low,high) \ |
59,54 → 57,6 |
: "=A" (val) \ |
:: "ebx","ecx") |
//Low level time read function |
extern __inline__ void ll_read_timespec(struct timespec *tspec) |
{ |
extern unsigned int clk_per_msec; |
extern unsigned long long *ptr_init_nsec; |
extern unsigned long long *ptr_init_tsc; |
if (clk_per_msec == 0) { |
NULL_TIMESPEC(tspec); |
return; |
} |
__asm__("xorl %%eax,%%eax\n\t" |
"cpuid\n\t" |
"rdtsc\n\t" |
"pushl %%eax\n\t" |
"pushl %%edx\n\t" |
"xorl %%eax,%%eax\n\t" |
"cpuid\n\t" |
"popl %%edx\n\t" |
"popl %%eax\n\t" |
"movl %4,%%ebx\n\t" |
"subl (%%edi),%%eax\n\t" |
"sbbl 4(%%edi),%%edx\n\t" |
"movl %%edx,%%ecx\n\t" |
"movl $1000000,%%edi\n\t" |
"mull %%edi\n\t" |
"pushl %%eax\n\t" |
"movl %%ecx,%%eax\n\t" |
"movl %%edx,%%ecx\n\t" |
"mull %%edi\n\t" |
"addl %%ecx,%%eax\n\t" |
"adcl $0,%%edx\n\t" |
"divl %%ebx\n\t" |
"movl %%eax,%%ecx\n\t" |
"popl %%eax\n\t" |
"divl %%ebx\n\t" |
"movl %%ecx,%%edx\n\t" |
"addl (%%esi),%%eax\n\t" |
"adcl 4(%%esi),%%edx\n\t" |
"movl $1000000000,%%edi\n\t" |
"divl %%edi\n\t" |
: "=a" (tspec->tv_sec), "=d" (tspec->tv_nsec) |
: "D" (ptr_init_tsc), "S" (ptr_init_nsec), "m" (clk_per_msec) |
: "ebx", "ecx"); |
} |
#define rdmsr(msr,val1,val2) \ |
__asm__ __volatile__("rdmsr" \ |
: "=a" (val1), "=d" (val2) \ |
/shark/trunk/oslib/ll/i386/pit.h |
---|
181,8 → 181,8 |
(t)->gigas += (t)->units / 1432809, \ |
(t)->units %= 1432809) |
#define NULLPITSPEC(t) (t)->units = 0, (t)->gigas = 0 |
#define PITSPEC2USEC(t) ((((t)->units * 1000) / 1197) \ |
+ (((t)->gigas * 1000) * 1197)) |
#define PITSPEC2USEC(t) ((((signed long long)((t)->units) * 1000000) / 1193182) \ |
+ (((signed long long)((t)->gigas) * 1000000) * 1193182)) |
#define CPPITSPEC(a, b) (b)->units = (a)->units, (b)->gigas = (a)->gigas |
END_DEF |
#endif /* __PIT_H__ */ |
/shark/trunk/oslib/ll/sys/ll/time.h |
---|
127,21 → 127,21 |
#if 0 |
#define PITSPEC2TIMESPEC(a,b) \ |
((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197) * 1000, \ |
(b)->tv_sec = ((a)->gigas * 1197) / 1000) /*, \ |
((b)->tv_nsec = (((signed long long)((a)->units) * 1000000) / 1193182) * 1000, \ |
(b)->tv_sec = ((signed long long)((a)->gigas) * 1193182) / 1000000) /*, \ |
(b)->tv_sec += (b)->tv_nsec / 1000000000, \ |
(b)->tv_nsec %= 1000000000) */ |
#else |
/*#define PITSPEC2TIMESPEC(a,b) \ |
((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197) * 1000, \ |
(b)->tv_nsec += (((a)->gigas * 1197) % 1000) * 1000000, \ |
(b)->tv_sec = ((a)->gigas * 1197) / 1000 , \ |
((b)->tv_nsec = (((signed long long)((a)->units) * 1000000) / 1193182) * 1000, \ |
(b)->tv_nsec += (((signed long long)((a)->gigas) * 1193182) % 1000000) * 1000000, \ |
(b)->tv_sec = ((signed long long)((a)->gigas) * 1193182) / 1000000 , \ |
(b)->tv_sec += (b)->tv_nsec / 1000000000, \ |
(b)->tv_nsec %= 1000000000)*/ |
#define PITSPEC2TIMESPEC(a,b) \ |
((b)->tv_nsec = (((DWORD)((a)->units) * 1000) / 1197), \ |
(b)->tv_nsec += (((a)->gigas * 1197) % 1000) * 1000, \ |
(b)->tv_sec = ((a)->gigas * 1197) / 1000 , \ |
((b)->tv_nsec = (((signed long long)((a)->units) * 1000000) / 1193182), \ |
(b)->tv_nsec += (((signed long long)((a)->gigas) * 1193182) % 1000000) * 1000, \ |
(b)->tv_sec = ((signed long long)((a)->gigas) * 1193182) / 1000000 , \ |
(b)->tv_sec += (b)->tv_nsec / 1000000, \ |
(b)->tv_nsec %= 1000000, \ |
(b)->tv_nsec *= 1000) |
148,6 → 148,7 |
#endif |
TIME ll_gettime(int mode, struct timespec *tsres); |
void ll_read_timespec(struct timespec *tspec); |
#define TIME_PTICK 1 |
#define TIME_EXACT 2 |