portasm.S 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. * FreeRTOS Kernel V10.4.6
  3. * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * SPDX-License-Identifier: MIT
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. * this software and associated documentation files (the "Software"), to deal in
  9. * the Software without restriction, including without limitation the rights to
  10. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. * the Software, and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * https://www.FreeRTOS.org
  25. * https://github.com/FreeRTOS
  26. *
  27. */
  28. /* FreeRTOS includes. */
  29. #include "FreeRTOSConfig.h"
  30. /* Xilinx library includes. */
  31. #include "microblaze_exceptions_g.h"
  32. #include "xparameters.h"
  33. /* The context is oversized to allow functions called from the ISR to write
  34. back into the caller stack. */
  35. #if( XPAR_MICROBLAZE_USE_FPU != 0 )
  36. #define portCONTEXT_SIZE 136
  37. #define portMINUS_CONTEXT_SIZE -136
  38. #else
  39. #define portCONTEXT_SIZE 132
  40. #define portMINUS_CONTEXT_SIZE -132
  41. #endif
  42. /* Offsets from the stack pointer at which saved registers are placed. */
  43. #define portR31_OFFSET 4
  44. #define portR30_OFFSET 8
  45. #define portR29_OFFSET 12
  46. #define portR28_OFFSET 16
  47. #define portR27_OFFSET 20
  48. #define portR26_OFFSET 24
  49. #define portR25_OFFSET 28
  50. #define portR24_OFFSET 32
  51. #define portR23_OFFSET 36
  52. #define portR22_OFFSET 40
  53. #define portR21_OFFSET 44
  54. #define portR20_OFFSET 48
  55. #define portR19_OFFSET 52
  56. #define portR18_OFFSET 56
  57. #define portR17_OFFSET 60
  58. #define portR16_OFFSET 64
  59. #define portR15_OFFSET 68
  60. #define portR14_OFFSET 72
  61. #define portR13_OFFSET 76
  62. #define portR12_OFFSET 80
  63. #define portR11_OFFSET 84
  64. #define portR10_OFFSET 88
  65. #define portR9_OFFSET 92
  66. #define portR8_OFFSET 96
  67. #define portR7_OFFSET 100
  68. #define portR6_OFFSET 104
  69. #define portR5_OFFSET 108
  70. #define portR4_OFFSET 112
  71. #define portR3_OFFSET 116
  72. #define portR2_OFFSET 120
  73. #define portCRITICAL_NESTING_OFFSET 124
  74. #define portMSR_OFFSET 128
  75. #define portFSR_OFFSET 132
  76. .extern pxCurrentTCB
  77. .extern XIntc_DeviceInterruptHandler
  78. .extern vTaskSwitchContext
  79. .extern uxCriticalNesting
  80. .extern pulISRStack
  81. .extern ulTaskSwitchRequested
  82. .extern vPortExceptionHandler
  83. .extern pulStackPointerOnFunctionEntry
  84. .global _interrupt_handler
  85. .global VPortYieldASM
  86. .global vPortStartFirstTask
  87. .global vPortExceptionHandlerEntry
  88. .macro portSAVE_CONTEXT
  89. /* Make room for the context on the stack. */
  90. addik r1, r1, portMINUS_CONTEXT_SIZE
  91. /* Stack general registers. */
  92. swi r31, r1, portR31_OFFSET
  93. swi r30, r1, portR30_OFFSET
  94. swi r29, r1, portR29_OFFSET
  95. swi r28, r1, portR28_OFFSET
  96. swi r27, r1, portR27_OFFSET
  97. swi r26, r1, portR26_OFFSET
  98. swi r25, r1, portR25_OFFSET
  99. swi r24, r1, portR24_OFFSET
  100. swi r23, r1, portR23_OFFSET
  101. swi r22, r1, portR22_OFFSET
  102. swi r21, r1, portR21_OFFSET
  103. swi r20, r1, portR20_OFFSET
  104. swi r19, r1, portR19_OFFSET
  105. swi r18, r1, portR18_OFFSET
  106. swi r17, r1, portR17_OFFSET
  107. swi r16, r1, portR16_OFFSET
  108. swi r15, r1, portR15_OFFSET
  109. /* R14 is saved later as it needs adjustment if a yield is performed. */
  110. swi r13, r1, portR13_OFFSET
  111. swi r12, r1, portR12_OFFSET
  112. swi r11, r1, portR11_OFFSET
  113. swi r10, r1, portR10_OFFSET
  114. swi r9, r1, portR9_OFFSET
  115. swi r8, r1, portR8_OFFSET
  116. swi r7, r1, portR7_OFFSET
  117. swi r6, r1, portR6_OFFSET
  118. swi r5, r1, portR5_OFFSET
  119. swi r4, r1, portR4_OFFSET
  120. swi r3, r1, portR3_OFFSET
  121. swi r2, r1, portR2_OFFSET
  122. /* Stack the critical section nesting value. */
  123. lwi r18, r0, uxCriticalNesting
  124. swi r18, r1, portCRITICAL_NESTING_OFFSET
  125. /* Stack MSR. */
  126. mfs r18, rmsr
  127. swi r18, r1, portMSR_OFFSET
  128. #if( XPAR_MICROBLAZE_USE_FPU != 0 )
  129. /* Stack FSR. */
  130. mfs r18, rfsr
  131. swi r18, r1, portFSR_OFFSET
  132. #endif
  133. /* Save the top of stack value to the TCB. */
  134. lwi r3, r0, pxCurrentTCB
  135. sw r1, r0, r3
  136. .endm
  137. .macro portRESTORE_CONTEXT
  138. /* Load the top of stack value from the TCB. */
  139. lwi r18, r0, pxCurrentTCB
  140. lw r1, r0, r18
  141. /* Restore the general registers. */
  142. lwi r31, r1, portR31_OFFSET
  143. lwi r30, r1, portR30_OFFSET
  144. lwi r29, r1, portR29_OFFSET
  145. lwi r28, r1, portR28_OFFSET
  146. lwi r27, r1, portR27_OFFSET
  147. lwi r26, r1, portR26_OFFSET
  148. lwi r25, r1, portR25_OFFSET
  149. lwi r24, r1, portR24_OFFSET
  150. lwi r23, r1, portR23_OFFSET
  151. lwi r22, r1, portR22_OFFSET
  152. lwi r21, r1, portR21_OFFSET
  153. lwi r20, r1, portR20_OFFSET
  154. lwi r19, r1, portR19_OFFSET
  155. lwi r17, r1, portR17_OFFSET
  156. lwi r16, r1, portR16_OFFSET
  157. lwi r15, r1, portR15_OFFSET
  158. lwi r14, r1, portR14_OFFSET
  159. lwi r13, r1, portR13_OFFSET
  160. lwi r12, r1, portR12_OFFSET
  161. lwi r11, r1, portR11_OFFSET
  162. lwi r10, r1, portR10_OFFSET
  163. lwi r9, r1, portR9_OFFSET
  164. lwi r8, r1, portR8_OFFSET
  165. lwi r7, r1, portR7_OFFSET
  166. lwi r6, r1, portR6_OFFSET
  167. lwi r5, r1, portR5_OFFSET
  168. lwi r4, r1, portR4_OFFSET
  169. lwi r3, r1, portR3_OFFSET
  170. lwi r2, r1, portR2_OFFSET
  171. /* Reload the rmsr from the stack. */
  172. lwi r18, r1, portMSR_OFFSET
  173. mts rmsr, r18
  174. #if( XPAR_MICROBLAZE_USE_FPU != 0 )
  175. /* Reload the FSR from the stack. */
  176. lwi r18, r1, portFSR_OFFSET
  177. mts rfsr, r18
  178. #endif
  179. /* Load the critical nesting value. */
  180. lwi r18, r1, portCRITICAL_NESTING_OFFSET
  181. swi r18, r0, uxCriticalNesting
  182. /* Test the critical nesting value. If it is non zero then the task last
  183. exited the running state using a yield. If it is zero, then the task
  184. last exited the running state through an interrupt. */
  185. xori r18, r18, 0
  186. bnei r18, exit_from_yield
  187. /* r18 was being used as a temporary. Now restore its true value from the
  188. stack. */
  189. lwi r18, r1, portR18_OFFSET
  190. /* Remove the stack frame. */
  191. addik r1, r1, portCONTEXT_SIZE
  192. /* Return using rtid so interrupts are re-enabled as this function is
  193. exited. */
  194. rtid r14, 0
  195. or r0, r0, r0
  196. .endm
  197. /* This function is used to exit portRESTORE_CONTEXT() if the task being
  198. returned to last left the Running state by calling taskYIELD() (rather than
  199. being preempted by an interrupt). */
  200. .text
  201. .align 4
  202. exit_from_yield:
  203. /* r18 was being used as a temporary. Now restore its true value from the
  204. stack. */
  205. lwi r18, r1, portR18_OFFSET
  206. /* Remove the stack frame. */
  207. addik r1, r1, portCONTEXT_SIZE
  208. /* Return to the task. */
  209. rtsd r14, 0
  210. or r0, r0, r0
  211. .text
  212. .align 4
  213. _interrupt_handler:
  214. portSAVE_CONTEXT
  215. /* Stack the return address. */
  216. swi r14, r1, portR14_OFFSET
  217. /* Switch to the ISR stack. */
  218. lwi r1, r0, pulISRStack
  219. /* The parameter to the interrupt handler. */
  220. ori r5, r0, configINTERRUPT_CONTROLLER_TO_USE
  221. /* Execute any pending interrupts. */
  222. bralid r15, XIntc_DeviceInterruptHandler
  223. or r0, r0, r0
  224. /* See if a new task should be selected to execute. */
  225. lwi r18, r0, ulTaskSwitchRequested
  226. or r18, r18, r0
  227. /* If ulTaskSwitchRequested is already zero, then jump straight to
  228. restoring the task that is already in the Running state. */
  229. beqi r18, task_switch_not_requested
  230. /* Set ulTaskSwitchRequested back to zero as a task switch is about to be
  231. performed. */
  232. swi r0, r0, ulTaskSwitchRequested
  233. /* ulTaskSwitchRequested was not 0 when tested. Select the next task to
  234. execute. */
  235. bralid r15, vTaskSwitchContext
  236. or r0, r0, r0
  237. task_switch_not_requested:
  238. /* Restore the context of the next task scheduled to execute. */
  239. portRESTORE_CONTEXT
  240. .text
  241. .align 4
  242. VPortYieldASM:
  243. portSAVE_CONTEXT
  244. /* Modify the return address so a return is done to the instruction after
  245. the call to VPortYieldASM. */
  246. addi r14, r14, 8
  247. swi r14, r1, portR14_OFFSET
  248. /* Switch to use the ISR stack. */
  249. lwi r1, r0, pulISRStack
  250. /* Select the next task to execute. */
  251. bralid r15, vTaskSwitchContext
  252. or r0, r0, r0
  253. /* Restore the context of the next task scheduled to execute. */
  254. portRESTORE_CONTEXT
  255. .text
  256. .align 4
  257. vPortStartFirstTask:
  258. portRESTORE_CONTEXT
  259. #if ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 )
  260. .text
  261. .align 4
  262. vPortExceptionHandlerEntry:
  263. /* Take a copy of the stack pointer before vPortExecptionHandler is called,
  264. storing its value prior to the function stack frame being created. */
  265. swi r1, r0, pulStackPointerOnFunctionEntry
  266. bralid r15, vPortExceptionHandler
  267. or r0, r0, r0
  268. #endif /* ( MICROBLAZE_EXCEPTIONS_ENABLED == 1 ) && ( configINSTALL_EXCEPTION_HANDLERS == 1 ) */