]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/armos.c
remove conflict indicator.
[thirdparty/binutils-gdb.git] / sim / arm / armos.c
CommitLineData
c906108c
SS
1/* 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,
7f53bc35
NC
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. */
c906108c
SS
24
25#include "config.h"
6d358e86 26#include "ansidecl.h"
c906108c
SS
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
dfcd3bfb 51#include <unistd.h> /* For SEEK_SET etc */
c906108c
SS
52#endif
53
54#ifdef __riscos
dfcd3bfb 55extern int _fisatty (FILE *);
c906108c
SS
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"
f1129fb8
NC
73#include "armemu.h"
74
c906108c
SS
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
dfcd3bfb
JM
86extern unsigned ARMul_OSInit (ARMul_State * state);
87extern void ARMul_OSExit (ARMul_State * state);
88extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
89extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector,
90 ARMword pc);
91extern ARMword ARMul_OSLastErrorP (ARMul_State * state);
92extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr);
c906108c
SS
93
94#define BUFFERSIZE 4096
95#ifndef FOPEN_MAX
96#define FOPEN_MAX 64
97#endif
98#define UNIQUETEMPS 256
99
7f53bc35 100/* OS private Information. */
c906108c 101
dfcd3bfb
JM
102struct 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};
c906108c
SS
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 )
dfcd3bfb
JM
122#else
123#define FIXCRLF(t,c) c
c906108c
SS
124#endif
125
6d358e86 126static ARMword softvectorcode[] =
7f53bc35
NC
127{
128 /* Basic: swi tidyexception + event; mov pc, lr;
129 ldmia r11,{r11,pc}; 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 */
c906108c
SS
140};
141
1e5d4e46
NC
142/* Set to prevent aborts when emulating SWI routines. */
143static int in_SWI_handler = 0;
144
7f53bc35 145/* Time for the Operating System to initialise itself. */
c906108c 146
dfcd3bfb
JM
147unsigned
148ARMul_OSInit (ARMul_State * state)
c906108c
SS
149{
150#ifndef NOOS
151#ifndef VALIDATE
dfcd3bfb
JM
152 ARMword instr, i, j;
153 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
154
155 if (state->OSptr == NULL)
156 {
157 state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
158 if (state->OSptr == NULL)
159 {
160 perror ("OS Memory");
161 exit (15);
162 }
c906108c 163 }
7f53bc35 164
dfcd3bfb
JM
165 OSptr = (struct OSblock *) state->OSptr;
166 OSptr->ErrorP = 0;
167 state->Reg[13] = ADDRSUPERSTACK; /* set up a stack for the current mode */
168 ARMul_SetReg (state, SVC32MODE, 13, ADDRSUPERSTACK); /* and for supervisor mode */
169 ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK); /* and for abort 32 mode */
170 ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK); /* and for undef 32 mode */
c1a72ffd 171 ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK); /* and for system mode */
dfcd3bfb 172 instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8); /* load pc from soft vector */
7f53bc35 173
dfcd3bfb
JM
174 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
175 ARMul_WriteWord (state, i, instr); /* write hardware vectors */
7f53bc35 176
88694af3
NC
177 SWI_vector_installed = 0;
178
dfcd3bfb
JM
179 for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
180 {
181 ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
182 ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
183 SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
c906108c 184 }
7f53bc35 185
dfcd3bfb
JM
186 for (i = 0; i < sizeof (softvectorcode); i += 4)
187 ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
7f53bc35 188
dfcd3bfb
JM
189 for (i = 0; i < FOPEN_MAX; i++)
190 OSptr->FileTable[i] = NULL;
7f53bc35 191
dfcd3bfb
JM
192 for (i = 0; i < UNIQUETEMPS; i++)
193 OSptr->tempnames[i] = NULL;
7f53bc35 194
dfcd3bfb 195 ARMul_ConsolePrint (state, ", Demon 1.01");
c906108c
SS
196
197/* #ifndef ASIM */
198
dfcd3bfb
JM
199 /* install fpe */
200 for (i = 0; i < fpesize; i += 4) /* copy the code */
201 ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
7f53bc35 202
dfcd3bfb
JM
203 for (i = FPESTART + fpesize;; i -= 4)
204 { /* reverse the error strings */
205 if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
206 break;
207 if (state->bigendSig && j < 0x80000000)
208 { /* it's part of the string so swap it */
209 j = ((j >> 0x18) & 0x000000ff) |
210 ((j >> 0x08) & 0x0000ff00) |
211 ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
212 ARMul_WriteWord (state, i, j);
213 }
c906108c 214 }
7f53bc35 215
dfcd3bfb
JM
216 ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, 4)); /* copy old illegal instr vector */
217 ARMul_WriteWord (state, 4, FPENEWVECT (ARMul_ReadWord (state, i - 4))); /* install new vector */
218 ARMul_ConsolePrint (state, ", FPE");
c906108c 219
6d358e86 220/* #endif ASIM */
c906108c
SS
221#endif /* VALIDATE */
222#endif /* NOOS */
223
7f53bc35 224 return TRUE;
c906108c
SS
225}
226
dfcd3bfb
JM
227void
228ARMul_OSExit (ARMul_State * state)
c906108c 229{
dfcd3bfb 230 free ((char *) state->OSptr);
c906108c
SS
231}
232
233
7f53bc35 234/* Return the last Operating System Error. */
c906108c 235
dfcd3bfb 236ARMword ARMul_OSLastErrorP (ARMul_State * state)
c906108c 237{
dfcd3bfb 238 return ((struct OSblock *) state->OSptr)->ErrorP;
c906108c
SS
239}
240
7f53bc35
NC
241static int translate_open_mode[] =
242{
dfcd3bfb
JM
243 O_RDONLY, /* "r" */
244 O_RDONLY + O_BINARY, /* "rb" */
245 O_RDWR, /* "r+" */
246 O_RDWR + O_BINARY, /* "r+b" */
247 O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
248 O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
249 O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
250 O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
251 O_WRONLY + O_APPEND + O_CREAT, /* "a" */
252 O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
253 O_RDWR + O_APPEND + O_CREAT, /* "a+" */
254 O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
c906108c
SS
255};
256
dfcd3bfb
JM
257static void
258SWIWrite0 (ARMul_State * state, ARMword addr)
c906108c
SS
259{
260 ARMword temp;
dfcd3bfb 261 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
262
263 while ((temp = ARMul_ReadByte (state, addr++)) != 0)
2acceee2 264 (void) fputc ((char) temp, stdout);
c906108c
SS
265
266 OSptr->ErrorNo = errno;
267}
268
dfcd3bfb
JM
269static void
270WriteCommandLineTo (ARMul_State * state, ARMword addr)
c906108c
SS
271{
272 ARMword temp;
273 char *cptr = state->CommandLine;
7f53bc35 274
c906108c
SS
275 if (cptr == NULL)
276 cptr = "\0";
dfcd3bfb
JM
277 do
278 {
279 temp = (ARMword) * cptr++;
280 ARMul_WriteByte (state, addr++, temp);
281 }
282 while (temp != 0);
c906108c
SS
283}
284
dfcd3bfb
JM
285static void
286SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
c906108c 287{
dfcd3bfb 288 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
289 char dummy[2000];
290 int flags;
291 int i;
292
6d358e86 293 for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++)
c906108c
SS
294 ;
295
7f53bc35 296 /* Now we need to decode the Demon open mode. */
c906108c
SS
297 flags = translate_open_mode[SWIflags];
298
7f53bc35 299 /* Filename ":tt" is special: it denotes stdin/out. */
c906108c
SS
300 if (strcmp (dummy, ":tt") == 0)
301 {
dfcd3bfb
JM
302 if (flags == O_RDONLY) /* opening tty "r" */
303 state->Reg[0] = 0; /* stdin */
304 else
305 state->Reg[0] = 1; /* stdout */
c906108c
SS
306 }
307 else
308 {
2df3850c 309 state->Reg[0] = (int) open (dummy, flags, 0666);
c906108c
SS
310 OSptr->ErrorNo = errno;
311 }
312}
313
dfcd3bfb
JM
314static void
315SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 316{
dfcd3bfb 317 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
318 int res;
319 int i;
320 char *local = malloc (len);
321
c2d11a7d
JM
322 if (local == NULL)
323 {
6d358e86 324 fprintf (stderr, "sim: Unable to read 0x%ulx bytes - out of memory\n",
dfcd3bfb 325 len);
c2d11a7d
JM
326 return;
327 }
dfcd3bfb 328
c906108c
SS
329 res = read (f, local, len);
330 if (res > 0)
dfcd3bfb 331 for (i = 0; i < res; i++)
c906108c 332 ARMul_WriteByte (state, ptr + i, local[i]);
7f53bc35 333
c906108c
SS
334 free (local);
335 state->Reg[0] = res == -1 ? -1 : len - res;
336 OSptr->ErrorNo = errno;
337}
338
dfcd3bfb
JM
339static void
340SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 341{
dfcd3bfb 342 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c 343 int res;
6d358e86 344 ARMword i;
c906108c
SS
345 char *local = malloc (len);
346
c2d11a7d 347 if (local == NULL)
c906108c 348 {
6d358e86
NC
349 fprintf (stderr, "sim: Unable to write 0x%lx bytes - out of memory\n",
350 (long) len);
c2d11a7d 351 return;
c906108c 352 }
dfcd3bfb
JM
353
354 for (i = 0; i < len; i++)
c2d11a7d
JM
355 local[i] = ARMul_ReadByte (state, ptr + i);
356
c906108c
SS
357 res = write (f, local, len);
358 state->Reg[0] = res == -1 ? -1 : len - res;
359 free (local);
7f53bc35 360
c906108c
SS
361 OSptr->ErrorNo = errno;
362}
363
dfcd3bfb
JM
364static void
365SWIflen (ARMul_State * state, ARMword fh)
c906108c 366{
dfcd3bfb 367 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
368 ARMword addr;
369
370 if (fh == 0 || fh > FOPEN_MAX)
371 {
372 OSptr->ErrorNo = EBADF;
373 state->Reg[0] = -1L;
374 return;
375 }
376
377 addr = lseek (fh, 0, SEEK_CUR);
6d358e86
NC
378
379 state->Reg[0] = lseek (fh, 0L, SEEK_END);
380 (void) lseek (fh, addr, SEEK_SET);
c906108c
SS
381
382 OSptr->ErrorNo = errno;
383}
384
7f53bc35
NC
385/* The emulator calls this routine when a SWI instruction is encuntered.
386 The parameter passed is the SWI number (lower 24 bits of the instruction). */
c906108c 387
dfcd3bfb
JM
388unsigned
389ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
c906108c 390{
1e5d4e46
NC
391 ARMword addr;
392 ARMword temp;
393 ARMword saved_number = 0;
394 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
7f53bc35 395
1e5d4e46
NC
396 in_SWI_handler = 1;
397
7f53bc35
NC
398 /* Intel do not want DEMON SWI support. */
399 if (state->is_XScale)
400 switch (number)
401 {
402 case SWI_Read:
403 case SWI_Write:
404 case SWI_Open:
405 case SWI_Clock:
406 case SWI_Time:
407 case SWI_Close:
408 case SWI_Flen:
409 case SWI_Exit:
410 case SWI_Seek:
411 case SWI_WriteC:
412 case SWI_Write0:
413 case SWI_GetErrno:
414 case SWI_GetEnv:
415 saved_number = number;
416 number = -1;
417 default:
418 break;
419 }
420
c906108c
SS
421 switch (number)
422 {
423 case SWI_Read:
dfcd3bfb 424 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
1e5d4e46 425 break;
c906108c
SS
426
427 case SWI_Write:
dfcd3bfb 428 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
1e5d4e46 429 break;
c906108c
SS
430
431 case SWI_Open:
dfcd3bfb 432 SWIopen (state, state->Reg[0], state->Reg[1]);
1e5d4e46 433 break;
c906108c 434
dfcd3bfb 435 case SWI_Clock:
7f53bc35 436 /* Return number of centi-seconds. */
dfcd3bfb 437 state->Reg[0] =
c906108c 438#ifdef CLOCKS_PER_SEC
dfcd3bfb
JM
439 (CLOCKS_PER_SEC >= 100)
440 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
441 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 442#else
7f53bc35 443 /* Presume unix... clock() returns microseconds. */
dfcd3bfb 444 (ARMword) (clock () / 10000);
c906108c 445#endif
dfcd3bfb 446 OSptr->ErrorNo = errno;
1e5d4e46 447 break;
dfcd3bfb
JM
448
449 case SWI_Time:
450 state->Reg[0] = (ARMword) time (NULL);
451 OSptr->ErrorNo = errno;
1e5d4e46 452 break;
dfcd3bfb 453
c906108c
SS
454 case SWI_Close:
455 state->Reg[0] = close (state->Reg[0]);
456 OSptr->ErrorNo = errno;
1e5d4e46 457 break;
c906108c 458
dfcd3bfb 459 case SWI_Flen:
c906108c 460 SWIflen (state, state->Reg[0]);
1e5d4e46 461 break;
c906108c
SS
462
463 case SWI_Exit:
dfcd3bfb 464 state->Emulate = FALSE;
1e5d4e46 465 break;
c906108c
SS
466
467 case SWI_Seek:
1e5d4e46
NC
468 /* We must return non-zero for failure. */
469 state->Reg[0] = -1 >= lseek (state->Reg[0], state->Reg[1], SEEK_SET);
470 OSptr->ErrorNo = errno;
471 break;
c906108c 472
dfcd3bfb
JM
473 case SWI_WriteC:
474 (void) fputc ((int) state->Reg[0], stdout);
475 OSptr->ErrorNo = errno;
1e5d4e46 476 break;
c906108c 477
dfcd3bfb 478 case SWI_Write0:
c906108c 479 SWIWrite0 (state, state->Reg[0]);
1e5d4e46 480 break;
c906108c 481
dfcd3bfb
JM
482 case SWI_GetErrno:
483 state->Reg[0] = OSptr->ErrorNo;
1e5d4e46 484 break;
c906108c 485
dfcd3bfb
JM
486 case SWI_GetEnv:
487 state->Reg[0] = ADDRCMDLINE;
488 if (state->MemSize)
489 state->Reg[1] = state->MemSize;
490 else
491 state->Reg[1] = ADDRUSERSTACK;
c906108c 492
dfcd3bfb 493 WriteCommandLineTo (state, state->Reg[0]);
1e5d4e46 494 break;
7f53bc35 495
f1129fb8
NC
496 case SWI_Breakpoint:
497 state->EndCondition = RDIError_BreakpointReached;
498 state->Emulate = FALSE;
1e5d4e46 499 break;
c906108c 500
7f53bc35 501 /* Handle Angel SWIs as well as Demon ones. */
c906108c
SS
502 case AngelSWI_ARM:
503 case AngelSWI_Thumb:
7f53bc35 504 /* R1 is almost always a parameter block. */
c906108c 505 addr = state->Reg[1];
7f53bc35 506 /* R0 is a reason code. */
c906108c
SS
507 switch (state->Reg[0])
508 {
7f53bc35 509 /* Unimplemented reason codes. */
c906108c
SS
510 case AngelSWI_Reason_ReadC:
511 case AngelSWI_Reason_IsTTY:
512 case AngelSWI_Reason_TmpNam:
513 case AngelSWI_Reason_Remove:
514 case AngelSWI_Reason_Rename:
515 case AngelSWI_Reason_System:
516 case AngelSWI_Reason_EnterSVC:
517 default:
518 state->Emulate = FALSE;
1e5d4e46 519 in_SWI_handler = 0;
7f53bc35 520 return FALSE;
c906108c
SS
521
522 case AngelSWI_Reason_Clock:
7f53bc35 523 /* Return number of centi-seconds. */
c906108c
SS
524 state->Reg[0] =
525#ifdef CLOCKS_PER_SEC
526 (CLOCKS_PER_SEC >= 100)
dfcd3bfb
JM
527 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
528 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 529#else
7f53bc35 530 /* Presume unix... clock() returns microseconds. */
dfcd3bfb 531 (ARMword) (clock () / 10000);
c906108c
SS
532#endif
533 OSptr->ErrorNo = errno;
1e5d4e46 534 break;
c906108c
SS
535
536 case AngelSWI_Reason_Time:
537 state->Reg[0] = (ARMword) time (NULL);
538 OSptr->ErrorNo = errno;
1e5d4e46 539 break;
c906108c
SS
540
541 case AngelSWI_Reason_WriteC:
dfcd3bfb 542 (void) fputc ((int) ARMul_ReadByte (state, addr), stdout);
c906108c 543 OSptr->ErrorNo = errno;
94ab9d7b 544 /* Fall thgrough. */
c906108c
SS
545
546 case AngelSWI_Reason_Write0:
547 SWIWrite0 (state, addr);
1e5d4e46 548 break;
c906108c
SS
549
550 case AngelSWI_Reason_Close:
551 state->Reg[0] = close (ARMul_ReadWord (state, addr));
552 OSptr->ErrorNo = errno;
1e5d4e46 553 break;
c906108c
SS
554
555 case AngelSWI_Reason_Seek:
dfcd3bfb
JM
556 state->Reg[0] = -1 >= lseek (ARMul_ReadWord (state, addr),
557 ARMul_ReadWord (state, addr + 4),
c906108c
SS
558 SEEK_SET);
559 OSptr->ErrorNo = errno;
1e5d4e46 560 break;
c906108c
SS
561
562 case AngelSWI_Reason_FLen:
563 SWIflen (state, ARMul_ReadWord (state, addr));
1e5d4e46 564 break;
c906108c 565
dfcd3bfb 566 case AngelSWI_Reason_GetCmdLine:
c906108c 567 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
1e5d4e46 568 break;
c906108c
SS
569
570 case AngelSWI_Reason_HeapInfo:
7f53bc35 571 /* R1 is a pointer to a pointer. */
c906108c
SS
572 addr = ARMul_ReadWord (state, addr);
573
7f53bc35 574 /* Pick up the right memory limit. */
c906108c
SS
575 if (state->MemSize)
576 temp = state->MemSize;
577 else
578 temp = ADDRUSERSTACK;
579
dfcd3bfb
JM
580 ARMul_WriteWord (state, addr, 0); /* Heap base */
581 ARMul_WriteWord (state, addr + 4, temp); /* Heap limit */
582 ARMul_WriteWord (state, addr + 8, temp); /* Stack base */
583 ARMul_WriteWord (state, addr + 12, temp); /* Stack limit */
1e5d4e46 584 break;
c906108c
SS
585
586 case AngelSWI_Reason_ReportException:
587 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
588 state->Reg[0] = 0;
589 else
590 state->Reg[0] = -1;
dfcd3bfb 591 state->Emulate = FALSE;
1e5d4e46 592 break;
c906108c
SS
593
594 case ADP_Stopped_ApplicationExit:
595 state->Reg[0] = 0;
dfcd3bfb 596 state->Emulate = FALSE;
1e5d4e46 597 break;
dfcd3bfb 598
c906108c
SS
599 case ADP_Stopped_RunTimeError:
600 state->Reg[0] = -1;
dfcd3bfb 601 state->Emulate = FALSE;
1e5d4e46 602 break;
c906108c
SS
603
604 case AngelSWI_Reason_Errno:
605 state->Reg[0] = OSptr->ErrorNo;
1e5d4e46 606 break;
c906108c
SS
607
608 case AngelSWI_Reason_Open:
dfcd3bfb
JM
609 SWIopen (state,
610 ARMul_ReadWord (state, addr),
611 ARMul_ReadWord (state, addr + 4));
1e5d4e46 612 break;
c906108c
SS
613
614 case AngelSWI_Reason_Read:
dfcd3bfb
JM
615 SWIread (state,
616 ARMul_ReadWord (state, addr),
617 ARMul_ReadWord (state, addr + 4),
618 ARMul_ReadWord (state, addr + 8));
1e5d4e46 619 break;
c906108c
SS
620
621 case AngelSWI_Reason_Write:
dfcd3bfb
JM
622 SWIwrite (state,
623 ARMul_ReadWord (state, addr),
624 ARMul_ReadWord (state, addr + 4),
625 ARMul_ReadWord (state, addr + 8));
1e5d4e46 626 break;
c906108c
SS
627 }
628
f1129fb8 629 case 0x90:
9a6b6a66 630 case 0x91:
f1129fb8
NC
631 case 0x92:
632 /* These are used by the FPE code. */
1e5d4e46 633 break;
f1129fb8 634
dfcd3bfb 635 default:
1e5d4e46 636 in_SWI_handler = 0;
94ab9d7b 637
1e5d4e46
NC
638 /* If there is a SWI vector installed use it. */
639 if (state->is_XScale && saved_number != -1)
640 number = saved_number;
7f53bc35 641
1e5d4e46
NC
642 if (SWI_vector_installed && number != SWI_Breakpoint)
643 {
644 ARMword cpsr;
645 ARMword i_size;
94ab9d7b 646
1e5d4e46
NC
647 cpsr = ARMul_GetCPSR (state);
648 i_size = INSN_SIZE;
94ab9d7b 649
1e5d4e46 650 ARMul_SetSPSR (state, SVC32MODE, cpsr);
94ab9d7b 651
1e5d4e46
NC
652 cpsr &= ~0xbf;
653 cpsr |= SVC32MODE | 0x80;
654 ARMul_SetCPSR (state, cpsr);
94ab9d7b 655
1e5d4e46
NC
656 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
657 state->NextInstr = RESUME;
658 state->Reg[15] = state->pc = ARMSWIV;
659 FLUSHPIPE;
660 }
661 else
662 {
f1129fb8 663 fprintf (stderr, "unknown SWI encountered - %x - ignoring\n", number);
1e5d4e46
NC
664 return FALSE;
665 }
c906108c 666 }
1e5d4e46
NC
667
668 in_SWI_handler = 0;
669 return TRUE;
c906108c
SS
670}
671
c906108c
SS
672#ifndef NOOS
673#ifndef ASIM
674
f1129fb8
NC
675/* The emulator calls this routine when an Exception occurs. The second
676 parameter is the address of the relevant exception vector. Returning
677 FALSE from this routine causes the trap to be taken, TRUE causes it to
678 be ignored (so set state->Emulate to FALSE!). */
c906108c 679
dfcd3bfb 680unsigned
7f53bc35 681ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
f1129fb8
NC
682 ARMword vector ATTRIBUTE_UNUSED,
683 ARMword pc ATTRIBUTE_UNUSED)
684{
1e5d4e46
NC
685 /* If we are inside a SWI handler routine, then ignore any exceptions.
686 They could be caused by data exceptions for misaligned reads, for
687 example, but for the purposes of emulating a SWI, we do not care. */
688
689 return in_SWI_handler;
c906108c
SS
690}
691
692#endif
c906108c 693#endif /* NOOS */