source: trunk/libs/newlib/src/libgloss/visium/syscalls.c @ 546

Last change on this file since 546 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 7.1 KB
Line 
1/* system calls for the Visium processor.
2
3   Copyright (c) 2015 Rolls-Royce Controls and Data Services Limited.
4   All rights reserved.
5
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8
9     * Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11     * Redistributions in binary form must reproduce the above copyright
12       notice, this list of conditions and the following disclaimer in the
13       documentation and/or other materials provided with the distribution.
14     * Neither the name of Rolls-Royce Controls and Data Services Limited nor
15       the names of its contributors may be used to endorse or promote products
16       derived from this software without specific prior written permission.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28   THE POSSIBILITY OF SUCH DAMAGE.  */
29
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <sys/time.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <errno.h>
36#include <stdarg.h>
37#include <string.h>
38#include "io.h"
39#include "syscall.h"
40
41#ifdef TARGET_SIM
42struct file_register2
43{
44  unsigned action;
45  unsigned p1, p2, p3, p4;
46  unsigned error;
47  unsigned retval;
48};
49
50extern struct file_register2 _sim_fileio_register;
51
52static volatile struct file_register2 *const fileio = &_sim_fileio_register;
53
54static int
55do_syscall (unsigned action, unsigned p1, unsigned p2,
56            unsigned p3, unsigned p4, int *error)
57{
58  fileio->p1 = p1;
59  fileio->p2 = p2;
60  fileio->p3 = p3;
61  fileio->p4 = p4;
62  fileio->action = action;
63
64  *error = (int) fileio->error;
65  return (int) fileio->retval;
66}
67#else
68static int
69do_syscall (unsigned action, unsigned p1, unsigned p2,
70            unsigned p3, unsigned p4, int *error)
71{
72  int ret;
73  int err;
74
75  /* There is a two instruction delay after the software interrupt is
76     initiated, to allow it to take effect. */
77
78  asm volatile ("\n\
79        move.l  r1,%3\n\
80        move.l  r2,%4\n\
81        move.l  r3,%5\n\
82        moviu   r5,%%u 0x20002208\n\
83        movil   r5,%%l 0x20002208\n\
84        move.l  r4,%6\n\
85        write.l (r5),%2\n\
86        nop\n\
87        nop\n\
88        move.l  %0,r1\n\
89        move.l  %1,r2"
90        : "=r" (ret), "=r" (err)
91        : "r" (action), "r" (p1), "r" (p2), "r" (p3), "r" (p4)
92        : "r1", "r2", "r3", "r4", "r5");
93
94  *error = err;
95  return ret;
96}
97#endif
98
99int
100close (int fildes)
101{
102  int status;
103  int error;
104
105  status = do_syscall (SYS_close, fildes, 0, 0, 0, &error);
106
107  if (status < 0)
108    errno = __hosted_from_gdb_errno (error);
109
110  return status;
111}
112
113void _exit (int) __attribute ((__noreturn__));
114
115void
116_exit (int code)
117{
118#ifdef TARGET_SIM
119  asm volatile ("stop    0,%0" : : "r" (code & 0xff));
120#else
121  int error;
122  do_syscall (SYS_exit, code, 0, 0, 0, &error);
123#endif
124
125  /* Should never reach this point.  Since this function is not supposed to
126     return, pretend to get stuck in a loop. */
127  while (1)
128    ;
129}
130
131#ifdef TARGET_SIM
132extern long long _sim_cmdline_header;
133
134long long
135_get_cmdline (void)
136{
137  return _sim_cmdline_header;
138}
139#endif
140
141int
142fstat (int fildes, struct stat *st)
143{
144  struct gdb_stat gst;
145  int status;
146  int error;
147
148  status = do_syscall (SYS_fstat, fildes, (unsigned) &gst, 0, 0, &error);
149
150  if (status < 0)
151    errno = __hosted_from_gdb_errno (error);
152  else
153    __hosted_from_gdb_stat (&gst, st);
154
155  return status;
156}
157
158int
159gettimeofday (struct timeval *__p, void *__tz)
160{
161  struct timeval *tv = __p;
162  struct timezone *tz = __tz;
163  struct gdb_timeval gtv;
164  int status;
165  int error;
166
167  status = do_syscall (SYS_gettimeofday, (unsigned) &gtv, 0, 0, 0, &error);
168
169  /* The timezone argument is not really supported so:
170      Local time is GMT, no daylight saving */
171  if (tz)
172    {
173      tz->tz_minuteswest = 0;
174      tz->tz_dsttime = 0;
175    }
176
177  if (status < 0)
178    errno = __hosted_from_gdb_errno (error);
179  else
180    __hosted_from_gdb_timeval (&gtv, tv);
181
182  return status;
183}
184
185int
186isatty (int fildes)
187{
188  int status;
189  int error;
190
191  status = do_syscall (SYS_isatty, fildes, 0, 0, 0, &error);
192
193  if (status == 0)
194    errno = __hosted_from_gdb_errno (error);
195
196  return status;
197}
198
199off_t
200lseek (int fildes, off_t offset, int whence)
201{
202  off_t ret;
203  int error;
204
205  ret = do_syscall (SYS_lseek, fildes, offset,
206                    __hosted_to_gdb_lseek_flags (whence), 0, &error);
207
208  if (ret == (off_t)-1)
209    errno = __hosted_from_gdb_errno (error);
210
211  return ret;
212}
213
214int
215open (const char *path, int oflag, ...)
216{
217  mode_t mode = 0;
218  int status;
219  int error;
220  int len = strlen (path) + 1;
221
222  if (oflag & O_CREAT)
223    {
224      va_list ap;
225      va_start (ap, oflag);
226      mode = va_arg (ap, mode_t);
227      va_end (ap);
228    }
229
230  status = do_syscall (SYS_open, (unsigned) path, len,
231                       __hosted_to_gdb_open_flags (oflag),
232                       __hosted_to_gdb_mode_t (mode), &error);
233
234  if (status < 0)
235    errno = __hosted_from_gdb_errno (error);
236
237  return status;
238}
239
240int
241read (int fildes, void *buf, size_t nbyte)
242{
243  int status;
244  int error;
245
246  status = do_syscall (SYS_read, fildes, (unsigned) buf, nbyte, 0, &error);
247
248  if (status < 0)
249    errno = __hosted_from_gdb_errno (error);
250
251  return status;
252}
253
254int
255rename (const char *old, const char *new)
256{
257  int status;
258  int error;
259  int oldlen = strlen (old) + 1;
260  int newlen = strlen (new) + 1;
261
262  status = do_syscall (SYS_rename, (unsigned) old, oldlen, (unsigned) new,
263                       newlen, &error);
264
265  if (status < 0)
266    errno = __hosted_from_gdb_errno (error);
267
268  return status;
269}
270
271int
272stat (const char *path, struct stat *st)
273{
274  struct gdb_stat gst;
275  int status;
276  int error;
277  int len = strlen (path) + 1;
278
279  status = do_syscall (SYS_stat, (unsigned) path, len, (unsigned) &gst, 0,
280                       &error);
281
282  if (status < 0)
283    errno = __hosted_from_gdb_errno (error);
284  else
285    __hosted_from_gdb_stat (&gst, st);
286
287  return status;
288}
289
290int
291system (const char *string)
292{
293  int status;
294  int error;
295  int len = strlen (string) + 1;
296
297  status = do_syscall (SYS_system, (unsigned) string, len, 0, 0, &error);
298
299  return status;
300}
301
302int
303unlink (const char *path)
304{
305  int status;
306  int error;
307  int len = strlen (path) + 1;
308
309  status = do_syscall (SYS_unlink, (unsigned) path, len, 0, 0, &error);
310
311  if (status < 0)
312    errno = __hosted_from_gdb_errno (error);
313
314  return status;
315}
316
317int
318write (int fildes, const void *buf, size_t nbyte)
319{
320  int status;
321  int error;
322
323  status = do_syscall (SYS_write, fildes, (unsigned) buf, nbyte, 0, &error);
324
325  if (status < 0)
326    errno = __hosted_from_gdb_errno (error);
327
328  return status;
329}
330
331extern clock_t _sim_clock;
332
333clock_t
334clock (void)
335{
336#ifdef TARGET_SIM
337  return _sim_clock;
338#else
339  return (clock_t) -1;
340#endif
341}
Note: See TracBrowser for help on using the repository browser.