]> sourceware.org Git - newlib-cygwin.git/blob - libgloss/tic6x/syscalls.c
2010-11-17 Bernd Schmidt <bernds@codesourcery.com>
[newlib-cygwin.git] / libgloss / tic6x / syscalls.c
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
49 struct __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
57 struct __attribute__((packed)) cio_open_from_host
58 {
59 /* File descriptor (little endian). */
60 short fd;
61 };
62
63 struct __attribute__((packed)) cio_close_to_host
64 {
65 /* File descriptor (little endian). */
66 short fd;
67 };
68
69 struct __attribute__((packed)) cio_close_from_host
70 {
71 /* Result (little endian). */
72 short result;
73 };
74
75 struct __attribute__((packed)) cio_read_to_host
76 {
77 /* File descriptor (little endian). */
78 short fd;
79 /* Length (little endian). */
80 short length;
81 };
82
83 struct __attribute__((packed)) cio_read_from_host
84 {
85 /* Result (little endian). */
86 short result;
87 };
88
89 struct __attribute__((packed)) cio_write_to_host
90 {
91 /* File descriptor (little endian). */
92 short fd;
93 /* Length (little endian). */
94 short length;
95 };
96
97 struct __attribute__((packed)) cio_write_from_host
98 {
99 /* Result (little endian). */
100 short result;
101 };
102
103 struct __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
113 struct __attribute__((packed)) cio_lseek_from_host
114 {
115 /* Result (little endian). */
116 int result;
117 };
118
119 struct __attribute__((packed)) cio_unlink_to_host
120 {
121 /* Empty. */
122 };
123
124 struct __attribute__((packed)) cio_unlink_from_host
125 {
126 /* Result (little endian). */
127 short result;
128 };
129
130 struct __attribute__((packed)) cio_rename_to_host
131 {
132 /* Empty. */
133 };
134
135 struct __attribute__((packed)) cio_rename_from_host
136 {
137 /* Result (little endian). */
138 short result;
139 };
140
141 struct __attribute__((packed)) cio_gettime_to_host
142 {
143 /* Empty. */
144 };
145
146 struct __attribute__((packed)) cio_gettime_from_host
147 {
148 /* Time (little endian). */
149 int time;
150 };
151
152 struct __attribute__((packed)) cio_getclk_to_host
153 {
154 /* Empty. */
155 };
156
157 struct __attribute__((packed)) cio_getclk_from_host
158 {
159 /* Clock cycles (little endian). */
160 int result;
161 };
162
163 struct __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
187 struct __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
209 union
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
228 static void __attribute__((noinline))
229 do_semi_call (void)
230 {
231 asm volatile (".globl C$$IO$$\nnop\nC$$IO$$:nop" : "+m" (_CIOBUF_));
232 }
233
234 static inline void
235 semi_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
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)
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
259 void
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
267 int
268 open (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
283 int
284 close (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
291 int
292 read (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
303 int
304 write (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
314 int
315 lseek (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
324 int
325 unlink (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
331 int
332 rename (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
339 int
340 gettimeofday (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
360 clock_t
361 clock (void)
362 {
363 semi_call_wrapper (_DTGETCLK, NULL, 0);
364 return SWAPINT (_CIOBUF_.u.from_host.parms.getclk.result);
365 }
366
367
368 int
369 isatty (int file __attribute__((unused)))
370 {
371 errno = ENOSYS;
372 return 0;
373 }
374
375 int
376 fstat (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 }
This page took 0.052429 seconds and 5 git commands to generate.