asm.S 3.5 KB

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