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

Subversion Repositories or1k

[/] [or1k/] [tags/] [tn_m001/] [gdb-5.0/] [sim/] [arm/] [armos.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/*  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
#ifndef NOOS
74
#ifndef VALIDATE
75
/* #ifndef ASIM */
76
#include "armfpe.h"
77
/* #endif */
78
#endif
79
#endif
80
 
81
/* For RDIError_BreakpointReached.  */
82
#include "dbg_rdi.h"
83
 
84
extern unsigned ARMul_OSInit (ARMul_State * state);
85
extern void ARMul_OSExit (ARMul_State * state);
86
extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
87
extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector,
88
                                   ARMword pc);
89
extern ARMword ARMul_OSLastErrorP (ARMul_State * state);
90
extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr);
91
 
92
#define BUFFERSIZE 4096
93
#ifndef FOPEN_MAX
94
#define FOPEN_MAX 64
95
#endif
96
#define UNIQUETEMPS 256
97
 
98
/***************************************************************************\
99
*                          OS private Information                           *
100
\***************************************************************************/
101
 
102
struct OSblock
103
{
104
  ARMword Time0;
105
  ARMword ErrorP;
106
  ARMword ErrorNo;
107
  FILE *FileTable[FOPEN_MAX];
108
  char FileFlags[FOPEN_MAX];
109
  char *tempnames[UNIQUETEMPS];
110
};
111
 
112
#define NOOP 0
113
#define BINARY 1
114
#define READOP 2
115
#define WRITEOP 4
116
 
117
#ifdef macintosh
118
#define FIXCRLF(t,c) ((t & BINARY) ? \
119
                      c : \
120
                      ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
121
                     )
122
#else
123
#define FIXCRLF(t,c) c
124
#endif
125
 
126
static ARMword softvectorcode[] =
127
{       /* basic: swi tidyexception + event; mov pc, lr;
128
           ldmia r11,{r11,pc}; swi generateexception  + event.  */
129
  0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080,       /*Reset */
130
  0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081,       /*Undef */
131
  0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082,       /*SWI  */
132
  0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083,       /*Prefetch abort */
133
  0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084,       /*Data abort */
134
  0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085,       /*Address exception */
135
  0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /*IRQ*/
136
  0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /*FIQ*/
137
  0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088,       /*Error */
138
  0xe1a0f00e                    /* default handler */
139
};
140
 
141
/***************************************************************************\
142
*            Time for the Operating System to initialise itself.            *
143
\***************************************************************************/
144
 
145
unsigned
146
ARMul_OSInit (ARMul_State * state)
147
{
148
#ifndef NOOS
149
#ifndef VALIDATE
150
  ARMword instr, i, j;
151
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
152
 
153
  if (state->OSptr == NULL)
154
    {
155
      state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
156
      if (state->OSptr == NULL)
157
        {
158
          perror ("OS Memory");
159
          exit (15);
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
  instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8);   /* load pc from soft vector */
169
  for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
170
    ARMul_WriteWord (state, i, instr);  /* write hardware vectors */
171
  for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
172
    {
173
      ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
174
      ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
175
                       SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
176
    }
177
  for (i = 0; i < sizeof (softvectorcode); i += 4)
178
    ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
179
  for (i = 0; i < FOPEN_MAX; i++)
180
    OSptr->FileTable[i] = NULL;
181
  for (i = 0; i < UNIQUETEMPS; i++)
182
    OSptr->tempnames[i] = NULL;
183
  ARMul_ConsolePrint (state, ", Demon 1.01");
184
 
185
/* #ifndef ASIM */
186
 
187
  /* install fpe */
188
  for (i = 0; i < fpesize; i += 4)       /* copy the code */
189
    ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
190
  for (i = FPESTART + fpesize;; i -= 4)
191
    {                           /* reverse the error strings */
192
      if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
193
        break;
194
      if (state->bigendSig && j < 0x80000000)
195
        {                       /* it's part of the string so swap it */
196
          j = ((j >> 0x18) & 0x000000ff) |
197
            ((j >> 0x08) & 0x0000ff00) |
198
            ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
199
          ARMul_WriteWord (state, i, j);
200
        }
201
    }
202
  ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, 4));       /* copy old illegal instr vector */
203
  ARMul_WriteWord (state, 4, FPENEWVECT (ARMul_ReadWord (state, i - 4)));       /* install new vector */
204
  ARMul_ConsolePrint (state, ", FPE");
205
 
206
/* #endif  ASIM */
207
#endif /* VALIDATE */
208
#endif /* NOOS */
209
 
210
  return (TRUE);
211
}
212
 
