Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 241 → Rev 242

/shark/trunk/oslib/kl/advtimer.c
53,6 → 53,8
unsigned char save_CMOS_regA;
unsigned char save_CMOS_regB;
 
//#define IRQ8_DEBUG
 
void HandlerIRQ8(void *p)
{
 
69,12 → 71,24
signed long delta_clk_per_msec;
cli();
 
#ifdef IRQ8_DEBUG
message("(IRQ8");
#endif
 
CMOS_READ(0x0C,set);
 
__asm__("rdtsc\n\t"
__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"
87,6 → 101,7
"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"
94,8 → 109,8
"movl %%eax,(%%esi)\n\t"
:
: "D" (ptr_init_tsc), "S" (ptr_dn), "b" (ptr_clk_per_msec),
"c" (0), "m" (Mconst), "a" (0), "d" (0));
: "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;
103,6 → 118,11
if (init_step < 5) {
init_step++;
sti();
#ifdef IRQ8_DEBUG
message(")");
#endif
 
return;
}
129,12 → 149,14
last_delta_clk_per_msec = delta_clk_per_msec;
total_delta_clk_per_msec += delta_clk_per_msec;
#ifdef IRQ8_DEBUG
message(")");
#endif
 
sti();
}
 
#define HZ 100
 
#ifdef CONFIG_MELAN
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
#else
141,13 → 163,8
# define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
#endif
 
#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ)
#define COUNTER_END 1000
 
#define CALIBRATE_LATCH (5 * LATCH)
#define CALIBRATE_TIME (5 * 1000020/HZ)
 
#define COUNTER_END 50
 
//TSC Calibration (idea from the linux kernel code)
void ll_calibrate_tsc(void)
{
166,12 → 183,13
outp(0x43,0xB0); /* binary, mode 0, LSB/MSB, Ch 2 */
outp(0x42,0xFF); /* LSB of count */
outp(0x42,0xFF); /* MSB of count */
 
rdtscll(start);
outp(0x43,0x00);
rdtscll(start);
outp(0x43,0x00);
start_8253 = inp(0x42);
start_8253 |= inp(0x42) << 8;
 
rdtscll(start);
do {
outp(0x43,0x00);
179,41 → 197,36
end_8253 |= inp(0x42) << 8;
 
} while (end_8253 > COUNTER_END);
rdtscll(end);
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
 
outp(0x43,0xB0); /* binary, mode 0, LSB/MSB, Ch 2 */
outp(0x42,0xFF); /* LSB of count */
outp(0x42,0xFF); /* MSB of count */
do {
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
} while (end_8253 < COUNTER_END);
 
rdtscll(start);
outp(0x43,0x00);
start_8253 = inp(0x42);
start_8253 |= inp(0x42) << 8;
do {
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
} while (end_8253 > COUNTER_END);
 
do {
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
 
} while (end_8253 > COUNTER_END);
rdtscll(end);
rdtscll(end);
outp(0x43,0x00);
end_8253 = inp(0x42);
end_8253 |= inp(0x42) << 8;
rdtscll(end);
 
//Delta TSC
dtsc = end - start;
 
//Delta PIT
delta_8253 = start_8253 - end_8253 + 1;
delta_8253 = start_8253 - end_8253 + 0x10001;
 
if (delta_8253 > 0xFFFF) {
if (delta_8253 > 0x20000) {
message("Error calculating Delta PIT\n");
ll_abort(10);
}
222,7 → 235,7
 
message("Delta PIT = %10ld\n",(long)delta_8253);
 
clk_per_msec = dtsc * CALIBRATE_LATCH * 1000 / delta_8253 / CALIBRATE_TIME;
clk_per_msec = dtsc * CLOCK_TICK_RATE / delta_8253 * 100002 / 100000000;
message("Calibrated Clk_per_msec = %10ld\n",(long)clk_per_msec);
 
242,8 → 255,16
return;
}
__asm__("rdtsc\n\t"
"subl (%%edi),%%eax\n\t"
__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"
253,6 → 274,7
"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"
263,8 → 285,8
"divl %7\n\t"
: "=a" (tspec->tv_sec), "=d" (tspec->tv_nsec)
: "D" (ptr_init_tsc), "S" (ptr_init_nsec), "b" (ptr_clk_per_msec),
"c" (0), "m" (Mconst), "m" (Gconst));
: "D" (ptr_init_tsc), "S" (ptr_init_nsec), "b" (0),
"c" (0), "m" (Mconst), "m" (Gconst), "m" (ptr_clk_per_msec));
}