1/* 2 * Copyright (c) 2014-2018, 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 <platform_def.h> 10#include <psci.h> 11 12 .globl psci_do_pwrdown_cache_maintenance 13 .globl psci_do_pwrup_cache_maintenance 14 .globl psci_power_down_wfi 15#if !ERROR_DEPRECATED 16 .globl psci_entrypoint 17#endif 18 19/* ----------------------------------------------------------------------- 20 * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 21 * 22 * This function performs cache maintenance for the specified power 23 * level. The levels of cache affected are determined by the power 24 * level which is passed as the argument i.e. level 0 results 25 * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 26 * for a higher power level. 27 * 28 * Additionally, this function also ensures that stack memory is correctly 29 * flushed out to avoid coherency issues due to a change in its memory 30 * attributes after the data cache is disabled. 31 * ----------------------------------------------------------------------- 32 */ 33func psci_do_pwrdown_cache_maintenance 34 stp x29, x30, [sp,#-16]! 35 stp x19, x20, [sp,#-16]! 36 37 /* --------------------------------------------- 38 * Invoke CPU-specific power down operations for 39 * the appropriate level 40 * --------------------------------------------- 41 */ 42 bl prepare_cpu_pwr_dwn 43 44 /* --------------------------------------------- 45 * Do stack maintenance by flushing the used 46 * stack to the main memory and invalidating the 47 * remainder. 48 * --------------------------------------------- 49 */ 50 bl plat_get_my_stack 51 52 /* --------------------------------------------- 53 * Calculate and store the size of the used 54 * stack memory in x1. 55 * --------------------------------------------- 56 */ 57 mov x19, x0 58 mov x1, sp 59 sub x1, x0, x1 60 mov x0, sp 61 bl flush_dcache_range 62 63 /* --------------------------------------------- 64 * Calculate and store the size of the unused 65 * stack memory in x1. Calculate and store the 66 * stack base address in x0. 67 * --------------------------------------------- 68 */ 69 sub x0, x19, #PLATFORM_STACK_SIZE 70 sub x1, sp, x0 71 bl inv_dcache_range 72 73 ldp x19, x20, [sp], #16 74 ldp x29, x30, [sp], #16 75 ret 76endfunc psci_do_pwrdown_cache_maintenance 77 78 79/* ----------------------------------------------------------------------- 80 * void psci_do_pwrup_cache_maintenance(void); 81 * 82 * This function performs cache maintenance after this cpu is powered up. 83 * Currently, this involves managing the used stack memory before turning 84 * on the data cache. 85 * ----------------------------------------------------------------------- 86 */ 87func psci_do_pwrup_cache_maintenance 88 stp x29, x30, [sp,#-16]! 89 90 /* --------------------------------------------- 91 * Ensure any inflight stack writes have made it 92 * to main memory. 93 * --------------------------------------------- 94 */ 95 dmb st 96 97 /* --------------------------------------------- 98 * Calculate and store the size of the used 99 * stack memory in x1. Calculate and store the 100 * stack base address in x0. 101 * --------------------------------------------- 102 */ 103 bl plat_get_my_stack 104 mov x1, sp 105 sub x1, x0, x1 106 mov x0, sp 107 bl inv_dcache_range 108 109 /* --------------------------------------------- 110 * Enable the data cache. 111 * --------------------------------------------- 112 */ 113 mrs x0, sctlr_el3 114 orr x0, x0, #SCTLR_C_BIT 115 msr sctlr_el3, x0 116 isb 117 118#if PLAT_XLAT_TABLES_DYNAMIC 119 /* --------------------------------------------- 120 * During warm boot the MMU is enabled with data 121 * cache disabled, then the interconnect is set 122 * up and finally the data cache is enabled. 123 * 124 * During this period, if another CPU modifies 125 * the translation tables, the MMU table walker 126 * may read the old entries. This is only a 127 * problem for dynamic regions, the warm boot 128 * code isn't affected because it is static. 129 * 130 * Invalidate all TLB entries loaded while the 131 * CPU wasn't coherent with the rest of the 132 * system. 133 * --------------------------------------------- 134 */ 135 tlbi alle3 136 dsb ish 137 isb 138#endif 139 140 ldp x29, x30, [sp], #16 141 ret 142endfunc psci_do_pwrup_cache_maintenance 143 144/* ----------------------------------------------------------------------- 145 * void psci_power_down_wfi(void); 146 * This function is called to indicate to the power controller that it 147 * is safe to power down this cpu. It should not exit the wfi and will 148 * be released from reset upon power up. 149 * ----------------------------------------------------------------------- 150 */ 151func psci_power_down_wfi 152 dsb sy // ensure write buffer empty 153 wfi 154 no_ret plat_panic_handler 155endfunc psci_power_down_wfi 156 157/* ----------------------------------------------------------------------- 158 * void psci_entrypoint(void); 159 * The deprecated entry point for PSCI on warm boot for AArch64. 160 * ----------------------------------------------------------------------- 161 */ 162func_deprecated psci_entrypoint 163 b bl31_warm_entrypoint 164endfunc_deprecated psci_entrypoint 165