]> git.sur5r.net Git - freertos/commitdiff
Add flop support.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 17 Jan 2010 13:12:54 +0000 (13:12 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Sun, 17 Jan 2010 13:12:54 +0000 (13:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@961 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Source/portable/Renesas/SH2A_FPU/port.c
Source/portable/Renesas/SH2A_FPU/portasm.src
Source/portable/Renesas/SH2A_FPU/portmacro.h

index b6832f9c290860a4e60ca2152477c8f388fbb7f1..c52485c8169ae1cb327ded740db0b6dbc23f3e4d 100644 (file)
 #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
@@ -196,7 +204,7 @@ portBASE_TYPE xPortStartScheduler( void )
        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
@@ -229,6 +237,58 @@ extern void vApplicationSetupTimerInterrupt( void );
 }\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
index 1d832a90dfa223c321b05295f11ed59788c8603b..948b57dd7df274566f6c3fbe26a3c512a1803a5f 100644 (file)
 \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
@@ -118,19 +120,7 @@ _vPortStartFirstTask:
        \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
@@ -176,5 +166,58 @@ _ulPortGetGBR:
        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
index b1c88de7d4be336afe5d6696ce6c29839541722c..ca59d72db49f07ebef8e4ecfbdeff2a61d435f14 100644 (file)
@@ -90,15 +90,27 @@ extern "C" {
 /*-----------------------------------------------------------*/\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