asm.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. mul t0, a2, t0
  77. sub sp, sp, t0
  78. // Set frame pointer
  79. add s0, sp, zero
  80. // Set trap handler
  81. la t0, _start_trap
  82. csrw mtvec, t0
  83. jal zero, _start_rust
  84. .cfi_endproc
  85. /*
  86. Trap entry point (_start_trap)
  87. Saves caller saved registers ra, t0..6, a0..7, calls _start_trap_rust,
  88. restores caller saved registers and then returns.
  89. */
  90. .section .trap, "ax"
  91. .global _start_trap
  92. _start_trap:
  93. addi sp, sp, -16*REGBYTES
  94. STORE ra, 0*REGBYTES(sp)
  95. STORE t0, 1*REGBYTES(sp)
  96. STORE t1, 2*REGBYTES(sp)
  97. STORE t2, 3*REGBYTES(sp)
  98. STORE t3, 4*REGBYTES(sp)
  99. STORE t4, 5*REGBYTES(sp)
  100. STORE t5, 6*REGBYTES(sp)
  101. STORE t6, 7*REGBYTES(sp)
  102. STORE a0, 8*REGBYTES(sp)
  103. STORE a1, 9*REGBYTES(sp)
  104. STORE a2, 10*REGBYTES(sp)
  105. STORE a3, 11*REGBYTES(sp)
  106. STORE a4, 12*REGBYTES(sp)
  107. STORE a5, 13*REGBYTES(sp)
  108. STORE a6, 14*REGBYTES(sp)
  109. STORE a7, 15*REGBYTES(sp)
  110. jal ra, _start_trap_rust
  111. LOAD ra, 0*REGBYTES(sp)
  112. LOAD t0, 1*REGBYTES(sp)
  113. LOAD t1, 2*REGBYTES(sp)
  114. LOAD t2, 3*REGBYTES(sp)
  115. LOAD t3, 4*REGBYTES(sp)
  116. LOAD t4, 5*REGBYTES(sp)
  117. LOAD t5, 6*REGBYTES(sp)
  118. LOAD t6, 7*REGBYTES(sp)
  119. LOAD a0, 8*REGBYTES(sp)
  120. LOAD a1, 9*REGBYTES(sp)
  121. LOAD a2, 10*REGBYTES(sp)
  122. LOAD a3, 11*REGBYTES(sp)
  123. LOAD a4, 12*REGBYTES(sp)
  124. LOAD a5, 13*REGBYTES(sp)
  125. LOAD a6, 14*REGBYTES(sp)
  126. LOAD a7, 15*REGBYTES(sp)
  127. addi sp, sp, 16*REGBYTES
  128. mret
  129. /* Make sure there is an abort when linking */
  130. .section .text
  131. .globl abort
  132. abort:
  133. j abort