trap.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. .altmacro
  2. .macro SAVE_GP n
  3. sd x\n, \n*8(sp)
  4. .endm
  5. .macro LOAD_GP n
  6. ld x\n, \n*8(sp)
  7. .endm
  8. .section .text
  9. .globl trap_from_kernel
  10. .globl trap_from_user
  11. .globl return_to_user
  12. .align 2
  13. # just like a function call
  14. trap_from_kernel:
  15. # save s*
  16. addi sp, sp, -17*8
  17. sd ra, 1*8(sp)
  18. sd t0, 2*8(sp)
  19. sd t1, 3*8(sp)
  20. sd t2, 4*8(sp)
  21. sd t3, 5*8(sp)
  22. sd t4, 6*8(sp)
  23. sd t5, 7*8(sp)
  24. sd t6, 8*8(sp)
  25. sd a0, 9*8(sp)
  26. sd a1, 10*8(sp)
  27. sd a2, 11*8(sp)
  28. sd a3, 12*8(sp)
  29. sd a4, 13*8(sp)
  30. sd a5, 14*8(sp)
  31. sd a6, 15*8(sp)
  32. sd a7, 16*8(sp)
  33. call kernel_trap_entry
  34. # restore s*
  35. ld ra, 1*8(sp)
  36. ld t0, 2*8(sp)
  37. ld t1, 3*8(sp)
  38. ld t2, 4*8(sp)
  39. ld t3, 5*8(sp)
  40. ld t4, 6*8(sp)
  41. ld t5, 7*8(sp)
  42. ld t6, 8*8(sp)
  43. ld a0, 9*8(sp)
  44. ld a1, 10*8(sp)
  45. ld a2, 11*8(sp)
  46. ld a3, 12*8(sp)
  47. ld a4, 13*8(sp)
  48. ld a5, 14*8(sp)
  49. ld a6, 15*8(sp)
  50. ld a7, 16*8(sp)
  51. addi sp, sp, 17*8
  52. sret
  53. trap_from_user:
  54. # swap sp and sscratch(previously stored user TrapContext's address in return_to_user)
  55. csrrw sp, sscratch, sp
  56. sd x1, 1*8(sp)
  57. .set n, 3
  58. .rept 29
  59. SAVE_GP %n
  60. .set n, n+1
  61. .endr
  62. csrr t0, sstatus
  63. csrr t1, sepc
  64. sd t0, 32*8(sp) # save sstatus into the TrapContext
  65. sd t1, 33*8(sp) # save sepc into the TrapContext
  66. csrr t2, sscratch
  67. sd t2, 2*8(sp) # save user stack pointer into the TrapContext
  68. ld ra, 35*8(sp)
  69. ld s0, 36*8(sp)
  70. ld s1, 37*8(sp)
  71. ld s2, 38*8(sp)
  72. ld s3, 39*8(sp)
  73. ld s4, 40*8(sp)
  74. ld s5, 41*8(sp)
  75. ld s6, 42*8(sp)
  76. ld s7, 43*8(sp)
  77. ld s8, 44*8(sp)
  78. ld s9, 45*8(sp)
  79. ld s10, 46*8(sp)
  80. ld s11, 47*8(sp)
  81. ld fp, 48*8(sp)
  82. ld tp, 49*8(sp)
  83. ld sp, 34*8(sp)
  84. ret
  85. # a0: pointer to TrapContext in user space (constant)
  86. return_to_user:
  87. # sscratch store the TrapContext's address
  88. csrw sscratch, a0
  89. # offset in TrapContext's order
  90. sd sp, 34*8(a0)
  91. sd ra, 35*8(a0)
  92. sd s0, 36*8(a0)
  93. sd s1, 37*8(a0)
  94. sd s2, 38*8(a0)
  95. sd s3, 39*8(a0)
  96. sd s4, 40*8(a0)
  97. sd s5, 41*8(a0)
  98. sd s6, 42*8(a0)
  99. sd s7, 43*8(a0)
  100. sd s8, 44*8(a0)
  101. sd s9, 45*8(a0)
  102. sd s10, 46*8(a0)
  103. sd s11, 47*8(a0)
  104. sd fp, 48*8(a0)
  105. sd tp, 49*8(a0)
  106. mv sp, a0
  107. # now sp points to TrapContext in kernel space
  108. # restore sstatus and sepc
  109. ld t0, 32*8(sp)
  110. ld t1, 33*8(sp)
  111. csrw sstatus, t0
  112. csrw sepc, t1
  113. # save x* expect x0 and sp
  114. ld x1, 1*8(sp)
  115. .set n, 3
  116. .rept 29
  117. LOAD_GP %n
  118. .set n, n+1
  119. .endr
  120. ld sp, 2*8(sp)
  121. sret