2 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 * SPDX-License-Identifier: MIT
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:
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
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.
24 * https://www.FreeRTOS.org
25 * https://github.com/FreeRTOS
31 #include "ISR_Support.h"
38 .extern vTaskSwitchContext
39 .extern vPortIncrementTick
42 .global vPortStartFirstTask
44 .global vPortTickInterruptHandler
47 /******************************************************************/
51 .ent vPortTickInterruptHandler
53 vPortTickInterruptHandler:
57 jal vPortIncrementTick
62 .end vPortTickInterruptHandler
64 /******************************************************************/
68 .ent vPortStartFirstTask
72 /* Simply restore the context of the highest priority task that has been
76 .end vPortStartFirstTask
80 /*******************************************************************/
88 /* Make room for the context. First save the current status so it can be
90 addiu sp, sp, -portCONTEXT_SIZE
93 /* Also save s6 and s5 so they can be used. Any nesting interrupts should
94 maintain the values of these registers across the ISR. */
97 sw k1, portSTATUS_STACK_LOCATION(sp)
99 /* Prepare to re-enabled interrupt above the kernel priority. */
101 ori k1, k1, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 )
104 /* s5 is used as the frame pointer. */
107 /* Swap to the system stack. This is not conditional on the nesting
108 count as this interrupt is always the lowest priority and therefore
109 the nesting is always 0. */
113 /* Set the nesting count. */
114 la k0, uxInterruptNesting
118 /* s6 holds the EPC value, this is saved with the rest of the context
119 after interrupts are enabled. */
122 /* Re-enable interrupts above configMAX_SYSCALL_INTERRUPT_PRIORITY. */
125 /* Save the context into the space just created. s6 is saved again
126 here as it now contains the EPC value. */
146 sw s6, portEPC_STACK_LOCATION(s5)
147 /* s5 and s6 has already been saved. */
155 /* s7 is used as a scratch register as this should always be saved across
156 nesting interrupts. */
162 /* Save the stack pointer to the task. */
167 /* Set the interrupt mask to the max priority that can use the API. The
168 yield handler will only be called at configKERNEL_INTERRUPT_PRIORITY which
169 is below configMAX_SYSCALL_INTERRUPT_PRIORITY - so this can only ever
170 raise the IPL value and never lower it. */
175 ori s6, s7, ( configMAX_SYSCALL_INTERRUPT_PRIORITY << 10 ) | 1
177 /* This mtc0 re-enables interrupts, but only above
178 configMAX_SYSCALL_INTERRUPT_PRIORITY. */
182 /* Clear the software interrupt in the core. */
188 /* Clear the interrupt in the interrupt controller. */
193 jal vTaskSwitchContext
196 /* Clear the interrupt mask again. The saved status value is still in s7. */
200 /* Restore the stack pointer from the TCB. */
205 /* Restore the rest of the context. */
216 /* s5 is loaded later. */
238 /* Protect access to the k registers, and others. */
242 /* Set nesting back to zero. As the lowest priority interrupt this
243 interrupt cannot have nested. */
244 la k0, uxInterruptNesting
247 /* Switch back to use the real stack pointer. */
250 /* Restore the real s5 value. */
253 /* Pop the status and epc values. */
254 lw k1, portSTATUS_STACK_LOCATION(sp)
255 lw k0, portEPC_STACK_LOCATION(sp)
257 /* Remove stack frame. */
258 addiu sp, sp, portCONTEXT_SIZE