OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [arm/] [syscalls.c] - Blame information for rev 617

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/* Support files for GNU libc.  Files in the system namespace go here.
2
   Files in the C namespace (ie those that do not start with an
3
   underscore) go in .c.  */
4
 
5
#include <_ansi.h>
6
#include <sys/types.h>
7
#include <sys/stat.h>
8
#include <sys/fcntl.h>
9
#include <stdio.h>
10
#include <time.h>
11
#include <sys/time.h>
12
#include <sys/times.h>
13
#include <errno.h>
14
#include <reent.h>
15
#include <signal.h>
16
#include <unistd.h>
17
#include <sys/wait.h>
18
#include "swi.h"
19
 
20
/* Forward prototypes.  */
21
int     _system     _PARAMS ((const char *));
22
int     _rename     _PARAMS ((const char *, const char *));
23
int     _isatty         _PARAMS ((int));
24
clock_t _times          _PARAMS ((struct tms *));
25
int     _gettimeofday   _PARAMS ((struct timeval *, void *));
26
void    _raise          _PARAMS ((void));
27
int     _unlink         _PARAMS ((const char *));
28
int     _link           _PARAMS ((void));
29
int     _stat           _PARAMS ((const char *, struct stat *));
30
int     _fstat          _PARAMS ((int, struct stat *));
31
caddr_t _sbrk           _PARAMS ((int));
32
int     _getpid         _PARAMS ((int));
33
int     _kill           _PARAMS ((int, int));
34
void    _exit           _PARAMS ((int));
35
int     _close          _PARAMS ((int));
36
int     _swiclose       _PARAMS ((int));
37
int     _open           _PARAMS ((const char *, int, ...));
38
int     _swiopen        _PARAMS ((const char *, int));
39
int     _write          _PARAMS ((int, char *, int));
40
int     _swiwrite       _PARAMS ((int, char *, int));
41
int     _lseek          _PARAMS ((int, int, int));
42
int     _swilseek       _PARAMS ((int, int, int));
43
int     _read           _PARAMS ((int, char *, int));
44
int     _swiread        _PARAMS ((int, char *, int));
45
void    initialise_monitor_handles _PARAMS ((void));
46
 
47
static int      wrap            _PARAMS ((int));
48
static int      error           _PARAMS ((int));
49
static int      get_errno       _PARAMS ((void));
50
static int      remap_handle    _PARAMS ((int));
51
static int      do_AngelSWI     _PARAMS ((int, void *));
52
static int      findslot        _PARAMS ((int));
53
 
54
/* Register name faking - works in collusion with the linker.  */
55
register char * stack_ptr asm ("sp");
56
 
57
 
58
/* following is copied from libc/stdio/local.h to check std streams */
59
extern void   _EXFUN(__sinit,(struct _reent *));
60
#define CHECK_INIT(ptr) \
61
  do                                            \
62
    {                                           \
63
      if ((ptr) && !(ptr)->__sdidinit)          \
64
        __sinit (ptr);                          \
65
    }                                           \
66
  while (0)
67
 
68
/* Adjust our internal handles to stay away from std* handles.  */
69
#define FILE_HANDLE_OFFSET (0x20)
70
 
71
static int monitor_stdin;
72
static int monitor_stdout;
73
static int monitor_stderr;
74
 
75
/* Struct used to keep track of the file position, just so we
76
   can implement fseek(fh,x,SEEK_CUR).  */
77
typedef struct
78
{
79
  int handle;
80
  int pos;
81
}
82
poslog;
83
 
84
#define MAX_OPEN_FILES 20
85
static poslog openfiles [MAX_OPEN_FILES];
86
 
87
static int
88
findslot (int fh)
89
{
90
  int i;
91
  for (i = 0; i < MAX_OPEN_FILES; i ++)
92
    if (openfiles[i].handle == fh)
93
      break;
94
  return i;
95
}
96
 
97
#ifdef ARM_RDI_MONITOR
98
 
