(SWIWrite0): Catch big-endian bug when printing characters
[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
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)
0d9fd8f1
NC
277 {
278 char buffer = temp;
279 /* Note - we cannot just cast 'temp' to a (char *) here,
280 since on a big-endian host the byte value will end
281 up in the wrong place and a nul character will be printed. */
282 (void) sim_callback->write_stdout (sim_callback, & buffer, 1);
283 }
c906108c 284
b3ba81f8 285 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
286}
287
dfcd3bfb
JM
288static void
289WriteCommandLineTo (ARMul_State * state, ARMword addr)
c906108c
SS
290{
291 ARMword temp;
292 char *cptr = state->CommandLine;
7f53bc35 293
c906108c
SS
294 if (cptr == NULL)
295 cptr = "\0";
dfcd3bfb
JM
296 do
297 {
298 temp = (ARMword) * cptr++;
917bca4f 299 ARMul_SafeWriteByte (state, addr++, temp);
dfcd3bfb
JM
300 }
301 while (temp != 0);
c906108c
SS
302}
303
dfcd3bfb
JM
304static void
305SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
c906108c 306{
dfcd3bfb 307 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
308 char dummy[2000];
309 int flags;
310 int i;
311
917bca4f 312 for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++)
c906108c
SS
313 ;
314
7f53bc35 315 /* Now we need to decode the Demon open mode. */
c906108c
SS
316 flags = translate_open_mode[SWIflags];
317
7f53bc35 318 /* Filename ":tt" is special: it denotes stdin/out. */
c906108c
SS
319 if (strcmp (dummy, ":tt") == 0)
320 {
dfcd3bfb
JM
321 if (flags == O_RDONLY) /* opening tty "r" */
322 state->Reg[0] = 0; /* stdin */
323 else
324 state->Reg[0] = 1; /* stdout */
c906108c
SS
325 }
326 else
327 {
b3ba81f8
KS
328 state->Reg[0] = sim_callback->open (sim_callback, dummy, flags);
329 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
330 }
331}
332
dfcd3bfb
JM
333static void
334SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 335{
dfcd3bfb 336 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
337 int res;
338 int i;
339 char *local = malloc (len);
340
c2d11a7d
JM
341 if (local == NULL)
342 {
d8512e6a
NC
343 sim_callback->printf_filtered
344 (sim_callback,
345 "sim: Unable to read 0x%ulx bytes - out of memory\n",
346 len);
c2d11a7d
JM
347 return;
348 }
dfcd3bfb 349
b3ba81f8 350 res = sim_callback->read (sim_callback, f, local, len);
c906108c 351 if (res > 0)
dfcd3bfb 352 for (i = 0; i < res; i++)
917bca4f 353 ARMul_SafeWriteByte (state, ptr + i, local[i]);
7f53bc35 354
c906108c
SS
355 free (local);
356 state->Reg[0] = res == -1 ? -1 : len - res;
b3ba81f8 357 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
358}
359
dfcd3bfb
JM
360static void
361SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 362{
dfcd3bfb 363 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c 364 int res;
6d358e86 365 ARMword i;
c906108c
SS
366 char *local = malloc (len);
367
c2d11a7d 368 if (local == NULL)
c906108c 369 {
d8512e6a
NC
370 sim_callback->printf_filtered
371 (sim_callback,
372 "sim: Unable to write 0x%lx bytes - out of memory\n",
373 (long) len);
c2d11a7d 374 return;
c906108c 375 }
dfcd3bfb
JM
376
377 for (i = 0; i < len; i++)
917bca4f 378 local[i] = ARMul_SafeReadByte (state, ptr + i);
c2d11a7d 379
b3ba81f8 380 res = sim_callback->write (sim_callback, f, local, len);
c906108c
SS
381 state->Reg[0] = res == -1 ? -1 : len - res;
382 free (local);
7f53bc35 383
b3ba81f8 384 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
385}
386
dfcd3bfb
JM
387static void
388SWIflen (ARMul_State * state, ARMword fh)
c906108c 389{
dfcd3bfb 390 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
391 ARMword addr;
392
393 if (fh == 0 || fh > FOPEN_MAX)
394 {
395 OSptr->ErrorNo = EBADF;
396 state->Reg[0] = -1L;
397 return;
398 }
399
b3ba81f8 400 addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
6d358e86 401
b3ba81f8
KS
402 state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
403 (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
c906108c 404
b3ba81f8 405 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
406}
407
7f53bc35
NC
408/* The emulator calls this routine when a SWI instruction is encuntered.
409 The parameter passed is the SWI number (lower 24 bits of the instruction). */
c906108c 410
dfcd3bfb
JM
411unsigned
412ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
c906108c 413{
1e5d4e46 414 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
de4112fa
NC
415 int unhandled = FALSE;
416
c906108c
SS
417 switch (number)
418 {
419 case SWI_Read:
de4112fa
NC
420 if (swi_mask & SWI_MASK_DEMON)
421 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
422 else
423 unhandled = TRUE;
1e5d4e46 424 break;
c906108c
SS
425
426 case SWI_Write:
de4112fa
NC
427 if (swi_mask & SWI_MASK_DEMON)
428 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
429 else
430 unhandled = TRUE;
1e5d4e46 431 break;
c906108c
SS
432
433 case SWI_Open:
de4112fa
NC
434 if (swi_mask & SWI_MASK_DEMON)
435 SWIopen (state, state->Reg[0], state->Reg[1]);
436 else
437 unhandled = TRUE;
1e5d4e46 438 break;
c906108c 439
dfcd3bfb 440 case SWI_Clock:
de4112fa
NC
441 if (swi_mask & SWI_MASK_DEMON)
442 {
443 /* Return number of centi-seconds. */
444 state->Reg[0] =
c906108c 445#ifdef CLOCKS_PER_SEC
de4112fa
NC
446 (CLOCKS_PER_SEC >= 100)
447 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
448 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 449#else
de4112fa
NC
450 /* Presume unix... clock() returns microseconds. */
451 (ARMword) (clock () / 10000);
c906108c 452#endif
de4112fa
NC
453 OSptr->ErrorNo = errno;
454 }
455 else
456 unhandled = TRUE;
1e5d4e46 457 break;
dfcd3bfb
JM
458
459 case SWI_Time:
de4112fa
NC
460 if (swi_mask & SWI_MASK_DEMON)
461 {
462 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
463 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
464 }
465 else
466 unhandled = TRUE;
1e5d4e46 467 break;
dfcd3bfb 468
c906108c 469 case SWI_Close:
de4112fa
NC
470 if (swi_mask & SWI_MASK_DEMON)
471 {
472 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
473 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
474 }
475 else
476 unhandled = TRUE;
1e5d4e46 477 break;
c906108c 478
dfcd3bfb 479 case SWI_Flen:
de4112fa
NC
480 if (swi_mask & SWI_MASK_DEMON)
481 SWIflen (state, state->Reg[0]);
482 else
483 unhandled = TRUE;
1e5d4e46 484 break;
c906108c
SS
485
486 case SWI_Exit:
de4112fa
NC
487 if (swi_mask & SWI_MASK_DEMON)
488 state->Emulate = FALSE;
489 else
490 unhandled = TRUE;
1e5d4e46 491 break;
c906108c
SS
492
493 case SWI_Seek:
de4112fa
NC
494 if (swi_mask & SWI_MASK_DEMON)
495 {
496 /* We must return non-zero for failure. */
497 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET);
498 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
499 }
500 else
501 unhandled = TRUE;
1e5d4e46 502 break;
c906108c 503
dfcd3bfb 504 case SWI_WriteC:
de4112fa
NC
505 if (swi_mask & SWI_MASK_DEMON)
506 {
507 char tmp = state->Reg[0];
508 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
509 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
510 }
511 else
512 unhandled = TRUE;
1e5d4e46 513 break;
c906108c 514
dfcd3bfb 515 case SWI_Write0:
de4112fa
NC
516 if (swi_mask & SWI_MASK_DEMON)
517 SWIWrite0 (state, state->Reg[0]);
518 else
519 unhandled = TRUE;
1e5d4e46 520 break;
c906108c 521
dfcd3bfb 522 case SWI_GetErrno:
de4112fa
NC
523 if (swi_mask & SWI_MASK_DEMON)
524 state->Reg[0] = OSptr->ErrorNo;
525 else
526 unhandled = TRUE;
1e5d4e46 527 break;
c906108c 528
dfcd3bfb 529 case SWI_GetEnv:
de4112fa
NC
530 if (swi_mask & SWI_MASK_DEMON)
531 {
532 state->Reg[0] = ADDRCMDLINE;
533 if (state->MemSize)
534 state->Reg[1] = state->MemSize;
535 else
536 state->Reg[1] = ADDRUSERSTACK;
c906108c 537
de4112fa
NC
538 WriteCommandLineTo (state, state->Reg[0]);
539 }
540 else
541 unhandled = TRUE;
1e5d4e46 542 break;
7f53bc35 543
f1129fb8
NC
544 case SWI_Breakpoint:
545 state->EndCondition = RDIError_BreakpointReached;
546 state->Emulate = FALSE;
1e5d4e46 547 break;
c906108c 548
7f53bc35 549 /* Handle Angel SWIs as well as Demon ones. */
c906108c
SS
550 case AngelSWI_ARM:
551 case AngelSWI_Thumb:
de4112fa 552 if (swi_mask & SWI_MASK_ANGEL)
c906108c 553 {
de4112fa
NC
554 ARMword addr;
555 ARMword temp;
556
557 /* R1 is almost always a parameter block. */
558 addr = state->Reg[1];
559 /* R0 is a reason code. */
560 switch (state->Reg[0])
561 {
c7a7b500
NC
562 case -1:
563 /* This can happen when a SWI is interrupted (eg receiving a
564 ctrl-C whilst processing SWIRead()). The SWI will complete
565 returning -1 in r0 to the caller. If GDB is then used to
566 resume the system call the reason code will now be -1. */
2ec3c90a 567 return TRUE;
c7a7b500 568
de4112fa
NC
569 /* Unimplemented reason codes. */
570 case AngelSWI_Reason_ReadC:
571 case AngelSWI_Reason_IsTTY:
572 case AngelSWI_Reason_TmpNam:
573 case AngelSWI_Reason_Remove:
574 case AngelSWI_Reason_Rename:
575 case AngelSWI_Reason_System:
576 case AngelSWI_Reason_EnterSVC:
577 default:
578 state->Emulate = FALSE;
579 return FALSE;
580
581 case AngelSWI_Reason_Clock:
582 /* Return number of centi-seconds. */
583 state->Reg[0] =
c906108c 584#ifdef CLOCKS_PER_SEC
de4112fa
NC
585 (CLOCKS_PER_SEC >= 100)
586 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
587 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 588#else
de4112fa
NC
589 /* Presume unix... clock() returns microseconds. */
590 (ARMword) (clock () / 10000);
c906108c 591#endif
de4112fa
NC
592 OSptr->ErrorNo = errno;
593 break;
594
595 case AngelSWI_Reason_Time:
596 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
597 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
598 break;
599
600 case AngelSWI_Reason_WriteC:
601 {
602 char tmp = ARMul_SafeReadByte (state, addr);
603 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
604 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
605 break;
606 }
607
608 case AngelSWI_Reason_Write0:
609 SWIWrite0 (state, addr);
610 break;
611
612 case AngelSWI_Reason_Close:
613 state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
614 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
615 break;
616
617 case AngelSWI_Reason_Seek:
618 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
619 ARMul_ReadWord (state, addr + 4),
620 SEEK_SET);
621 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
622 break;
623
624 case AngelSWI_Reason_FLen:
625 SWIflen (state, ARMul_ReadWord (state, addr));
626 break;
627
628 case AngelSWI_Reason_GetCmdLine:
629 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
630 break;
631
632 case AngelSWI_Reason_HeapInfo:
633 /* R1 is a pointer to a pointer. */
634 addr = ARMul_ReadWord (state, addr);
635
636 /* Pick up the right memory limit. */
637 if (state->MemSize)
638 temp = state->MemSize;
639 else
640 temp = ADDRUSERSTACK;
641
642 ARMul_WriteWord (state, addr, 0); /* Heap base. */
643 ARMul_WriteWord (state, addr + 4, temp); /* Heap limit. */
644 ARMul_WriteWord (state, addr + 8, temp); /* Stack base. */
645 ARMul_WriteWord (state, addr + 12, temp); /* Stack limit. */
646 break;
647
648 case AngelSWI_Reason_ReportException:
649 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
650 state->Reg[0] = 0;
651 else
652 state->Reg[0] = -1;
653 state->Emulate = FALSE;
654 break;
655
656 case ADP_Stopped_ApplicationExit:
657 state->Reg[0] = 0;
658 state->Emulate = FALSE;
659 break;
660
661 case ADP_Stopped_RunTimeError:
662 state->Reg[0] = -1;
663 state->Emulate = FALSE;
664 break;
665
666 case AngelSWI_Reason_Errno:
667 state->Reg[0] = OSptr->ErrorNo;
668 break;
669
670 case AngelSWI_Reason_Open:
671 SWIopen (state,
672 ARMul_ReadWord (state, addr),
673 ARMul_ReadWord (state, addr + 4));
674 break;
675
676 case AngelSWI_Reason_Read:
677 SWIread (state,
678 ARMul_ReadWord (state, addr),
679 ARMul_ReadWord (state, addr + 4),
680 ARMul_ReadWord (state, addr + 8));
681 break;
682
683 case AngelSWI_Reason_Write:
684 SWIwrite (state,
685 ARMul_ReadWord (state, addr),
686 ARMul_ReadWord (state, addr + 4),
687 ARMul_ReadWord (state, addr + 8));
688 break;
689 }
c906108c 690 }
de4112fa
NC
691 else
692 unhandled = TRUE;
693 break;
c906108c 694
f1129fb8 695 case 0x90:
9a6b6a66 696 case 0x91:
f1129fb8
NC
697 case 0x92:
698 /* These are used by the FPE code. */
1e5d4e46 699 break;
f1129fb8 700
c7a7b500
NC
701 case -1:
702 /* This can happen when a SWI is interrupted (eg receiving a
703 ctrl-C whilst processing SWIRead()). The SWI will complete
704 returning -1 in r0 to the caller. If GDB is then used to
705 resume the system call the reason code will now be -1. */
2ec3c90a 706 return TRUE;
c7a7b500 707
d8512e6a 708 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
de4112fa 709 if (swi_mask & SWI_MASK_REDBOOT)
d8512e6a 710 {
de4112fa
NC
711 switch (state->Reg[0])
712 {
713 /* These numbers are defined in libgloss/syscall.h
714 but the simulator should not be dependend upon
715 libgloss being installed. */
716 case 1: /* Exit. */
717 state->Emulate = FALSE;
718 /* Copy exit code into r0. */
719 state->Reg[0] = state->Reg[1];
720 break;
721
722 case 2: /* Open. */
723 SWIopen (state, state->Reg[1], state->Reg[2]);
724 break;
725
726 case 3: /* Close. */
727 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
728 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
729 break;
730
731 case 4: /* Read. */
732 SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
733 break;
734
735 case 5: /* Write. */
736 SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
737 break;
738
739 case 6: /* Lseek. */
740 state->Reg[0] = sim_callback->lseek (sim_callback,
741 state->Reg[1],
742 state->Reg[2],
743 state->Reg[3]);
744 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
745 break;
746
747 case 17: /* Utime. */
748 state->Reg[0] = (ARMword) sim_callback->time (sim_callback,
749 (long *) state->Reg[1]);
750 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
751 break;
752
753 case 7: /* Unlink. */
754 case 8: /* Getpid. */
755 case 9: /* Kill. */
756 case 10: /* Fstat. */
757 case 11: /* Sbrk. */
758 case 12: /* Argvlen. */
759 case 13: /* Argv. */
760 case 14: /* ChDir. */
761 case 15: /* Stat. */
762 case 16: /* Chmod. */
763 case 18: /* Time. */
764 sim_callback->printf_filtered
765 (sim_callback,
766 "sim: unhandled RedBoot syscall '%d' encountered - ignoring\n",
767 state->Reg[0]);
768 return FALSE;
769
770 default:
771 sim_callback->printf_filtered
772 (sim_callback,
773 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
774 state->Reg[0]);
775 return FALSE;
776 }
777 break;
d8512e6a 778 }
d8512e6a 779
dfcd3bfb 780 default:
de4112fa
NC
781 unhandled = TRUE;
782 }
783
784 if (unhandled)
785 {
786 if (SWI_vector_installed)
1e5d4e46
NC
787 {
788 ARMword cpsr;
789 ARMword i_size;
94ab9d7b 790
1e5d4e46
NC
791 cpsr = ARMul_GetCPSR (state);
792 i_size = INSN_SIZE;
94ab9d7b 793
1e5d4e46 794 ARMul_SetSPSR (state, SVC32MODE, cpsr);
94ab9d7b 795
1e5d4e46
NC
796 cpsr &= ~0xbf;
797 cpsr |= SVC32MODE | 0x80;
798 ARMul_SetCPSR (state, cpsr);
94ab9d7b 799
1e5d4e46
NC
800 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
801 state->NextInstr = RESUME;
802 state->Reg[15] = state->pc = ARMSWIV;
803 FLUSHPIPE;
804 }
805 else
806 {
d8512e6a
NC
807 sim_callback->printf_filtered
808 (sim_callback,
809 "sim: unknown SWI encountered - %x - ignoring\n",
810 number);
1e5d4e46
NC
811 return FALSE;
812 }
c906108c 813 }
1e5d4e46 814
1e5d4e46 815 return TRUE;
c906108c
SS
816}
817
c906108c
SS
818#ifndef NOOS
819#ifndef ASIM
820
f1129fb8
NC
821/* The emulator calls this routine when an Exception occurs. The second
822 parameter is the address of the relevant exception vector. Returning
823 FALSE from this routine causes the trap to be taken, TRUE causes it to
824 be ignored (so set state->Emulate to FALSE!). */
c906108c 825
dfcd3bfb 826unsigned
7f53bc35 827ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
f1129fb8
NC
828 ARMword vector ATTRIBUTE_UNUSED,
829 ARMword pc ATTRIBUTE_UNUSED)
830{
917bca4f 831 return FALSE;
c906108c
SS
832}
833
834#endif
c906108c 835#endif /* NOOS */
This page took 0.201021 seconds and 4 git commands to generate.