OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [sys/] [arm/] [syscalls.c] - Blame information for rev 1773

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

Line No. Rev Author Line
1 1010 ivang
/* 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 "swi.h"
16
 
17
/* Forward prototypes.  */
18
int     isatty          _PARAMS ((int));
19
clock_t _times          _PARAMS ((struct tms *));
20
int     _gettimeofday   _PARAMS ((struct timeval *, struct timezone *));
21
void    _raise          _PARAMS ((void));
22
int     _unlink         _PARAMS ((void));
23
int     _link           _PARAMS ((void));
24
int     _fstat          _PARAMS ((int, struct stat *));
25
caddr_t _sbrk           _PARAMS ((int));
26
int     _getpid         _PARAMS ((int));
27
int     _kill           _PARAMS ((int, int));
28
void    _exit           _PARAMS ((int));
29
int     _close          _PARAMS ((int));
30
int     _swiclose       _PARAMS ((int));
31
int     _open           _PARAMS ((const char *, int, ...));
32
int     _swiopen        _PARAMS ((const char *, int));
33
int     _write          _PARAMS ((int, char *, int));
34
int     _swiwrite       _PARAMS ((int, char *, int));
35
int     _lseek          _PARAMS ((int, int, int));
36
int     _swilseek       _PARAMS ((int, int, int));
37
int     _read           _PARAMS ((int, char *, int));
38
int     _swiread        _PARAMS ((int, char *, int));
39
void    initialise_monitor_handles _PARAMS ((void));
40
 
41
static int      wrap            _PARAMS ((int));
42
static int      error           _PARAMS ((int));
43
static int      get_errno       _PARAMS ((void));
44
static int      remap_handle    _PARAMS ((int));
45
static int      do_AngelSWI     _PARAMS ((int, void *));
46
static int      findslot        _PARAMS ((int));
47
 
48
/* Register name faking - works in collusion with the linker.  */
49
register char * stack_ptr asm ("sp");
50
 
51
 
52
/* following is copied from libc/stdio/local.h to check std streams */
53
extern void   _EXFUN(__sinit,(struct _reent *));
54
#define CHECK_INIT(fp) \
55
  do                                    \
56
    {                                   \
57
      if ((fp)->_data == 0)             \
58
        (fp)->_data = _REENT;           \
59
      if (!(fp)->_data->__sdidinit)     \
60
        __sinit ((fp)->_data);          \
61
    }                                   \
62
  while (0)
63
 
64
/* Adjust our internal handles to stay away from std* handles.  */
65
#define FILE_HANDLE_OFFSET (0x20)
66
 
67
static int std_files_checked;
68
static int monitor_stdin;
69
static int monitor_stdout;
70
static int monitor_stderr;
71
 
72
/* Struct used to keep track of the file position, just so we
73
   can implement fseek(fh,x,SEEK_CUR).  */
74
typedef struct
75
{
76
  int handle;
77
  int pos;
78
}
79
poslog;
80
 
81
#define MAX_OPEN_FILES 20
82
static poslog openfiles [MAX_OPEN_FILES];
83
 
84
static int
85
findslot (int fh)
86
{
87
  int i;
88
  for (i = 0; i < MAX_OPEN_FILES; i ++)
89
    if (openfiles[i].handle == fh)
90
      break;
91
  return i;
92
}
93
 
94
#ifdef ARM_RDI_MONITOR
95
 
96
static inline int
97
do_AngelSWI (int reason, void * arg)
98
{
99
  int value;
100
  asm volatile ("mov r0, %1; mov r1, %2; swi %a3; mov %0, r0"
101
       : "=r" (value) /* Outputs */
102
       : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
103
       : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
104
                /* Clobbers r0 and r1, and lr if in supervisor mode */);
105
                /* Accordingly to page 13-77 of ARM DUI 0040D other registers
106
                   can also be clobbered.  Some memory positions may also be
107
                   changed by a system call, so they should not be kept in
108
                   registers. Note: we are assuming the manual is right and
109
                   Angel is respecting the APCS.  */
110
  return value;
111
}
112
#endif /* ARM_RDI_MONITOR */
113
 
