context_gcc.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. * void rt_hw_context_switch_to(rt_ubase_t to);
  67. *
  68. * a0 --> to SP pointer
  69. */
  70. .globl rt_hw_context_switch_to
  71. rt_hw_context_switch_to:
  72. LOAD sp, (a0)
  73. call rt_thread_self
  74. mv s1, a0
  75. #ifdef RT_USING_SMART
  76. call lwp_aspace_switch
  77. #endif
  78. RESTORE_CONTEXT
  79. sret
  80. /*
  81. * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
  82. *
  83. * a0 --> from SP pointer
  84. * a1 --> to SP pointer
  85. *
  86. * It should only be used on local interrupt disable
  87. */
  88. .globl rt_hw_context_switch
  89. rt_hw_context_switch:
  90. RESERVE_CONTEXT
  91. STORE sp, (a0)
  92. // restore to thread SP
  93. LOAD sp, (a1)
  94. // restore Address Space
  95. call rt_thread_self
  96. mv s1, a0
  97. #ifdef RT_USING_SMART
  98. call lwp_aspace_switch
  99. #endif
  100. RESTORE_CONTEXT
  101. sret