suspend_entry.S 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2021 Western Digital Corporation or its affiliates.
  4. * Copyright (c) 2022 Ventana Micro Systems Inc.
  5. */
  6. #include <linux/linkage.h>
  7. #include <asm/asm.h>
  8. #include <asm/asm-offsets.h>
  9. #include <asm/csr.h>
  10. #include <asm/xip_fixup.h>
  11. .text
  12. .altmacro
  13. .option norelax
  14. ENTRY(__cpu_suspend_enter)
  15. /* Save registers (except A0 and T0-T6) */
  16. REG_S ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
  17. REG_S sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
  18. REG_S gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
  19. REG_S tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
  20. REG_S s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
  21. REG_S s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
  22. REG_S a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
  23. REG_S a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
  24. REG_S a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
  25. REG_S a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
  26. REG_S a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
  27. REG_S a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
  28. REG_S a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
  29. REG_S s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
  30. REG_S s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
  31. REG_S s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
  32. REG_S s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
  33. REG_S s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
  34. REG_S s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
  35. REG_S s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
  36. REG_S s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
  37. REG_S s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
  38. REG_S s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
  39. /* Save CSRs */
  40. csrr t0, CSR_EPC
  41. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
  42. csrr t0, CSR_STATUS
  43. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
  44. csrr t0, CSR_TVAL
  45. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
  46. csrr t0, CSR_CAUSE
  47. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
  48. /* Return non-zero value */
  49. li a0, 1
  50. /* Return to C code */
  51. ret
  52. END(__cpu_suspend_enter)
  53. ENTRY(__cpu_resume_enter)
  54. /* Load the global pointer */
  55. .option push
  56. .option norelax
  57. la gp, __global_pointer$
  58. .option pop
  59. #ifdef CONFIG_MMU
  60. /* Save A0 and A1 */
  61. add t0, a0, zero
  62. add t1, a1, zero
  63. /* Enable MMU */
  64. la a0, swapper_pg_dir
  65. XIP_FIXUP_OFFSET a0
  66. call relocate_enable_mmu
  67. /* Restore A0 and A1 */
  68. add a0, t0, zero
  69. add a1, t1, zero
  70. #endif
  71. /* Make A0 point to suspend context */
  72. add a0, a1, zero
  73. /* Restore CSRs */
  74. REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
  75. csrw CSR_EPC, t0
  76. REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
  77. csrw CSR_STATUS, t0
  78. REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
  79. csrw CSR_TVAL, t0
  80. REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
  81. csrw CSR_CAUSE, t0
  82. /* Restore registers (except A0 and T0-T6) */
  83. REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
  84. REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
  85. REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
  86. REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
  87. REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
  88. REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
  89. REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
  90. REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
  91. REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
  92. REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
  93. REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
  94. REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
  95. REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
  96. REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
  97. REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
  98. REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
  99. REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
  100. REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
  101. REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
  102. REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
  103. REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
  104. REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
  105. REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
  106. /* Return zero value */
  107. add a0, zero, zero
  108. /* Return to C code */
  109. ret
  110. END(__cpu_resume_enter)