1/* 2 * Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <asm_macros.S> 8#include <assert_macros.S> 9#include <cpu_macros.S> 10#include <lib/psci/psci.h> 11#include <platform_def.h> 12 13 .globl psci_do_pwrdown_cache_maintenance 14 .globl psci_do_pwrup_cache_maintenance 15 .globl psci_power_down_wfi 16 17/* ----------------------------------------------------------------------- 18 * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 19 * 20 * This function performs cache maintenance for the specified power 21 * level. The levels of cache affected are determined by the power 22 * level which is passed as the argument i.e. level 0 results 23 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 24 * for a higher power level. 25 * 26 * Additionally, this function also ensures that stack memory is correctly 27 * flushed out to avoid coherency issues due to a change in its memory 28 * attributes after the data cache is disabled. 29 * ----------------------------------------------------------------------- 30 */ 31func psci_do_pwrdown_cache_maintenance 32 stp x29, x30, [sp,#-16]! 33 stp x19, x20, [sp,#-16]! 34 35 /* --------------------------------------------- 36 * Invoke CPU-specific power down operations for 37 * the appropriate level 38 * --------------------------------------------- 39 */ 40 bl prepare_cpu_pwr_dwn 41 42 /* --------------------------------------------- 43 * Do stack maintenance by flushing the used 44 * stack to the main memory and invalidating the 45 * remainder. 46 * --------------------------------------------- 47 */ 48 bl plat_get_my_stack 49 50 /* --------------------------------------------- 51 * Calculate and store the size of the used 52 * stack memory in x1. 53 * --------------------------------------------- 54 */ 55 mov x19, x0 56 mov x1, sp 57 sub x1, x0, x1 58 mov x0, sp 59 bl flush_dcache_range 60 61 /* --------------------------------------------- 62 * Calculate and store the size of the unused 63 * stack memory in x1. Calculate and store the 64 * stack base address in x0. 65 * --------------------------------------------- 66 */ 67 sub x0, x19, #PLATFORM_STACK_SIZE 68 sub x1, sp, x0 69 bl inv_dcache_range 70 71 ldp x19, x20, [sp], #16 72 ldp x29, x30, [sp], #16 73 ret 74endfunc psci_do_pwrdown_cache_maintenance 75 76 77/* ----------------------------------------------------------------------- 78 * void psci_do_pwrup_cache_maintenance(void); 79 * 80 * This function performs cache maintenance after this cpu is powered up. 81 * Currently, this involves managing the used stack memory before turning 82 * on the data cache. 83 * ----------------------------------------------------------------------- 84 */ 85func psci_do_pwrup_cache_maintenance 86 stp x29, x30, [sp,#-16]! 87 88 /* --------------------------------------------- 89 * Ensure any inflight stack writes have made it 90 * to main memory. 91 * --------------------------------------------- 92 */ 93 dmb st 94 95 /* --------------------------------------------- 96 * Calculate and store the size of the used 97 * stack memory in x1. Calculate and store the 98 * stack base address in x0. 99 * --------------------------------------------- 100 */ 101 bl plat_get_my_stack 102 mov x1, sp 103 sub x1, x0, x1 104 mov x0, sp 105 bl inv_dcache_range 106 107 /* --------------------------------------------- 108 * Enable the data cache. 109 * --------------------------------------------- 110 */ 111 mrs x0, sctlr_el3 112 orr x0, x0, #SCTLR_C_BIT 113 msr sctlr_el3, x0 114 isb 115 116 ldp x29, x30, [sp], #16 117 ret 118endfunc psci_do_pwrup_cache_maintenance 119 120/* ----------------------------------------------------------------------- 121 * void psci_power_down_wfi(void); 122 * This function is called to indicate to the power controller that it 123 * is safe to power down this cpu. It should not exit the wfi and will 124 * be released from reset upon power up. 125 * ----------------------------------------------------------------------- 126 */ 127func psci_power_down_wfi 128 apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597 129 130 dsb sy // ensure write buffer empty 1311: 132 wfi 133 b 1b 134endfunc psci_power_down_wfi 135