Changeset 878

Show
Ignore:
Timestamp:
02/19/08 13:26:27 (13 years ago)
Author:
ppalmers
Message:

fix nonmonotonic CTR reads (occurs on NEC card)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libffado/src/libieee1394/CycleTimerHelper.cpp

    r866 r878  
    6565    , m_first_run ( true ) 
    6666    , m_sleep_until ( 0 ) 
     67    , m_cycle_timer_prev ( 0 ) 
     68    , m_cycle_timer_ticks_prev ( 0 ) 
    6769    , m_Thread ( NULL ) 
    6870    , m_realtime ( false ) 
     
    8486    , m_first_run ( true ) 
    8587    , m_sleep_until ( 0 ) 
     88    , m_cycle_timer_prev ( 0 ) 
     89    , m_cycle_timer_ticks_prev ( 0 ) 
    8690    , m_Thread ( NULL ) 
    8791    , m_realtime ( rt ) 
     
    323327    return true; 
    324328} 
     329 
    325330uint32_t 
    326331CycleTimerHelper::getCycleTimerTicks() 
    327332{ 
     333    return CYCLE_TIMER_TO_TICKS(getCycleTimer()); 
     334} 
     335 
     336uint32_t 
     337CycleTimerHelper::getCycleTimerTicks(uint64_t now) 
     338{ 
     339    debugWarning("not implemented!\n"); 
     340    return getCycleTimerTicks(); 
     341} 
     342 
     343uint32_t 
     344CycleTimerHelper::getCycleTimer() 
     345{ 
     346    bool good=false; 
     347    int maxtries = 10; 
    328348    uint32_t cycle_timer; 
    329349    uint64_t local_time; 
    330     if(!m_Parent.readCycleTimerReg(&cycle_timer, &local_time)) { 
    331         debugError("Could not read cycle timer register\n"); 
    332         return 0; 
    333     } 
    334     return CYCLE_TIMER_TO_TICKS(cycle_timer); 
    335 
    336  
    337 uint32_t 
    338 CycleTimerHelper::getCycleTimerTicks(uint64_t now) 
    339 
    340     debugWarning("not implemented!\n"); 
    341     return getCycleTimerTicks(); 
    342 
    343  
    344 uint32_t 
    345 CycleTimerHelper::getCycleTimer() 
    346 
    347     uint32_t cycle_timer; 
    348     uint64_t local_time; 
    349     if(!m_Parent.readCycleTimerReg(&cycle_timer, &local_time)) { 
    350         debugError("Could not read cycle timer register\n"); 
    351         return 0; 
    352     } 
     350     
     351    do { 
     352        // the ctr read can return 0 sometimes. if that happens, reread the ctr. 
     353        int maxtries2=10; 
     354        do { 
     355            if(!m_Parent.readCycleTimerReg(&cycle_timer, &local_time)) { 
     356                debugError("Could not read cycle timer register\n"); 
     357                return 0; 
     358            } 
     359            if (cycle_timer == 0) { 
     360                debugOutput(DEBUG_LEVEL_VERBOSE, 
     361                           "Bogus CTR: %08X on try %02d\n", 
     362                           cycle_timer, maxtries2); 
     363            } 
     364        } while (cycle_timer == 0 && maxtries2--); 
     365         
     366        // catch bogus ctr reads (can happen) 
     367        uint64_t cycle_timer_ticks = CYCLE_TIMER_TO_TICKS(cycle_timer); 
     368     
     369        if (diffTicks(cycle_timer_ticks, m_cycle_timer_ticks_prev) < 0) { 
     370            debugOutput( DEBUG_LEVEL_VERBOSE, 
     371                        "non-monotonic CTR (try %02d): %llu -> %llu\n", 
     372                        maxtries, m_cycle_timer_ticks_prev, cycle_timer_ticks); 
     373            debugOutput( DEBUG_LEVEL_VERBOSE, 
     374                        "                            : %08X -> %08X\n", 
     375                        m_cycle_timer_prev, cycle_timer); 
     376            debugOutput( DEBUG_LEVEL_VERBOSE, 
     377                        " current: %011llu (%03us %04ucy %04uticks)\n", 
     378                        cycle_timer_ticks, 
     379                        (unsigned int)TICKS_TO_SECS( cycle_timer_ticks ), 
     380                        (unsigned int)TICKS_TO_CYCLES( cycle_timer_ticks ), 
     381                        (unsigned int)TICKS_TO_OFFSET( cycle_timer_ticks ) ); 
     382            debugOutput( DEBUG_LEVEL_VERBOSE, 
     383                        " prev   : %011llu (%03us %04ucy %04uticks)\n", 
     384                        m_cycle_timer_ticks_prev, 
     385                        (unsigned int)TICKS_TO_SECS( m_cycle_timer_ticks_prev ), 
     386                        (unsigned int)TICKS_TO_CYCLES( m_cycle_timer_ticks_prev ), 
     387                        (unsigned int)TICKS_TO_OFFSET( m_cycle_timer_ticks_prev ) ); 
     388        } else { 
     389            good = true; 
     390            m_cycle_timer_prev = cycle_timer; 
     391            m_cycle_timer_ticks_prev = cycle_timer_ticks; 
     392        } 
     393    } while (!good && maxtries--); 
    353394    return cycle_timer; 
    354395} 
  • trunk/libffado/src/libieee1394/CycleTimerHelper.h

    r864 r878  
    119119    ffado_microsecs_t m_sleep_until; 
    120120 
     121    uint32_t m_cycle_timer_prev; 
     122    uint32_t m_cycle_timer_ticks_prev; 
     123 
    121124    // cached vars used for computation 
    122125    struct compute_vars {