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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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