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