suspend_entry.S 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 <linux/cfi_types.h>
  8. #include <asm/asm.h>
  9. #include <asm/asm-offsets.h>
  10. #include <asm/assembler.h>
  11. #include <asm/csr.h>
  12. #include <asm/xip_fixup.h>
  13. .text
  14. .altmacro
  15. .option norelax
  16. SYM_FUNC_START(__cpu_suspend_enter)
  17. /* Save registers (except A0 and T0-T6) */
  18. REG_S ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
  19. REG_S sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
  20. REG_S gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
  21. REG_S tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
  22. REG_S s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
  23. REG_S s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
  24. REG_S a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
  25. REG_S a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
  26. REG_S a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
  27. REG_S a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
  28. REG_S a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
  29. REG_S a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
  30. REG_S a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
  31. REG_S s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
  32. REG_S s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
  33. REG_S s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
  34. REG_S s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
  35. REG_S s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
  36. REG_S s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
  37. REG_S s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
  38. REG_S s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
  39. REG_S s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
  40. REG_S s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
  41. /* Save CSRs */
  42. csrr t0, CSR_EPC
  43. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
  44. csrr t0, CSR_STATUS
  45. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
  46. csrr t0, CSR_TVAL
  47. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
  48. csrr t0, CSR_CAUSE
  49. REG_S t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
  50. /* Return non-zero value */
  51. li a0, 1
  52. /* Return to C code */
  53. ret
  54. SYM_FUNC_END(__cpu_suspend_enter)
  55. SYM_TYPED_FUNC_START(__cpu_resume_enter)
  56. /* Load the global pointer */
  57. load_global_pointer
  58. #ifdef CONFIG_MMU
  59. /* Save A0 and A1 */
  60. add t0, a0, zero
  61. add t1, a1, zero
  62. /* Enable MMU */
  63. la a0, swapper_pg_dir
  64. XIP_FIXUP_OFFSET a0
  65. call relocate_enable_mmu
  66. /* Restore A0 and A1 */
  67. add a0, t0, zero
  68. add a1, t1, zero
  69. #endif
  70. /* Make A0 point to suspend context */
  71. add a0, a1, zero
  72. /* Restore CSRs */
  73. suspend_restore_csrs
  74. /* Restore registers (except A0 and T0-T6) */
  75. suspend_restore_regs
  76. /* Return zero value */
  77. add a0, zero, zero
  78. /* Return to C code */
  79. ret
  80. SYM_FUNC_END(__cpu_resume_enter)