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