From 0d020822ae88b8623fa6c9c55973f0045194dcef Mon Sep 17 00:00:00 2001 From: Boyan Karatotev Date: Tue, 19 Nov 2024 11:27:01 +0000 Subject: [PATCH] perf(cpus): inline the reset function Similar to the cpu_rev_var and cpu_ger_rev_var functions, inline the call_reset_handler handler. This way we skip the costly branch at no extra cost as this is the only place where this is called. While we're at it, drop the options for CPU_NO_RESET_FUNC. The only cpus that need that are virtual cpus which can spare the tiny bit of performance lost. The rest are real cores which can save on the check for zero. Now is a good time to put the assert for a missing cpu in the get_cpu_ops_ptr function so that it's a bit better encapsulated. Change-Id: Ia7c3dcd13b75e5d7c8bafad4698994ea65f42406 Signed-off-by: Boyan Karatotev --- docs/design/firmware-design.rst | 6 +-- include/arch/aarch64/asm_macros.S | 23 +++++++++++ include/arch/aarch64/el2_common_macros.S | 4 +- include/arch/aarch64/el3_common_macros.S | 12 +----- include/lib/cpus/aarch32/cpu_macros.S | 5 +-- include/lib/cpus/aarch64/cpu_macros.S | 3 +- include/lib/cpus/cpu_ops.h | 2 - lib/cpus/aarch32/aem_generic.S | 7 +++- lib/cpus/aarch64/a64fx.S | 5 ++- lib/cpus/aarch64/aem_generic.S | 9 +++-- lib/cpus/aarch64/cpu_helpers.S | 49 ++++-------------------- lib/cpus/aarch64/generic.S | 4 +- lib/cpus/aarch64/qemu_max.S | 7 +++- 13 files changed, 64 insertions(+), 72 deletions(-) diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index cda80ca4c..975c1f2fa 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -247,7 +247,7 @@ BL1 performs minimal architectural initialization as follows. - CPU initialization - BL1 calls the ``reset_handler()`` function which in turn calls the CPU + BL1 calls the ``reset_handler`` macro/function which in turn calls the CPU specific reset handler function (see the section: "CPU specific operations framework"). @@ -1337,7 +1337,7 @@ Guidelines for Reset Handlers TF-A implements a framework that allows CPU and platform ports to perform actions very early after a CPU is released from reset in both the cold and warm -boot paths. This is done by calling the ``reset_handler()`` function in both +boot paths. This is done by calling the ``reset_handler`` macro/function in both the BL1 and BL31 images. It in turn calls the platform and CPU specific reset handling functions. @@ -2904,7 +2904,7 @@ kernel at boot time. These can be found in the ``fdts`` directory. -------------- -*Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.* .. _SMCCC: https://developer.arm.com/docs/den0028/latest .. _PSCI: https://developer.arm.com/documentation/den0022/latest/ diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S index ff0127819..dce07d9c0 100644 --- a/include/arch/aarch64/asm_macros.S +++ b/include/arch/aarch64/asm_macros.S @@ -8,6 +8,7 @@ #include #include +#include #include /* @@ -340,4 +341,26 @@ mrs \reg, ID_AA64ISAR2_EL1 ands \reg, \reg, #(ID_AA64ISAR2_SYSREG128_MASK << ID_AA64ISAR2_SYSREG128_SHIFT) .endm + +.macro call_reset_handler +#if !(defined(IMAGE_BL2) && ENABLE_RME) + /* --------------------------------------------------------------------- + * It is a cold boot. + * Perform any processor specific actions upon reset e.g. cache, TLB + * invalidations etc. + * --------------------------------------------------------------------- + */ + /* The plat_reset_handler can clobber x0 - x18, x30 */ + bl plat_reset_handler + + /* Get the matching cpu_ops pointer */ + bl get_cpu_ops_ptr + + /* Get the cpu_ops reset handler */ + ldr x2, [x0, #CPU_RESET_FUNC] + + /* The cpu_ops reset handler can clobber x0 - x19, x30 */ + blr x2 +#endif +.endm #endif /* ASM_MACROS_S */ diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S index b9b0e3db6..5db683124 100644 --- a/include/arch/aarch64/el2_common_macros.S +++ b/include/arch/aarch64/el2_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -293,7 +293,7 @@ * invalidations etc. * --------------------------------------------------------------------- */ - bl reset_handler + call_reset_handler el2_arch_init_common diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 204625cee..fd16fb5cb 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -219,15 +219,7 @@ msr vbar_el3, x0 isb -#if !(defined(IMAGE_BL2) && ENABLE_RME) - /* --------------------------------------------------------------------- - * It is a cold boot. - * Perform any processor specific actions upon reset e.g. cache, TLB - * invalidations etc. - * --------------------------------------------------------------------- - */ - bl reset_handler -#endif + call_reset_handler el3_arch_init_common diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S index cfa5831fc..a878a5f60 100644 --- a/include/lib/cpus/aarch32/cpu_macros.S +++ b/include/lib/cpus/aarch32/cpu_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -48,8 +48,7 @@ * _midr: * Numeric value expected to read from CPU's MIDR * _resetfunc: - * Reset function for the CPU. If there's no CPU reset function, - * specify CPU_NO_RESET_FUNC + * Reset function for the CPU * _power_down_ops: * Comma-separated list of functions to perform power-down * operatios on the CPU. At least one, and up to diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S index 17592d349..c8f4bde25 100644 --- a/include/lib/cpus/aarch64/cpu_macros.S +++ b/include/lib/cpus/aarch64/cpu_macros.S @@ -49,8 +49,7 @@ * _midr: * Numeric value expected to read from CPU's MIDR * _resetfunc: - * Reset function for the CPU. If there's no CPU reset function, - * specify CPU_NO_RESET_FUNC + * Reset function for the CPU. * _extra1: * This is a placeholder for future per CPU operations. Currently, * some CPUs use this entry to set a test function to determine if diff --git a/include/lib/cpus/cpu_ops.h b/include/lib/cpus/cpu_ops.h index c1bdf8d01..0b08919f4 100644 --- a/include/lib/cpus/cpu_ops.h +++ b/include/lib/cpus/cpu_ops.h @@ -21,8 +21,6 @@ /* The number of CPU operations allowed */ #define CPU_MAX_PWR_DWN_OPS 2 -/* Special constant to specify that CPU has no reset function */ -#define CPU_NO_RESET_FUNC 0 #if __aarch64__ #define CPU_NO_EXTRA1_FUNC 0 diff --git a/lib/cpus/aarch32/aem_generic.S b/lib/cpus/aarch32/aem_generic.S index f4dc0d172..a42457534 100644 --- a/lib/cpus/aarch32/aem_generic.S +++ b/lib/cpus/aarch32/aem_generic.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,8 +40,11 @@ func aem_generic_cluster_pwr_dwn b dcsw_op_all endfunc aem_generic_cluster_pwr_dwn +func aem_generic_reset_func + bx lr +endfunc aem_generic_reset_func /* cpu_ops for Base AEM FVP */ -declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \ +declare_cpu_ops aem_generic, BASE_AEM_MIDR, aem_generic_reset_func, \ aem_generic_core_pwr_dwn, \ aem_generic_cluster_pwr_dwn diff --git a/lib/cpus/aarch64/a64fx.S b/lib/cpus/aarch64/a64fx.S index 4893a44d7..a53467aa1 100644 --- a/lib/cpus/aarch64/a64fx.S +++ b/lib/cpus/aarch64/a64fx.S @@ -29,12 +29,15 @@ endfunc a64fx_cluster_pwr_dwn a64fx_regs: /* The ascii list of register names to be reported */ .asciz "" +cpu_reset_func_start a64fx +cpu_reset_func_end a64fx + func a64fx_cpu_reg_dump adr x6, a64fx_regs ret endfunc a64fx_cpu_reg_dump -declare_cpu_ops a64fx, A64FX_MIDR, CPU_NO_RESET_FUNC \ +declare_cpu_ops a64fx, A64FX_MIDR, a64fx_reset_func \ a64fx_core_pwr_dwn, \ a64fx_cluster_pwr_dwn diff --git a/lib/cpus/aarch64/aem_generic.S b/lib/cpus/aarch64/aem_generic.S index d5634cff8..9002da65b 100644 --- a/lib/cpus/aarch64/aem_generic.S +++ b/lib/cpus/aarch64/aem_generic.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -74,6 +74,9 @@ func aem_generic_cluster_pwr_dwn b dcsw_op_all endfunc aem_generic_cluster_pwr_dwn +cpu_reset_func_start aem_generic +cpu_reset_func_end aem_generic + /* --------------------------------------------- * This function provides cpu specific * register information for crash reporting. @@ -94,11 +97,11 @@ endfunc aem_generic_cpu_reg_dump /* cpu_ops for Base AEM FVP */ -declare_cpu_ops aem_generic, BASE_AEM_MIDR, CPU_NO_RESET_FUNC, \ +declare_cpu_ops aem_generic, BASE_AEM_MIDR, aem_generic_reset_func, \ aem_generic_core_pwr_dwn, \ aem_generic_cluster_pwr_dwn /* cpu_ops for Foundation FVP */ -declare_cpu_ops aem_generic, FOUNDATION_AEM_MIDR, CPU_NO_RESET_FUNC, \ +declare_cpu_ops aem_generic, FOUNDATION_AEM_MIDR, aem_generic_reset_func, \ aem_generic_core_pwr_dwn, \ aem_generic_cluster_pwr_dwn diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index ead91c388..e60842211 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -14,47 +14,6 @@ #include #include - /* Reset fn is needed in BL at reset vector */ -#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || \ - (defined(IMAGE_BL2) && RESET_TO_BL2) - /* - * The reset handler common to all platforms. After a matching - * cpu_ops structure entry is found, the correponding reset_handler - * in the cpu_ops is invoked. - * Clobbers: x0 - x19, x30 - */ - .globl reset_handler -func reset_handler - mov x19, x30 - - /* The plat_reset_handler can clobber x0 - x18, x30 */ - bl plat_reset_handler - - /* Get the matching cpu_ops pointer */ - bl get_cpu_ops_ptr - -#if ENABLE_ASSERTIONS - /* - * Assert if invalid cpu_ops obtained. If this is not valid, it may - * suggest that the proper CPU file hasn't been included. - */ - cmp x0, #0 - ASM_ASSERT(ne) -#endif - - /* Get the cpu_ops reset handler */ - ldr x2, [x0, #CPU_RESET_FUNC] - mov x30, x19 - cbz x2, 1f - - /* The cpu_ops reset handler can clobber x0 - x19, x30 */ - br x2 -1: - ret -endfunc reset_handler - -#endif - #ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */ /* * void prepare_cpu_pwr_dwn(unsigned int power_level) @@ -212,6 +171,14 @@ search_def_ptr: mov x2, #0 b 1b error_exit: +#endif +#if ENABLE_ASSERTIONS + /* + * Assert if invalid cpu_ops obtained. If this is not valid, it may + * suggest that the proper CPU file hasn't been included. + */ + cmp x0, #0 + ASM_ASSERT(ne) #endif ret endfunc get_cpu_ops_ptr diff --git a/lib/cpus/aarch64/generic.S b/lib/cpus/aarch64/generic.S index 5d7a857e0..849056f49 100644 --- a/lib/cpus/aarch64/generic.S +++ b/lib/cpus/aarch64/generic.S @@ -80,7 +80,9 @@ endfunc generic_cluster_pwr_dwn * --------------------------------------------- */ .equ generic_cpu_reg_dump, 0 -.equ generic_reset_func, 0 + +cpu_reset_func_start generic +cpu_reset_func_end generic declare_cpu_ops generic, AARCH64_GENERIC_MIDR, \ generic_reset_func, \ diff --git a/lib/cpus/aarch64/qemu_max.S b/lib/cpus/aarch64/qemu_max.S index fb03cf15b..529bb4f2a 100644 --- a/lib/cpus/aarch64/qemu_max.S +++ b/lib/cpus/aarch64/qemu_max.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -47,6 +47,9 @@ func qemu_max_cluster_pwr_dwn b dcsw_op_all endfunc qemu_max_cluster_pwr_dwn +cpu_reset_func_start qemu_max +cpu_reset_func_end qemu_max + /* --------------------------------------------- * This function provides cpu specific * register information for crash reporting. @@ -67,6 +70,6 @@ endfunc qemu_max_cpu_reg_dump /* cpu_ops for QEMU MAX */ -declare_cpu_ops qemu_max, QEMU_MAX_MIDR, CPU_NO_RESET_FUNC, \ +declare_cpu_ops qemu_max, QEMU_MAX_MIDR, qemu_max_reset_func, \ qemu_max_core_pwr_dwn, \ qemu_max_cluster_pwr_dwn