context_gcc.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "nds32.h"
  2. #include "os_cpu_common.h"
  3. #include "config.h"
  4. .align 4
  5. ! void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
  6. ! R0 --> from
  7. ! R1 --> to
  8. .section .text
  9. .global rt_hw_context_switch_interrupt
  10. .global rt_hw_context_switch
  11. rt_hw_context_switch_interrupt:
  12. rt_hw_context_switch:
  13. push25 $r6,#8 ! {$r6, $fp, $gp, $lp}
  14. la $r2, rt_thread_switch_interrupt_flag
  15. lw $r3, [$r2]
  16. movi $r4, #1
  17. beq $r3, $r4, _reswitch
  18. sw $r4, [$r2] ! set rt_thread_switch_interrupt_flag to 1
  19. la $r2, rt_interrupt_from_thread
  20. sw $r0, [$r2] ! set rt_interrupt_from_thread
  21. _reswitch:
  22. la $r2, rt_interrupt_to_thread
  23. sw $r1, [$r2] ! set rt_interrupt_to_thread
  24. bal hal_intc_swi_trigger ! trigger the swi exception (causes context switch)
  25. pop25 $r6,#8 ! {$r6, $fp, $gp, $lp}
  26. ! R0 --> switch from thread stack
  27. ! R1 --> switch to thread stack
  28. ! psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack
  29. .align 4
  30. .global OS_Trap_Interrupt_SWI
  31. OS_Trap_Interrupt_SWI:
  32. ! pushm $r0, $r5
  33. setgie.d ! disable interrupt to protect context switch
  34. dsb
  35. IntlDescend ! Descend interrupt level
  36. movi $r0, 0x0
  37. mtsr $r0, $INT_PEND ! clean SWI pending
  38. la $r0, rt_thread_switch_interrupt_flag ! get rt_thread_switch_interrupt_flag
  39. lw $r1, [$r0]
  40. beqz $r1, pendsv_exit ! swi has already been handled
  41. movi $r1, #0
  42. sw $r1, [$r0] ! clear rt_thread_switch_interrupt_flag to 0
  43. la $r0, rt_interrupt_from_thread
  44. lw $r1, [$r0]
  45. beqz $r1, switch_to_thread ! skip register save at the first time(os startup phase)
  46. SAVE_ALL
  47. move $r1, $sp
  48. la $r0, rt_interrupt_from_thread
  49. lw $r0, [$r0]
  50. sw $r1, [$r0]
  51. switch_to_thread:
  52. la $r1, rt_interrupt_to_thread
  53. lw $r1, [$r1]
  54. lw $r1, [$r1] ! load thread stack pointer
  55. move $sp, $r1 ! update stack pointer
  56. RESTORE_ALL ! pop registers
  57. pendsv_exit:
  58. setgie.e
  59. iret
  60. .align 4
  61. ! void rt_hw_context_switch_to(rt_uint32 to);
  62. ! R0 --> to
  63. .global rt_hw_context_switch_to
  64. rt_hw_context_switch_to:
  65. la $r1, rt_interrupt_to_thread
  66. sw $r0, [$r1]
  67. ! set from thread to 0
  68. la $r1, rt_interrupt_from_thread
  69. movi $r0, #0
  70. sw $r0, [$r1]
  71. ! set interrupt flag to 1
  72. la $r1, rt_thread_switch_interrupt_flag
  73. movi $r0, #1
  74. sw $r0, [$r1]
  75. ! set the SWI exception priority(must be the lowest level)
  76. ! todo
  77. ! trigger the SWI exception (causes context switch)
  78. jal hal_intc_swi_trigger
  79. setgie.e ! enable interrupts at processor level
  80. 1:
  81. b 1b ! never reach here
  82. #ifndef VECTOR_NUMINTRS
  83. #define VECTOR_NUMINTRS 32
  84. #endif
  85. .global OS_Trap_Int_Common
  86. ! Set up Interrupt vector ISR
  87. ! HW#IRQ_SWI_VECTOR : OS_Trap_Interrupt_SWI (SWI)
  88. ! HW#n : OS_Trap_Int_Common
  89. .macro SET_HWISR num
  90. .global OS_Trap_Interrupt_HW\num
  91. .if \num == IRQ_SWI_VECTOR
  92. .set OS_Trap_Interrupt_HW\num, OS_Trap_Interrupt_SWI
  93. .else
  94. .set OS_Trap_Interrupt_HW\num, OS_Trap_Int_Common
  95. .endif
  96. .endm
  97. .altmacro
  98. .set irqno, 0
  99. .rept VECTOR_NUMINTRS
  100. SET_HWISR %irqno
  101. .set irqno, irqno+1
  102. .endr
  103. .noaltmacro
  104. ! .global OS_Trap_Int_Common
  105. OS_Trap_Int_Common:
  106. #ifdef MPU_SUPPORT
  107. mfsr $p1, $PSW
  108. ori $p1, $p1, (PSW_mskIT | PSW_mskDT)
  109. mtsr $p1, $PSW ! enable IT/DT
  110. dsb
  111. pushm $r0, $r5
  112. move $r0, $p0 ! IRQ number
  113. #endif
  114. ! $r0 : HW Interrupt vector number
  115. SAVE_CALLER
  116. IntlDescend ! Descend interrupt level
  117. mfsr $r1, $IPSW ! Use IPSW.CPL to check come from thread or ISR
  118. srli45 $r1, #PSW_offCPL
  119. fexti33 $r1, #0x2 ! IPSW.CPL
  120. bnec $r1, #0x7, 2f ! IPSW.CPL != 7, come form ISR, reentrant
  121. move $fp, $sp ! save old stack pointer
  122. la $sp, __OS_Int_Stack ! switch to interrupt stack
  123. 2:
  124. setgie.e ! allow nested now
  125. ! The entire CPU state is now stashed on the stack,
  126. ! and the stack is also 8-byte alignment.
  127. ! We can call C program based interrupt handler now.
  128. la $r1, OS_CPU_Vector_Table
  129. lw $r1, [$r1+($r0<<2)] ! ISR function pointer
  130. jral $r1 ! Call ISR
  131. la $r1, __OS_Int_Stack ! Check for nested interruption return
  132. bne $r1, $sp, 3f ! $sp != __OS_Int_Stack?
  133. move $sp, $fp ! Move back to the thread stack
  134. 3:
  135. RESTORE_CALLER
  136. iret
  137. ! .set OS_Trap_Interrupt_HW9, OS_Trap_Interrupt_SWI
  138. ! .set OS_Trap_Interrupt_HW19, OS_Trap_Int_Common
  139. !*********************************************
  140. ! POINTERS TO VARIABLES
  141. !*********************************************
  142. #ifdef MPU_SUPPORT
  143. .section privileged_data
  144. #else
  145. .section .bss
  146. #endif
  147. .skip IRQ_STACK_SIZE
  148. .align 3
  149. __OS_Int_Stack:
  150. .end