114
/* Function to convert std(in|out|err) handles to internal versions.  */
115
static int
116
remap_handle (int fh)
117
{
118
  if (!std_files_checked)
119
    {
120
       CHECK_INIT(stdin);
121
       CHECK_INIT(stdout);
122
       CHECK_INIT(stderr);
123
       std_files_checked = 1;
124
    }
125
  if (fh == __sfileno (stdin))
126
    return monitor_stdin;
127
  if (fh == __sfileno (stdout))
128
    return monitor_stdout;
129
  if (fh == __sfileno (stderr))
130
    return monitor_stderr;
131
 
132
  return fh - FILE_HANDLE_OFFSET;
133
}
134
 
135
void
136
initialise_monitor_handles (void)
137
{
138
  int i;
139
 
140
#ifdef ARM_RDI_MONITOR
141
  int volatile block[3];
142
 
143
  block[0] = (int) ":tt";
144
  block[2] = 3;     /* length of filename */
145
  block[1] = 0;     /* mode "r" */
146
  monitor_stdin = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
147
 
148
  block[0] = (int) ":tt";
149
  block[2] = 3;     /* length of filename */
150
  block[1] = 4;     /* mode "w" */
151
  monitor_stdout = monitor_stderr = do_AngelSWI (AngelSWI_Reason_Open, (void *) block);
152
#else
153
  int fh;
154
  const char * name;
155
 
156
  name = ":tt";
157
  asm ("mov r0,%2; mov r1, #0; swi %a1; mov %0, r0"
158
       : "=r"(fh)
159
       : "i" (SWI_Open),"r"(name)
160
       : "r0","r1");
161
  monitor_stdin = fh;
162
 
163
  name = ":tt";
164
  asm ("mov r0,%2; mov r1, #4; swi %a1; mov %0, r0"
165
       : "=r"(fh)
166
       : "i" (SWI_Open),"r"(name)
167
       : "r0","r1");
168
  monitor_stdout = monitor_stderr = fh;
169
#endif
170
 
171
  for (i = 0; i < MAX_OPEN_FILES; i ++)
172
    openfiles[i].handle = -1;
173
 
174
  openfiles[0].handle = monitor_stdin;
175
  openfiles[0].pos = 0;
176
  openfiles[1].handle = monitor_stdout;
177
  openfiles[1].pos = 0;
178
}
179
 
180
static int
181
get_errno (void)
182
{
183
#ifdef ARM_RDI_MONITOR
184
  return do_AngelSWI (AngelSWI_Reason_Errno, NULL);
185
#else
186
  asm ("swi %a0" :: "i" (SWI_GetErrno));
187
#endif
188
}
189
 
190
static int
191
error (int result)
192
{
193
  errno = get_errno ();
194
  return result;
195
}
196
 
197
static int
198
wrap (int result)
199
{
200
  if (result == -1)
201
    return error (-1);
202
  return result;
203
}
204
 
205
/* Returns # chars not! written.  */
206
int
207
_swiread (int file,
208
          char * ptr,
209
          int len)
210
{
211
  int fh = remap_handle (file);
212
#ifdef ARM_RDI_MONITOR
213
  int block[3];
214
 
215
  block[0] = fh;
216
  block[1] = (int) ptr;
217
  block[2] = len;
218
 
219
  return do_AngelSWI (AngelSWI_Reason_Read, block);
220
#else
221
  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
222
       : /* No outputs */
223
       : "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
224
       : "r0","r1","r2");
225
#endif
226
}
227
 
228
int
229
_read (int file,
230
       char * ptr,
231
       int len)
232
{
233
  int slot = findslot (remap_handle (file));
234
  int x = _swiread (file, ptr, len);
235
 
236
  if (x < 0)
237
    return error (-1);
238
 
239
  if (slot != MAX_OPEN_FILES)
240
    openfiles [slot].pos += len - x;
241
 
242
  /* x == len is not an error, at least if we want feof() to work.  */
243
  return len - x;
244
}
245
 
246
int
247
_swilseek (int file,
248
           int ptr,
249
           int dir)
250
{
251
  int res;
252
  int fh = remap_handle (file);
253
  int slot = findslot (fh);
254
#ifdef ARM_RDI_MONITOR
255
  int block[2];
256
#endif
257
 
258
  if (dir == SEEK_CUR)
259
    {
260
      if (slot == MAX_OPEN_FILES)
261
        return -1;
262
      ptr = openfiles[slot].pos + ptr;
263
      dir = SEEK_SET;
264
    }
265
 
266
#ifdef ARM_RDI_MONITOR
267
  if (dir == SEEK_END)
268
    {
269
      block[0] = fh;
270
      ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);
271
    }
