HAL_CM0.s 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*----------------------------------------------------------------------------
  2. * CMSIS-RTOS - RTX
  3. *----------------------------------------------------------------------------
  4. * Name: HAL_CM0.S
  5. * Purpose: Hardware Abstraction Layer for Cortex-M0
  6. * Rev.: V4.70
  7. *----------------------------------------------------------------------------
  8. *
  9. * Copyright (c) 1999-2009 KEIL, 2009-2017 ARM Germany GmbH. All rights reserved.
  10. *
  11. * SPDX-License-Identifier: Apache-2.0
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the License); you may
  14. * not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  21. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. *---------------------------------------------------------------------------*/
  25. NAME HAL_CM0.S
  26. #define TCB_TSTACK 40
  27. EXTERN os_flags
  28. EXTERN os_tsk
  29. EXTERN rt_alloc_box
  30. EXTERN rt_free_box
  31. EXTERN rt_stk_check
  32. EXTERN rt_pop_req
  33. EXTERN rt_systick
  34. EXTERN os_tick_irqack
  35. EXTERN SVC_Table
  36. EXTERN SVC_Count
  37. /*----------------------------------------------------------------------------
  38. * Functions
  39. *---------------------------------------------------------------------------*/
  40. SECTION .text:CODE:NOROOT(2)
  41. THUMB
  42. /*--------------------------- rt_set_PSP ------------------------------------*/
  43. ; void rt_set_PSP (U32 stack);
  44. PUBLIC rt_set_PSP
  45. rt_set_PSP:
  46. MSR PSP,R0
  47. BX LR
  48. /*--------------------------- rt_get_PSP ------------------------------------*/
  49. ; U32 rt_get_PSP (void);
  50. PUBLIC rt_get_PSP
  51. rt_get_PSP:
  52. MRS R0,PSP
  53. BX LR
  54. /*--------------------------- os_set_env ------------------------------------*/
  55. ; void os_set_env (void);
  56. /* Switch to Unprivileged/Privileged Thread mode, use PSP. */
  57. PUBLIC os_set_env
  58. os_set_env:
  59. MOV R0,SP /* PSP = MSP */
  60. MSR PSP,R0
  61. LDR R0,=os_flags
  62. LDRB R0,[R0]
  63. LSLS R0,#31
  64. BNE PrivilegedE
  65. MOVS R0,#0x03 /* Unprivileged Thread mode, use PSP */
  66. MSR CONTROL,R0
  67. BX LR
  68. PrivilegedE:
  69. MOVS R0,#0x02 /* Privileged Thread mode, use PSP */
  70. MSR CONTROL,R0
  71. BX LR
  72. /*--------------------------- _alloc_box ------------------------------------*/
  73. ; void *_alloc_box (void *box_mem);
  74. /* Function wrapper for Unprivileged/Privileged mode. */
  75. PUBLIC _alloc_box
  76. _alloc_box:
  77. LDR R3,=rt_alloc_box
  78. MOV R12,R3
  79. MRS R3,IPSR
  80. LSLS R3,#24
  81. BNE PrivilegedA
  82. MRS R3,CONTROL
  83. LSLS R3,#31
  84. BEQ PrivilegedA
  85. SVC 0
  86. BX LR
  87. PrivilegedA:
  88. BX R12
  89. /*--------------------------- _free_box -------------------------------------*/
  90. ; U32 _free_box (void *box_mem, void *box);
  91. /* Function wrapper for Unprivileged/Privileged mode. */
  92. PUBLIC _free_box
  93. _free_box:
  94. LDR R3,=rt_free_box
  95. MOV R12,R3
  96. MRS R3,IPSR
  97. LSLS R3,#24
  98. BNE PrivilegedF
  99. MRS R3,CONTROL
  100. LSLS R3,#31
  101. BEQ PrivilegedF
  102. SVC 0
  103. BX LR
  104. PrivilegedF:
  105. BX R12
  106. /*-------------------------- SVC_Handler ------------------------------------*/
  107. ; void SVC_Handler (void);
  108. PUBLIC SVC_Handler
  109. SVC_Handler:
  110. MRS R0,PSP /* Read PSP */
  111. LDR R1,[R0,#24] /* Read Saved PC from Stack */
  112. SUBS R1,R1,#2 /* Point to SVC Instruction */
  113. LDRB R1,[R1] /* Load SVC Number */
  114. CMP R1,#0
  115. BNE SVC_User /* User SVC Number > 0 */
  116. MOV LR,R4
  117. LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */
  118. MOV R12,R4
  119. MOV R4,LR
  120. BLX R12 /* Call SVC Function */
  121. MRS R3,PSP /* Read PSP */
  122. STMIA R3!,{R0-R2} /* Store return values */
  123. LDR R3,=os_tsk
  124. LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.next */
  125. CMP R1,R2
  126. BEQ SVC_Exit /* no task switch */
  127. SUBS R3,#8
  128. CMP R1,#0 /* Runtask deleted? */
  129. BEQ SVC_Next
  130. MRS R0,PSP /* Read PSP */
  131. SUBS R0,R0,#32 /* Adjust Start Address */
  132. STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */
  133. STMIA R0!,{R4-R7} /* Save old context (R4-R7) */
  134. MOV R4,R8
  135. MOV R5,R9
  136. MOV R6,R10
  137. MOV R7,R11
  138. STMIA R0!,{R4-R7} /* Save old context (R8-R11) */
  139. PUSH {R2,R3}
  140. BL rt_stk_check /* Check for Stack overflow */
  141. POP {R2,R3}
  142. SVC_Next:
  143. STR R2,[R3] /* os_tsk.run = os_tsk.next */
  144. LDR R0,[R2,#TCB_TSTACK] /* os_tsk.next->tsk_stack */
  145. ADDS R0,R0,#16 /* Adjust Start Address */
  146. LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */
  147. MOV R8,R4
  148. MOV R9,R5
  149. MOV R10,R6
  150. MOV R11,R7
  151. MSR PSP,R0 /* Write PSP */
  152. SUBS R0,R0,#32 /* Adjust Start Address */
  153. LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */
  154. SVC_Exit:
  155. MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */
  156. MVNS R0,R0
  157. BX R0 /* RETI to Thread Mode, use PSP */
  158. /*------------------- User SVC ------------------------------*/
  159. SVC_User:
  160. PUSH {R4,LR} /* Save Registers */
  161. LDR R2,=SVC_Count
  162. LDR R2,[R2]
  163. CMP R1,R2
  164. BHI SVC_Done /* Overflow */
  165. LDR R4,=SVC_Table-4
  166. LSLS R1,R1,#2
  167. LDR R4,[R4,R1] /* Load SVC Function Address */
  168. MOV LR,R4
  169. LDMIA R0,{R0-R3,R4} /* Read R0-R3,R12 from stack */
  170. MOV R12,R4
  171. BLX LR /* Call SVC Function */
  172. MRS R4,PSP /* Read PSP */
  173. STMIA R4!,{R0-R3} /* Function return values */
  174. SVC_Done:
  175. POP {R4,PC} /* RETI */
  176. /*-------------------------- PendSV_Handler ---------------------------------*/
  177. ; void PendSV_Handler (void);
  178. PUBLIC PendSV_Handler
  179. PendSV_Handler:
  180. BL rt_pop_req
  181. Sys_Switch:
  182. LDR R3,=os_tsk
  183. LDMIA R3!,{R1,R2} /* os_tsk.run, os_tsk.next */
  184. CMP R1,R2
  185. BEQ Sys_Exit /* no task switch */
  186. SUBS R3,#8
  187. MRS R0,PSP /* Read PSP */
  188. SUBS R0,R0,#32 /* Adjust Start Address */
  189. STR R0,[R1,#TCB_TSTACK] /* Update os_tsk.run->tsk_stack */
  190. STMIA R0!,{R4-R7} /* Save old context (R4-R7) */
  191. MOV R4,R8
  192. MOV R5,R9
  193. MOV R6,R10
  194. MOV R7,R11
  195. STMIA R0!,{R4-R7} /* Save old context (R8-R11) */
  196. PUSH {R2,R3}
  197. BL rt_stk_check /* Check for Stack overflow */
  198. POP {R2,R3}
  199. STR R2,[R3] /* os_tsk.run = os_tsk.next */
  200. LDR R0,[R2,#TCB_TSTACK] /* os_tsk.next->tsk_stack */
  201. ADDS R0,R0,#16 /* Adjust Start Address */
  202. LDMIA R0!,{R4-R7} /* Restore new Context (R8-R11) */
  203. MOV R8,R4
  204. MOV R9,R5
  205. MOV R10,R6
  206. MOV R11,R7
  207. MSR PSP,R0 /* Write PSP */
  208. SUBS R0,R0,#32 /* Adjust Start Address */
  209. LDMIA R0!,{R4-R7} /* Restore new Context (R4-R7) */
  210. Sys_Exit:
  211. MOVS R0,#~0xFFFFFFFD /* Set EXC_RETURN value */
  212. MVNS R0,R0
  213. BX R0 /* RETI to Thread Mode, use PSP */
  214. /*-------------------------- SysTick_Handler --------------------------------*/
  215. ; void SysTick_Handler (void);
  216. PUBLIC SysTick_Handler
  217. SysTick_Handler:
  218. BL rt_systick
  219. B Sys_Switch
  220. /*-------------------------- OS_Tick_Handler --------------------------------*/
  221. ; void OS_Tick_Handler (void);
  222. PUBLIC OS_Tick_Handler
  223. OS_Tick_Handler:
  224. BL os_tick_irqack
  225. BL rt_systick
  226. B Sys_Switch
  227. END
  228. /*----------------------------------------------------------------------------
  229. * end of file
  230. *---------------------------------------------------------------------------*/