32,6 → 32,8 |
#include <ll/sys/ll/event.h> |
#include <ll/sys/ll/time.h> |
|
#define CALIBRATE_USING_CMOS |
|
unsigned char use_tsc = 1; //Enable the TSC counter mode |
unsigned char use_cmos = 0; //Enable the RTC correction |
|
192,6 → 194,8 |
start_8253 = inp(0x42); |
start_8253 |= inp(0x42) << 8; |
barrier(); |
rdtscll(start); |
barrier(); |
|
do { |
|
208,12 → 212,14 |
end_8253 = inp(0x42); |
end_8253 |= inp(0x42) << 8; |
barrier(); |
rdtscll(end); |
barrier(); |
|
//Delta TSC |
dtsc = end - start; |
|
//Delta PIT |
delta_8253 = start_8253 - end_8253 - 1; |
delta_8253 = start_8253 - end_8253; |
|
if (delta_8253 > 0x20000) { |
message("Error calculating Delta PIT\n"); |
232,6 → 238,86 |
|
} |
|
#define CMOS_INIT 0 |
#define CMOS_BEGIN 1 |
#define CMOS_START 2 |
#define CMOS_END 3 |
|
int cmos_calibrate_status = CMOS_INIT; |
signed long long irq8_start; |
signed long long irq8_end; |
|
void calibrate_IRQ8(void *p) |
{ |
|
unsigned char set; |
|
cli(); |
|
CMOS_READ(0x0C,set); |
|
barrier(); |
rdtscll(irq8_end); |
barrier(); |
|
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_INIT) { |
cmos_calibrate_status = CMOS_BEGIN; |
} |
|
sti(); |
|
} |
|
//TSC Calibration using RTC |
void ll_calibrate_tsc_cmos(void) |
{ |
|
signed long long dtsc; |
|
cli(); |
|
irq_bind(8, calibrate_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 |
|
irq_unmask(8); |
|
sti(); |
|
while (cmos_calibrate_status != CMOS_END) { |
barrier(); |
} |
|
dtsc = irq8_end - irq8_start; |
|
clk_per_msec = dtsc / 500; |
|
message("Calibrated Clk_per_msec = %10ld\n",(long)clk_per_msec); |
|
cli(); |
|
irq_mask(8); |
|
CMOS_WRITE(0x0A,save_CMOS_regA); |
CMOS_WRITE(0x0B,save_CMOS_regB); |
|
sti(); |
|
} |
|
//Low level time read function |
void ll_read_timespec(struct timespec *tspec) |
{ |
284,8 → 370,12 |
|
if (use_tsc) { |
|
ll_calibrate_tsc(); |
|
#ifdef CALIBRATE_USING_CMOS |
ll_calibrate_tsc_cmos(); |
#else |
ll_calibrate_tsc(); |
#endif |
|
last_delta_clk_per_msec = 0; |
total_delta_clk_per_msec = 0; |
|