#4455 closed defect (fixed)

bsps/i386: TSC calibration inaccurate

Reported by: Jan Sommer Owned by: Jan Sommer
Priority: normal Milestone: 6.1
Component: admin Version: 6
Severity: normal Keywords: i386 clock
Cc: Blocked By:
Blocking:

Description

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)))
      break;
    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.

Change History (2)

comment:1 Changed on 06/11/21 at 06:32:17 by Jan Sommer

Owner: set to Jan Sommer
Status: newaccepted

comment:2 Changed on 06/21/21 at 08:11:43 by Jan Sommer <jan.sommer@…>

Resolution: fixed
Status: acceptedclosed

In 93f9645/rtems:

bsps/i386: Update calibration of TSC to be more accurate

Closes #4455

Note: See TracTickets for help on using tickets.