Cygwin: lockf: Fix adding a new lock over multiple locks
[newlib-cygwin.git] / libgloss / tic6x / syscalls.c
blob393fba6613e80f9bff982c288135182644353270
1 /* Copyright (c) 2010 CodeSourcery, Inc.
2 All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 * Neither the name of CodeSourcery nor the
12 names of its contributors may be used to endorse or promote products
13 derived from this software without specific prior written permission.
15 THIS SOFTWARE IS PROVIDED BY CODESOURCERY, INC. ``AS IS'' AND ANY
16 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CODESOURCERY BE LIABLE
19 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 DAMAGE. */
28 #include <stdio.h>
29 #include <string.h>
30 #include <time.h>
31 #include <sys/time.h>
32 #include <sys/stat.h>
33 #include <errno.h>
35 #define _DTOPEN 0xf0
36 #define _DTCLOSE 0xf1
37 #define _DTREAD 0xf2
38 #define _DTWRITE 0xf3
39 #define _DTLSEEK 0xf4
40 #define _DTUNLINK 0xf5
41 #define _DTGETENV 0xf6
42 #define _DTRENAME 0xf7
43 #define _DTGETTIME 0xf8
44 #define _DTGETCLK 0xf9
45 #define _DTSYNC 0xff
47 #define CIOBUFSIZ (BUFSIZ + 32)
49 struct __attribute__((packed)) cio_open_to_host
51 /* Suggested file descriptor (little endian). */
52 short fd;
53 /* Flags (little endian). */
54 short flags;
57 struct __attribute__((packed)) cio_open_from_host
59 /* File descriptor (little endian). */
60 short fd;
63 struct __attribute__((packed)) cio_close_to_host
65 /* File descriptor (little endian). */
66 short fd;
69 struct __attribute__((packed)) cio_close_from_host
71 /* Result (little endian). */
72 short result;
75 struct __attribute__((packed)) cio_read_to_host
77 /* File descriptor (little endian). */
78 short fd;
79 /* Length (little endian). */
80 short length;
83 struct __attribute__((packed)) cio_read_from_host
85 /* Result (little endian). */
86 short result;
89 struct __attribute__((packed)) cio_write_to_host
91 /* File descriptor (little endian). */
92 short fd;
93 /* Length (little endian). */
94 short length;
97 struct __attribute__((packed)) cio_write_from_host
99 /* Result (little endian). */
100 short result;
103 struct __attribute__((packed)) cio_lseek_to_host
105 /* File descriptor (little endian). */
106 short fd;
107 /* Offset (little endian). */
108 int offset;
109 /* Whence (little endian). */
110 short whence;
113 struct __attribute__((packed)) cio_lseek_from_host
115 /* Result (little endian). */
116 int result;
119 struct __attribute__((packed)) cio_unlink_to_host
121 /* Empty. */
124 struct __attribute__((packed)) cio_unlink_from_host
126 /* Result (little endian). */
127 short result;
130 struct __attribute__((packed)) cio_rename_to_host
132 /* Empty. */
135 struct __attribute__((packed)) cio_rename_from_host
137 /* Result (little endian). */
138 short result;
141 struct __attribute__((packed)) cio_gettime_to_host
143 /* Empty. */
146 struct __attribute__((packed)) cio_gettime_from_host
148 /* Time (little endian). */
149 int time;
152 struct __attribute__((packed)) cio_getclk_to_host
154 /* Empty. */
157 struct __attribute__((packed)) cio_getclk_from_host
159 /* Clock cycles (little endian). */
160 int result;
163 struct __attribute__((packed)) cio_to_host
165 /* Data length (target endian). */
166 unsigned int length;
167 /* Command. */
168 unsigned char command;
169 /* Parameters. */
170 union
172 unsigned char buf[8];
173 struct cio_open_to_host open;
174 struct cio_close_to_host close;
175 struct cio_read_to_host read;
176 struct cio_write_to_host write;
177 struct cio_lseek_to_host lseek;
178 struct cio_unlink_to_host unlink;
179 struct cio_rename_to_host rename;
180 struct cio_gettime_to_host gettime;
181 struct cio_getclk_to_host getclk;
182 } parms;
183 /* Variable-length data. */
184 unsigned char data[];
187 struct __attribute__((packed)) cio_from_host
189 /* Length (target endian). */
190 unsigned int length;
191 /* Parameters. */
192 union
194 unsigned char buf[8];
195 struct cio_open_from_host open;
196 struct cio_close_from_host close;
197 struct cio_read_from_host read;
198 struct cio_write_from_host write;
199 struct cio_lseek_from_host lseek;
200 struct cio_unlink_from_host unlink;
201 struct cio_rename_from_host rename;
202 struct cio_gettime_from_host gettime;
203 struct cio_getclk_from_host getclk;
204 } parms;
205 /* Data. */
206 unsigned char data[];
209 union
211 unsigned char buf[CIOBUFSIZ];
212 int align;
213 union
215 struct cio_to_host to_host;
216 struct cio_from_host from_host;
217 } u;
218 } _CIOBUF_ __attribute__((section(".cio")));
220 #ifdef _BIG_ENDIAN
221 #define SWAPSHORT(s) ((short)((((s) & 0xff) << 8) | (((s) & 0xff00) >> 8)))
222 #define SWAPINT(i) (__builtin_bswap32 (i))
223 #else
224 #define SWAPSHORT(s) (s)
225 #define SWAPINT(i) (i)
226 #endif
228 static void __attribute__((noinline))
229 do_semi_call (void)
231 asm volatile (".globl C$$IO$$\nnop\nC$$IO$$:nop" : "+m" (_CIOBUF_));
234 static inline void
235 semi_call_wrapper (unsigned char command, const char *data,
236 unsigned int length)
238 _CIOBUF_.u.to_host.length = length;
239 _CIOBUF_.u.to_host.command = command;
240 if (data != NULL)
241 memcpy (_CIOBUF_.u.to_host.data, data, length);
242 do_semi_call ();
245 static inline void
246 semi_call_wrapper2 (unsigned char command, const char *data1,
247 unsigned int length1, const char *data2,
248 unsigned int length2)
250 _CIOBUF_.u.to_host.length = length1 + length2;
251 _CIOBUF_.u.to_host.command = command;
252 if (data1 != NULL)
253 memcpy (_CIOBUF_.u.to_host.data, data1, length1);
254 if (data2 != NULL)
255 memcpy (_CIOBUF_.u.to_host.data + length1, data2, length2);
256 do_semi_call ();
259 void
260 _exit (int status)
262 /* The semihosting interface appears to provide no way to return an
263 exit status. */
264 asm volatile (".globl C$$EXIT\nnop\nC$$EXIT:nop");
268 open (const char *path, int flags, ...)
270 /* ??? It's not clear what the suggested fd is for. */
271 static short suggest_fd = 3;
272 short ret_fd;
273 ++suggest_fd;
274 _CIOBUF_.u.to_host.parms.open.fd = SWAPSHORT (suggest_fd);
275 _CIOBUF_.u.to_host.parms.open.flags = SWAPSHORT (flags);
276 semi_call_wrapper (_DTOPEN, path, strlen (path) + 1);
277 ret_fd = SWAPSHORT (_CIOBUF_.u.from_host.parms.open.fd);
278 if (ret_fd == -1)
279 return -1;
280 return suggest_fd;
284 close (int fd)
286 _CIOBUF_.u.to_host.parms.close.fd = SWAPSHORT (fd);
287 semi_call_wrapper (_DTCLOSE, NULL, 0);
288 return SWAPSHORT (_CIOBUF_.u.from_host.parms.close.result);
292 read (int fd, char *ptr, int len)
294 if (len > BUFSIZ)
295 len = BUFSIZ;
296 _CIOBUF_.u.to_host.parms.read.fd = SWAPSHORT (fd);
297 _CIOBUF_.u.to_host.parms.read.length = SWAPSHORT (len);
298 semi_call_wrapper (_DTREAD, NULL, 0);
299 memcpy (ptr, _CIOBUF_.u.from_host.data, _CIOBUF_.u.from_host.length);
300 return SWAPSHORT (_CIOBUF_.u.from_host.parms.read.result);
304 write (int fd, char *ptr, int len)
306 if (len > BUFSIZ)
307 len = BUFSIZ;
308 _CIOBUF_.u.to_host.parms.write.fd = SWAPSHORT (fd);
309 _CIOBUF_.u.to_host.parms.write.length = SWAPSHORT (len);
310 semi_call_wrapper (_DTWRITE, ptr, len);
311 return SWAPSHORT (_CIOBUF_.u.from_host.parms.write.result);
315 lseek (int fd, int offset, int whence)
317 _CIOBUF_.u.to_host.parms.lseek.fd = SWAPSHORT (fd);
318 _CIOBUF_.u.to_host.parms.lseek.offset = SWAPINT (offset);
319 _CIOBUF_.u.to_host.parms.lseek.whence = SWAPSHORT (whence);
320 semi_call_wrapper (_DTLSEEK, NULL, 0);
321 return SWAPINT (_CIOBUF_.u.from_host.parms.lseek.result);
325 unlink (const char *path)
327 semi_call_wrapper (_DTUNLINK, path, strlen (path) + 1);
328 return SWAPSHORT (_CIOBUF_.u.from_host.parms.unlink.result);
332 rename (const char *oldpath, const char *newpath)
334 semi_call_wrapper2 (_DTRENAME, oldpath, strlen (oldpath) + 1,
335 newpath, strlen (newpath) + 1);
336 return SWAPSHORT (_CIOBUF_.u.from_host.parms.rename.result);
340 gettimeofday (struct timeval *tp, void *tzvp)
342 struct timezone *tzp = tzvp;
344 if (tp)
346 semi_call_wrapper (_DTGETTIME, NULL, 0);
347 tp->tv_sec = SWAPINT (_CIOBUF_.u.from_host.parms.gettime.time);
348 tp->tv_usec = 0;
351 if (tzp)
353 tzp->tz_minuteswest = 0;
354 tzp->tz_dsttime = 0;
357 return 0;
360 clock_t
361 clock (void)
363 semi_call_wrapper (_DTGETCLK, NULL, 0);
364 return SWAPINT (_CIOBUF_.u.from_host.parms.getclk.result);
369 isatty (int file __attribute__((unused)))
371 errno = ENOSYS;
372 return 0;
376 fstat (int fd, struct stat *buf)
378 buf->st_mode = S_IFCHR; /* Always pretend to be a tty */
379 buf->st_blksize = 0;
381 return (0);