1/* 2 * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <asm_macros.S> 8#include <lib/psci/psci.h> 9#include <platform_def.h> 10 11 .globl psci_do_pwrdown_cache_maintenance 12 .globl psci_do_pwrup_cache_maintenance 13 14/* ----------------------------------------------------------------------- 15 * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 16 * 17 * This function performs cache maintenance for the specified power 18 * level. The levels of cache affected are determined by the power 19 * level which is passed as the argument i.e. level 0 results 20 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 21 * for a higher power level. 22 * 23 * Additionally, this function also ensures that stack memory is correctly 24 * flushed out to avoid coherency issues due to a change in its memory 25 * attributes after the data cache is disabled. 26 * ----------------------------------------------------------------------- 27 */ 28func psci_do_pwrdown_cache_maintenance 29 push {r4, lr} 30 31 /* ---------------------------------------------- 32 * Turn OFF cache and do stack maintenance 33 * prior to cpu operations . This sequence is 34 * different from AArch64 because in AArch32 the 35 * assembler routines for cpu operations utilize 36 * the stack whereas in AArch64 it doesn't. 37 * ---------------------------------------------- 38 */ 39 mov r4, r0 40 bl do_stack_maintenance 41 42 /* --------------------------------------------- 43 * Invoke CPU-specifc power down operations for 44 * the appropriate level 45 * --------------------------------------------- 46 */ 47 mov r0, r4 48 pop {r4, lr} 49 b prepare_cpu_pwr_dwn 50endfunc psci_do_pwrdown_cache_maintenance 51 52 53/* ----------------------------------------------------------------------- 54 * void psci_do_pwrup_cache_maintenance(void); 55 * 56 * This function performs cache maintenance after this cpu is powered up. 57 * Currently, this involves managing the used stack memory before turning 58 * on the data cache. 59 * ----------------------------------------------------------------------- 60 */ 61func psci_do_pwrup_cache_maintenance 62 /* r12 is pushed to meet the 8 byte stack alignment requirement */ 63 push {r12, lr} 64 65 /* --------------------------------------------- 66 * Ensure any inflight stack writes have made it 67 * to main memory. 68 * --------------------------------------------- 69 */ 70 dmb st 71 72 /* --------------------------------------------- 73 * Calculate and store the size of the used 74 * stack memory in r1. Calculate and store the 75 * stack base address in r0. 76 * --------------------------------------------- 77 */ 78 bl plat_get_my_stack 79 mov r1, sp 80 sub r1, r0, r1 81 mov r0, sp 82 bl inv_dcache_range 83 84 /* --------------------------------------------- 85 * Enable the data cache. 86 * --------------------------------------------- 87 */ 88 ldcopr r0, SCTLR 89 orr r0, r0, #SCTLR_C_BIT 90 stcopr r0, SCTLR 91 isb 92 93 pop {r12, pc} 94endfunc psci_do_pwrup_cache_maintenance 95 96 /* --------------------------------------------- 97 * void do_stack_maintenance(void) 98 * Do stack maintenance by flushing the used 99 * stack to the main memory and invalidating the 100 * remainder. 101 * --------------------------------------------- 102 */ 103func do_stack_maintenance 104 push {r4, lr} 105 bl plat_get_my_stack 106 107 /* Turn off the D-cache */ 108 ldcopr r1, SCTLR 109 bic r1, #SCTLR_C_BIT 110 stcopr r1, SCTLR 111 isb 112 113 /* --------------------------------------------- 114 * Calculate and store the size of the used 115 * stack memory in r1. 116 * --------------------------------------------- 117 */ 118 mov r4, r0 119 mov r1, sp 120 sub r1, r0, r1 121 mov r0, sp 122 bl flush_dcache_range 123 124 /* --------------------------------------------- 125 * Calculate and store the size of the unused 126 * stack memory in r1. Calculate and store the 127 * stack base address in r0. 128 * --------------------------------------------- 129 */ 130 sub r0, r4, #PLATFORM_STACK_SIZE 131 sub r1, sp, r0 132 bl inv_dcache_range 133 134 pop {r4, pc} 135endfunc do_stack_maintenance 136