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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [arm/] [armos.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/*  armos.c -- ARMulator OS interface:  ARM6 Instruction Emulator.
2
    Copyright (C) 1994 Advanced RISC Machines Ltd.
3
 
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8
 
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13
 
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
17
 
18
/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
19
   including all the SWI's required to support the C library. The code in
20
   it is not really for the faint-hearted (especially the abort handling
21
   code), but it is a complete example. Defining NOOS will disable all the
22
   fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
23
   0x11 to halt the emulator.  */
24
 
25
#include "config.h"
26
#include "ansidecl.h"
27
 
28
#include <time.h>
29
#include <errno.h>
30
#include <limits.h>
31
#include <string.h>
32
#include "targ-vals.h"
33
 
34
#ifndef TARGET_O_BINARY
35
#define TARGET_O_BINARY 0
36
#endif
37
 
38
#ifdef HAVE_UNISTD_H
39
#include <unistd.h>             /* For SEEK_SET etc.  */
40
#endif
41
 
42
#ifdef __riscos
43
extern int _fisatty (FILE *);
44
#define isatty_(f) _fisatty(f)
45
#else
46
#ifdef __ZTC__
47
#include <io.h>
48
#define isatty_(f) isatty((f)->_file)
49
#else
50
#ifdef macintosh
51
#include <ioctl.h>
52
#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
53
#else
54
#define isatty_(f) isatty (fileno (f))
55
#endif
56
#endif
57
#endif
58
 
59
#include "armdefs.h"
60
#include "armos.h"
61
#include "armemu.h"
62
 
63
#ifndef NOOS
64
#ifndef VALIDATE
65
/* #ifndef ASIM */
66
#include "armfpe.h"
67
/* #endif */
68
#endif
69
#endif
70
 
71
/* For RDIError_BreakpointReached.  */
72
#include "dbg_rdi.h"
73
 
74
#include "gdb/callback.h"
75
extern host_callback *sim_callback;
76
 
77
extern unsigned ARMul_OSInit       (ARMul_State *);
78
extern void     ARMul_OSExit       (ARMul_State *);
79
extern unsigned ARMul_OSHandleSWI  (ARMul_State *, ARMword);
80
extern unsigned ARMul_OSException  (ARMul_State *, ARMword, ARMword);
81
extern ARMword  ARMul_OSLastErrorP (ARMul_State *);
82
extern ARMword  ARMul_Debug        (ARMul_State *, ARMword, ARMword);
83
 
84
#define BUFFERSIZE 4096
85
#ifndef FOPEN_MAX
86
#define FOPEN_MAX 64
87
#endif
88
#define UNIQUETEMPS 256
89
#ifndef PATH_MAX
90
#define PATH_MAX 1024
91
#endif
92
 
93
/* OS private Information.  */
94
 
95
struct OSblock
96
{
97
  ARMword Time0;
98
  ARMword ErrorP;
99
  ARMword ErrorNo;
100
  FILE *FileTable[FOPEN_MAX];
101
  char FileFlags[FOPEN_MAX];
102
  char *tempnames[UNIQUETEMPS];
103
};
104
 
105
#define NOOP 0
106
#define BINARY 1
107
#define READOP 2
108
#define WRITEOP 4
109
 
110
#ifdef macintosh
111
#define FIXCRLF(t,c) ((t & BINARY) ? \
112
                      c : \
113
                      ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
114
                     )
115
#else
116
#define FIXCRLF(t,c) c
117
#endif
118
 
119
/* Bit mask of enabled SWI implementations.  */
120
unsigned int swi_mask = -1;
121
 
122
 
123
static ARMword softvectorcode[] =
124
{
125
  /* Installed instructions:
126
       swi    tidyexception + event;
127
       mov    lr, pc;
128
       ldmia  fp, {fp, pc};
129
       swi    generateexception  + event.  */
130
  0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
131
  0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
132
  0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
133
  0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
134
  0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
135
  0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
136
  0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
137
  0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
138
  0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
139
  0xe1a0f00e                    /* Default handler */
140
};
141
 
142
/* Time for the Operating System to initialise itself.  */
143
 
