# FPU-data and context switch on Zynq

**URL:** <https://forums.freertos.org/t/fpu-data-and-context-switch-on-zynq/3936>\
**Category:** Kernel\
**Created:** [September 11, 2013, 11:09am UTC](https://forums.freertos.org/t/fpu-data-and-context-switch-on-zynq/3936 "2013-09-11T11:09:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 11, 2013, 11:09am UTC](https://forums.freertos.org/t/fpu-data-and-context-switch-on-zynq/3936/1 "2013-09-11T11:09:45Z")

</div>

**[spacesickpuppy](https://sourceforge.net/u/spacesickpuppy/)** wrote on [Wednesday, September 11, 2013](https://sourceforge.net/p/freertos/discussion/382005/thread/afd69637/#784b):

Hi,  
I’m trying to implement floating-point support in the context switch on the FreeRTOS&nbsp; Zynq port. [http://www.freertos.org/Interactive\_Frames/Open\_Frames.html?http://interactive.freertos.org/entries/23277857-Updated-Xilinx-FreeRTOS-port-for-Zynq-to-SDK-14-4-release](http://www.freertos.org/Interactive_Frames/Open_Frames.html?http://interactive.freertos.org/entries/23277857-Updated-Xilinx-FreeRTOS-port-for-Zynq-to-SDK-14-4-release)

I’m running it on the ZC702 board and using GCC.

What I have tried is adding the following lines to the FIQHandler in port\_asm\_vectors.s and the portSAVE\_CONTEXT and portRESTORE\_CONTEXT&nbsp; routines:

```
vpush {d0-d7}
vpush {d16-d31}
vmrs r1, FPSCR 
push {r1} 
vmrs r1, FPEXC 
push {r1}

pop {r2}
vmsr FPEXC, r2 
pop {r2}
vmsr FPSCR, r2 
vpop {d16-d31}
vpop {d0-d7}

```

The modifications seems not to help at all, floating-point values are still corrupted in tasks.

The save and restore routines look like this:

```
#define portSAVE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
																		\
	/* Push R0 as we are going to use the register. */ \
	__asm volatile ( \
	"STMDB	SP!, {R0} \n\t"	\
																		\
	/* Set R0 to point to the task stack pointer. */ \
	"STMDB	SP,{SP}^ \n\t"	\
	"NOP \n\t"	\
	"SUB	SP, SP, #4 \n\t"	\
	"LDMIA	SP!,{R0} \n\t"	\
																		\
	/* Push the return address onto the stack. */ \
	"STMDB	R0!, {LR} \n\t"	\
																		\
	/* Now we have saved LR we can use it instead of R0. */ \
	"MOV	LR, R0 \n\t"	\
																		\
	/* Pop R0 so we can save it onto the system mode stack. */ \
	"LDMIA	SP!, {R0} \n\t"	\
																		\
	/* Push all the system mode registers onto the task stack. */ \
	"STMDB	LR,{R0-LR}^ \n\t"	\
	"NOP \n\t"	\
	"SUB	LR, LR, #60 \n\t"	\
                                    \
/*Save floating-point registers*/	\
  "vpush {d0-d15} \n\t"	\
	"vpush {d16-d31} \n\t"	\
	"vmrs r1, FPSCR \n\t"	\
	"push {r1} \n\t"	\
	"vmrs r1, FPEXC \n\t"	\
	"push {r1} \n\t"	\
                                    \
	/* Push the SPSR onto the task stack. */ \
	"MRS	R0, SPSR \n\t"	\
	"STMDB	LR!, {R0} \n\t"	\
																		\
	"LDR	R0, =ulCriticalNesting \n\t"	\
	"LDR	R0, [R0] \n\t"	\
	"STMDB	LR!, {R0} \n\t"	\
																		\
	/* Store the new top of stack for the task. */ \
	"LDR	R0, =pxCurrentTCB \n\t"	\
	"LDR	R0, [R0] \n\t"	\
	"STR	LR, [R0] \n\t"	\
	); \
	( void ) ulCriticalNesting; \
	( void ) pxCurrentTCB; \
}

#define portRESTORE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
																		\
	/* Set the LR to the task stack. */ \
	__asm volatile ( \
	"LDR R0, =pxCurrentTCB \n\t"	\
	"LDR R0, [R0] \n\t"	\
	"LDR LR, [R0] \n\t"	\
																		\
	/* The critical nesting depth is the first item on the stack. */	\
	/* Load it into the ulCriticalNesting variable. */ \
	"LDR R0, =ulCriticalNesting \n\t"	\
	"LDMFD	LR!, {R1} \n\t"	\
	"STR R1, [R0] \n\t"	\
																		\
	/* Get the SPSR from the stack. */ \
	"LDMFD	LR!, {R0} \n\t"	\
	"MSR SPSR, R0 \n\t"	\
                                      \
  /*Restore floating-point registers*/	\
	"pop {r2} \n\t"	\
	"vmsr FPEXC, r2 \n\t"	\
	"pop {r2} \n\t"	\
	"vmsr FPSCR, r2 \n\t"	\
	"vpop {d16-d31} \n\t"	\
	"vpop {d0-d15} \n\t"	\
                                    \
	/* Restore all system mode registers for the task. */ \
	"LDMFD	LR, {R0-R14}^ \n\t"	\
	"NOP \n\t"	\
																		\
	/* Restore the return address. */ \
	"LDR LR, [LR, #+60] \n\t"	\
																		\
	/* And return - correcting the offset in the LR to obtain the */	\
	/* correct address. */ \
	"SUBS	PC, LR, #4 \n\t"	\
	"NOP \n\t"	\
	"NOP \n\t"	\
	); \
	( void ) ulCriticalNesting; \
	( void ) pxCurrentTCB; \
}

```

Am I looking in the right place in the code?

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [September 11, 2013, 11:15am UTC](https://forums.freertos.org/t/fpu-data-and-context-switch-on-zynq/3936/2 "2013-09-11T11:15:01Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Wednesday, September 11, 2013](https://sourceforge.net/p/freertos/discussion/382005/thread/afd69637/#bd06):

Unfortunately we can’t support third party code.&nbsp; However, the official ARM Cortex-A9 port includes FPU support.&nbsp; You could try using that. [http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html](http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html)

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [September 11, 2013, 11:38am UTC](https://forums.freertos.org/t/fpu-data-and-context-switch-on-zynq/3936/3 "2013-09-11T11:38:26Z")

</div>

**[spacesickpuppy](https://sourceforge.net/u/spacesickpuppy/)** wrote on [Wednesday, September 11, 2013](https://sourceforge.net/p/freertos/discussion/382005/thread/afd69637/#6951):

I have looked at the Cortex-A9 ports in the official release. Unfortunately there is no version for GCC with FPU support.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [September 11, 2013, 11:55am UTC](https://forums.freertos.org/t/fpu-data-and-context-switch-on-zynq/3936/4 "2013-09-11T11:55:16Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Wednesday, September 11, 2013](https://sourceforge.net/p/freertos/discussion/382005/thread/afd69637/#714a):

If you were using GCC the C code would not change, and the assembler instructions would not change, but the assembly file would have to be in GCC format.&nbsp; You can see how this is done by comparing the RVDS Cortex-M3 port layer code to the GCC Cortex-M3 port layer code.

Regards.
