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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [arm/] [armos.c] - Blame information for rev 1783

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

Line No. Rev Author Line
1 1181 sfurman
/*  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 <string.h>
31
#include <fcntl.h>
32
 
33
#ifndef O_RDONLY
34
#define O_RDONLY 0
35
#endif
36
#ifndef O_WRONLY
37
#define O_WRONLY 1
38
#endif
39
#ifndef O_RDWR
40
#define O_RDWR   2
41
#endif
42
#ifndef O_BINARY
43
#define O_BINARY 0
44
#endif
45
 
46
#ifdef __STDC__
47
#define unlink(s) remove(s)
48
#endif
49
 
50
#ifdef HAVE_UNISTD_H
51
#include <unistd.h>             /* For SEEK_SET etc.  */
52
#endif
53
 
54
#ifdef __riscos
55
extern int _fisatty (FILE *);
56
#define isatty_(f) _fisatty(f)
57
#else
58
#ifdef __ZTC__
59
#include <io.h>
60
#define isatty_(f) isatty((f)->_file)
61
#else
62
#ifdef macintosh
63
#include <ioctl.h>
64
#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
65
#else
66
#define isatty_(f) isatty (fileno (f))
67
#endif
68
#endif
69
#endif
70
 
71
#include "armdefs.h"
72
#include "armos.h"
73
#include "armemu.h"
74
 
75
#ifndef NOOS
76
#ifndef VALIDATE
77
/* #ifndef ASIM */
78
#include "armfpe.h"
79
/* #endif */
80
#endif
81
#endif
82
 
83
/* For RDIError_BreakpointReached.  */
84
#include "dbg_rdi.h"
85
 
86
#include "gdb/callback.h"
87
extern host_callback *sim_callback;
88
 
89
extern unsigned ARMul_OSInit       (ARMul_State *);
90
extern void     ARMul_OSExit       (ARMul_State *);
91
extern unsigned ARMul_OSHandleSWI  (ARMul_State *, ARMword);
92
extern unsigned ARMul_OSException  (ARMul_State *, ARMword, ARMword);
93
extern ARMword  ARMul_OSLastErrorP (ARMul_State *);
94
extern ARMword  ARMul_Debug        (ARMul_State *, ARMword, ARMword);
95
 
96
#define BUFFERSIZE 4096
97
#ifndef FOPEN_MAX
98
#define FOPEN_MAX 64
99
#endif
100
#define UNIQUETEMPS 256
101
 
102
/* OS private Information.  */
103
 
104
struct OSblock
105
{
106
  ARMword Time0;
107
  ARMword ErrorP;
108
  ARMword ErrorNo;
109
  FILE *FileTable[FOPEN_MAX];
110
  char FileFlags[FOPEN_MAX];
111
  char *tempnames[UNIQUETEMPS];
112
};
113
 
114
#define NOOP 0
115
#define BINARY 1
116
#define READOP 2
117
#define WRITEOP 4
118
 
119
#ifdef macintosh
120
#define FIXCRLF(t,c) ((t & BINARY) ? \
121
                      c : \
122
                      ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
123
                     )
124
#else
125
#define FIXCRLF(t,c) c
126
#endif
127
 
128
/* Bit mask of enabled SWI implementations.  */
129
unsigned int swi_mask = -1;
130
 
131
 
132
static ARMword softvectorcode[] =
133
{
134
  /* Basic: swi tidyexception + event; mov pc, lr;
135
     ldmia r11,{r11,pc}; swi generateexception  + event.  */
136
  0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
137
  0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
138
  0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
139
  0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
140
  0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
141
  0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
142
  0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
143
  0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
144
  0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
145
  0xe1a0f00e                    /* Default handler */
146
};
147
 
148
/* Time for the Operating System to initialise itself.  */
149
 
150
unsigned
151
ARMul_OSInit (ARMul_State * state)
152
{
153
#ifndef NOOS
154
#ifndef VALIDATE
155
  ARMword instr, i, j;
156
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
157
 
158
  if (state->OSptr == NULL)
159
    {
160
      state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
161
      if (state->OSptr == NULL)
162
        {
163
          perror ("OS Memory");
164
          exit (15);
165
        }
166
    }
167
 
168
  OSptr = (struct OSblock *) state->OSptr;
169
  OSptr->ErrorP = 0;
170
  state->Reg[13] = ADDRSUPERSTACK;                      /* Set up a stack for the current mode...  */
171
  ARMul_SetReg (state, SVC32MODE,   13, ADDRSUPERSTACK);/* ...and for supervisor mode...  */
172
  ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);/* ...and for abort 32 mode...  */
