mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-04 11:09: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 )
 | 
					                                     void * pvParameters )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t * pulLocal;
 | 
					    uint32_t * pulLocal;
 | 
				
			||||||
 | 
					    /* With large data sizeof( StackType_t ) == 2, and
 | 
				
			||||||
    /* With large code and large data sizeof( StackType_t ) == 2, and
 | 
					     * sizeof( StackType_t * ) == 4.  With small data
 | 
				
			||||||
    * sizeof( StackType_t * ) == 4.  With small code and small data
 | 
					     * sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
 | 
				
			||||||
    * sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
 | 
					#if __DATA_MODEL__ == __DATA_MODEL_FAR__
 | 
				
			||||||
 | 
					 | 
				
			||||||
    #if __DATA_MODEL__ == __DATA_MODEL_FAR__
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /* Far pointer parameters are passed using the A:DE registers (24-bit).
 | 
					        /* 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
 | 
					         * 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. */
 | 
					         * storing the pvParameters value. */
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
					        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
				
			||||||
        *pulLocal = ( uint32_t ) pvParameters;
 | 
					        #if  __CALLING_CONVENTION__ == __CC_V2__
 | 
				
			||||||
        pxTopOfStack--;
 | 
					            /* 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
 | 
					        /* 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
 | 
					         * 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. */
 | 
					         * 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 * ) pxTopOfStack;
 | 
				
			||||||
        *pulLocal = ( uint32_t ) prvTaskExitError;
 | 
					        *pulLocal = ( uint32_t ) prvTaskExitError;
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* The task function start address combined with the PSW is also stored
 | 
					        /* 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. */
 | 
					         * as a 32-bit value. So leave a space for the second two bytes. */
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
					        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
				
			||||||
        *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
 | 
					        *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
 | 
					        /* Register image on task entry. */
 | 
				
			||||||
        /* An initial value for the AX register. */
 | 
					        #if  __CALLING_CONVENTION__ == __CC_V2__
 | 
				
			||||||
        *pxTopOfStack = ( StackType_t ) 0x1111;
 | 
					        {
 | 
				
			||||||
 | 
					            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--;
 | 
					        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
 | 
					         * 32-bit value.  See the comments above the prvTaskExitError() prototype
 | 
				
			||||||
         * at the top of this file. */
 | 
					         * at the top of this file. */
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
					        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
				
			||||||
        *pulLocal = ( uint32_t ) prvTaskExitError;
 | 
					        *pulLocal = ( uint32_t ) prvTaskExitError;
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Task function.  Again as it is written as a 32-bit value a space is
 | 
					        /* Task function.  Again as it is written as a 32-bit value a space is
 | 
				
			||||||
         * left on the stack for the second two bytes. */
 | 
					         * left on the stack for the second two bytes. */
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Task function start address combined with the PSW. */
 | 
					        /* Task function start address combined with the PSW. */
 | 
				
			||||||
        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
					        pulLocal = ( uint32_t * ) pxTopOfStack;
 | 
				
			||||||
        *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
 | 
					        *pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        pxTopOfStack--;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* The parameter is passed in AX. */
 | 
					        /* The parameter is passed in AX. */
 | 
				
			||||||
        *pxTopOfStack = ( StackType_t ) pvParameters;
 | 
					        *pxTopOfStack = ( StackType_t ) pvParameters;
 | 
				
			||||||
        pxTopOfStack--;
 | 
					        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__ */
 | 
					#endif /* __DATA_MODEL__ */
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 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--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Finally the critical section nesting count is set to zero when the task
 | 
					    /* Finally the critical section nesting count is set to zero when the task
 | 
				
			||||||
     * first starts. */
 | 
					     * first starts. */
 | 
				
			||||||
    *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
 | 
					    *pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Return a pointer to the top of the stack that has been generated so
 | 
					    /* 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. */
 | 
					     * it can be stored in the task control block for the task. */
 | 
				
			||||||
    return pxTopOfStack;
 | 
					    return pxTopOfStack;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*-----------------------------------------------------------*/
 | 
					/*-----------------------------------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void prvTaskExitError( void )
 | 
					static void prvTaskExitError( void )
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user