99
static inline int
100
do_AngelSWI (int reason, void * arg)
101
{
102
  int value;
103
  asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0"
104
       : "=r" (value) /* Outputs */
105
       : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
106
       : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
107
                /* Clobbers r0 and r1, and lr if in supervisor mode */);
108
                /* Accordingly to page 13-77 of ARM DUI 0040D other registers
109
                   can also be clobbered.  Some memory positions may also be
110
                   changed by a system call, so they should not be kept in
111
                   registers. Note: we are assuming the manual is right and
112
                   Angel is respecting the APCS.  */
113
  return value;
114
}
115
#endif /* ARM_RDI_MONITOR */
116
 
117
/* Function to convert std(in|out|err) handles to internal versions.  */
118
static int
119
remap_handle (int fh)
120
{
121
  CHECK_INIT(_REENT);
122
 
123
  if (fh == STDIN_FILENO)
124
    return monitor_stdin;
125
  if (fh == STDOUT_FILENO)
126
    return monitor_stdout;
127
  if (fh == STDERR_FILENO)
128
    return monitor_stderr;
129
 
130
  return fh - FILE_HANDLE_OFFSET;
131
}
132
 
133
void
134
initialise_monitor_handles (void)
135
{
136
  int i;
137
 
138
#ifdef ARM_RDI_MONITOR
139
  int volatile block[3];
140
 
141
  block[0] = (int) ":tt";
142
  block[2] = 3;     /* length of filename */
143
  block[1] = 0;     /* mode "r" */
144
  monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
145
 
146
  block[0] = (int) ":tt";
147
  block[2] = 3;     /* length of filename */
148
  block[1] = 4;     /* mode "w" */
149
  monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
150
#else
151
  int fh;
152
  const char * name;
153
 
154
  name = ":tt";
155
  asm ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"
156
       : "=r"(fh)
157
       : "i" (SWI_Open),"r"(name)
158
       : "r0","r1");
159
  monitor_stdin = fh;
160
 
161
  name = ":tt";
162
  asm ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"
163
       : "=r"(fh)
164
       : "i" (SWI_Open),"r"(name)
165
       : "r0","r1");
166
  monitor_stdout = monitor_stderr = fh;
167
#endif
168
 
169
  for (i = 0; i < MAX_OPEN_FILES; i ++)
170
    openfiles[i].handle = -1;
171
 
172
  openfiles[0].handle = monitor_stdin;
173
  openfiles[0].pos = 0;
174
  openfiles[1].handle = monitor_stdout;
175
  openfiles[1].pos = 0;
176
}
177
 
178
static int
179
get_errno (void)
180
{
181
#ifdef ARM_RDI_MONITOR
182
  return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
183
#else
184
  asm ("swi %a0" :: "i" (SWI_GetErrno));
185
#endif
186
}
187
 
188
static int
189
error (int result)
190
{
191
  errno = get_errno ();
192
  return result;
193
}
194
 
195
static int
196
wrap (int result)
197
{
198
  if (result == -1)
199
    return error (-1);
200
  return result;
201
}
202
 
203
/* Returns # chars not! written.  */
204
int
205
_swiread (int file,
206
          char * ptr,
207
          int len)
208
{
209
  int fh = remap_handle (file);
210
#ifdef ARM_RDI_MONITOR
211
  int block[3];
212
 
213
  block[0] = fh;
214
  block[1] = (int) ptr;
215
  block[2] = len;
216
 
217
  return do_AngelSWI (AngelSWI_Reason_Read, block);
218
#else
219
  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
220
       : /* No outputs */
221
       : "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
222
       : "r0","r1","r2");
223
#endif
224
}
225
 
226
int
227
_read (int file,
228
       char * ptr,
229
       int len)
230
{
231
  int slot = findslot (remap_handle (file));
232
  int x = _swiread (file, ptr, len);
233
 
234
  if (x < 0)
235
    return error (-1);
236
 
237
  if (slot != MAX_OPEN_FILES)
238
    openfiles [slot].pos += len - x;
239
 
240
  /* x == len is not an error, at least if we want feof() to work.  */
241
  return len - x;
242
}
243
 
244
int
245
_swilseek (int file,
246
           int ptr,
247
           int dir)
