1727e5238SSoby Mathew/* 2727e5238SSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3727e5238SSoby Mathew * 4*82cb2c1aSdp-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 949f3ee61cSSoby Mathew pop {r12, pc} 95727e5238SSoby Mathewendfunc psci_do_pwrup_cache_maintenance 96727e5238SSoby Mathew 97727e5238SSoby Mathew /* --------------------------------------------- 98727e5238SSoby Mathew * void do_stack_maintenance(void) 99727e5238SSoby Mathew * Do stack maintenance by flushing the used 100727e5238SSoby Mathew * stack to the main memory and invalidating the 101727e5238SSoby Mathew * remainder. 102727e5238SSoby Mathew * --------------------------------------------- 103727e5238SSoby Mathew */ 104727e5238SSoby Mathewfunc do_stack_maintenance 105727e5238SSoby Mathew push {r4, lr} 106727e5238SSoby Mathew bl plat_get_my_stack 107727e5238SSoby Mathew 108727e5238SSoby Mathew /* Turn off the D-cache */ 109727e5238SSoby Mathew ldcopr r1, SCTLR 110727e5238SSoby Mathew bic r1, #SCTLR_C_BIT 111727e5238SSoby Mathew stcopr r1, SCTLR 112727e5238SSoby Mathew isb 113727e5238SSoby Mathew 114727e5238SSoby Mathew /* --------------------------------------------- 115727e5238SSoby Mathew * Calculate and store the size of the used 116727e5238SSoby Mathew * stack memory in r1. 117727e5238SSoby Mathew * --------------------------------------------- 118727e5238SSoby Mathew */ 119727e5238SSoby Mathew mov r4, r0 120727e5238SSoby Mathew mov r1, sp 121727e5238SSoby Mathew sub r1, r0, r1 122727e5238SSoby Mathew mov r0, sp 123727e5238SSoby Mathew bl flush_dcache_range 124727e5238SSoby Mathew 125727e5238SSoby Mathew /* --------------------------------------------- 126727e5238SSoby Mathew * Calculate and store the size of the unused 127727e5238SSoby Mathew * stack memory in r1. Calculate and store the 128727e5238SSoby Mathew * stack base address in r0. 129727e5238SSoby Mathew * --------------------------------------------- 130727e5238SSoby Mathew */ 131727e5238SSoby Mathew sub r0, r4, #PLATFORM_STACK_SIZE 132727e5238SSoby Mathew sub r1, sp, r0 133727e5238SSoby Mathew bl inv_dcache_range 134727e5238SSoby Mathew 135727e5238SSoby Mathew pop {r4, pc} 136727e5238SSoby Mathewendfunc do_stack_maintenance 137727e5238SSoby Mathew 138727e5238SSoby Mathew/* ----------------------------------------------------------------------- 139727e5238SSoby Mathew * This function is called to indicate to the power controller that it 140727e5238SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will 141727e5238SSoby Mathew * be released from reset upon power up. 142727e5238SSoby Mathew * ----------------------------------------------------------------------- 143727e5238SSoby Mathew */ 144727e5238SSoby Mathewfunc psci_power_down_wfi 145727e5238SSoby Mathew dsb sy // ensure write buffer empty 146727e5238SSoby Mathew wfi 147a806dad5SJeenu Viswambharan no_ret plat_panic_handler 148727e5238SSoby Mathewendfunc psci_power_down_wfi 149