144
unsigned
145
ARMul_OSInit (ARMul_State * state)
146
{
147
#ifndef NOOS
148
#ifndef VALIDATE
149
  ARMword instr, i, j;
150
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
151
 
152
  if (state->OSptr == NULL)
153
    {
154
      state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
155
      if (state->OSptr == NULL)
156
        {
157
          perror ("OS Memory");
158
          exit (15);
159
        }
160
    }
161
 
162
  OSptr = (struct OSblock *) state->OSptr;
163
  OSptr->ErrorP = 0;
164
  state->Reg[13] = ADDRSUPERSTACK;                      /* Set up a stack for the current mode...  */
165
  ARMul_SetReg (state, SVC32MODE,   13, ADDRSUPERSTACK);/* ...and for supervisor mode...  */
166
  ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);/* ...and for abort 32 mode...  */
167
  ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode...  */
168
  ARMul_SetReg (state, SYSTEMMODE,  13, ADDRSUPERSTACK);/* ...and for system mode.  */
169
  instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8);           /* Load pc from soft vector */
170
 
171
  for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
172
    /* Write hardware vectors.  */
173
    ARMul_WriteWord (state, i, instr);
174
 
175
  SWI_vector_installed = 0;
176
 
177
  for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
178
    {
179
      ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
180
      ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
181
                       SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
182
    }
183
 
184
  for (i = 0; i < sizeof (softvectorcode); i += 4)
185
    ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
186
 
187
  for (i = 0; i < FOPEN_MAX; i++)
188
    OSptr->FileTable[i] = NULL;
189
 
190
  for (i = 0; i < UNIQUETEMPS; i++)
191
    OSptr->tempnames[i] = NULL;
192
 
193
  ARMul_ConsolePrint (state, ", Demon 1.01");
194
 
195
/* #ifndef ASIM */
196
 
197
  /* Install FPE.  */
198
  for (i = 0; i < fpesize; i += 4)
199
    /* Copy the code.  */
200
    ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
201
 
202
  /* Scan backwards from the end of the code.  */
203
  for (i = FPESTART + fpesize;; i -= 4)
204
    {
205
      /* When we reach the marker value, break out of
206
         the loop, leaving i pointing at the maker.  */
207
      if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
208
        break;
209
 
210
      /* If necessary, reverse the error strings.  */
211
      if (state->bigendSig && j < 0x80000000)
212
        {
213
          /* It's part of the string so swap it.  */
214
          j = ((j >> 0x18) & 0x000000ff) |
215
            ((j >> 0x08) & 0x0000ff00) |
216
            ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
217
          ARMul_WriteWord (state, i, j);
218
        }
219
    }
220
 
221
  /* Copy old illegal instr vector.  */
222
  ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, ARMUndefinedInstrV));
223
  /* Install new vector.  */
224
  ARMul_WriteWord (state, ARMUndefinedInstrV, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
225
  ARMul_ConsolePrint (state, ", FPE");
226
 
227
/* #endif  ASIM */
228
#endif /* VALIDATE */
229
#endif /* NOOS */
230
 
231
  /* Intel do not want DEMON SWI support.  */
232
   if (state->is_XScale)
233
    swi_mask = SWI_MASK_ANGEL;
234
 
235
   return TRUE;
236
}
237
 
238
void
239
ARMul_OSExit (ARMul_State * state)
240
{
241
  free ((char *) state->OSptr);
242
}
243
 
244
 
245
/* Return the last Operating System Error.  */
246
 
247
ARMword ARMul_OSLastErrorP (ARMul_State * state)
248
{
249
  return ((struct OSblock *) state->OSptr)->ErrorP;
250
}
251
 
252
static int translate_open_mode[] =
253
{
254
  TARGET_O_RDONLY,              /* "r"   */
255
  TARGET_O_RDONLY + TARGET_O_BINARY,    /* "rb"  */
256
  TARGET_O_RDWR,                /* "r+"  */
257
  TARGET_O_RDWR + TARGET_O_BINARY,              /* "r+b" */
258
  TARGET_O_WRONLY + TARGET_O_CREAT + TARGET_O_TRUNC,    /* "w"   */
259
  TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC,  /* "wb"  */
260
  TARGET_O_RDWR + TARGET_O_CREAT + TARGET_O_TRUNC,      /* "w+"  */
261
  TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC,    /* "w+b" */
262
  TARGET_O_WRONLY + TARGET_O_APPEND + TARGET_O_CREAT,   /* "a"   */
263
  TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT, /* "ab"  */
264
  TARGET_O_RDWR + TARGET_O_APPEND + TARGET_O_CREAT,     /* "a+"  */
265
  TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT    /* "a+b" */
266
};
267
 
