123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /*
- * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <asm_macros.S>
- #include <lib/psci/psci.h>
- #include <platform_def.h>
- .globl psci_do_pwrdown_cache_maintenance
- .globl psci_do_pwrup_cache_maintenance
- .globl psci_power_down_wfi
- /* -----------------------------------------------------------------------
- * 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
- push {r4, lr}
- /* ----------------------------------------------
- * Turn OFF cache and do stack maintenance
- * prior to cpu operations . This sequence is
- * different from AArch64 because in AArch32 the
- * assembler routines for cpu operations utilize
- * the stack whereas in AArch64 it doesn't.
- * ----------------------------------------------
- */
- mov r4, r0
- bl do_stack_maintenance
- /* ---------------------------------------------
- * Invoke CPU-specifc power down operations for
- * the appropriate level
- * ---------------------------------------------
- */
- mov r0, r4
- pop {r4, lr}
- b prepare_cpu_pwr_dwn
- 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
- /* r12 is pushed to meet the 8 byte stack alignment requirement */
- push {r12, lr}
- /* ---------------------------------------------
- * Ensure any inflight stack writes have made it
- * to main memory.
- * ---------------------------------------------
- */
- dmb st
- /* ---------------------------------------------
- * Calculate and store the size of the used
- * stack memory in r1. Calculate and store the
- * stack base address in r0.
- * ---------------------------------------------
- */
- bl plat_get_my_stack
- mov r1, sp
- sub r1, r0, r1
- mov r0, sp
- bl inv_dcache_range
- /* ---------------------------------------------
- * Enable the data cache.
- * ---------------------------------------------
- */
- ldcopr r0, SCTLR
- orr r0, r0, #SCTLR_C_BIT
- stcopr r0, SCTLR
- isb
- pop {r12, pc}
- endfunc psci_do_pwrup_cache_maintenance
- /* ---------------------------------------------
- * void do_stack_maintenance(void)
- * Do stack maintenance by flushing the used
- * stack to the main memory and invalidating the
- * remainder.
- * ---------------------------------------------
- */
- func do_stack_maintenance
- push {r4, lr}
- bl plat_get_my_stack
- /* Turn off the D-cache */
- ldcopr r1, SCTLR
- bic r1, #SCTLR_C_BIT
- stcopr r1, SCTLR
- isb
- /* ---------------------------------------------
- * Calculate and store the size of the used
- * stack memory in r1.
- * ---------------------------------------------
- */
- mov r4, r0
- mov r1, sp
- sub r1, r0, r1
- mov r0, sp
- bl flush_dcache_range
- /* ---------------------------------------------
- * Calculate and store the size of the unused
- * stack memory in r1. Calculate and store the
- * stack base address in r0.
- * ---------------------------------------------
- */
- sub r0, r4, #PLATFORM_STACK_SIZE
- sub r1, sp, r0
- bl inv_dcache_range
- pop {r4, pc}
- endfunc do_stack_maintenance
- /* -----------------------------------------------------------------------
- * 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
- 1:
- wfi
- b 1b
- endfunc psci_power_down_wfi
|