fixed more binutils issues (newer gcc/libc)
[zpugcc/jano.git] / toolchain / gcc / libgloss / zpu / syscalls.c
blob2e8eabfdc283b3b02deb2ee4364a065ad6d3ac38
1 #include <syscall.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <sys/stat.h>
6 #include "fileio.h"
8 #define SYS_ftruncate 3000
9 #define SYS_isatty 3001
11 /* Set to 1 if we are running on hardware. The config instruction is
12 * always emulated on the simulator. The emulation code pokes this
13 * variable to 1.
15 extern int _hardware;
17 /* _cpu_config==0 => Abel
18 * _cpu_config==1 => Zeta
19 * _cpu_config==2 => Phi
21 extern int _cpu_config;
23 int _use_syscall;
26 extern int _syscall(int *foo, int ID, ...);
28 extern int main(int argc, char **argv);
30 static char *args[]={"dummy.exe"};
32 extern void _init(void);
33 void _initIO(void);
35 void __attribute__ ((weak)) _premain()
37 int t;
38 /* we only use syscalls w/Zeta */
39 _use_syscall=(_cpu_config==1);
40 _initIO();
42 _init();
43 t=main(1, args);
44 exit(t);
45 for (;;);
49 /* NOTE!!!! compiled with -fomit-frame-pointer to make sure that 'status' has the
50 * correct value when breakpointing at _exit
52 void __attribute__ ((weak)) _exit (int status)
54 /* end of the universe, cause memory fault */
55 __asm("breakpoint");
56 for (;;);
59 void __attribute__ ((weak)) _zpu_interrupt(void)
61 /* not implemented in libgloss */
62 __asm("breakpoint");
63 for (;;);
67 int __attribute__ ((weak))
68 _DEFUN (write, (fd, buf, nbytes),
69 int fd _AND
70 char *buf _AND
71 int nbytes)
73 if (_use_syscall)
75 int t;
76 int result;
77 result=_syscall(&t, SYS_write, fd, buf, nbytes);
78 errno=t;
79 return result;
80 } else
82 int i;
84 for (i = 0; i < nbytes; i++) {
85 if (*(buf + i) == '\n') {
86 outbyte ('\r');
88 outbyte (*(buf + i));
90 return (nbytes);
96 * read -- read bytes from the serial port. Ignore fd, since
97 * we only have stdin.
99 int __attribute__ ((weak))
100 _DEFUN (read, (fd, buf, nbytes),
101 int fd _AND
102 char *buf _AND
103 int nbytes)
105 if (_use_syscall)
107 int t;
108 int result;
109 result=_syscall(&t, SYS_read, fd, buf, nbytes);
110 errno=t;
111 return result;
112 } else
114 int i = 0;
116 for (i = 0; i < nbytes; i++) {
117 char t=inbyte();
119 if ((t!='\r')&&(t!='\n'))
121 *(buf + i) = t;
122 outbyte(t); // echo
123 } else
125 // terminate the line in the way expected by the libraries
126 *(buf + i) = '\n';
127 i++;
128 outbyte('\r');
129 outbyte('\n');
130 break;
133 return (i);
140 * open -- open a file descriptor. We don't have a filesystem, so
141 * we return an error.
143 int __attribute__ ((weak)) open(const char *buf,
144 int flags,
145 int mode,
146 ...)
148 if (_use_syscall)
150 int t;
151 int result;
152 result=_syscall(&t, SYS_open, buf, strlen(buf)+1, flags, mode);
153 errno=t;
154 return result;
155 } else
157 errno = EIO;
158 return (-1);
165 * close -- We don't need to do anything, but pretend we did.
167 int __attribute__ ((weak))
168 _DEFUN (close ,(fd),
169 int fd)
171 if (_use_syscall)
173 int t;
174 int result;
175 result=_syscall(&t, SYS_close, fd);
176 errno=t;
177 return result;
178 } else
180 return (0);
187 int __attribute__ ((weak))
188 ftruncate (int file, off_t length)
191 if (_use_syscall)
193 int t;
194 int result;
195 result=_syscall(&t, SYS_ftruncate, file, length);
196 errno=t;
197 return result;
198 } else
201 return -1;
207 * unlink -- since we have no file system,
208 * we just return an error.
210 int __attribute__ ((weak))
211 _DEFUN (unlink, (path),
212 char * path)
214 if (_use_syscall)
216 int t;
217 int result;
218 result=_syscall(&t, SYS_unlink, path, strlen(path)+1);
219 errno=t;
220 return result;
221 } else
223 errno = EIO;
224 return (-1);
230 * lseek -- Since a serial port is non-seekable, we return an error.
232 off_t __attribute__ ((weak))
233 _DEFUN (lseek, (fd, offset, whence),
234 int fd _AND
235 off_t offset _AND
236 int whence)
238 if (_use_syscall)
240 int t;
241 int result;
242 result=_syscall(&t, SYS_lseek, fd, offset, whence);
243 errno=t;
244 return result;
245 } else
247 errno = ESPIPE;
248 return ((off_t)-1);
252 /* we convert from bigendian to smallendian*/
253 static long conv(char *a, int len)
255 long t=0;
256 int i;
257 for (i=0; i<len; i++)
259 t|=(((int)a[i])&0xff)<<((len-1-i)*8);
261 return t;
264 static void convert(struct fio_stat *gdb_stat, struct stat *buf)
266 memset(buf, 0, sizeof(*buf));
267 buf->st_dev=conv(gdb_stat->fst_dev, sizeof(gdb_stat->fst_dev));
268 buf->st_ino=conv(gdb_stat->fst_ino, sizeof(gdb_stat->fst_ino));
269 buf->st_mode=conv(gdb_stat->fst_mode, sizeof(gdb_stat->fst_mode));
270 buf->st_nlink=conv(gdb_stat->fst_nlink, sizeof(gdb_stat->fst_nlink));
271 buf->st_uid=conv(gdb_stat->fst_uid, sizeof(gdb_stat->fst_uid));
272 buf->st_gid=conv(gdb_stat->fst_gid, sizeof(gdb_stat->fst_gid));
273 buf->st_rdev=conv(gdb_stat->fst_rdev, sizeof(gdb_stat->fst_rdev));
274 buf->st_size=conv(gdb_stat->fst_size, sizeof(gdb_stat->fst_size));
275 #if 0
276 conv_64(fio_ulong_t, &gdb_stat->fst_blksize);
277 conv_64(fio_ulong_t, &gdb_stat->fst_blocks);
278 #endif
279 #if 0
280 conv_time(fst_atime;
281 conv_time(fst_mtime;
282 conv_time(fst_ctime;
283 #endif
286 int __attribute__ ((weak))
287 _DEFUN (fstat, (fd, buf),
288 int fd _AND
289 struct stat *buf)
291 if (_use_syscall)
293 int t;
294 int result;
295 struct fio_stat gdb_stat;
296 result=_syscall(&t, SYS_fstat, fd, &gdb_stat);
297 convert(&gdb_stat, buf);
298 errno=t;
299 return result;
300 } else
303 * fstat -- Since we have no file system, we just return an error.
305 buf->st_mode = S_IFCHR; /* Always pretend to be a tty */
306 buf->st_blksize = 0;
308 return (0);
313 int __attribute__ ((weak))
314 _DEFUN (stat, (path, buf),
315 const char *path _AND
316 struct stat *buf)
318 if (_use_syscall)
320 int t;
321 int result;
322 struct fio_stat gdb_stat;
323 result=_syscall(&t, SYS_stat, path, strlen(path)+1, &gdb_stat);
324 convert(&gdb_stat, buf);
325 errno=t;
326 return result;
327 } else
329 errno = EIO;
330 return (-1);
336 int __attribute__ ((weak))
337 _DEFUN (isatty, (fd),
338 int fd)
340 if (_use_syscall)
342 int t;
343 int result;
344 result=_syscall(&t, SYS_isatty, fd);
345 errno=t;
346 return result;
347 } else
350 * isatty -- returns 1 if connected to a terminal device,
351 * returns 0 if not. Since we're hooked up to a
352 * serial port, we'll say yes _AND return a 1.
354 return (1);