You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeRTOS-Kernel/Source/portable/GCC/PPC405_Xilinx/portasm.s

242 lines
4.5 KiB
ArmAsm

#include "xreg405.h"
.extern pxCurrentTCB
.extern vTaskSwitchContext
.extern vTaskIncrementTick
.extern vPortISRHandler
.global vPortStartFirstTask
.global vPortYield
.global vPortTickISR
.global vPortISRWrapper
.set portCONTEXT_SIZE, 156
.set portR0_OFFSET, 152
.set portGPR_OFFSET, 32
.set portCR_OFFSET, 28
.set portXER_OFFSET, 24
.set portLR_OFFSET, 16
.set portCTR_OFFSET, 16
.set portUSPRG0_OFFSET, 12
.set portSRR0_OFFSET, 8
.set portSRR1_OFFSET, 4
.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 portRESTORE_CONTEXT
# 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 )
# Pop the special purpose registers
lwz R0, portSRR1_OFFSET( SP )
mtspr SRR1, R0
lwz R0, portSRR0_OFFSET( SP )
mtspr SRR0, R0
lwz R0, portUSPRG0_OFFSET( SP )
mtspr 256, R0 #USPRG0
lwz R0, portCTR_OFFSET( SP )
mtspr CTR, R0
lwz R0, portLR_OFFSET( SP )
mtspr LR, R0
lwz R0, portXER_OFFSET( SP )
mtspr XER, R0
lwz R0, portCR_OFFSET( SP )
mtcr R0
# Pop GPRs
lmw R2, portGPR_OFFSET( SP )
# Finally pop R0 and correct the stack pointer
lwz R0, portR0_OFFSET( SP )
addi R1, R1, portCONTEXT_SIZE
# Start the task running
rfi
.endm
.macro portSAVE_CONTEXT
# Make room on the stack.
subi R1, R1, portCONTEXT_SIZE
# Push R0, then the GPRs
stw R0, portR0_OFFSET( SP )
stm R2, portGPR_OFFSET( SP )
# Push the SFRs
mfcr R0
stw R0, portCR_OFFSET( SP )
mfspr R0, XER
stw R0, portXER_OFFSET( SP )
mfspr R0, LR
stw R0, portLR_OFFSET( SP )
mfspr R0, CTR
stw R0, portCTR_OFFSET( SP )
mfspr R0, 256 #USPRG0
stw R0, portUSPRG0_OFFSET( SP )
mfspr R0, SRR0
stw R0, portSRR0_OFFSET( SP )
mfspr R0, SRR1
stw R0, portSRR1_OFFSET( SP )
# 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 )
.endm
.macro int_epilogue
# 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
.endm
.macro portENTER_SWITCHING_ISR
# 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 portEXIT_SWITCHING_ISR
# 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:
int_epilogue
rfi
#vPortStartFirstTask:
# portRESTORE_CONTEXT
# rfi
vPortYield:
portENTER_SWITCHING_ISR
bl vTaskSwitchContext
portEXIT_SWITCHING_ISR
blr
vPortTickISR:
portENTER_SWITCHING_ISR
bl vTaskIncrementTick
#if configUSE_PREEMPTION == 1
bl vTaskSwitchContext
#endif
# Clear the interrupt
lis R0, 2048
mttsr R0
portEXIT_SWITCHING_ISR
blr
vPortISRWrapper:
portENTER_SWITCHING_ISR
bl vPortISRHandler
portEXIT_SWITCHING_ISR
blr