272
 
273
  /* This code only does absolute seeks.  */
274
  block[0] = remap_handle (file);
275
  block[1] = ptr;
276
  res = do_AngelSWI (AngelSWI_Reason_Seek, block);
277
#else
278
  if (dir == SEEK_END)
279
    {
280
      asm ("mov r0, %2; swi %a1; mov %0, r0"
281
           : "=r" (res)
282
           : "i" (SWI_Flen), "r" (fh)
283
           : "r0");
284
      ptr += res;
285
    }
286
 
287
  /* This code only does absolute seeks.  */
288
  asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
289
       : "=r" (res)
290
       : "i" (SWI_Seek), "r" (fh), "r" (ptr)
291
       : "r0", "r1");
292
#endif
293
 
294
  if (slot != MAX_OPEN_FILES && res == 0)
295
    openfiles[slot].pos = ptr;
296
 
297
  /* This is expected to return the position in the file.  */
298
  return res == 0 ? ptr : -1;
299
}
300
 
301
int
302
_lseek (int file,
303
        int ptr,
304
        int dir)
305
{
306
  return wrap (_swilseek (file, ptr, dir));
307
}
308
 
309
/* Returns #chars not! written.  */
310
int
311
_swiwrite (
312
           int    file,
313
           char * ptr,
314
           int    len)
315
{
316
  int fh = remap_handle (file);
317
#ifdef ARM_RDI_MONITOR
318
  int block[3];
319
 
320
  block[0] = fh;
321
  block[1] = (int) ptr;
322
  block[2] = len;
323
 
324
  return do_AngelSWI (AngelSWI_Reason_Write, block);
325
#else
326
  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
327
       : /* No outputs */
328
       : "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
329
       : "r0","r1","r2");
330
#endif
331
}
332
 
333
int
334
_write (int    file,
335
        char * ptr,
336
        int    len)
337
{
338
  int slot = findslot (remap_handle (file));
339
  int x = _swiwrite (file, ptr,len);
340
 
341
  if (x == -1 || x == len)
342
    return error (-1);
343
 
344
  if (slot != MAX_OPEN_FILES)
345
    openfiles[slot].pos += len - x;
346
 
347
  return len - x;
348
}
349
 
350
extern int strlen (const char *);
351
 
352
int
353
_swiopen (const char * path,
354
          int          flags)
355
{
356
  int aflags = 0, fh;
357
#ifdef ARM_RDI_MONITOR
358
  int block[3];
359
#endif
360
 
361
  int i = findslot (-1);
362
 
363
  if (i == MAX_OPEN_FILES)
364
    return -1;
365
 
366
  /* The flags are Unix-style, so we need to convert them.  */
367
#ifdef O_BINARY
368
  if (flags & O_BINARY)
369
    aflags |= 1;
370
#endif
371
 
372
  if (flags & O_RDWR)
373
    aflags |= 2;
374
 
375
  if (flags & O_CREAT)
376
    aflags |= 4;
377
 
378
  if (flags & O_TRUNC)
379
    aflags |= 4;
380
 
381
  if (flags & O_APPEND)
382
    {
383
      aflags &= ~4;     /* Can't ask for w AND a; means just 'a'.  */
384
      aflags |= 8;
385
    }
386
 
387
#ifdef ARM_RDI_MONITOR
388
  block[0] = (int) path;
389
  block[2] = strlen (path);
390
  block[1] = aflags;
391
 
392
  fh = do_AngelSWI (AngelSWI_Reason_Open, block);
393
 
394
#else
395
  asm ("mov r0,%2; mov r1, %3; swi %a1; mov %0, r0"
396
       : "=r"(fh)
397
       : "i" (SWI_Open),"r"(path),"r"(aflags)
398
       : "r0","r1");
399
#endif
400
 
401
  if (fh >= 0)
402
    {
403
      openfiles[i].handle = fh;
404
      openfiles[i].pos = 0;
405
    }
406
 
407
  return fh >= 0 ? fh + FILE_HANDLE_OFFSET : error (fh);
408
}
409
 
410
int
411
_open (const char * path,
412
       int          flags,
413
       ...)
