irq_cm4f.S 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (c) 2013-2018 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * -----------------------------------------------------------------------------
  19. *
  20. * Project: CMSIS-RTOS RTX
  21. * Title: Cortex-M4F Exception handlers
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. .syntax unified
  26. .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
  27. .equ TCB_SP_OFS, 56 // TCB.SP offset
  28. .equ TCB_SF_OFS, 34 // TCB.stack_frame offset
  29. .section ".rodata"
  30. .global irqRtxLib // Non weak library reference
  31. irqRtxLib:
  32. .byte 0
  33. .thumb
  34. .section ".text"
  35. .align 2
  36. .thumb_func
  37. .type SVC_Handler, %function
  38. .global SVC_Handler
  39. .fnstart
  40. .cantunwind
  41. SVC_Handler:
  42. TST LR,#0x04 // Determine return stack from EXC_RETURN bit 2
  43. ITE EQ
  44. MRSEQ R0,MSP // Get MSP if return stack is MSP
  45. MRSNE R0,PSP // Get PSP if return stack is PSP
  46. LDR R1,[R0,#24] // Load saved PC from stack
  47. LDRB R1,[R1,#-2] // Load SVC number
  48. CBNZ R1,SVC_User // Branch if not SVC 0
  49. PUSH {R0,LR} // Save SP and EXC_RETURN
  50. LDM R0,{R0-R3,R12} // Load function parameters and address from stack
  51. BLX R12 // Call service function
  52. POP {R12,LR} // Restore SP and EXC_RETURN
  53. STM R12,{R0-R1} // Store function return values
  54. SVC_Context:
  55. LDR R3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run
  56. LDM R3,{R1,R2} // Load osRtxInfo.thread.run: curr & next
  57. CMP R1,R2 // Check if thread switch is required
  58. IT EQ
  59. BXEQ LR // Exit when threads are the same
  60. CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted
  61. TST LR,#0x10 // Check if extended stack frame
  62. BNE SVC_ContextSwitch
  63. LDR R1,=0xE000EF34 // FPCCR Address
  64. LDR R0,[R1] // Load FPCCR
  65. BIC R0,R0,#1 // Clear LSPACT (Lazy state)
  66. STR R0,[R1] // Store FPCCR
  67. B SVC_ContextSwitch
  68. SVC_ContextSave:
  69. STMDB R12!,{R4-R11} // Save R4..R11
  70. TST LR,#0x10 // Check if extended stack frame
  71. IT EQ
  72. VSTMDBEQ R12!,{S16-S31} // Save VFP S16.S31
  73. STR R12,[R1,#TCB_SP_OFS] // Store SP
  74. STRB LR, [R1,#TCB_SF_OFS] // Store stack frame information
  75. SVC_ContextSwitch:
  76. STR R2,[R3] // osRtxInfo.thread.run: curr = next
  77. SVC_ContextRestore:
  78. LDRB R1,[R2,#TCB_SF_OFS] // Load stack frame information
  79. LDR R0,[R2,#TCB_SP_OFS] // Load SP
  80. ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN
  81. TST LR,#0x10 // Check if extended stack frame
  82. IT EQ
  83. VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31
  84. LDMIA R0!,{R4-R11} // Restore R4..R11
  85. MSR PSP,R0 // Set PSP
  86. SVC_Exit:
  87. BX LR // Exit from handler
  88. SVC_User:
  89. LDR R2,=osRtxUserSVC // Load address of SVC table
  90. LDR R3,[R2] // Load SVC maximum number
  91. CMP R1,R3 // Check SVC number range
  92. BHI SVC_Exit // Branch if out of range
  93. PUSH {R0,LR} // Save SP and EXC_RETURN
  94. LDR R12,[R2,R1,LSL #2] // Load address of SVC function
  95. LDM R0,{R0-R3} // Load function parameters from stack
  96. BLX R12 // Call service function
  97. POP {R12,LR} // Restore SP and EXC_RETURN
  98. STR R0,[R12] // Store function return value
  99. BX LR // Return from handler
  100. .fnend
  101. .size SVC_Handler, .-SVC_Handler
  102. .thumb_func
  103. .type PendSV_Handler, %function
  104. .global PendSV_Handler
  105. .fnstart
  106. .cantunwind
  107. PendSV_Handler:
  108. PUSH {R0,LR} // Save EXC_RETURN
  109. BL osRtxPendSV_Handler // Call osRtxPendSV_Handler
  110. POP {R0,LR} // Restore EXC_RETURN
  111. MRS R12,PSP
  112. B SVC_Context
  113. .fnend
  114. .size PendSV_Handler, .-PendSV_Handler
  115. .thumb_func
  116. .type SysTick_Handler, %function
  117. .global SysTick_Handler
  118. .fnstart
  119. .cantunwind
  120. SysTick_Handler:
  121. PUSH {R0,LR} // Save EXC_RETURN
  122. BL osRtxTick_Handler // Call osRtxTick_Handler
  123. POP {R0,LR} // Restore EXC_RETURN
  124. MRS R12,PSP
  125. B SVC_Context
  126. .fnend
  127. .size SysTick_Handler, .-SysTick_Handler
  128. .end