1*727e5238SSoby Mathew/* 2*727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3*727e5238SSoby Mathew * 4*727e5238SSoby Mathew * Redistribution and use in source and binary forms, with or without 5*727e5238SSoby Mathew * modification, are permitted provided that the following conditions are met: 6*727e5238SSoby Mathew * 7*727e5238SSoby Mathew * Redistributions of source code must retain the above copyright notice, this 8*727e5238SSoby Mathew * list of conditions and the following disclaimer. 9*727e5238SSoby Mathew * 10*727e5238SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 11*727e5238SSoby Mathew * this list of conditions and the following disclaimer in the documentation 12*727e5238SSoby Mathew * and/or other materials provided with the distribution. 13*727e5238SSoby Mathew * 14*727e5238SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 15*727e5238SSoby Mathew * to endorse or promote products derived from this software without specific 16*727e5238SSoby Mathew * prior written permission. 17*727e5238SSoby Mathew * 18*727e5238SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*727e5238SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*727e5238SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*727e5238SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*727e5238SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*727e5238SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*727e5238SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*727e5238SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*727e5238SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*727e5238SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*727e5238SSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 29*727e5238SSoby Mathew */ 30*727e5238SSoby Mathew 31*727e5238SSoby Mathew#include <asm_macros.S> 32*727e5238SSoby Mathew#include <platform_def.h> 33*727e5238SSoby Mathew#include <psci.h> 34*727e5238SSoby Mathew 35*727e5238SSoby Mathew .globl psci_do_pwrdown_cache_maintenance 36*727e5238SSoby Mathew .globl psci_do_pwrup_cache_maintenance 37*727e5238SSoby Mathew .globl psci_power_down_wfi 38*727e5238SSoby Mathew 39*727e5238SSoby Mathew/* ----------------------------------------------------------------------- 40*727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 41*727e5238SSoby Mathew * 42*727e5238SSoby Mathew * This function performs cache maintenance for the specified power 43*727e5238SSoby Mathew * level. The levels of cache affected are determined by the power 44*727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results 45*727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 46*727e5238SSoby Mathew * for a higher power level. 47*727e5238SSoby Mathew * 48*727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly 49*727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory 50*727e5238SSoby Mathew * attributes after the data cache is disabled. 51*727e5238SSoby Mathew * ----------------------------------------------------------------------- 52*727e5238SSoby Mathew */ 53*727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance 54*727e5238SSoby Mathew push {r4, lr} 55*727e5238SSoby Mathew 56*727e5238SSoby Mathew /* ---------------------------------------------- 57*727e5238SSoby Mathew * Turn OFF cache and do stack maintenance 58*727e5238SSoby Mathew * prior to cpu operations . This sequence is 59*727e5238SSoby Mathew * different from AArch64 because in AArch32 the 60*727e5238SSoby Mathew * assembler routines for cpu operations utilize 61*727e5238SSoby Mathew * the stack whereas in AArch64 it doesn't. 62*727e5238SSoby Mathew * ---------------------------------------------- 63*727e5238SSoby Mathew */ 64*727e5238SSoby Mathew mov r4, r0 65*727e5238SSoby Mathew bl do_stack_maintenance 66*727e5238SSoby Mathew 67*727e5238SSoby Mathew /* --------------------------------------------- 68*727e5238SSoby Mathew * Determine how many levels of cache will be 69*727e5238SSoby Mathew * subject to cache maintenance. Power level 70*727e5238SSoby Mathew * 0 implies that only the cpu is being powered 71*727e5238SSoby Mathew * down. Only the L1 data cache needs to be 72*727e5238SSoby Mathew * flushed to the PoU in this case. For a higher 73*727e5238SSoby Mathew * power level we are assuming that a flush 74*727e5238SSoby Mathew * of L1 data and L2 unified cache is enough. 75*727e5238SSoby Mathew * This information should be provided by the 76*727e5238SSoby Mathew * platform. 77*727e5238SSoby Mathew * --------------------------------------------- 78*727e5238SSoby Mathew */ 79*727e5238SSoby Mathew cmp r4, #PSCI_CPU_PWR_LVL 80*727e5238SSoby Mathew pop {r4,lr} 81*727e5238SSoby Mathew 82*727e5238SSoby Mathew beq prepare_core_pwr_dwn 83*727e5238SSoby Mathew b prepare_cluster_pwr_dwn 84*727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance 85*727e5238SSoby Mathew 86*727e5238SSoby Mathew 87*727e5238SSoby Mathew/* ----------------------------------------------------------------------- 88*727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void); 89*727e5238SSoby Mathew * 90*727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up. 91*727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning 92*727e5238SSoby Mathew * on the data cache. 93*727e5238SSoby Mathew * ----------------------------------------------------------------------- 94*727e5238SSoby Mathew */ 95*727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance 96*727e5238SSoby Mathew push {lr} 97*727e5238SSoby Mathew 98*727e5238SSoby Mathew /* --------------------------------------------- 99*727e5238SSoby Mathew * Ensure any inflight stack writes have made it 100*727e5238SSoby Mathew * to main memory. 101*727e5238SSoby Mathew * --------------------------------------------- 102*727e5238SSoby Mathew */ 103*727e5238SSoby Mathew dmb st 104*727e5238SSoby Mathew 105*727e5238SSoby Mathew /* --------------------------------------------- 106*727e5238SSoby Mathew * Calculate and store the size of the used 107*727e5238SSoby Mathew * stack memory in r1. Calculate and store the 108*727e5238SSoby Mathew * stack base address in r0. 109*727e5238SSoby Mathew * --------------------------------------------- 110*727e5238SSoby Mathew */ 111*727e5238SSoby Mathew bl plat_get_my_stack 112*727e5238SSoby Mathew mov r1, sp 113*727e5238SSoby Mathew sub r1, r0, r1 114*727e5238SSoby Mathew mov r0, sp 115*727e5238SSoby Mathew bl inv_dcache_range 116*727e5238SSoby Mathew 117*727e5238SSoby Mathew /* --------------------------------------------- 118*727e5238SSoby Mathew * Enable the data cache. 119*727e5238SSoby Mathew * --------------------------------------------- 120*727e5238SSoby Mathew */ 121*727e5238SSoby Mathew ldcopr r0, SCTLR 122*727e5238SSoby Mathew orr r0, r0, #SCTLR_C_BIT 123*727e5238SSoby Mathew stcopr r0, SCTLR 124*727e5238SSoby Mathew isb 125*727e5238SSoby Mathew 126*727e5238SSoby Mathew pop {pc} 127*727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance 128*727e5238SSoby Mathew 129*727e5238SSoby Mathew /* --------------------------------------------- 130*727e5238SSoby Mathew * void do_stack_maintenance(void) 131*727e5238SSoby Mathew * Do stack maintenance by flushing the used 132*727e5238SSoby Mathew * stack to the main memory and invalidating the 133*727e5238SSoby Mathew * remainder. 134*727e5238SSoby Mathew * --------------------------------------------- 135*727e5238SSoby Mathew */ 136*727e5238SSoby Mathewfunc do_stack_maintenance 137*727e5238SSoby Mathew push {r4, lr} 138*727e5238SSoby Mathew bl plat_get_my_stack 139*727e5238SSoby Mathew 140*727e5238SSoby Mathew /* Turn off the D-cache */ 141*727e5238SSoby Mathew ldcopr r1, SCTLR 142*727e5238SSoby Mathew bic r1, #SCTLR_C_BIT 143*727e5238SSoby Mathew stcopr r1, SCTLR 144*727e5238SSoby Mathew isb 145*727e5238SSoby Mathew 146*727e5238SSoby Mathew /* --------------------------------------------- 147*727e5238SSoby Mathew * Calculate and store the size of the used 148*727e5238SSoby Mathew * stack memory in r1. 149*727e5238SSoby Mathew * --------------------------------------------- 150*727e5238SSoby Mathew */ 151*727e5238SSoby Mathew mov r4, r0 152*727e5238SSoby Mathew mov r1, sp 153*727e5238SSoby Mathew sub r1, r0, r1 154*727e5238SSoby Mathew mov r0, sp 155*727e5238SSoby Mathew bl flush_dcache_range 156*727e5238SSoby Mathew 157*727e5238SSoby Mathew /* --------------------------------------------- 158*727e5238SSoby Mathew * Calculate and store the size of the unused 159*727e5238SSoby Mathew * stack memory in r1. Calculate and store the 160*727e5238SSoby Mathew * stack base address in r0. 161*727e5238SSoby Mathew * --------------------------------------------- 162*727e5238SSoby Mathew */ 163*727e5238SSoby Mathew sub r0, r4, #PLATFORM_STACK_SIZE 164*727e5238SSoby Mathew sub r1, sp, r0 165*727e5238SSoby Mathew bl inv_dcache_range 166*727e5238SSoby Mathew 167*727e5238SSoby Mathew pop {r4, pc} 168*727e5238SSoby Mathewendfunc do_stack_maintenance 169*727e5238SSoby Mathew 170*727e5238SSoby Mathew/* ----------------------------------------------------------------------- 171*727e5238SSoby Mathew * This function is called to indicate to the power controller that it 172*727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will 173*727e5238SSoby Mathew * be released from reset upon power up. 174*727e5238SSoby Mathew * ----------------------------------------------------------------------- 175*727e5238SSoby Mathew */ 176*727e5238SSoby Mathewfunc psci_power_down_wfi 177*727e5238SSoby Mathew dsb sy // ensure write buffer empty 178*727e5238SSoby Mathew wfi 179*727e5238SSoby Mathew bl plat_panic_handler 180*727e5238SSoby Mathewendfunc psci_power_down_wfi 181