psci_helpers.S 4.3 KB

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