268
static void
269
SWIWrite0 (ARMul_State * state, ARMword addr)
270
{
271
  ARMword temp;
272
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
273
 
274
  while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
275
    {
276
      char buffer = temp;
277
      /* Note - we cannot just cast 'temp' to a (char *) here,
278
         since on a big-endian host the byte value will end
279
         up in the wrong place and a nul character will be printed.  */
280
      (void) sim_callback->write_stdout (sim_callback, & buffer, 1);
281
    }
282
 
283
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
284
}
285
 
286
static void
287
WriteCommandLineTo (ARMul_State * state, ARMword addr)
288
{
289
  ARMword temp;
290
  char *cptr = state->CommandLine;
291
 
292
  if (cptr == NULL)
293
    cptr = "\0";
294
  do
295
    {
296
      temp = (ARMword) * cptr++;
297
      ARMul_SafeWriteByte (state, addr++, temp);
298
    }
299
  while (temp != 0);
300
}
301
 
302
static int
303
ReadFileName (ARMul_State * state, char *buf, ARMword src, size_t n)
304
{
305
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
306
  char *p = buf;
307
 
308
  while (n--)
309
    if ((*p++ = ARMul_SafeReadByte (state, src++)) == '\0')
310
      return 0;
311
  OSptr->ErrorNo = cb_host_to_target_errno (sim_callback, ENAMETOOLONG);
312
  state->Reg[0] = -1;
313
  return -1;
314
}
315
 
316
static void
317
SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
318
{
319
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
320
  char buf[PATH_MAX];
321
  int flags;
322
 
323
  if (ReadFileName (state, buf, name, sizeof buf) == -1)
324
    return;
325
 
326
  /* Now we need to decode the Demon open mode.  */
327
  flags = translate_open_mode[SWIflags];
328
 
329
  /* Filename ":tt" is special: it denotes stdin/out.  */
330
  if (strcmp (buf, ":tt") == 0)
331
    {
332
      if (flags == TARGET_O_RDONLY) /* opening tty "r" */
333
        state->Reg[0] = 0;        /* stdin */
334
      else
335
        state->Reg[0] = 1;       /* stdout */
336
    }
337
  else
338
    {
339
      state->Reg[0] = sim_callback->open (sim_callback, buf, flags);
340
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
341
    }
342
}
343
 
344
static void
345
SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
346
{
347
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
348
  int res;
349
  int i;
350
  char *local = malloc (len);
351
 
352
  if (local == NULL)
353
    {
354
      sim_callback->printf_filtered
355
        (sim_callback,
356
         "sim: Unable to read 0x%ulx bytes - out of memory\n",
357
         len);
358
      return;
359
    }
360
 
361
  res = sim_callback->read (sim_callback, f, local, len);
362
  if (res > 0)
363
    for (i = 0; i < res; i++)
364
      ARMul_SafeWriteByte (state, ptr + i, local[i]);
365
 
366
  free (local);
367
  state->Reg[0] = res == -1 ? -1 : len - res;
368
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
369
}
370
 
371
static void
372
SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
373
{
374
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
375
  int res;
376
  ARMword i;
377
  char *local = malloc (len);
378
 
379
  if (local == NULL)
380
    {
381
      sim_callback->printf_filtered
382
        (sim_callback,
383
         "sim: Unable to write 0x%lx bytes - out of memory\n",
384
         (long) len);
385
      return;
386
    }
387
 
388
  for (i = 0; i < len; i++)
389
    local[i] = ARMul_SafeReadByte (state, ptr + i);
390
 
391
  res = sim_callback->write (sim_callback, f, local, len);
392
  state->Reg[0] = res == -1 ? -1 : len - res;
393
  free (local);
394
 
395
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
396
}
397
 
