1727e5238SSoby Mathew/* 2727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3727e5238SSoby Mathew * 4727e5238SSoby Mathew * Redistribution and use in source and binary forms, with or without 5727e5238SSoby Mathew * modification, are permitted provided that the following conditions are met: 6727e5238SSoby Mathew * 7727e5238SSoby Mathew * Redistributions of source code must retain the above copyright notice, this 8727e5238SSoby Mathew * list of conditions and the following disclaimer. 9727e5238SSoby Mathew * 10727e5238SSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 11727e5238SSoby Mathew * this list of conditions and the following disclaimer in the documentation 12727e5238SSoby Mathew * and/or other materials provided with the distribution. 13727e5238SSoby Mathew * 14727e5238SSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 15727e5238SSoby Mathew * to endorse or promote products derived from this software without specific 16727e5238SSoby Mathew * prior written permission. 17727e5238SSoby Mathew * 18727e5238SSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19727e5238SSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20727e5238SSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21727e5238SSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22727e5238SSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23727e5238SSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24727e5238SSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25727e5238SSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26727e5238SSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27727e5238SSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28727e5238SSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 29727e5238SSoby Mathew */ 30727e5238SSoby Mathew 31727e5238SSoby Mathew#include <asm_macros.S> 32727e5238SSoby Mathew#include <platform_def.h> 33727e5238SSoby Mathew#include <psci.h> 34727e5238SSoby Mathew 35727e5238SSoby Mathew .globl psci_do_pwrdown_cache_maintenance 36727e5238SSoby Mathew .globl psci_do_pwrup_cache_maintenance 37727e5238SSoby Mathew .globl psci_power_down_wfi 38727e5238SSoby Mathew 39727e5238SSoby Mathew/* ----------------------------------------------------------------------- 40727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 41727e5238SSoby Mathew * 42727e5238SSoby Mathew * This function performs cache maintenance for the specified power 43727e5238SSoby Mathew * level. The levels of cache affected are determined by the power 44727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results 45727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 46727e5238SSoby Mathew * for a higher power level. 47727e5238SSoby Mathew * 48727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly 49727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory 50727e5238SSoby Mathew * attributes after the data cache is disabled. 51727e5238SSoby Mathew * ----------------------------------------------------------------------- 52727e5238SSoby Mathew */ 53727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance 54727e5238SSoby Mathew push {r4, lr} 55727e5238SSoby Mathew 56727e5238SSoby Mathew /* ---------------------------------------------- 57727e5238SSoby Mathew * Turn OFF cache and do stack maintenance 58727e5238SSoby Mathew * prior to cpu operations . This sequence is 59727e5238SSoby Mathew * different from AArch64 because in AArch32 the 60727e5238SSoby Mathew * assembler routines for cpu operations utilize 61727e5238SSoby Mathew * the stack whereas in AArch64 it doesn't. 62727e5238SSoby Mathew * ---------------------------------------------- 63727e5238SSoby Mathew */ 64727e5238SSoby Mathew mov r4, r0 65727e5238SSoby Mathew bl do_stack_maintenance 66727e5238SSoby Mathew 67727e5238SSoby Mathew /* --------------------------------------------- 68*5dd9dbb5SJeenu Viswambharan * Invoke CPU-specifc power down operations for 69*5dd9dbb5SJeenu Viswambharan * the appropriate level 70727e5238SSoby Mathew * --------------------------------------------- 71727e5238SSoby Mathew */ 72*5dd9dbb5SJeenu Viswambharan mov r0, r4 73727e5238SSoby Mathew pop {r4, lr} 74*5dd9dbb5SJeenu Viswambharan b prepare_cpu_pwr_dwn 75727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance 76727e5238SSoby Mathew 77727e5238SSoby Mathew 78727e5238SSoby Mathew/* ----------------------------------------------------------------------- 79727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void); 80727e5238SSoby Mathew * 81727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up. 82727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning 83727e5238SSoby Mathew * on the data cache. 84727e5238SSoby Mathew * ----------------------------------------------------------------------- 85727e5238SSoby Mathew */ 86727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance 879f3ee61cSSoby Mathew /* r12 is pushed to meet the 8 byte stack alignment requirement */ 889f3ee61cSSoby Mathew push {r12, lr} 89727e5238SSoby Mathew 90727e5238SSoby Mathew /* --------------------------------------------- 91727e5238SSoby Mathew * Ensure any inflight stack writes have made it 92727e5238SSoby Mathew * to main memory. 93727e5238SSoby Mathew * --------------------------------------------- 94727e5238SSoby Mathew */ 95727e5238SSoby Mathew dmb st 96727e5238SSoby Mathew 97727e5238SSoby Mathew /* --------------------------------------------- 98727e5238SSoby Mathew * Calculate and store the size of the used 99727e5238SSoby Mathew * stack memory in r1. Calculate and store the 100727e5238SSoby Mathew * stack base address in r0. 101727e5238SSoby Mathew * --------------------------------------------- 102727e5238SSoby Mathew */ 103727e5238SSoby Mathew bl plat_get_my_stack 104727e5238SSoby Mathew mov r1, sp 105727e5238SSoby Mathew sub r1, r0, r1 106727e5238SSoby Mathew mov r0, sp 107727e5238SSoby Mathew bl inv_dcache_range 108727e5238SSoby Mathew 109727e5238SSoby Mathew /* --------------------------------------------- 110727e5238SSoby Mathew * Enable the data cache. 111727e5238SSoby Mathew * --------------------------------------------- 112727e5238SSoby Mathew */ 113727e5238SSoby Mathew ldcopr r0, SCTLR 114727e5238SSoby Mathew orr r0, r0, #SCTLR_C_BIT 115727e5238SSoby Mathew stcopr r0, SCTLR 116727e5238SSoby Mathew isb 117727e5238SSoby Mathew 1189f3ee61cSSoby Mathew pop {r12, pc} 119727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance 120727e5238SSoby Mathew 121727e5238SSoby Mathew /* --------------------------------------------- 122727e5238SSoby Mathew * void do_stack_maintenance(void) 123727e5238SSoby Mathew * Do stack maintenance by flushing the used 124727e5238SSoby Mathew * stack to the main memory and invalidating the 125727e5238SSoby Mathew * remainder. 126727e5238SSoby Mathew * --------------------------------------------- 127727e5238SSoby Mathew */ 128727e5238SSoby Mathewfunc do_stack_maintenance 129727e5238SSoby Mathew push {r4, lr} 130727e5238SSoby Mathew bl plat_get_my_stack 131727e5238SSoby Mathew 132727e5238SSoby Mathew /* Turn off the D-cache */ 133727e5238SSoby Mathew ldcopr r1, SCTLR 134727e5238SSoby Mathew bic r1, #SCTLR_C_BIT 135727e5238SSoby Mathew stcopr r1, SCTLR 136727e5238SSoby Mathew isb 137727e5238SSoby Mathew 138727e5238SSoby Mathew /* --------------------------------------------- 139727e5238SSoby Mathew * Calculate and store the size of the used 140727e5238SSoby Mathew * stack memory in r1. 141727e5238SSoby Mathew * --------------------------------------------- 142727e5238SSoby Mathew */ 143727e5238SSoby Mathew mov r4, r0 144727e5238SSoby Mathew mov r1, sp 145727e5238SSoby Mathew sub r1, r0, r1 146727e5238SSoby Mathew mov r0, sp 147727e5238SSoby Mathew bl flush_dcache_range 148727e5238SSoby Mathew 149727e5238SSoby Mathew /* --------------------------------------------- 150727e5238SSoby Mathew * Calculate and store the size of the unused 151727e5238SSoby Mathew * stack memory in r1. Calculate and store the 152727e5238SSoby Mathew * stack base address in r0. 153727e5238SSoby Mathew * --------------------------------------------- 154727e5238SSoby Mathew */ 155727e5238SSoby Mathew sub r0, r4, #PLATFORM_STACK_SIZE 156727e5238SSoby Mathew sub r1, sp, r0 157727e5238SSoby Mathew bl inv_dcache_range 158727e5238SSoby Mathew 159727e5238SSoby Mathew pop {r4, pc} 160727e5238SSoby Mathewendfunc do_stack_maintenance 161727e5238SSoby Mathew 162727e5238SSoby Mathew/* ----------------------------------------------------------------------- 163727e5238SSoby Mathew * This function is called to indicate to the power controller that it 164727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will 165727e5238SSoby Mathew * be released from reset upon power up. 166727e5238SSoby Mathew * ----------------------------------------------------------------------- 167727e5238SSoby Mathew */ 168727e5238SSoby Mathewfunc psci_power_down_wfi 169727e5238SSoby Mathew dsb sy // ensure write buffer empty 170727e5238SSoby Mathew wfi 171a806dad5SJeenu Viswambharan no_ret plat_panic_handler 172727e5238SSoby Mathewendfunc psci_power_down_wfi 173