213
void
214
ARMul_OSExit (ARMul_State * state)
215
{
216
  free ((char *) state->OSptr);
217
}
218
 
219
 
220
/***************************************************************************\
221
*                  Return the last Operating System Error.                  *
222
\***************************************************************************/
223
 
224
ARMword ARMul_OSLastErrorP (ARMul_State * state)
225
{
226
  return ((struct OSblock *) state->OSptr)->ErrorP;
227
}
228
 
229
static int translate_open_mode[] = {
230
  O_RDONLY,                     /* "r"   */
231
  O_RDONLY + O_BINARY,          /* "rb"  */
232
  O_RDWR,                       /* "r+"  */
233
  O_RDWR + O_BINARY,            /* "r+b" */
234
  O_WRONLY + O_CREAT + O_TRUNC, /* "w"   */
235
  O_WRONLY + O_BINARY + O_CREAT + O_TRUNC,      /* "wb"  */
236
  O_RDWR + O_CREAT + O_TRUNC,   /* "w+"  */
237
  O_RDWR + O_BINARY + O_CREAT + O_TRUNC,        /* "w+b" */
238
  O_WRONLY + O_APPEND + O_CREAT,        /* "a"   */
239
  O_WRONLY + O_BINARY + O_APPEND + O_CREAT,     /* "ab"  */
240
  O_RDWR + O_APPEND + O_CREAT,  /* "a+"  */
241
  O_RDWR + O_BINARY + O_APPEND + O_CREAT        /* "a+b" */
242
};
243
 
244
static void
245
SWIWrite0 (ARMul_State * state, ARMword addr)
246
{
247
  ARMword temp;
248
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
249
 
250
  while ((temp = ARMul_ReadByte (state, addr++)) != 0)
251
    (void) fputc ((char) temp, stdout);
252
 
253
  OSptr->ErrorNo = errno;
254
}
255
 
256
static void
257
WriteCommandLineTo (ARMul_State * state, ARMword addr)
258
{
259
  ARMword temp;
260
  char *cptr = state->CommandLine;
261
  if (cptr == NULL)
262
    cptr = "\0";
263
  do
264
    {
265
      temp = (ARMword) * cptr++;
266
      ARMul_WriteByte (state, addr++, temp);
267
    }
268
  while (temp != 0);
269
}
270
 
271
static void
272
SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
273
{
274
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
275
  char dummy[2000];
276
  int flags;
277
  int i;
278
 
279
  for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++)
280
    ;
281
 
282
  /* Now we need to decode the Demon open mode */
283
  flags = translate_open_mode[SWIflags];
284
 
285
  /* Filename ":tt" is special: it denotes stdin/out */
286
  if (strcmp (dummy, ":tt") == 0)
287
    {
288
      if (flags == O_RDONLY)    /* opening tty "r" */
289
        state->Reg[0] = 0;        /* stdin */
290
      else
291
        state->Reg[0] = 1;       /* stdout */
292
    }
293
  else
294
    {
295
      state->Reg[0] = (int) open (dummy, flags, 0666);
296
      OSptr->ErrorNo = errno;
297
    }
298
}
299
 
300
static void
301
SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
302
{
303
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
304
  int res;
305
  int i;
306
  char *local = malloc (len);
307
 
308
  if (local == NULL)
309
    {
310
      fprintf (stderr, "sim: Unable to read 0x%ulx bytes - out of memory\n",
311
               len);
312
      return;
313
    }
314
 
315
  res = read (f, local, len);
316
  if (res > 0)
317
    for (i = 0; i < res; i++)
318
      ARMul_WriteByte (state, ptr + i, local[i]);
319
  free (local);
320
  state->Reg[0] = res == -1 ? -1 : len - res;
321
  OSptr->ErrorNo = errno;
322
}
323
 
324
static void
325
SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
326
{
327
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
328
  int res;
329
  ARMword i;
330
  char *local = malloc (len);
331
 
332
  if (local == NULL)
333
    {
334
      fprintf (stderr, "sim: Unable to write 0x%lx bytes - out of memory\n",
335
               (long) len);
336
      return;
337
    }
338
 
339
  for (i = 0; i < len; i++)
340
    local[i] = ARMul_ReadByte (state, ptr + i);
341
 
342
  res = write (f, local, len);
343
  state->Reg[0] = res == -1 ? -1 : len - res;
344
  free (local);
345
  OSptr->ErrorNo = errno;
346
}
347
 