248
{
249
  int res;
250
  int fh = remap_handle (file);
251
  int slot = findslot (fh);
252
#ifdef ARM_RDI_MONITOR
253
  int block[2];
254
#endif
255
 
256
  if (dir == SEEK_CUR)
257
    {
258
      if (slot == MAX_OPEN_FILES)
259
        return -1;
260
      ptr = openfiles[slot].pos + ptr;
261
      dir = SEEK_SET;
262
    }
263
 
264
#ifdef ARM_RDI_MONITOR
265
  if (dir == SEEK_END)
266
    {
267
      block[0] = fh;
268
      ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);
269
    }
270
 
271
  /* This code only does absolute seeks.  */
272
  block[0] = remap_handle (file);
273
  block[1] = ptr;
274
  res = do_AngelSWI (AngelSWI_Reason_Seek, block);
275
#else
276
  if (dir == SEEK_END)
277
    {
278
      asm ("mov r0, %2; swi %a1; mov %0, r0"
279
           : "=r" (res)
280
           : "i" (SWI_Flen), "r" (fh)
281
           : "r0");
282
      ptr += res;
283
    }
284
 
285
  /* This code only does absolute seeks.  */
286
  asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
287
       : "=r" (res)
288
       : "i" (SWI_Seek), "r" (fh), "r" (ptr)
289
       : "r0", "r1");
290
#endif
291
 
292
  if (slot != MAX_OPEN_FILES && res == 0)
293
    openfiles[slot].pos = ptr;
294
 
295
  /* This is expected to return the position in the file.  */
296
  return res == 0 ? ptr : -1;
297
}
298
 
299
int
300
_lseek (int file,
301
        int ptr,
302
        int dir)
303
{
304
  return wrap (_swilseek (file, ptr, dir));
305
}
306
 
307
/* Returns #chars not! written.  */
308
int
309
_swiwrite (
310
           int    file,
311
           char * ptr,
312
           int    len)
313
{
314
  int fh = remap_handle (file);
315
#ifdef ARM_RDI_MONITOR
316
  int block[3];
317
 
318
  block[0] = fh;
319
  block[1] = (int) ptr;
320
  block[2] = len;
321
 
322
  return do_AngelSWI (AngelSWI_Reason_Write, block);
323
#else
324
  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
325
       : /* No outputs */
326
       : "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
327
       : "r0","r1","r2");
328
#endif
329
}
330
 
331
int
332
_write (int    file,
333
        char * ptr,
334
        int    len)
335
{
336
  int slot = findslot (remap_handle (file));
337
  int x = _swiwrite (file, ptr,len);
338
 
339
  if (x == -1 || x == len)
340
    return error (-1);
341
 
342
  if (slot != MAX_OPEN_FILES)
343
    openfiles[slot].pos += len - x;
344
 
345
  return len - x;
346
}
347
 
348
extern int strlen (const char *);
349
 
350
int
351
_swiopen (const char * path,
352
          int          flags)
353
{
354
  int aflags = 0, fh;
355
#ifdef ARM_RDI_MONITOR
356
  int block[3];
357
#endif
358
 
359
  int i = findslot (-1);
360
 
361
  if (i == MAX_OPEN_FILES)
362
    return -1;
363
 
364
  /* The flags are Unix-style, so we need to convert them.  */
365
#ifdef O_BINARY
366
  if (flags & O_BINARY)
367
    aflags |= 1;
368
#endif
369
 
370
  if (flags & O_RDWR)
371
    aflags |= 2;
372
 
373
  if (flags & O_CREAT)
374
    aflags |= 4;
375
 
376
  if (flags & O_TRUNC)
377
    aflags |= 4;
378
 
379
  if (flags & O_APPEND)
380
    {
381
      aflags &= ~4;     /* Can't ask for w AND a; means just 'a'.  */
382
      aflags |= 8;
383
    }
384
 
385
#ifdef ARM_RDI_MONITOR
386
  block[0] = (int) path;
387
  block[2] = strlen (path);
388
  block[1] = aflags;
389
 
390
  fh = do_AngelSWI (AngelSWI_Reason_Open, block);
391
 
392
#else
393
  asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
394
       : "=r"(fh)
395
       : "i" (SWI_Open),"r"(path),"r"(aflags)
396
       : "r0","r1");