414
{
415
  return wrap (_swiopen (path, flags));
416
}
417
 
418
int
419
_swiclose (int file)
420
{
421
  int myhan = remap_handle (file);
422
  int slot = findslot (myhan);
423
 
424
  if (slot != MAX_OPEN_FILES)
425
    openfiles[slot].handle = -1;
426
 
427
#ifdef ARM_RDI_MONITOR
428
  return do_AngelSWI (AngelSWI_Reason_Close, & myhan);
429
#else
430
  asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
431
#endif
432
}
433
 
434
int
435
_close (int file)
436
{
437
  return wrap (_swiclose (file));
438
}
439
 
440
void
441
_exit (int n)
442
{
443
  /* FIXME: return code is thrown away.  */
444
 
445
#ifdef ARM_RDI_MONITOR
446
  do_AngelSWI (AngelSWI_Reason_ReportException,
447
              (void *) ADP_Stopped_ApplicationExit);
448
#else
449
  asm ("swi %a0" :: "i" (SWI_Exit));
450
#endif
451
  n = n;
452
}
453
 
454
int
455
_kill (int n, int m)
456
{
457
#ifdef ARM_RDI_MONITOR
458
  return do_AngelSWI (AngelSWI_Reason_ReportException,
459
                      (void *) ADP_Stopped_ApplicationExit);
460
#else
461
  asm ("swi %a0" :: "i" (SWI_Exit));
462
#endif
463
  n = n; m = m;
464
}
465
 
466
int
467
_getpid (int n)
468
{
469
  return 1;
470
  n = n;
471
}
472
 
473
extern void abort (void);
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
      _write (1, "_sbrk: Heap and stack collision\n", 32);
490
      abort ();
491
    }
492
 
493
  heap_end += incr;
494
 
495
  return (caddr_t) prev_heap_end;
496
}
497
 
498
extern void memset (struct stat *, int, unsigned int);
499
 
500
int
501
_fstat (int file, struct stat * st)
502
{
503
  memset (st, 0, sizeof (* st));
504
  st->st_mode = S_IFCHR;
505
  st->st_blksize = 1024;
506
  return 0;
507
  file = file;
508
}
509
 
510
int
511
_link (void)
512
{
513
  return -1;
514
}
515
 
516
int
517
_unlink (void)
518
{
519
  return -1;
520
}
521
 
522
void
523
_raise (void)
524
{
525
  return;
526
}
527
 
528
int
529
_gettimeofday (struct timeval * tp, struct timezone * tzp)
530
{
531
 
532
  if (tp)
533
    {
534
    /* Ask the host for the seconds since the Unix epoch.  */
535
#ifdef ARM_RDI_MONITOR
536
      tp->tv_sec = do_AngelSWI (AngelSWI_Reason_Time,NULL);
537
#else
538
      {
539
        int value;
540
        asm ("swi %a1; mov %0, r0" : "=r" (value): "i" (SWI_Time) : "r0");
541
        tp->tv_sec = value;
542
      }
543
#endif
544
      tp->tv_usec = 0;
545
    }
546
 
547
  /* Return fixed data for the timezone.  */
548
  if (tzp)
549
    {
550
      tzp->tz_minuteswest = 0;
551
      tzp->tz_dsttime = 0;
552
    }
553
 
554
  return 0;
555
}
556
 
557
/* Return a clock that ticks at 100Hz.  */
558
clock_t
559
_times (struct tms * tp)
560
{
561
  clock_t timeval;
562
 
563
#ifdef ARM_RDI_MONITOR
564
  timeval = do_AngelSWI (AngelSWI_Reason_Clock,NULL);
565
#else
566
  asm ("swi %a1; mov %0, r0" : "=r" (timeval): "i" (SWI_Clock) : "r0");
567
#endif
568
 
569
  if (tp)
570
    {
571
      tp->tms_utime  = timeval; /* user time */
572
      tp->tms_stime  = 0;        /* system time */
573
      tp->tms_cutime = 0;        /* user time, children */
574
      tp->tms_cstime = 0;        /* system time, children */
575
    }
576
 
577
  return timeval;
578
};
579
 
580
 
581
int
582
isatty (int fd)
583
{
584
  return 1;
585
  fd = fd;
586
}

powered by: WebSVN 2.1.0

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