Skip to content

Commit dde270b

Browse files
author
Thomas Quiniou
committed
fix[RL78 Port] incorrect register image for pvParameters in FAR model (#1316)
In the RL78 FAR data model, pxPortInitialiseStack() did not correctly initialize the register image for the task parameter (pvParameters). The saved A:DE registers were filled with dummy values instead of the actual pointer value. As a result, when the first context restore occurred, the compiler's function prologue read a corrupted parameter from the register image. This only affected FAR builds; NEAR model was not impacted. This patch updates the RL78 FAR path so that the register image matches the calling convention: - DE = low 16 bits of pvParameters - A = high 8 bits of pvParameters (via AX register image, X = 0) With this change, tasks in FAR model receive the correct parameter at entry, while NEAR model remains unchanged.
1 parent ccabdec commit dde270b

File tree

1 file changed

+51
-20
lines changed

1 file changed

+51
-20
lines changed

portable/IAR/RL78/port.c

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
9595
uint32_t * pulLocal;
9696

9797
/* With large code and large data sizeof( StackType_t ) == 2, and
98-
* sizeof( StackType_t * ) == 4. With small code and small data
99-
* sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
98+
* sizeof( StackType_t * ) == 4. With small code and small data
99+
* sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
100100

101-
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
101+
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
102102
{
103103
/* Far pointer parameters are passed using the A:DE registers (24-bit).
104104
* Although they are stored in memory as a 32-bit value. Hence decrement
@@ -124,13 +124,44 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
124124
*pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
125125
pxTopOfStack--;
126126

127-
/* An initial value for the AX register. */
128-
*pxTopOfStack = ( StackType_t ) 0x1111;
127+
/* In FAR data model, the compiler expects the task parameter (pvParameters)
128+
* to be passed in the A:DE registers (24-bit). Therefore the parameter is
129+
* split into:
130+
* - DE = low 16 bits
131+
* - A = high 8 bits (loaded through the AX register image, X = 0)
132+
* This ensures that the task entry function receives pvParameters in the
133+
* format required by the C calling convention. */
134+
{
135+
uint32_t p = ( uint32_t ) pvParameters;
136+
/* low 16 bits */
137+
uint16_t de_init = (uint16_t)( p & 0xFFFFU );
138+
/* A = high byte, X = 0 */
139+
uint16_t ax_init = (uint16_t)( ((p >> 16) & 0xFFU) << 8 );
140+
141+
/* AX register image */
142+
*pxTopOfStack = ( StackType_t ) ax_init;
143+
pxTopOfStack--;
144+
145+
/* HL register image (dummy) */
146+
*pxTopOfStack = ( StackType_t ) 0x2222;
147+
pxTopOfStack--;
148+
149+
/* CS:ES register image */
150+
*pxTopOfStack = ( StackType_t ) 0x0F00;
151+
pxTopOfStack--;
152+
153+
/* DE register image */
154+
*pxTopOfStack = ( StackType_t ) de_init;
155+
pxTopOfStack--;
156+
}
157+
158+
/* BC remains a dummy value (not used for parameter passing). */
159+
*pxTopOfStack = ( StackType_t ) 0xBCBC;
129160
pxTopOfStack--;
130161
}
131-
#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
162+
#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
132163
{
133-
/* The return address, leaving space for the first two bytes of the
164+
/* The return address, leaving space for the first two bytes of the
134165
* 32-bit value. See the comments above the prvTaskExitError() prototype
135166
* at the top of this file. */
136167
pxTopOfStack--;
@@ -150,22 +181,22 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
150181
/* The parameter is passed in AX. */
151182
*pxTopOfStack = ( StackType_t ) pvParameters;
152183
pxTopOfStack--;
153-
}
154-
#endif /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
155184

156-
/* An initial value for the HL register. */
157-
*pxTopOfStack = ( StackType_t ) 0x2222;
158-
pxTopOfStack--;
185+
/* An initial value for the HL register. */
186+
*pxTopOfStack = ( StackType_t ) 0x2222;
187+
pxTopOfStack--;
159188

160-
/* CS and ES registers. */
161-
*pxTopOfStack = ( StackType_t ) 0x0F00;
162-
pxTopOfStack--;
189+
/* CS and ES registers. */
190+
*pxTopOfStack = ( StackType_t ) 0x0F00;
191+
pxTopOfStack--;
163192

164-
/* The remaining general purpose registers DE and BC */
165-
*pxTopOfStack = ( StackType_t ) 0xDEDE;
166-
pxTopOfStack--;
167-
*pxTopOfStack = ( StackType_t ) 0xBCBC;
168-
pxTopOfStack--;
193+
/* The remaining general purpose registers DE and BC */
194+
*pxTopOfStack = ( StackType_t ) 0xDEDE;
195+
pxTopOfStack--;
196+
*pxTopOfStack = ( StackType_t ) 0xBCBC;
197+
pxTopOfStack--;
198+
}
199+
#endif /* __DATA_MODEL__ */
169200

170201
/* Finally the critical section nesting count is set to zero when the task
171202
* first starts. */

0 commit comments

Comments
 (0)