1532ed618SSoby Mathew/* 2*cc94e71bSBoyan Karatotev * Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved. 3532ed618SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5532ed618SSoby Mathew */ 6532ed618SSoby Mathew 7532ed618SSoby Mathew#include <asm_macros.S> 8532ed618SSoby Mathew#include <assert_macros.S> 9db9ee834SBoyan Karatotev#include <cpu_macros.S> 1009d40e0eSAntonio Nino Diaz#include <lib/psci/psci.h> 11532ed618SSoby Mathew#include <platform_def.h> 12532ed618SSoby Mathew 13532ed618SSoby Mathew .globl psci_do_pwrdown_cache_maintenance 14532ed618SSoby Mathew .globl psci_do_pwrup_cache_maintenance 15cf0b1492SSoby Mathew .globl psci_power_down_wfi 16532ed618SSoby Mathew 17532ed618SSoby Mathew/* ----------------------------------------------------------------------- 18532ed618SSoby Mathew * void psci_do_pwrdown_cache_maintenance(unsigned int power level); 19532ed618SSoby Mathew * 20532ed618SSoby Mathew * This function performs cache maintenance for the specified power 21532ed618SSoby Mathew * level. The levels of cache affected are determined by the power 22532ed618SSoby Mathew * level which is passed as the argument i.e. level 0 results 23532ed618SSoby Mathew * in a flush of the L1 cache. Both the L1 and L2 caches are flushed 24532ed618SSoby Mathew * for a higher power level. 25532ed618SSoby Mathew * 26532ed618SSoby Mathew * Additionally, this function also ensures that stack memory is correctly 27532ed618SSoby Mathew * flushed out to avoid coherency issues due to a change in its memory 28532ed618SSoby Mathew * attributes after the data cache is disabled. 29532ed618SSoby Mathew * ----------------------------------------------------------------------- 30532ed618SSoby Mathew */ 31532ed618SSoby Mathewfunc psci_do_pwrdown_cache_maintenance 32532ed618SSoby Mathew stp x29, x30, [sp,#-16]! 33532ed618SSoby Mathew stp x19, x20, [sp,#-16]! 34532ed618SSoby Mathew 35532ed618SSoby Mathew /* --------------------------------------------- 365dd9dbb5SJeenu Viswambharan * Invoke CPU-specific power down operations for 375dd9dbb5SJeenu Viswambharan * the appropriate level 38532ed618SSoby Mathew * --------------------------------------------- 39532ed618SSoby Mathew */ 405dd9dbb5SJeenu Viswambharan bl prepare_cpu_pwr_dwn 41532ed618SSoby Mathew 42532ed618SSoby Mathew /* --------------------------------------------- 43532ed618SSoby Mathew * Do stack maintenance by flushing the used 44532ed618SSoby Mathew * stack to the main memory and invalidating the 45532ed618SSoby Mathew * remainder. 46532ed618SSoby Mathew * --------------------------------------------- 47532ed618SSoby Mathew */ 48532ed618SSoby Mathew bl plat_get_my_stack 49532ed618SSoby Mathew 50532ed618SSoby Mathew /* --------------------------------------------- 51532ed618SSoby Mathew * Calculate and store the size of the used 52532ed618SSoby Mathew * stack memory in x1. 53532ed618SSoby Mathew * --------------------------------------------- 54532ed618SSoby Mathew */ 55532ed618SSoby Mathew mov x19, x0 56532ed618SSoby Mathew mov x1, sp 57532ed618SSoby Mathew sub x1, x0, x1 58532ed618SSoby Mathew mov x0, sp 59532ed618SSoby Mathew bl flush_dcache_range 60532ed618SSoby Mathew 61532ed618SSoby Mathew /* --------------------------------------------- 62532ed618SSoby Mathew * Calculate and store the size of the unused 63532ed618SSoby Mathew * stack memory in x1. Calculate and store the 64532ed618SSoby Mathew * stack base address in x0. 65532ed618SSoby Mathew * --------------------------------------------- 66532ed618SSoby Mathew */ 67532ed618SSoby Mathew sub x0, x19, #PLATFORM_STACK_SIZE 68532ed618SSoby Mathew sub x1, sp, x0 69532ed618SSoby Mathew bl inv_dcache_range 70532ed618SSoby Mathew 71532ed618SSoby Mathew ldp x19, x20, [sp], #16 72532ed618SSoby Mathew ldp x29, x30, [sp], #16 73532ed618SSoby Mathew ret 74532ed618SSoby Mathewendfunc psci_do_pwrdown_cache_maintenance 75532ed618SSoby Mathew 76532ed618SSoby Mathew 77532ed618SSoby Mathew/* ----------------------------------------------------------------------- 78532ed618SSoby Mathew * void psci_do_pwrup_cache_maintenance(void); 79532ed618SSoby Mathew * 80532ed618SSoby Mathew * This function performs cache maintenance after this cpu is powered up. 81532ed618SSoby Mathew * Currently, this involves managing the used stack memory before turning 82532ed618SSoby Mathew * on the data cache. 83532ed618SSoby Mathew * ----------------------------------------------------------------------- 84532ed618SSoby Mathew */ 85532ed618SSoby Mathewfunc psci_do_pwrup_cache_maintenance 86532ed618SSoby Mathew stp x29, x30, [sp,#-16]! 87532ed618SSoby Mathew 88532ed618SSoby Mathew /* --------------------------------------------- 89532ed618SSoby Mathew * Ensure any inflight stack writes have made it 90532ed618SSoby Mathew * to main memory. 91532ed618SSoby Mathew * --------------------------------------------- 92532ed618SSoby Mathew */ 93532ed618SSoby Mathew dmb st 94532ed618SSoby Mathew 95532ed618SSoby Mathew /* --------------------------------------------- 96532ed618SSoby Mathew * Calculate and store the size of the used 97532ed618SSoby Mathew * stack memory in x1. Calculate and store the 98532ed618SSoby Mathew * stack base address in x0. 99532ed618SSoby Mathew * --------------------------------------------- 100532ed618SSoby Mathew */ 101532ed618SSoby Mathew bl plat_get_my_stack 102532ed618SSoby Mathew mov x1, sp 103532ed618SSoby Mathew sub x1, x0, x1 104532ed618SSoby Mathew mov x0, sp 105532ed618SSoby Mathew bl inv_dcache_range 106532ed618SSoby Mathew 107532ed618SSoby Mathew /* --------------------------------------------- 108532ed618SSoby Mathew * Enable the data cache. 109532ed618SSoby Mathew * --------------------------------------------- 110532ed618SSoby Mathew */ 111532ed618SSoby Mathew mrs x0, sctlr_el3 112532ed618SSoby Mathew orr x0, x0, #SCTLR_C_BIT 113532ed618SSoby Mathew msr sctlr_el3, x0 114532ed618SSoby Mathew isb 115532ed618SSoby Mathew 116532ed618SSoby Mathew ldp x29, x30, [sp], #16 117532ed618SSoby Mathew ret 118532ed618SSoby Mathewendfunc psci_do_pwrup_cache_maintenance 119cf0b1492SSoby Mathew 120cf0b1492SSoby Mathew/* ----------------------------------------------------------------------- 121cf0b1492SSoby Mathew * void psci_power_down_wfi(void); 122cf0b1492SSoby Mathew * This function is called to indicate to the power controller that it 123cf0b1492SSoby Mathew * is safe to power down this cpu. It should not exit the wfi and will 124cf0b1492SSoby Mathew * be released from reset upon power up. 125cf0b1492SSoby Mathew * ----------------------------------------------------------------------- 126cf0b1492SSoby Mathew */ 127cf0b1492SSoby Mathewfunc psci_power_down_wfi 128db9ee834SBoyan Karatotev apply_erratum cortex_a510, ERRATUM(2684597), ERRATA_A510_2684597 129db9ee834SBoyan Karatotev 130cf0b1492SSoby Mathew dsb sy // ensure write buffer empty 131695a48b5SHarrison Mutai1: 132cf0b1492SSoby Mathew wfi 133695a48b5SHarrison Mutai b 1b 134*cc94e71bSBoyan Karatotev 135*cc94e71bSBoyan Karatotev /* 136*cc94e71bSBoyan Karatotev * in case the WFI wasn't terminal, we have to undo errata mitigations. 137*cc94e71bSBoyan Karatotev * These will be smart enough to handle being called the same way 138*cc94e71bSBoyan Karatotev */ 139*cc94e71bSBoyan Karatotev apply_erratum cortex_a710, ERRATUM(2291219), ERRATA_A710_2291219 140*cc94e71bSBoyan Karatotev apply_erratum cortex_x3, ERRATUM(2313909), ERRATA_X3_2313909, NO_GET_CPU_REV 141*cc94e71bSBoyan Karatotev apply_erratum neoverse_n2, ERRATUM(2326639), ERRATA_N2_2326639, NO_GET_CPU_REV 142cf0b1492SSoby Mathewendfunc psci_power_down_wfi 143