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