348
static void
349
SWIflen (ARMul_State * state, ARMword fh)
350
{
351
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
352
  ARMword addr;
353
 
354
  if (fh == 0 || fh > FOPEN_MAX)
355
    {
356
      OSptr->ErrorNo = EBADF;
357
      state->Reg[0] = -1L;
358
      return;
359
    }
360
 
361
  addr = lseek (fh, 0, SEEK_CUR);
362
 
363
  state->Reg[0] = lseek (fh, 0L, SEEK_END);
364
  (void) lseek (fh, addr, SEEK_SET);
365
 
366
  OSptr->ErrorNo = errno;
367
}
368
 
369
/***************************************************************************\
370
* The emulator calls this routine when a SWI instruction is encuntered. The *
371
* parameter passed is the SWI number (lower 24 bits of the instruction).    *
372
\***************************************************************************/
373
 
374
unsigned
375
ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
376
{
377
  ARMword addr, temp;
378
  struct OSblock *OSptr = (struct OSblock *) state->OSptr;
379
 
380
  switch (number)
381
    {
382
    case SWI_Read:
383
      SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
384
      return TRUE;
385
 
386
    case SWI_Write:
387
      SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
388
      return TRUE;
389
 
390
    case SWI_Open:
391
      SWIopen (state, state->Reg[0], state->Reg[1]);
392
      return TRUE;
393
 
394
    case SWI_Clock:
395
      /* return number of centi-seconds... */
396
      state->Reg[0] =
397
#ifdef CLOCKS_PER_SEC
398
        (CLOCKS_PER_SEC >= 100)
399
        ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
400
        : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
401
#else
402
        /* presume unix... clock() returns microseconds */
403
        (ARMword) (clock () / 10000);
404
#endif
405
      OSptr->ErrorNo = errno;
406
      return (TRUE);
407
 
408
    case SWI_Time:
409
      state->Reg[0] = (ARMword) time (NULL);
410
      OSptr->ErrorNo = errno;
411
      return (TRUE);
412
 
413
    case SWI_Close:
414
      state->Reg[0] = close (state->Reg[0]);
415
      OSptr->ErrorNo = errno;
416
      return TRUE;
417
 
418
    case SWI_Flen:
419
      SWIflen (state, state->Reg[0]);
420
      return (TRUE);
421
 
422
    case SWI_Exit:
423
      state->Emulate = FALSE;
424
      return TRUE;
425
 
426
    case SWI_Seek:
427
      {
428
        /* We must return non-zero for failure */
429
        state->Reg[0] = -1 >= lseek (state->Reg[0], state->Reg[1], SEEK_SET);
430
        OSptr->ErrorNo = errno;
431
        return TRUE;
432
      }
433
 
434
    case SWI_WriteC:
435
      (void) fputc ((int) state->Reg[0], stdout);
436
      OSptr->ErrorNo = errno;
437
      return (TRUE);
438
 
439
    case SWI_Write0:
440
      SWIWrite0 (state, state->Reg[0]);
441
      return (TRUE);
442
 
443
    case SWI_GetErrno:
444
      state->Reg[0] = OSptr->ErrorNo;
445
      return (TRUE);
446
 
447
    case SWI_Breakpoint:
448
      state->EndCondition = RDIError_BreakpointReached;
449
      state->Emulate = FALSE;
450
      return (TRUE);
451
 
452
    case SWI_GetEnv:
453
      state->Reg[0] = ADDRCMDLINE;
454
      if (state->MemSize)
455
        state->Reg[1] = state->MemSize;
456
      else
457
        state->Reg[1] = ADDRUSERSTACK;
458
 
459
      WriteCommandLineTo (state, state->Reg[0]);
460
      return (TRUE);
461
 
462
      /* Handle Angel SWIs as well as Demon ones */
463
    case AngelSWI_ARM:
464
    case AngelSWI_Thumb:
465
      /* R1 is almost always a parameter block */
466
      addr = state->Reg[1];
467
      /* R0 is a reason code */
468
      switch (state->Reg[0])
469
        {
470
          /* Unimplemented reason codes */
471
        case AngelSWI_Reason_ReadC:
472
        case AngelSWI_Reason_IsTTY:
473
        case AngelSWI_Reason_TmpNam:
474
        case AngelSWI_Reason_Remove:
475
        case AngelSWI_Reason_Rename:
476
        case AngelSWI_Reason_System:
477
        case AngelSWI_Reason_EnterSVC:
478
        default:
479
          state->Emulate = FALSE;
480
          return (FALSE);
481
 
482
        case AngelSWI_Reason_Clock:
483
          /* return number of centi-seconds... */
484
          state->Reg[0] =
485
#ifdef CLOCKS_PER_SEC
486
            (CLOCKS_PER_SEC >= 100)
487
            ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
488
            : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
489
#else
490
            /* presume unix... clock() returns microseconds */
491
            (ARMword) (clock () / 10000);
492
#endif
493
          OSptr->ErrorNo = errno;
494
          return (TRUE);
495
 
496
        case AngelSWI_Reason_Time:
497
          state->Reg[0] = (ARMword) time (NULL);
498
          OSptr->ErrorNo = errno;
499
          return (TRUE);
500
 
501
        case AngelSWI_Reason_WriteC:
502
          (void) fputc ((int) ARMul_ReadByte (state, addr), stdout);
503
          OSptr->ErrorNo = errno;
504
          return (TRUE);
505
 
506
        case AngelSWI_Reason_Write0:
507
          SWIWrite0 (state, addr);
508
          return (TRUE);
509
 
510
        case AngelSWI_Reason_Close:
511
          state->Reg[0] = close (ARMul_ReadWord (state, addr));
512
          OSptr->ErrorNo = errno;
513
          return (TRUE);
514
 
515
        case AngelSWI_Reason_Seek:
516
          state->Reg[0] = -1 >= lseek (ARMul_ReadWord (state, addr),
517
                                       ARMul_ReadWord (state, addr + 4),
518
                                       SEEK_SET);
519
          OSptr->ErrorNo = errno;
520
          return (TRUE);
521
 
522
        case AngelSWI_Reason_FLen:
523
          SWIflen (state, ARMul_ReadWord (state, addr));
524
          return (TRUE);
525
 
526
        case AngelSWI_Reason_GetCmdLine:
527
          WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
528
          return (TRUE);
529
 
530
        case AngelSWI_Reason_HeapInfo:
531
          /* R1 is a pointer to a pointer */
532
          addr = ARMul_ReadWord (state, addr);
533
 
534
          /* Pick up the right memory limit */
535
          if (state->MemSize)
536
            temp = state->MemSize;
537
          else
538
            temp = ADDRUSERSTACK;
539
 
540
          ARMul_WriteWord (state, addr, 0);      /* Heap base */
541
          ARMul_WriteWord (state, addr + 4, temp);      /* Heap limit */
542
          ARMul_WriteWord (state, addr + 8, temp);      /* Stack base */
543
          ARMul_WriteWord (state, addr + 12, temp);     /* Stack limit */
544
          return (TRUE);
545
 
546
        case AngelSWI_Reason_ReportException:
547
          if (state->Reg[1] == ADP_Stopped_ApplicationExit)
548
            state->Reg[0] = 0;
549
          else
550
            state->Reg[0] = -1;
551
          state->Emulate = FALSE;
552
          return TRUE;
553
 
554
        case ADP_Stopped_ApplicationExit:
555
          state->Reg[0] = 0;
556
          state->Emulate = FALSE;
557
          return (TRUE);
558
 
559
        case ADP_Stopped_RunTimeError:
560
          state->Reg[0] = -1;
561
          state->Emulate = FALSE;
562
          return (TRUE);
563
 
564
        case AngelSWI_Reason_Errno:
565
          state->Reg[0] = OSptr->ErrorNo;
566
          return (TRUE);
567
 
568
        case AngelSWI_Reason_Open:
569
          SWIopen (state,
570
                   ARMul_ReadWord (state, addr),
571
                   ARMul_ReadWord (state, addr + 4));
572
          return TRUE;
573
 
574
        case AngelSWI_Reason_Read:
575
          SWIread (state,
576
                   ARMul_ReadWord (state, addr),
577
                   ARMul_ReadWord (state, addr + 4),
578
                   ARMul_ReadWord (state, addr + 8));
579
          return TRUE;
580
 
581
        case AngelSWI_Reason_Write:
582
          SWIwrite (state,
583
                    ARMul_ReadWord (state, addr),
584
                    ARMul_ReadWord (state, addr + 4),
585
                    ARMul_ReadWord (state, addr + 8));
586
          return TRUE;
587
        }
588
 
589
    default:
590
      state->Emulate = FALSE;
591
      return (FALSE);
592
    }
593
}
594
 
595
#ifndef NOOS
596
#ifndef ASIM
597
 
598
/***************************************************************************\
599
* The emulator calls this routine when an Exception occurs.  The second     *
600
* parameter is the address of the relevant exception vector.  Returning     *
601
* FALSE from this routine causes the trap to be taken, TRUE causes it to    *
602
* be ignored (so set state->Emulate to FALSE!).                             *
603
\***************************************************************************/
604
 
605
unsigned
606
ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED, ARMword vector ATTRIBUTE_UNUSED, ARMword pc ATTRIBUTE_UNUSED)
607
{                               /* don't use this here */
608
  return (FALSE);
609
}
610
 
611
#endif
612
 
613
 
614
#endif /* NOOS */

powered by: WebSVN 2.1.0

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