arm-trusted-firmware/lib/psci/aarch64/psci_helpers.S

165 lines
4.9 KiB
ArmAsm
Raw Normal View History

/*
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
#include <assert_macros.S>
#include <platform_def.h>
#include <psci.h>
.globl psci_do_pwrdown_cache_maintenance
.globl psci_do_pwrup_cache_maintenance
Introduce PSCI Library Interface This patch introduces the PSCI Library interface. The major changes introduced are as follows: * Earlier BL31 was responsible for Architectural initialization during cold boot via bl31_arch_setup() whereas PSCI was responsible for the same during warm boot. This functionality is now consolidated by the PSCI library and it does Architectural initialization via psci_arch_setup() during both cold and warm boots. * Earlier the warm boot entry point was always `psci_entrypoint()`. This was not flexible enough as a library interface. Now PSCI expects the runtime firmware to provide the entry point via `psci_setup()`. A new function `bl31_warm_entrypoint` is introduced in BL31 and the previous `psci_entrypoint()` is deprecated. * The `smc_helpers.h` is reorganized to separate the SMC Calling Convention defines from the Trusted Firmware SMC helpers. The former is now in a new header file `smcc.h` and the SMC helpers are moved to Architecture specific header. * The CPU context is used by PSCI for context initialization and restoration after power down (PSCI Context). It is also used by BL31 for SMC handling and context management during Normal-Secure world switch (SMC Context). The `psci_smc_handler()` interface is redefined to not use SMC helper macros thus enabling to decouple the PSCI context from EL3 runtime firmware SMC context. This enables PSCI to be integrated with other runtime firmware using a different SMC context. NOTE: With this patch the architectural setup done in `bl31_arch_setup()` is done as part of `psci_setup()` and hence `bl31_platform_setup()` will be invoked prior to architectural setup. It is highly unlikely that the platform setup will depend on architectural setup and cause any failure. Please be be aware of this change in sequence. Change-Id: I7f497a08d33be234bbb822c28146250cb20dab73
2016-04-29 19:01:30 +01:00
.globl psci_power_down_wfi
#if !ERROR_DEPRECATED
.globl psci_entrypoint
#endif
/* -----------------------------------------------------------------------
* void psci_do_pwrdown_cache_maintenance(unsigned int power level);
*
* This function performs cache maintenance for the specified power
* level. The levels of cache affected are determined by the power
* level which is passed as the argument i.e. level 0 results
* in a flush of the L1 cache. Both the L1 and L2 caches are flushed
* for a higher power level.
*
* Additionally, this function also ensures that stack memory is correctly
* flushed out to avoid coherency issues due to a change in its memory
* attributes after the data cache is disabled.
* -----------------------------------------------------------------------
*/
func psci_do_pwrdown_cache_maintenance
stp x29, x30, [sp,#-16]!
stp x19, x20, [sp,#-16]!
/* ---------------------------------------------
* Invoke CPU-specific power down operations for
* the appropriate level
* ---------------------------------------------
*/
bl prepare_cpu_pwr_dwn
/* ---------------------------------------------
* Do stack maintenance by flushing the used
* stack to the main memory and invalidating the
* remainder.
* ---------------------------------------------
*/
bl plat_get_my_stack
/* ---------------------------------------------
* Calculate and store the size of the used
* stack memory in x1.
* ---------------------------------------------
*/
mov x19, x0
mov x1, sp
sub x1, x0, x1
mov x0, sp
bl flush_dcache_range
/* ---------------------------------------------
* Calculate and store the size of the unused
* stack memory in x1. Calculate and store the
* stack base address in x0.
* ---------------------------------------------
*/
sub x0, x19, #PLATFORM_STACK_SIZE
sub x1, sp, x0
bl inv_dcache_range
ldp x19, x20, [sp], #16
ldp x29, x30, [sp], #16
ret
endfunc psci_do_pwrdown_cache_maintenance
/* -----------------------------------------------------------------------
* void psci_do_pwrup_cache_maintenance(void);
*
* This function performs cache maintenance after this cpu is powered up.
* Currently, this involves managing the used stack memory before turning
* on the data cache.
* -----------------------------------------------------------------------
*/
func psci_do_pwrup_cache_maintenance
stp x29, x30, [sp,#-16]!
/* ---------------------------------------------
* Ensure any inflight stack writes have made it
* to main memory.
* ---------------------------------------------
*/
dmb st
/* ---------------------------------------------
* Calculate and store the size of the used
* stack memory in x1. Calculate and store the
* stack base address in x0.
* ---------------------------------------------
*/
bl plat_get_my_stack
mov x1, sp
sub x1, x0, x1
mov x0, sp
bl inv_dcache_range
/* ---------------------------------------------
* Enable the data cache.
* ---------------------------------------------
*/
mrs x0, sctlr_el3
orr x0, x0, #SCTLR_C_BIT
msr sctlr_el3, x0
isb
#if PLAT_XLAT_TABLES_DYNAMIC
/* ---------------------------------------------
* During warm boot the MMU is enabled with data
* cache disabled, then the interconnect is set
* up and finally the data cache is enabled.
*
* During this period, if another CPU modifies
* the translation tables, the MMU table walker
* may read the old entries. This is only a
* problem for dynamic regions, the warm boot
* code isn't affected because it is static.
*
* Invalidate all TLB entries loaded while the
* CPU wasn't coherent with the rest of the
* system.
* ---------------------------------------------
*/
tlbi alle3
dsb ish
isb
#endif
ldp x29, x30, [sp], #16
ret
endfunc psci_do_pwrup_cache_maintenance
Introduce PSCI Library Interface This patch introduces the PSCI Library interface. The major changes introduced are as follows: * Earlier BL31 was responsible for Architectural initialization during cold boot via bl31_arch_setup() whereas PSCI was responsible for the same during warm boot. This functionality is now consolidated by the PSCI library and it does Architectural initialization via psci_arch_setup() during both cold and warm boots. * Earlier the warm boot entry point was always `psci_entrypoint()`. This was not flexible enough as a library interface. Now PSCI expects the runtime firmware to provide the entry point via `psci_setup()`. A new function `bl31_warm_entrypoint` is introduced in BL31 and the previous `psci_entrypoint()` is deprecated. * The `smc_helpers.h` is reorganized to separate the SMC Calling Convention defines from the Trusted Firmware SMC helpers. The former is now in a new header file `smcc.h` and the SMC helpers are moved to Architecture specific header. * The CPU context is used by PSCI for context initialization and restoration after power down (PSCI Context). It is also used by BL31 for SMC handling and context management during Normal-Secure world switch (SMC Context). The `psci_smc_handler()` interface is redefined to not use SMC helper macros thus enabling to decouple the PSCI context from EL3 runtime firmware SMC context. This enables PSCI to be integrated with other runtime firmware using a different SMC context. NOTE: With this patch the architectural setup done in `bl31_arch_setup()` is done as part of `psci_setup()` and hence `bl31_platform_setup()` will be invoked prior to architectural setup. It is highly unlikely that the platform setup will depend on architectural setup and cause any failure. Please be be aware of this change in sequence. Change-Id: I7f497a08d33be234bbb822c28146250cb20dab73
2016-04-29 19:01:30 +01:00
/* -----------------------------------------------------------------------
* void psci_power_down_wfi(void);
* This function is called to indicate to the power controller that it
* is safe to power down this cpu. It should not exit the wfi and will
* be released from reset upon power up.
* -----------------------------------------------------------------------
*/
func psci_power_down_wfi
dsb sy // ensure write buffer empty
wfi
no_ret plat_panic_handler
Introduce PSCI Library Interface This patch introduces the PSCI Library interface. The major changes introduced are as follows: * Earlier BL31 was responsible for Architectural initialization during cold boot via bl31_arch_setup() whereas PSCI was responsible for the same during warm boot. This functionality is now consolidated by the PSCI library and it does Architectural initialization via psci_arch_setup() during both cold and warm boots. * Earlier the warm boot entry point was always `psci_entrypoint()`. This was not flexible enough as a library interface. Now PSCI expects the runtime firmware to provide the entry point via `psci_setup()`. A new function `bl31_warm_entrypoint` is introduced in BL31 and the previous `psci_entrypoint()` is deprecated. * The `smc_helpers.h` is reorganized to separate the SMC Calling Convention defines from the Trusted Firmware SMC helpers. The former is now in a new header file `smcc.h` and the SMC helpers are moved to Architecture specific header. * The CPU context is used by PSCI for context initialization and restoration after power down (PSCI Context). It is also used by BL31 for SMC handling and context management during Normal-Secure world switch (SMC Context). The `psci_smc_handler()` interface is redefined to not use SMC helper macros thus enabling to decouple the PSCI context from EL3 runtime firmware SMC context. This enables PSCI to be integrated with other runtime firmware using a different SMC context. NOTE: With this patch the architectural setup done in `bl31_arch_setup()` is done as part of `psci_setup()` and hence `bl31_platform_setup()` will be invoked prior to architectural setup. It is highly unlikely that the platform setup will depend on architectural setup and cause any failure. Please be be aware of this change in sequence. Change-Id: I7f497a08d33be234bbb822c28146250cb20dab73
2016-04-29 19:01:30 +01:00
endfunc psci_power_down_wfi
/* -----------------------------------------------------------------------
* void psci_entrypoint(void);
* The deprecated entry point for PSCI on warm boot for AArch64.
* -----------------------------------------------------------------------
*/
func_deprecated psci_entrypoint
b bl31_warm_entrypoint
endfunc_deprecated psci_entrypoint