Expose ARMv8 Generic Timer through internal CPU global time functions.

Signed-off-by: Brian Brooks <[email protected]>

---

v2:
 - Add text to explain the usage of the ARM architected timer (Petri)


 platform/linux-generic/arch/arm/odp_cpu_arch.c | 38 +++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/platform/linux-generic/arch/arm/odp_cpu_arch.c 
b/platform/linux-generic/arch/arm/odp_cpu_arch.c
index c31f9084..91d439d9 100644
--- a/platform/linux-generic/arch/arm/odp_cpu_arch.c
+++ b/platform/linux-generic/arch/arm/odp_cpu_arch.c
@@ -50,15 +50,51 @@ uint64_t odp_cpu_cycles_resolution(void)
 
 int cpu_has_global_time(void)
 {
-       return 0;
+       uint64_t hz = cpu_global_time_freq();
+
+       /*
+        * The system counter portion of the architected timer must
+        * provide a uniform view of system time to all processing
+        * elements in the system. This should hold true even for
+        * heterogeneous SoCs.
+        *
+        * Determine whether the system has 'global time' by checking
+        * whether a read of the architected timer frequency sys reg
+        * returns a sane value. Sane is considered to be within
+        * 1MHz and 6GHz (1us and .1667ns period).
+        */
+       return hz >= 1000000 && hz <= 6000000000;
 }
 
 uint64_t cpu_global_time(void)
 {
+#if __ARM_ARCH == 8
+       uint64_t cntvct;
+
+       /*
+        * To be consistent with other architectures, do not issue a
+        * serializing instruction, e.g. ISB, before reading this
+        * sys reg.
+        */
+
+       /* Memory clobber to minimize optimization around load from sys reg. */
+       __asm__ volatile("mrs %0, cntvct_el0" : "=r"(cntvct) : : "memory");
+
+       return cntvct;
+#else
        return 0;
+#endif
 }
 
 uint64_t cpu_global_time_freq(void)
 {
+#if __ARM_ARCH == 8
+       uint64_t cntfrq;
+
+       __asm__ volatile("mrs %0, cntfrq_el0" : "=r"(cntfrq) : : );
+
+       return cntfrq;
+#else
        return 0;
+#endif
 }
-- 
2.13.0

Reply via email to