interrupt_gcc.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/10/02 Bernard The first version
  9. * 2018/12/27 Jesven Add SMP schedule
  10. * 2021/02/02 lizhirui Add userspace support
  11. * 2021/12/24 JasonHu Add user setting save/restore
  12. */
  13. #include "cpuport.h"
  14. #include "encoding.h"
  15. #include "stackframe.h"
  16. .section .text.entry
  17. .align 2
  18. .global trap_entry
  19. .extern __stack_cpu0
  20. .extern get_current_thread_kernel_stack_top
  21. trap_entry:
  22. //backup sp
  23. csrrw sp, sscratch, sp
  24. //load interrupt stack
  25. la sp, __stack_cpu0
  26. //backup context
  27. SAVE_ALL
  28. RESTORE_SYS_GP
  29. #ifdef RT_USING_SMART
  30. //check syscall
  31. csrr t0, scause
  32. li t1, 8//environment call from u-mode
  33. beq t0, t1, syscall_entry
  34. #endif
  35. csrr a0, scause
  36. csrrc a1, stval, zero
  37. csrr a2, sepc
  38. mv a3, sp
  39. /* scause, stval, sepc, sp */
  40. call handle_trap
  41. /* need to switch new thread */
  42. la s0, rt_thread_switch_interrupt_flag
  43. lw s2, 0(s0)
  44. beqz s2, spurious_interrupt
  45. sw zero, 0(s0)
  46. .global rt_hw_context_switch_interrupt_do
  47. rt_hw_context_switch_interrupt_do:
  48. #ifdef RT_USING_SMART
  49. //swap to thread kernel stack
  50. csrr t0, sstatus
  51. andi t0, t0, 0x100
  52. beqz t0, __restore_sp_from_tcb_interrupt
  53. #endif
  54. __restore_sp_from_sscratch_interrupt:
  55. csrr t0, sscratch
  56. j __move_stack_context_interrupt
  57. #ifdef RT_USING_SMART
  58. __restore_sp_from_tcb_interrupt:
  59. la s0, rt_interrupt_from_thread
  60. LOAD a0, 0(s0)
  61. jal rt_thread_sp_to_thread
  62. jal get_thread_kernel_stack_top
  63. mv t0, a0
  64. #endif
  65. __move_stack_context_interrupt:
  66. mv t1, sp//src
  67. mv sp, t0//switch stack
  68. addi sp, sp, -CTX_REG_NR * REGBYTES
  69. //copy context
  70. li s0, CTX_REG_NR//cnt
  71. mv t2, sp//dst
  72. copy_context_loop_interrupt:
  73. LOAD t0, 0(t1)
  74. STORE t0, 0(t2)
  75. addi s0, s0, -1
  76. addi t1, t1, 8
  77. addi t2, t2, 8
  78. bnez s0, copy_context_loop_interrupt
  79. la s0, rt_interrupt_from_thread
  80. LOAD s1, 0(s0)
  81. STORE sp, 0(s1)
  82. la s0, rt_interrupt_to_thread
  83. LOAD s1, 0(s0)
  84. LOAD sp, 0(s1)
  85. #ifdef RT_USING_SMART
  86. mv a0, s1
  87. jal rt_thread_sp_to_thread
  88. jal lwp_aspace_switch
  89. #endif
  90. spurious_interrupt:
  91. RESTORE_ALL
  92. sret
  93. .global rt_hw_interrupt_enable
  94. rt_hw_interrupt_enable:
  95. csrs sstatus, a0 /* restore to old csr */
  96. jr ra
  97. .global rt_hw_interrupt_disable
  98. rt_hw_interrupt_disable:
  99. csrrci a0, sstatus, 2 /* clear SIE */
  100. jr ra