irq_armv6m.S 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright (c) 2013-2023 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: ARMv6-M Exception handlers
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. .syntax unified
  26. #include "rtx_def.h"
  27. .equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
  28. .equ TCB_SP_OFS, 56 // TCB.SP offset
  29. .equ TCB_ZONE_OFS, 68 // TCB.zone offset
  30. .equ osRtxErrorStackOverflow, 1 // Stack overflow
  31. .equ osRtxErrorSVC, 6 // Invalid SVC function called
  32. .section ".rodata"
  33. .global irqRtxLib // Non weak library reference
  34. irqRtxLib:
  35. .byte 0
  36. .thumb
  37. .section ".text"
  38. .align 2
  39. .eabi_attribute Tag_ABI_align_preserved, 1
  40. .thumb_func
  41. .type SVC_Handler, %function
  42. .global SVC_Handler
  43. .fnstart
  44. .cantunwind
  45. SVC_Handler:
  46. mov r0,lr
  47. lsrs r0,r0,#3 // Determine return stack from EXC_RETURN bit 2
  48. bcc SVC_MSP // Branch if return stack is MSP
  49. mrs r0,psp // Get PSP
  50. SVC_Number:
  51. ldr r1,[r0,#24] // Load saved PC from stack
  52. subs r1,r1,#2 // Point to SVC instruction
  53. ldrb r1,[r1] // Load SVC number
  54. cmp r1,#0 // Check SVC number
  55. bne SVC_User // Branch if not SVC 0
  56. #ifdef RTX_SVC_PTR_CHECK
  57. subs r1,r7,#0x01 // Clear T-bit of function address
  58. lsls r2,r1,#29 // Check if 8-byte aligned
  59. beq SVC_PtrBoundsCheck // Branch if address is aligned
  60. SVC_PtrInvalid:
  61. push {r0,lr} // Save SP and EXC_RETURN
  62. movs r0,#osRtxErrorSVC // Parameter: code
  63. mov r1,r7 // Parameter: object_id
  64. bl osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
  65. pop {r2,r3} // Restore SP and EXC_RETURN
  66. mov lr,r3 // Set EXC_RETURN
  67. b SVC_Context // Branch to context handling
  68. SVC_PtrBoundsCheck:
  69. ldr r2,=Image$$RTX_SVC_VENEERS$$Base
  70. ldr r3,=Image$$RTX_SVC_VENEERS$$Length
  71. subs r2,r1,r2 // Subtract SVC table base address
  72. cmp r2,r3 // Compare with SVC table boundaries
  73. bhs SVC_PtrInvalid // Branch if address is out of bounds
  74. #endif // RTX_SVC_PTR_CHECK
  75. push {r0,lr} // Save SP and EXC_RETURN
  76. ldmia r0,{r0-r3} // Load function parameters from stack
  77. blx r7 // Call service function
  78. pop {r2,r3} // Restore SP and EXC_RETURN
  79. str r0,[r2] // Store function return value
  80. mov lr,r3 // Set EXC_RETURN
  81. SVC_Context:
  82. ldr r3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.thread.run
  83. ldmia r3!,{r1,r2} // Load osRtxInfo.thread.run: curr & next
  84. cmp r1,r2 // Check if thread switch is required
  85. beq SVC_Exit // Branch when threads are the same
  86. subs r3,r3,#8 // Adjust address
  87. str r2,[r3] // osRtxInfo.thread.run: curr = next
  88. cmp r1,#0
  89. beq SVC_ContextRestore // Branch if running thread is deleted
  90. SVC_ContextSave:
  91. mrs r0,psp // Get PSP
  92. subs r0,r0,#32 // Calculate SP: space for R4..R11
  93. str r0,[r1,#TCB_SP_OFS] // Store SP
  94. #ifdef RTX_STACK_CHECK
  95. push {r1,r2} // Save osRtxInfo.thread.run: curr & next
  96. mov r0,r1 // Parameter: osRtxInfo.thread.run.curr
  97. bl osRtxThreadStackCheck // Check if thread stack is overrun
  98. pop {r1,r2} // Restore osRtxInfo.thread.run: curr & next
  99. cmp r0,#0
  100. bne SVC_ContextSaveRegs // Branch when stack check is ok
  101. movs r0,#osRtxErrorStackOverflow // Parameter: r0=code, r1=object_id
  102. bl osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
  103. ldr r3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.thread.run
  104. ldr r2,[r3,#4] // Load osRtxInfo.thread.run: next
  105. str r2,[r3] // osRtxInfo.thread.run: curr = next
  106. movs r1,#0 // Simulate deleted running thread
  107. b SVC_ContextRestore // Branch to context restore handling
  108. SVC_ContextSaveRegs:
  109. ldr r0,[r1,#TCB_SP_OFS] // Load SP
  110. #endif // RTX_STACK_CHECK
  111. stmia r0!,{r4-r7} // Save R4..R7
  112. mov r4,r8
  113. mov r5,r9
  114. mov r6,r10
  115. mov r7,r11
  116. stmia r0!,{r4-r7} // Save R8..R11
  117. SVC_ContextRestore:
  118. movs r4,r2 // Assign osRtxInfo.thread.run.next to R4
  119. #ifdef RTX_EXECUTION_ZONE
  120. movs r3,#TCB_ZONE_OFS // Get TCB.zone offset
  121. ldrb r0,[r2,r3] // Load osRtxInfo.thread.run.next: zone
  122. cmp r1,#0
  123. beq SVC_ZoneSetup // Branch if running thread is deleted
  124. ldrb r1,[r1,r3] // Load osRtxInfo.thread.run.curr: zone
  125. cmp r0,r1 // Check if next:zone == curr:zone
  126. beq SVC_ContextRestore_N // Branch if zone has not changed
  127. SVC_ZoneSetup:
  128. bl osZoneSetup_Callback // Setup zone for next thread
  129. #endif // RTX_EXECUTION_ZONE
  130. SVC_ContextRestore_N:
  131. ldr r0,[r4,#TCB_SP_OFS] // Load SP
  132. adds r0,r0,#16 // Adjust address
  133. ldmia r0!,{r4-r7} // Restore R8..R11
  134. mov r8,r4
  135. mov r9,r5
  136. mov r10,r6
  137. mov r11,r7
  138. msr psp,r0 // Set PSP
  139. subs r0,r0,#32 // Adjust address
  140. ldmia r0!,{r4-r7} // Restore R4..R7
  141. movs r0,#2 // Binary complement of 0xFFFFFFFD
  142. mvns r0,r0 // Set EXC_RETURN value
  143. bx r0 // Exit from handler
  144. SVC_MSP:
  145. mrs r0,msp // Get MSP
  146. b SVC_Number
  147. SVC_Exit:
  148. bx lr // Exit from handler
  149. SVC_User:
  150. ldr r2,=osRtxUserSVC // Load address of SVC table
  151. ldr r3,[r2] // Load SVC maximum number
  152. cmp r1,r3 // Check SVC number range
  153. bhi SVC_Exit // Branch if out of range
  154. push {r0,lr} // Save SP and EXC_RETURN
  155. lsls r1,r1,#2
  156. ldr r3,[r2,r1] // Load address of SVC function
  157. mov r12,r3
  158. ldmia r0,{r0-r3} // Load function parameters from stack
  159. blx r12 // Call service function
  160. pop {r2,r3} // Restore SP and EXC_RETURN
  161. str r0,[r2] // Store function return value
  162. bx r3 // Return from handler
  163. .fnend
  164. .size SVC_Handler, .-SVC_Handler
  165. .thumb_func
  166. .type PendSV_Handler, %function
  167. .global PendSV_Handler
  168. .fnstart
  169. .cantunwind
  170. PendSV_Handler:
  171. push {r0,lr} // Save EXC_RETURN
  172. bl osRtxPendSV_Handler // Call osRtxPendSV_Handler
  173. pop {r0,r1} // Restore EXC_RETURN
  174. mov lr,r1 // Set EXC_RETURN
  175. b SVC_Context // Branch to context handling
  176. .fnend
  177. .size PendSV_Handler, .-PendSV_Handler
  178. .thumb_func
  179. .type SysTick_Handler, %function
  180. .global SysTick_Handler
  181. .fnstart
  182. .cantunwind
  183. SysTick_Handler:
  184. push {r0,lr} // Save EXC_RETURN
  185. bl osRtxTick_Handler // Call osRtxTick_Handler
  186. pop {r0,r1} // Restore EXC_RETURN
  187. mov lr,r1 // Set EXC_RETURN
  188. b SVC_Context // Branch to context handling
  189. .fnend
  190. .size SysTick_Handler, .-SysTick_Handler
  191. #ifdef RTX_SAFETY_FEATURES
  192. .thumb_func
  193. .type osFaultResume, %function
  194. .global osFaultResume
  195. .fnstart
  196. .cantunwind
  197. osFaultResume:
  198. b SVC_Context // Branch to context handling
  199. .fnend
  200. .size osFaultResume, .-osFaultResume
  201. #endif // RTX_SAFETY_FEATURES
  202. .end