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 vApplicationIRQHandler 33 EXTERN vTaskSwitchContext 34 EXTERN ulPortYieldRequired 35 EXTERN ulPortInterruptNesting 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 46 SECTION .text:CODE:ROOT(2) 47 ARM 48 49 INCLUDE portASM.h 50 51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 52; SVC handler is used to yield a task. 53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 54FreeRTOS_SWI_Handler 55 56 PRESERVE8 57 58 ; Save the context of the current task and select a new task to run. 59 portSAVE_CONTEXT 60 LDR R0, =vTaskSwitchContext 61 BLX R0 62 portRESTORE_CONTEXT 63 64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 65; vPortRestoreTaskContext is used to start the scheduler. 66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 67vPortRestoreTaskContext 68 ; Switch to system mode 69 CPS #SYS_MODE 70 portRESTORE_CONTEXT 71 72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 73; PL390 GIC interrupt handler 74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 75FreeRTOS_IRQ_Handler 76 77 ; Return to the interrupted instruction. 78 SUB lr, lr, #4 79 80 ; Push the return address and SPSR 81 PUSH {lr} 82 MRS lr, SPSR 83 PUSH {lr} 84 85 ; Change to supervisor mode to allow reentry. 86 CPS #SVC_MODE 87 88 ; Push used registers. 89 PUSH {r0-r4, r12} 90 91 ; Increment nesting count. r3 holds the address of ulPortInterruptNesting 92 ; for future use. r1 holds the original ulPortInterruptNesting value for 93 ; future use. 94 LDR r3, =ulPortInterruptNesting 95 LDR r1, [r3] 96 ADD r4, r1, #1 97 STR r4, [r3] 98 99 ; Read value from the interrupt acknowledge register, which is stored in r0 100 ; for future parameter and interrupt clearing use. 101 LDR r2, =portICCIAR_INTERRUPT_ACKNOWLEDGE_REGISTER_ADDRESS 102 LDR r0, [r2] 103 104 ; Ensure bit 2 of the stack pointer is clear. r2 holds the bit 2 value for 105 ; future use. _RB_ Is this ever necessary if start of stack is 8-byte aligned? 106 MOV r2, sp 107 AND r2, r2, #4 108 SUB sp, sp, r2 109 110 ; Call the interrupt handler. r4 is pushed to maintain alignment. 111 PUSH {r0-r4, lr} 112 LDR r1, =vApplicationIRQHandler 113 BLX r1 114 POP {r0-r4, lr} 115 ADD sp, sp, r2 116 117 CPSID i 118 119 ; Write the value read from ICCIAR to ICCEOIR 120 LDR r4, =portICCEOIR_END_OF_INTERRUPT_REGISTER_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 174 END 175