1 #include <syscall.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <sys/stat.h>
5
6 #include "fileio.h"
7
8 #define SYS_ftruncate 3000
9 #define SYS_isatty 3001
10
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.
14 */
15 extern int _hardware;
16
17 /* _cpu_config==0 => Abel
18 * _cpu_config==1 => Zeta
19 * _cpu_config==2 => Phi
20 */
21 extern int _cpu_config;
22
23 int _use_syscall;
24
25
26 extern int _syscall(int *foo, int ID, ...);
27
28 extern int main(int argc, char **argv);
29
30 static char *args[]={"dummy.exe"};
31
32 extern void _init(void);
33 void _initIO(void);
34
_premain()35 void __attribute__ ((weak)) _premain()
36 {
37 int t;
38 /* we only use syscalls w/Zeta */
39 _use_syscall=(_cpu_config==1);
40 _initIO();
41
42 _init();
43 t=main(1, args);
44 exit(t);
45 for (;;);
46 }
47
48
49 /* NOTE!!!! compiled with -fomit-frame-pointer to make sure that 'status' has the
50 * correct value when breakpointing at _exit
51 */
_exit(int status)52 void __attribute__ ((weak)) _exit (int status)
53 {
54 /* end of the universe, cause memory fault */
55 __asm("breakpoint");
56 for (;;);
57 }
58
_zpu_interrupt(void)59 void __attribute__ ((weak)) _zpu_interrupt(void)
60 {
61 /* not implemented in libgloss */
62 __asm("breakpoint");
63 for (;;);
64 }
65
66
67 int __attribute__ ((weak))
68 _DEFUN (write, (fd, buf, nbytes),
69 int fd _AND
70 char *buf _AND
71 int nbytes)
72 {
73 if (_use_syscall)
74 {
75 int t;
76 int result;
77 result=_syscall(&t, SYS_write, fd, buf, nbytes);
78 errno=t;
79 return result;
80 } else
81 {
82 int i;
83
84 for (i = 0; i < nbytes; i++) {
85 if (*(buf + i) == '\n') {
86 outbyte ('\r');
87 }
88 outbyte (*(buf + i));
89 }
90 return (nbytes);
91 }
92 }
93
94
95 /*
96 * read -- read bytes from the serial port. Ignore fd, since
97 * we only have stdin.
98 */
99 int __attribute__ ((weak))
100 _DEFUN (read, (fd, buf, nbytes),
101 int fd _AND
102 char *buf _AND
103 int nbytes)
104 {
105 if (_use_syscall)
106 {
107 int t;
108 int result;
109 result=_syscall(&t, SYS_read, fd, buf, nbytes);
110 errno=t;
111 return result;
112 } else
113 {
114 int i = 0;
115
116 for (i = 0; i < nbytes; i++) {
117 char t=inbyte();
118
119 if ((t!='\r')&&(t!='\n'))
120 {
121 *(buf + i) = t;
122 outbyte(t); // echo
123 } else
124 {
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;
131 }
132 }
133 return (i);
134 }
135 }
136
137
138
139 /*
140 * open -- open a file descriptor. We don't have a filesystem, so
141 * we return an error.
142 */
open(const char * buf,int flags,int mode,...)143 int __attribute__ ((weak)) open(const char *buf,
144 int flags,
145 int mode,
146 ...)
147 {
148 if (_use_syscall)
149 {
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
156 {
157 errno = EIO;
158 return (-1);
159 }
160 }
161
162
163
164 /*
165 * close -- We don't need to do anything, but pretend we did.
166 */
167 int __attribute__ ((weak))
168 _DEFUN (close ,(fd),
169 int fd)
170 {
171 if (_use_syscall)
172 {
173 int t;
174 int result;
175 result=_syscall(&t, SYS_close, fd);
176 errno=t;
177 return result;
178 } else
179 {
180 return (0);
181 }
182 }
183
184
185
186
187 int __attribute__ ((weak))
ftruncate(int file,off_t length)188 ftruncate (int file, off_t length)
189 {
190 /*
191 if (_use_syscall)
192 {
193 int t;
194 int result;
195 result=_syscall(&t, SYS_ftruncate, file, length);
196 errno=t;
197 return result;
198 } else
199 */
200 {
201 return -1;
202 }
203 }
204
205
206 /*
207 * unlink -- since we have no file system,
208 * we just return an error.
209 */
210 int __attribute__ ((weak))
211 _DEFUN (unlink, (path),
212 char * path)
213 {
214 if (_use_syscall)
215 {
216 int t;
217 int result;
218 result=_syscall(&t, SYS_unlink, path, strlen(path)+1);
219 errno=t;
220 return result;
221 } else
222 {
223 errno = EIO;
224 return (-1);
225 }
226 }
227
228
229 /*
230 * lseek -- Since a serial port is non-seekable, we return an error.
231 */
232 off_t __attribute__ ((weak))
233 _DEFUN (lseek, (fd, offset, whence),
234 int fd _AND
235 off_t offset _AND
236 int whence)
237 {
238 if (_use_syscall)
239 {
240 int t;
241 int result;
242 result=_syscall(&t, SYS_lseek, fd, offset, whence);
243 errno=t;
244 return result;
245 } else
246 {
247 errno = ESPIPE;
248 return ((off_t)-1);
249 }
250 }
251
252 /* we convert from bigendian to smallendian*/
conv(char * a,int len)253 static long conv(char *a, int len)
254 {
255 long t=0;
256 int i;
257 for (i=0; i<len; i++)
258 {
259 t|=(((int)a[i])&0xff)<<((len-1-i)*8);
260 }
261 return t;
262 }
263
convert(struct fio_stat * gdb_stat,struct stat * buf)264 static void convert(struct fio_stat *gdb_stat, struct stat *buf)
265 {
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
284 }
285
286 int __attribute__ ((weak))
287 _DEFUN (fstat, (fd, buf),
288 int fd _AND
289 struct stat *buf)
290 {
291 if (_use_syscall)
292 {
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
301 {
302 /*
303 * fstat -- Since we have no file system, we just return an error.
304 */
305 buf->st_mode = S_IFCHR; /* Always pretend to be a tty */
306 buf->st_blksize = 0;
307
308 return (0);
309 }
310 }
311
312
313 int __attribute__ ((weak))
314 _DEFUN (stat, (path, buf),
315 const char *path _AND
316 struct stat *buf)
317 {
318 if (_use_syscall)
319 {
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
328 {
329 errno = EIO;
330 return (-1);
331 }
332 }
333
334
335
336 int __attribute__ ((weak))
337 _DEFUN (isatty, (fd),
338 int fd)
339 {
340 if (_use_syscall)
341 {
342 int t;
343 int result;
344 result=_syscall(&t, SYS_isatty, fd);
345 errno=t;
346 return result;
347 } else
348 {
349 /*
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.
353 */
354 return (1);
355 }
356 }
357