Skip to content

Commit a1f6e1f

Browse files
sauleThsQuinThomas Quiniou
andauthored
fix[RL78 Port] incorrect register image for pvParameters in FAR model (#1316) (#1317)
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>
1 parent a8ae21c commit a1f6e1f

File tree

1 file changed

+61
-35
lines changed

1 file changed

+61
-35
lines changed

portable/IAR/RL78/port.c

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -93,88 +93,114 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
9393
void * pvParameters )
9494
{
9595
uint32_t * pulLocal;
96-
97-
/* 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. */
100-
101-
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
96+
/* With large data sizeof( StackType_t ) == 2, and
97+
* sizeof( StackType_t * ) == 4. With small data
98+
* sizeof( StackType_t ) == 2 and sizeof( StackType_t * ) == 2. */
99+
#if __DATA_MODEL__ == __DATA_MODEL_FAR__
102100
{
103101
/* Far pointer parameters are passed using the A:DE registers (24-bit).
104102
* Although they are stored in memory as a 32-bit value. Hence decrement
105103
* the stack pointer, so 2 bytes are left for the contents of A, before
106104
* storing the pvParameters value. */
107105
pxTopOfStack--;
108106
pulLocal = ( uint32_t * ) pxTopOfStack;
109-
*pulLocal = ( uint32_t ) pvParameters;
110-
pxTopOfStack--;
111-
107+
#if __CALLING_CONVENTION__ == __CC_V2__
108+
/* V2: parameter via A:DE, do not push pvParameters on stack */
109+
#else
110+
/* V1 or unknown: keep stack write */
111+
*pulLocal = ( uint32_t ) pvParameters;
112+
pxTopOfStack--;
113+
#endif
112114
/* The return address is a 32-bit value. So decrement the stack pointer
113115
* in order to make extra room needed to store the correct value. See the
114116
* comments above the prvTaskExitError() prototype at the top of this file. */
115117
pxTopOfStack--;
116118
pulLocal = ( uint32_t * ) pxTopOfStack;
117119
*pulLocal = ( uint32_t ) prvTaskExitError;
118120
pxTopOfStack--;
119-
120121
/* The task function start address combined with the PSW is also stored
121122
* as a 32-bit value. So leave a space for the second two bytes. */
122123
pxTopOfStack--;
123124
pulLocal = ( uint32_t * ) pxTopOfStack;
124125
*pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
125126
pxTopOfStack--;
126-
127-
/* An initial value for the AX register. */
128-
*pxTopOfStack = ( StackType_t ) 0x1111;
127+
/* Register image on task entry. */
128+
#if __CALLING_CONVENTION__ == __CC_V2__
129+
{
130+
uint32_t p = ( uint32_t ) pvParameters;
131+
uint16_t de_init = (uint16_t)( p & 0xFFFFU );
132+
uint16_t ax_init = (uint16_t)( ((p >> 16) & 0xFFU) << 8 );
133+
/* AX register image */
134+
*pxTopOfStack = ( StackType_t ) ax_init;
135+
pxTopOfStack--;
136+
/* HL register image (dummy) */
137+
*pxTopOfStack = ( StackType_t ) 0x2222;
138+
pxTopOfStack--;
139+
/* CS:ES register image */
140+
*pxTopOfStack = ( StackType_t ) 0x0F00;
141+
pxTopOfStack--;
142+
/* DE register image */
143+
*pxTopOfStack = ( StackType_t ) de_init;
144+
pxTopOfStack--;
145+
}
146+
#else
147+
/* An initial value for the AX register. */
148+
*pxTopOfStack = ( StackType_t ) 0x1111;
149+
pxTopOfStack--;
150+
/* HL register image (dummy) */
151+
*pxTopOfStack = ( StackType_t ) 0x2222;
152+
pxTopOfStack--;
153+
/* CS:ES register image */
154+
*pxTopOfStack = ( StackType_t ) 0x0F00;
155+
pxTopOfStack--;
156+
/* DE register image (dummy) */
157+
*pxTopOfStack = ( StackType_t ) 0xDEDE;
158+
pxTopOfStack--;
159+
#endif
160+
/* BC remains a dummy value (not used for parameter passing). */
161+
*pxTopOfStack = ( StackType_t ) 0xBCBC;
129162
pxTopOfStack--;
130163
}
131-
#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
164+
#else /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
132165
{
133-
/* The return address, leaving space for the first two bytes of the
166+
/* The return address, leaving space for the first two bytes of the
134167
* 32-bit value. See the comments above the prvTaskExitError() prototype
135168
* at the top of this file. */
136169
pxTopOfStack--;
137170
pulLocal = ( uint32_t * ) pxTopOfStack;
138171
*pulLocal = ( uint32_t ) prvTaskExitError;
139172
pxTopOfStack--;
140-
141173
/* Task function. Again as it is written as a 32-bit value a space is
142174
* left on the stack for the second two bytes. */
143175
pxTopOfStack--;
144-
145176
/* Task function start address combined with the PSW. */
146177
pulLocal = ( uint32_t * ) pxTopOfStack;
147178
*pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );
148179
pxTopOfStack--;
149-
150180
/* The parameter is passed in AX. */
151181
*pxTopOfStack = ( StackType_t ) pvParameters;
152182
pxTopOfStack--;
183+
/* An initial value for the HL register. */
184+
*pxTopOfStack = ( StackType_t ) 0x2222;
185+
pxTopOfStack--;
186+
/* CS and ES registers. */
187+
*pxTopOfStack = ( StackType_t ) 0x0F00;
188+
pxTopOfStack--;
189+
/* The remaining general purpose registers DE and BC */
190+
*pxTopOfStack = ( StackType_t ) 0xDEDE;
191+
pxTopOfStack--;
192+
*pxTopOfStack = ( StackType_t ) 0xBCBC;
193+
pxTopOfStack--;
153194
}
154-
#endif /* if __DATA_MODEL__ == __DATA_MODEL_FAR__ */
155-
156-
/* An initial value for the HL register. */
157-
*pxTopOfStack = ( StackType_t ) 0x2222;
158-
pxTopOfStack--;
159-
160-
/* CS and ES registers. */
161-
*pxTopOfStack = ( StackType_t ) 0x0F00;
162-
pxTopOfStack--;
163-
164-
/* The remaining general purpose registers DE and BC */
165-
*pxTopOfStack = ( StackType_t ) 0xDEDE;
166-
pxTopOfStack--;
167-
*pxTopOfStack = ( StackType_t ) 0xBCBC;
168-
pxTopOfStack--;
169-
195+
#endif /* __DATA_MODEL__ */
170196
/* Finally the critical section nesting count is set to zero when the task
171197
* first starts. */
172198
*pxTopOfStack = ( StackType_t ) portNO_CRITICAL_SECTION_NESTING;
173-
174199
/* Return a pointer to the top of the stack that has been generated so
175200
* it can be stored in the task control block for the task. */
176201
return pxTopOfStack;
177202
}
203+
178204
/*-----------------------------------------------------------*/
179205

180206
static void prvTaskExitError( void )

0 commit comments

Comments
 (0)