mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 02:59:01 +01:00 
			
		
		
		
	In the RL78 FAR data model, pxPortInitialiseStack() did not initialize the register image for the task parameter (pvParameters) correctly. A:DE registers were saved with dummy values instead of the actual pointer. Effect: on first context restore the function prologue read a corrupted parameter. NEAR builds were not affected. This patch aligns the FAR path with the calling convention and compiler version: - IAR V2: pass pvParameters via registers → DE = low 16 bits, A = high 8 - IAR V1 (fallback): keep legacy stack write Also keeps the original stack-frame layout and updates the comment to reflect that pointer sizes depend on __DATA_MODEL__. Result: tasks in FAR receive the correct parameter at entry; NEAR remains unchanged. Co-authored-by: Thomas Quiniou <tquiniou@fdi-access.com>
This commit is contained in:
		
							parent
							
								
									a8ae21c88e
								
							
						
					
					
						commit
						a1f6e1f64f
					
				@ -93,12 +93,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                     void * pvParameters )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t * pulLocal;
 | 
			
		||||
 | 
			
		||||
    /* With large code and large data sizeof( StackType_t ) == 2, and
 | 
			
		||||
    * sizeof( StackType_t * ) == 4.  With small code and small data
 | 
			
		||||
    * sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
 | 
			
		||||
 | 
			
		||||
    #if __DATA_MODEL__ == __DATA_MODEL_FAR__
 | 
			
		||||
    /* With large data sizeof( StackType_t ) == 2, and
 | 
			
		||||
     * sizeof( StackType_t * ) == 4.  With small data
 | 
			
		||||
     * sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
 | 
			
		||||
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
 | 
			
		||||
    {
 | 
			
		||||
        /* Far pointer parameters are passed using the A:DE registers (24-bit).
 | 
			
		||||
         * Although they are stored in memory as a 32-bit value.  Hence decrement
 | 
			
		||||
@ -106,9 +104,13 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
         * storing the pvParameters value. */
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
			
		||||
        *pulLocal = ( uint32_t ) pvParameters;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
        #if  __CALLING_CONVENTION__ == __CC_V2__
 | 
			
		||||
            /* V2: parameter via A:DE, do not push pvParameters on stack */
 | 
			
		||||
        #else
 | 
			
		||||
            /* V1 or unknown: keep stack write */
 | 
			
		||||
            *pulLocal = ( uint32_t ) pvParameters;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
        #endif
 | 
			
		||||
        /* The return address is a 32-bit value. So decrement the stack pointer
 | 
			
		||||
         * in order to make extra room needed to store the correct value.  See the
 | 
			
		||||
         * comments above the prvTaskExitError() prototype at the top of this file. */
 | 
			
		||||
@ -116,65 +118,89 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
			
		||||
        *pulLocal = ( uint32_t ) prvTaskExitError;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
        /* The task function start address combined with the PSW is also stored
 | 
			
		||||
         * as a 32-bit value. So leave a space for the second two bytes. */
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
			
		||||
        *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
        /* An initial value for the AX register. */
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) 0x1111;
 | 
			
		||||
        /* Register image on task entry. */
 | 
			
		||||
        #if  __CALLING_CONVENTION__ == __CC_V2__
 | 
			
		||||
        {
 | 
			
		||||
            uint32_t p = ( uint32_t ) pvParameters;
 | 
			
		||||
            uint16_t de_init = (uint16_t)( p & 0xFFFFU );
 | 
			
		||||
            uint16_t ax_init = (uint16_t)( ((p >> 16) & 0xFFU) << 8 );
 | 
			
		||||
            /* AX register image */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) ax_init;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
            /* HL register image (dummy) */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) 0x2222;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
            /* CS:ES register image */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) 0x0F00;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
            /* DE register image */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) de_init;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
        }
 | 
			
		||||
        #else
 | 
			
		||||
            /* An initial value for the AX register. */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) 0x1111;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
            /* HL register image (dummy) */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) 0x2222;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
            /* CS:ES register image */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) 0x0F00;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
            /* DE register image (dummy) */
 | 
			
		||||
            *pxTopOfStack = ( StackType_t ) 0xDEDE;
 | 
			
		||||
            pxTopOfStack--;
 | 
			
		||||
        #endif
 | 
			
		||||
        /* BC remains a dummy value (not used for parameter passing). */
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) 0xBCBC;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
    }
 | 
			
		||||
    #else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
 | 
			
		||||
#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
 | 
			
		||||
    {
 | 
			
		||||
        /* The return address, leaving space for the first two bytes of the
 | 
			
		||||
       /* The return address, leaving space for the first two bytes of the
 | 
			
		||||
         * 32-bit value.  See the comments above the prvTaskExitError() prototype
 | 
			
		||||
         * at the top of this file. */
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
			
		||||
        *pulLocal = ( uint32_t ) prvTaskExitError;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
        /* Task function.  Again as it is written as a 32-bit value a space is
 | 
			
		||||
         * left on the stack for the second two bytes. */
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
        /* Task function start address combined with the PSW. */
 | 
			
		||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
			
		||||
        *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
        /* The parameter is passed in AX. */
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) pvParameters;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        /* An initial value for the HL register. */
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) 0x2222;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        /* CS and ES registers. */
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) 0x0F00;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        /* The remaining general purpose registers DE and BC */
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) 0xDEDE;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
        *pxTopOfStack = ( StackType_t ) 0xBCBC;
 | 
			
		||||
        pxTopOfStack--;
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
 | 
			
		||||
 | 
			
		||||
    /* An initial value for the HL register. */
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) 0x2222;
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
    /* CS and ES registers. */
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) 0x0F00;
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
    /* The remaining general purpose registers DE and BC */
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) 0xDEDE;
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) 0xBCBC;
 | 
			
		||||
    pxTopOfStack--;
 | 
			
		||||
 | 
			
		||||
#endif /* __DATA_MODEL__ */
 | 
			
		||||
    /* Finally the critical section nesting count is set to zero when the task
 | 
			
		||||
     * first starts. */
 | 
			
		||||
    *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
 | 
			
		||||
 | 
			
		||||
    /* Return a pointer to the top of the stack that has been generated so
 | 
			
		||||
     * it can be stored in the task control block for the task. */
 | 
			
		||||
    return pxTopOfStack;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvTaskExitError( void )
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user