1727e5238SSoby Mathew/* 2*26441030SAntonio Nino Diaz * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. 3727e5238SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5727e5238SSoby Mathew */ 6727e5238SSoby Mathew 7727e5238SSoby Mathew#include <asm_macros.S> 8727e5238SSoby Mathew#include <platform_def.h> 9727e5238SSoby Mathew#include <psci.h> 10727e5238SSoby Mathew 11727e5238SSoby Mathew .globl psci_do_pwrdown_cache_maintenance 12727e5238SSoby Mathew .globl psci_do_pwrup_cache_maintenance 13727e5238SSoby Mathew .globl psci_power_down_wfi 14727e5238SSoby Mathew 15727e5238SSoby Mathew/* ----------------------------------------------------------------------- 16727e5238SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 17727e5238SSoby Mathew * 18727e5238SSoby Mathew * This function performs cache maintenance for the specified power 19727e5238SSoby Mathew * level. The levels of cache affected are determined by the power 20727e5238SSoby Mathew * level which is passed as the argument i.e. level 0 results 21727e5238SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 22727e5238SSoby Mathew * for a higher power level. 23727e5238SSoby Mathew * 24727e5238SSoby Mathew * Additionally, this function also ensures that stack memory is correctly 25727e5238SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory 26727e5238SSoby Mathew * attributes after the data cache is disabled. 27727e5238SSoby Mathew * ----------------------------------------------------------------------- 28727e5238SSoby Mathew */ 29727e5238SSoby Mathewfunc psci_do_pwrdown_cache_maintenance 30727e5238SSoby Mathew push {r4, lr} 31727e5238SSoby Mathew 32727e5238SSoby Mathew /* ---------------------------------------------- 33727e5238SSoby Mathew * Turn OFF cache and do stack maintenance 34727e5238SSoby Mathew * prior to cpu operations . This sequence is 35727e5238SSoby Mathew * different from AArch64 because in AArch32 the 36727e5238SSoby Mathew * assembler routines for cpu operations utilize 37727e5238SSoby Mathew * the stack whereas in AArch64 it doesn't. 38727e5238SSoby Mathew * ---------------------------------------------- 39727e5238SSoby Mathew */ 40727e5238SSoby Mathew mov r4, r0 41727e5238SSoby Mathew bl do_stack_maintenance 42727e5238SSoby Mathew 43727e5238SSoby Mathew /* --------------------------------------------- 445dd9dbb5SJeenu Viswambharan * Invoke CPU-specifc power down operations for 455dd9dbb5SJeenu Viswambharan * the appropriate level 46727e5238SSoby Mathew * --------------------------------------------- 47727e5238SSoby Mathew */ 485dd9dbb5SJeenu Viswambharan mov r0, r4 49727e5238SSoby Mathew pop {r4, lr} 505dd9dbb5SJeenu Viswambharan b prepare_cpu_pwr_dwn 51727e5238SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance 52727e5238SSoby Mathew 53727e5238SSoby Mathew 54727e5238SSoby Mathew/* ----------------------------------------------------------------------- 55727e5238SSoby Mathew * void psci_do_pwrup_cache_maintenance(void); 56727e5238SSoby Mathew * 57727e5238SSoby Mathew * This function performs cache maintenance after this cpu is powered up. 58727e5238SSoby Mathew * Currently, this involves managing the used stack memory before turning 59727e5238SSoby Mathew * on the data cache. 60727e5238SSoby Mathew * ----------------------------------------------------------------------- 61727e5238SSoby Mathew */ 62727e5238SSoby Mathewfunc psci_do_pwrup_cache_maintenance 639f3ee61cSSoby Mathew /* r12 is pushed to meet the 8 byte stack alignment requirement */ 649f3ee61cSSoby Mathew push {r12, lr} 65727e5238SSoby Mathew 66727e5238SSoby Mathew /* --------------------------------------------- 67727e5238SSoby Mathew * Ensure any inflight stack writes have made it 68727e5238SSoby Mathew * to main memory. 69727e5238SSoby Mathew * --------------------------------------------- 70727e5238SSoby Mathew */ 71727e5238SSoby Mathew dmb st 72727e5238SSoby Mathew 73727e5238SSoby Mathew /* --------------------------------------------- 74727e5238SSoby Mathew * Calculate and store the size of the used 75727e5238SSoby Mathew * stack memory in r1. Calculate and store the 76727e5238SSoby Mathew * stack base address in r0. 77727e5238SSoby Mathew * --------------------------------------------- 78727e5238SSoby Mathew */ 79727e5238SSoby Mathew bl plat_get_my_stack 80727e5238SSoby Mathew mov r1, sp 81727e5238SSoby Mathew sub r1, r0, r1 82727e5238SSoby Mathew mov r0, sp 83727e5238SSoby Mathew bl inv_dcache_range 84727e5238SSoby Mathew 85727e5238SSoby Mathew /* --------------------------------------------- 86727e5238SSoby Mathew * Enable the data cache. 87727e5238SSoby Mathew * --------------------------------------------- 88727e5238SSoby Mathew */ 89727e5238SSoby Mathew ldcopr r0, SCTLR 90727e5238SSoby Mathew orr r0, r0, #SCTLR_C_BIT 91727e5238SSoby Mathew stcopr r0, SCTLR 92727e5238SSoby Mathew isb 93727e5238SSoby Mathew 94*26441030SAntonio Nino Diaz#if PLAT_XLAT_TABLES_DYNAMIC 95*26441030SAntonio Nino Diaz /* --------------------------------------------- 96*26441030SAntonio Nino Diaz * During warm boot the MMU is enabled with data 97*26441030SAntonio Nino Diaz * cache disabled, then the interconnect is set 98*26441030SAntonio Nino Diaz * up and finally the data cache is enabled. 99*26441030SAntonio Nino Diaz * 100*26441030SAntonio Nino Diaz * During this period, if another CPU modifies 101*26441030SAntonio Nino Diaz * the translation tables, the MMU table walker 102*26441030SAntonio Nino Diaz * may read the old entries. This is only a 103*26441030SAntonio Nino Diaz * problem for dynamic regions, the warm boot 104*26441030SAntonio Nino Diaz * code isn't affected because it is static. 105*26441030SAntonio Nino Diaz * 106*26441030SAntonio Nino Diaz * Invalidate all TLB entries loaded while the 107*26441030SAntonio Nino Diaz * CPU wasn't coherent with the rest of the 108*26441030SAntonio Nino Diaz * system. 109*26441030SAntonio Nino Diaz * --------------------------------------------- 110*26441030SAntonio Nino Diaz */ 111*26441030SAntonio Nino Diaz stcopr r0, TLBIALL 112*26441030SAntonio Nino Diaz dsb ish 113*26441030SAntonio Nino Diaz isb 114*26441030SAntonio Nino Diaz#endif 115*26441030SAntonio Nino Diaz 1169f3ee61cSSoby Mathew pop {r12, pc} 117727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance 118727e5238SSoby Mathew 119727e5238SSoby Mathew /* --------------------------------------------- 120727e5238SSoby Mathew * void do_stack_maintenance(void) 121727e5238SSoby Mathew * Do stack maintenance by flushing the used 122727e5238SSoby Mathew * stack to the main memory and invalidating the 123727e5238SSoby Mathew * remainder. 124727e5238SSoby Mathew * --------------------------------------------- 125727e5238SSoby Mathew */ 126727e5238SSoby Mathewfunc do_stack_maintenance 127727e5238SSoby Mathew push {r4, lr} 128727e5238SSoby Mathew bl plat_get_my_stack 129727e5238SSoby Mathew 130727e5238SSoby Mathew /* Turn off the D-cache */ 131727e5238SSoby Mathew ldcopr r1, SCTLR 132727e5238SSoby Mathew bic r1, #SCTLR_C_BIT 133727e5238SSoby Mathew stcopr r1, SCTLR 134727e5238SSoby Mathew isb 135727e5238SSoby Mathew 136727e5238SSoby Mathew /* --------------------------------------------- 137727e5238SSoby Mathew * Calculate and store the size of the used 138727e5238SSoby Mathew * stack memory in r1. 139727e5238SSoby Mathew * --------------------------------------------- 140727e5238SSoby Mathew */ 141727e5238SSoby Mathew mov r4, r0 142727e5238SSoby Mathew mov r1, sp 143727e5238SSoby Mathew sub r1, r0, r1 144727e5238SSoby Mathew mov r0, sp 145727e5238SSoby Mathew bl flush_dcache_range 146727e5238SSoby Mathew 147727e5238SSoby Mathew /* --------------------------------------------- 148727e5238SSoby Mathew * Calculate and store the size of the unused 149727e5238SSoby Mathew * stack memory in r1. Calculate and store the 150727e5238SSoby Mathew * stack base address in r0. 151727e5238SSoby Mathew * --------------------------------------------- 152727e5238SSoby Mathew */ 153727e5238SSoby Mathew sub r0, r4, #PLATFORM_STACK_SIZE 154727e5238SSoby Mathew sub r1, sp, r0 155727e5238SSoby Mathew bl inv_dcache_range 156727e5238SSoby Mathew 157727e5238SSoby Mathew pop {r4, pc} 158727e5238SSoby Mathewendfunc do_stack_maintenance 159727e5238SSoby Mathew 160727e5238SSoby Mathew/* ----------------------------------------------------------------------- 161727e5238SSoby Mathew * This function is called to indicate to the power controller that it 162727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will 163727e5238SSoby Mathew * be released from reset upon power up. 164727e5238SSoby Mathew * ----------------------------------------------------------------------- 165727e5238SSoby Mathew */ 166727e5238SSoby Mathewfunc psci_power_down_wfi 167727e5238SSoby Mathew dsb sy // ensure write buffer empty 168727e5238SSoby Mathew wfi 169a806dad5SJeenu Viswambharan no_ret plat_panic_handler 170727e5238SSoby Mathewendfunc psci_power_down_wfi 171