arch: arm: add CPU global time

Message ID 20170608034656.106575-1-brian.brooks@arm.com
State Accepted
Commit 0d24adacfe17c8e0e1348f19cd8b75b64cb13ccf
Headers show

Commit Message

Brian Brooks June 8, 2017, 3:46 a.m.
Expose ARMv8 Generic Timer through internal CPU global time functions.

Signed-off-by: Brian Brooks <brian.brooks@arm.com>


---

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

-- 
2.13.0

Comments

Bill Fischofer June 8, 2017, 4:04 a.m. | #1
On Wed, Jun 7, 2017 at 10:46 PM, Brian Brooks <brian.brooks@arm.com> wrote:
> Expose ARMv8 Generic Timer through internal CPU global time functions.

>

> Signed-off-by: Brian Brooks <brian.brooks@arm.com>


Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>


>

> ---

>

> 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

>
Maxim Uvarov June 20, 2017, 7:29 p.m. | #2
Merged,
Maxim.

On 06/08/17 07:04, Bill Fischofer wrote:
> On Wed, Jun 7, 2017 at 10:46 PM, Brian Brooks <brian.brooks@arm.com> wrote:

>> Expose ARMv8 Generic Timer through internal CPU global time functions.

>>

>> Signed-off-by: Brian Brooks <brian.brooks@arm.com>

> 

> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org>

> 

>>

>> ---

>>

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

>>

Patch hide | download patch | download mbox

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
 }