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