X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..c6bf4f310a33a9262d455ea4d3f0630b1255e3fe:/libsyscall/wrappers/mach_approximate_time.s diff --git a/libsyscall/wrappers/mach_approximate_time.s b/libsyscall/wrappers/mach_approximate_time.s index 7ef3336f7..f1e6ed871 100644 --- a/libsyscall/wrappers/mach_approximate_time.s +++ b/libsyscall/wrappers/mach_approximate_time.s @@ -29,7 +29,45 @@ #include #include -#if defined(__i386__) +#if defined(__arm__) + + .text + .align 2 + .globl _mach_approximate_time +_mach_approximate_time: + + movw r0, #((_COMM_PAGE_APPROX_TIME_SUPPORTED>>0)&0x0FFFF) + movt r0, #((_COMM_PAGE_APPROX_TIME_SUPPORTED>>16)&0x0FFFF) + ldrb r0, [r0] // load COMM_PAGE_APPROX_TIME_SUPPORTED + cmp r0, #1 // check if approx time is supported + + bne _mach_absolute_time // if not supported, fall through to + // absolute_time + + movw r2, #((_COMM_PAGE_APPROX_TIME>>0)&0x0FFFF) + movt r2, #((_COMM_PAGE_APPROX_TIME>>16)&0x0FFFF) + + // at this point, r2->COMM_PAGE_APPROX_TIME, which is a 64-bit value. + // Since this is a 32-bit architecture, and the commpage is readonly, + // there is no "guaranteed" atomic way to read all 64-bits with + // hardware protection. Even the ldrd instruction is not guaranteed to + // complete atomically. The solution is to use a 32-bit high/low/high + // read with a consistency check on the high bits. To further + // complicate things, reading the same location in memory back to back + // could trigger a predictive read, which would defeat the purpose of + // doing the consistency check so we insert a data memory barrier to + // prevent this. +_consistency_check: + ldr r1, [r2,#4] // load high + ldr r0, [r2] // load low + dsb // avoid predictive reads that could + // be invalid if interrupted + ldr r3, [r2,#4] // load high again + cmp r1, r3 // check that high1 == high2 + bne _consistency_check // try again if not + bx lr + +#elif defined(__i386__) .text .align 4, 0x90