Changeset d11b711 in rtems


Ignore:
Timestamp:
Jan 28, 2015, 4:04:26 AM (5 years ago)
Author:
Nick Withers <nick.withers@…>
Branches:
4.11, master
Children:
ead010c
Parents:
40d062f5
git-author:
Nick Withers <nick.withers@…> (01/28/15 04:04:26)
git-committer:
Sebastian Huber <sebastian.huber@…> (01/30/15 05:57:00)
Message:

bsps/powerpc: Fix a clock driver

PowerPC Book E: Account for an extra tick period if a tick increment's
pending.

Close #2230.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c

    r40d062f5 rd11b711  
    4747 *  This is the value programmed into the count down timer.
    4848 */
    49 uint32_t   Clock_Decrementer_value;
     49static uint32_t   Clock_Decrementer_value;
     50
     51/*
     52 *  This is the value by which elapsed count down timer ticks are multiplied to
     53 *  give an elapsed duration in nanoseconds, left-shifted by 32 bits
     54 */
     55static uint64_t   Clock_Decrementer_reference;
    5056
    5157void clockOff(void* unused)
     
    210216}
    211217
     218static uint32_t Clock_driver_nanoseconds_since_last_tick_bookE(void)
     219{
     220  uint32_t clicks;
     221  uint64_t c;
     222
     223  PPC_Get_decrementer( clicks );
     224  c = Clock_Decrementer_value - clicks;
     225
     226  /*
     227   * Check whether a clock tick interrupt is pending and hence that the
     228   * decrementer's wrapped. If it has, we'll compensate by returning a time one
     229   * tick period longer.
     230   *
     231   * We have to check interrupt status after reading the decrementer. If we
     232   * don't, we may miss an interrupt and read a wrapped decrementer value
     233   * without compensating for it
     234   */
     235  if ( _read_BOOKE_TSR() & BOOKE_TSR_DIS )
     236  {
     237    /*
     238     * Re-read the decrementer: The tick interrupt may have been
     239     * generated and the decrementer wrapped during the time since we
     240     * last read it and the time we checked the interrupt status
     241     */
     242    PPC_Get_decrementer( clicks );
     243    c = (Clock_Decrementer_value - clicks) + Clock_Decrementer_value;
     244  }
     245
     246  return (uint32_t)((c * Clock_Decrementer_reference) >> 32);
     247}
     248
    212249/*
    213250 *  Clock_initialize
     
    224261
    225262  Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)*
    226             (rtems_configuration_get_microseconds_per_tick()/1000);
     263            rtems_configuration_get_milliseconds_per_tick();
     264
     265  Clock_Decrementer_reference = ((uint64_t)1000000U<<32)/
     266            (BSP_bus_frequency/BSP_time_base_divisor);
    227267
    228268  /* set the decrementer now, prior to installing the handler
     
    245285    rtems_interrupt_enable(l);
    246286
    247   }
    248 
    249   /*
    250    *  Set the nanoseconds since last tick handler
    251    */
    252   rtems_clock_set_nanoseconds_extension(
    253     Clock_driver_nanoseconds_since_last_tick
    254   );
     287    /*
     288     *  Set the nanoseconds since last tick handler
     289     */
     290    rtems_clock_set_nanoseconds_extension(
     291      Clock_driver_nanoseconds_since_last_tick_bookE
     292    );
     293  }
     294  else
     295  {
     296    /*
     297     *  Set the nanoseconds since last tick handler
     298     */
     299    rtems_clock_set_nanoseconds_extension(
     300      Clock_driver_nanoseconds_since_last_tick
     301    );
     302  }
    255303
    256304  /*
Note: See TracChangeset for help on using the changeset viewer.