397
#endif
398
 
399
  if (fh >= 0)
400
    {
401
      openfiles[i].handle = fh;
402
      openfiles[i].pos = 0;
403
    }
404
 
405
  return fh >= 0 ? fh + FILE_HANDLE_OFFSET : error (fh);
406
}
407
 
408
int
409
_open (const char * path,
410
       int          flags,
411
       ...)
412
{
413
  return wrap (_swiopen (path, flags));
414
}
415
 
416
int
417
_swiclose (int file)
418
{
419
  int myhan = remap_handle (file);
420
  int slot = findslot (myhan);
421
 
422
  if (slot != MAX_OPEN_FILES)
423
    openfiles[slot].handle = -1;
424
 
425
#ifdef ARM_RDI_MONITOR
426
  return do_AngelSWI (AngelSWI_Reason_Close, & myhan);
427
#else
428
  asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
429
#endif
430
}
431
 
432
int
433
_close (int file)
434
{
435
  return wrap (_swiclose (file));
436
}
437
 
438
int
439
_kill (int pid, int sig)
440
{
441
  (void)pid; (void)sig;
442
#ifdef ARM_RDI_MONITOR
443
  /* Note: The pid argument is thrown away.  */
444
  switch (sig) {
445
          case SIGABRT:
446
                  return do_AngelSWI (AngelSWI_Reason_ReportException,
447
                                  (void *) ADP_Stopped_RunTimeError);
448
          default:
449
                  return do_AngelSWI (AngelSWI_Reason_ReportException,
450
                                  (void *) ADP_Stopped_ApplicationExit);
451
  }
452
#else
453
  asm ("swi %a0" :: "i" (SWI_Exit));
454
#endif
455
}
456
 
457
void
458
_exit (int status)
459
{
460
  /* There is only one SWI for both _exit and _kill. For _exit, call
461
     the SWI with the second argument set to -1, an invalid value for
462
     signum, so that the SWI handler can distinguish the two calls.
463
     Note: The RDI implementation of _kill throws away both its
464
     arguments.  */
465
  _kill(status, -1);
466
}
467
 
468
int
469
_getpid (int n)
470
{
471
  return 1;
472
  n = n;
473
}
474
 
475
caddr_t
476
_sbrk (int incr)
477
{
478
  extern char   end asm ("end");        /* Defined by the linker.  */
479
  static char * heap_end;
480
  char *        prev_heap_end;
481
 
482
  if (heap_end == NULL)
483
    heap_end = & end;
484
 
485
  prev_heap_end = heap_end;
486
 
487
  if (heap_end + incr > stack_ptr)
488
    {
489
      /* Some of the libstdc++-v3 tests rely upon detecting
490
         out of memory errors, so do not abort here.  */
491
#if 0
492
      extern void abort (void);
493
 
494
      _write (1, "_sbrk: Heap and stack collision\n", 32);
495
 
496
      abort ();
497
#else
498
      errno = ENOMEM;
499
      return (caddr_t) -1;
500
#endif
501
    }
502
 
503
  heap_end += incr;
504
 
505
  return (caddr_t) prev_heap_end;
506
}
507
 
508
extern void memset (struct stat *, int, unsigned int);
509
 
510
int
511
_fstat (int file, struct stat * st)
512
{
513
  memset (st, 0, sizeof (* st));
514
  st->st_mode = S_IFCHR;
515
  st->st_blksize = 1024;
516
  return 0;
517
  file = file;
518
}
519
 
520
int _stat (const char *fname, struct stat *st)
521
{
522
  int file;
523
 
524
  /* The best we can do is try to open the file readonly.  If it exists,
525
     then we can guess a few things about it.  */
526
  if ((file = _open (fname, O_RDONLY)) < 0)
527
    return -1;
528
 
529
  memset (st, 0, sizeof (* st));
530
  st->st_mode = S_IFREG | S_IREAD;
531
  st->st_blksize = 1024;
532
  _swiclose (file); /* Not interested in the error.  */
533
  return 0;
534
}
535
 
