diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject
index d62cf321ed..857eea3302 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.cproject
@@ -26,45 +26,45 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
+
+
+
+
-
-
+
@@ -80,8 +80,8 @@
-
-
+
+
@@ -91,64 +91,67 @@
-
-
-
-
diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.settings/org.eclipse.core.resources.prefs b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.settings/org.eclipse.core.resources.prefs
index 7a91b46759..e164ebf77e 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.settings/org.eclipse.core.resources.prefs
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/.settings/org.eclipse.core.resources.prefs
@@ -10,3 +10,14 @@ encoding//Debug/startup/subdir_rules.mk=UTF-8
encoding//Debug/startup/subdir_vars.mk=UTF-8
encoding//Debug/subdir_rules.mk=UTF-8
encoding//Debug/subdir_vars.mk=UTF-8
+encoding//Debug_with_FPU/demo/subdir_rules.mk=UTF-8
+encoding//Debug_with_FPU/demo/subdir_vars.mk=UTF-8
+encoding//Debug_with_FPU/makefile=UTF-8
+encoding//Debug_with_FPU/objects.mk=UTF-8
+encoding//Debug_with_FPU/os/subdir_rules.mk=UTF-8
+encoding//Debug_with_FPU/os/subdir_vars.mk=UTF-8
+encoding//Debug_with_FPU/sources.mk=UTF-8
+encoding//Debug_with_FPU/startup/subdir_rules.mk=UTF-8
+encoding//Debug_with_FPU/startup/subdir_vars.mk=UTF-8
+encoding//Debug_with_FPU/subdir_rules.mk=UTF-8
+encoding//Debug_with_FPU/subdir_vars.mk=UTF-8
diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/FreeRTOSConfig.h
index e3d22ae9cb..514b62ed1b 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/FreeRTOSConfig.h
@@ -79,50 +79,53 @@
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
-#define configUSE_PREEMPTION 1
-#define configUSE_IDLE_HOOK 1
-#define configUSE_TICK_HOOK 1
-#define configUSE_TRACE_FACILITY 0
-#define configUSE_16_BIT_TICKS 0
-#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 90000000 ) /* Timer clock. */
-#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
-#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 8 )
-#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )
-#define configTOTAL_HEAP_SIZE ( ( size_t ) 32768 )
-#define configMAX_TASK_NAME_LEN ( 16 )
-#define configIDLE_SHOULD_YIELD 1
-#define configGENERATE_RUN_TIME_STATS 0
-#define configUSE_MALLOC_FAILED_HOOK 1
-
-#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_PREEMPTION 1
+#define configUSE_FPU 1
+#define configUSE_IDLE_HOOK 1
+#define configUSE_TICK_HOOK 1
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_16_BIT_TICKS 0
+#define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 90000000 ) /* Timer clock. */
+#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
+#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 8 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 )
+#define configTOTAL_HEAP_SIZE ( ( size_t ) 32768 )
+#define configMAX_TASK_NAME_LEN ( 16 )
+#define configIDLE_SHOULD_YIELD 1
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_MALLOC_FAILED_HOOK 1
+
+#define configCHECK_FOR_STACK_OVERFLOW 2
/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
+#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Mutexes */
-#define configUSE_MUTEXES 1
-#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
/* Semaphores */
#define configUSE_COUNTING_SEMAPHORES 1
/* Timers */
-#define configUSE_TIMERS 1
+#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH ( 128 )
/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 0
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_xTaskResumeFromISR 0
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 0
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_xTaskResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define configASSERT( x ) if( ( x ) == pdFALSE ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
+
#endif /* FREERTOS_CONFIG_H */
diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c
index fdba8b7d23..6bc7e50a14 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/main.c
@@ -113,7 +113,6 @@ extern void main_full( void );
/* See the documentation page for this demo on the FreeRTOS.org web site for
full information - including hardware setup requirements. */
-
int main( void )
{
/* Prepare the hardware to run this demo. */
diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/port.c b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/port.c
index 1f72ac4daa..ded485033f 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/port.c
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/port.c
@@ -90,9 +90,9 @@ unsigned portLONG ulCriticalNesting = 9999;
/* Constants required to set up the initial stack of each task. */
-#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1F )
-#define portINITIAL_FPSCR ( ( portSTACK_TYPE ) 0x00 )
-#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0x04 )
+#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1F )
+#define portINITIAL_FPSCR ( ( portSTACK_TYPE ) 0x00 )
+#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0x04 )
#define portTHUMB_MODE_BIT ( ( portSTACK_TYPE ) 0x20 )
/* The number of words on the stack frame between the saved Top Of Stack and
@@ -106,6 +106,12 @@ extern void vPortStartFirstTask( void );
/*-----------------------------------------------------------*/
+/* Saved as part of the task context. Set to pdFALSE if the task does not
+require an FPU context. */
+unsigned long ulTaskHasFPUContext = 0;
+
+/*-----------------------------------------------------------*/
+
/*
* See header file for description.
@@ -116,6 +122,13 @@ portSTACK_TYPE *pxOriginalTOS;
pxOriginalTOS = pxTopOfStack;
+ #if __TI_VFP_SUPPORT__
+ {
+ /* Ensure the stack is correctly aligned on exit. */
+ pxTopOfStack--;
+ }
+ #endif
+
/* Setup the initial stack of the task. The stack is set exactly as
expected by the portRESTORE_CONTEXT() macro. */
@@ -167,8 +180,7 @@ portSTACK_TYPE *pxOriginalTOS;
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack--;
- /* The last thing onto the stack is the status register, which is set for
- system mode, with interrupts enabled. */
+ /* Set the status register for system mode, with interrupts enabled. */
*pxTopOfStack = ( portSTACK_TYPE ) ( ( _get_CPSR() & ~0xFF ) | portINITIAL_SPSR );
if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )
@@ -177,6 +189,17 @@ portSTACK_TYPE *pxOriginalTOS;
*pxTopOfStack |= portTHUMB_MODE_BIT;
}
+ #ifdef __TI_VFP_SUPPORT__
+ {
+ pxTopOfStack--;
+
+ /* The last thing on the stack is the tasks ulUsingFPU value, which by
+ default is set to indicate that the stack frame does not include FPU
+ registers. */
+ *pxTopOfStack = pdFALSE;
+ }
+ #endif
+
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
@@ -307,3 +330,21 @@ void vPortExitCritical( void )
}
/*-----------------------------------------------------------*/
+#if __TI_VFP_SUPPORT__
+
+ void vPortTaskUsesFPU( void )
+ {
+ extern void vPortInitialiseFPSCR( void );
+
+ /* A task is registering the fact that it needs an FPU context. Set the
+ FPU flag (saved as part of the task context. */
+ ulTaskHasFPUContext = pdTRUE;
+
+ /* Initialise the floating point status register. */
+ vPortInitialiseFPSCR();
+ }
+
+#endif /* __TI_VFP_SUPPORT__ */
+
+/*-----------------------------------------------------------*/
+
diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/portASM.asm b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/portASM.asm
index 2805d0279f..522c40cc82 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/portASM.asm
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/os/portASM.asm
@@ -51,117 +51,203 @@
; licensing and training services.
;*/
-; TCJ: Using SSI interrupt todo portYIELD_WITHIN_API, means that we do not need
-; to save ulCriticalNesting in the task context
-
.text
.arm
+ .ref vTaskSwitchContext
+ .ref vTaskIncrementTick
+ .ref ulTaskHasFPUContext
+ .ref pxCurrentTCB
-;-------------------------------------------------------------------------------
+;/*-----------------------------------------------------------*/
;
; Save Task Context
;
portSAVE_CONTEXT .macro
- stmfd sp!, {r0}
- stmfd sp, {sp}^
- sub sp, sp, #4
- ldmfd sp!, {r0}
- stmfd r0!, {lr}
- mov lr, r0
- ldmfd sp!, {r0}
- stmfd lr, {r0-lr}^
- sub lr, lr, #0x3C
- .if (__TI_VFPV3D16_SUPPORT__)
- fstmdbd lr!, {d0-d15}
- mrs r0, spsr
- fmrx r1, fpscr
- stmfd lr!, {r0,r1}
- .else
- mrs r0, spsr
- stmfd lr!, {r0}
- .endif
- ldr r0, curTCB
- ldr r0, [r0]
- str lr, [r0]
- .endm
+ DSB
-;-------------------------------------------------------------------------------
+ ; Push R0 as we are going to use it
+ STMDB SP!, {R0}
+
+ ; Set R0 to point to the task stack pointer.
+ STMDB SP,{SP}^
+ SUB SP, SP, #4
+ LDMIA SP!,{R0}
+
+ ; Push the return address onto the stack.
+ STMDB R0!, {LR}
+
+ ; Now LR has been saved, it can be used instead of R0.
+ MOV LR, R0
+
+ ; Pop R0 so it can be saved onto the task stack.
+ LDMIA SP!, {R0}
+
+ ; Push all the system mode registers onto the task stack.
+ STMDB LR,{R0-LR}^
+ SUB LR, LR, #60
+ ; Push the SPSR onto the task stack.
+ MRS R0, SPSR
+ STMDB LR!, {R0}
+
+ .if (__TI_VFP_SUPPORT__)
+ ;Determine if the task maintains an FPU context.
+ LDR R0, ulFPUContextConst
+ LDR R0, [R0]
+
+ ; Test the flag
+ CMP R0, #0
+
+ ; If the task is not using a floating point context then skip the
+ ; saving of the FPU registers.
+ BEQ PC+3
+ FSTMDBD LR!, {D0-D15}
+ FMRX R1, FPSCR
+ STMFD LR!, {R1}
+
+ ; Save the flag
+ STMDB LR!, {R0}
+ .endif
+
+ ; Store the new top of stack for the task.
+ LDR R0, pxCurrentTCBConst
+ LDR R0, [R0]
+ STR LR, [R0]
+
+ .endm
+
+;/*-----------------------------------------------------------*/
+;
; Restore Task Context
;
portRESTORE_CONTEXT .macro
- ldr r0, curTCB
- ldr r0, [r0]
- ldr lr, [r0]
- .if (__TI_VFPV3D16_SUPPORT__)
- ldmfd lr!, {r0,r1}
- fldmiad lr!, {d0-d15}
- fmxr fpscr, r1
- .else
- ldmfd lr!, {r0}
- .endif
- msr spsr_csxf, r0
- ldmfd lr, {r0-r14}^
- ldr lr, [lr, #0x3C]
- subs pc, lr, #4
+ LDR R0, pxCurrentTCBConst
+ LDR R0, [R0]
+ LDR LR, [R0]
+
+ .if (__TI_VFP_SUPPORT__)
+ ; The floating point context flag is the first thing on the stack.
+ LDR R0, ulFPUContextConst
+ LDMFD LR!, {R1}
+ STR R1, [R0]
+
+ ; Test the flag
+ CMP R1, #0
+
+ ; If the task is not using a floating point context then skip the
+ ; VFP register loads.
+ BEQ PC+3
+
+ ; Restore the floating point context.
+ LDMFD LR!, {R0}
+ FLDMIAD LR!, {D0-D15}
+ FMXR FPSCR, R0
+ .endif
+
+ ; Get the SPSR from the stack.
+ LDMFD LR!, {R0}
+ MSR SPSR_CF, R0
+
+ ; Restore all system mode registers for the task.
+ LDMFD LR, {R0-R14}^
+
+ ; Restore the return address.
+ LDR LR, [LR, #+60]
+
+ ; And return - correcting the offset in the LR to obtain the
+ ; correct address.
+ SUBS PC, LR, #4
.endm
-;-------------------------------------------------------------------------------
-; Start First Task
+;/*-----------------------------------------------------------*/
+; Start the first task by restoring its context.
.def vPortStartFirstTask
-vPortStartFirstTask
+vPortStartFirstTask:
portRESTORE_CONTEXT
-;-------------------------------------------------------------------------------
-; Yield Processor
+;/*-----------------------------------------------------------*/
+; Yield to another task.
.def vPortYieldProcessor
- .ref vTaskSwitchContext
-vPortYieldProcessor
- add lr, lr, #4
+vPortYieldProcessor:
+ ; Within an IRQ ISR the link register has an offset from the true return
+ ; address. SWI doesn't do this. Add the offset manually so the ISR
+ ; return code can be used.
+ ADD LR, LR, #4
+
+ ; First save the context of the current task.
portSAVE_CONTEXT
- bl vTaskSwitchContext
+
+ ; Select the next task to execute. */
+ BL vTaskSwitchContext
+
+ ; Restore the context of the task selected to execute.
portRESTORE_CONTEXT
-;-------------------------------------------------------------------------------
-; Yield Processor From Within FreeRTOS API
+;/*-----------------------------------------------------------*/
+; Yield to another task from within the FreeRTOS API
.def vPortYeildWithinAPI
-vPortYeildWithinAPI
+vPortYeildWithinAPI:
+ ; Save the context of the current task.
+
portSAVE_CONTEXT
- ; clear SSI flag
- movw r0, #0xFFF4
- movt r0, #0xFFFF
- ldr r0, [r0];
- ; switch task
- bl vTaskSwitchContext
+ ; Clear SSI flag.
+ MOVW R0, #0xFFF4
+ MOVT R0, #0xFFFF
+ LDR R0, [R0]
+
+ ; Select the next task to execute. */
+ BL vTaskSwitchContext
+
+ ; Restore the context of the task selected to execute.
portRESTORE_CONTEXT
-;-------------------------------------------------------------------------------
+;/*-----------------------------------------------------------*/
; Preemptive Tick
.def vPortPreemptiveTick
- .ref vTaskIncrementTick
-vPortPreemptiveTick
+vPortPreemptiveTick:
+
+ ; Save the context of the current task.
portSAVE_CONTEXT
- ; clear interrupt flag
- movw r0, #0xFC88
- movt r0, #0xFFFF
- mov r1, #1
- str r1, [r0]
- bl vTaskIncrementTick
- bl vTaskSwitchContext
+
+ ; Clear interrupt flag
+ MOVW R0, #0xFC88
+ MOVT R0, #0xFFFF
+ MOV R1, #1
+ STR R1, [R0]
+
+ ; Increment the tick count, making any adjustments to the blocked lists
+ ; that may be necessary.
+ BL vTaskIncrementTick
+
+ ; Select the next task to execute.
+ BL vTaskSwitchContext
+
+ ; Restore the context of the task selected to execute.
portRESTORE_CONTEXT
;-------------------------------------------------------------------------------
- .ref pxCurrentTCB
-curTCB .word pxCurrentTCB
+ .if (__TI_VFP_SUPPORT__)
+
+ .def vPortInitialiseFPSCR
+
+vPortInitialiseFPSCR:
+
+ MOV R0, #0
+ FMXR FPSCR, R0
+ BX LR
+
+ .endif ;__TI_VFP_SUPPORT__
+pxCurrentTCBConst .word pxCurrentTCB
+ulFPUContextConst .word ulTaskHasFPUContext
;-------------------------------------------------------------------------------
diff --git a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/reg_test.asm b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/reg_test.asm
index 5e0e583802..d39c09dee5 100644
--- a/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/reg_test.asm
+++ b/FreeRTOS/Demo/CORTEX_R4_RM48_CCS5/reg_test.asm
@@ -68,10 +68,20 @@
;
.def vRegTestTask1
.ref ulRegTest1Counter
+
+ .if (__TI_VFP_SUPPORT__)
+ .ref vPortTaskUsesFPU
+ .endif ;__TI_VFP_SUPPORT__
+
.text
.arm
vRegTestTask1:
+ .if (__TI_VFP_SUPPORT__)
+ ; Let the port layer know that this task needs its FPU context saving.
+ BL vPortTaskUsesFPU
+ .endif
+
; Fill each general purpose register with a known value.
mov r0, #0xFF
mov r1, #0x11
@@ -87,12 +97,134 @@ vRegTestTask1:
mov r11, #0xBB
mov r12, #0xCC
mov r14, #0xEE
+
+ .if (__TI_VFP_SUPPORT__)
+ ; Fill each FPU register with a known value.
+ vmov d0, r0, r1
+ vmov d1, r2, r3
+ vmov d2, r4, r5
+ vmov d3, r6, r7
+ vmov d4, r8, r9
+ vmov d5, r10, r11
+ vmov d6, r0, r1
+ vmov d7, r2, r3
+ vmov d8, r4, r5
+ vmov d9, r6, r7
+ vmov d10, r8, r9
+ vmov d11, r10, r11
+ vmov d12, r0, r1
+ vmov d13, r2, r3
+ vmov d14, r4, r5
+ vmov d15, r6, r7
+ .endif
+
vRegTestLoop1:
; Force yeild
swi #0
+ .if (__TI_VFP_SUPPORT__)
+ ; Check all the VFP registers still contain the values set above.
+ ; First save registers that are clobbered by the test.
+ push { r0-r1 }
+
+ vmov r0, r1, d0
+ cmp r0, #0xFF
+ bne reg1_error_loopf
+ cmp r1, #0x11
+ bne reg1_error_loopf
+ vmov r0, r1, d1
+ cmp r0, #0x22
+ bne reg1_error_loopf
+ cmp r1, #0x33
+ bne reg1_error_loopf
+ vmov r0, r1, d2
+ cmp r0, #0x44
+ bne reg1_error_loopf
+ cmp r1, #0x55
+ bne reg1_error_loopf
+ vmov r0, r1, d3
+ cmp r0, #0x66
+ bne reg1_error_loopf
+ cmp r1, #0x77
+ bne reg1_error_loopf
+ vmov r0, r1, d4
+ cmp r0, #0x88
+ bne reg1_error_loopf
+ cmp r1, #0x99
+ bne reg1_error_loopf
+ vmov r0, r1, d5
+ cmp r0, #0xAA
+ bne reg1_error_loopf
+ cmp r1, #0xBB
+ bne reg1_error_loopf
+ vmov r0, r1, d6
+ cmp r0, #0xFF
+ bne reg1_error_loopf
+ cmp r1, #0x11
+ bne reg1_error_loopf
+ vmov r0, r1, d7
+ cmp r0, #0x22
+ bne reg1_error_loopf
+ cmp r1, #0x33
+ bne reg1_error_loopf
+ vmov r0, r1, d8
+ cmp r0, #0x44
+ bne reg1_error_loopf
+ cmp r1, #0x55
+ bne reg1_error_loopf
+ vmov r0, r1, d9
+ cmp r0, #0x66
+ bne reg1_error_loopf
+ cmp r1, #0x77
+ bne reg1_error_loopf
+ vmov r0, r1, d10
+ cmp r0, #0x88
+ bne reg1_error_loopf
+ cmp r1, #0x99
+ bne reg1_error_loopf
+ vmov r0, r1, d11
+ cmp r0, #0xAA
+ bne reg1_error_loopf
+ cmp r1, #0xBB
+ bne reg1_error_loopf
+ vmov r0, r1, d12
+ cmp r0, #0xFF
+ bne reg1_error_loopf
+ cmp r1, #0x11
+ bne reg1_error_loopf
+ vmov r0, r1, d13
+ cmp r0, #0x22
+ bne reg1_error_loopf
+ cmp r1, #0x33
+ bne reg1_error_loopf
+ vmov r0, r1, d14
+ cmp r0, #0x44
+ bne reg1_error_loopf
+ cmp r1, #0x55
+ bne reg1_error_loopf
+ vmov r0, r1, d15
+ cmp r0, #0x66
+ bne reg1_error_loopf
+ cmp r1, #0x77
+ bne reg1_error_loopf
+
+ ; Restore the registers that were clobbered by the test.
+ pop {r0-r1}
+
+ ; VFP register test passed. Jump to the core register test.
+ b reg1_loopf_pass
+
+reg1_error_loopf:
+ ; If this line is hit then a VFP register value was found to be
+ ; incorrect.
+ b reg1_error_loopf
+
+reg1_loopf_pass:
+
+ .endif ;__TI_VFP_SUPPORT__
+
; Test each general purpose register to check that it still contains the
; expected known value, jumping to vRegTestError1 if any register contains
; an unexpected value.
@@ -151,6 +283,11 @@ vRegTestError1:
.arm
;
vRegTestTask2:
+ .if (__TI_VFP_SUPPORT__)
+ ; Let the port layer know that this task needs its FPU context saving.
+ BL vPortTaskUsesFPU
+ .endif
+
; Fill each general purpose register with a known value.
mov r0, #0xFF000000
mov r1, #0x11000000
@@ -167,8 +304,130 @@ vRegTestTask2:
mov r12, #0xCC000000
mov r14, #0xEE000000
+ .if (__TI_VFP_SUPPORT__)
+
+ ; Fill each FPU register with a known value.
+ vmov d0, r0, r1
+ vmov d1, r2, r3
+ vmov d2, r4, r5
+ vmov d3, r6, r7
+ vmov d4, r8, r9
+ vmov d5, r10, r11
+ vmov d6, r0, r1
+ vmov d7, r2, r3
+ vmov d8, r4, r5
+ vmov d9, r6, r7
+ vmov d10, r8, r9
+ vmov d11, r10, r11
+ vmov d12, r0, r1
+ vmov d13, r2, r3
+ vmov d14, r4, r5
+ vmov d15, r6, r7
+ .endif
+
vRegTestLoop2:
+ .if (__TI_VFP_SUPPORT__)
+ ; Check all the VFP registers still contain the values set above.
+ ; First save registers that are clobbered by the test.
+ push { r0-r1 }
+
+ vmov r0, r1, d0
+ cmp r0, #0xFF000000
+ bne reg2_error_loopf
+ cmp r1, #0x11000000
+ bne reg2_error_loopf
+ vmov r0, r1, d1
+ cmp r0, #0x22000000
+ bne reg2_error_loopf
+ cmp r1, #0x33000000
+ bne reg2_error_loopf
+ vmov r0, r1, d2
+ cmp r0, #0x44000000
+ bne reg2_error_loopf
+ cmp r1, #0x55000000
+ bne reg2_error_loopf
+ vmov r0, r1, d3
+ cmp r0, #0x66000000
+ bne reg2_error_loopf
+ cmp r1, #0x77000000
+ bne reg2_error_loopf
+ vmov r0, r1, d4
+ cmp r0, #0x88000000
+ bne reg2_error_loopf
+ cmp r1, #0x99000000
+ bne reg2_error_loopf
+ vmov r0, r1, d5
+ cmp r0, #0xAA000000
+ bne reg2_error_loopf
+ cmp r1, #0xBB000000
+ bne reg2_error_loopf
+ vmov r0, r1, d6
+ cmp r0, #0xFF000000
+ bne reg2_error_loopf
+ cmp r1, #0x11000000
+ bne reg2_error_loopf
+ vmov r0, r1, d7
+ cmp r0, #0x22000000
+ bne reg2_error_loopf
+ cmp r1, #0x33000000
+ bne reg2_error_loopf
+ vmov r0, r1, d8
+ cmp r0, #0x44000000
+ bne reg2_error_loopf
+ cmp r1, #0x55000000
+ bne reg2_error_loopf
+ vmov r0, r1, d9
+ cmp r0, #0x66000000
+ bne reg2_error_loopf
+ cmp r1, #0x77000000
+ bne reg2_error_loopf
+ vmov r0, r1, d10
+ cmp r0, #0x88000000
+ bne reg2_error_loopf
+ cmp r1, #0x99000000
+ bne reg2_error_loopf
+ vmov r0, r1, d11
+ cmp r0, #0xAA000000
+ bne reg2_error_loopf
+ cmp r1, #0xBB000000
+ bne reg2_error_loopf
+ vmov r0, r1, d12
+ cmp r0, #0xFF000000
+ bne reg2_error_loopf
+ cmp r1, #0x11000000
+ bne reg2_error_loopf
+ vmov r0, r1, d13
+ cmp r0, #0x22000000
+ bne reg2_error_loopf
+ cmp r1, #0x33000000
+ bne reg2_error_loopf
+ vmov r0, r1, d14
+ cmp r0, #0x44000000
+ bne reg2_error_loopf
+ cmp r1, #0x55000000
+ bne reg2_error_loopf
+ vmov r0, r1, d15
+ cmp r0, #0x66000000
+ bne reg2_error_loopf
+ cmp r1, #0x77000000
+ bne reg2_error_loopf
+
+ ; Restore the registers that were clobbered by the test.
+ pop {r0-r1}
+
+ ; VFP register test passed. Jump to the core register test.
+ b reg2_loopf_pass
+
+reg2_error_loopf:
+ ; If this line is hit then a VFP register value was found to be
+ ; incorrect.
+ b reg2_error_loopf
+
+reg2_loopf_pass:
+
+ .endif ;__TI_VFP_SUPPORT__
+
; Test each general purpose register to check that it still contains the
; expected known value, jumping to vRegTestError2 if any register contains
; an unexpected value.