1 /* syscalls.c --- implement system calls for the RX simulator.
3 Copyright (C) 2005-2024 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This must come before any other includes. */
30 #include "sim/callback.h"
35 #include "target-newlib-syscall.h"
37 /* The current syscall callbacks we're using. */
38 static struct host_callback_struct
*callbacks
;
41 set_callbacks (struct host_callback_struct
*cb
)
46 struct host_callback_struct
*
53 /* Arguments 1..4 are in R1..R4, remainder on stack.
55 Return value in R1..R4 as needed.
56 structs bigger than 16 bytes: pointer pushed on stack last
58 We only support arguments that fit in general registers.
60 The system call number is in R5. We expect ssycalls to look like
78 return get_reg (argp
);
80 rv
= mem_get_si (get_reg (sp
) + stackp
);
86 read_target (char *buffer
, int address
, int count
, int asciiz
)
91 byte
= mem_get_qi (address
++);
93 if (asciiz
&& (byte
== 0))
100 write_target (char *buffer
, int address
, int count
, int asciiz
)
106 mem_put_qi (address
++, byte
);
107 if (asciiz
&& (byte
== 0))
113 #define PTRSZ (A16 ? 2 : 3)
115 static char *callnames
[] = {
143 static char buf
[256];
149 printf ("\033[31m/* SYSCALL(%d) = %s */\033[0m\n", id
, id
<= TARGET_NEWLIB_SYS_link
? callnames
[id
] : "unknown");
152 case TARGET_NEWLIB_SYS_exit
:
156 printf ("[exit %d]\n", ec
);
157 return RX_MAKE_EXITED (ec
);
161 case TARGET_NEWLIB_SYS_open
:
165 /* The open function is defined as taking a variable number of arguments
166 because the third parameter to it is optional:
167 open (const char * filename, int flags, ...);
168 Hence the oflags and cflags arguments will be on the stack and we need
169 to skip the (empty) argument registers r3 and r4. */
174 read_target (buf
, path
, 256, 1);
176 printf ("open(\"%s\",0x%x,%#o) = ", buf
, oflags
, cflags
);
179 /* The callback vector ignores CFLAGS. */
180 rv
= callbacks
->open (callbacks
, buf
, oflags
);
186 h_oflags
|= O_WRONLY
;
192 h_oflags
|= O_APPEND
;
195 rv
= open (buf
, h_oflags
, cflags
);
203 case TARGET_NEWLIB_SYS_close
:
208 rv
= callbacks
->close (callbacks
, fd
);
214 printf ("close(%d) = %d\n", fd
, rv
);
219 case TARGET_NEWLIB_SYS_read
:
225 if (count
> sizeof (buf
))
226 count
= sizeof (buf
);
228 rv
= callbacks
->read (callbacks
, fd
, buf
, count
);
230 rv
= read (fd
, buf
, count
);
232 printf ("read(%d,%d) = %d\n", fd
, count
, rv
);
234 write_target (buf
, addr
, rv
, 0);
239 case TARGET_NEWLIB_SYS_write
:
245 if (count
> sizeof (buf
))
246 count
= sizeof (buf
);
248 printf ("write(%d,0x%x,%d)\n", fd
, addr
, count
);
249 read_target (buf
, addr
, count
, 0);
253 rv
= callbacks
->write (callbacks
, fd
, buf
, count
);
255 rv
= write (fd
, buf
, count
);
257 printf ("write(%d,%d) = %d\n", fd
, count
, rv
);
262 case TARGET_NEWLIB_SYS_getpid
:
266 case TARGET_NEWLIB_SYS_gettimeofday
:
271 rv
= gettimeofday (&tv
, 0);
273 printf ("gettimeofday: %" PRId64
" sec %" PRId64
" usec to 0x%x\n",
274 (int64_t)tv
.tv_sec
, (int64_t)tv
.tv_usec
, tvaddr
);
275 mem_put_si (tvaddr
, tv
.tv_sec
);
276 mem_put_si (tvaddr
+ 4, tv
.tv_usec
);
281 case TARGET_NEWLIB_SYS_kill
:
288 printf ("[signal %d]\n", sig
);
289 return RX_MAKE_STOPPED (sig
);
296 int heaptop_arg
= arg ();
298 printf ("sbrk: heap top set to %x\n", heaptop_arg
);
299 heaptop
= heaptop_arg
;
301 heapbottom
= heaptop_arg
;
308 mem_put_si (addr
, rx_cycles
+ mem_usage_cycles());
313 return RX_MAKE_STEPPED ();