Author: mmlr Date: 2011-05-23 15:25:44 +0200 (Mon, 23 May 2011) New Revision: 41680 Changeset: https://dev.haiku-os.org/changeset/41680 Modified: haiku/trunk/src/system/boot/platform/bios_ia32/cpu.cpp Log: * Re-program the timer for each loop instead of waiting for it to wrap around. With that we will usually start right away without having to wait for the timer to be in the desired state, which removes roughly 116ms of spinning around for a normal calibration run. * Read back the value once after programming. The delay this introduces accounts for the fact that the counter will only start counting down on the next clock cycle. Modified: haiku/trunk/src/system/boot/platform/bios_ia32/cpu.cpp =================================================================== --- haiku/trunk/src/system/boot/platform/bios_ia32/cpu.cpp 2011-05-23 12:47:32 UTC (rev 41679) +++ haiku/trunk/src/system/boot/platform/bios_ia32/cpu.cpp 2011-05-23 13:25:44 UTC (rev 41680) @@ -185,9 +185,22 @@ double& conversionFactor, uint16& expired) { uint8 select = channel << PIT_SELECT_CHANNEL_SHIFT; + out8(select | PIT_ACCESS_LOW_THEN_HIGH_BYTE | PIT_MODE_RATE_GENERATOR + | PIT_BINARY_MODE, PIT_CONTROL); + + // Fill in count of 0xffff, low then high byte uint8 channelPort = PIT_CHANNEL_PORT_BASE + channel; + out8(0xff, channelPort); + out8(0xff, channelPort); - // Wait for the PIT to arrive at our starting position (high byte == 0xff) + // Read the count back once to delay the start. This ensures that we've + // waited long enough for the counter to actually start counting down, as + // this only happens on the next clock cycle after reload. + in8(channelPort); + in8(channelPort); + + // We're expecting the PIT to be at the starting position (high byte 0xff) + // as we just programmed it, but if it isn't we wait for it to wrap. uint8 startLow; uint8 startHigh; do { @@ -221,26 +234,15 @@ calculate_cpu_conversion_factor() { uint8 channel = 0; - uint8 channelPort = PIT_CHANNEL_PORT_BASE + channel; - uint8 control; // When using channel 2, enable the input and disable the speaker. if (channel == 2) { - control = in8(PIT_CHANNEL_2_CONTROL); + uint8 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); - uint64 tscDeltaQuick, tscDeltaSlower, tscDeltaSlow; double conversionFactorQuick, conversionFactorSlower, conversionFactorSlow; uint16 expired;