* Use macros to make the PIT programming more readable. Yes, I know that the PIT
timer code has such definitions too, but they're not quite as verbose. Will eventually make the latter use these too. * Prepare for possibly using other PIT channels for the calibration. Right now everything's the same still. * Add disabled print of the resulting factors. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41669 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
10919035c8
commit
d620303480
@ -34,7 +34,39 @@ extern "C" uint64 rdtsc();
|
|||||||
|
|
||||||
uint32 gTimeConversionFactor;
|
uint32 gTimeConversionFactor;
|
||||||
|
|
||||||
#define TIMER_CLKNUM_HZ (14318180/12)
|
// PIT definitions
|
||||||
|
#define TIMER_CLKNUM_HZ (14318180 / 12)
|
||||||
|
|
||||||
|
// PIT IO Ports
|
||||||
|
#define PIT_CHANNEL_PORT_BASE 0x40
|
||||||
|
#define PIT_CONTROL 0x43
|
||||||
|
|
||||||
|
// Channel selection
|
||||||
|
#define PIT_SELECT_CHANNEL_SHIFT 6
|
||||||
|
|
||||||
|
// Access mode
|
||||||
|
#define PIT_ACCESS_LATCH_COUNTER (0 << 4)
|
||||||
|
#define PIT_ACCESS_LOW_BYTE_ONLY (1 << 4)
|
||||||
|
#define PIT_ACCESS_HIGH_BYTE_ONLY (2 << 4)
|
||||||
|
#define PIT_ACCESS_LOW_THEN_HIGH_BYTE (3 << 4)
|
||||||
|
|
||||||
|
// Operating modes
|
||||||
|
#define PIT_MODE_INTERRUPT_ON_0 (0 << 1)
|
||||||
|
#define PIT_MODE_HARDWARE_COUNTDOWN (1 << 1)
|
||||||
|
#define PIT_MODE_RATE_GENERATOR (2 << 1)
|
||||||
|
#define PIT_MODE_SQUARE_WAVE_GENERATOR (3 << 1)
|
||||||
|
#define PIT_MODE_SOFTWARE_STROBE (4 << 1)
|
||||||
|
#define PIT_MODE_HARDWARE_STROBE (5 << 1)
|
||||||
|
|
||||||
|
// BCD/Binary mode
|
||||||
|
#define PIT_BINARY_MODE 0
|
||||||
|
#define PIT_BCD_MODE 1
|
||||||
|
|
||||||
|
// Channel 2 control (speaker)
|
||||||
|
#define PIT_CHANNEL_2_CONTROL 0x61
|
||||||
|
#define PIT_CHANNEL_2_GATE_HIGH 0x01
|
||||||
|
#define PIT_CHANNEL_2_SPEAKER_OFF_MASK ~0x02
|
||||||
|
|
||||||
|
|
||||||
#define CPUID_EFLAGS (1UL << 21)
|
#define CPUID_EFLAGS (1UL << 21)
|
||||||
#define RDTSC_FEATURE (1UL << 4)
|
#define RDTSC_FEATURE (1UL << 4)
|
||||||
@ -151,22 +183,39 @@ calculate_cpu_conversion_factor()
|
|||||||
uint64 p1, p2, p3;
|
uint64 p1, p2, p3;
|
||||||
double r1, r2, r3;
|
double r1, r2, r3;
|
||||||
|
|
||||||
out8(0x34, 0x43); /* program the timer to count down mode */
|
uint8 channel = 0;
|
||||||
out8(0xff, 0x40); /* low and then high */
|
uint8 channelPort = PIT_CHANNEL_PORT_BASE + channel;
|
||||||
out8(0xff, 0x40);
|
uint8 control;
|
||||||
|
|
||||||
|
// When using channel 2, enable the input and disable the speaker.
|
||||||
|
if (channel == 2) {
|
||||||
|
control = in8(PIT_CHANNEL_2_CONTROL);
|
||||||
|
control &= PIT_CHANNEL_2_SPEAKER_OFF_MASK;
|
||||||
|
control |= PIT_CHANNEL_2_GATE_HIGH;
|
||||||
|
out8(control, PIT_CHANNEL_2_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 select = channel << PIT_SELECT_CHANNEL_SHIFT;
|
||||||
|
control = select | PIT_ACCESS_LOW_THEN_HIGH_BYTE | PIT_MODE_RATE_GENERATOR
|
||||||
|
| PIT_BINARY_MODE;
|
||||||
|
out8(control, PIT_CONTROL);
|
||||||
|
|
||||||
|
// Fill in count of 0xffff, low then high byte
|
||||||
|
out8(0xff, channelPort);
|
||||||
|
out8(0xff, channelPort);
|
||||||
|
|
||||||
/* quick sample */
|
/* quick sample */
|
||||||
quick_sample:
|
quick_sample:
|
||||||
do {
|
do {
|
||||||
out8(0x00, 0x43); /* latch counter value */
|
out8(select | PIT_ACCESS_LATCH_COUNTER, PIT_CONTROL);
|
||||||
s_low = in8(0x40);
|
s_low = in8(channelPort);
|
||||||
s_high = in8(0x40);
|
s_high = in8(channelPort);
|
||||||
} while (s_high != 255);
|
} while (s_high != 255);
|
||||||
t1 = rdtsc();
|
t1 = rdtsc();
|
||||||
do {
|
do {
|
||||||
out8(0x00, 0x43); /* latch counter value */
|
out8(select | PIT_ACCESS_LATCH_COUNTER, PIT_CONTROL);
|
||||||
low = in8(0x40);
|
low = in8(channelPort);
|
||||||
high = in8(0x40);
|
high = in8(channelPort);
|
||||||
} while (high > 224);
|
} while (high > 224);
|
||||||
t2 = rdtsc();
|
t2 = rdtsc();
|
||||||
|
|
||||||
@ -176,15 +225,15 @@ quick_sample:
|
|||||||
/* not so quick sample */
|
/* not so quick sample */
|
||||||
not_so_quick_sample:
|
not_so_quick_sample:
|
||||||
do {
|
do {
|
||||||
out8(0x00, 0x43); /* latch counter value */
|
out8(select | PIT_ACCESS_LATCH_COUNTER, PIT_CONTROL);
|
||||||
s_low = in8(0x40);
|
s_low = in8(channelPort);
|
||||||
s_high = in8(0x40);
|
s_high = in8(channelPort);
|
||||||
} while (s_high != 255);
|
} while (s_high != 255);
|
||||||
t1 = rdtsc();
|
t1 = rdtsc();
|
||||||
do {
|
do {
|
||||||
out8(0x00, 0x43); /* latch counter value */
|
out8(select | PIT_ACCESS_LATCH_COUNTER, PIT_CONTROL);
|
||||||
low = in8(0x40);
|
low = in8(channelPort);
|
||||||
high = in8(0x40);
|
high = in8(channelPort);
|
||||||
} while (high > 192);
|
} while (high > 192);
|
||||||
t2 = rdtsc();
|
t2 = rdtsc();
|
||||||
p2 = t2-t1;
|
p2 = t2-t1;
|
||||||
@ -200,15 +249,15 @@ not_so_quick_sample:
|
|||||||
|
|
||||||
/* slow sample */
|
/* slow sample */
|
||||||
do {
|
do {
|
||||||
out8(0x00, 0x43); /* latch counter value */
|
out8(select | PIT_ACCESS_LATCH_COUNTER, PIT_CONTROL);
|
||||||
s_low = in8(0x40);
|
s_low = in8(channelPort);
|
||||||
s_high = in8(0x40);
|
s_high = in8(channelPort);
|
||||||
} while (s_high != 255);
|
} while (s_high != 255);
|
||||||
t1 = rdtsc();
|
t1 = rdtsc();
|
||||||
do {
|
do {
|
||||||
out8(0x00, 0x43); /* latch counter value */
|
out8(select | PIT_ACCESS_LATCH_COUNTER, PIT_CONTROL);
|
||||||
low = in8(0x40);
|
low = in8(channelPort);
|
||||||
high = in8(0x40);
|
high = in8(channelPort);
|
||||||
} while (high > 128);
|
} while (high > 128);
|
||||||
t2 = rdtsc();
|
t2 = rdtsc();
|
||||||
|
|
||||||
@ -238,6 +287,7 @@ not_so_quick_sample:
|
|||||||
|
|
||||||
gKernelArgs.arch_args.system_time_cv_factor = gTimeConversionFactor;
|
gKernelArgs.arch_args.system_time_cv_factor = gTimeConversionFactor;
|
||||||
gKernelArgs.arch_args.cpu_clock_speed = p3 / expired;
|
gKernelArgs.arch_args.cpu_clock_speed = p3 / expired;
|
||||||
|
//dprintf("factors: %lu %llu\n", gTimeConversionFactor, p3 / expired);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user