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