1;/* 2; * FreeRTOS Kernel V11.1.0 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 29 INCLUDE portmacro.inc 30 31 IMPORT vApplicationIRQHandler 32 IMPORT vTaskSwitchContext 33 IMPORT ulPortYieldRequired 34 IMPORT ulPortInterruptNesting 35 IMPORT vTaskSwitchContext 36 IMPORT ulICCIAR 37 IMPORT ulICCEOIR 38 39 EXPORT FreeRTOS_SWI_Handler 40 EXPORT FreeRTOS_IRQ_Handler 41 EXPORT vPortRestoreTaskContext 42 43 ARM 44 AREA PORT_ASM, CODE, READONLY 45 46 47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 48; SVC handler is used to yield a task. 49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 50FreeRTOS_SWI_Handler 51 52 PRESERVE8 53 54 ; Save the context of the current task and select a new task to run. 55 portSAVE_CONTEXT 56 LDR R0, =vTaskSwitchContext 57 BLX R0 58 portRESTORE_CONTEXT 59 60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 61; vPortRestoreTaskContext is used to start the scheduler. 62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 63vPortRestoreTaskContext 64 ; Switch to system mode 65 CPS #SYS_MODE 66 portRESTORE_CONTEXT 67 68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 69; PL390 GIC interrupt handler 70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 71FreeRTOS_IRQ_Handler 72 73 ; Return to the interrupted instruction. 74 SUB lr, lr, #4 75 76 ; Push the return address and SPSR 77 PUSH {lr} 78 MRS lr, SPSR 79 PUSH {lr} 80 81 ; Change to supervisor mode to allow reentry. 82 CPS #SVC_MODE 83 84 ; Push used registers. 85 PUSH {r0-r4, r12} 86 87 ; Increment nesting count. r3 holds the address of ulPortInterruptNesting 88 ; for future use. r1 holds the original ulPortInterruptNesting value for 89 ; future use. 90 LDR r3, =ulPortInterruptNesting 91 LDR r1, [r3] 92 ADD r4, r1, #1 93 STR r4, [r3] 94 95 ; Read value from the interrupt acknowledge register, which is stored in r0 96 ; for future parameter and interrupt clearing use. 97 LDR r2, =ulICCIAR 98 LDR r0, [r2] 99 100 ; Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for 101 ; future use. _RB_ Does this ever actually need to be done provided the 102 ; start of the stack is 8-byte aligned? 103 MOV r2, sp 104 AND r2, r2, #4 105 SUB sp, sp, r2 106 107 ; Call the interrupt handler. r4 is pushed to maintain alignment. 108 PUSH {r0-r4, lr} 109 LDR r1, =vApplicationIRQHandler 110 BLX r1 111 POP {r0-r4, lr} 112 ADD sp, sp, r2 113 114 CPSID i 115 116 ; Write the value read from ICCIAR to ICCEOIR 117 LDR r4, =ulICCEOIR 118 STR r0, [r4] 119 120 ; Restore the old nesting count 121 STR r1, [r3] 122 123 ; A context switch is never performed if the nesting count is not 0 124 CMP r1, #0 125 BNE exit_without_switch 126 127 ; Did the interrupt request a context switch? r1 holds the address of 128 ; ulPortYieldRequired and r0 the value of ulPortYieldRequired for future 129 ; use. 130 LDR r1, =ulPortYieldRequired 131 LDR r0, [r1] 132 CMP r0, #0 133 BNE switch_before_exit 134 135exit_without_switch 136 ; No context switch. Restore used registers, LR_irq and SPSR before 137 ; returning. 138 POP {r0-r4, r12} 139 CPS #IRQ_MODE 140 POP {LR} 141 MSR SPSR_cxsf, LR 142 POP {LR} 143 MOVS PC, LR 144 145switch_before_exit 146 ; A context switch is to be performed. Clear the context switch pending 147 ; flag. 148 MOV r0, #0 149 STR r0, [r1] 150 151 ; Restore used registers, LR-irq and SPSR before saving the context 152 ; to the task stack. 153 POP {r0-r4, r12} 154 CPS #IRQ_MODE 155 POP {LR} 156 MSR SPSR_cxsf, LR 157 POP {LR} 158 portSAVE_CONTEXT 159 160 ; Call the function that selects the new task to execute. 161 ; vTaskSwitchContext() if vTaskSwitchContext() uses LDRD or STRD 162 ; instructions, or 8 byte aligned stack allocated data. LR does not need 163 ; saving as a new LR will be loaded by portRESTORE_CONTEXT anyway. 164 LDR r0, =vTaskSwitchContext 165 BLX r0 166 167 ; Restore the context of, and branch to, the task selected to execute next. 168 portRESTORE_CONTEXT 169 170 171 END 172