398
static void
399
SWIflen (ARMul_State * state, ARMword fh)
400
{
401
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
402
  ARMword addr;
403
 
404
  if (fh > FOPEN_MAX)
405
    {
406
      OSptr->ErrorNo = EBADF;
407
      state->Reg[0] = -1L;
408
      return;
409
    }
410
 
411
  addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
412
 
413
  state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
414
  (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
415
 
416
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
417
}
418
 
419
static void
420
SWIremove (ARMul_State * state, ARMword path)
421
{
422
  char buf[PATH_MAX];
423
 
424
  if (ReadFileName (state, buf, path, sizeof buf) != -1)
425
    {
426
      struct OSblock *OSptr = (struct OSblock *) state->OSptr;
427
      state->Reg[0] = sim_callback->unlink (sim_callback, buf);
428
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
429
    }
430
}
431
 
432
static void
433
SWIrename (ARMul_State * state, ARMword old, ARMword new)
434
{
435
  char oldbuf[PATH_MAX], newbuf[PATH_MAX];
436
 
437
  if (ReadFileName (state, oldbuf, old, sizeof oldbuf) != -1
438
      && ReadFileName (state, newbuf, new, sizeof newbuf) != -1)
439
    {
440
      struct OSblock *OSptr = (struct OSblock *) state->OSptr;
441
      state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf);
442
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
443
    }
444
}
445
 
446
/* The emulator calls this routine when a SWI instruction is encuntered.
447
   The parameter passed is the SWI number (lower 24 bits of the instruction).  */
448
 
449
unsigned
450
ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
451
{
452
  struct OSblock * OSptr = (struct OSblock *) state->OSptr;
453
  int              unhandled = FALSE;
454
 
455
  switch (number)
456
    {
457
    case SWI_Read:
458
      if (swi_mask & SWI_MASK_DEMON)
459
        SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
460
      else
461
        unhandled = TRUE;
462
      break;
463
 
464
    case SWI_Write:
465
      if (swi_mask & SWI_MASK_DEMON)
466
        SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
467
      else
468
        unhandled = TRUE;
469
      break;
470
 
471
    case SWI_Open:
472
      if (swi_mask & SWI_MASK_DEMON)
473
        SWIopen (state, state->Reg[0], state->Reg[1]);
474
      else
475
        unhandled = TRUE;
476
      break;
477
 
478
    case SWI_Clock:
479
      if (swi_mask & SWI_MASK_DEMON)
480
        {
481
          /* Return number of centi-seconds.  */
482
          state->Reg[0] =
483
#ifdef CLOCKS_PER_SEC
484
            (CLOCKS_PER_SEC >= 100)
485
            ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
486
            : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
487
#else
488
          /* Presume unix... clock() returns microseconds.  */
489
          (ARMword) (clock () / 10000);
490
#endif
491
          OSptr->ErrorNo = errno;
492
        }
493
      else
494
        unhandled = TRUE;
495
      break;
496
 
497
    case SWI_Time:
498
      if (swi_mask & SWI_MASK_DEMON)
499
        {
500
          state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
501
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
502
        }
503
      else
504
        unhandled = TRUE;
505
      break;
506
 
507
    case SWI_Close:
508
      if (swi_mask & SWI_MASK_DEMON)
509
        {
510
          state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
511
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
512
        }
513
      else
514
        unhandled = TRUE;
515
      break;
516
 
517
    case SWI_Flen:
518
      if (swi_mask & SWI_MASK_DEMON)
519
        SWIflen (state, state->Reg[0]);
520
      else
521
        unhandled = TRUE;
522
      break;
523
 
524
    case SWI_Exit:
525
      if (swi_mask & SWI_MASK_DEMON)
526
        state->Emulate = FALSE;
527
      else
528
        unhandled = TRUE;
529
      break;
530
 
531
    case SWI_Seek:
532
      if (swi_mask & SWI_MASK_DEMON)
533
        {
534
          /* We must return non-zero for failure.  */
535
          state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET);
536
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
537
        }
538
      else
539
        unhandled = TRUE;
540
      break;
541
 
542
    case SWI_WriteC:
543
      if (swi_mask & SWI_MASK_DEMON)
544
        {
545
          char tmp = state->Reg[0];
546
          (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
547
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
548
        }
549
      else
550
        unhandled = TRUE;
551
      break;
552
 
553
    case SWI_Write0:
554
      if (swi_mask & SWI_MASK_DEMON)
555
        SWIWrite0 (state, state->Reg[0]);
556
      else
557
        unhandled = TRUE;
558
      break;
559
 
560
    case SWI_GetErrno:
561
      if (swi_mask & SWI_MASK_DEMON)
562
        state->Reg[0] = OSptr->ErrorNo;
563
      else
564
        unhandled = TRUE;
565
      break;
566
 
567
    case SWI_GetEnv:
568
      if (swi_mask & SWI_MASK_DEMON)
569
        {
570
          state->Reg[0] = ADDRCMDLINE;
571
          if (state->MemSize)
572
            state->Reg[1] = state->MemSize;
573
          else
574
            state->Reg[1] = ADDRUSERSTACK;
575
 
576
          WriteCommandLineTo (state, state->Reg[0]);
577
        }
578
      else
579
        unhandled = TRUE;
580
      break;
581
 
582
    case SWI_Breakpoint:
583
      state->EndCondition = RDIError_BreakpointReached;
584
      state->Emulate = FALSE;
585
      break;
586
 
587
    case SWI_Remove:
588
      if (swi_mask & SWI_MASK_DEMON)
589
        SWIremove (state, state->Reg[0]);
590
      else
591
        unhandled = TRUE;
592
      break;
593
 
594
    case SWI_Rename:
595
      if (swi_mask & SWI_MASK_DEMON)
596
        SWIrename (state, state->Reg[0], state->Reg[1]);
597
      else
598
        unhandled = TRUE;
599
      break;
600
 
601
    case SWI_IsTTY:
602
      if (swi_mask & SWI_MASK_DEMON)
603
        {
604
          state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]);
605
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
606
        }
