Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions portable/Renesas/SH2A_FPU/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,6 @@
* value is for all interrupts to be enabled. */
#define portINITIAL_SR ( 0UL )

/* Dimensions the array into which the floating point context is saved.
* Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4
* bytes big. If this number is changed then the 72 in portasm.src also needs
* changing. */
#define portFLOP_REGISTERS_TO_STORE ( 18 )
#define portFLOP_STORAGE_SIZE ( portFLOP_REGISTERS_TO_STORE * 4 )

#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
#error configSUPPORT_DYNAMIC_ALLOCATION must be 1 to use this port.
#endif
Expand Down Expand Up @@ -245,26 +238,35 @@ BaseType_t xPortUsesFloatingPoint( TaskHandle_t xTask )
xTask = ( TaskHandle_t ) pxCurrentTCB;
}

/* Allocate a buffer large enough to hold all the flop registers. */
pulFlopBuffer = ( uint32_t * ) pvPortMalloc( portFLOP_STORAGE_SIZE );

if( pulFlopBuffer != NULL )
/* The task tag already owns the FPU buffer for this port. Do not replace
* it, or the original allocation would become unreachable. */
if( xTaskGetApplicationTaskTag( xTask ) != NULL )
{
/* Start with the registers in a benign state. */
memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );

/* The first thing to get saved in the buffer is the FPSCR value -
* initialise this to the current FPSCR value. */
*pulFlopBuffer = get_fpscr();

/* Use the task tag to point to the flop buffer. Pass pointer to just
* above the buffer because the flop save routine uses a pre-decrement. */
vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) );
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
/* Allocate a buffer large enough to hold all the flop registers. */
pulFlopBuffer = ( uint32_t * ) pvPortMalloc( portFLOP_STORAGE_SIZE );

if( pulFlopBuffer != NULL )
{
/* Start with the registers in a benign state. */
memset( ( void * ) pulFlopBuffer, 0x00, portFLOP_STORAGE_SIZE );

/* The first thing to get saved in the buffer is the FPSCR value -
* initialise this to the current FPSCR value. */
*pulFlopBuffer = get_fpscr();

/* Use the task tag to point to the flop buffer. Pass pointer to just
* above the buffer because the flop save routine uses a pre-decrement. */
vTaskSetApplicationTaskTag( xTask, ( void * ) ( pulFlopBuffer + portFLOP_REGISTERS_TO_STORE ) );
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
}

return xReturn;
Expand Down
22 changes: 22 additions & 0 deletions portable/Renesas/SH2A_FPU/portmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ typedef unsigned long UBaseType_t;
#define portYIELD_TRAP_NO ( 33 )
#define portKERNEL_INTERRUPT_PRIORITY ( 1 )

/* Dimensions the array into which the floating point context is saved.
* Allocate enough space for FPR0 to FPR15, FPUL and FPSCR, each of which is 4
* bytes big. If this number is changed then the 72 in portasm.src also needs
* changing. */
#define portFLOP_REGISTERS_TO_STORE ( 18 )
#define portFLOP_STORAGE_SIZE ( portFLOP_REGISTERS_TO_STORE * 4 )

void vPortYield( void );
#define portYIELD() vPortYield()

Expand Down Expand Up @@ -112,6 +119,21 @@ void vPortRestoreFlopRegisters( void * pulBuffer );
#define traceTASK_SWITCHED_OUT() do { if( pxCurrentTCB->pxTaskTag != NULL ) vPortSaveFlopRegisters( pxCurrentTCB->pxTaskTag ); } while( 0 )
#define traceTASK_SWITCHED_IN() do { if( pxCurrentTCB->pxTaskTag != NULL ) vPortRestoreFlopRegisters( pxCurrentTCB->pxTaskTag ); } while( 0 )

/* pxTaskTag points just above the FPU context buffer because the save routine
* uses a pre-decrement. Recover the allocation base before freeing it. */
#define portCLEAN_UP_TCB( pxTCB ) \
do \
{ \
if( ( pxTCB )->pxTaskTag != NULL ) \
{ \
uint32_t * pulFlopBufferEnd = \
( uint32_t * ) ( pxTCB )->pxTaskTag; \
vPortFree( ( void * ) ( pulFlopBufferEnd - \
portFLOP_REGISTERS_TO_STORE ) ); \
( pxTCB )->pxTaskTag = NULL; \
} \
} while( 0 )

/*
* These macros should be called directly, but through the taskENTER_CRITICAL()
* and taskEXIT_CRITICAL() macros.
Expand Down