port_asm.S 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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. #include "ISR_Support.h"
  31. /* Microchip includes. */
  32. #include <xc.h>
  33. #include <sys/asm.h>
  34. .extern pxCurrentTCB
  35. .extern vTaskSwitchContext
  36. .extern vPortIncrementTick
  37. .extern xISRStackTop
  38. PORT_CPP_JTVIC_BASE = 0xBFFFC000
  39. PORT_CCP_JTVIC_GIRQ24_SRC = 0xBFFFC100
  40. .global vPortStartFirstTask .text
  41. .global vPortYieldISR .text
  42. .global vPortTickInterruptHandler .text
  43. /******************************************************************/
  44. /***************************************************************
  45. * The following is needed to locate the
  46. * vPortTickInterruptHandler function into the correct vector
  47. * MEC14xx - This ISR will only be used if HW timers' interrupts
  48. * in GIRQ23 are disaggregated.
  49. *
  50. ***************************************************************/
  51. .set noreorder
  52. .set noat
  53. .set micromips
  54. .section .text, code
  55. .ent vPortTickInterruptHandler
  56. #if configTIMERS_DISAGGREGATED_ISRS == 0
  57. .globl girq23_isr
  58. girq23_isr:
  59. vPortTickInterruptHandler:
  60. portSAVE_CONTEXT
  61. jal girq23_handler
  62. nop
  63. portRESTORE_CONTEXT
  64. .end vPortTickInterruptHandler
  65. #else
  66. .globl girq23_b4
  67. girq23_b4:
  68. vPortTickInterruptHandler:
  69. portSAVE_CONTEXT
  70. jal vPortIncrementTick
  71. nop
  72. portRESTORE_CONTEXT
  73. .end vPortTickInterruptHandler
  74. #endif /* #if configTIMERS_DISAGGREGATED_ISRS == 0 */
  75. /******************************************************************/
  76. .set micromips
  77. .set noreorder
  78. .set noat
  79. .section .text, code
  80. .ent vPortStartFirstTask
  81. vPortStartFirstTask:
  82. /* Simply restore the context of the highest priority task that has
  83. been created so far. */
  84. portRESTORE_CONTEXT
  85. .end vPortStartFirstTask
  86. /*******************************************************************/
  87. /***************************************************************
  88. * The following is needed to locate the vPortYieldISR function into the correct
  89. * vector.
  90. ***************************************************************/
  91. .set micromips
  92. .set noreorder
  93. .set noat
  94. .section .text, code
  95. .global vPortYieldISR
  96. #if configCPU_DISAGGREGATED_ISRS == 0
  97. .global girq24_isr
  98. .ent girq24_isr
  99. girq24_isr:
  100. la k0, PORT_CPP_JTVIC_BASE
  101. lw k0, 0x10C(k0)
  102. andi k1, k0, 0x2
  103. bgtz k1, vPortYieldISR
  104. nop
  105. portSAVE_CONTEXT
  106. jal girq24_b_0_2
  107. portRESTORE_CONTEXT
  108. .end girq24_isr
  109. #else
  110. .global girq24_b1
  111. girq24_b1:
  112. #endif
  113. .ent vPortYieldISR
  114. vPortYieldISR:
  115. /* Make room for the context. First save the current status so it can be
  116. manipulated, and the cause and EPC registers so thier original values
  117. are captured. */
  118. addiu sp, sp, -portCONTEXT_SIZE
  119. mfc0 k1, _CP0_STATUS
  120. /* Also save s6 and s5 so they can be used. Any nesting interrupts should
  121. maintain the values of these registers across the ISR. */
  122. sw s6, 44(sp)
  123. sw s5, 40(sp)
  124. sw k1, portSTATUS_STACK_LOCATION(sp)
  125. /* Prepare to re-enable interrupts above the kernel priority. */
  126. ins k1, zero, 10, 7 /* Clear IPL bits 0:6. */
  127. ins k1, zero, 18, 1 /* Clear IPL bit 7 */
  128. ori k1, k1, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 )
  129. ins k1, zero, 1, 4 /* Clear EXL, ERL and UM. */
  130. /* s5 is used as the frame pointer. */
  131. add s5, zero, sp
  132. /* Swap to the system stack. This is not conditional on the nesting
  133. count as this interrupt is always the lowest priority and therefore
  134. the nesting is always 0. */
  135. la sp, xISRStackTop
  136. lw sp, (sp)
  137. /* Set the nesting count. */
  138. la k0, uxInterruptNesting
  139. addiu s6, zero, 1
  140. sw s6, 0(k0)
  141. /* s6 holds the EPC value, this is saved with the rest of the context
  142. after interrupts are enabled. */
  143. mfc0 s6, _CP0_EPC
  144. /* Re-enable interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY. */
  145. mtc0 k1, _CP0_STATUS
  146. /* Save the context into the space just created. s6 is saved again
  147. here as it now contains the EPC value. */
  148. sw ra, 120(s5)
  149. sw s8, 116(s5)
  150. sw t9, 112(s5)
  151. sw t8, 108(s5)
  152. sw t7, 104(s5)
  153. sw t6, 100(s5)
  154. sw t5, 96(s5)
  155. sw t4, 92(s5)
  156. sw t3, 88(s5)
  157. sw t2, 84(s5)
  158. sw t1, 80(s5)
  159. sw t0, 76(s5)
  160. sw a3, 72(s5)
  161. sw a2, 68(s5)
  162. sw a1, 64(s5)
  163. sw a0, 60(s5)
  164. sw v1, 56(s5)
  165. sw v0, 52(s5)
  166. sw s7, 48(s5)
  167. sw s6, portEPC_STACK_LOCATION(s5)
  168. /* s5 and s6 has already been saved. */
  169. sw s4, 36(s5)
  170. sw s3, 32(s5)
  171. sw s2, 28(s5)
  172. sw s1, 24(s5)
  173. sw s0, 20(s5)
  174. sw $1, 16(s5)
  175. /* s7 is used as a scratch register as this should always be saved acro ss
  176. nesting interrupts. */
  177. mfhi s7
  178. sw s7, 12(s5)
  179. mflo s7
  180. sw s7, 8(s5)
  181. /* Save the stack pointer to the task. */
  182. la s7, pxCurrentTCB
  183. lw s7, (s7)
  184. sw s5, (s7)
  185. /* Set the interrupt mask to the max priority that can use the API.
  186. The yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY
  187. which is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only
  188. ever raise the IPL value and never lower it. */
  189. di
  190. ehb
  191. mfc0 s7, _CP0_STATUS
  192. ins s7, zero, 10, 7
  193. ins s7, zero, 18, 1
  194. ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1
  195. /* This mtc0 re-enables interrupts, but only above
  196. configMAX_SYSCALL_INTERRUPT_PRIORITY. */
  197. mtc0 s6, _CP0_STATUS
  198. ehb
  199. /* Clear the software interrupt in the core. */
  200. mfc0 s6, _CP0_CAUSE
  201. ins s6, zero, 8, 1
  202. mtc0 s6, _CP0_CAUSE
  203. ehb
  204. /* Clear the interrupt in the interrupt controller.
  205. MEC14xx GIRQ24 Source bit[1] = 1 to clear */
  206. la s6, PORT_CCP_JTVIC_GIRQ24_SRC
  207. addiu s4, zero, 2
  208. sw s4, (s6)
  209. jal vTaskSwitchContext
  210. nop
  211. /* Clear the interrupt mask again. The saved status value is still in s7 */
  212. mtc0 s7, _CP0_STATUS
  213. ehb
  214. /* Restore the stack pointer from the TCB. */
  215. la s0, pxCurrentTCB
  216. lw s0, (s0)
  217. lw s5, (s0)
  218. /* Restore the rest of the context. */
  219. lw s0, 8(s5)
  220. mtlo s0
  221. lw s0, 12(s5)
  222. mthi s0
  223. lw $1, 16(s5)
  224. lw s0, 20(s5)
  225. lw s1, 24(s5)
  226. lw s2, 28(s5)
  227. lw s3, 32(s5)
  228. lw s4, 36(s5)
  229. /* s5 is loaded later. */
  230. lw s6, 44(s5)
  231. lw s7, 48(s5)
  232. lw v0, 52(s5)
  233. lw v1, 56(s5)
  234. lw a0, 60(s5)
  235. lw a1, 64(s5)
  236. lw a2, 68(s5)
  237. lw a3, 72(s5)
  238. lw t0, 76(s5)
  239. lw t1, 80(s5)
  240. lw t2, 84(s5)
  241. lw t3, 88(s5)
  242. lw t4, 92(s5)
  243. lw t5, 96(s5)
  244. lw t6, 100(s5)
  245. lw t7, 104(s5)
  246. lw t8, 108(s5)
  247. lw t9, 112(s5)
  248. lw s8, 116(s5)
  249. lw ra, 120(s5)
  250. /* Protect access to the k registers, and others. */
  251. di
  252. ehb
  253. /* Set nesting back to zero. As the lowest priority interrupt this
  254. interrupt cannot have nested. */
  255. la k0, uxInterruptNesting
  256. sw zero, 0(k0)
  257. /* Switch back to use the real stack pointer. */
  258. add sp, zero, s5
  259. /* Restore the real s5 value. */
  260. lw s5, 40(sp)
  261. /* Pop the status and epc values. */
  262. lw k1, portSTATUS_STACK_LOCATION(sp)
  263. lw k0, portEPC_STACK_LOCATION(sp)
  264. /* Remove stack frame. */
  265. addiu sp, sp, portCONTEXT_SIZE
  266. mtc0 k1, _CP0_STATUS
  267. mtc0 k0, _CP0_EPC
  268. ehb
  269. eret
  270. nop
  271. .end vPortYieldISR