[RTEMS Project] #4455: bsps/i386: TSC calibration inaccurate

RTEMS trac trac at rtems.org
Fri Jun 11 06:31:54 UTC 2021

#4455: bsps/i386: TSC calibration inaccurate
  Reporter:  Jan Sommer  |      Owner:  (none)
      Type:  defect      |     Status:  new
  Priority:  normal      |  Milestone:  6.1
 Component:  admin       |    Version:  6
  Severity:  normal      |   Keywords:  i386 clock
Blocked By:              |   Blocking:
 The current implementation of the TSC calibration during startup yields
 inaccurate results.

 There are 2 issues:

 === 1. Rounding error:

 The `calibrate_tsc` function calibrates for 1s by waiting for
 `rtems_clock_get_ticks_per_second()` ticks via the PIT.

 The PIT has a frequency of 1193182 Hz. For a rtems tick of 1ms this yields
 1193. Waiting for 1s means then waiting for 1193000 PIT ticks (instead of
 the full 1193182).
 For a 1 GHz TSC clock this would yield already ~150 kHz less then the
 correct TSC frequency.

 === 2. Waiting for the first loop at begin of timer period

 for (i = rtems_clock_get_ticks_per_second() * pc386_isrs_per_tick;
      i != 0; --i ) {
   /* We know we've just completed a tick when timer goes from low to high
   then_lsb = then_msb = 0xff;
   do {                            <== First loop does not start at begin
 of clock period
     READ_8254(now_lsb, now_msb);
     if ((then_msb < now_msb) ||
         ((then_msb == now_msb) && (then_lsb < now_lsb)))
     then_lsb = now_lsb;
     then_msb = now_msb;
   } while (1);

 This can yield deviations of several MHz for the TSC frequency.
 For example, for a tested CPU with a TSC frequency of 19167.1 MHz yields a
 calibration result of 1912.3 MHz.

 === Proposed solution

 - Just wait 1193182 PIT ticks for 1 s instead of a number of rtems ticks
 - Use the raw timer value instead of waiting for clock ticks.

Ticket URL: <http://devel.rtems.org/ticket/4455>
RTEMS Project <http://www.rtems.org/>
RTEMS Project

More information about the bugs mailing list