]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/armos.c
* arch-utils.c (generic_register_byte): Fix to use the loop index
[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
d8512e6a 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
3c25f8c7 86#include "gdb/callback.h"
b3ba81f8
KS
87extern host_callback *sim_callback;
88
d8512e6a
NC
89extern unsigned ARMul_OSInit (ARMul_State *);
90extern void ARMul_OSExit (ARMul_State *);
91extern unsigned ARMul_OSHandleSWI (ARMul_State *, ARMword);
92extern unsigned ARMul_OSException (ARMul_State *, ARMword, ARMword);
93extern ARMword ARMul_OSLastErrorP (ARMul_State *);
94extern ARMword ARMul_Debug (ARMul_State *, ARMword, ARMword);
c906108c
SS
95
96#define BUFFERSIZE 4096
97#ifndef FOPEN_MAX
98#define FOPEN_MAX 64
99#endif
100#define UNIQUETEMPS 256
101
7f53bc35 102/* OS private Information. */
c906108c 103
dfcd3bfb
JM
104struct OSblock
105{
106 ARMword Time0;
107 ARMword ErrorP;
108 ARMword ErrorNo;
109 FILE *FileTable[FOPEN_MAX];
110 char FileFlags[FOPEN_MAX];
111 char *tempnames[UNIQUETEMPS];
112};
c906108c
SS
113
114#define NOOP 0
115#define BINARY 1
116#define READOP 2
117#define WRITEOP 4
118
119#ifdef macintosh
120#define FIXCRLF(t,c) ((t & BINARY) ? \
121 c : \
122 ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
123 )
dfcd3bfb
JM
124#else
125#define FIXCRLF(t,c) c
c906108c
SS
126#endif
127
de4112fa
NC
128/* Bit mask of enabled SWI implementations. */
129unsigned int swi_mask = -1;
130
131
6d358e86 132static ARMword softvectorcode[] =
7f53bc35
NC
133{
134 /* Basic: swi tidyexception + event; mov pc, lr;
135 ldmia r11,{r11,pc}; swi generateexception + event. */
136 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
137 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
138 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
139 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
140 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
141 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
142 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
143 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
144 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
145 0xe1a0f00e /* Default handler */
c906108c
SS
146};
147
7f53bc35 148/* Time for the Operating System to initialise itself. */
c906108c 149
dfcd3bfb
JM
150unsigned
151ARMul_OSInit (ARMul_State * state)
c906108c
SS
152{
153#ifndef NOOS
154#ifndef VALIDATE
dfcd3bfb
JM
155 ARMword instr, i, j;
156 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
157
158 if (state->OSptr == NULL)
159 {
160 state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
161 if (state->OSptr == NULL)
162 {
163 perror ("OS Memory");
164 exit (15);
165 }
c906108c 166 }
7f53bc35 167
dfcd3bfb
JM
168 OSptr = (struct OSblock *) state->OSptr;
169 OSptr->ErrorP = 0;
d8512e6a
NC
170 state->Reg[13] = ADDRSUPERSTACK; /* Set up a stack for the current mode... */
171 ARMul_SetReg (state, SVC32MODE, 13, ADDRSUPERSTACK);/* ...and for supervisor mode... */
172 ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);/* ...and for abort 32 mode... */
173 ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode... */
174 ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK);/* ...and for system mode. */
175 instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8); /* Load pc from soft vector */
7f53bc35 176
dfcd3bfb 177 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
ace4f296
NC
178 /* Write hardware vectors. */
179 ARMul_WriteWord (state, i, instr);
7f53bc35 180
88694af3
NC
181 SWI_vector_installed = 0;
182
dfcd3bfb
JM
183 for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
184 {
185 ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
186 ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
187 SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
c906108c 188 }
7f53bc35 189
dfcd3bfb
JM
190 for (i = 0; i < sizeof (softvectorcode); i += 4)
191 ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
7f53bc35 192
dfcd3bfb
JM
193 for (i = 0; i < FOPEN_MAX; i++)
194 OSptr->FileTable[i] = NULL;
7f53bc35 195
dfcd3bfb
JM
196 for (i = 0; i < UNIQUETEMPS; i++)
197 OSptr->tempnames[i] = NULL;
7f53bc35 198
dfcd3bfb 199 ARMul_ConsolePrint (state, ", Demon 1.01");
c906108c
SS
200
201/* #ifndef ASIM */
202
d8512e6a
NC
203 /* Install FPE. */
204 for (i = 0; i < fpesize; i += 4)
205 /* Copy the code. */
dfcd3bfb 206 ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
7f53bc35 207
dfcd3bfb 208 for (i = FPESTART + fpesize;; i -= 4)
d8512e6a
NC
209 {
210 /* Reverse the error strings. */
dfcd3bfb
JM
211 if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
212 break;
213 if (state->bigendSig && j < 0x80000000)
d8512e6a
NC
214 {
215 /* It's part of the string so swap it. */
dfcd3bfb
JM
216 j = ((j >> 0x18) & 0x000000ff) |
217 ((j >> 0x08) & 0x0000ff00) |
218 ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
219 ARMul_WriteWord (state, i, j);
220 }
c906108c 221 }
7f53bc35 222
d8512e6a
NC
223 /* Copy old illegal instr vector. */
224 ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, 4));
225 /* Install new vector. */
226 ARMul_WriteWord (state, 4, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
dfcd3bfb 227 ARMul_ConsolePrint (state, ", FPE");
c906108c 228
6d358e86 229/* #endif ASIM */
c906108c
SS
230#endif /* VALIDATE */
231#endif /* NOOS */
232
de4112fa
NC
233 /* Intel do not want DEMON SWI support. */
234 if (state->is_XScale)
235 swi_mask = SWI_MASK_ANGEL;
10b57fcb
NC
236
237 return TRUE;
c906108c
SS
238}
239
dfcd3bfb
JM
240void
241ARMul_OSExit (ARMul_State * state)
c906108c 242{
dfcd3bfb 243 free ((char *) state->OSptr);
c906108c
SS
244}
245
246
7f53bc35 247/* Return the last Operating System Error. */
c906108c 248
dfcd3bfb 249ARMword ARMul_OSLastErrorP (ARMul_State * state)
c906108c 250{
dfcd3bfb 251 return ((struct OSblock *) state->OSptr)->ErrorP;
c906108c
SS
252}
253
7f53bc35
NC
254static int translate_open_mode[] =
255{
dfcd3bfb
JM
256 O_RDONLY, /* "r" */
257 O_RDONLY + O_BINARY, /* "rb" */
258 O_RDWR, /* "r+" */
259 O_RDWR + O_BINARY, /* "r+b" */
260 O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
261 O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
262 O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
263 O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
264 O_WRONLY + O_APPEND + O_CREAT, /* "a" */
265 O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
266 O_RDWR + O_APPEND + O_CREAT, /* "a+" */
267 O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
c906108c
SS
268};
269
dfcd3bfb
JM
270static void
271SWIWrite0 (ARMul_State * state, ARMword addr)
c906108c
SS
272{
273 ARMword temp;
dfcd3bfb 274 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c 275
917bca4f 276 while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
b3ba81f8 277 (void) sim_callback->write_stdout (sim_callback, (char *) &temp, 1);
c906108c 278
b3ba81f8 279 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
280}
281
dfcd3bfb
JM
282static void
283WriteCommandLineTo (ARMul_State * state, ARMword addr)
c906108c
SS
284{
285 ARMword temp;
286 char *cptr = state->CommandLine;
7f53bc35 287
c906108c
SS
288 if (cptr == NULL)
289 cptr = "\0";
dfcd3bfb
JM
290 do
291 {
292 temp = (ARMword) * cptr++;
917bca4f 293 ARMul_SafeWriteByte (state, addr++, temp);
dfcd3bfb
JM
294 }
295 while (temp != 0);
c906108c
SS
296}
297
dfcd3bfb
JM
298static void
299SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
c906108c 300{
dfcd3bfb 301 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
302 char dummy[2000];
303 int flags;
304 int i;
305
917bca4f 306 for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++)
c906108c
SS
307 ;
308
7f53bc35 309 /* Now we need to decode the Demon open mode. */
c906108c
SS
310 flags = translate_open_mode[SWIflags];
311
7f53bc35 312 /* Filename ":tt" is special: it denotes stdin/out. */
c906108c
SS
313 if (strcmp (dummy, ":tt") == 0)
314 {
dfcd3bfb
JM
315 if (flags == O_RDONLY) /* opening tty "r" */
316 state->Reg[0] = 0; /* stdin */
317 else
318 state->Reg[0] = 1; /* stdout */
c906108c
SS
319 }
320 else
321 {
b3ba81f8
KS
322 state->Reg[0] = sim_callback->open (sim_callback, dummy, flags);
323 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
324 }
325}
326
dfcd3bfb
JM
327static void
328SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 329{
dfcd3bfb 330 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
331 int res;
332 int i;
333 char *local = malloc (len);
334
c2d11a7d
JM
335 if (local == NULL)
336 {
d8512e6a
NC
337 sim_callback->printf_filtered
338 (sim_callback,
339 "sim: Unable to read 0x%ulx bytes - out of memory\n",
340 len);
c2d11a7d
JM
341 return;
342 }
dfcd3bfb 343
b3ba81f8 344 res = sim_callback->read (sim_callback, f, local, len);
c906108c 345 if (res > 0)
dfcd3bfb 346 for (i = 0; i < res; i++)
917bca4f 347 ARMul_SafeWriteByte (state, ptr + i, local[i]);
7f53bc35 348
c906108c
SS
349 free (local);
350 state->Reg[0] = res == -1 ? -1 : len - res;
b3ba81f8 351 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
352}
353
dfcd3bfb
JM
354static void
355SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 356{
dfcd3bfb 357 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c 358 int res;
6d358e86 359 ARMword i;
c906108c
SS
360 char *local = malloc (len);
361
c2d11a7d 362 if (local == NULL)
c906108c 363 {
d8512e6a
NC
364 sim_callback->printf_filtered
365 (sim_callback,
366 "sim: Unable to write 0x%lx bytes - out of memory\n",
367 (long) len);
c2d11a7d 368 return;
c906108c 369 }
dfcd3bfb
JM
370
371 for (i = 0; i < len; i++)
917bca4f 372 local[i] = ARMul_SafeReadByte (state, ptr + i);
c2d11a7d 373
b3ba81f8 374 res = sim_callback->write (sim_callback, f, local, len);
c906108c
SS
375 state->Reg[0] = res == -1 ? -1 : len - res;
376 free (local);
7f53bc35 377
b3ba81f8 378 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
379}
380
dfcd3bfb
JM
381static void
382SWIflen (ARMul_State * state, ARMword fh)
c906108c 383{
dfcd3bfb 384 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
385 ARMword addr;
386
387 if (fh == 0 || fh > FOPEN_MAX)
388 {
389 OSptr->ErrorNo = EBADF;
390 state->Reg[0] = -1L;
391 return;
392 }
393
b3ba81f8 394 addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
6d358e86 395
b3ba81f8
KS
396 state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
397 (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
c906108c 398
b3ba81f8 399 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
400}
401
7f53bc35
NC
402/* The emulator calls this routine when a SWI instruction is encuntered.
403 The parameter passed is the SWI number (lower 24 bits of the instruction). */
c906108c 404
dfcd3bfb
JM
405unsigned
406ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
c906108c 407{
1e5d4e46 408 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
de4112fa
NC
409 int unhandled = FALSE;
410
c906108c
SS
411 switch (number)
412 {
413 case SWI_Read:
de4112fa
NC
414 if (swi_mask & SWI_MASK_DEMON)
415 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
416 else
417 unhandled = TRUE;
1e5d4e46 418 break;
c906108c
SS
419
420 case SWI_Write:
de4112fa
NC
421 if (swi_mask & SWI_MASK_DEMON)
422 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
423 else
424 unhandled = TRUE;
1e5d4e46 425 break;
c906108c
SS
426
427 case SWI_Open:
de4112fa
NC
428 if (swi_mask & SWI_MASK_DEMON)
429 SWIopen (state, state->Reg[0], state->Reg[1]);
430 else
431 unhandled = TRUE;
1e5d4e46 432 break;
c906108c 433
dfcd3bfb 434 case SWI_Clock:
de4112fa
NC
435 if (swi_mask & SWI_MASK_DEMON)
436 {
437 /* Return number of centi-seconds. */
438 state->Reg[0] =
c906108c 439#ifdef CLOCKS_PER_SEC
de4112fa
NC
440 (CLOCKS_PER_SEC >= 100)
441 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
442 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 443#else
de4112fa
NC
444 /* Presume unix... clock() returns microseconds. */
445 (ARMword) (clock () / 10000);
c906108c 446#endif
de4112fa
NC
447 OSptr->ErrorNo = errno;
448 }
449 else
450 unhandled = TRUE;
1e5d4e46 451 break;
dfcd3bfb
JM
452
453 case SWI_Time:
de4112fa
NC
454 if (swi_mask & SWI_MASK_DEMON)
455 {
456 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
457 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
458 }
459 else
460 unhandled = TRUE;
1e5d4e46 461 break;
dfcd3bfb 462
c906108c 463 case SWI_Close:
de4112fa
NC
464 if (swi_mask & SWI_MASK_DEMON)
465 {
466 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
467 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
468 }
469 else
470 unhandled = TRUE;
1e5d4e46 471 break;
c906108c 472
dfcd3bfb 473 case SWI_Flen:
de4112fa
NC
474 if (swi_mask & SWI_MASK_DEMON)
475 SWIflen (state, state->Reg[0]);
476 else
477 unhandled = TRUE;
1e5d4e46 478 break;
c906108c
SS
479
480 case SWI_Exit:
de4112fa
NC
481 if (swi_mask & SWI_MASK_DEMON)
482 state->Emulate = FALSE;
483 else
484 unhandled = TRUE;
1e5d4e46 485 break;
c906108c
SS
486
487 case SWI_Seek:
de4112fa
NC
488 if (swi_mask & SWI_MASK_DEMON)
489 {
490 /* We must return non-zero for failure. */
491 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET);
492 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
493 }
494 else
495 unhandled = TRUE;
1e5d4e46 496 break;
c906108c 497
dfcd3bfb 498 case SWI_WriteC:
de4112fa
NC
499 if (swi_mask & SWI_MASK_DEMON)
500 {
501 char tmp = state->Reg[0];
502 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
503 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
504 }
505 else
506 unhandled = TRUE;
1e5d4e46 507 break;
c906108c 508
dfcd3bfb 509 case SWI_Write0:
de4112fa
NC
510 if (swi_mask & SWI_MASK_DEMON)
511 SWIWrite0 (state, state->Reg[0]);
512 else
513 unhandled = TRUE;
1e5d4e46 514 break;
c906108c 515
dfcd3bfb 516 case SWI_GetErrno:
de4112fa
NC
517 if (swi_mask & SWI_MASK_DEMON)
518 state->Reg[0] = OSptr->ErrorNo;
519 else
520 unhandled = TRUE;
1e5d4e46 521 break;
c906108c 522
dfcd3bfb 523 case SWI_GetEnv:
de4112fa
NC
524 if (swi_mask & SWI_MASK_DEMON)
525 {
526 state->Reg[0] = ADDRCMDLINE;
527 if (state->MemSize)
528 state->Reg[1] = state->MemSize;
529 else
530 state->Reg[1] = ADDRUSERSTACK;
c906108c 531
de4112fa
NC
532 WriteCommandLineTo (state, state->Reg[0]);
533 }
534 else
535 unhandled = TRUE;
1e5d4e46 536 break;
7f53bc35 537
f1129fb8
NC
538 case SWI_Breakpoint:
539 state->EndCondition = RDIError_BreakpointReached;
540 state->Emulate = FALSE;
1e5d4e46 541 break;
c906108c 542
7f53bc35 543 /* Handle Angel SWIs as well as Demon ones. */
c906108c
SS
544 case AngelSWI_ARM:
545 case AngelSWI_Thumb:
de4112fa 546 if (swi_mask & SWI_MASK_ANGEL)
c906108c 547 {
de4112fa
NC
548 ARMword addr;
549 ARMword temp;
550
551 /* R1 is almost always a parameter block. */
552 addr = state->Reg[1];
553 /* R0 is a reason code. */
554 switch (state->Reg[0])
555 {
c7a7b500
NC
556 case -1:
557 /* This can happen when a SWI is interrupted (eg receiving a
558 ctrl-C whilst processing SWIRead()). The SWI will complete
559 returning -1 in r0 to the caller. If GDB is then used to
560 resume the system call the reason code will now be -1. */
2ec3c90a 561 return TRUE;
c7a7b500 562
de4112fa
NC
563 /* Unimplemented reason codes. */
564 case AngelSWI_Reason_ReadC:
565 case AngelSWI_Reason_IsTTY:
566 case AngelSWI_Reason_TmpNam:
567 case AngelSWI_Reason_Remove:
568 case AngelSWI_Reason_Rename:
569 case AngelSWI_Reason_System:
570 case AngelSWI_Reason_EnterSVC:
571 default:
572 state->Emulate = FALSE;
573 return FALSE;
574
575 case AngelSWI_Reason_Clock:
576 /* Return number of centi-seconds. */
577 state->Reg[0] =
c906108c 578#ifdef CLOCKS_PER_SEC
de4112fa
NC
579 (CLOCKS_PER_SEC >= 100)
580 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
581 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 582#else
de4112fa
NC
583 /* Presume unix... clock() returns microseconds. */
584 (ARMword) (clock () / 10000);
c906108c 585#endif
de4112fa
NC
586 OSptr->ErrorNo = errno;
587 break;
588
589 case AngelSWI_Reason_Time:
590 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
591 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
592 break;
593
594 case AngelSWI_Reason_WriteC:
595 {
596 char tmp = ARMul_SafeReadByte (state, addr);
597 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
598 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
599 break;
600 }
601
602 case AngelSWI_Reason_Write0:
603 SWIWrite0 (state, addr);
604 break;
605
606 case AngelSWI_Reason_Close:
607 state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
608 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
609 break;
610
611 case AngelSWI_Reason_Seek:
612 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
613 ARMul_ReadWord (state, addr + 4),
614 SEEK_SET);
615 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
616 break;
617
618 case AngelSWI_Reason_FLen:
619 SWIflen (state, ARMul_ReadWord (state, addr));
620 break;
621
622 case AngelSWI_Reason_GetCmdLine:
623 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
624 break;
625
626 case AngelSWI_Reason_HeapInfo:
627 /* R1 is a pointer to a pointer. */
628 addr = ARMul_ReadWord (state, addr);
629
630 /* Pick up the right memory limit. */
631 if (state->MemSize)
632 temp = state->MemSize;
633 else
634 temp = ADDRUSERSTACK;
635
636 ARMul_WriteWord (state, addr, 0); /* Heap base. */
637 ARMul_WriteWord (state, addr + 4, temp); /* Heap limit. */
638 ARMul_WriteWord (state, addr + 8, temp); /* Stack base. */
639 ARMul_WriteWord (state, addr + 12, temp); /* Stack limit. */
640 break;
641
642 case AngelSWI_Reason_ReportException:
643 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
644 state->Reg[0] = 0;
645 else
646 state->Reg[0] = -1;
647 state->Emulate = FALSE;
648 break;
649
650 case ADP_Stopped_ApplicationExit:
651 state->Reg[0] = 0;
652 state->Emulate = FALSE;
653 break;
654
655 case ADP_Stopped_RunTimeError:
656 state->Reg[0] = -1;
657 state->Emulate = FALSE;
658 break;
659
660 case AngelSWI_Reason_Errno:
661 state->Reg[0] = OSptr->ErrorNo;
662 break;
663
664 case AngelSWI_Reason_Open:
665 SWIopen (state,
666 ARMul_ReadWord (state, addr),
667 ARMul_ReadWord (state, addr + 4));
668 break;
669
670 case AngelSWI_Reason_Read:
671 SWIread (state,
672 ARMul_ReadWord (state, addr),
673 ARMul_ReadWord (state, addr + 4),
674 ARMul_ReadWord (state, addr + 8));
675 break;
676
677 case AngelSWI_Reason_Write:
678 SWIwrite (state,
679 ARMul_ReadWord (state, addr),
680 ARMul_ReadWord (state, addr + 4),
681 ARMul_ReadWord (state, addr + 8));
682 break;
683 }
c906108c 684 }
de4112fa
NC
685 else
686 unhandled = TRUE;
687 break;
c906108c 688
f1129fb8 689 case 0x90:
9a6b6a66 690 case 0x91:
f1129fb8
NC
691 case 0x92:
692 /* These are used by the FPE code. */
1e5d4e46 693 break;
f1129fb8 694
c7a7b500
NC
695 case -1:
696 /* This can happen when a SWI is interrupted (eg receiving a
697 ctrl-C whilst processing SWIRead()). The SWI will complete
698 returning -1 in r0 to the caller. If GDB is then used to
699 resume the system call the reason code will now be -1. */
2ec3c90a 700 return TRUE;
c7a7b500 701
d8512e6a 702 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
de4112fa 703 if (swi_mask & SWI_MASK_REDBOOT)
d8512e6a 704 {
de4112fa
NC
705 switch (state->Reg[0])
706 {
707 /* These numbers are defined in libgloss/syscall.h
708 but the simulator should not be dependend upon
709 libgloss being installed. */
710 case 1: /* Exit. */
711 state->Emulate = FALSE;
712 /* Copy exit code into r0. */
713 state->Reg[0] = state->Reg[1];
714 break;
715
716 case 2: /* Open. */
717 SWIopen (state, state->Reg[1], state->Reg[2]);
718 break;
719
720 case 3: /* Close. */
721 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
722 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
723 break;
724
725 case 4: /* Read. */
726 SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
727 break;
728
729 case 5: /* Write. */
730 SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
731 break;
732
733 case 6: /* Lseek. */
734 state->Reg[0] = sim_callback->lseek (sim_callback,
735 state->Reg[1],
736 state->Reg[2],
737 state->Reg[3]);
738 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
739 break;
740
741 case 17: /* Utime. */
742 state->Reg[0] = (ARMword) sim_callback->time (sim_callback,
743 (long *) state->Reg[1]);
744 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
745 break;
746
747 case 7: /* Unlink. */
748 case 8: /* Getpid. */
749 case 9: /* Kill. */
750 case 10: /* Fstat. */
751 case 11: /* Sbrk. */
752 case 12: /* Argvlen. */
753 case 13: /* Argv. */
754 case 14: /* ChDir. */
755 case 15: /* Stat. */
756 case 16: /* Chmod. */
757 case 18: /* Time. */
758 sim_callback->printf_filtered
759 (sim_callback,
760 "sim: unhandled RedBoot syscall '%d' encountered - ignoring\n",
761 state->Reg[0]);
762 return FALSE;
763
764 default:
765 sim_callback->printf_filtered
766 (sim_callback,
767 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
768 state->Reg[0]);
769 return FALSE;
770 }
771 break;
d8512e6a 772 }
d8512e6a 773
dfcd3bfb 774 default:
de4112fa
NC
775 unhandled = TRUE;
776 }
777
778 if (unhandled)
779 {
780 if (SWI_vector_installed)
1e5d4e46
NC
781 {
782 ARMword cpsr;
783 ARMword i_size;
94ab9d7b 784
1e5d4e46
NC
785 cpsr = ARMul_GetCPSR (state);
786 i_size = INSN_SIZE;
94ab9d7b 787
1e5d4e46 788 ARMul_SetSPSR (state, SVC32MODE, cpsr);
94ab9d7b 789
1e5d4e46
NC
790 cpsr &= ~0xbf;
791 cpsr |= SVC32MODE | 0x80;
792 ARMul_SetCPSR (state, cpsr);
94ab9d7b 793
1e5d4e46
NC
794 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
795 state->NextInstr = RESUME;
796 state->Reg[15] = state->pc = ARMSWIV;
797 FLUSHPIPE;
798 }
799 else
800 {
d8512e6a
NC
801 sim_callback->printf_filtered
802 (sim_callback,
803 "sim: unknown SWI encountered - %x - ignoring\n",
804 number);
1e5d4e46
NC
805 return FALSE;
806 }
c906108c 807 }
1e5d4e46 808
1e5d4e46 809 return TRUE;
c906108c
SS
810}
811
c906108c
SS
812#ifndef NOOS
813#ifndef ASIM
814
f1129fb8
NC
815/* The emulator calls this routine when an Exception occurs. The second
816 parameter is the address of the relevant exception vector. Returning
817 FALSE from this routine causes the trap to be taken, TRUE causes it to
818 be ignored (so set state->Emulate to FALSE!). */
c906108c 819
dfcd3bfb 820unsigned
7f53bc35 821ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
f1129fb8
NC
822 ARMword vector ATTRIBUTE_UNUSED,
823 ARMword pc ATTRIBUTE_UNUSED)
824{
917bca4f 825 return FALSE;
c906108c
SS
826}
827
828#endif
c906108c 829#endif /* NOOS */