irq_armv8mbl.s 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. NAME irq_armv8mbl.s
  26. #include "rtx_def.h"
  27. I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
  28. TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
  29. TCB_SP_OFS EQU 56 ; TCB.SP offset
  30. TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
  31. TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset
  32. TCB_ZONE_OFS EQU 68 ; TCB.zone offset
  33. osRtxErrorStackOverflow\
  34. EQU 1 ; Stack overflow
  35. osRtxErrorSVC EQU 6 ; Invalid SVC function called
  36. PRESERVE8
  37. SECTION .rodata:DATA:NOROOT(2)
  38. EXPORT irqRtxLib
  39. irqRtxLib DCB 0 ; Non weak library reference
  40. SECTION .text:CODE:NOROOT(2)
  41. THUMB
  42. SVC_Handler
  43. EXPORT SVC_Handler
  44. IMPORT osRtxUserSVC
  45. IMPORT osRtxInfo
  46. #ifdef RTX_STACK_CHECK
  47. IMPORT osRtxThreadStackCheck
  48. IMPORT osRtxKernelErrorNotify
  49. #endif
  50. #ifdef RTX_SVC_PTR_CHECK
  51. IMPORT |Image$$RTX_SVC_VENEERS$$Base|
  52. IMPORT |Image$$RTX_SVC_VENEERS$$Length|
  53. IMPORT osRtxKernelErrorNotify
  54. #endif
  55. #ifdef RTX_EXECUTION_ZONE
  56. IMPORT osZoneSetup_Callback
  57. #endif
  58. #ifdef RTX_TZ_CONTEXT
  59. IMPORT TZ_LoadContext_S
  60. IMPORT TZ_StoreContext_S
  61. #endif
  62. MOV R0,LR
  63. LSRS R0,R0,#3 ; Determine return stack from EXC_RETURN bit 2
  64. BCC SVC_MSP ; Branch if return stack is MSP
  65. MRS R0,PSP ; Get PSP
  66. SVC_Number
  67. LDR R1,[R0,#24] ; Load saved PC from stack
  68. SUBS R1,R1,#2 ; Point to SVC instruction
  69. LDRB R1,[R1] ; Load SVC number
  70. CMP R1,#0 ; Check SVC number
  71. BNE SVC_User ; Branch if not SVC 0
  72. #ifdef RTX_SVC_PTR_CHECK
  73. SUBS R1,R7,#0x01 ; Clear T-bit of function address
  74. LSLS R2,R1,#29 ; Check if 8-byte aligned
  75. BEQ SVC_PtrBoundsCheck ; Branch if address is aligned
  76. SVC_PtrInvalid
  77. PUSH {R0,LR} ; Save SP and EXC_RETURN
  78. MOVS R0,#osRtxErrorSVC ; Parameter: code
  79. MOV R1,R7 ; Parameter: object_id
  80. BL osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
  81. POP {R2,R3} ; Restore SP and EXC_RETURN
  82. MOV LR,R3 ; Set EXC_RETURN
  83. B SVC_Context ; Branch to context handling
  84. SVC_PtrBoundsCheck
  85. LDR R2,=|Image$$RTX_SVC_VENEERS$$Base|
  86. LDR R3,=|Image$$RTX_SVC_VENEERS$$Length|
  87. SUBS R2,R1,R2 ; Subtract SVC table base address
  88. CMP R2,R3 ; Compare with SVC table boundaries
  89. BHS SVC_PtrInvalid ; Branch if address is out of bounds
  90. #endif
  91. PUSH {R0,LR} ; Save SP and EXC_RETURN
  92. LDMIA R0,{R0-R3} ; Load function parameters from stack
  93. BLX R7 ; Call service function
  94. POP {R2,R3} ; Restore SP and EXC_RETURN
  95. STR R0,[R2] ; Store function return value
  96. MOV LR,R3 ; Set EXC_RETURN
  97. SVC_Context
  98. LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.thread.run
  99. LDMIA R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
  100. CMP R1,R2 ; Check if thread switch is required
  101. BEQ SVC_Exit ; Branch when threads are the same
  102. SUBS R3,R3,#8 ; Adjust address
  103. STR R2,[R3] ; osRtxInfo.thread.run: curr = next
  104. CBZ R1,SVC_ContextRestore ; Branch if running thread is deleted
  105. SVC_ContextSave
  106. #ifdef RTX_TZ_CONTEXT
  107. MOV R3,LR ; Get EXC_RETURN
  108. LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
  109. CBZ R0,SVC_ContextSave_NS ; Branch if there is no secure context
  110. PUSH {R0-R3} ; Save registers
  111. BL TZ_StoreContext_S ; Store secure context
  112. POP {R0-R3} ; Restore registers
  113. MOV LR,R3 ; Set EXC_RETURN
  114. #endif
  115. SVC_ContextSave_NS
  116. MRS R0,PSP ; Get PSP
  117. #if (DOMAIN_NS != 0)
  118. MOV R3,LR ; Get EXC_RETURN
  119. LSLS R3,R3,#25 ; Check domain of interrupted thread
  120. BMI SVC_ContextSaveSP ; Branch if secure
  121. #endif
  122. #ifdef RTX_STACK_CHECK
  123. SUBS R0,R0,#32 ; Calculate SP: space for R4..R11
  124. SVC_ContextSaveSP
  125. STR R0,[R1,#TCB_SP_OFS] ; Store SP
  126. MOV R3,LR ; Get EXC_RETURN
  127. MOVS R0,#TCB_SF_OFS ; Get TCB.stack_frame offset
  128. STRB R3,[R1,R0] ; Store stack frame information
  129. PUSH {R1,R2} ; Save osRtxInfo.thread.run: curr & next
  130. MOV R0,R1 ; Parameter: osRtxInfo.thread.run.curr
  131. BL osRtxThreadStackCheck ; Check if thread stack is overrun
  132. POP {R1,R2} ; Restore osRtxInfo.thread.run: curr & next
  133. CBNZ R0,SVC_ContextSaveRegs ; Branch when stack check is ok
  134. MOVS R0,#osRtxErrorStackOverflow ; Parameter: r0=code, r1=object_id
  135. BL osRtxKernelErrorNotify ; Call osRtxKernelErrorNotify
  136. LDR R3,=osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.thread.run
  137. LDR R2,[R3,#4] ; Load osRtxInfo.thread.run: next
  138. STR R2,[R3] ; osRtxInfo.thread.run: curr = next
  139. MOVS R1,#0 ; Simulate deleted running thread
  140. B SVC_ContextRestore ; Branch to context restore handling
  141. SVC_ContextSaveRegs
  142. #if (DOMAIN_NS != 0)
  143. MOVS R0,#TCB_SF_OFS ; Get TCB.stack_frame offset
  144. LDRSB R3,[R1,R0] ; Load stack frame information
  145. LSLS R3,R3,#25 ; Check domain of interrupted thread
  146. BMI SVC_ContextRestore ; Branch if secure
  147. #endif
  148. LDR R0,[R1,#TCB_SP_OFS] ; Load SP
  149. STMIA R0!,{R4-R7} ; Save R4..R7
  150. MOV R4,R8
  151. MOV R5,R9
  152. MOV R6,R10
  153. MOV R7,R11
  154. STMIA R0!,{R4-R7} ; Save R8..R11
  155. #else
  156. SUBS R0,R0,#32 ; Calculate SP: space for R4..R11
  157. STMIA R0!,{R4-R7} ; Save R4..R7
  158. MOV R4,R8
  159. MOV R5,R9
  160. MOV R6,R10
  161. MOV R7,R11
  162. STMIA R0!,{R4-R7} ; Save R8..R11
  163. SUBS R0,R0,#32 ; Adjust address
  164. SVC_ContextSaveSP
  165. STR R0,[R1,#TCB_SP_OFS] ; Store SP
  166. MOV R3,LR ; Get EXC_RETURN
  167. MOVS R0,#TCB_SF_OFS ; Get TCB.stack_frame offset
  168. STRB R3,[R1,R0] ; Store stack frame information
  169. #endif
  170. SVC_ContextRestore
  171. MOVS R4,R2 ; Assign osRtxInfo.thread.run.next to R4
  172. #ifdef RTX_EXECUTION_ZONE
  173. MOVS R3,#TCB_ZONE_OFS ; Get TCB.zone offset
  174. LDRB R0,[R2,R3] ; Load osRtxInfo.thread.run.next: zone
  175. CBZ R1,SVC_ZoneSetup ; Branch if running thread is deleted
  176. LDRB R1,[R1,R3] ; Load osRtxInfo.thread.run.curr: zone
  177. CMP R0,R1 ; Check if next:zone == curr:zone
  178. BEQ SVC_ContextRestore_S ; Branch if zone has not changed
  179. SVC_ZoneSetup
  180. BL osZoneSetup_Callback ; Setup zone for next thread
  181. #endif
  182. SVC_ContextRestore_S
  183. #ifdef RTX_TZ_CONTEXT
  184. LDR R0,[R4,#TCB_TZM_OFS] ; Load TrustZone memory identifier
  185. CBZ R0,SVC_ContextRestore_NS ; Branch if there is no secure context
  186. BL TZ_LoadContext_S ; Load secure context
  187. #endif
  188. SVC_ContextRestore_NS
  189. LDR R0,[R4,#TCB_SM_OFS] ; Load stack memory base
  190. MSR PSPLIM,R0 ; Set PSPLIM
  191. MOVS R0,#TCB_SF_OFS ; Get TCB.stack_frame offset
  192. LDRSB R3,[R4,R0] ; Load stack frame information
  193. MOV LR,R3 ; Set EXC_RETURN
  194. LDR R0,[R4,#TCB_SP_OFS] ; Load SP
  195. #if (DOMAIN_NS != 0)
  196. LSLS R3,R3,#25 ; Check domain of interrupted thread
  197. BMI SVC_ContextRestoreSP ; Branch if secure
  198. #endif
  199. ADDS R0,R0,#16 ; Adjust address
  200. LDMIA R0!,{R4-R7} ; Restore R8..R11
  201. MOV R8,R4
  202. MOV R9,R5
  203. MOV R10,R6
  204. MOV R11,R7
  205. SUBS R0,R0,#32 ; Adjust address
  206. LDMIA R0!,{R4-R7} ; Restore R4..R7
  207. ADDS R0,R0,#16 ; Adjust address
  208. SVC_ContextRestoreSP
  209. MSR PSP,R0 ; Set PSP
  210. SVC_Exit
  211. BX LR ; Exit from handler
  212. SVC_MSP
  213. MRS R0,MSP ; Get MSP
  214. B SVC_Number
  215. SVC_User
  216. LDR R2,=osRtxUserSVC ; Load address of SVC table
  217. LDR R3,[R2] ; Load SVC maximum number
  218. CMP R1,R3 ; Check SVC number range
  219. BHI SVC_Exit ; Branch if out of range
  220. PUSH {R0,LR} ; Save SP and EXC_RETURN
  221. LSLS R1,R1,#2
  222. LDR R3,[R2,R1] ; Load address of SVC function
  223. MOV R12,R3
  224. LDMIA R0,{R0-R3} ; Load function parameters from stack
  225. BLX R12 ; Call service function
  226. POP {R2,R3} ; Restore SP and EXC_RETURN
  227. STR R0,[R2] ; Store function return value
  228. BX R3 ; Return from handler
  229. PendSV_Handler
  230. EXPORT PendSV_Handler
  231. IMPORT osRtxPendSV_Handler
  232. PUSH {R0,LR} ; Save EXC_RETURN
  233. BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler
  234. POP {R0,R1} ; Restore EXC_RETURN
  235. MOV LR,R1 ; Set EXC_RETURN
  236. B SVC_Context ; Branch to context handling
  237. SysTick_Handler
  238. EXPORT SysTick_Handler
  239. IMPORT osRtxTick_Handler
  240. PUSH {R0,LR} ; Save EXC_RETURN
  241. BL osRtxTick_Handler ; Call osRtxTick_Handler
  242. POP {R0,R1} ; Restore EXC_RETURN
  243. MOV LR,R1 ; Set EXC_RETURN
  244. B SVC_Context ; Branch to context handling
  245. #ifdef RTX_SAFETY_FEATURES
  246. osFaultResume PROC
  247. EXPORT osFaultResume
  248. B SVC_Context ; Branch to context handling
  249. ALIGN
  250. ENDP
  251. #endif
  252. END