1;/* 2; * FreeRTOS Kernel V10.6.2 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 .thumb 30 31 .ref pxCurrentTCB 32 .ref vTaskSwitchContext 33 .ref ulMaxSyscallInterruptPriority 34 35 .def xPortPendSVHandler 36 .def ulPortGetIPSR 37 .def vPortSVCHandler 38 .def vPortStartFirstTask 39 .def vPortEnableVFP 40 41NVICOffsetConst: .word 0xE000ED08 42CPACRConst: .word 0xE000ED88 43pxCurrentTCBConst: .word pxCurrentTCB 44ulMaxSyscallInterruptPriorityConst: .word ulMaxSyscallInterruptPriority 45 46; ----------------------------------------------------------- 47 48 .align 4 49ulPortGetIPSR: .asmfunc 50 mrs r0, ipsr 51 bx r14 52 .endasmfunc 53 ; ----------------------------------------------------------- 54 55 .align 4 56vPortSetInterruptMask: .asmfunc 57 push {r0} 58 ldr r0, ulMaxSyscallInterruptPriorityConst 59 msr basepri, r0 60 pop {r0} 61 bx r14 62 .endasmfunc 63; ----------------------------------------------------------- 64 65 .align 4 66xPortPendSVHandler: .asmfunc 67 mrs r0, psp 68 isb 69 70 ;/* Get the location of the current TCB. */ 71 ldr r3, pxCurrentTCBConst 72 ldr r2, [r3] 73 74 ;/* Is the task using the FPU context? If so, push high vfp registers. */ 75 tst r14, #0x10 76 it eq 77 vstmdbeq r0!, {s16-s31} 78 79 ;/* Save the core registers. */ 80 stmdb r0!, {r4-r11, r14} 81 82 ;/* Save the new top of stack into the first member of the TCB. */ 83 str r0, [r2] 84 85 stmdb sp!, {r0, r3} 86 ldr r0, ulMaxSyscallInterruptPriorityConst 87 ldr r1, [r0] 88 msr basepri, r1 89 dsb 90 isb 91 bl vTaskSwitchContext 92 mov r0, #0 93 msr basepri, r0 94 ldmia sp!, {r0, r3} 95 96 ;/* The first item in pxCurrentTCB is the task top of stack. */ 97 ldr r1, [r3] 98 ldr r0, [r1] 99 100 ;/* Pop the core registers. */ 101 ldmia r0!, {r4-r11, r14} 102 103 ;/* Is the task using the FPU context? If so, pop the high vfp registers 104 ;too. */ 105 tst r14, #0x10 106 it eq 107 vldmiaeq r0!, {s16-s31} 108 109 msr psp, r0 110 isb 111 bx r14 112 .endasmfunc 113 114; ----------------------------------------------------------- 115 116 .align 4 117vPortSVCHandler: .asmfunc 118 ;/* Get the location of the current TCB. */ 119 ldr r3, pxCurrentTCBConst 120 ldr r1, [r3] 121 ldr r0, [r1] 122 ;/* Pop the core registers. */ 123 ldmia r0!, {r4-r11, r14} 124 msr psp, r0 125 isb 126 mov r0, #0 127 msr basepri, r0 128 bx r14 129 .endasmfunc 130 131; ----------------------------------------------------------- 132 133 .align 4 134vPortStartFirstTask: .asmfunc 135 ;/* Use the NVIC offset register to locate the stack. */ 136 ldr r0, NVICOffsetConst 137 ldr r0, [r0] 138 ldr r0, [r0] 139 ;/* Set the msp back to the start of the stack. */ 140 msr msp, r0 141 ;/* Clear the bit that indicates the FPU is in use in case the FPU was used 142 ;before the scheduler was started - which would otherwise result in the 143 ;unnecessary leaving of space in the SVC stack for lazy saving of FPU 144 ;registers. */ 145 mov r0, #0 146 msr control, r0 147 ;/* Call SVC to start the first task. */ 148 cpsie i 149 cpsie f 150 dsb 151 isb 152 svc #0 153 .endasmfunc 154 155; ----------------------------------------------------------- 156 157 .align 4 158vPortEnableVFP: .asmfunc 159 ;/* The FPU enable bits are in the CPACR. */ 160 ldr.w r0, CPACRConst 161 ldr r1, [r0] 162 163 ;/* Enable CP10 and CP11 coprocessors, then save back. */ 164 orr r1, r1, #( 0xf << 20 ) 165 str r1, [r0] 166 bx r14 167 .endasmfunc 168 169 .end 170 171; ----------------------------------------------------------- 172