607
      else
608
        unhandled = TRUE;
609
      break;
610
 
611
      /* Handle Angel SWIs as well as Demon ones.  */
612
    case AngelSWI_ARM:
613
    case AngelSWI_Thumb:
614
      if (swi_mask & SWI_MASK_ANGEL)
615
        {
616
          ARMword addr;
617
          ARMword temp;
618
 
619
          /* R1 is almost always a parameter block.  */
620
          addr = state->Reg[1];
621
          /* R0 is a reason code.  */
622
          switch (state->Reg[0])
623
            {
624
            case -1:
625
              /* This can happen when a SWI is interrupted (eg receiving a
626
                 ctrl-C whilst processing SWIRead()).  The SWI will complete
627
                 returning -1 in r0 to the caller.  If GDB is then used to
628
                 resume the system call the reason code will now be -1.  */
629
              return TRUE;
630
 
631
              /* Unimplemented reason codes.  */
632
            case AngelSWI_Reason_ReadC:
633
            case AngelSWI_Reason_TmpNam:
634
            case AngelSWI_Reason_System:
635
            case AngelSWI_Reason_EnterSVC:
636
            default:
637
              state->Emulate = FALSE;
638
              return FALSE;
639
 
640
            case AngelSWI_Reason_Clock:
641
              /* Return number of centi-seconds.  */
642
              state->Reg[0] =
643
#ifdef CLOCKS_PER_SEC
644
                (CLOCKS_PER_SEC >= 100)
645
                ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
646
                : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
647
#else
648
              /* Presume unix... clock() returns microseconds.  */
649
              (ARMword) (clock () / 10000);
650
#endif
651
              OSptr->ErrorNo = errno;
652
              break;
653
 
654
            case AngelSWI_Reason_Time:
655
              state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
656
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
657
              break;
658
 
659
            case AngelSWI_Reason_WriteC:
660
              {
661
                char tmp = ARMul_SafeReadByte (state, addr);
662
                (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
663
                OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
664
                break;
665
              }
666
 
667
            case AngelSWI_Reason_Write0:
668
              SWIWrite0 (state, addr);
669
              break;
670
 
671
            case AngelSWI_Reason_Close:
672
              state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
673
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
674
              break;
675
 
676
            case AngelSWI_Reason_Seek:
677
              state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
678
                                                         ARMul_ReadWord (state, addr + 4),
679
                                                         SEEK_SET);
680
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
681
              break;
682
 
683
            case AngelSWI_Reason_FLen:
684
              SWIflen (state, ARMul_ReadWord (state, addr));
685
              break;
686
 
687
            case AngelSWI_Reason_GetCmdLine:
688
              WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
689
              break;
690
 
691
            case AngelSWI_Reason_HeapInfo:
692
              /* R1 is a pointer to a pointer.  */
693
              addr = ARMul_ReadWord (state, addr);
694
 
695
              /* Pick up the right memory limit.  */
696
              if (state->MemSize)
697
                temp = state->MemSize;
698
              else
699
                temp = ADDRUSERSTACK;
700
 
701
              ARMul_WriteWord (state, addr, 0);          /* Heap base.  */
702
              ARMul_WriteWord (state, addr + 4, temp);  /* Heap limit.  */
703
              ARMul_WriteWord (state, addr + 8, temp);  /* Stack base.  */
704
              ARMul_WriteWord (state, addr + 12, temp); /* Stack limit.  */
705
              break;
706
 
707
            case AngelSWI_Reason_ReportException:
708
              if (state->Reg[1] == ADP_Stopped_ApplicationExit)
709
                state->Reg[0] = 0;
710
              else
711
                state->Reg[0] = -1;
712
              state->Emulate = FALSE;
713
              break;
714
 
715
            case ADP_Stopped_ApplicationExit:
716
              state->Reg[0] = 0;
717
              state->Emulate = FALSE;
718
              break;
719
 
720
            case ADP_Stopped_RunTimeError:
721
              state->Reg[0] = -1;
722
              state->Emulate = FALSE;
723
              break;
724
 
725
            case AngelSWI_Reason_Errno:
726
              state->Reg[0] = OSptr->ErrorNo;
727
              break;
728
 
729
            case AngelSWI_Reason_Open:
730
              SWIopen (state,
731
                       ARMul_ReadWord (state, addr),
732
                       ARMul_ReadWord (state, addr + 4));
733
              break;
734
 
735
            case AngelSWI_Reason_Read:
736
              SWIread (state,
737
                       ARMul_ReadWord (state, addr),
738
                       ARMul_ReadWord (state, addr + 4),
739
                       ARMul_ReadWord (state, addr + 8));
740
              break;
741
 
742
            case AngelSWI_Reason_Write:
743
              SWIwrite (state,
744
                        ARMul_ReadWord (state, addr),
745
                        ARMul_ReadWord (state, addr + 4),
746
                        ARMul_ReadWord (state, addr + 8));
747
              break;
748
 
749
            case AngelSWI_Reason_IsTTY:
750
              state->Reg[0] = sim_callback->isatty (sim_callback,
751
                                                    ARMul_ReadWord (state, addr));
752
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
753
              break;
754
 
755
            case AngelSWI_Reason_Remove:
756
              SWIremove (state,
757
                         ARMul_ReadWord (state, addr));
758
 
759
            case AngelSWI_Reason_Rename:
760
              SWIrename (state,
761
                         ARMul_ReadWord (state, addr),
762
                         ARMul_ReadWord (state, addr + 4));
763
            }
764
        }
