Fix spelling typo
[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 259
917bca4f 260 while ((temp = ARMul_SafeReadByte (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++;
917bca4f 277 ARMul_SafeWriteByte (state, addr++, temp);
dfcd3bfb
JM
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
917bca4f 290 for (i = 0; (dummy[i] = ARMul_SafeReadByte (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++)
917bca4f 329 ARMul_SafeWriteByte (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++)
917bca4f 352 local[i] = ARMul_SafeReadByte (state, ptr + i);
c2d11a7d 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{
1e5d4e46
NC
388 ARMword addr;
389 ARMword temp;
390 ARMword saved_number = 0;
391 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
7f53bc35
NC
392
393 /* Intel do not want DEMON SWI support. */
394 if (state->is_XScale)
395 switch (number)
396 {
397 case SWI_Read:
398 case SWI_Write:
399 case SWI_Open:
400 case SWI_Clock:
401 case SWI_Time:
402 case SWI_Close:
403 case SWI_Flen:
404 case SWI_Exit:
405 case SWI_Seek:
406 case SWI_WriteC:
407 case SWI_Write0:
408 case SWI_GetErrno:
409 case SWI_GetEnv:
410 saved_number = number;
411 number = -1;
412 default:
413 break;
414 }
415
c906108c
SS
416 switch (number)
417 {
418 case SWI_Read:
dfcd3bfb 419 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
1e5d4e46 420 break;
c906108c
SS
421
422 case SWI_Write:
dfcd3bfb 423 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
1e5d4e46 424 break;
c906108c
SS
425
426 case SWI_Open:
dfcd3bfb 427 SWIopen (state, state->Reg[0], state->Reg[1]);
1e5d4e46 428 break;
c906108c 429
dfcd3bfb 430 case SWI_Clock:
7f53bc35 431 /* Return number of centi-seconds. */
dfcd3bfb 432 state->Reg[0] =
c906108c 433#ifdef CLOCKS_PER_SEC
dfcd3bfb
JM
434 (CLOCKS_PER_SEC >= 100)
435 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
436 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 437#else
7f53bc35 438 /* Presume unix... clock() returns microseconds. */
dfcd3bfb 439 (ARMword) (clock () / 10000);
c906108c 440#endif
dfcd3bfb 441 OSptr->ErrorNo = errno;
1e5d4e46 442 break;
dfcd3bfb
JM
443
444 case SWI_Time:
445 state->Reg[0] = (ARMword) time (NULL);
446 OSptr->ErrorNo = errno;
1e5d4e46 447 break;
dfcd3bfb 448
c906108c
SS
449 case SWI_Close:
450 state->Reg[0] = close (state->Reg[0]);
451 OSptr->ErrorNo = errno;
1e5d4e46 452 break;
c906108c 453
dfcd3bfb 454 case SWI_Flen:
c906108c 455 SWIflen (state, state->Reg[0]);
1e5d4e46 456 break;
c906108c
SS
457
458 case SWI_Exit:
dfcd3bfb 459 state->Emulate = FALSE;
1e5d4e46 460 break;
c906108c
SS
461
462 case SWI_Seek:
1e5d4e46
NC
463 /* We must return non-zero for failure. */
464 state->Reg[0] = -1 >= lseek (state->Reg[0], state->Reg[1], SEEK_SET);
465 OSptr->ErrorNo = errno;
466 break;
c906108c 467
dfcd3bfb
JM
468 case SWI_WriteC:
469 (void) fputc ((int) state->Reg[0], stdout);
470 OSptr->ErrorNo = errno;
1e5d4e46 471 break;
c906108c 472
dfcd3bfb 473 case SWI_Write0:
c906108c 474 SWIWrite0 (state, state->Reg[0]);
1e5d4e46 475 break;
c906108c 476
dfcd3bfb
JM
477 case SWI_GetErrno:
478 state->Reg[0] = OSptr->ErrorNo;
1e5d4e46 479 break;
c906108c 480
dfcd3bfb
JM
481 case SWI_GetEnv:
482 state->Reg[0] = ADDRCMDLINE;
483 if (state->MemSize)
484 state->Reg[1] = state->MemSize;
485 else
486 state->Reg[1] = ADDRUSERSTACK;
c906108c 487
dfcd3bfb 488 WriteCommandLineTo (state, state->Reg[0]);
1e5d4e46 489 break;
7f53bc35 490
f1129fb8
NC
491 case SWI_Breakpoint:
492 state->EndCondition = RDIError_BreakpointReached;
493 state->Emulate = FALSE;
1e5d4e46 494 break;
c906108c 495
7f53bc35 496 /* Handle Angel SWIs as well as Demon ones. */
c906108c
SS
497 case AngelSWI_ARM:
498 case AngelSWI_Thumb:
7f53bc35 499 /* R1 is almost always a parameter block. */
c906108c 500 addr = state->Reg[1];
7f53bc35 501 /* R0 is a reason code. */
c906108c
SS
502 switch (state->Reg[0])
503 {
7f53bc35 504 /* Unimplemented reason codes. */
c906108c
SS
505 case AngelSWI_Reason_ReadC:
506 case AngelSWI_Reason_IsTTY:
507 case AngelSWI_Reason_TmpNam:
508 case AngelSWI_Reason_Remove:
509 case AngelSWI_Reason_Rename:
510 case AngelSWI_Reason_System:
511 case AngelSWI_Reason_EnterSVC:
512 default:
513 state->Emulate = FALSE;
7f53bc35 514 return FALSE;
c906108c
SS
515
516 case AngelSWI_Reason_Clock:
7f53bc35 517 /* Return number of centi-seconds. */
c906108c
SS
518 state->Reg[0] =
519#ifdef CLOCKS_PER_SEC
520 (CLOCKS_PER_SEC >= 100)
dfcd3bfb
JM
521 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
522 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 523#else
7f53bc35 524 /* Presume unix... clock() returns microseconds. */
dfcd3bfb 525 (ARMword) (clock () / 10000);
c906108c
SS
526#endif
527 OSptr->ErrorNo = errno;
1e5d4e46 528 break;
c906108c
SS
529
530 case AngelSWI_Reason_Time:
531 state->Reg[0] = (ARMword) time (NULL);
532 OSptr->ErrorNo = errno;
1e5d4e46 533 break;
c906108c
SS
534
535 case AngelSWI_Reason_WriteC:
917bca4f 536 (void) fputc ((int) ARMul_SafeReadByte (state, addr), stdout);
c906108c 537 OSptr->ErrorNo = errno;
94ab9d7b 538 /* Fall thgrough. */
c906108c
SS
539
540 case AngelSWI_Reason_Write0:
541 SWIWrite0 (state, addr);
1e5d4e46 542 break;
c906108c
SS
543
544 case AngelSWI_Reason_Close:
545 state->Reg[0] = close (ARMul_ReadWord (state, addr));
546 OSptr->ErrorNo = errno;
1e5d4e46 547 break;
c906108c
SS
548
549 case AngelSWI_Reason_Seek:
dfcd3bfb
JM
550 state->Reg[0] = -1 >= lseek (ARMul_ReadWord (state, addr),
551 ARMul_ReadWord (state, addr + 4),
c906108c
SS
552 SEEK_SET);
553 OSptr->ErrorNo = errno;
1e5d4e46 554 break;
c906108c
SS
555
556 case AngelSWI_Reason_FLen:
557 SWIflen (state, ARMul_ReadWord (state, addr));
1e5d4e46 558 break;
c906108c 559
dfcd3bfb 560 case AngelSWI_Reason_GetCmdLine:
c906108c 561 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
1e5d4e46 562 break;
c906108c
SS
563
564 case AngelSWI_Reason_HeapInfo:
7f53bc35 565 /* R1 is a pointer to a pointer. */
c906108c
SS
566 addr = ARMul_ReadWord (state, addr);
567
7f53bc35 568 /* Pick up the right memory limit. */
c906108c
SS
569 if (state->MemSize)
570 temp = state->MemSize;
571 else
572 temp = ADDRUSERSTACK;
573
dfcd3bfb
JM
574 ARMul_WriteWord (state, addr, 0); /* Heap base */
575 ARMul_WriteWord (state, addr + 4, temp); /* Heap limit */
576 ARMul_WriteWord (state, addr + 8, temp); /* Stack base */
577 ARMul_WriteWord (state, addr + 12, temp); /* Stack limit */
1e5d4e46 578 break;
c906108c
SS
579
580 case AngelSWI_Reason_ReportException:
581 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
582 state->Reg[0] = 0;
583 else
584 state->Reg[0] = -1;
dfcd3bfb 585 state->Emulate = FALSE;
1e5d4e46 586 break;
c906108c
SS
587
588 case ADP_Stopped_ApplicationExit:
589 state->Reg[0] = 0;
dfcd3bfb 590 state->Emulate = FALSE;
1e5d4e46 591 break;
dfcd3bfb 592
c906108c
SS
593 case ADP_Stopped_RunTimeError:
594 state->Reg[0] = -1;
dfcd3bfb 595 state->Emulate = FALSE;
1e5d4e46 596 break;
c906108c
SS
597
598 case AngelSWI_Reason_Errno:
599 state->Reg[0] = OSptr->ErrorNo;
1e5d4e46 600 break;
c906108c
SS
601
602 case AngelSWI_Reason_Open:
dfcd3bfb
JM
603 SWIopen (state,
604 ARMul_ReadWord (state, addr),
605 ARMul_ReadWord (state, addr + 4));
1e5d4e46 606 break;
c906108c
SS
607
608 case AngelSWI_Reason_Read:
dfcd3bfb
JM
609 SWIread (state,
610 ARMul_ReadWord (state, addr),
611 ARMul_ReadWord (state, addr + 4),
612 ARMul_ReadWord (state, addr + 8));
1e5d4e46 613 break;
c906108c
SS
614
615 case AngelSWI_Reason_Write:
dfcd3bfb
JM
616 SWIwrite (state,
617 ARMul_ReadWord (state, addr),
618 ARMul_ReadWord (state, addr + 4),
619 ARMul_ReadWord (state, addr + 8));
1e5d4e46 620 break;
c906108c
SS
621 }
622
f1129fb8 623 case 0x90:
9a6b6a66 624 case 0x91:
f1129fb8
NC
625 case 0x92:
626 /* These are used by the FPE code. */
1e5d4e46 627 break;
f1129fb8 628
dfcd3bfb 629 default:
1e5d4e46
NC
630 /* If there is a SWI vector installed use it. */
631 if (state->is_XScale && saved_number != -1)
632 number = saved_number;
7f53bc35 633
1e5d4e46
NC
634 if (SWI_vector_installed && number != SWI_Breakpoint)
635 {
636 ARMword cpsr;
637 ARMword i_size;
94ab9d7b 638
1e5d4e46
NC
639 cpsr = ARMul_GetCPSR (state);
640 i_size = INSN_SIZE;
94ab9d7b 641
1e5d4e46 642 ARMul_SetSPSR (state, SVC32MODE, cpsr);
94ab9d7b 643
1e5d4e46
NC
644 cpsr &= ~0xbf;
645 cpsr |= SVC32MODE | 0x80;
646 ARMul_SetCPSR (state, cpsr);
94ab9d7b 647
1e5d4e46
NC
648 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
649 state->NextInstr = RESUME;
650 state->Reg[15] = state->pc = ARMSWIV;
651 FLUSHPIPE;
652 }
653 else
654 {
f1129fb8 655 fprintf (stderr, "unknown SWI encountered - %x - ignoring\n", number);
1e5d4e46
NC
656 return FALSE;
657 }
c906108c 658 }
1e5d4e46 659
1e5d4e46 660 return TRUE;
c906108c
SS
661}
662
c906108c
SS
663#ifndef NOOS
664#ifndef ASIM
665
f1129fb8
NC
666/* The emulator calls this routine when an Exception occurs. The second
667 parameter is the address of the relevant exception vector. Returning
668 FALSE from this routine causes the trap to be taken, TRUE causes it to
669 be ignored (so set state->Emulate to FALSE!). */
c906108c 670
dfcd3bfb 671unsigned
7f53bc35 672ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
f1129fb8
NC
673 ARMword vector ATTRIBUTE_UNUSED,
674 ARMword pc ATTRIBUTE_UNUSED)
675{
917bca4f 676 return FALSE;
c906108c
SS
677}
678
679#endif
c906108c 680#endif /* NOOS */
This page took 0.159454 seconds and 4 git commands to generate.