os_cpu_a.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. .extern OSTCBCur
  9. .extern OSTCBHighRdy
  10. .extern xPortTaskSwitch
  11. .global prvPortStartFirstTask
  12. .global irqc_msip_handler
  13. .section .text.entry
  14. .align 8
  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. .section .text
  64. .align 2
  65. irqc_msip_handler:
  66. addi sp, sp, -portCONTEXT_SIZE
  67. STORE x1, 1 * REGBYTES(sp) /* RA */
  68. STORE x5, 2 * REGBYTES(sp)
  69. STORE x6, 3 * REGBYTES(sp)
  70. STORE x7, 4 * REGBYTES(sp)
  71. STORE x8, 5 * REGBYTES(sp)
  72. STORE x9, 6 * REGBYTES(sp)
  73. STORE x10, 7 * REGBYTES(sp)
  74. STORE x11, 8 * REGBYTES(sp)
  75. STORE x12, 9 * REGBYTES(sp)
  76. STORE x13, 10 * REGBYTES(sp)
  77. STORE x14, 11 * REGBYTES(sp)
  78. STORE x15, 12 * REGBYTES(sp)
  79. #ifndef __riscv_32e
  80. STORE x16, 13 * REGBYTES(sp)
  81. STORE x17, 14 * REGBYTES(sp)
  82. STORE x18, 15 * REGBYTES(sp)
  83. STORE x19, 16 * REGBYTES(sp)
  84. STORE x20, 17 * REGBYTES(sp)
  85. STORE x21, 18 * REGBYTES(sp)
  86. STORE x22, 19 * REGBYTES(sp)
  87. STORE x23, 20 * REGBYTES(sp)
  88. STORE x24, 21 * REGBYTES(sp)
  89. STORE x25, 22 * REGBYTES(sp)
  90. STORE x26, 23 * REGBYTES(sp)
  91. STORE x27, 24 * REGBYTES(sp)
  92. STORE x28, 25 * REGBYTES(sp)
  93. STORE x29, 26 * REGBYTES(sp)
  94. STORE x30, 27 * REGBYTES(sp)
  95. STORE x31, 28 * REGBYTES(sp)
  96. #endif
  97. /* Push mstatus to stack */
  98. csrr t0, CSR_MSTATUS
  99. STORE t0, (portRegNum - 1) * REGBYTES(sp)
  100. /* Push additional registers */
  101. /* Store sp to task stack */
  102. LOAD t0, OSTCBCur
  103. STORE sp, 0(t0)
  104. csrr t0, CSR_MEPC
  105. STORE t0, 0(sp)
  106. jal xPortTaskSwitch
  107. /* Switch task context */
  108. LOAD t0, OSTCBHighRdy /* Load OSTCBHighRdy. */
  109. LOAD sp, 0x0(t0) /* Read sp from first TCB member */
  110. /* Pop PC from stack and set MEPC */
  111. LOAD t0, 0 * REGBYTES(sp)
  112. csrw CSR_MEPC, t0
  113. /* Pop additional registers */
  114. /* Pop mstatus from stack and set it */
  115. LOAD t0, (portRegNum - 1) * REGBYTES(sp)
  116. csrw CSR_MSTATUS, t0
  117. /* Interrupt still disable here */
  118. /* Restore Registers from Stack */
  119. LOAD x1, 1 * REGBYTES(sp) /* RA */
  120. LOAD x5, 2 * REGBYTES(sp)
  121. LOAD x6, 3 * REGBYTES(sp)
  122. LOAD x7, 4 * REGBYTES(sp)
  123. LOAD x8, 5 * REGBYTES(sp)
  124. LOAD x9, 6 * REGBYTES(sp)
  125. LOAD x10, 7 * REGBYTES(sp)
  126. LOAD x11, 8 * REGBYTES(sp)
  127. LOAD x12, 9 * REGBYTES(sp)
  128. LOAD x13, 10 * REGBYTES(sp)
  129. LOAD x14, 11 * REGBYTES(sp)
  130. LOAD x15, 12 * REGBYTES(sp)
  131. #ifndef __riscv_32e
  132. LOAD x16, 13 * REGBYTES(sp)
  133. LOAD x17, 14 * REGBYTES(sp)
  134. LOAD x18, 15 * REGBYTES(sp)
  135. LOAD x19, 16 * REGBYTES(sp)
  136. LOAD x20, 17 * REGBYTES(sp)
  137. LOAD x21, 18 * REGBYTES(sp)
  138. LOAD x22, 19 * REGBYTES(sp)
  139. LOAD x23, 20 * REGBYTES(sp)
  140. LOAD x24, 21 * REGBYTES(sp)
  141. LOAD x25, 22 * REGBYTES(sp)
  142. LOAD x26, 23 * REGBYTES(sp)
  143. LOAD x27, 24 * REGBYTES(sp)
  144. LOAD x28, 25 * REGBYTES(sp)
  145. LOAD x29, 26 * REGBYTES(sp)
  146. LOAD x30, 27 * REGBYTES(sp)
  147. LOAD x31, 28 * REGBYTES(sp)
  148. #endif
  149. addi sp, sp, portCONTEXT_SIZE
  150. mret