Cygwin: /proc/<PID>/stat: set field (18) according to scheduling policy
[newlib-cygwin.git] / libgloss / visium / syscalls.c
blobde0ec16fbb301c5a34194f390fe22f18b285a9f4
1 /* system calls for the Visium processor.
3 Copyright (c) 2015 Rolls-Royce Controls and Data Services Limited.
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
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.
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. */
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"
41 #ifdef TARGET_SIM
42 struct file_register2
44 unsigned action;
45 unsigned p1, p2, p3, p4;
46 unsigned error;
47 unsigned retval;
50 extern struct file_register2 _sim_fileio_register;
52 static volatile struct file_register2 *const fileio = &_sim_fileio_register;
54 static int
55 do_syscall (unsigned action, unsigned p1, unsigned p2,
56 unsigned p3, unsigned p4, int *error)
58 fileio->p1 = p1;
59 fileio->p2 = p2;
60 fileio->p3 = p3;
61 fileio->p4 = p4;
62 fileio->action = action;
64 *error = (int) fileio->error;
65 return (int) fileio->retval;
67 #else
68 static int
69 do_syscall (unsigned action, unsigned p1, unsigned p2,
70 unsigned p3, unsigned p4, int *error)
72 int ret;
73 int err;
75 /* There is a two instruction delay after the software interrupt is
76 initiated, to allow it to take effect. */
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");
94 *error = err;
95 return ret;
97 #endif
99 int
100 close (int fildes)
102 int status;
103 int error;
105 status = do_syscall (SYS_close, fildes, 0, 0, 0, &error);
107 if (status < 0)
108 errno = __hosted_from_gdb_errno (error);
110 return status;
113 void _exit (int) __attribute ((__noreturn__));
115 void
116 _exit (int code)
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
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)
131 #ifdef TARGET_SIM
132 extern long long _sim_cmdline_header;
134 long long
135 _get_cmdline (void)
137 return _sim_cmdline_header;
139 #endif
142 fstat (int fildes, struct stat *st)
144 struct gdb_stat gst;
145 int status;
146 int error;
148 status = do_syscall (SYS_fstat, fildes, (unsigned) &gst, 0, 0, &error);
150 if (status < 0)
151 errno = __hosted_from_gdb_errno (error);
152 else
153 __hosted_from_gdb_stat (&gst, st);
155 return status;
159 gettimeofday (struct timeval *__p, void *__tz)
161 struct timeval *tv = __p;
162 struct timezone *tz = __tz;
163 struct gdb_timeval gtv;
164 int status;
165 int error;
167 status = do_syscall (SYS_gettimeofday, (unsigned) &gtv, 0, 0, 0, &error);
169 /* The timezone argument is not really supported so:
170 Local time is GMT, no daylight saving */
171 if (tz)
173 tz->tz_minuteswest = 0;
174 tz->tz_dsttime = 0;
177 if (status < 0)
178 errno = __hosted_from_gdb_errno (error);
179 else
180 __hosted_from_gdb_timeval (&gtv, tv);
182 return status;
186 isatty (int fildes)
188 int status;
189 int error;
191 status = do_syscall (SYS_isatty, fildes, 0, 0, 0, &error);
193 if (status == 0)
194 errno = __hosted_from_gdb_errno (error);
196 return status;
199 off_t
200 lseek (int fildes, off_t offset, int whence)
202 off_t ret;
203 int error;
205 ret = do_syscall (SYS_lseek, fildes, offset,
206 __hosted_to_gdb_lseek_flags (whence), 0, &error);
208 if (ret == (off_t)-1)
209 errno = __hosted_from_gdb_errno (error);
211 return ret;
215 open (const char *path, int oflag, ...)
217 mode_t mode = 0;
218 int status;
219 int error;
220 int len = strlen (path) + 1;
222 if (oflag & O_CREAT)
224 va_list ap;
225 va_start (ap, oflag);
226 mode = va_arg (ap, mode_t);
227 va_end (ap);
230 status = do_syscall (SYS_open, (unsigned) path, len,
231 __hosted_to_gdb_open_flags (oflag),
232 __hosted_to_gdb_mode_t (mode), &error);
234 if (status < 0)
235 errno = __hosted_from_gdb_errno (error);
237 return status;
241 read (int fildes, void *buf, size_t nbyte)
243 int status;
244 int error;
246 status = do_syscall (SYS_read, fildes, (unsigned) buf, nbyte, 0, &error);
248 if (status < 0)
249 errno = __hosted_from_gdb_errno (error);
251 return status;
255 rename (const char *old, const char *new)
257 int status;
258 int error;
259 int oldlen = strlen (old) + 1;
260 int newlen = strlen (new) + 1;
262 status = do_syscall (SYS_rename, (unsigned) old, oldlen, (unsigned) new,
263 newlen, &error);
265 if (status < 0)
266 errno = __hosted_from_gdb_errno (error);
268 return status;
272 stat (const char *path, struct stat *st)
274 struct gdb_stat gst;
275 int status;
276 int error;
277 int len = strlen (path) + 1;
279 status = do_syscall (SYS_stat, (unsigned) path, len, (unsigned) &gst, 0,
280 &error);
282 if (status < 0)
283 errno = __hosted_from_gdb_errno (error);
284 else
285 __hosted_from_gdb_stat (&gst, st);
287 return status;
291 system (const char *string)
293 int status;
294 int error;
295 int len = strlen (string) + 1;
297 status = do_syscall (SYS_system, (unsigned) string, len, 0, 0, &error);
299 return status;
303 unlink (const char *path)
305 int status;
306 int error;
307 int len = strlen (path) + 1;
309 status = do_syscall (SYS_unlink, (unsigned) path, len, 0, 0, &error);
311 if (status < 0)
312 errno = __hosted_from_gdb_errno (error);
314 return status;
318 write (int fildes, const void *buf, size_t nbyte)
320 int status;
321 int error;
323 status = do_syscall (SYS_write, fildes, (unsigned) buf, nbyte, 0, &error);
325 if (status < 0)
326 errno = __hosted_from_gdb_errno (error);
328 return status;
331 extern clock_t _sim_clock;
333 clock_t
334 clock (void)
336 #ifdef TARGET_SIM
337 return _sim_clock;
338 #else
339 return (clock_t) -1;
340 #endif