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