diff options
author | Jack Lloyd <[email protected]> | 2018-03-06 08:01:34 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-03-06 08:01:34 -0500 |
commit | d96477e0c2239ec7a8ef721333be1e2e70e1abef (patch) | |
tree | c95b502cdd7b31e47ef39bd08b0ea30233ee41f1 /src/lib/utils | |
parent | d1c861c280d973990c25996ab8558e784283325b (diff) |
Correctly read the POWER cycle counter
The upper register can overflow so we need to re-read the upper
register to ensure we we not on a boundary.
GH #1460
Diffstat (limited to 'src/lib/utils')
-rw-r--r-- | src/lib/utils/os_utils.cpp | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp index b8c31234a..769615543 100644 --- a/src/lib/utils/os_utils.cpp +++ b/src/lib/utils/os_utils.cpp @@ -95,16 +95,19 @@ uint64_t OS::get_processor_timestamp() } #elif defined(BOTAN_TARGET_ARCH_IS_PPC64) - uint32_t rtc_low = 0, rtc_high = 0; - asm volatile("mftbu %0; mftb %1" : "=r" (rtc_high), "=r" (rtc_low)); - /* - qemu-ppc seems to not support mftb instr, it always returns zero. - If both time bases are 0, assume broken and return another clock. - */ - if(rtc_high > 0 || rtc_low > 0) + for(;;) { - rtc = (static_cast<uint64_t>(rtc_high) << 32) | rtc_low; + uint32_t rtc_low = 0, rtc_high = 0, rtc_high2 = 0; + asm volatile("mftbu %0" : "=r" (rtc_high)); + asm volatile("mftb %0" : "=r" (rtc_low)); + asm volatile("mftbu %0" : "=r" (rtc_high2)); + + if(rtc_high == rtc_high2) + { + rtc = (static_cast<uint64_t>(rtc_high) << 32) | rtc_low; + break; + } } #elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) |