536
int
537
_link (void)
538
{
539
  return -1;
540
}
541
 
542
int
543
_unlink (const char *path)
544
{
545
#ifdef ARM_RDI_MONITOR
546
  int block[2];
547
  block[0] = path;
548
  block[1] = strlen(path);
549
  return wrap (do_AngelSWI (AngelSWI_Reason_Remove, block)) ? -1 : 0;
550
#else  
551
  return -1;
552
#endif
553
}
554
 
555
void
556
_raise (void)
557
{
558
  return;
559
}
560
 
561
int
562
_gettimeofday (struct timeval * tp, void * tzvp)
563
{
564
  struct timezone *tzp = tzvp;
565
  if (tp)
566
    {
567
    /* Ask the host for the seconds since the Unix epoch.  */
568
#ifdef ARM_RDI_MONITOR
569
      tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL);
570
#else
571
      {
572
        int value;
573
        asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");
574
        tp->tv_sec = value;
575
      }
576
#endif
577
      tp->tv_usec = 0;
578
    }
579
 
580
  /* Return fixed data for the timezone.  */
581
  if (tzp)
582
    {
583
      tzp->tz_minuteswest = 0;
584
      tzp->tz_dsttime = 0;
585
    }
586
 
587
  return 0;
588
}
589
 
590
/* Return a clock that ticks at 100Hz.  */
591
clock_t
592
_times (struct tms * tp)
593
{
594
  clock_t timeval;
595
 
596
#ifdef ARM_RDI_MONITOR
597
  timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);
598
#else
599
  asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
600
#endif
601
 
602
  if (tp)
603
    {
604
      tp->tms_utime  = timeval; /* user time */
605
      tp->tms_stime  = 0;        /* system time */
606
      tp->tms_cutime = 0;        /* user time, children */
607
      tp->tms_cstime = 0;        /* system time, children */
608
    }
609
 
610
  return timeval;
611
};
612
 
613
 
614
int
615
_isatty (int fd)
616
{
617
#ifdef ARM_RDI_MONITOR
618
  int fh = remap_handle (fd);
619
  return wrap (do_AngelSWI (AngelSWI_Reason_IsTTY, &fh));
620
#else
621
  return (fd <= 2) ? 1 : 0;  /* one of stdin, stdout, stderr */
622
#endif
623
}
624
 
625
int
626
_system (const char *s)
627
{
628
#ifdef ARM_RDI_MONITOR
629
  int block[2];
630
  int e;
631
 
632
  /* Hmmm.  The ARM debug interface specification doesn't say whether
633
     SYS_SYSTEM does the right thing with a null argument, or assign any
634
     meaning to its return value.  Try to do something reasonable....  */
635
  if (!s)
636
    return 1;  /* maybe there is a shell available? we can hope. :-P */
637
  block[0] = s;
638
  block[1] = strlen (s);
639
  e = wrap (do_AngelSWI (AngelSWI_Reason_System, block));
640
  if ((e >= 0) && (e < 256))
641
    {
642
      /* We have to convert e, an exit status to the encoded status of
643
         the command.  To avoid hard coding the exit status, we simply
644
         loop until we find the right position.  */
645
      int exit_code;
646
 
647
      for (exit_code = e; e && WEXITSTATUS (e) != exit_code; e <<= 1)
648
        continue;
649
    }
650
  return e;
651
#else
652
  if (s == NULL)
653
    return 0;
654
  errno = ENOSYS;
655
  return -1;
656
#endif
657
}
658
 
659
int
660
_rename (const char * oldpath, const char * newpath)
661
{
662
#ifdef ARM_RDI_MONITOR
663
  int block[4];
664
  block[0] = oldpath;
665
  block[1] = strlen(oldpath);
666
  block[2] = newpath;
667
  block[3] = strlen(newpath);
668
  return wrap (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
669
#else  
670
  errno = ENOSYS;
671
  return -1;
672
#endif
673
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.