765
      else
766
        unhandled = TRUE;
767
      break;
768
 
769
      /* The following SWIs are generated by the softvectorcode[]
770
         installed by default by the simulator.  */
771
    case 0x91: /* Undefined Instruction.  */
772
      {
773
        ARMword addr = state->RegBank[UNDEFBANK][14] - 4;
774
 
775
        sim_callback->printf_filtered
776
          (sim_callback, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x.  Stopping.\n",
777
           ARMul_ReadWord (state, addr), addr);
778
        state->EndCondition = RDIError_SoftwareInterrupt;
779
        state->Emulate = FALSE;
780
        return FALSE;
781
      }
782
 
783
    case 0x90: /* Reset.  */
784
    case 0x92: /* SWI.  */
785
      /* These two can be safely ignored.  */
786
      break;
787
 
788
    case 0x93: /* Prefetch Abort.  */
789
    case 0x94: /* Data Abort.  */
790
    case 0x95: /* Address Exception.  */
791
    case 0x96: /* IRQ.  */
792
    case 0x97: /* FIQ.  */
793
    case 0x98: /* Error.  */
794
      unhandled = TRUE;
795
      break;
796
 
797
    case -1:
798
      /* This can happen when a SWI is interrupted (eg receiving a
799
         ctrl-C whilst processing SWIRead()).  The SWI will complete
800
         returning -1 in r0 to the caller.  If GDB is then used to
801
         resume the system call the reason code will now be -1.  */
802
      return TRUE;
803
 
804
    case 0x180001: /* RedBoot's Syscall SWI in ARM mode.  */
805
      if (swi_mask & SWI_MASK_REDBOOT)
