asm.S 3.2 KB

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