asm.S 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #if __riscv_xlen == 64
  2. # define STORE sd
  3. # define LOAD ld
  4. # define LOG_REGBYTES 3
  5. #else
  6. # define STORE sw
  7. # define LOAD lw
  8. # define LOG_REGBYTES 2
  9. #endif
  10. #define REGBYTES (1 << LOG_REGBYTES)
  11. /*
  12. Entry point of all programs (_start).
  13. It initializes DWARF call frame information, the stack pointer, the
  14. frame pointer (needed for closures to work in start_rust) and the global
  15. pointer. Then it calls _start_rust.
  16. */
  17. .section .init, "ax"
  18. .global _start
  19. _start:
  20. /* Jump to the absolute address defined by the linker script. */
  21. // for 32bit
  22. .if __riscv_xlen == 32
  23. lui ra, %hi(_abs_start)
  24. jr %lo(_abs_start)(ra)
  25. .endif
  26. // for 64bit
  27. .if __riscv_xlen == 64
  28. 1:
  29. auipc ra, %pcrel_hi(1f)
  30. ld ra, %pcrel_lo(1b)(ra)
  31. jr ra
  32. .align 3
  33. 1:
  34. .dword _abs_start
  35. .endif
  36. _abs_start:
  37. .cfi_startproc
  38. .cfi_undefined ra
  39. csrw mie, 0
  40. csrw mip, 0
  41. li x1, 0
  42. li x2, 0
  43. li x3, 0
  44. li x4, 0
  45. li x5, 0
  46. li x6, 0
  47. li x7, 0
  48. li x8, 0
  49. li x9, 0
  50. li x10,0
  51. li x11,0
  52. li x12,0
  53. li x13,0
  54. li x14,0
  55. li x15,0
  56. li x16,0
  57. li x17,0
  58. li x18,0
  59. li x19,0
  60. li x20,0
  61. li x21,0
  62. li x22,0
  63. li x23,0
  64. li x24,0
  65. li x25,0
  66. li x26,0
  67. li x27,0
  68. li x28,0
  69. li x29,0
  70. li x30,0
  71. li x31,0
  72. .option push
  73. .option norelax
  74. la gp, __global_pointer$
  75. .option pop
  76. // Check hart id
  77. csrr a2, mhartid
  78. lui t0, %hi(_max_hart_id)
  79. add t0, t0, %lo(_max_hart_id)
  80. bgtu a2, t0, abort
  81. // Allocate stacks
  82. la sp, _stack_start
  83. lui t0, %hi(_hart_stack_size)
  84. add t0, t0, %lo(_hart_stack_size)
  85. #ifdef __riscv_mul
  86. mul t0, a2, t0
  87. #else
  88. beqz a2, 2f // Jump if single-hart
  89. mv t1, a2
  90. mv t2, t0
  91. 1:
  92. add t0, t0, t2
  93. addi t1, t1, -1
  94. bnez t1, 1b
  95. 2:
  96. #endif
  97. sub sp, sp, t0
  98. // Set frame pointer
  99. add s0, sp, zero
  100. // Set trap handler
  101. la t0, _start_trap
  102. csrw mtvec, t0
  103. jal zero, _start_rust
  104. .cfi_endproc
  105. /*
  106. Trap entry point (_start_trap)
  107. Saves caller saved registers ra, t0..6, a0..7, calls _start_trap_rust,
  108. restores caller saved registers and then returns.
  109. */
  110. .section .trap, "ax"
  111. .global _start_trap
  112. _start_trap:
  113. addi sp, sp, -16*REGBYTES
  114. STORE ra, 0*REGBYTES(sp)
  115. STORE t0, 1*REGBYTES(sp)
  116. STORE t1, 2*REGBYTES(sp)
  117. STORE t2, 3*REGBYTES(sp)
  118. STORE t3, 4*REGBYTES(sp)
  119. STORE t4, 5*REGBYTES(sp)
  120. STORE t5, 6*REGBYTES(sp)
  121. STORE t6, 7*REGBYTES(sp)
  122. STORE a0, 8*REGBYTES(sp)
  123. STORE a1, 9*REGBYTES(sp)
  124. STORE a2, 10*REGBYTES(sp)
  125. STORE a3, 11*REGBYTES(sp)
  126. STORE a4, 12*REGBYTES(sp)
  127. STORE a5, 13*REGBYTES(sp)
  128. STORE a6, 14*REGBYTES(sp)
  129. STORE a7, 15*REGBYTES(sp)
  130. add a0, sp, zero
  131. jal ra, _start_trap_rust
  132. LOAD ra, 0*REGBYTES(sp)
  133. LOAD t0, 1*REGBYTES(sp)
  134. LOAD t1, 2*REGBYTES(sp)
  135. LOAD t2, 3*REGBYTES(sp)
  136. LOAD t3, 4*REGBYTES(sp)
  137. LOAD t4, 5*REGBYTES(sp)
  138. LOAD t5, 6*REGBYTES(sp)
  139. LOAD t6, 7*REGBYTES(sp)
  140. LOAD a0, 8*REGBYTES(sp)
  141. LOAD a1, 9*REGBYTES(sp)
  142. LOAD a2, 10*REGBYTES(sp)
  143. LOAD a3, 11*REGBYTES(sp)
  144. LOAD a4, 12*REGBYTES(sp)
  145. LOAD a5, 13*REGBYTES(sp)
  146. LOAD a6, 14*REGBYTES(sp)
  147. LOAD a7, 15*REGBYTES(sp)
  148. addi sp, sp, 16*REGBYTES
  149. mret
  150. /* Make sure there is an abort when linking */
  151. .section .text
  152. .globl abort
  153. abort:
  154. j abort