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