From c720e9eee4429a6436b1d34fcd98977f37e19b78 Mon Sep 17 00:00:00 2001 From: chao an Date: Thu, 19 Sep 2024 08:32:35 +0800 Subject: [PATCH] arm/cortex-a,r: replace cp15 instruct to macros align operation This is continue work of https://github.com/apache/nuttx/pull/13486 Discussion here: https://github.com/apache/nuttx/pull/13486#discussion_r1764354675 1. move cp15.h to arch public 2. replace cp15 instruct to macros align operation 3. add memory barrier to avoid compiler optimization Signed-off-by: chao an --- arch/arm/{src => include}/armv7-a/barriers.h | 2 +- arch/arm/{src => include}/armv7-a/cp15.h | 2 +- arch/arm/include/armv7-a/irq.h | 26 ++++-------- arch/arm/{src => include}/armv7-r/barriers.h | 2 +- arch/arm/{src => include}/armv7-r/cp15.h | 2 +- arch/arm/include/armv7-r/irq.h | 43 +++++++++++--------- arch/arm/{src => include}/armv8-r/barriers.h | 2 +- arch/arm/{src => include}/armv8-r/cp15.h | 2 +- arch/arm/include/armv8-r/irq.h | 43 +++++++++++--------- arch/arm/src/Makefile | 9 ++-- 10 files changed, 68 insertions(+), 65 deletions(-) rename arch/arm/{src => include}/armv7-a/barriers.h (98%) rename arch/arm/{src => include}/armv7-a/cp15.h (99%) rename arch/arm/{src => include}/armv7-r/barriers.h (98%) rename arch/arm/{src => include}/armv7-r/cp15.h (99%) rename arch/arm/{src => include}/armv8-r/barriers.h (98%) rename arch/arm/{src => include}/armv8-r/cp15.h (99%) diff --git a/arch/arm/src/armv7-a/barriers.h b/arch/arm/include/armv7-a/barriers.h similarity index 98% rename from arch/arm/src/armv7-a/barriers.h rename to arch/arm/include/armv7-a/barriers.h index 2258e4110f57d..0251cec7fe397 100644 --- a/arch/arm/src/armv7-a/barriers.h +++ b/arch/arm/include/armv7-a/barriers.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv7-a/barriers.h + * arch/arm/include/armv7-a/barriers.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/arm/src/armv7-a/cp15.h b/arch/arm/include/armv7-a/cp15.h similarity index 99% rename from arch/arm/src/armv7-a/cp15.h rename to arch/arm/include/armv7-a/cp15.h index f1258091922a4..9c15c2cad5c24 100644 --- a/arch/arm/src/armv7-a/cp15.h +++ b/arch/arm/include/armv7-a/cp15.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv7-a/cp15.h + * arch/arm/include/armv7-a/cp15.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index c7876f5f4f3d9..701a77e7e1888 100644 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -36,6 +36,9 @@ # include #endif +#include "cp15.h" +#include "barriers.h" + /**************************************************************************** * Pre-processor Prototypes ****************************************************************************/ @@ -457,11 +460,8 @@ static inline_function int up_cpu_index(void) /* Read the Multiprocessor Affinity Register (MPIDR) */ - __asm__ __volatile__ - ( - "mrc " "p15, " "0" ", %0, " "c0" ", " "c0" ", " "5" "\n" - : "=r"(mpidr) - ); + ARM_ISB(); + mpidr = CP15_GET(MPIDR); /* And return the CPU ID field */ @@ -500,23 +500,15 @@ static inline_function uint32_t up_getsp(void) noinstrument_function static inline_function uint32_t *up_current_regs(void) { - uint32_t *regs; - __asm__ __volatile__ - ( - "mrc " "p15, " "0" ", %0, " "c13" ", " "c0" ", " "4" "\n" - : "=r"(regs) - ); - return regs; + ARM_ISB(); + return (uint32_t *)CP15_GET(TPIDRPRW); } noinstrument_function static inline_function void up_set_current_regs(uint32_t *regs) { - __asm__ __volatile__ - ( - "mcr " "p15, " "0" ", %0, " "c13" ", " "c0" ", " "4" "\n" - :: "r"(regs) - ); + CP15_SET(TPIDRPRW, regs); + ARM_ISB(); } noinstrument_function diff --git a/arch/arm/src/armv7-r/barriers.h b/arch/arm/include/armv7-r/barriers.h similarity index 98% rename from arch/arm/src/armv7-r/barriers.h rename to arch/arm/include/armv7-r/barriers.h index 71005f4a4dff9..dab5c1560a113 100644 --- a/arch/arm/src/armv7-r/barriers.h +++ b/arch/arm/include/armv7-r/barriers.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv7-r/barriers.h + * arch/arm/include/armv7-r/barriers.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/arm/src/armv7-r/cp15.h b/arch/arm/include/armv7-r/cp15.h similarity index 99% rename from arch/arm/src/armv7-r/cp15.h rename to arch/arm/include/armv7-r/cp15.h index f91c65450448e..4be2acf3f6cab 100644 --- a/arch/arm/src/armv7-r/cp15.h +++ b/arch/arm/include/armv7-r/cp15.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv7-r/cp15.h + * arch/arm/include/armv7-r/cp15.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/arm/include/armv7-r/irq.h b/arch/arm/include/armv7-r/irq.h index 1b6d6e1b46131..b555ef79a8adc 100644 --- a/arch/arm/include/armv7-r/irq.h +++ b/arch/arm/include/armv7-r/irq.h @@ -36,6 +36,9 @@ # include #endif +#include "cp15.h" +#include "barriers.h" + /**************************************************************************** * Pre-processor Prototypes ****************************************************************************/ @@ -357,7 +360,7 @@ static inline irqstate_t irqstate(void) /* Disable IRQs and return the previous IRQ state */ -static inline irqstate_t up_irq_save(void) +noinstrument_function static inline irqstate_t up_irq_save(void) { unsigned int cpsr; @@ -417,7 +420,7 @@ static inline irqstate_t up_irq_disable(void) /* Restore saved IRQ & FIQ state */ -static inline void up_irq_restore(irqstate_t flags) +noinstrument_function static inline void up_irq_restore(irqstate_t flags) { __asm__ __volatile__ ( @@ -452,11 +455,8 @@ static inline_function int up_cpu_index(void) /* Read the Multiprocessor Affinity Register (MPIDR) */ - __asm__ __volatile__ - ( - "mrc " "p15, " "0" ", %0, " "c0" ", " "c0" ", " "5" "\n" - : "=r"(mpidr) - ); + ARM_ISB(); + mpidr = CP15_GET(MPIDR); /* And return the CPU ID field */ @@ -479,26 +479,31 @@ static inline_function uint32_t up_getsp(void) return sp; } +/**************************************************************************** + * Name: + * up_current_regs/up_set_current_regs + * + * Description: + * We use the following code to manipulate the TPIDRPRW register, + * which exists uniquely for each CPU and is primarily designed to store + * current thread information. Currently, we leverage it to store interrupt + * information, with plans to further optimize its use for storing both + * thread and interrupt information in the future. + * + ****************************************************************************/ + noinstrument_function static inline_function uint32_t *up_current_regs(void) { - uint32_t *regs; - __asm__ __volatile__ - ( - "mrc " "p15, " "0" ", %0, " "c13" ", " "c0" ", " "4" "\n" - : "=r"(regs) - ); - return regs; + ARM_ISB(); + return (uint32_t *)CP15_GET(TPIDRPRW); } noinstrument_function static inline_function void up_set_current_regs(uint32_t *regs) { - __asm__ __volatile__ - ( - "mcr " "p15, " "0" ", %0, " "c13" ", " "c0" ", " "4" "\n" - :: "r"(regs) - ); + CP15_SET(TPIDRPRW, regs); + ARM_ISB(); } noinstrument_function diff --git a/arch/arm/src/armv8-r/barriers.h b/arch/arm/include/armv8-r/barriers.h similarity index 98% rename from arch/arm/src/armv8-r/barriers.h rename to arch/arm/include/armv8-r/barriers.h index 7e542eb99d7a4..9f407bcd651d3 100644 --- a/arch/arm/src/armv8-r/barriers.h +++ b/arch/arm/include/armv8-r/barriers.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv8-r/barriers.h + * arch/arm/include/armv8-r/barriers.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/arm/src/armv8-r/cp15.h b/arch/arm/include/armv8-r/cp15.h similarity index 99% rename from arch/arm/src/armv8-r/cp15.h rename to arch/arm/include/armv8-r/cp15.h index 40c4717865717..a0c8a6c16eea7 100644 --- a/arch/arm/src/armv8-r/cp15.h +++ b/arch/arm/include/armv8-r/cp15.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/armv8-r/cp15.h + * arch/arm/include/armv8-r/cp15.h * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/arch/arm/include/armv8-r/irq.h b/arch/arm/include/armv8-r/irq.h index 53fb064d84db3..082915ab201b5 100644 --- a/arch/arm/include/armv8-r/irq.h +++ b/arch/arm/include/armv8-r/irq.h @@ -36,6 +36,9 @@ # include #endif +#include "cp15.h" +#include "barriers.h" + /**************************************************************************** * Pre-processor Prototypes ****************************************************************************/ @@ -357,7 +360,7 @@ static inline irqstate_t irqstate(void) /* Disable IRQs and return the previous IRQ state */ -static inline irqstate_t up_irq_save(void) +noinstrument_function static inline irqstate_t up_irq_save(void) { unsigned int cpsr; @@ -417,7 +420,7 @@ static inline irqstate_t up_irq_disable(void) /* Restore saved IRQ & FIQ state */ -static inline void up_irq_restore(irqstate_t flags) +noinstrument_function static inline void up_irq_restore(irqstate_t flags) { __asm__ __volatile__ ( @@ -452,11 +455,8 @@ static inline_function int up_cpu_index(void) /* Read the Multiprocessor Affinity Register (MPIDR) */ - __asm__ __volatile__ - ( - "mrc " "p15, " "0" ", %0, " "c0" ", " "c0" ", " "5" "\n" - : "=r"(mpidr) - ); + ARM_ISB(); + mpidr = CP15_GET(MPIDR); /* And return the CPU ID field */ @@ -479,26 +479,31 @@ static inline_function uint32_t up_getsp(void) return sp; } +/**************************************************************************** + * Name: + * up_current_regs/up_set_current_regs + * + * Description: + * We use the following code to manipulate the TPIDRPRW register, + * which exists uniquely for each CPU and is primarily designed to store + * current thread information. Currently, we leverage it to store interrupt + * information, with plans to further optimize its use for storing both + * thread and interrupt information in the future. + * + ****************************************************************************/ + noinstrument_function static inline_function uint32_t *up_current_regs(void) { - uint32_t *regs; - __asm__ __volatile__ - ( - "mrc " "p15, " "0" ", %0, " "c13" ", " "c0" ", " "4" "\n" - : "=r"(regs) - ); - return regs; + ARM_ISB(); + return (uint32_t *)CP15_GET(TPIDRPRW); } noinstrument_function static inline_function void up_set_current_regs(uint32_t *regs) { - __asm__ __volatile__ - ( - "mcr " "p15, " "0" ", %0, " "c13" ", " "c0" ", " "4" "\n" - :: "r"(regs) - ); + CP15_SET(TPIDRPRW, regs); + ARM_ISB(); } noinstrument_function diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile index becb8a00f1a36..6d8d90807fa68 100644 --- a/arch/arm/src/Makefile +++ b/arch/arm/src/Makefile @@ -37,11 +37,12 @@ else # ARM9, ARM7TDMI, etc. ARCH_SUBDIR = arm endif -ARCH_SRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src +ARCH_SRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH) -INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)chip -INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)common -INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)$(ARCH_SUBDIR) +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)src$(DELIM)chip +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)src$(DELIM)common +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)src$(DELIM)$(ARCH_SUBDIR) +INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)include$(DELIM)$(ARCH_SUBDIR) INCLUDES += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)sched CPPFLAGS += $(INCLUDES)