Changeset 4925ab4 in rtems


Ignore:
Timestamp:
Jun 11, 2021, 7:35:30 AM (7 weeks ago)
Author:
Jan Sommer <jan.sommer@…>
Branches:
5
Children:
e5a1b15
Parents:
8d4382b
git-author:
Jan Sommer <jan.sommer@…> (06/11/21 07:35:30)
git-committer:
Jan Sommer <jan.sommer@…> (06/21/21 08:13:37)
Message:

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

Closes #4456

File:
1 edited

Legend:

Unmodified
Added
Removed
  • bsps/i386/pc386/clock/ckinit.c

    r8d4382b r4925ab4  
    105105/*
    106106 * Calibrate CPU cycles per tick. Interrupts should be disabled.
     107 * Will also set the PIT, so call this before registering the
     108 * periodic timer for rtems tick generation
    107109 */
    108110static void calibrate_tsc(void)
    109111{
    110112  uint64_t              begin_time;
    111   uint8_t               then_lsb, then_msb, now_lsb, now_msb;
    112   uint32_t              i;
     113  uint8_t               lsb, msb;
     114  uint32_t              max_timer_value;
     115  uint32_t              last_tick, cur_tick;
     116  int32_t               diff, remaining;
     117
     118  /* Set the timer to free running mode */
     119  outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_INTTC);
     120  /* Reset the 16 timer reload value, first LSB, then MSB */
     121  outport_byte(TIMER_CNTR0, 0);
     122  outport_byte(TIMER_CNTR0, 0);
     123  /* We use the full 16 bit */
     124  max_timer_value = 0xffff;
     125  /* Calibrate for 1s, i.e. TIMER_TICK PIT ticks */
     126  remaining = TIMER_TICK;
     127
     128  begin_time = rdtsc();
     129  READ_8254(lsb, msb);
     130  last_tick = (msb << 8) | lsb;
     131  while(remaining > 0) {
     132    READ_8254(lsb, msb);
     133    cur_tick = (msb << 8) | lsb;
     134    /* PIT counts down, so subtract cur from last */
     135    diff = last_tick - cur_tick;
     136    last_tick = cur_tick;
     137    if (diff < 0) {
     138        diff += max_timer_value;
     139    }
     140    remaining -= diff;
     141  }
     142
     143  pc586_tsc_frequency = rdtsc() - begin_time;
     144
     145#if 0
     146  printk( "CPU clock at %u Hz\n", (uint32_t)(pc586_tsc_frequency ));
     147#endif
     148}
     149
     150static void clockOn(void)
     151{
    113152
    114153  /*
    115    * We just reset the timer, so we know we're at the beginning of a tick.
     154   * First calibrate the TSC. Do this every time we
     155   * turn the clock on in case the CPU clock speed has changed.
    116156   */
    117 
    118   /*
    119    * Count cycles. Watching the timer introduces a several microsecond
    120    * uncertaintity, so let it cook for a while and divide by the number of
    121    * ticks actually executed.
    122    */
    123 
    124   begin_time = rdtsc();
    125 
    126   for (i = rtems_clock_get_ticks_per_second() * pc386_isrs_per_tick;
    127        i != 0; --i ) {
    128     /* We know we've just completed a tick when timer goes from low to high */
    129     then_lsb = then_msb = 0xff;
    130     do {
    131       READ_8254(now_lsb, now_msb);
    132       if ((then_msb < now_msb) ||
    133           ((then_msb == now_msb) && (then_lsb < now_lsb)))
    134         break;
    135       then_lsb = now_lsb;
    136       then_msb = now_msb;
    137     } while (1);
    138   }
    139 
    140   pc586_tsc_frequency = rdtsc() - begin_time;
    141 
    142 #if 0
    143   printk( "CPU clock at %u MHz\n", (uint32_t)(pc586_tsc_frequency / 1000000));
    144 #endif
    145 }
    146 
    147 static void clockOn(void)
    148 {
     157  if ( x86_has_tsc() ) {
     158    calibrate_tsc();
     159  }
     160
    149161  rtems_interrupt_lock_context lock_context;
    150162  pc386_isrs_per_tick        = 1;
     
    172184
    173185  bsp_interrupt_vector_enable( BSP_PERIODIC_TIMER );
    174 
    175   /*
    176    * Now calibrate cycles per tick. Do this every time we
    177    * turn the clock on in case the CPU clock speed has changed.
    178    */
    179   if ( x86_has_tsc() )
    180     calibrate_tsc();
    181186}
    182187
Note: See TracChangeset for help on using the changeset viewer.