#include "FreeRTOS.h"\r
#include "task.h"\r
\r
-#define portINITIAL_SR 0UL /* No interrupts masked. */\r
+/* Library includes. */\r
+#include "string.h"\r
\r
+#define portINITIAL_SR 0UL /* No interrupts masked. */\r
+\r
+/* Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4\r
+bytes big. If this number is changed then the 72 in portasm.src also needs\r
+changing. */\r
+#define portFLOP_REGISTERS_TO_STORE ( 18 )\r
+#define portFLOP_STORAGE_SIZE ( portFLOP_REGISTERS_TO_STORE * 4 )\r
\r
/*-----------------------------------------------------------*/\r
\r
prvSetupTimerInterrupt();\r
\r
/* Start the first task. */\r
- trapa( 32 );\r
+ trapa( portSTART_SCHEDULER_TRAP_NO );\r
\r
/* Should not get here. */\r
return pdFAIL;\r
}\r
/*-----------------------------------------------------------*/\r
\r
+void vPortYield( void )\r
+{\r
+long lInterruptMask;\r
+\r
+ lInterruptMask = get_imask();\r
+\r
+ /* taskYIELD() can only be called from a task, not an interrupt, so the\r
+ current interrupt mask can only be 0 or portKERNEL_INTERRUPT_PRIORITY and\r
+ the mask can be set without risk of accidentally lowering the mask value. */ \r
+ set_imask( portKERNEL_INTERRUPT_PRIORITY );\r
+ \r
+ trapa( portYIELD_TRAP_NO );\r
+ \r
+ set_imask( ( int ) lInterruptMask );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+portBASE_TYPE xPortUsesFloatingPoint( xTaskHandle xTask )\r
+{\r
+unsigned long *pulFlopBuffer;\r
+portBASE_TYPE xReturn;\r
+extern void * volatile pxCurrentTCB;\r
+\r
+ if( xTask == NULL )\r
+ {\r
+ xTask = pxCurrentTCB;\r
+ }\r
+\r
+ /* Allocate a buffer large enough to hold all the flop registers. */\r
+ pulFlopBuffer = ( unsigned long * ) pvPortMalloc( portFLOP_STORAGE_SIZE );\r
+ \r
+ if( pulFlopBuffer != NULL )\r
+ {\r
+ memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );\r
+ \r
+ *pulFlopBuffer = get_fpscr();\r
+ \r
+ /* Use the task tag to point to the flop buffer. Pass pointer to just above\r
+ the buffer because the flop save routine uses a pre-decrement. */\r
+ vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) ); \r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+ \r
+ return xReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
\r
\r
\r
\r
.export _vPortStartFirstTask\r
.export _ulPortGetGBR\r
- .export _vPortYield\r
+ .export _vPortYieldHandler\r
.export _vPortPreemptiveTick\r
.export _vPortCooperativeTick\r
+ .export _vPortSaveFlopRegisters\r
+ .export _vPortRestoreFlopRegisters\r
\r
.section P\r
\r
\r
;-----------------------------------------------------------\r
\r
-_vPortYield:\r
-\r
- ; Push r0 so it can be used.\r
- mov.l r0, @-r15\r
- \r
- ; Set the interrupt mask in the status register.\r
- stc sr, r0\r
- or #H'70, r0\r
- ldc r0, sr\r
- \r
- ; Restore r0 so its original value can be saved by the movml.l instruction \r
- ; below, without ending up with two copies on the stack.\r
- mov.l @r15+, r0\r
+_vPortYieldHandler:\r
\r
portSAVE_CONTEXT\r
\r
rts\r
nop\r
\r
+;-----------------------------------------------------------\r
+\r
+_vPortSaveFlopRegisters:\r
+\r
+ fmov.s fr0, @-r4\r
+ fmov.s fr1, @-r4\r
+ fmov.s fr2, @-r4\r
+ fmov.s fr3, @-r4\r
+ fmov.s fr4, @-r4\r
+ fmov.s fr5, @-r4\r
+ fmov.s fr6, @-r4\r
+ fmov.s fr7, @-r4\r
+ fmov.s fr8, @-r4\r
+ fmov.s fr9, @-r4\r
+ fmov.s fr10, @-r4\r
+ fmov.s fr11, @-r4\r
+ fmov.s fr12, @-r4\r
+ fmov.s fr13, @-r4\r
+ fmov.s fr14, @-r4\r
+ fmov.s fr15, @-r4 \r
+ sts.l fpul, @-r4\r
+ sts.l fpscr, @-r4\r
+ \r
+ rts\r
+ nop\r
+\r
+;-----------------------------------------------------------\r
+ \r
+_vPortRestoreFlopRegisters:\r
+\r
+ add.l #-72, r4\r
+ lds.l @r4+, fpscr\r
+ lds.l @r4+, fpul \r
+ fmov.s @r4+, fr15\r
+ fmov.s @r4+, fr14\r
+ fmov.s @r4+, fr13\r
+ fmov.s @r4+, fr12\r
+ fmov.s @r4+, fr11\r
+ fmov.s @r4+, fr10\r
+ fmov.s @r4+, fr9\r
+ fmov.s @r4+, fr8\r
+ fmov.s @r4+, fr7\r
+ fmov.s @r4+, fr6\r
+ fmov.s @r4+, fr5\r
+ fmov.s @r4+, fr4\r
+ fmov.s @r4+, fr3\r
+ fmov.s @r4+, fr2\r
+ fmov.s @r4+, fr1\r
+ fmov.s @r4+, fr0\r
+ \r
+ rts\r
+ nop\r
+ \r
.end\r
\r
/*-----------------------------------------------------------*/\r
\r
/* Hardware specifics. */\r
-#define portBYTE_ALIGNMENT 4\r
-#define portSTACK_GROWTH -1\r
-#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) \r
-#define portYIELD() trapa( 33 )\r
-#define portNOP() nop()\r
+#define portBYTE_ALIGNMENT 4\r
+#define portSTACK_GROWTH -1\r
+#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) \r
+#define portNOP() nop()\r
+#define portSTART_SCHEDULER_TRAP_NO ( 32 )\r
+#define portYIELD_TRAP_NO ( 33 )\r
+#define portKERNEL_INTERRUPT_PRIORITY ( 1 )\r
+\r
+void vPortYield( void );\r
+#define portYIELD() vPortYield()\r
+\r
+portBASE_TYPE xPortUsesFloatingPoint( void* xTask );\r
+void vPortSaveFlopRegisters( void *pulBuffer );\r
+void vPortRestoreFlopRegisters( void *pulBuffer );\r
+#define traceTASK_SWITCHED_OUT() if( pxCurrentTCB->pxTaskTag != NULL ) vPortSaveFlopRegisters( pxCurrentTCB->pxTaskTag )\r
+#define traceTASK_SWITCHED_IN() if( pxCurrentTCB->pxTaskTag != NULL ) vPortRestoreFlopRegisters( pxCurrentTCB->pxTaskTag )\r
+\r
/*-----------------------------------------------------------*/\r
\r
#define portENABLE_INTERRUPTS() set_imask( 0x00 )\r
-#define portDISABLE_INTERRUPTS() set_imask( configMAX_SYSCALL_INTERRUPT_PRIORITY )\r
+#define portDISABLE_INTERRUPTS() set_imask( portKERNEL_INTERRUPT_PRIORITY )\r
\r
/* Critical section handling. */\r
#define portCRITICAL_NESTING_IN_TCB ( 1 )\r