173
  ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode...  */
174
  ARMul_SetReg (state, SYSTEMMODE,  13, ADDRSUPERSTACK);/* ...and for system mode.  */
175
  instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8);           /* Load pc from soft vector */
176
 
177
  for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
178
    /* Write hardware vectors.  */
179
    ARMul_WriteWord (state, i, instr);
180
 
181
  SWI_vector_installed = 0;
182
 
183
  for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
184
    {
185
      ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
186
      ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
187
                       SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
188
    }
189
 
190
  for (i = 0; i < sizeof (softvectorcode); i += 4)
191
    ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
192
 
193
  for (i = 0; i < FOPEN_MAX; i++)
194
    OSptr->FileTable[i] = NULL;
195
 
196
  for (i = 0; i < UNIQUETEMPS; i++)
197
    OSptr->tempnames[i] = NULL;
198
 
199
  ARMul_ConsolePrint (state, ", Demon 1.01");
200
 
201
/* #ifndef ASIM */
202
 
203
  /* Install FPE.  */
204
  for (i = 0; i < fpesize; i += 4)
205
    /* Copy the code.  */
206
    ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
207
 
208
  for (i = FPESTART + fpesize;; i -= 4)
209
    {
210
      /* Reverse the error strings.  */
211
      if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
212
        break;
213
      if (state->bigendSig && j < 0x80000000)
214
        {
215
          /* It's part of the string so swap it.  */
216
          j = ((j >> 0x18) & 0x000000ff) |
217
            ((j >> 0x08) & 0x0000ff00) |
218
            ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
219
          ARMul_WriteWord (state, i, j);
220
        }
221
    }
222
 
223
  /* Copy old illegal instr vector.  */
224
  ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, 4));
225
  /* Install new vector.  */
226
  ARMul_WriteWord (state, 4, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
227
  ARMul_ConsolePrint (state, ", FPE");
228
 
229
/* #endif  ASIM */
230
#endif /* VALIDATE */
231
#endif /* NOOS */
232
 
233
  /* Intel do not want DEMON SWI support.  */
234
   if (state->is_XScale)
235
    swi_mask = SWI_MASK_ANGEL;
236
 
237
   return TRUE;
238
}
239
 
240
void
241
ARMul_OSExit (ARMul_State * state)
242
{
243
  free ((char *) state->OSptr);
244
}
245
 
246
 
247
/* Return the last Operating System Error.  */
248
 
249
ARMword ARMul_OSLastErrorP (ARMul_State * state)
250
{
251
  return ((struct OSblock *) state->OSptr)->ErrorP;
252
}
253
 
254
static int translate_open_mode[] =
255
{
256
  O_RDONLY,                     /* "r"   */
257
  O_RDONLY + O_BINARY,          /* "rb"  */
258
  O_RDWR,                       /* "r+"  */
259
  O_RDWR + O_BINARY,            /* "r+b" */
260
  O_WRONLY + O_CREAT + O_TRUNC, /* "w"   */
261
  O_WRONLY + O_BINARY + O_CREAT + O_TRUNC,      /* "wb"  */
262
  O_RDWR + O_CREAT + O_TRUNC,   /* "w+"  */
263
  O_RDWR + O_BINARY + O_CREAT + O_TRUNC,        /* "w+b" */
264
  O_WRONLY + O_APPEND + O_CREAT,        /* "a"   */
265
  O_WRONLY + O_BINARY + O_APPEND + O_CREAT,     /* "ab"  */
266
  O_RDWR + O_APPEND + O_CREAT,  /* "a+"  */
267
  O_RDWR + O_BINARY + O_APPEND + O_CREAT        /* "a+b" */
268
};
269
 
270
static void
271
SWIWrite0 (ARMul_State * state, ARMword addr)
272
{
273
  ARMword temp;
274
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
275
 
276
  while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
277
    (void) sim_callback->write_stdout (sim_callback, (char *) &temp, 1);
278
 
279
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
280
}
281
 
