trapentry.S 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. #include "mem.h"
  2. /* This file was provided by the RISCV project at UC Berkeley. */
  3. #define PT_IP 0
  4. #define PT_SP 8
  5. #define PT_GP 16
  6. #define PT_TP 24
  7. #define PT_T0 32
  8. #define PT_T1 40
  9. #define PT_T2 48
  10. #define PT_S0 56
  11. #define PT_S1 64
  12. #define PT_A0 72
  13. #define PT_A1 80
  14. #define PT_A2 88
  15. #define PT_A3 96
  16. #define PT_A4 104
  17. #define PT_A5 112
  18. #define PT_A6 120
  19. #define PT_A7 128
  20. #define PT_S2 136
  21. #define PT_S3 144
  22. #define PT_S4 152
  23. #define PT_S5 160
  24. #define PT_S6 168
  25. #define PT_S7 176
  26. #define PT_S8 184
  27. #define PT_S9 192
  28. #define PT_S10 200
  29. #define PT_S11 208
  30. #define PT_T3 216
  31. #define PT_T4 224
  32. #define PT_T5 232
  33. #define PT_T6 240
  34. #define PT_SSTATUS 248
  35. #define PT_SEPC 256
  36. #define PT_SBADADDR 264
  37. #define PT_SCAUSE 272
  38. #define PT_SINSNN 280
  39. #define PT_SFTYPE 296
  40. .text
  41. .altmacro
  42. .macro SAVE_ALL
  43. LOCAL _restore_kernel_sp
  44. LOCAL _save_context
  45. addi sp, sp, -304
  46. sd x1, PT_IP(sp)
  47. sd x3, PT_GP(sp)
  48. sd x5, PT_T0(sp)
  49. sd x6, PT_T1(sp)
  50. sd x7, PT_T2(sp)
  51. sd x8, PT_S0(sp)
  52. sd x9, PT_S1(sp)
  53. sd x10, PT_A0(sp)
  54. sd x11, PT_A1(sp)
  55. sd x12, PT_A2(sp)
  56. sd x13, PT_A3(sp)
  57. sd x14, PT_A4(sp)
  58. sd x15, PT_A5(sp)
  59. sd x16, PT_A6(sp)
  60. sd x17, PT_A7(sp)
  61. sd x18, PT_S2(sp)
  62. sd x19, PT_S3(sp)
  63. sd x20, PT_S4(sp)
  64. sd x21, PT_S5(sp)
  65. sd x22, PT_S6(sp)
  66. sd x23, PT_S7(sp)
  67. sd x24, PT_S8(sp)
  68. sd x25, PT_S9(sp)
  69. sd x26, PT_S10(sp)
  70. sd x27, PT_S11(sp)
  71. sd x28, PT_T3(sp)
  72. sd x29, PT_T4(sp)
  73. sd x30, PT_T5(sp)
  74. sd x31, PT_T6(sp)
  75. /* Disable FPU to detect illegal usage of
  76. floating point in kernel space */
  77. //li t0, SR_FS
  78. csrr s0, sscratch
  79. csrrc s1, sstatus, t0
  80. csrr s2, sepc
  81. csrr s3, 0x143 /* and someday ... sbadaddr*/
  82. csrr s4, 0x142 //scause
  83. sd s0, PT_SP(sp)
  84. sd s1, PT_SSTATUS(sp)
  85. sd s2, PT_SEPC(sp)
  86. sd s3, PT_SBADADDR(sp)
  87. sd s4, PT_SCAUSE(sp)
  88. .endm
  89. .macro RESTORE_ALL
  90. ld a0, PT_SSTATUS(sp)
  91. ld a2, PT_SEPC(sp)
  92. csrw sstatus, a0
  93. csrw sepc, a2
  94. ld x1, PT_IP(sp)
  95. ld x3, PT_GP(sp)
  96. ld x5, PT_T0(sp)
  97. ld x6, PT_T1(sp)
  98. ld x7, PT_T2(sp)
  99. ld x8, PT_S0(sp)
  100. ld x9, PT_S1(sp)
  101. ld x10, PT_A0(sp)
  102. ld x11, PT_A1(sp)
  103. ld x12, PT_A2(sp)
  104. ld x13, PT_A3(sp)
  105. ld x14, PT_A4(sp)
  106. ld x15, PT_A5(sp)
  107. ld x16, PT_A6(sp)
  108. ld x17, PT_A7(sp)
  109. ld x18, PT_S2(sp)
  110. ld x19, PT_S3(sp)
  111. ld x20, PT_S4(sp)
  112. ld x21, PT_S5(sp)
  113. ld x22, PT_S6(sp)
  114. ld x23, PT_S7(sp)
  115. ld x24, PT_S8(sp)
  116. ld x25, PT_S9(sp)
  117. ld x26, PT_S10(sp)
  118. ld x27, PT_S11(sp)
  119. ld x28, PT_T3(sp)
  120. ld x29, PT_T4(sp)
  121. ld x30, PT_T5(sp)
  122. ld x31, PT_T6(sp)
  123. .endm
  124. /* we just figure out early whether it's user or not, and branch to totally different code paths.
  125. * it's just easier that way, even though there's duplication of code.
  126. * At this level, duplication is not such a problem since, once written, this kind of code never changes.
  127. */
  128. .globl supervisor_trap_entry
  129. supervisor_trap_entry:
  130. /* If coming from userspace, preserve the user stack pointer and load
  131. the kernel stack pointer. If we came from the kernel, sscratch
  132. will contain 0, and we should continue on the current stack. */
  133. csrrw sp, sscratch, sp
  134. /* if it is 0 we were in kernel mode. */
  135. beqz sp, kernel
  136. sd tp, 32(sp) // rathole.
  137. mv tp, sp
  138. ld sp, 16(sp) // Proc
  139. ld sp, 280(sp) // kstack
  140. addi sp, sp, 1024
  141. addi sp, sp, 1024
  142. addi sp, sp, 1024
  143. addi sp, sp, 1024
  144. addi sp, sp, 1024
  145. addi sp, sp, 1024
  146. addi sp, sp, 1024
  147. SAVE_ALL
  148. // tp is special, we don't want to touch it in kernel interrupts.
  149. ld x1, 32(tp)
  150. sd x1, PT_TP(sp)
  151. /* Set sscratch register to 0, so that if a recursive exception
  152. occurs, the exception vector knows it came from the kernel */
  153. csrw sscratch, x0
  154. la ra, user_ret_from_exception
  155. /* MSB of cause differentiates between
  156. interrupts and exceptions */
  157. bge s4, zero, 1f
  158. /* Handle interrupts */
  159. move a0, sp /* pt_regs */
  160. tail _trap
  161. 1:
  162. /* Handle syscalls */
  163. li t0, 8
  164. beq s4, t0, user_handle_syscall
  165. move a0, sp /* pt_regs */
  166. tail _trap
  167. user_handle_syscall:
  168. /* Advance SEPC to avoid executing the original
  169. scall instruction on sret */
  170. addi s2, s2, 0x4
  171. sd s2, PT_SEPC(sp)
  172. /* System calls run with interrupts enabled */
  173. csrs sstatus, 1/*SR_IE*/
  174. move a1, sp /* pt_regs */
  175. ld a0, PT_A7(sp)
  176. call syscall
  177. user_ret_from_syscall:
  178. user_ret_from_exception:
  179. #define sstatus 0x100
  180. #define siebitno 1
  181. // splhi
  182. li a0, siebitno
  183. csrrs a0, sstatus, a0
  184. /* Put Mach pointer in sscratch in for user mode. */
  185. csrw sscratch, tp
  186. user_restore_all:
  187. RESTORE_ALL
  188. ld x4, PT_TP(sp)
  189. ld x2, PT_SP(sp)
  190. /* FUUUUUUCCCCCKKKKK */
  191. /* someday this toolchain will be done. */
  192. .long 0x10200073
  193. sret
  194. .globl _sysrforkret
  195. _sysrforkret:
  196. addi sp, sp, 32
  197. sd x0, PT_A0(sp)
  198. tail user_ret_from_syscall
  199. kernel:
  200. csrrw sp, sscratch, sp
  201. //csrr sp, sscratch
  202. SAVE_ALL
  203. la ra, kernel_ret_from_exception
  204. /* MSB of cause differentiates between
  205. interrupts and exceptions */
  206. bge s4, zero, 1f
  207. /* Handle interrupts */
  208. move a0, sp /* pt_regs */
  209. tail _trap
  210. 1:
  211. /* Handle syscalls */
  212. li t0, 8
  213. beq s4, t0, kernel_handle_syscall
  214. move a0, sp /* pt_regs */
  215. tail _trap
  216. kernel_handle_syscall:
  217. // TODO: panic: syscall in kernel mode.
  218. j kernel_handle_syscall
  219. kernel_ret_from_exception:
  220. #define sstatus 0x100
  221. #define siebitno 1
  222. // splhi
  223. li a0, siebitno
  224. csrrc a0, sstatus, a0
  225. kernel_restore_all:
  226. RESTORE_ALL
  227. addi sp, sp, 304
  228. /* FUUUUUUCCCCCKKKKK */
  229. /* someday this toolchain will be done. */
  230. .long 0x10200073
  231. sret
  232. #if 0
  233. END(handle_exception)
  234. ENTRY(ret_from_fork)
  235. la ra, ret_from_exception
  236. tail schedule_tail
  237. ENDPROC(ret_from_fork)
  238. /*
  239. * Integer register context switch
  240. * The callee-saved registers must be saved and restored.
  241. *
  242. * a0: previous task_struct (must be preserved across the switch)
  243. * a1: next task_struct
  244. */
  245. ENTRY(__switch_to)
  246. /* Save context into prev->thread */
  247. sd ra, THREAD_RA(a0)
  248. sd sp, THREAD_SP(a0)
  249. sd s0, THREAD_S0(a0)
  250. sd s1, THREAD_S1(a0)
  251. sd s2, THREAD_S2(a0)
  252. sd s3, THREAD_S3(a0)
  253. sd s4, THREAD_S4(a0)
  254. sd s5, THREAD_S5(a0)
  255. sd s6, THREAD_S6(a0)
  256. sd s7, THREAD_S7(a0)
  257. sd s8, THREAD_S8(a0)
  258. sd s9, THREAD_S9(a0)
  259. sd s10, THREAD_S10(a0)
  260. sd s11, THREAD_S11(a0)
  261. /* Restore context from next->thread */
  262. ld ra, THREAD_RA(a1)
  263. ld sp, THREAD_SP(a1)
  264. ld s0, THREAD_S0(a1)
  265. ld s1, THREAD_S1(a1)
  266. ld s2, THREAD_S2(a1)
  267. ld s3, THREAD_S3(a1)
  268. ld s4, THREAD_S4(a1)
  269. ld s5, THREAD_S5(a1)
  270. ld s6, THREAD_S6(a1)
  271. ld s7, THREAD_S7(a1)
  272. ld s8, THREAD_S8(a1)
  273. ld s9, THREAD_S9(a1)
  274. ld s10, THREAD_S10(a1)
  275. ld s11, THREAD_S11(a1)
  276. mv tp, a1 /* Next current pointer */
  277. ret
  278. ENDPROC(__switch_to)
  279. ENTRY(__fstate_save)
  280. li t1, SR_FS
  281. csrs sstatus, t1
  282. frcsr t0
  283. fsd f0, THREAD_F0(a0)
  284. fsd f1, THREAD_F1(a0)
  285. fsd f2, THREAD_F2(a0)
  286. fsd f3, THREAD_F3(a0)
  287. fsd f4, THREAD_F4(a0)
  288. fsd f5, THREAD_F5(a0)
  289. fsd f6, THREAD_F6(a0)
  290. fsd f7, THREAD_F7(a0)
  291. fsd f8, THREAD_F8(a0)
  292. fsd f9, THREAD_F9(a0)
  293. fsd f10, THREAD_F10(a0)
  294. fsd f11, THREAD_F11(a0)
  295. fsd f12, THREAD_F12(a0)
  296. fsd f13, THREAD_F13(a0)
  297. fsd f14, THREAD_F14(a0)
  298. fsd f15, THREAD_F15(a0)
  299. fsd f16, THREAD_F16(a0)
  300. fsd f17, THREAD_F17(a0)
  301. fsd f18, THREAD_F18(a0)
  302. fsd f19, THREAD_F19(a0)
  303. fsd f20, THREAD_F20(a0)
  304. fsd f21, THREAD_F21(a0)
  305. fsd f22, THREAD_F22(a0)
  306. fsd f23, THREAD_F23(a0)
  307. fsd f24, THREAD_F24(a0)
  308. fsd f25, THREAD_F25(a0)
  309. fsd f26, THREAD_F26(a0)
  310. fsd f27, THREAD_F27(a0)
  311. fsd f28, THREAD_F28(a0)
  312. fsd f29, THREAD_F29(a0)
  313. fsd f30, THREAD_F30(a0)
  314. fsd f31, THREAD_F31(a0)
  315. sw t0, THREAD_FCSR(a0)
  316. csrc sstatus, t1
  317. ret
  318. ENDPROC(__fstate_save)
  319. ENTRY(__fstate_restore)
  320. li t1, SR_FS
  321. lw t0, THREAD_FCSR(a0)
  322. csrs sstatus, t1
  323. fld f0, THREAD_F0(a0)
  324. fld f1, THREAD_F1(a0)
  325. fld f2, THREAD_F2(a0)
  326. fld f3, THREAD_F3(a0)
  327. fld f4, THREAD_F4(a0)
  328. fld f5, THREAD_F5(a0)
  329. fld f6, THREAD_F6(a0)
  330. fld f7, THREAD_F7(a0)
  331. fld f8, THREAD_F8(a0)
  332. fld f9, THREAD_F9(a0)
  333. fld f10, THREAD_F10(a0)
  334. fld f11, THREAD_F11(a0)
  335. fld f12, THREAD_F12(a0)
  336. fld f13, THREAD_F13(a0)
  337. fld f14, THREAD_F14(a0)
  338. fld f15, THREAD_F15(a0)
  339. fld f16, THREAD_F16(a0)
  340. fld f17, THREAD_F17(a0)
  341. fld f18, THREAD_F18(a0)
  342. fld f19, THREAD_F19(a0)
  343. fld f20, THREAD_F20(a0)
  344. fld f21, THREAD_F21(a0)
  345. fld f22, THREAD_F22(a0)
  346. fld f23, THREAD_F23(a0)
  347. fld f24, THREAD_F24(a0)
  348. fld f25, THREAD_F25(a0)
  349. fld f26, THREAD_F26(a0)
  350. fld f27, THREAD_F27(a0)
  351. fld f28, THREAD_F28(a0)
  352. fld f29, THREAD_F29(a0)
  353. fld f30, THREAD_F30(a0)
  354. fld f31, THREAD_F31(a0)
  355. fscsr t0
  356. csrc sstatus, t1
  357. ret
  358. ENDPROC(__fstate_restore)
  359. .section ".rodata"
  360. /* Exception vector table */
  361. ENTRY(excp_vect_table)
  362. PTR do_trap_insn_misaligned
  363. PTR do_page_fault
  364. PTR do_trap_insn_illegal
  365. PTR do_trap_unknown
  366. PTR do_trap_unknown
  367. PTR do_page_fault
  368. PTR do_trap_unknown
  369. PTR do_page_fault
  370. PTR 0 /* handle_syscall */
  371. PTR do_trap_break
  372. excp_vect_table_end:
  373. END(excp_vect_table)
  374. #endif