context_gcc.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/10/28 Bernard The unify RISC-V porting implementation
  9. * 2018/12/27 Jesven Add SMP support
  10. * 2021/02/02 lizhirui Add userspace support
  11. * 2022/10/22 Shell Support User mode RVV;
  12. * Trimming process switch context
  13. */
  14. #include "cpuport.h"
  15. #include "stackframe.h"
  16. #define _REG_IDX(name) RT_HW_SWITCH_CONTEXT_##name
  17. #define REG_IDX(name) _REG_IDX(name)
  18. .macro SAVE_REG reg, index
  19. STORE \reg, \index*REGBYTES(sp)
  20. .endm
  21. .macro LOAD_REG reg, index
  22. LOAD \reg, \index*REGBYTES(sp)
  23. .endm
  24. .macro RESERVE_CONTEXT
  25. addi sp, sp, -(RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES)
  26. SAVE_REG tp, REG_IDX(TP)
  27. SAVE_REG ra, REG_IDX(RA)
  28. SAVE_REG s0, REG_IDX(S0)
  29. SAVE_REG s1, REG_IDX(S1)
  30. SAVE_REG s2, REG_IDX(S2)
  31. SAVE_REG s3, REG_IDX(S3)
  32. SAVE_REG s4, REG_IDX(S4)
  33. SAVE_REG s5, REG_IDX(S5)
  34. SAVE_REG s6, REG_IDX(S6)
  35. SAVE_REG s7, REG_IDX(S7)
  36. SAVE_REG s8, REG_IDX(S8)
  37. SAVE_REG s9, REG_IDX(S9)
  38. SAVE_REG s10, REG_IDX(S10)
  39. SAVE_REG s11, REG_IDX(S11)
  40. csrr s11, sstatus
  41. li s10, (SSTATUS_SPP)
  42. or s11, s11, s10
  43. SAVE_REG s11, REG_IDX(SSTATUS)
  44. .endm
  45. .macro RESTORE_CONTEXT
  46. LOAD_REG s11, REG_IDX(SSTATUS)
  47. csrw sstatus, s11
  48. LOAD_REG s11, REG_IDX(S11)
  49. LOAD_REG s10, REG_IDX(S10)
  50. LOAD_REG s9, REG_IDX(S9)
  51. LOAD_REG s8, REG_IDX(S8)
  52. LOAD_REG s7, REG_IDX(S7)
  53. LOAD_REG s6, REG_IDX(S6)
  54. LOAD_REG s5, REG_IDX(S5)
  55. LOAD_REG s4, REG_IDX(S4)
  56. LOAD_REG s3, REG_IDX(S3)
  57. LOAD_REG s2, REG_IDX(S2)
  58. LOAD_REG s1, REG_IDX(S1)
  59. LOAD_REG s0, REG_IDX(S0)
  60. LOAD_REG ra, REG_IDX(RA)
  61. LOAD_REG tp, REG_IDX(TP)
  62. addi sp, sp, RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES
  63. csrw sepc, ra
  64. .endm
  65. /*
  66. * #ifdef RT_USING_SMP
  67. * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
  68. * #else
  69. * void rt_hw_context_switch_to(rt_ubase_t to);
  70. * #endif
  71. * a0 --> to
  72. * a1 --> to_thread
  73. */
  74. .globl rt_hw_context_switch_to
  75. rt_hw_context_switch_to:
  76. LOAD sp, (a0)
  77. #ifdef RT_USING_SMP
  78. /* Pass the previous CPU lock status to rt_cpus_lock_status_restore for restoration */
  79. mv a0, a1
  80. call rt_cpus_lock_status_restore
  81. #endif
  82. call rt_thread_self
  83. mv s1, a0
  84. #ifndef RT_USING_SMP
  85. //if enable RT_USING_SMP, it will finished by rt_cpus_lock_status_restore.
  86. #ifdef RT_USING_SMART
  87. call lwp_aspace_switch
  88. #endif
  89. #endif
  90. RESTORE_CONTEXT
  91. sret
  92. /*
  93. * #ifdef RT_USING_SMP
  94. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
  95. * #else
  96. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
  97. * #endif
  98. *
  99. * a0 --> from SP pointer
  100. * a1 --> to SP pointer
  101. * a2 --> to_thread
  102. *
  103. * It should only be used on local interrupt disable
  104. */
  105. .globl rt_hw_context_switch
  106. rt_hw_context_switch:
  107. RESERVE_CONTEXT
  108. STORE sp, (a0)
  109. // restore to thread SP
  110. LOAD sp, (a1)
  111. #ifdef RT_USING_SMP
  112. /* Pass the previous CPU lock status to rt_cpus_lock_status_restore for restoration */
  113. mv a0, a2
  114. call rt_cpus_lock_status_restore
  115. #endif /*RT_USING_SMP*/
  116. // restore Address Space
  117. call rt_thread_self
  118. mv s1, a0
  119. #ifndef RT_USING_SMP
  120. // if enable RT_USING_SMP, it will finished by rt_cpus_lock_status_restore.
  121. #ifdef RT_USING_SMART
  122. call lwp_aspace_switch
  123. #endif
  124. #endif
  125. RESTORE_CONTEXT
  126. sret