interrupt_gcc.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #define __ASSEMBLY__
  14. #include "cpuport.h"
  15. #include "encoding.h"
  16. #include "stackframe.h"
  17. .section .text.entry
  18. .align 2
  19. .global trap_entry
  20. .extern __stack_cpu0
  21. .extern get_current_thread_kernel_stack_top
  22. trap_entry:
  23. //backup sp
  24. csrrw sp, sscratch, sp
  25. //load interrupt stack
  26. la sp, __stack_cpu0
  27. //backup context
  28. SAVE_ALL
  29. RESTORE_SYS_GP
  30. //check syscall
  31. csrr t0, scause
  32. li t1, 8//environment call from u-mode
  33. beq t0, t1, syscall_entry
  34. csrr a0, scause
  35. csrrc a1, stval, zero
  36. csrr a2, sepc
  37. mv a3, sp
  38. /* scause, stval, sepc, sp */
  39. call handle_trap
  40. /* need to switch new thread */
  41. la s0, rt_thread_switch_interrupt_flag
  42. lw s2, 0(s0)
  43. beqz s2, spurious_interrupt
  44. sw zero, 0(s0)
  45. .global rt_hw_context_switch_interrupt_do
  46. rt_hw_context_switch_interrupt_do:
  47. //swap to thread kernel stack
  48. csrr t0, sstatus
  49. andi t0, t0, 0x100
  50. beqz t0, __restore_sp_from_tcb_interrupt
  51. __restore_sp_from_sscratch_interrupt:
  52. csrr t0, sscratch
  53. j __move_stack_context_interrupt
  54. __restore_sp_from_tcb_interrupt:
  55. la s0, rt_interrupt_from_thread
  56. LOAD a0, 0(s0)
  57. jal rt_thread_sp_to_thread
  58. jal get_thread_kernel_stack_top
  59. mv t0, a0
  60. __move_stack_context_interrupt:
  61. mv t1, sp//src
  62. mv sp, t0//switch stack
  63. addi sp, sp, -CTX_REG_NR * REGBYTES
  64. //copy context
  65. li s0, CTX_REG_NR//cnt
  66. mv t2, sp//dst
  67. copy_context_loop_interrupt:
  68. LOAD t0, 0(t1)
  69. STORE t0, 0(t2)
  70. addi s0, s0, -1
  71. addi t1, t1, 8
  72. addi t2, t2, 8
  73. bnez s0, copy_context_loop_interrupt
  74. la s0, rt_interrupt_from_thread
  75. LOAD s1, 0(s0)
  76. STORE sp, 0(s1)
  77. la s0, rt_interrupt_to_thread
  78. LOAD s1, 0(s0)
  79. LOAD sp, 0(s1)
  80. #ifdef RT_USING_USERSPACE
  81. mv a0, s1
  82. jal rt_thread_sp_to_thread
  83. jal lwp_mmu_switch
  84. #endif
  85. spurious_interrupt:
  86. RESTORE_ALL
  87. sret
  88. .global rt_hw_interrupt_enable
  89. rt_hw_interrupt_enable:
  90. csrs sstatus, a0 /* restore to old csr */
  91. jr ra
  92. .global rt_hw_interrupt_disable
  93. rt_hw_interrupt_disable:
  94. csrrci a0, sstatus, 2 /* clear SIE */
  95. jr ra