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#include "FreeRTOSConfig.h" 30 31 .extern pxCurrentTCB 32 .extern vTaskSwitchContext 33 .extern xTaskIncrementTick 34 .extern vPortISRHandler 35 36 .global vPortStartFirstTask 37 .global vPortYield 38 .global vPortTickISR 39 .global vPortISRWrapper 40 .global vPortSaveFPURegisters 41 .global vPortRestoreFPURegisters 42 43.set BChainField, 0 44.set NextLRField, BChainField + 4 45.set MSRField, NextLRField + 4 46.set PCField, MSRField + 4 47.set LRField, PCField + 4 48.set CTRField, LRField + 4 49.set XERField, CTRField + 4 50.set CRField, XERField + 4 51.set USPRG0Field, CRField + 4 52.set r0Field, USPRG0Field + 4 53.set r2Field, r0Field + 4 54.set r3r31Field, r2Field + 4 55.set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4 56 57 58.macro portSAVE_STACK_POINTER_AND_LR 59 60 /* Get the address of the TCB. */ 61 xor R0, R0, R0 62 addis R2, R0, pxCurrentTCB@ha 63 lwz R2, pxCurrentTCB@l( R2 ) 64 65 /* Store the stack pointer into the TCB */ 66 stw SP, 0( R2 ) 67 68 /* Save the link register */ 69 stwu R1, -24( R1 ) 70 mflr R0 71 stw R31, 20( R1 ) 72 stw R0, 28( R1 ) 73 mr R31, r1 74 75.endm 76 77.macro portRESTORE_STACK_POINTER_AND_LR 78 79 /* Restore the link register */ 80 lwz R11, 0( R1 ) 81 lwz R0, 4( R11 ) 82 mtlr R0 83 lwz R31, -4( R11 ) 84 mr R1, R11 85 86 /* Get the address of the TCB. */ 87 xor R0, R0, R0 88 addis SP, R0, pxCurrentTCB@ha 89 lwz SP, pxCurrentTCB@l( R1 ) 90 91 /* Get the task stack pointer from the TCB. */ 92 lwz SP, 0( SP ) 93 94.endm 95 96 97vPortStartFirstTask: 98 99 /* Get the address of the TCB. */ 100 xor R0, R0, R0 101 addis SP, R0, pxCurrentTCB@ha 102 lwz SP, pxCurrentTCB@l( SP ) 103 104 /* Get the task stack pointer from the TCB. */ 105 lwz SP, 0( SP ) 106 107 /* Restore MSR register to SRR1. */ 108 lwz R0, MSRField(R1) 109 mtsrr1 R0 110 111 /* Restore current PC location to SRR0. */ 112 lwz R0, PCField(R1) 113 mtsrr0 R0 114 115 /* Save USPRG0 register */ 116 lwz R0, USPRG0Field(R1) 117 mtspr 0x100,R0 118 119 /* Restore Condition register */ 120 lwz R0, CRField(R1) 121 mtcr R0 122 123 /* Restore Fixed Point Exception register */ 124 lwz R0, XERField(R1) 125 mtxer R0 126 127 /* Restore Counter register */ 128 lwz R0, CTRField(R1) 129 mtctr R0 130 131 /* Restore Link register */ 132 lwz R0, LRField(R1) 133 mtlr R0 134 135 /* Restore remaining GPR registers. */ 136 lmw R3,r3r31Field(R1) 137 138 /* Restore r0 and r2. */ 139 lwz R0, r0Field(R1) 140 lwz R2, r2Field(R1) 141 142 /* Remove frame from stack */ 143 addi R1,R1,IFrameSize 144 145 /* Return into the first task */ 146 rfi 147 148 149 150vPortYield: 151 152 portSAVE_STACK_POINTER_AND_LR 153 bl vTaskSwitchContext 154 portRESTORE_STACK_POINTER_AND_LR 155 blr 156 157vPortTickISR: 158 159 portSAVE_STACK_POINTER_AND_LR 160 bl xTaskIncrementTick 161 162 #if configUSE_PREEMPTION == 1 163 bl vTaskSwitchContext 164 #endif 165 166 /* Clear the interrupt */ 167 lis R0, 2048 168 mttsr R0 169 170 portRESTORE_STACK_POINTER_AND_LR 171 blr 172 173vPortISRWrapper: 174 175 portSAVE_STACK_POINTER_AND_LR 176 bl vPortISRHandler 177 portRESTORE_STACK_POINTER_AND_LR 178 blr 179 180#if configUSE_FPU == 1 181 182vPortSaveFPURegisters: 183 184 /* Enable APU and mark FPU as present. */ 185 mfmsr r0 186 xor r30, r30, r30 187 oris r30, r30, 512 188 ori r30, r30, 8192 189 or r0, r0, r30 190 mtmsr r0 191 192#ifdef USE_DP_FPU 193 194 /* Buffer address is in r3. Save each flop register into an offset from 195 this buffer address. */ 196 stfd f0, 0(r3) 197 stfd f1, 8(r3) 198 stfd f2, 16(r3) 199 stfd f3, 24(r3) 200 stfd f4, 32(r3) 201 stfd f5, 40(r3) 202 stfd f6, 48(r3) 203 stfd f7, 56(r3) 204 stfd f8, 64(r3) 205 stfd f9, 72(r3) 206 stfd f10, 80(r3) 207 stfd f11, 88(r3) 208 stfd f12, 96(r3) 209 stfd f13, 104(r3) 210 stfd f14, 112(r3) 211 stfd f15, 120(r3) 212 stfd f16, 128(r3) 213 stfd f17, 136(r3) 214 stfd f18, 144(r3) 215 stfd f19, 152(r3) 216 stfd f20, 160(r3) 217 stfd f21, 168(r3) 218 stfd f22, 176(r3) 219 stfd f23, 184(r3) 220 stfd f24, 192(r3) 221 stfd f25, 200(r3) 222 stfd f26, 208(r3) 223 stfd f27, 216(r3) 224 stfd f28, 224(r3) 225 stfd f29, 232(r3) 226 stfd f30, 240(r3) 227 stfd f31, 248(r3) 228 229 /* Also save the FPSCR. */ 230 mffs f31 231 stfs f31, 256(r3) 232 233#else 234 235 /* Buffer address is in r3. Save each flop register into an offset from 236 this buffer address. */ 237 stfs f0, 0(r3) 238 stfs f1, 4(r3) 239 stfs f2, 8(r3) 240 stfs f3, 12(r3) 241 stfs f4, 16(r3) 242 stfs f5, 20(r3) 243 stfs f6, 24(r3) 244 stfs f7, 28(r3) 245 stfs f8, 32(r3) 246 stfs f9, 36(r3) 247 stfs f10, 40(r3) 248 stfs f11, 44(r3) 249 stfs f12, 48(r3) 250 stfs f13, 52(r3) 251 stfs f14, 56(r3) 252 stfs f15, 60(r3) 253 stfs f16, 64(r3) 254 stfs f17, 68(r3) 255 stfs f18, 72(r3) 256 stfs f19, 76(r3) 257 stfs f20, 80(r3) 258 stfs f21, 84(r3) 259 stfs f22, 88(r3) 260 stfs f23, 92(r3) 261 stfs f24, 96(r3) 262 stfs f25, 100(r3) 263 stfs f26, 104(r3) 264 stfs f27, 108(r3) 265 stfs f28, 112(r3) 266 stfs f29, 116(r3) 267 stfs f30, 120(r3) 268 stfs f31, 124(r3) 269 270 /* Also save the FPSCR. */ 271 mffs f31 272 stfs f31, 128(r3) 273 274#endif 275 276 blr 277 278#endif /* configUSE_FPU. */ 279 280 281#if configUSE_FPU == 1 282 283vPortRestoreFPURegisters: 284 285 /* Enable APU and mark FPU as present. */ 286 mfmsr r0 287 xor r30, r30, r30 288 oris r30, r30, 512 289 ori r30, r30, 8192 290 or r0, r0, r30 291 mtmsr r0 292 293#ifdef USE_DP_FPU 294 295 /* Buffer address is in r3. Restore each flop register from an offset 296 into this buffer. 297 298 First the FPSCR. */ 299 lfs f31, 256(r3) 300 mtfsf f31, 7 301 302 lfd f0, 0(r3) 303 lfd f1, 8(r3) 304 lfd f2, 16(r3) 305 lfd f3, 24(r3) 306 lfd f4, 32(r3) 307 lfd f5, 40(r3) 308 lfd f6, 48(r3) 309 lfd f7, 56(r3) 310 lfd f8, 64(r3) 311 lfd f9, 72(r3) 312 lfd f10, 80(r3) 313 lfd f11, 88(r3) 314 lfd f12, 96(r3) 315 lfd f13, 104(r3) 316 lfd f14, 112(r3) 317 lfd f15, 120(r3) 318 lfd f16, 128(r3) 319 lfd f17, 136(r3) 320 lfd f18, 144(r3) 321 lfd f19, 152(r3) 322 lfd f20, 160(r3) 323 lfd f21, 168(r3) 324 lfd f22, 176(r3) 325 lfd f23, 184(r3) 326 lfd f24, 192(r3) 327 lfd f25, 200(r3) 328 lfd f26, 208(r3) 329 lfd f27, 216(r3) 330 lfd f28, 224(r3) 331 lfd f29, 232(r3) 332 lfd f30, 240(r3) 333 lfd f31, 248(r3) 334 335#else 336 337 /* Buffer address is in r3. Restore each flop register from an offset 338 into this buffer. 339 340 First the FPSCR. */ 341 lfs f31, 128(r3) 342 mtfsf f31, 7 343 344 lfs f0, 0(r3) 345 lfs f1, 4(r3) 346 lfs f2, 8(r3) 347 lfs f3, 12(r3) 348 lfs f4, 16(r3) 349 lfs f5, 20(r3) 350 lfs f6, 24(r3) 351 lfs f7, 28(r3) 352 lfs f8, 32(r3) 353 lfs f9, 36(r3) 354 lfs f10, 40(r3) 355 lfs f11, 44(r3) 356 lfs f12, 48(r3) 357 lfs f13, 52(r3) 358 lfs f14, 56(r3) 359 lfs f15, 60(r3) 360 lfs f16, 64(r3) 361 lfs f17, 68(r3) 362 lfs f18, 72(r3) 363 lfs f19, 76(r3) 364 lfs f20, 80(r3) 365 lfs f21, 84(r3) 366 lfs f22, 88(r3) 367 lfs f23, 92(r3) 368 lfs f24, 96(r3) 369 lfs f25, 100(r3) 370 lfs f26, 104(r3) 371 lfs f27, 108(r3) 372 lfs f28, 112(r3) 373 lfs f29, 116(r3) 374 lfs f30, 120(r3) 375 lfs f31, 124(r3) 376 377#endif 378 379 blr 380 381#endif /* configUSE_FPU. */ 382