282
static void
283
WriteCommandLineTo (ARMul_State * state, ARMword addr)
284
{
285
  ARMword temp;
286
  char *cptr = state->CommandLine;
287
 
288
  if (cptr == NULL)
289
    cptr = "\0";
290
  do
291
    {
292
      temp = (ARMword) * cptr++;
293
      ARMul_SafeWriteByte (state, addr++, temp);
294
    }
295
  while (temp != 0);
296
}
297
 
298
static void
299
SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
300
{
301
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
302
  char dummy[2000];
303
  int flags;
304
  int i;
305
 
306
  for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++)
307
    ;
308
 
309
  /* Now we need to decode the Demon open mode.  */
310
  flags = translate_open_mode[SWIflags];
311
 
312
  /* Filename ":tt" is special: it denotes stdin/out.  */
313
  if (strcmp (dummy, ":tt") == 0)
314
    {
315
      if (flags == O_RDONLY)    /* opening tty "r" */
316
        state->Reg[0] = 0;        /* stdin */
317
      else
318
        state->Reg[0] = 1;       /* stdout */
319
    }
320
  else
321
    {
322
      state->Reg[0] = sim_callback->open (sim_callback, dummy, flags);
323
      OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
324
    }
325
}
326
 
327
static void
328
SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
329
{
330
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
331
  int res;
332
  int i;
333
  char *local = malloc (len);
334
 
335
  if (local == NULL)
336
    {
337
      sim_callback->printf_filtered
338
        (sim_callback,
339
         "sim: Unable to read 0x%ulx bytes - out of memory\n",
340
         len);
341
      return;
342
    }
343
 
344
  res = sim_callback->read (sim_callback, f, local, len);
345
  if (res > 0)
346
    for (i = 0; i < res; i++)
347
      ARMul_SafeWriteByte (state, ptr + i, local[i]);
348
 
349
  free (local);
350
  state->Reg[0] = res == -1 ? -1 : len - res;
351
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
352
}
353
 
354
static void
355
SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
356
{
357
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
358
  int res;
359
  ARMword i;
360
  char *local = malloc (len);
361
 
362
  if (local == NULL)
363
    {
364
      sim_callback->printf_filtered
365
        (sim_callback,
366
         "sim: Unable to write 0x%lx bytes - out of memory\n",
367
         (long) len);
368
      return;
369
    }
370
 
371
  for (i = 0; i < len; i++)
372
    local[i] = ARMul_SafeReadByte (state, ptr + i);
373
 
374
  res = sim_callback->write (sim_callback, f, local, len);
375
  state->Reg[0] = res == -1 ? -1 : len - res;
376
  free (local);
377
 
378
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
379
}
380
 
