source: trunk/libs/newlib/src/libgloss/tic6x/syscalls.c @ 621

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

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

File size: 9.0 KB
Line 
1/* Copyright (c) 2010 CodeSourcery, Inc.
2   All rights reserved.
3
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.
14
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.  */
27
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>
34
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
46
47#define CIOBUFSIZ (BUFSIZ + 32)
48
49struct __attribute__((packed)) cio_open_to_host
50{
51  /* Suggested file descriptor (little endian).  */
52  short fd;
53  /* Flags (little endian).  */
54  short flags;
55};
56
57struct __attribute__((packed)) cio_open_from_host
58{
59  /* File descriptor (little endian).  */
60  short fd;
61};
62
63struct __attribute__((packed)) cio_close_to_host
64{
65  /* File descriptor (little endian).  */
66  short fd;
67};
68
69struct __attribute__((packed)) cio_close_from_host
70{
71  /* Result (little endian).  */
72  short result;
73};
74
75struct __attribute__((packed)) cio_read_to_host
76{
77  /* File descriptor (little endian).  */
78  short fd;
79  /* Length (little endian).  */
80  short length;
81};
82
83struct __attribute__((packed)) cio_read_from_host
84{
85  /* Result (little endian).  */
86  short result;
87};
88
89struct __attribute__((packed)) cio_write_to_host
90{
91  /* File descriptor (little endian).  */
92  short fd;
93  /* Length (little endian).  */
94  short length;
95};
96
97struct __attribute__((packed)) cio_write_from_host
98{
99  /* Result (little endian).  */
100  short result;
101};
102
103struct __attribute__((packed)) cio_lseek_to_host
104{
105  /* File descriptor (little endian).  */
106  short fd;
107  /* Offset (little endian).  */
108  int offset;
109  /* Whence (little endian).  */
110  short whence;
111};
112
113struct __attribute__((packed)) cio_lseek_from_host
114{
115  /* Result (little endian).  */
116  int result;
117};
118
119struct __attribute__((packed)) cio_unlink_to_host
120{
121  /* Empty.  */
122};
123
124struct __attribute__((packed)) cio_unlink_from_host
125{
126  /* Result (little endian).  */
127  short result;
128};
129
130struct __attribute__((packed)) cio_rename_to_host
131{
132  /* Empty.  */
133};
134
135struct __attribute__((packed)) cio_rename_from_host
136{
137  /* Result (little endian).  */
138  short result;
139};
140
141struct __attribute__((packed)) cio_gettime_to_host
142{
143  /* Empty.  */
144};
145
146struct __attribute__((packed)) cio_gettime_from_host
147{
148  /* Time (little endian).  */
149  int time;
150};
151
152struct __attribute__((packed)) cio_getclk_to_host
153{
154  /* Empty.  */
155};
156
157struct __attribute__((packed)) cio_getclk_from_host
158{
159  /* Clock cycles (little endian).  */
160  int result;
161};
162
163struct __attribute__((packed)) cio_to_host
164{
165  /* Data length (target endian).  */
166  unsigned int length;
167  /* Command.  */
168  unsigned char command;
169  /* Parameters.  */
170  union
171  {
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[];
185};
186
187struct __attribute__((packed)) cio_from_host
188{
189  /* Length (target endian).  */
190  unsigned int length;
191  /* Parameters.  */
192  union
193  {
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[];
207};
208
209union
210{
211  unsigned char buf[CIOBUFSIZ];
212  int align;
213  union
214  {
215    struct cio_to_host to_host;
216    struct cio_from_host from_host;
217  } u;
218} _CIOBUF_ __attribute__((section(".cio")));
219
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
227
228static void __attribute__((noinline))
229do_semi_call (void)
230{
231  asm volatile (".globl C$$IO$$\nnop\nC$$IO$$:nop" : "+m" (_CIOBUF_));
232}
233
234static inline void
235semi_call_wrapper (unsigned char command, const char *data,
236                   unsigned int length)
237{
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 ();
243}
244
245static inline void
246semi_call_wrapper2 (unsigned char command, const char *data1,
247                    unsigned int length1, const char *data2,
248                    unsigned int length2)
249{
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 ();
257}
258
259void
260_exit (int status)
261{
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");
265}
266
267int
268open (const char *path, int flags, ...)
269{
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;
281}
282
283int
284close (int fd)
285{
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);
289}
290
291int
292read (int fd, char *ptr, int len)
293{
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);
301}
302
303int
304write (int fd, char *ptr, int len)
305{
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);
312}
313
314int
315lseek (int fd, int offset, int whence)
316{
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);
322}
323
324int
325unlink (const char *path)
326{
327  semi_call_wrapper (_DTUNLINK, path, strlen (path) + 1);
328  return SWAPSHORT (_CIOBUF_.u.from_host.parms.unlink.result);
329}
330
331int
332rename (const char *oldpath, const char *newpath)
333{
334  semi_call_wrapper2 (_DTRENAME, oldpath, strlen (oldpath) + 1,
335                      newpath, strlen (newpath) + 1);
336  return SWAPSHORT (_CIOBUF_.u.from_host.parms.rename.result);
337}
338
339int
340gettimeofday (struct timeval *tp, void *tzvp)
341{
342  struct timezone *tzp = tzvp;
343
344  if (tp)
345    {
346      semi_call_wrapper (_DTGETTIME, NULL, 0);
347      tp->tv_sec = SWAPINT (_CIOBUF_.u.from_host.parms.gettime.time);
348      tp->tv_usec = 0;
349    }
350
351  if (tzp)
352    {
353      tzp->tz_minuteswest = 0;
354      tzp->tz_dsttime = 0;
355    }
356
357  return 0;
358}
359
360clock_t
361clock (void)
362{
363  semi_call_wrapper (_DTGETCLK, NULL, 0);
364  return SWAPINT (_CIOBUF_.u.from_host.parms.getclk.result);
365}
366
367
368int
369isatty (int file __attribute__((unused)))
370{
371  errno = ENOSYS;
372  return 0;
373}
374
375int
376fstat (int fd, struct stat *buf)
377{
378  buf->st_mode = S_IFCHR;       /* Always pretend to be a tty */
379  buf->st_blksize = 0;
380
381  return (0);
382}
Note: See TracBrowser for help on using the repository browser.