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