fw_base.S 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #include <sbi/riscv_asm.h>
  10. #include <sbi/riscv_encoding.h>
  11. #include <sbi/sbi_platform.h>
  12. #include <sbi/sbi_scratch.h>
  13. #include <sbi/sbi_trap.h>
  14. #define BOOT_STATUS_RELOCATE_DONE 1
  15. #define BOOT_STATUS_BOOT_HART_DONE 2
  16. .macro MOV_3R __d0, __s0, __d1, __s1, __d2, __s2
  17. add \__d0, \__s0, zero
  18. add \__d1, \__s1, zero
  19. add \__d2, \__s2, zero
  20. .endm
  21. .macro MOV_5R __d0, __s0, __d1, __s1, __d2, __s2, __d3, __s3, __d4, __s4
  22. add \__d0, \__s0, zero
  23. add \__d1, \__s1, zero
  24. add \__d2, \__s2, zero
  25. add \__d3, \__s3, zero
  26. add \__d4, \__s4, zero
  27. .endm
  28. /*
  29. * If __start_reg <= __check_reg and __check_reg < __end_reg then
  30. * jump to __pass
  31. */
  32. .macro BRANGE __start_reg, __end_reg, __check_reg, __jump_lable
  33. blt \__check_reg, \__start_reg, 999f
  34. bge \__check_reg, \__end_reg, 999f
  35. j \__jump_lable
  36. 999:
  37. .endm
  38. .section .entry, "ax", %progbits
  39. .align 3
  40. .globl _start
  41. .globl _start_warm
  42. _start:
  43. /* Find preferred boot HART id */
  44. MOV_3R s0, a0, s1, a1, s2, a2
  45. call fw_boot_hart
  46. add a6, a0, zero
  47. MOV_3R a0, s0, a1, s1, a2, s2
  48. li a7, -1
  49. beq a6, a7, _try_lottery
  50. /* Jump to relocation wait loop if we are not boot hart */
  51. bne a0, a6, _wait_relocate_copy_done
  52. _try_lottery:
  53. /* Jump to relocation wait loop if we don't get relocation lottery */
  54. la a6, _relocate_lottery
  55. li a7, 1
  56. amoadd.w a6, a7, (a6)
  57. bnez a6, _wait_relocate_copy_done
  58. /* Save load address */
  59. la t0, _load_start
  60. la t1, _start
  61. REG_S t1, 0(t0)
  62. /* Relocate if load address != link address */
  63. _relocate:
  64. la t0, _link_start
  65. REG_L t0, 0(t0)
  66. la t1, _link_end
  67. REG_L t1, 0(t1)
  68. la t2, _load_start
  69. REG_L t2, 0(t2)
  70. sub t3, t1, t0
  71. add t3, t3, t2
  72. beq t0, t2, _relocate_done
  73. la t4, _relocate_done
  74. sub t4, t4, t2
  75. add t4, t4, t0
  76. blt t2, t0, _relocate_copy_to_upper
  77. _relocate_copy_to_lower:
  78. ble t1, t2, _relocate_copy_to_lower_loop
  79. la t3, _relocate_lottery
  80. BRANGE t2, t1, t3, _start_hang
  81. la t3, _boot_status
  82. BRANGE t2, t1, t3, _start_hang
  83. la t3, _relocate
  84. la t5, _relocate_done
  85. BRANGE t2, t1, t3, _start_hang
  86. BRANGE t2, t1, t5, _start_hang
  87. BRANGE t3, t5, t2, _start_hang
  88. _relocate_copy_to_lower_loop:
  89. REG_L t3, 0(t2)
  90. REG_S t3, 0(t0)
  91. add t0, t0, __SIZEOF_POINTER__
  92. add t2, t2, __SIZEOF_POINTER__
  93. blt t0, t1, _relocate_copy_to_lower_loop
  94. jr t4
  95. _relocate_copy_to_upper:
  96. ble t3, t0, _relocate_copy_to_upper_loop
  97. la t2, _relocate_lottery
  98. BRANGE t0, t3, t2, _start_hang
  99. la t2, _boot_status
  100. BRANGE t0, t3, t2, _start_hang
  101. la t2, _relocate
  102. la t5, _relocate_done
  103. BRANGE t0, t3, t2, _start_hang
  104. BRANGE t0, t3, t5, _start_hang
  105. BRANGE t2, t5, t0, _start_hang
  106. _relocate_copy_to_upper_loop:
  107. add t3, t3, -__SIZEOF_POINTER__
  108. add t1, t1, -__SIZEOF_POINTER__
  109. REG_L t2, 0(t3)
  110. REG_S t2, 0(t1)
  111. blt t0, t1, _relocate_copy_to_upper_loop
  112. jr t4
  113. _wait_relocate_copy_done:
  114. la t0, _start
  115. la t1, _link_start
  116. REG_L t1, 0(t1)
  117. beq t0, t1, _wait_for_boot_hart
  118. la t2, _boot_status
  119. la t3, _wait_for_boot_hart
  120. sub t3, t3, t0
  121. add t3, t3, t1
  122. 1:
  123. /* waitting for relocate copy done (_boot_status == 1) */
  124. li t4, BOOT_STATUS_RELOCATE_DONE
  125. REG_L t5, 0(t2)
  126. /* Reduce the bus traffic so that boot hart may proceed faster */
  127. nop
  128. nop
  129. nop
  130. bgt t4, t5, 1b
  131. jr t3
  132. _relocate_done:
  133. /*
  134. * Mark relocate copy done
  135. * Use _boot_status copy relative to the load address
  136. */
  137. la t0, _boot_status
  138. la t1, _link_start
  139. REG_L t1, 0(t1)
  140. la t2, _load_start
  141. REG_L t2, 0(t2)
  142. sub t0, t0, t1
  143. add t0, t0, t2
  144. li t1, BOOT_STATUS_RELOCATE_DONE
  145. REG_S t1, 0(t0)
  146. fence rw, rw
  147. /* At this point we are running from link address */
  148. /* Reset all registers for boot HART */
  149. li ra, 0
  150. call _reset_regs
  151. /* Zero-out BSS */
  152. la s4, _bss_start
  153. la s5, _bss_end
  154. _bss_zero:
  155. REG_S zero, (s4)
  156. add s4, s4, __SIZEOF_POINTER__
  157. blt s4, s5, _bss_zero
  158. /* Setup temporary trap handler */
  159. la s4, _start_hang
  160. csrw CSR_MTVEC, s4
  161. /* Setup temporary stack */
  162. la s4, _fw_end
  163. li s5, (SBI_SCRATCH_SIZE * 2)
  164. add sp, s4, s5
  165. /* Allow main firmware to save info */
  166. MOV_5R s0, a0, s1, a1, s2, a2, s3, a3, s4, a4
  167. call fw_save_info
  168. MOV_5R a0, s0, a1, s1, a2, s2, a3, s3, a4, s4
  169. #ifdef FW_FDT_PATH
  170. /* Override previous arg1 */
  171. la a1, fw_fdt_bin
  172. #endif
  173. /*
  174. * Initialize platform
  175. * Note: The a0 to a4 registers passed to the
  176. * firmware are parameters to this function.
  177. */
  178. MOV_5R s0, a0, s1, a1, s2, a2, s3, a3, s4, a4
  179. call fw_platform_init
  180. add t0, a0, zero
  181. MOV_5R a0, s0, a1, s1, a2, s2, a3, s3, a4, s4
  182. add a1, t0, zero
  183. /* Preload HART details
  184. * s7 -> HART Count
  185. * s8 -> HART Stack Size
  186. */
  187. la a4, platform
  188. #if __riscv_xlen == 64
  189. lwu s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
  190. lwu s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
  191. #else
  192. lw s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
  193. lw s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
  194. #endif
  195. /* Setup scratch space for all the HARTs*/
  196. la tp, _fw_end
  197. mul a5, s7, s8
  198. add tp, tp, a5
  199. /* Keep a copy of tp */
  200. add t3, tp, zero
  201. /* Counter */
  202. li t2, 1
  203. /* hartid 0 is mandated by ISA */
  204. li t1, 0
  205. _scratch_init:
  206. add tp, t3, zero
  207. mul a5, s8, t1
  208. sub tp, tp, a5
  209. li a5, SBI_SCRATCH_SIZE
  210. sub tp, tp, a5
  211. /* Initialize scratch space */
  212. /* Store fw_start and fw_size in scratch space */
  213. la a4, _fw_start
  214. la a5, _fw_end
  215. mul t0, s7, s8
  216. add a5, a5, t0
  217. sub a5, a5, a4
  218. REG_S a4, SBI_SCRATCH_FW_START_OFFSET(tp)
  219. REG_S a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)
  220. /* Store next arg1 in scratch space */
  221. MOV_3R s0, a0, s1, a1, s2, a2
  222. call fw_next_arg1
  223. REG_S a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)
  224. MOV_3R a0, s0, a1, s1, a2, s2
  225. /* Store next address in scratch space */
  226. MOV_3R s0, a0, s1, a1, s2, a2
  227. call fw_next_addr
  228. REG_S a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp)
  229. MOV_3R a0, s0, a1, s1, a2, s2
  230. /* Store next mode in scratch space */
  231. MOV_3R s0, a0, s1, a1, s2, a2
  232. call fw_next_mode
  233. REG_S a0, SBI_SCRATCH_NEXT_MODE_OFFSET(tp)
  234. MOV_3R a0, s0, a1, s1, a2, s2
  235. /* Store warm_boot address in scratch space */
  236. la a4, _start_warm
  237. REG_S a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
  238. /* Store platform address in scratch space */
  239. la a4, platform
  240. REG_S a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
  241. /* Store hartid-to-scratch function address in scratch space */
  242. la a4, _hartid_to_scratch
  243. REG_S a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
  244. /* Store trap-exit function address in scratch space */
  245. la a4, _trap_exit
  246. REG_S a4, SBI_SCRATCH_TRAP_EXIT_OFFSET(tp)
  247. /* Clear tmp0 in scratch space */
  248. REG_S zero, SBI_SCRATCH_TMP0_OFFSET(tp)
  249. /* Store firmware options in scratch space */
  250. MOV_3R s0, a0, s1, a1, s2, a2
  251. #ifdef FW_OPTIONS
  252. li a0, FW_OPTIONS
  253. #else
  254. call fw_options
  255. #endif
  256. REG_S a0, SBI_SCRATCH_OPTIONS_OFFSET(tp)
  257. MOV_3R a0, s0, a1, s1, a2, s2
  258. /* Move to next scratch space */
  259. add t1, t1, t2
  260. blt t1, s7, _scratch_init
  261. /*
  262. * Relocate Flatened Device Tree (FDT)
  263. * source FDT address = previous arg1
  264. * destination FDT address = next arg1
  265. *
  266. * Note: We will preserve a0 and a1 passed by
  267. * previous booting stage.
  268. */
  269. beqz a1, _fdt_reloc_done
  270. /* Mask values in a3 and a4 */
  271. li a3, ~(__SIZEOF_POINTER__ - 1)
  272. li a4, 0xff
  273. /* t1 = destination FDT start address */
  274. MOV_3R s0, a0, s1, a1, s2, a2
  275. call fw_next_arg1
  276. add t1, a0, zero
  277. MOV_3R a0, s0, a1, s1, a2, s2
  278. beqz t1, _fdt_reloc_done
  279. beq t1, a1, _fdt_reloc_done
  280. and t1, t1, a3
  281. /* t0 = source FDT start address */
  282. add t0, a1, zero
  283. and t0, t0, a3
  284. /* t2 = source FDT size in big-endian */
  285. #if __riscv_xlen == 64
  286. lwu t2, 4(t0)
  287. #else
  288. lw t2, 4(t0)
  289. #endif
  290. /* t3 = bit[15:8] of FDT size */
  291. add t3, t2, zero
  292. srli t3, t3, 16
  293. and t3, t3, a4
  294. slli t3, t3, 8
  295. /* t4 = bit[23:16] of FDT size */
  296. add t4, t2, zero
  297. srli t4, t4, 8
  298. and t4, t4, a4
  299. slli t4, t4, 16
  300. /* t5 = bit[31:24] of FDT size */
  301. add t5, t2, zero
  302. and t5, t5, a4
  303. slli t5, t5, 24
  304. /* t2 = bit[7:0] of FDT size */
  305. srli t2, t2, 24
  306. and t2, t2, a4
  307. /* t2 = FDT size in little-endian */
  308. or t2, t2, t3
  309. or t2, t2, t4
  310. or t2, t2, t5
  311. /* t2 = destination FDT end address */
  312. add t2, t1, t2
  313. /* FDT copy loop */
  314. ble t2, t1, _fdt_reloc_done
  315. _fdt_reloc_again:
  316. REG_L t3, 0(t0)
  317. REG_S t3, 0(t1)
  318. add t0, t0, __SIZEOF_POINTER__
  319. add t1, t1, __SIZEOF_POINTER__
  320. blt t1, t2, _fdt_reloc_again
  321. _fdt_reloc_done:
  322. /* mark boot hart done */
  323. li t0, BOOT_STATUS_BOOT_HART_DONE
  324. la t1, _boot_status
  325. REG_S t0, 0(t1)
  326. fence rw, rw
  327. j _start_warm
  328. /* waiting for boot hart to be done (_boot_status == 2) */
  329. _wait_for_boot_hart:
  330. li t0, BOOT_STATUS_BOOT_HART_DONE
  331. la t1, _boot_status
  332. REG_L t1, 0(t1)
  333. /* Reduce the bus traffic so that boot hart may proceed faster */
  334. nop
  335. nop
  336. nop
  337. bne t0, t1, _wait_for_boot_hart
  338. _start_warm:
  339. /* Reset all registers for non-boot HARTs */
  340. li ra, 0
  341. call _reset_regs
  342. /* Disable and clear all interrupts */
  343. csrw CSR_MIE, zero
  344. csrw CSR_MIP, zero
  345. /* Find HART count and HART stack size */
  346. la a4, platform
  347. #if __riscv_xlen == 64
  348. lwu s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
  349. lwu s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
  350. #else
  351. lw s7, SBI_PLATFORM_HART_COUNT_OFFSET(a4)
  352. lw s8, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(a4)
  353. #endif
  354. REG_L s9, SBI_PLATFORM_HART_INDEX2ID_OFFSET(a4)
  355. /* Find HART id */
  356. csrr s6, CSR_MHARTID
  357. /* Find HART index */
  358. beqz s9, 3f
  359. li a4, 0
  360. 1:
  361. #if __riscv_xlen == 64
  362. lwu a5, (s9)
  363. #else
  364. lw a5, (s9)
  365. #endif
  366. beq a5, s6, 2f
  367. add s9, s9, 4
  368. add a4, a4, 1
  369. blt a4, s7, 1b
  370. li a4, -1
  371. 2: add s6, a4, zero
  372. 3: bge s6, s7, _start_hang
  373. /* Find the scratch space based on HART index */
  374. la tp, _fw_end
  375. mul a5, s7, s8
  376. add tp, tp, a5
  377. mul a5, s8, s6
  378. sub tp, tp, a5
  379. li a5, SBI_SCRATCH_SIZE
  380. sub tp, tp, a5
  381. /* update the mscratch */
  382. csrw CSR_MSCRATCH, tp
  383. /* Setup stack */
  384. add sp, tp, zero
  385. /* Setup trap handler */
  386. la a4, _trap_handler
  387. #if __riscv_xlen == 32
  388. csrr a5, CSR_MISA
  389. srli a5, a5, ('H' - 'A')
  390. andi a5, a5, 0x1
  391. beq a5, zero, _skip_trap_handler_rv32_hyp
  392. la a4, _trap_handler_rv32_hyp
  393. _skip_trap_handler_rv32_hyp:
  394. #endif
  395. csrw CSR_MTVEC, a4
  396. #if __riscv_xlen == 32
  397. /* Override trap exit for H-extension */
  398. csrr a5, CSR_MISA
  399. srli a5, a5, ('H' - 'A')
  400. andi a5, a5, 0x1
  401. beq a5, zero, _skip_trap_exit_rv32_hyp
  402. la a4, _trap_exit_rv32_hyp
  403. csrr a5, CSR_MSCRATCH
  404. REG_S a4, SBI_SCRATCH_TRAP_EXIT_OFFSET(a5)
  405. _skip_trap_exit_rv32_hyp:
  406. #endif
  407. /* Initialize SBI runtime */
  408. csrr a0, CSR_MSCRATCH
  409. call sbi_init
  410. /* We don't expect to reach here hence just hang */
  411. j _start_hang
  412. .align 3
  413. _relocate_lottery:
  414. RISCV_PTR 0
  415. _boot_status:
  416. RISCV_PTR 0
  417. _load_start:
  418. RISCV_PTR _fw_start
  419. _link_start:
  420. RISCV_PTR _fw_start
  421. _link_end:
  422. RISCV_PTR _fw_reloc_end
  423. .section .entry, "ax", %progbits
  424. .align 3
  425. .globl _hartid_to_scratch
  426. _hartid_to_scratch:
  427. /*
  428. * a0 -> HART ID (passed by caller)
  429. * a1 -> HART Index (passed by caller)
  430. * t0 -> HART Stack Size
  431. * t1 -> HART Stack End
  432. * t2 -> Temporary
  433. */
  434. la t2, platform
  435. #if __riscv_xlen == 64
  436. lwu t0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(t2)
  437. lwu t2, SBI_PLATFORM_HART_COUNT_OFFSET(t2)
  438. #else
  439. lw t0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(t2)
  440. lw t2, SBI_PLATFORM_HART_COUNT_OFFSET(t2)
  441. #endif
  442. sub t2, t2, a1
  443. mul t2, t2, t0
  444. la t1, _fw_end
  445. add t1, t1, t2
  446. li t2, SBI_SCRATCH_SIZE
  447. sub a0, t1, t2
  448. ret
  449. .section .entry, "ax", %progbits
  450. .align 3
  451. .globl _start_hang
  452. _start_hang:
  453. wfi
  454. j _start_hang
  455. .section .entry, "ax", %progbits
  456. .align 3
  457. .globl fw_platform_init
  458. .weak fw_platform_init
  459. fw_platform_init:
  460. add a0, a1, zero
  461. ret
  462. .macro TRAP_SAVE_AND_SETUP_SP_T0
  463. /* Swap TP and MSCRATCH */
  464. csrrw tp, CSR_MSCRATCH, tp
  465. /* Save T0 in scratch space */
  466. REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp)
  467. /*
  468. * Set T0 to appropriate exception stack
  469. *
  470. * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1;
  471. * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP))
  472. *
  473. * Came_From_M_Mode = 0 ==> Exception_Stack = TP
  474. * Came_From_M_Mode = -1 ==> Exception_Stack = SP
  475. */
  476. csrr t0, CSR_MSTATUS
  477. srl t0, t0, MSTATUS_MPP_SHIFT
  478. and t0, t0, PRV_M
  479. slti t0, t0, PRV_M
  480. add t0, t0, -1
  481. xor sp, sp, tp
  482. and t0, t0, sp
  483. xor sp, sp, tp
  484. xor t0, tp, t0
  485. /* Save original SP on exception stack */
  486. REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0)
  487. /* Set SP to exception stack and make room for trap registers */
  488. add sp, t0, -(SBI_TRAP_REGS_SIZE)
  489. /* Restore T0 from scratch space */
  490. REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp)
  491. /* Save T0 on stack */
  492. REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
  493. /* Swap TP and MSCRATCH */
  494. csrrw tp, CSR_MSCRATCH, tp
  495. .endm
  496. .macro TRAP_SAVE_MEPC_MSTATUS have_mstatush
  497. /* Save MEPC and MSTATUS CSRs */
  498. csrr t0, CSR_MEPC
  499. REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
  500. csrr t0, CSR_MSTATUS
  501. REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
  502. .if \have_mstatush
  503. csrr t0, CSR_MSTATUSH
  504. REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
  505. .else
  506. REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
  507. .endif
  508. .endm
  509. .macro TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
  510. /* Save all general regisers except SP and T0 */
  511. REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
  512. REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
  513. REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
  514. REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
  515. REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
  516. REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
  517. REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
  518. REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
  519. REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
  520. REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
  521. REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
  522. REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
  523. REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
  524. REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
  525. REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
  526. REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
  527. REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
  528. REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
  529. REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
  530. REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
  531. REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
  532. REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
  533. REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
  534. REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
  535. REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
  536. REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
  537. REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
  538. REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
  539. REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
  540. REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
  541. .endm
  542. .macro TRAP_CALL_C_ROUTINE
  543. /* Call C routine */
  544. add a0, sp, zero
  545. call sbi_trap_handler
  546. .endm
  547. .macro TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
  548. /* Restore all general regisers except SP and T0 */
  549. REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
  550. REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
  551. REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
  552. REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
  553. REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
  554. REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
  555. REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
  556. REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
  557. REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
  558. REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
  559. REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
  560. REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
  561. REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
  562. REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
  563. REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
  564. REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
  565. REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
  566. REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
  567. REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
  568. REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
  569. REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
  570. REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
  571. REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
  572. REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
  573. REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
  574. REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
  575. REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
  576. REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
  577. REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
  578. .endm
  579. .macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush
  580. /* Restore MEPC and MSTATUS CSRs */
  581. REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
  582. csrw CSR_MEPC, t0
  583. REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
  584. csrw CSR_MSTATUS, t0
  585. .if \have_mstatush
  586. REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
  587. csrw CSR_MSTATUSH, t0
  588. .endif
  589. .endm
  590. .macro TRAP_RESTORE_SP_T0
  591. /* Restore T0 */
  592. REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
  593. /* Restore SP */
  594. REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
  595. .endm
  596. .section .entry, "ax", %progbits
  597. .align 3
  598. .globl _trap_handler
  599. _trap_handler:
  600. TRAP_SAVE_AND_SETUP_SP_T0
  601. TRAP_SAVE_MEPC_MSTATUS 0
  602. TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
  603. TRAP_CALL_C_ROUTINE
  604. TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
  605. TRAP_RESTORE_MEPC_MSTATUS 0
  606. TRAP_RESTORE_SP_T0
  607. mret
  608. .section .entry, "ax", %progbits
  609. .align 3
  610. .globl _trap_exit
  611. _trap_exit:
  612. add sp, a0, zero
  613. TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
  614. TRAP_RESTORE_MEPC_MSTATUS 0
  615. TRAP_RESTORE_SP_T0
  616. mret
  617. #if __riscv_xlen == 32
  618. .section .entry, "ax", %progbits
  619. .align 3
  620. .globl _trap_handler_rv32_hyp
  621. _trap_handler_rv32_hyp:
  622. TRAP_SAVE_AND_SETUP_SP_T0
  623. TRAP_SAVE_MEPC_MSTATUS 1
  624. TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
  625. TRAP_CALL_C_ROUTINE
  626. TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
  627. TRAP_RESTORE_MEPC_MSTATUS 1
  628. TRAP_RESTORE_SP_T0
  629. mret
  630. .section .entry, "ax", %progbits
  631. .align 3
  632. .globl _trap_exit_rv32_hyp
  633. _trap_exit_rv32_hyp:
  634. add sp, a0, zero
  635. TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
  636. TRAP_RESTORE_MEPC_MSTATUS 1
  637. TRAP_RESTORE_SP_T0
  638. mret
  639. #endif
  640. .section .entry, "ax", %progbits
  641. .align 3
  642. .globl _reset_regs
  643. _reset_regs:
  644. /* flush the instruction cache */
  645. fence.i
  646. /* Reset all registers except ra, a0, a1 and a2 */
  647. li sp, 0
  648. li gp, 0
  649. li tp, 0
  650. li t0, 0
  651. li t1, 0
  652. li t2, 0
  653. li s0, 0
  654. li s1, 0
  655. li a3, 0
  656. li a4, 0
  657. li a5, 0
  658. li a6, 0
  659. li a7, 0
  660. li s2, 0
  661. li s3, 0
  662. li s4, 0
  663. li s5, 0
  664. li s6, 0
  665. li s7, 0
  666. li s8, 0
  667. li s9, 0
  668. li s10, 0
  669. li s11, 0
  670. li t3, 0
  671. li t4, 0
  672. li t5, 0
  673. li t6, 0
  674. csrw CSR_MSCRATCH, 0
  675. ret
  676. #ifdef FW_FDT_PATH
  677. .section .rodata
  678. .align 4
  679. .globl fw_fdt_bin
  680. fw_fdt_bin:
  681. .incbin FW_FDT_PATH
  682. #ifdef FW_FDT_PADDING
  683. .fill FW_FDT_PADDING, 1, 0
  684. #endif
  685. #endif