irq_armv8mbl.S 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright (c) 2016-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: ARMv8-M Baseline 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_SM_OFS, 48 // TCB.stack_mem offset
  29. .equ TCB_SP_OFS, 56 // TCB.SP offset
  30. .equ TCB_SF_OFS, 34 // TCB.stack_frame offset
  31. .equ TCB_TZM_OFS, 64 // TCB.tz_memory offset
  32. .equ TCB_ZONE_OFS,68 // TCB.zone offset
  33. .equ osRtxErrorStackOverflow, 1 // Stack overflow
  34. .equ osRtxErrorSVC, 6 // Invalid SVC function called
  35. .section ".rodata"
  36. .global irqRtxLib // Non weak library reference
  37. irqRtxLib:
  38. .byte 0
  39. .thumb
  40. .section ".text"
  41. .align 2
  42. .eabi_attribute Tag_ABI_align_preserved, 1
  43. .thumb_func
  44. .type SVC_Handler, %function
  45. .global SVC_Handler
  46. .fnstart
  47. .cantunwind
  48. SVC_Handler:
  49. mov r0,lr
  50. lsrs r0,r0,#3 // Determine return stack from EXC_RETURN bit 2
  51. bcc SVC_MSP // Branch if return stack is MSP
  52. mrs r0,psp // Get PSP
  53. SVC_Number:
  54. ldr r1,[r0,#24] // Load saved PC from stack
  55. subs r1,r1,#2 // Point to SVC instruction
  56. ldrb r1,[r1] // Load SVC number
  57. cmp r1,#0 // Check SVC number
  58. bne SVC_User // Branch if not SVC 0
  59. #ifdef RTX_SVC_PTR_CHECK
  60. subs r1,r7,#0x01 // Clear T-bit of function address
  61. lsls r2,r1,#29 // Check if 8-byte aligned
  62. beq SVC_PtrBoundsCheck // Branch if address is aligned
  63. SVC_PtrInvalid:
  64. push {r0,lr} // Save SP and EXC_RETURN
  65. movs r0,#osRtxErrorSVC // Parameter: code
  66. mov r1,r7 // Parameter: object_id
  67. bl osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
  68. pop {r2,r3} // Restore SP and EXC_RETURN
  69. mov lr,r3 // Set EXC_RETURN
  70. b SVC_Context // Branch to context handling
  71. SVC_PtrBoundsCheck:
  72. ldr r2,=Image$$RTX_SVC_VENEERS$$Base
  73. ldr r3,=Image$$RTX_SVC_VENEERS$$Length
  74. subs r2,r1,r2 // Subtract SVC table base address
  75. cmp r2,r3 // Compare with SVC table boundaries
  76. bhs SVC_PtrInvalid // Branch if address is out of bounds
  77. #endif // RTX_SVC_PTR_CHECK
  78. push {r0,lr} // Save SP and EXC_RETURN
  79. ldmia r0,{r0-r3} // Load function parameters from stack
  80. blx r7 // Call service function
  81. pop {r2,r3} // Restore SP and EXC_RETURN
  82. str r0,[r2] // Store function return value
  83. mov lr,r3 // Set EXC_RETURN
  84. SVC_Context:
  85. ldr r3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.thread.run
  86. ldmia r3!,{r1,r2} // Load osRtxInfo.thread.run: curr & next
  87. cmp r1,r2 // Check if thread switch is required
  88. beq SVC_Exit // Branch when threads are the same
  89. subs r3,r3,#8 // Adjust address
  90. str r2,[r3] // osRtxInfo.thread.run: curr = next
  91. cbz r1,SVC_ContextRestore // Branch if running thread is deleted
  92. SVC_ContextSave:
  93. #ifdef RTX_TZ_CONTEXT
  94. mov r3,lr // Get EXC_RETURN
  95. ldr r0,[r1,#TCB_TZM_OFS] // Load TrustZone memory identifier
  96. cbz r0,SVC_ContextSave_NS // Branch if there is no secure context
  97. push {r0-r3} // Save registers
  98. bl TZ_StoreContext_S // Store secure context
  99. pop {r0-r3} // Restore registers
  100. mov lr,r3 // Set EXC_RETURN
  101. #endif
  102. SVC_ContextSave_NS:
  103. mrs r0,psp // Get PSP
  104. #if (DOMAIN_NS != 0)
  105. mov r3,lr // Get EXC_RETURN
  106. lsls r3,r3,#25 // Check domain of interrupted thread
  107. bmi SVC_ContextSaveSP // Branch if secure
  108. #endif
  109. #ifdef RTX_STACK_CHECK
  110. subs r0,r0,#32 // Calculate SP: space for R4..R11
  111. SVC_ContextSaveSP:
  112. str r0,[r1,#TCB_SP_OFS] // Store SP
  113. mov r3,lr // Get EXC_RETURN
  114. movs r0,#TCB_SF_OFS // Get TCB.stack_frame offset
  115. strb r3,[r1,r0] // Store stack frame information
  116. push {r1,r2} // Save osRtxInfo.thread.run: curr & next
  117. mov r0,r1 // Parameter: osRtxInfo.thread.run.curr
  118. bl osRtxThreadStackCheck // Check if thread stack is overrun
  119. pop {r1,r2} // Restore osRtxInfo.thread.run: curr & next
  120. cbnz r0,SVC_ContextSaveRegs // Branch when stack check is ok
  121. movs r0,#osRtxErrorStackOverflow // Parameter: r0=code, r1=object_id
  122. bl osRtxKernelErrorNotify // Call osRtxKernelErrorNotify
  123. ldr r3,=osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.thread.run
  124. ldr r2,[r3,#4] // Load osRtxInfo.thread.run: next
  125. str r2,[r3] // osRtxInfo.thread.run: curr = next
  126. movs r1,#0 // Simulate deleted running thread
  127. b SVC_ContextRestore // Branch to context restore handling
  128. SVC_ContextSaveRegs:
  129. #if (DOMAIN_NS != 0)
  130. movs r0,#TCB_SF_OFS // Get TCB.stack_frame offset
  131. ldrsb r3,[r1,r0] // Load stack frame information
  132. lsls r3,r3,#25 // Check domain of interrupted thread
  133. bmi SVC_ContextRestore // Branch if secure
  134. #endif
  135. ldr r0,[r1,#TCB_SP_OFS] // Load SP
  136. stmia r0!,{r4-r7} // Save R4..R7
  137. mov r4,r8
  138. mov r5,r9
  139. mov r6,r10
  140. mov r7,r11
  141. stmia r0!,{r4-r7} // Save R8..R11
  142. #else
  143. subs r0,r0,#32 // Calculate SP: space for R4..R11
  144. stmia r0!,{r4-r7} // Save R4..R7
  145. mov r4,r8
  146. mov r5,r9
  147. mov r6,r10
  148. mov r7,r11
  149. stmia r0!,{r4-r7} // Save R8..R11
  150. subs r0,r0,#32 // Adjust address
  151. SVC_ContextSaveSP:
  152. str r0,[r1,#TCB_SP_OFS] // Store SP
  153. mov r3,lr // Get EXC_RETURN
  154. movs r0,#TCB_SF_OFS // Get TCB.stack_frame offset
  155. strb r3,[r1,r0] // Store stack frame information
  156. #endif // RTX_STACK_CHECK
  157. SVC_ContextRestore:
  158. movs r4,r2 // Assign osRtxInfo.thread.run.next to R4
  159. #ifdef RTX_EXECUTION_ZONE
  160. movs r3,#TCB_ZONE_OFS // Get TCB.zone offset
  161. ldrb r0,[r2,r3] // Load osRtxInfo.thread.run.next: zone
  162. cbz r1,SVC_ZoneSetup // Branch if running thread is deleted
  163. ldrb r1,[r1,r3] // Load osRtxInfo.thread.run.curr: zone
  164. cmp r0,r1 // Check if next:zone == curr:zone
  165. beq SVC_ContextRestore_S // Branch if zone has not changed
  166. SVC_ZoneSetup:
  167. bl osZoneSetup_Callback // Setup zone for next thread
  168. #endif // RTX_EXECUTION_ZONE
  169. SVC_ContextRestore_S:
  170. #ifdef RTX_TZ_CONTEXT
  171. ldr r0,[r4,#TCB_TZM_OFS] // Load TrustZone memory identifier
  172. cbz r0,SVC_ContextRestore_NS // Branch if there is no secure context
  173. bl TZ_LoadContext_S // Load secure context
  174. #endif
  175. SVC_ContextRestore_NS:
  176. ldr r0,[r4,#TCB_SM_OFS] // Load stack memory base
  177. msr psplim,r0 // Set PSPLIM
  178. movs r0,#TCB_SF_OFS // Get TCB.stack_frame offset
  179. ldrsb r3,[r4,r0] // Load stack frame information
  180. mov lr,r3 // Set EXC_RETURN
  181. ldr r0,[r4,#TCB_SP_OFS] // Load SP
  182. #if (DOMAIN_NS != 0)
  183. lsls r3,r3,#25 // Check domain of interrupted thread
  184. bmi SVC_ContextRestoreSP // Branch if secure
  185. #endif
  186. adds r0,r0,#16 // Adjust address
  187. ldmia r0!,{r4-r7} // Restore R8..R11
  188. mov r8,r4
  189. mov r9,r5
  190. mov r10,r6
  191. mov r11,r7
  192. subs r0,r0,#32 // Adjust address
  193. ldmia r0!,{r4-r7} // Restore R4..R7
  194. adds r0,r0,#16 // Adjust address
  195. SVC_ContextRestoreSP:
  196. msr psp,r0 // Set PSP
  197. SVC_Exit:
  198. bx lr // Exit from handler
  199. SVC_MSP:
  200. mrs r0,msp // Get MSP
  201. b SVC_Number
  202. SVC_User:
  203. ldr r2,=osRtxUserSVC // Load address of SVC table
  204. ldr r3,[r2] // Load SVC maximum number
  205. cmp r1,r3 // Check SVC number range
  206. bhi SVC_Exit // Branch if out of range
  207. push {r0,lr} // Save SP and EXC_RETURN
  208. lsls r1,r1,#2
  209. ldr r3,[r2,r1] // Load address of SVC function
  210. mov r12,r3
  211. ldmia r0,{r0-r3} // Load function parameters from stack
  212. blx r12 // Call service function
  213. pop {r2,r3} // Restore SP and EXC_RETURN
  214. str r0,[r2] // Store function return value
  215. bx r3 // Return from handler
  216. .fnend
  217. .size SVC_Handler, .-SVC_Handler
  218. .thumb_func
  219. .type PendSV_Handler, %function
  220. .global PendSV_Handler
  221. .fnstart
  222. .cantunwind
  223. PendSV_Handler:
  224. push {r0,lr} // Save EXC_RETURN
  225. bl osRtxPendSV_Handler // Call osRtxPendSV_Handler
  226. pop {r0,r1} // Restore EXC_RETURN
  227. mov lr,r1 // Set EXC_RETURN
  228. b SVC_Context // Branch to context handling
  229. .fnend
  230. .size PendSV_Handler, .-PendSV_Handler
  231. .thumb_func
  232. .type SysTick_Handler, %function
  233. .global SysTick_Handler
  234. .fnstart
  235. .cantunwind
  236. SysTick_Handler:
  237. push {r0,lr} // Save EXC_RETURN
  238. bl osRtxTick_Handler // Call osRtxTick_Handler
  239. pop {r0,r1} // Restore EXC_RETURN
  240. mov lr,r1 // Set EXC_RETURN
  241. b SVC_Context // Branch to context handling
  242. .fnend
  243. .size SysTick_Handler, .-SysTick_Handler
  244. #ifdef RTX_SAFETY_FEATURES
  245. .thumb_func
  246. .type osFaultResume, %function
  247. .global osFaultResume
  248. .fnstart
  249. .cantunwind
  250. osFaultResume:
  251. b SVC_Context // Branch to context handling
  252. .fnend
  253. .size osFaultResume, .-osFaultResume
  254. #endif // RTX_SAFETY_FEATURES
  255. .end