os_cpu_a.S 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "riscv_encoding.h"
  2. #ifndef __riscv_32e
  3. #define portRegNum 32
  4. #else
  5. #define portRegNum 14
  6. #endif
  7. #define portCONTEXT_SIZE ( portRegNum * REGBYTES )
  8. PUBLIC prvPortStartFirstTask, irqc_msip_handler
  9. EXTERN xPortTaskSwitch
  10. EXTERN OSTCBCur
  11. EXTERN OSTCBHighRdy
  12. EXTERN CSTACK$$Limit
  13. SECTION `.text`:CODE:NOROOT(2)
  14. CODE
  15. /* Start the first task. This also clears the bit that indicates the FPU is
  16. in use in case the FPU was used before the scheduler was started - which
  17. would otherwise result in the unnecessary leaving of space in the stack
  18. for lazy saving of FPU registers. */
  19. ALIGN 3
  20. prvPortStartFirstTask:
  21. LOAD sp, OSTCBHighRdy /* Load OSTCBHighRdy. */
  22. LOAD sp, 0x0(sp) /* Read sp from first TCB member */
  23. /* Pop PC from stack and set MEPC */
  24. LOAD t0, 0 * REGBYTES(sp)
  25. csrw CSR_MEPC, t0
  26. /* Pop mstatus from stack and set it */
  27. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  28. csrw CSR_MSTATUS, t0
  29. /* Interrupt still disable here */
  30. /* Restore Registers from Stack */
  31. LOAD x1, 1 * REGBYTES(sp) /* RA */
  32. LOAD x5, 2 * REGBYTES(sp)
  33. LOAD x6, 3 * REGBYTES(sp)
  34. LOAD x7, 4 * REGBYTES(sp)
  35. LOAD x8, 5 * REGBYTES(sp)
  36. LOAD x9, 6 * REGBYTES(sp)
  37. LOAD x10, 7 * REGBYTES(sp)
  38. LOAD x11, 8 * REGBYTES(sp)
  39. LOAD x12, 9 * REGBYTES(sp)
  40. LOAD x13, 10 * REGBYTES(sp)
  41. LOAD x14, 11 * REGBYTES(sp)
  42. LOAD x15, 12 * REGBYTES(sp)
  43. #ifndef __riscv_32e
  44. LOAD x16, 13 * REGBYTES(sp)
  45. LOAD x17, 14 * REGBYTES(sp)
  46. LOAD x18, 15 * REGBYTES(sp)
  47. LOAD x19, 16 * REGBYTES(sp)
  48. LOAD x20, 17 * REGBYTES(sp)
  49. LOAD x21, 18 * REGBYTES(sp)
  50. LOAD x22, 19 * REGBYTES(sp)
  51. LOAD x23, 20 * REGBYTES(sp)
  52. LOAD x24, 21 * REGBYTES(sp)
  53. LOAD x25, 22 * REGBYTES(sp)
  54. LOAD x26, 23 * REGBYTES(sp)
  55. LOAD x27, 24 * REGBYTES(sp)
  56. LOAD x28, 25 * REGBYTES(sp)
  57. LOAD x29, 26 * REGBYTES(sp)
  58. LOAD x30, 27 * REGBYTES(sp)
  59. LOAD x31, 28 * REGBYTES(sp)
  60. #endif
  61. addi sp, sp, portCONTEXT_SIZE
  62. mret
  63. ALIGN 2
  64. irqc_msip_handler:
  65. addi sp, sp, -portCONTEXT_SIZE
  66. STORE x1, 1 * REGBYTES(sp) /* RA */
  67. STORE x5, 2 * REGBYTES(sp)
  68. STORE x6, 3 * REGBYTES(sp)
  69. STORE x7, 4 * REGBYTES(sp)
  70. STORE x8, 5 * REGBYTES(sp)
  71. STORE x9, 6 * REGBYTES(sp)
  72. STORE x10, 7 * REGBYTES(sp)
  73. STORE x11, 8 * REGBYTES(sp)
  74. STORE x12, 9 * REGBYTES(sp)
  75. STORE x13, 10 * REGBYTES(sp)
  76. STORE x14, 11 * REGBYTES(sp)
  77. STORE x15, 12 * REGBYTES(sp)
  78. #ifndef __riscv_32e
  79. STORE x16, 13 * REGBYTES(sp)
  80. STORE x17, 14 * REGBYTES(sp)
  81. STORE x18, 15 * REGBYTES(sp)
  82. STORE x19, 16 * REGBYTES(sp)
  83. STORE x20, 17 * REGBYTES(sp)
  84. STORE x21, 18 * REGBYTES(sp)
  85. STORE x22, 19 * REGBYTES(sp)
  86. STORE x23, 20 * REGBYTES(sp)
  87. STORE x24, 21 * REGBYTES(sp)
  88. STORE x25, 22 * REGBYTES(sp)
  89. STORE x26, 23 * REGBYTES(sp)
  90. STORE x27, 24 * REGBYTES(sp)
  91. STORE x28, 25 * REGBYTES(sp)
  92. STORE x29, 26 * REGBYTES(sp)
  93. STORE x30, 27 * REGBYTES(sp)
  94. STORE x31, 28 * REGBYTES(sp)
  95. #endif
  96. /* Push mstatus to stack */
  97. csrr t0, CSR_MSTATUS
  98. STORE t0, (portRegNum - 1) * REGBYTES(sp)
  99. /* Push additional registers */
  100. /* Store sp to task stack */
  101. LOAD t0, OSTCBCur
  102. STORE sp, 0(t0)
  103. csrr t0, CSR_MEPC
  104. STORE t0, 0(sp)
  105. jal xPortTaskSwitch
  106. /* Switch task context */
  107. LOAD t0, OSTCBHighRdy /* Load OSTCBHighRdy. */
  108. LOAD sp, 0x0(t0) /* Read sp from first TCB member */
  109. /* Pop PC from stack and set MEPC */
  110. LOAD t0, 0 * REGBYTES(sp)
  111. csrw CSR_MEPC, t0
  112. /* Pop additional registers */
  113. /* Pop mstatus from stack and set it */
  114. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  115. csrw CSR_MSTATUS, t0
  116. /* Interrupt still disable here */
  117. /* Restore Registers from Stack */
  118. LOAD x1, 1 * REGBYTES(sp) /* RA */
  119. LOAD x5, 2 * REGBYTES(sp)
  120. LOAD x6, 3 * REGBYTES(sp)
  121. LOAD x7, 4 * REGBYTES(sp)
  122. LOAD x8, 5 * REGBYTES(sp)
  123. LOAD x9, 6 * REGBYTES(sp)
  124. LOAD x10, 7 * REGBYTES(sp)
  125. LOAD x11, 8 * REGBYTES(sp)
  126. LOAD x12, 9 * REGBYTES(sp)
  127. LOAD x13, 10 * REGBYTES(sp)
  128. LOAD x14, 11 * REGBYTES(sp)
  129. LOAD x15, 12 * REGBYTES(sp)
  130. #ifndef __riscv_32e
  131. LOAD x16, 13 * REGBYTES(sp)
  132. LOAD x17, 14 * REGBYTES(sp)
  133. LOAD x18, 15 * REGBYTES(sp)
  134. LOAD x19, 16 * REGBYTES(sp)
  135. LOAD x20, 17 * REGBYTES(sp)
  136. LOAD x21, 18 * REGBYTES(sp)
  137. LOAD x22, 19 * REGBYTES(sp)
  138. LOAD x23, 20 * REGBYTES(sp)
  139. LOAD x24, 21 * REGBYTES(sp)
  140. LOAD x25, 22 * REGBYTES(sp)
  141. LOAD x26, 23 * REGBYTES(sp)
  142. LOAD x27, 24 * REGBYTES(sp)
  143. LOAD x28, 25 * REGBYTES(sp)
  144. LOAD x29, 26 * REGBYTES(sp)
  145. LOAD x30, 27 * REGBYTES(sp)
  146. LOAD x31, 28 * REGBYTES(sp)
  147. #endif
  148. addi sp, sp, portCONTEXT_SIZE
  149. mret
  150. END