@@ -53,18 +53,18 @@ typedef uintptr_t (*syscall_t)(unsigned int, ...);
53
53
****************************************************************************/
54
54
55
55
static void arm64_dump_syscall (const char * tag , uint64_t cmd ,
56
- const uint64_t * regs )
56
+ const struct regs_context * f_regs )
57
57
{
58
- svcinfo ("SYSCALL %s: regs: %p cmd: %" PRId64 "\n" , tag , regs , cmd );
58
+ svcinfo ("SYSCALL %s: regs: %p cmd: %" PRId64 "\n" , tag , f_regs , cmd );
59
59
60
60
svcinfo ("x0: 0x%-16lx x1: 0x%lx\n" ,
61
- regs [REG_X0 ], regs [REG_X1 ]);
61
+ f_regs -> regs [REG_X0 ], f_regs -> regs [REG_X1 ]);
62
62
svcinfo ("x2: 0x%-16lx x3: 0x%lx\n" ,
63
- regs [REG_X2 ], regs [REG_X3 ]);
63
+ f_regs -> regs [REG_X2 ], f_regs -> regs [REG_X3 ]);
64
64
svcinfo ("x4: 0x%-16lx x5: 0x%lx\n" ,
65
- regs [REG_X4 ], regs [REG_X5 ]);
65
+ f_regs -> regs [REG_X4 ], f_regs -> regs [REG_X5 ]);
66
66
svcinfo ("x6: 0x%-16lx x7: 0x%lx\n" ,
67
- regs [REG_X6 ], regs [REG_X7 ]);
67
+ f_regs -> regs [REG_X6 ], f_regs -> regs [REG_X7 ]);
68
68
}
69
69
70
70
#ifdef CONFIG_LIB_SYSCALL
@@ -145,32 +145,32 @@ uintptr_t dispatch_syscall(unsigned int nbr, uintptr_t parm1,
145
145
#endif
146
146
147
147
/****************************************************************************
148
- * Name: arm64_syscall
148
+ * Name: arm64_syscall_switch
149
149
*
150
150
* Description:
151
151
* task switch syscall
152
152
*
153
153
****************************************************************************/
154
154
155
- uint64_t * arm64_syscall (uint64_t * regs )
155
+ uint64_t * arm64_syscall_switch (uint64_t * regs )
156
156
{
157
- uint64_t * ret_regs = regs ;
158
157
uint64_t cmd ;
158
+ struct regs_context * f_regs ;
159
+ uint64_t * ret_regs ;
159
160
struct tcb_s * tcb ;
160
161
int cpu ;
161
- #ifdef CONFIG_BUILD_KERNEL
162
- uint64_t spsr ;
163
- #endif
164
162
165
163
/* Nested interrupts are not supported */
166
164
167
165
DEBUGASSERT (regs );
168
166
167
+ f_regs = (struct regs_context * )regs ;
168
+
169
169
/* The SYSCALL command is in x0 on entry. Parameters follow in x1..x7 */
170
170
171
- cmd = regs [REG_X0 ];
171
+ cmd = f_regs -> regs [REG_X0 ];
172
172
173
- arm64_dump_syscall (__func__ , cmd , regs );
173
+ arm64_dump_syscall (__func__ , cmd , f_regs );
174
174
175
175
switch (cmd )
176
176
{
@@ -192,7 +192,7 @@ uint64_t *arm64_syscall(uint64_t *regs)
192
192
* set will determine the restored context.
193
193
*/
194
194
195
- ret_regs = (uint64_t * )regs [REG_X1 ];
195
+ ret_regs = (uint64_t * )f_regs -> regs [REG_X1 ];
196
196
197
197
DEBUGASSERT (ret_regs );
198
198
}
@@ -216,13 +216,85 @@ uint64_t *arm64_syscall(uint64_t *regs)
216
216
217
217
case SYS_switch_context :
218
218
{
219
- DEBUGASSERT (regs [REG_X1 ] != 0 && regs [REG_X2 ] != 0 );
220
- * (uint64_t * * )regs [REG_X1 ] = regs ;
219
+ DEBUGASSERT (f_regs -> regs [REG_X1 ] != 0 &&
220
+ f_regs -> regs [REG_X2 ] != 0 );
221
+ * (uint64_t * * )f_regs -> regs [REG_X1 ] = regs ;
221
222
222
- ret_regs = (uint64_t * )regs [REG_X2 ];
223
+ ret_regs = (uint64_t * ) f_regs -> regs [REG_X2 ];
223
224
}
224
225
break ;
225
226
227
+ default :
228
+ {
229
+ svcerr ("ERROR: Bad SYS call: 0x%" PRIx64 "\n" , cmd );
230
+ ret_regs = 0 ;
231
+ return 0 ;
232
+ }
233
+ break ;
234
+ }
235
+
236
+ if ((uint64_t * )f_regs != ret_regs )
237
+ {
238
+ #ifdef CONFIG_ARCH_ADDRENV
239
+ /* Make sure that the address environment for the previously
240
+ * running task is closed down gracefully (data caches dump,
241
+ * MMU flushed) and set up the address environment for the new
242
+ * thread at the head of the ready-to-run list.
243
+ */
244
+
245
+ addrenv_switch (NULL );
246
+ #endif
247
+
248
+ /* Record the new "running" task. g_running_tasks[] is only used by
249
+ * assertion logic for reporting crashes.
250
+ */
251
+
252
+ cpu = this_cpu ();
253
+ tcb = current_task (cpu );
254
+ g_running_tasks [cpu ] = tcb ;
255
+
256
+ /* Restore the cpu lock */
257
+
258
+ restore_critical_section (tcb , cpu );
259
+ }
260
+
261
+ return ret_regs ;
262
+ }
263
+
264
+ /****************************************************************************
265
+ * Name: arm64_syscall
266
+ *
267
+ * Description:
268
+ * SVC interrupts will vector here with insn=the SVC instruction and
269
+ * xcp=the interrupt context
270
+ *
271
+ * The handler may get the SVC number be de-referencing the return
272
+ * address saved in the xcp and decoding the SVC instruction
273
+ *
274
+ ****************************************************************************/
275
+
276
+ int arm64_syscall (uint64_t * regs )
277
+ {
278
+ uint64_t cmd ;
279
+ struct regs_context * f_regs ;
280
+ #ifdef CONFIG_BUILD_KERNEL
281
+ uint64_t spsr ;
282
+ #endif
283
+
284
+ /* Nested interrupts are not supported */
285
+
286
+ DEBUGASSERT (regs );
287
+
288
+ f_regs = (struct regs_context * )regs ;
289
+
290
+ /* The SYSCALL command is in x0 on entry. Parameters follow in x1..x7 */
291
+
292
+ cmd = f_regs -> regs [REG_X0 ];
293
+
294
+ arm64_dump_syscall (__func__ , cmd , f_regs );
295
+
296
+ switch (cmd )
297
+ {
226
298
#ifdef CONFIG_BUILD_KERNEL
227
299
/* R0=SYS_signal_handler: This a user signal handler callback
228
300
*
@@ -324,59 +396,11 @@ uint64_t *arm64_syscall(uint64_t *regs)
324
396
break ;
325
397
#endif
326
398
327
- /* This is not an architecture-specific system call. If NuttX is built
328
- * as a standalone kernel with a system call interface, then all of the
329
- * additional system calls must be handled as in the default case.
330
- */
331
-
332
399
default :
333
- {
334
- #ifdef CONFIG_LIB_SYSCALL
335
400
336
- /* Verify that the SYS call number is within range */
337
-
338
- DEBUGASSERT (cmd >= CONFIG_SYS_RESERVED && cmd < SYS_maxsyscall );
339
-
340
- /* Make sure that there is a no saved SYSCALL return address. We
341
- * cannot yet handle nested system calls.
342
- */
343
-
344
- regs [REG_X0 ] = dispatch_syscall (regs [REG_X0 ], regs [REG_X1 ],
345
- regs [REG_X2 ], regs [REG_X3 ],
346
- regs [REG_X4 ], regs [REG_X5 ],
347
- regs [REG_X6 ]);
348
-
349
- #else
350
- svcerr ("ERROR: Bad SYS call: 0x%" PRIx64 "\n" , cmd );
351
- #endif
352
- }
353
- break ;
401
+ DEBUGPANIC ();
402
+ break ;
354
403
}
355
404
356
- if (regs != ret_regs )
357
- {
358
- #ifdef CONFIG_ARCH_ADDRENV
359
- /* Make sure that the address environment for the previously
360
- * running task is closed down gracefully (data caches dump,
361
- * MMU flushed) and set up the address environment for the new
362
- * thread at the head of the ready-to-run list.
363
- */
364
-
365
- addrenv_switch (NULL );
366
- #endif
367
-
368
- /* Record the new "running" task. g_running_tasks[] is only used by
369
- * assertion logic for reporting crashes.
370
- */
371
-
372
- cpu = this_cpu ();
373
- tcb = current_task (cpu );
374
- g_running_tasks [cpu ] = tcb ;
375
-
376
- /* Restore the cpu lock */
377
-
378
- restore_critical_section (tcb , cpu );
379
- }
380
-
381
- return ret_regs ;
405
+ return 0 ;
382
406
}
0 commit comments