381
static void
382
SWIflen (ARMul_State * state, ARMword fh)
383
{
384
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
385
  ARMword addr;
386
 
387
  if (fh == 0 || fh > FOPEN_MAX)
388
    {
389
      OSptr->ErrorNo = EBADF;
390
      state->Reg[0] = -1L;
391
      return;
392
    }
393
 
394
  addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
395
 
396
  state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
397
  (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
398
 
399
  OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
400
}
401
 
402
/* The emulator calls this routine when a SWI instruction is encuntered.
403
   The parameter passed is the SWI number (lower 24 bits of the instruction).  */
404
 
405
unsigned
406
ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
407
{
408
  struct OSblock * OSptr = (struct OSblock *) state->OSptr;
409
  int              unhandled = FALSE;
410
 
411
  switch (number)
412
    {
413
    case SWI_Read:
414
      if (swi_mask & SWI_MASK_DEMON)
415
        SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
416
      else
417
        unhandled = TRUE;
418
      break;
419
 
420
    case SWI_Write:
421
      if (swi_mask & SWI_MASK_DEMON)
422
        SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
423
      else
424
        unhandled = TRUE;
425
      break;
426
 
427
    case SWI_Open:
428
      if (swi_mask & SWI_MASK_DEMON)
429
        SWIopen (state, state->Reg[0], state->Reg[1]);
430
      else
431
        unhandled = TRUE;
432
      break;
433
 
434
    case SWI_Clock:
435
      if (swi_mask & SWI_MASK_DEMON)
436
        {
437
          /* Return number of centi-seconds.  */
438
          state->Reg[0] =
439
#ifdef CLOCKS_PER_SEC
440
            (CLOCKS_PER_SEC >= 100)
441
            ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
442
            : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
443
#else
444
          /* Presume unix... clock() returns microseconds.  */
445
          (ARMword) (clock () / 10000);
446
#endif
447
          OSptr->ErrorNo = errno;
448
        }
449
      else
450
        unhandled = TRUE;
451
      break;
452
 
453
    case SWI_Time:
454
      if (swi_mask & SWI_MASK_DEMON)
455
        {
456
          state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
457
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
458
        }
459
      else
460
        unhandled = TRUE;
461
      break;
462
 
463
    case SWI_Close:
464
      if (swi_mask & SWI_MASK_DEMON)
465
        {
466
          state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
467
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
468
        }
469
      else
470
        unhandled = TRUE;
471
      break;
472
 
473
    case SWI_Flen:
474
      if (swi_mask & SWI_MASK_DEMON)
475
        SWIflen (state, state->Reg[0]);
476
      else
477
        unhandled = TRUE;
478
      break;
479
 
480
    case SWI_Exit:
481
      if (swi_mask & SWI_MASK_DEMON)
482
        state->Emulate = FALSE;
483
      else
484
        unhandled = TRUE;
485
      break;
486
 
487
    case SWI_Seek:
488
      if (swi_mask & SWI_MASK_DEMON)
489
        {
490
          /* We must return non-zero for failure.  */
491
          state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET);
492
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
493
        }
494
      else
495
        unhandled = TRUE;
496
      break;
497
 
498
    case SWI_WriteC:
499
      if (swi_mask & SWI_MASK_DEMON)
500
        {
501
          char tmp = state->Reg[0];
502
          (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
503
          OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
504
        }
505
      else
506
        unhandled = TRUE;
507
      break;
508
 
509
    case SWI_Write0:
510
      if (swi_mask & SWI_MASK_DEMON)
511
        SWIWrite0 (state, state->Reg[0]);
512
      else
513
        unhandled = TRUE;
514
      break;
515
 
516
    case SWI_GetErrno:
517
      if (swi_mask & SWI_MASK_DEMON)
518
        state->Reg[0] = OSptr->ErrorNo;
519
      else
520
        unhandled = TRUE;
521
      break;
522
 
523
    case SWI_GetEnv:
524
      if (swi_mask & SWI_MASK_DEMON)
525
        {
526
          state->Reg[0] = ADDRCMDLINE;
527
          if (state->MemSize)
528
            state->Reg[1] = state->MemSize;
529
          else
530
            state->Reg[1] = ADDRUSERSTACK;
531
 
532
          WriteCommandLineTo (state, state->Reg[0]);
533
        }
534
      else
535
        unhandled = TRUE;
536
      break;
537
 
538
    case SWI_Breakpoint:
539
      state->EndCondition = RDIError_BreakpointReached;
540
      state->Emulate = FALSE;
541
      break;
542
 
543
      /* Handle Angel SWIs as well as Demon ones.  */
544
    case AngelSWI_ARM:
545
    case AngelSWI_Thumb:
546
      if (swi_mask & SWI_MASK_ANGEL)
547
        {
548
          ARMword addr;
549
          ARMword temp;
550
 
551
          /* R1 is almost always a parameter block.  */
552
          addr = state->Reg[1];
553
          /* R0 is a reason code.  */
554
          switch (state->Reg[0])
555
            {
556
            case -1:
557
              /* This can happen when a SWI is interrupted (eg receiving a
558
                 ctrl-C whilst processing SWIRead()).  The SWI will complete
559
                 returning -1 in r0 to the caller.  If GDB is then used to
560
                 resume the system call the reason code will now be -1.  */
561
              return TRUE;
562
 
563
              /* Unimplemented reason codes.  */
564
            case AngelSWI_Reason_ReadC:
565
            case AngelSWI_Reason_IsTTY:
566
            case AngelSWI_Reason_TmpNam:
567
            case AngelSWI_Reason_Remove:
568
            case AngelSWI_Reason_Rename:
569
            case AngelSWI_Reason_System:
570
            case AngelSWI_Reason_EnterSVC:
571
            default:
572
              state->Emulate = FALSE;
573
              return FALSE;
574
 
575
            case AngelSWI_Reason_Clock:
576
              /* Return number of centi-seconds.  */
577
              state->Reg[0] =
578
#ifdef CLOCKS_PER_SEC
579
                (CLOCKS_PER_SEC >= 100)
580
                ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
581
                : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
582
#else
583
              /* Presume unix... clock() returns microseconds.  */
584
              (ARMword) (clock () / 10000);
585
#endif
586
              OSptr->ErrorNo = errno;
587
              break;
588
 
589
            case AngelSWI_Reason_Time:
590
              state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
591
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
592
              break;
593
 
594
            case AngelSWI_Reason_WriteC:
595
              {
596
                char tmp = ARMul_SafeReadByte (state, addr);
597
                (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
598
                OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
599
                break;
600
              }
601
 
602
            case AngelSWI_Reason_Write0:
603
              SWIWrite0 (state, addr);
604
              break;
605
 
606
            case AngelSWI_Reason_Close:
607
              state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
608
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
609
              break;
610
 
611
            case AngelSWI_Reason_Seek:
612
              state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
613
                                                         ARMul_ReadWord (state, addr + 4),
614
                                                         SEEK_SET);
615
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
616
              break;
617
 
618
            case AngelSWI_Reason_FLen:
619
              SWIflen (state, ARMul_ReadWord (state, addr));
620
              break;
621
 
622
            case AngelSWI_Reason_GetCmdLine:
623
              WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
624
              break;
625
 
626
            case AngelSWI_Reason_HeapInfo:
627
              /* R1 is a pointer to a pointer.  */
628
              addr = ARMul_ReadWord (state, addr);
629
 
630
              /* Pick up the right memory limit.  */
631
              if (state->MemSize)
632
                temp = state->MemSize;
633
              else
634
                temp = ADDRUSERSTACK;
635
 
636
              ARMul_WriteWord (state, addr, 0);          /* Heap base.  */
637
              ARMul_WriteWord (state, addr + 4, temp);  /* Heap limit.  */
638
              ARMul_WriteWord (state, addr + 8, temp);  /* Stack base.  */
639
              ARMul_WriteWord (state, addr + 12, temp); /* Stack limit.  */
640
              break;
641
 
642
            case AngelSWI_Reason_ReportException:
643
              if (state->Reg[1] == ADP_Stopped_ApplicationExit)
644
                state->Reg[0] = 0;
645
              else
646
                state->Reg[0] = -1;
647
              state->Emulate = FALSE;
648
              break;
649
 
650
            case ADP_Stopped_ApplicationExit:
651
              state->Reg[0] = 0;
652
              state->Emulate = FALSE;
653
              break;
654
 
655
            case ADP_Stopped_RunTimeError:
656
              state->Reg[0] = -1;
657
              state->Emulate = FALSE;
658
              break;
659
 
660
            case AngelSWI_Reason_Errno:
661
              state->Reg[0] = OSptr->ErrorNo;
662
              break;
663
 
664
            case AngelSWI_Reason_Open:
665
              SWIopen (state,
666
                       ARMul_ReadWord (state, addr),
667
                       ARMul_ReadWord (state, addr + 4));
668
              break;
669
 
670
            case AngelSWI_Reason_Read:
671
              SWIread (state,
672
                       ARMul_ReadWord (state, addr),
673
                       ARMul_ReadWord (state, addr + 4),
674
                       ARMul_ReadWord (state, addr + 8));
675
              break;
676
 
677
            case AngelSWI_Reason_Write:
678
              SWIwrite (state,
679
                        ARMul_ReadWord (state, addr),
680
                        ARMul_ReadWord (state, addr + 4),
681
                        ARMul_ReadWord (state, addr + 8));
682
              break;
683
            }
684
        }
685
      else
686
        unhandled = TRUE;
687
      break;
688
 
689
    case 0x90:
690
    case 0x91:
691
    case 0x92:
692
      /* These are used by the FPE code.  */
693
      break;
694
 
695
    case -1:
696
      /* This can happen when a SWI is interrupted (eg receiving a
697
         ctrl-C whilst processing SWIRead()).  The SWI will complete
698
         returning -1 in r0 to the caller.  If GDB is then used to
699
         resume the system call the reason code will now be -1.  */
700
      return TRUE;
701
 
702
    case 0x180001: /* RedBoot's Syscall SWI in ARM mode.  */
703
      if (swi_mask & SWI_MASK_REDBOOT)
704
        {
705
          switch (state->Reg[0])
706
            {
707
              /* These numbers are defined in libgloss/syscall.h
708
                 but the simulator should not be dependend upon
709
                 libgloss being installed.  */
710
            case 1:  /* Exit.  */
711
              state->Emulate = FALSE;
712
              /* Copy exit code into r0.  */
713
              state->Reg[0] = state->Reg[1];
714
              break;
715
 
716
            case 2:  /* Open.  */
717
              SWIopen (state, state->Reg[1], state->Reg[2]);
718
              break;
719
 
720
            case 3:  /* Close.  */
721
              state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
722
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
723
              break;
724
 
725
            case 4:  /* Read.  */
726
              SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
727
              break;
728
 
729
            case 5:  /* Write.  */
730
              SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
731
              break;
732
 
733
            case 6:  /* Lseek.  */
734
              state->Reg[0] = sim_callback->lseek (sim_callback,
735
                                                   state->Reg[1],
736
                                                   state->Reg[2],
737
                                                   state->Reg[3]);
738
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
739
              break;
740
 
741
            case 17: /* Utime.  */
742
              state->Reg[0] = (ARMword) sim_callback->time (sim_callback,
743
                                                            (long *) state->Reg[1]);
744
              OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
745
              break;
746
 
747
            case 7:  /* Unlink.  */
748
            case 8:  /* Getpid.  */
749
            case 9:  /* Kill.  */
750
            case 10: /* Fstat.  */
751
            case 11: /* Sbrk.  */
752
            case 12: /* Argvlen.  */
753
            case 13: /* Argv.  */
754
            case 14: /* ChDir.  */
755
            case 15: /* Stat.  */
756
            case 16: /* Chmod.  */
757
            case 18: /* Time.  */
758
              sim_callback->printf_filtered
759
                (sim_callback,
760
                 "sim: unhandled RedBoot syscall '%d' encountered - ignoring\n",
761
                 state->Reg[0]);
762
              return FALSE;
763
 
764
            default:
765
              sim_callback->printf_filtered
766
                (sim_callback,
767
                 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
768
                 state->Reg[0]);
769
              return FALSE;
770
            }
771
          break;
772
        }
773
 
774
    default:
775
      unhandled = TRUE;
776
    }
777
 
778
  if (unhandled)
779
    {
780
      if (SWI_vector_installed)
781
        {
782
          ARMword cpsr;
783
          ARMword i_size;
784
 
785
          cpsr = ARMul_GetCPSR (state);
786
          i_size = INSN_SIZE;
787
 
788
          ARMul_SetSPSR (state, SVC32MODE, cpsr);
789
 
790
          cpsr &= ~0xbf;
791
          cpsr |= SVC32MODE | 0x80;
792
          ARMul_SetCPSR (state, cpsr);
793
 
794
          state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
795
          state->NextInstr            = RESUME;
796
          state->Reg[15]              = state->pc = ARMSWIV;
797
          FLUSHPIPE;
798
        }
799
      else
800
        {
801
          sim_callback->printf_filtered
802
            (sim_callback,
803
             "sim: unknown SWI encountered - %x - ignoring\n",
804
             number);
805
          return FALSE;
806
        }
807
    }
808
 
809
  return TRUE;
810
}
811
 
812
#ifndef NOOS
813
#ifndef ASIM
814
 
815
/* The emulator calls this routine when an Exception occurs.  The second
816
   parameter is the address of the relevant exception vector.  Returning
817
   FALSE from this routine causes the trap to be taken, TRUE causes it to
818
   be ignored (so set state->Emulate to FALSE!).  */
819
 
820
unsigned
821
ARMul_OSException (ARMul_State * state  ATTRIBUTE_UNUSED,
822
                   ARMword       vector ATTRIBUTE_UNUSED,
823
                   ARMword       pc     ATTRIBUTE_UNUSED)
824
{
825
  return FALSE;
826
}
827
 
828
#endif
829
#endif /* NOOS */

powered by: WebSVN 2.1.0

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