806
        {
807
          switch (state->Reg[0])
808
            {
809
              /* These numbers are defined in libgloss/syscall.h
810
                 but the simulator should not be dependend upon
811
                 libgloss being installed.  */
812
            case 1:  /* Exit.  */
813
              state->Emulate = FALSE;
814
              /* Copy exit code into r0.  */
815
              state->Reg[0] = state->Reg[1];
816
              break;
817
 
818
            case 2:  /* Open.  */
819
              SWIopen (state, state->Reg[1], state->Reg[2]);
820
              break;
821
 
822
            case 3:  /* Close.  */
823
              state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
824
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
825
              break;
826
 
827
            case 4:  /* Read.  */
828
              SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
829
              break;
830
 
831
            case 5:  /* Write.  */
832
              SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
833
              break;
834
 
835
            case 6:  /* Lseek.  */
836
              state->Reg[0] = sim_callback->lseek (sim_callback,
837
                                                   state->Reg[1],
838
                                                   state->Reg[2],
839
                                                   state->Reg[3]);
840
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
841
              break;
842
 
843
            case 17: /* Utime.  */
844
              state->Reg[0] = (ARMword) sim_callback->time (sim_callback,
845
                                                            (long *) state->Reg[1]);
846
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
847
              break;
848
 
849
            case 7:  /* Unlink.  */
850
            case 8:  /* Getpid.  */
851
            case 9:  /* Kill.  */
852
            case 10: /* Fstat.  */
853
            case 11: /* Sbrk.  */
854
            case 12: /* Argvlen.  */
855
            case 13: /* Argv.  */
856
            case 14: /* ChDir.  */
857
            case 15: /* Stat.  */
858
            case 16: /* Chmod.  */
859
            case 18: /* Time.  */
860
              sim_callback->printf_filtered
861
                (sim_callback,
862
                 "sim: unhandled RedBoot syscall `%d' encountered - "
863
                 "returning ENOSYS\n",
864
                 state->Reg[0]);
865
              state->Reg[0] = -1;
866
              OSptr->ErrorNo = cb_host_to_target_errno
867
                (sim_callback, ENOSYS);
868
              break;
869
            case 1001: /* Meminfo. */
870
              {
871
                ARMword totmem = state->Reg[1],
872
                        topmem = state->Reg[2];
873
                ARMword stack = state->MemSize > 0
874
                  ? state->MemSize : ADDRUSERSTACK;
875
                if (totmem != 0)
876
                  ARMul_WriteWord (state, totmem, stack);
877
                if (topmem != 0)
878
                  ARMul_WriteWord (state, topmem, stack);
879
                state->Reg[0] = 0;
880
                break;
881
              }
882
 
883
            default:
884
              sim_callback->printf_filtered
885
                (sim_callback,
886
                 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
887
                 state->Reg[0]);
888
              return FALSE;
889
            }
890
          break;
891
        }
892
 
893
    default:
894
      unhandled = TRUE;
895
    }
896
 
897
  if (unhandled)
898
    {
899
      if (SWI_vector_installed)
900
        {
901
          ARMword cpsr;
902
          ARMword i_size;
903
 
904
          cpsr = ARMul_GetCPSR (state);
905
          i_size = INSN_SIZE;
906
 
907
          ARMul_SetSPSR (state, SVC32MODE, cpsr);
908
 
909
          cpsr &= ~0xbf;
910
          cpsr |= SVC32MODE | 0x80;
911
          ARMul_SetCPSR (state, cpsr);
912
 
913
          state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
914
          state->NextInstr            = RESUME;
915
          state->Reg[15]              = state->pc = ARMSWIV;
916
          FLUSHPIPE;
917
        }
918
      else
919
        {
920
          sim_callback->printf_filtered
921
            (sim_callback,
922
             "sim: unknown SWI encountered - %x - ignoring\n",
923
             number);
924
          return FALSE;
925
        }
926
    }
927
 
928
  return TRUE;
929
}
930
 
931
#ifndef NOOS
932
#ifndef ASIM
933
 
934
/* The emulator calls this routine when an Exception occurs.  The second
935
   parameter is the address of the relevant exception vector.  Returning
936
   FALSE from this routine causes the trap to be taken, TRUE causes it to
937
   be ignored (so set state->Emulate to FALSE!).  */
938
 
939
unsigned
940
ARMul_OSException (ARMul_State * state  ATTRIBUTE_UNUSED,
941
                   ARMword       vector ATTRIBUTE_UNUSED,
942
                   ARMword       pc     ATTRIBUTE_UNUSED)
943
{
944
  return FALSE;
945
}
946
 
947
#endif
948
#endif /* NOOS */

powered by: WebSVN 2.1.0

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