[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCHv6 13/37] plat/common: Add counter workaround for Cortex-A73 erratum 858921
Reviewed-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx> On 14.09.2018 09:56, Wei Chen wrote: The errata #858921 describes that Cortex-A73 (r0p0 - r0p2) counter read can return a wrong value when the counter crosses a 32bit boundary, but newer Cortex-A73 are not affected. The workaround involves performing the read twice, compare bit[32] of the two read values. If bit[32] is different, keep the first value, otherwise keep the second value. Signed-off-by: Wei Chen <wei.chen@xxxxxxx> --- arch/arm/arm64/Config.uk | 8 ++++++++ plat/common/arm/time.c | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/arch/arm/arm64/Config.uk b/arch/arm/arm64/Config.uk index 7797516..8c20e68 100644 --- a/arch/arm/arm64/Config.uk +++ b/arch/arm/arm64/Config.uk @@ -46,3 +46,11 @@ config MARCH_ARM64_CORTEXA75 Compile for Armv8.2 Cortex-A75 (and compatible) CPUsendchoice+ +config ARM64_ERRATUM_858921 + bool "Workaround for Cortex-A73 erratum 858921" + default y + help + This option enables a workaround for Cortex-A73 (r0p0 - r0p2), + whose counter may return a wrong value when the counter crosses + a 32-bit boundary. The newer Cortex-A73 are not affected. diff --git a/plat/common/arm/time.c b/plat/common/arm/time.c index a84e1a5..93b0521 100644 --- a/plat/common/arm/time.c +++ b/plat/common/arm/time.c @@ -63,10 +63,30 @@ static inline uint32_t get_counter_frequency(void) return SYSREG_READ32(cntfrq_el0); }+#ifdef CONFIG_ARM64_ERRATUM_858921+/* + * The errata #858921 describes that Cortex-A73 (r0p0 - r0p2) counter + * read can return a wrong value when the counter crosses a 32bit boundary. + * But newer Cortex-A73 are not affected. + * + * The workaround involves performing the read twice, compare bit[32] of + * the two read values. If bit[32] is different, keep the first value, + * otherwise keep the second value. + */ +static uint64_t read_virtual_count(void) +{ + uint64_t val_1st, val_2nd; + + val_1st = SYSREG_READ64(cntvct_el0); + val_2nd = SYSREG_READ64(cntvct_el0); + return (((val_1st ^ val_2nd) >> 32) & 1) ? val_1st : val_2nd; +} +#else static inline uint64_t read_virtual_count(void) { return SYSREG_READ64(cntvct_el0); } +#endif/** monotonic_clock(): returns # of nanoseconds passed since _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |