Home | History | Annotate | Download | only in aarch32
      1 /*
      2  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #include <asm_macros.S>
      8 #include <platform_def.h>
      9 #include <psci.h>
     10 
     11 	.globl	psci_do_pwrdown_cache_maintenance
     12 	.globl	psci_do_pwrup_cache_maintenance
     13 	.globl	psci_power_down_wfi
     14 
     15 /* -----------------------------------------------------------------------
     16  * void psci_do_pwrdown_cache_maintenance(unsigned int power level);
     17  *
     18  * This function performs cache maintenance for the specified power
     19  * level. The levels of cache affected are determined by the power
     20  * level which is passed as the argument i.e. level 0 results
     21  * in a flush of the L1 cache. Both the L1 and L2 caches are flushed
     22  * for a higher power level.
     23  *
     24  * Additionally, this function also ensures that stack memory is correctly
     25  * flushed out to avoid coherency issues due to a change in its memory
     26  * attributes after the data cache is disabled.
     27  * -----------------------------------------------------------------------
     28  */
     29 func psci_do_pwrdown_cache_maintenance
     30 	push	{r4, lr}
     31 
     32 	/* ----------------------------------------------
     33 	 * Turn OFF cache and do stack maintenance
     34 	 * prior to cpu operations . This sequence is
     35 	 * different from AArch64 because in AArch32 the
     36 	 * assembler routines for cpu operations utilize
     37 	 * the stack whereas in AArch64 it doesn't.
     38 	 * ----------------------------------------------
     39 	 */
     40 	mov	r4, r0
     41 	bl	do_stack_maintenance
     42 
     43 	/* ---------------------------------------------
     44 	 * Invoke CPU-specifc power down operations for
     45 	 * the appropriate level
     46 	 * ---------------------------------------------
     47 	 */
     48 	mov	r0, r4
     49 	pop	{r4, lr}
     50 	b	prepare_cpu_pwr_dwn
     51 endfunc psci_do_pwrdown_cache_maintenance
     52 
     53 
     54 /* -----------------------------------------------------------------------
     55  * void psci_do_pwrup_cache_maintenance(void);
     56  *
     57  * This function performs cache maintenance after this cpu is powered up.
     58  * Currently, this involves managing the used stack memory before turning
     59  * on the data cache.
     60  * -----------------------------------------------------------------------
     61  */
     62 func psci_do_pwrup_cache_maintenance
     63 	/* r12 is pushed to meet the 8 byte stack alignment requirement */
     64 	push	{r12, lr}
     65 
     66 	/* ---------------------------------------------
     67 	 * Ensure any inflight stack writes have made it
     68 	 * to main memory.
     69 	 * ---------------------------------------------
     70 	 */
     71 	dmb	st
     72 
     73 	/* ---------------------------------------------
     74 	 * Calculate and store the size of the used
     75 	 * stack memory in r1. Calculate and store the
     76 	 * stack base address in r0.
     77 	 * ---------------------------------------------
     78 	 */
     79 	bl	plat_get_my_stack
     80 	mov	r1, sp
     81 	sub	r1, r0, r1
     82 	mov	r0, sp
     83 	bl	inv_dcache_range
     84 
     85 	/* ---------------------------------------------
     86 	 * Enable the data cache.
     87 	 * ---------------------------------------------
     88 	 */
     89 	ldcopr	r0, SCTLR
     90 	orr	r0, r0, #SCTLR_C_BIT
     91 	stcopr	r0, SCTLR
     92 	isb
     93 
     94 	pop	{r12, pc}
     95 endfunc psci_do_pwrup_cache_maintenance
     96 
     97 	/* ---------------------------------------------
     98 	 * void do_stack_maintenance(void)
     99 	 * Do stack maintenance by flushing the used
    100 	 * stack to the main memory and invalidating the
    101 	 * remainder.
    102 	 * ---------------------------------------------
    103 	 */
    104 func do_stack_maintenance
    105 	push	{r4, lr}
    106 	bl	plat_get_my_stack
    107 
    108 	/* Turn off the D-cache */
    109 	ldcopr	r1, SCTLR
    110 	bic	r1, #SCTLR_C_BIT
    111 	stcopr	r1, SCTLR
    112 	isb
    113 
    114 	/* ---------------------------------------------
    115 	 * Calculate and store the size of the used
    116 	 * stack memory in r1.
    117 	 * ---------------------------------------------
    118 	 */
    119 	mov	r4, r0
    120 	mov	r1, sp
    121 	sub	r1, r0, r1
    122 	mov	r0, sp
    123 	bl	flush_dcache_range
    124 
    125 	/* ---------------------------------------------
    126 	 * Calculate and store the size of the unused
    127 	 * stack memory in r1. Calculate and store the
    128 	 * stack base address in r0.
    129 	 * ---------------------------------------------
    130 	 */
    131 	sub	r0, r4, #PLATFORM_STACK_SIZE
    132 	sub	r1, sp, r0
    133 	bl	inv_dcache_range
    134 
    135 	pop	{r4, pc}
    136 endfunc do_stack_maintenance
    137 
    138 /* -----------------------------------------------------------------------
    139  * This function is called to indicate to the power controller that it
    140  * is safe to power down this cpu. It should not exit the wfi and will
    141  * be released from reset upon power up.
    142  * -----------------------------------------------------------------------
    143  */
    144 func psci_power_down_wfi
    145 	dsb	sy		// ensure write buffer empty
    146 	wfi
    147 	no_ret	plat_panic_handler
    148 endfunc psci_power_down_wfi
    149