/* | |
FreeRTOS V7.2.0 - Copyright (C) 2012 Real Time Engineers Ltd. | |
*************************************************************************** | |
* * | |
* FreeRTOS tutorial books are available in pdf and paperback. * | |
* Complete, revised, and edited pdf reference manuals are also * | |
* available. * | |
* * | |
* Purchasing FreeRTOS documentation will not only help you, by * | |
* ensuring you get running as quickly as possible and with an * | |
* in-depth knowledge of how to use FreeRTOS, it will also help * | |
* the FreeRTOS project to continue with its mission of providing * | |
* professional grade, cross platform, de facto standard solutions * | |
* for microcontrollers - completely free of charge! * | |
* * | |
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< * | |
* * | |
* Thank you for using FreeRTOS, and thank you for your support! * | |
* * | |
*************************************************************************** | |
This file is part of the FreeRTOS distribution. | |
FreeRTOS is free software; you can redistribute it and/or modify it under | |
the terms of the GNU General Public License (version 2) as published by the | |
Free Software Foundation AND MODIFIED BY the FreeRTOS exception. | |
>>>NOTE<<< The modification to the GPL is included to allow you to | |
distribute a combined work that includes FreeRTOS without being obliged to | |
provide the source code for proprietary components outside of the FreeRTOS | |
kernel. FreeRTOS is distributed in the hope that it will be useful, but | |
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
more details. You should have received a copy of the GNU General Public | |
License and the FreeRTOS license exception along with FreeRTOS; if not it | |
can be viewed here: http://www.freertos.org/a00114.html and also obtained | |
by writing to Richard Barry, contact details for whom are available on the | |
FreeRTOS WEB site. | |
1 tab == 4 spaces! | |
*************************************************************************** | |
* * | |
* Having a problem? Start by reading the FAQ "My application does * | |
* not run, what could be wrong? * | |
* * | |
* http://www.FreeRTOS.org/FAQHelp.html * | |
* * | |
*************************************************************************** | |
http://www.FreeRTOS.org - Documentation, training, latest information, | |
license and contact details. | |
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, | |
including FreeRTOS+Trace - an indispensable productivity tool. | |
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell | |
the code with commercial support, indemnification, and middleware, under | |
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also | |
provide a safety engineered and independently SIL3 certified version under | |
the SafeRTOS brand: http://www.SafeRTOS.com. | |
*/ | |
#include "FreeRTOSConfig.h" | |
.extern pxCurrentTCB | |
.extern vTaskSwitchContext | |
.extern vTaskIncrementTick | |
.extern vPortISRHandler | |
.global vPortStartFirstTask | |
.global vPortYield | |
.global vPortTickISR | |
.global vPortISRWrapper | |
.global vPortSaveFPURegisters | |
.global vPortRestoreFPURegisters | |
.set BChainField, 0 | |
.set NextLRField, BChainField + 4 | |
.set MSRField, NextLRField + 4 | |
.set PCField, MSRField + 4 | |
.set LRField, PCField + 4 | |
.set CTRField, LRField + 4 | |
.set XERField, CTRField + 4 | |
.set CRField, XERField + 4 | |
.set USPRG0Field, CRField + 4 | |
.set r0Field, USPRG0Field + 4 | |
.set r2Field, r0Field + 4 | |
.set r3r31Field, r2Field + 4 | |
.set IFrameSize, r3r31Field + ( ( 31 - 3 ) + 1 ) * 4 | |
.macro portSAVE_STACK_POINTER_AND_LR | |
/* Get the address of the TCB. */ | |
xor R0, R0, R0 | |
addis R2, R0, pxCurrentTCB@ha | |
lwz R2, pxCurrentTCB@l( R2 ) | |
/* Store the stack pointer into the TCB */ | |
stw SP, 0( R2 ) | |
/* Save the link register */ | |
stwu R1, -24( R1 ) | |
mflr R0 | |
stw R31, 20( R1 ) | |
stw R0, 28( R1 ) | |
mr R31, r1 | |
.endm | |
.macro portRESTORE_STACK_POINTER_AND_LR | |
/* Restore the link register */ | |
lwz R11, 0( R1 ) | |
lwz R0, 4( R11 ) | |
mtlr R0 | |
lwz R31, -4( R11 ) | |
mr R1, R11 | |
/* Get the address of the TCB. */ | |
xor R0, R0, R0 | |
addis SP, R0, pxCurrentTCB@ha | |
lwz SP, pxCurrentTCB@l( R1 ) | |
/* Get the task stack pointer from the TCB. */ | |
lwz SP, 0( SP ) | |
.endm | |
vPortStartFirstTask: | |
/* Get the address of the TCB. */ | |
xor R0, R0, R0 | |
addis SP, R0, pxCurrentTCB@ha | |
lwz SP, pxCurrentTCB@l( SP ) | |
/* Get the task stack pointer from the TCB. */ | |
lwz SP, 0( SP ) | |
/* Restore MSR register to SRR1. */ | |
lwz R0, MSRField(R1) | |
mtsrr1 R0 | |
/* Restore current PC location to SRR0. */ | |
lwz R0, PCField(R1) | |
mtsrr0 R0 | |
/* Save USPRG0 register */ | |
lwz R0, USPRG0Field(R1) | |
mtspr 0x100,R0 | |
/* Restore Condition register */ | |
lwz R0, CRField(R1) | |
mtcr R0 | |
/* Restore Fixed Point Exception register */ | |
lwz R0, XERField(R1) | |
mtxer R0 | |
/* Restore Counter register */ | |
lwz R0, CTRField(R1) | |
mtctr R0 | |
/* Restore Link register */ | |
lwz R0, LRField(R1) | |
mtlr R0 | |
/* Restore remaining GPR registers. */ | |
lmw R3,r3r31Field(R1) | |
/* Restore r0 and r2. */ | |
lwz R0, r0Field(R1) | |
lwz R2, r2Field(R1) | |
/* Remove frame from stack */ | |
addi R1,R1,IFrameSize | |
/* Return into the first task */ | |
rfi | |
vPortYield: | |
portSAVE_STACK_POINTER_AND_LR | |
bl vTaskSwitchContext | |
portRESTORE_STACK_POINTER_AND_LR | |
blr | |
vPortTickISR: | |
portSAVE_STACK_POINTER_AND_LR | |
bl vTaskIncrementTick | |
#if configUSE_PREEMPTION == 1 | |
bl vTaskSwitchContext | |
#endif | |
/* Clear the interrupt */ | |
lis R0, 2048 | |
mttsr R0 | |
portRESTORE_STACK_POINTER_AND_LR | |
blr | |
vPortISRWrapper: | |
portSAVE_STACK_POINTER_AND_LR | |
bl vPortISRHandler | |
portRESTORE_STACK_POINTER_AND_LR | |
blr | |
#if configUSE_FPU == 1 | |
vPortSaveFPURegisters: | |
/* Enable APU and mark FPU as present. */ | |
mfmsr r0 | |
xor r30, r30, r30 | |
oris r30, r30, 512 | |
ori r30, r30, 8192 | |
or r0, r0, r30 | |
mtmsr r0 | |
#ifdef USE_DP_FPU | |
/* Buffer address is in r3. Save each flop register into an offset from | |
this buffer address. */ | |
stfd f0, 0(r3) | |
stfd f1, 8(r3) | |
stfd f2, 16(r3) | |
stfd f3, 24(r3) | |
stfd f4, 32(r3) | |
stfd f5, 40(r3) | |
stfd f6, 48(r3) | |
stfd f7, 56(r3) | |
stfd f8, 64(r3) | |
stfd f9, 72(r3) | |
stfd f10, 80(r3) | |
stfd f11, 88(r3) | |
stfd f12, 96(r3) | |
stfd f13, 104(r3) | |
stfd f14, 112(r3) | |
stfd f15, 120(r3) | |
stfd f16, 128(r3) | |
stfd f17, 136(r3) | |
stfd f18, 144(r3) | |
stfd f19, 152(r3) | |
stfd f20, 160(r3) | |
stfd f21, 168(r3) | |
stfd f22, 176(r3) | |
stfd f23, 184(r3) | |
stfd f24, 192(r3) | |
stfd f25, 200(r3) | |
stfd f26, 208(r3) | |
stfd f27, 216(r3) | |
stfd f28, 224(r3) | |
stfd f29, 232(r3) | |
stfd f30, 240(r3) | |
stfd f31, 248(r3) | |
/* Also save the FPSCR. */ | |
mffs f31 | |
stfs f31, 256(r3) | |
#else | |
/* Buffer address is in r3. Save each flop register into an offset from | |
this buffer address. */ | |
stfs f0, 0(r3) | |
stfs f1, 4(r3) | |
stfs f2, 8(r3) | |
stfs f3, 12(r3) | |
stfs f4, 16(r3) | |
stfs f5, 20(r3) | |
stfs f6, 24(r3) | |
stfs f7, 28(r3) | |
stfs f8, 32(r3) | |
stfs f9, 36(r3) | |
stfs f10, 40(r3) | |
stfs f11, 44(r3) | |
stfs f12, 48(r3) | |
stfs f13, 52(r3) | |
stfs f14, 56(r3) | |
stfs f15, 60(r3) | |
stfs f16, 64(r3) | |
stfs f17, 68(r3) | |
stfs f18, 72(r3) | |
stfs f19, 76(r3) | |
stfs f20, 80(r3) | |
stfs f21, 84(r3) | |
stfs f22, 88(r3) | |
stfs f23, 92(r3) | |
stfs f24, 96(r3) | |
stfs f25, 100(r3) | |
stfs f26, 104(r3) | |
stfs f27, 108(r3) | |
stfs f28, 112(r3) | |
stfs f29, 116(r3) | |
stfs f30, 120(r3) | |
stfs f31, 124(r3) | |
/* Also save the FPSCR. */ | |
mffs f31 | |
stfs f31, 128(r3) | |
#endif | |
blr | |
#endif /* configUSE_FPU. */ | |
#if configUSE_FPU == 1 | |
vPortRestoreFPURegisters: | |
/* Enable APU and mark FPU as present. */ | |
mfmsr r0 | |
xor r30, r30, r30 | |
oris r30, r30, 512 | |
ori r30, r30, 8192 | |
or r0, r0, r30 | |
mtmsr r0 | |
#ifdef USE_DP_FPU | |
/* Buffer address is in r3. Restore each flop register from an offset | |
into this buffer. | |
First the FPSCR. */ | |
lfs f31, 256(r3) | |
mtfsf f31, 7 | |
lfd f0, 0(r3) | |
lfd f1, 8(r3) | |
lfd f2, 16(r3) | |
lfd f3, 24(r3) | |
lfd f4, 32(r3) | |
lfd f5, 40(r3) | |
lfd f6, 48(r3) | |
lfd f7, 56(r3) | |
lfd f8, 64(r3) | |
lfd f9, 72(r3) | |
lfd f10, 80(r3) | |
lfd f11, 88(r3) | |
lfd f12, 96(r3) | |
lfd f13, 104(r3) | |
lfd f14, 112(r3) | |
lfd f15, 120(r3) | |
lfd f16, 128(r3) | |
lfd f17, 136(r3) | |
lfd f18, 144(r3) | |
lfd f19, 152(r3) | |
lfd f20, 160(r3) | |
lfd f21, 168(r3) | |
lfd f22, 176(r3) | |
lfd f23, 184(r3) | |
lfd f24, 192(r3) | |
lfd f25, 200(r3) | |
lfd f26, 208(r3) | |
lfd f27, 216(r3) | |
lfd f28, 224(r3) | |
lfd f29, 232(r3) | |
lfd f30, 240(r3) | |
lfd f31, 248(r3) | |
#else | |
/* Buffer address is in r3. Restore each flop register from an offset | |
into this buffer. | |
First the FPSCR. */ | |
lfs f31, 128(r3) | |
mtfsf f31, 7 | |
lfs f0, 0(r3) | |
lfs f1, 4(r3) | |
lfs f2, 8(r3) | |
lfs f3, 12(r3) | |
lfs f4, 16(r3) | |
lfs f5, 20(r3) | |
lfs f6, 24(r3) | |
lfs f7, 28(r3) | |
lfs f8, 32(r3) | |
lfs f9, 36(r3) | |
lfs f10, 40(r3) | |
lfs f11, 44(r3) | |
lfs f12, 48(r3) | |
lfs f13, 52(r3) | |
lfs f14, 56(r3) | |
lfs f15, 60(r3) | |
lfs f16, 64(r3) | |
lfs f17, 68(r3) | |
lfs f18, 72(r3) | |
lfs f19, 76(r3) | |
lfs f20, 80(r3) | |
lfs f21, 84(r3) | |
lfs f22, 88(r3) | |
lfs f23, 92(r3) | |
lfs f24, 96(r3) | |
lfs f25, 100(r3) | |
lfs f26, 104(r3) | |
lfs f27, 108(r3) | |
lfs f28, 112(r3) | |
lfs f29, 116(r3) | |
lfs f30, 120(r3) | |
lfs f31, 124(r3) | |
#endif | |
blr | |
#endif /* configUSE_FPU. */ | |