diff --git a/Makefile b/Makefile index 9f9061c4a..1c2dcb9a7 100644 --- a/Makefile +++ b/Makefile @@ -459,6 +459,7 @@ $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA)) $(eval $(call assert_boolean,SPIN_ON_BL1_EXIT)) $(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) +$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY)) $(eval $(call assert_numeric,ARM_ARCH_MAJOR)) $(eval $(call assert_numeric,ARM_ARCH_MINOR)) @@ -496,6 +497,7 @@ $(eval $(call add_define,SPD_${SPD})) $(eval $(call add_define,SPIN_ON_BL1_EXIT)) $(eval $(call add_define,TRUSTED_BOARD_BOOT)) $(eval $(call add_define,USE_COHERENT_MEM)) +$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY)) # Define the EL3_PAYLOAD_BASE flag only if it is provided. ifdef EL3_PAYLOAD_BASE diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 623832900..a847ae32d 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -185,26 +185,27 @@ func bl31_warm_entrypoint * * The PSCI implementation invokes platform routines that enable CPUs to * participate in coherency. On a system where CPUs are not - * cache-coherent out of reset, having caches enabled until such time - * might lead to coherency issues (resulting from stale data getting - * speculatively fetched, among others). Therefore we keep data caches - * disabled while enabling the MMU, thereby forcing data accesses to - * have non-cacheable, nGnRnE attributes (these will always be coherent - * with main memory). + * cache-coherent without appropriate platform specific programming, + * having caches enabled until such time might lead to coherency issues + * (resulting from stale data getting speculatively fetched, among + * others). Therefore we keep data caches disabled even after enabling + * the MMU for such platforms. * - * On systems with hardware-assisted coherency, where CPUs are expected - * to be cache-coherent out of reset without needing explicit software - * intervention, PSCI need not invoke platform routines to enter - * coherency (as CPUs already are); and there's no reason to have caches - * disabled either. + * On systems with hardware-assisted coherency, or on single cluster + * platforms, such platform specific programming is not required to + * enter coherency (as CPUs already are); and there's no reason to have + * caches disabled either. */ -#if HW_ASSISTED_COHERENCY - mov x0, #0 -#else mov x0, #DISABLE_DCACHE -#endif bl bl31_plat_enable_mmu +#if HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY + mrs x0, sctlr_el3 + orr x0, x0, #SCTLR_C_BIT + msr sctlr_el3, x0 + isb +#endif + bl psci_warmboot_entrypoint #if ENABLE_RUNTIME_INSTRUMENTATION diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S index c7f60b589..477b55b4e 100644 --- a/bl32/sp_min/aarch32/entrypoint.S +++ b/bl32/sp_min/aarch32/entrypoint.S @@ -236,24 +236,27 @@ func sp_min_warm_entrypoint * * The PSCI implementation invokes platform routines that enable CPUs to * participate in coherency. On a system where CPUs are not - * cache-coherent out of reset, having caches enabled until such time - * might lead to coherency issues (resulting from stale data getting - * speculatively fetched, among others). Therefore we keep data caches - * disabled while enabling the MMU, thereby forcing data accesses to - * have non-cacheable, nGnRnE attributes (these will always be coherent - * with main memory). + * cache-coherent without appropriate platform specific programming, + * having caches enabled until such time might lead to coherency issues + * (resulting from stale data getting speculatively fetched, among + * others). Therefore we keep data caches disabled even after enabling + * the MMU for such platforms. * - * On systems where CPUs are cache-coherent out of reset, however, PSCI - * need not invoke platform routines to enter coherency (as CPUs already - * are), and there's no reason to have caches disabled either. + * On systems with hardware-assisted coherency, or on single cluster + * platforms, such platform specific programming is not required to + * enter coherency (as CPUs already are); and there's no reason to have + * caches disabled either. */ -#if HW_ASSISTED_COHERENCY - mov r0, #0 -#else mov r0, #DISABLE_DCACHE -#endif bl bl32_plat_enable_mmu +#if HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY + ldcopr r0, SCTLR + orr r0, r0, #SCTLR_C_BIT + stcopr r0, SCTLR + isb +#endif + bl sp_min_warm_boot /* Program the registers in cpu_context and exit monitor mode */ diff --git a/docs/user-guide.md b/docs/user-guide.md index a1df96524..af7741e63 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -349,7 +349,8 @@ performed. initiate the operations, and the rest is managed in hardware, minimizing active software management. In such systems, this boolean option enables ARM Trusted Firmware to carry out build and run-time optimizations during boot - and power management operations. This option defaults to 0. + and power management operations. This option defaults to 0 and if it is + enabled, then it implies `WARMBOOT_ENABLE_DCACHE_EARLY` is also enabled. * `LOAD_IMAGE_V2`: Boolean option to enable support for new version (v2) of image loading, which provides more flexibility and scalability around what @@ -508,6 +509,12 @@ performed. to a string formed by concatenating the version number, build type and build string. +* `WARMBOOT_ENABLE_DCACHE_EARLY` : Boolean option to enable D-cache early on + the CPU after warm boot. This is applicable for platforms which do not + require interconnect programming to enable cache coherency (eg: single + cluster platforms). If this option is enabled, then warm boot path + enables D-caches immediately after enabling MMU. This option defaults to 0. + #### ARM development platform specific build options * `ARM_BL31_IN_DRAM`: Boolean option to select loading of BL31 in TZC secured diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c index 675ed6681..76e67a362 100644 --- a/lib/psci/psci_on.c +++ b/lib/psci/psci_on.c @@ -165,7 +165,7 @@ void psci_cpu_on_finish(unsigned int cpu_idx, */ psci_plat_pm_ops->pwr_domain_on_finish(state_info); -#if !HW_ASSISTED_COHERENCY +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) /* * Arch. management: Enable data cache and manage stack memory */ diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c index 08c8fd6a6..bf95df247 100644 --- a/lib/psci/psci_suspend.c +++ b/lib/psci/psci_suspend.c @@ -302,7 +302,7 @@ void psci_cpu_suspend_finish(unsigned int cpu_idx, */ psci_plat_pm_ops->pwr_domain_suspend_finish(state_info); -#if !HW_ASSISTED_COHERENCY +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) /* Arch. management: Enable the data cache, stack memory maintenance. */ psci_do_pwrup_cache_maintenance(); #endif diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index e66f5112a..903363a46 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -154,3 +154,9 @@ USE_COHERENT_MEM := 1 # Build verbosity V := 0 + +# Whether to enable D-Cache early during warm boot. This is usually +# applicable for platforms wherein interconnect programming is not +# required to enable cache coherency after warm reset (eg: single cluster +# platforms). +WARMBOOT_ENABLE_DCACHE_EARLY := 0