Add support for target specific command line switches to old-style simualtors.
[deliverable/binutils-gdb.git] / sim / arm / armos.c
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,
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. */
24
25 #include "config.h"
26 #include "ansidecl.h"
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
51 #include <unistd.h> /* For SEEK_SET etc. */
52 #endif
53
54 #ifdef __riscos
55 extern int _fisatty (FILE *);
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"
73 #include "armemu.h"
74
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
86 #include "callback.h"
87 extern host_callback *sim_callback;
88
89 extern unsigned ARMul_OSInit (ARMul_State *);
90 extern void ARMul_OSExit (ARMul_State *);
91 extern unsigned ARMul_OSHandleSWI (ARMul_State *, ARMword);
92 extern unsigned ARMul_OSException (ARMul_State *, ARMword, ARMword);
93 extern ARMword ARMul_OSLastErrorP (ARMul_State *);
94 extern ARMword ARMul_Debug (ARMul_State *, ARMword, ARMword);
95
96 #define BUFFERSIZE 4096
97 #ifndef FOPEN_MAX
98 #define FOPEN_MAX 64
99 #endif
100 #define UNIQUETEMPS 256
101
102 /* OS private Information. */
103
104 struct 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 };
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 )
124 #else
125 #define FIXCRLF(t,c) c
126 #endif
127
128 /* Bit mask of enabled SWI implementations. */
129 unsigned int swi_mask = -1;
130
131
132 static ARMword softvectorcode[] =
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 */
146 };
147
148 /* Time for the Operating System to initialise itself. */
149
150 unsigned
151 ARMul_OSInit (ARMul_State * state)
152 {
153 #ifndef NOOS
154 #ifndef VALIDATE
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 }
166 }
167
168 OSptr = (struct OSblock *) state->OSptr;
169 OSptr->ErrorP = 0;
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 */
176
177 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
178 /* Write hardware vectors. */
179 ARMul_WriteWord (state, i, instr);
180
181 SWI_vector_installed = 0;
182
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);
188 }
189
190 for (i = 0; i < sizeof (softvectorcode); i += 4)
191 ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
192
193 for (i = 0; i < FOPEN_MAX; i++)
194 OSptr->FileTable[i] = NULL;
195
196 for (i = 0; i < UNIQUETEMPS; i++)
197 OSptr->tempnames[i] = NULL;
198
199 ARMul_ConsolePrint (state, ", Demon 1.01");
200
201 /* #ifndef ASIM */
202
203 /* Install FPE. */
204 for (i = 0; i < fpesize; i += 4)
205 /* Copy the code. */
206 ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
207
208 for (i = FPESTART + fpesize;; i -= 4)
209 {
210 /* Reverse the error strings. */
211 if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
212 break;
213 if (state->bigendSig && j < 0x80000000)
214 {
215 /* It's part of the string so swap it. */
216 j = ((j >> 0x18) & 0x000000ff) |
217 ((j >> 0x08) & 0x0000ff00) |
218 ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
219 ARMul_WriteWord (state, i, j);
220 }
221 }
222
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)));
227 ARMul_ConsolePrint (state, ", FPE");
228
229 /* #endif ASIM */
230 #endif /* VALIDATE */
231 #endif /* NOOS */
232
233 /* Intel do not want DEMON SWI support. */
234 if (state->is_XScale)
235 swi_mask = SWI_MASK_ANGEL;
236
237 return TRUE;
238 }
239
240 void
241 ARMul_OSExit (ARMul_State * state)
242 {
243 free ((char *) state->OSptr);
244 }
245
246
247 /* Return the last Operating System Error. */
248
249 ARMword ARMul_OSLastErrorP (ARMul_State * state)
250 {
251 return ((struct OSblock *) state->OSptr)->ErrorP;
252 }
253
254 static int translate_open_mode[] =
255 {
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" */
268 };
269
270 static void
271 SWIWrite0 (ARMul_State * state, ARMword addr)
272 {
273 ARMword temp;
274 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
275
276 while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
277 (void) sim_callback->write_stdout (sim_callback, (char *) &temp, 1);
278
279 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
280 }
281
282 static void
283 WriteCommandLineTo (ARMul_State * state, ARMword addr)
284 {
285 ARMword temp;
286 char *cptr = state->CommandLine;
287
288 if (cptr == NULL)
289 cptr = "\0";
290 do
291 {
292 temp = (ARMword) * cptr++;
293 ARMul_SafeWriteByte (state, addr++, temp);
294 }
295 while (temp != 0);
296 }
297
298 static void
299 SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
300 {
301 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
302 char dummy[2000];
303 int flags;
304 int i;
305
306 for (i = 0; (dummy[i] = ARMul_SafeReadByte (state, name + i)); i++)
307 ;
308
309 /* Now we need to decode the Demon open mode. */
310 flags = translate_open_mode[SWIflags];
311
312 /* Filename ":tt" is special: it denotes stdin/out. */
313 if (strcmp (dummy, ":tt") == 0)
314 {
315 if (flags == O_RDONLY) /* opening tty "r" */
316 state->Reg[0] = 0; /* stdin */
317 else
318 state->Reg[0] = 1; /* stdout */
319 }
320 else
321 {
322 state->Reg[0] = sim_callback->open (sim_callback, dummy, flags);
323 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
324 }
325 }
326
327 static void
328 SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
329 {
330 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
331 int res;
332 int i;
333 char *local = malloc (len);
334
335 if (local == NULL)
336 {
337 sim_callback->printf_filtered
338 (sim_callback,
339 "sim: Unable to read 0x%ulx bytes - out of memory\n",
340 len);
341 return;
342 }
343
344 res = sim_callback->read (sim_callback, f, local, len);
345 if (res > 0)
346 for (i = 0; i < res; i++)
347 ARMul_SafeWriteByte (state, ptr + i, local[i]);
348
349 free (local);
350 state->Reg[0] = res == -1 ? -1 : len - res;
351 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
352 }
353
354 static void
355 SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
356 {
357 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
358 int res;
359 ARMword i;
360 char *local = malloc (len);
361
362 if (local == NULL)
363 {
364 sim_callback->printf_filtered
365 (sim_callback,
366 "sim: Unable to write 0x%lx bytes - out of memory\n",
367 (long) len);
368 return;
369 }
370
371 for (i = 0; i < len; i++)
372 local[i] = ARMul_SafeReadByte (state, ptr + i);
373
374 res = sim_callback->write (sim_callback, f, local, len);
375 state->Reg[0] = res == -1 ? -1 : len - res;
376 free (local);
377
378 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
379 }
380
381 static void
382 SWIflen (ARMul_State * state, ARMword fh)
383 {
384 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
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
394 addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
395
396 state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
397 (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
398
399 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
400 }
401
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). */
404
405 unsigned
406 ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
407 {
408 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
409 int unhandled = FALSE;
410
411 switch (number)
412 {
413 case SWI_Read:
414 if (swi_mask & SWI_MASK_DEMON)
415 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
416 else
417 unhandled = TRUE;
418 break;
419
420 case SWI_Write:
421 if (swi_mask & SWI_MASK_DEMON)
422 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
423 else
424 unhandled = TRUE;
425 break;
426
427 case SWI_Open:
428 if (swi_mask & SWI_MASK_DEMON)
429 SWIopen (state, state->Reg[0], state->Reg[1]);
430 else
431 unhandled = TRUE;
432 break;
433
434 case SWI_Clock:
435 if (swi_mask & SWI_MASK_DEMON)
436 {
437 /* Return number of centi-seconds. */
438 state->Reg[0] =
439 #ifdef CLOCKS_PER_SEC
440 (CLOCKS_PER_SEC >= 100)
441 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
442 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
443 #else
444 /* Presume unix... clock() returns microseconds. */
445 (ARMword) (clock () / 10000);
446 #endif
447 OSptr->ErrorNo = errno;
448 }
449 else
450 unhandled = TRUE;
451 break;
452
453 case SWI_Time:
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;
461 break;
462
463 case SWI_Close:
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;
471 break;
472
473 case SWI_Flen:
474 if (swi_mask & SWI_MASK_DEMON)
475 SWIflen (state, state->Reg[0]);
476 else
477 unhandled = TRUE;
478 break;
479
480 case SWI_Exit:
481 if (swi_mask & SWI_MASK_DEMON)
482 state->Emulate = FALSE;
483 else
484 unhandled = TRUE;
485 break;
486
487 case SWI_Seek:
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;
496 break;
497
498 case SWI_WriteC:
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;
507 break;
508
509 case SWI_Write0:
510 if (swi_mask & SWI_MASK_DEMON)
511 SWIWrite0 (state, state->Reg[0]);
512 else
513 unhandled = TRUE;
514 break;
515
516 case SWI_GetErrno:
517 if (swi_mask & SWI_MASK_DEMON)
518 state->Reg[0] = OSptr->ErrorNo;
519 else
520 unhandled = TRUE;
521 break;
522
523 case SWI_GetEnv:
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;
531
532 WriteCommandLineTo (state, state->Reg[0]);
533 }
534 else
535 unhandled = TRUE;
536 break;
537
538 case SWI_Breakpoint:
539 state->EndCondition = RDIError_BreakpointReached;
540 state->Emulate = FALSE;
541 break;
542
543 /* Handle Angel SWIs as well as Demon ones. */
544 case AngelSWI_ARM:
545 case AngelSWI_Thumb:
546 if (swi_mask & SWI_MASK_ANGEL)
547 {
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 {
556 /* Unimplemented reason codes. */
557 case AngelSWI_Reason_ReadC:
558 case AngelSWI_Reason_IsTTY:
559 case AngelSWI_Reason_TmpNam:
560 case AngelSWI_Reason_Remove:
561 case AngelSWI_Reason_Rename:
562 case AngelSWI_Reason_System:
563 case AngelSWI_Reason_EnterSVC:
564 default:
565 state->Emulate = FALSE;
566 return FALSE;
567
568 case AngelSWI_Reason_Clock:
569 /* Return number of centi-seconds. */
570 state->Reg[0] =
571 #ifdef CLOCKS_PER_SEC
572 (CLOCKS_PER_SEC >= 100)
573 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
574 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
575 #else
576 /* Presume unix... clock() returns microseconds. */
577 (ARMword) (clock () / 10000);
578 #endif
579 OSptr->ErrorNo = errno;
580 break;
581
582 case AngelSWI_Reason_Time:
583 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
584 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
585 break;
586
587 case AngelSWI_Reason_WriteC:
588 {
589 char tmp = ARMul_SafeReadByte (state, addr);
590 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
591 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
592 break;
593 }
594
595 case AngelSWI_Reason_Write0:
596 SWIWrite0 (state, addr);
597 break;
598
599 case AngelSWI_Reason_Close:
600 state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
601 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
602 break;
603
604 case AngelSWI_Reason_Seek:
605 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
606 ARMul_ReadWord (state, addr + 4),
607 SEEK_SET);
608 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
609 break;
610
611 case AngelSWI_Reason_FLen:
612 SWIflen (state, ARMul_ReadWord (state, addr));
613 break;
614
615 case AngelSWI_Reason_GetCmdLine:
616 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
617 break;
618
619 case AngelSWI_Reason_HeapInfo:
620 /* R1 is a pointer to a pointer. */
621 addr = ARMul_ReadWord (state, addr);
622
623 /* Pick up the right memory limit. */
624 if (state->MemSize)
625 temp = state->MemSize;
626 else
627 temp = ADDRUSERSTACK;
628
629 ARMul_WriteWord (state, addr, 0); /* Heap base. */
630 ARMul_WriteWord (state, addr + 4, temp); /* Heap limit. */
631 ARMul_WriteWord (state, addr + 8, temp); /* Stack base. */
632 ARMul_WriteWord (state, addr + 12, temp); /* Stack limit. */
633 break;
634
635 case AngelSWI_Reason_ReportException:
636 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
637 state->Reg[0] = 0;
638 else
639 state->Reg[0] = -1;
640 state->Emulate = FALSE;
641 break;
642
643 case ADP_Stopped_ApplicationExit:
644 state->Reg[0] = 0;
645 state->Emulate = FALSE;
646 break;
647
648 case ADP_Stopped_RunTimeError:
649 state->Reg[0] = -1;
650 state->Emulate = FALSE;
651 break;
652
653 case AngelSWI_Reason_Errno:
654 state->Reg[0] = OSptr->ErrorNo;
655 break;
656
657 case AngelSWI_Reason_Open:
658 SWIopen (state,
659 ARMul_ReadWord (state, addr),
660 ARMul_ReadWord (state, addr + 4));
661 break;
662
663 case AngelSWI_Reason_Read:
664 SWIread (state,
665 ARMul_ReadWord (state, addr),
666 ARMul_ReadWord (state, addr + 4),
667 ARMul_ReadWord (state, addr + 8));
668 break;
669
670 case AngelSWI_Reason_Write:
671 SWIwrite (state,
672 ARMul_ReadWord (state, addr),
673 ARMul_ReadWord (state, addr + 4),
674 ARMul_ReadWord (state, addr + 8));
675 break;
676 }
677 }
678 else
679 unhandled = TRUE;
680 break;
681
682 case 0x90:
683 case 0x91:
684 case 0x92:
685 /* These are used by the FPE code. */
686 break;
687
688 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
689 if (swi_mask & SWI_MASK_REDBOOT)
690 {
691 switch (state->Reg[0])
692 {
693 /* These numbers are defined in libgloss/syscall.h
694 but the simulator should not be dependend upon
695 libgloss being installed. */
696 case 1: /* Exit. */
697 state->Emulate = FALSE;
698 /* Copy exit code into r0. */
699 state->Reg[0] = state->Reg[1];
700 break;
701
702 case 2: /* Open. */
703 SWIopen (state, state->Reg[1], state->Reg[2]);
704 break;
705
706 case 3: /* Close. */
707 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
708 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
709 break;
710
711 case 4: /* Read. */
712 SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
713 break;
714
715 case 5: /* Write. */
716 SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
717 break;
718
719 case 6: /* Lseek. */
720 state->Reg[0] = sim_callback->lseek (sim_callback,
721 state->Reg[1],
722 state->Reg[2],
723 state->Reg[3]);
724 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
725 break;
726
727 case 17: /* Utime. */
728 state->Reg[0] = (ARMword) sim_callback->time (sim_callback,
729 (long *) state->Reg[1]);
730 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
731 break;
732
733 case 7: /* Unlink. */
734 case 8: /* Getpid. */
735 case 9: /* Kill. */
736 case 10: /* Fstat. */
737 case 11: /* Sbrk. */
738 case 12: /* Argvlen. */
739 case 13: /* Argv. */
740 case 14: /* ChDir. */
741 case 15: /* Stat. */
742 case 16: /* Chmod. */
743 case 18: /* Time. */
744 sim_callback->printf_filtered
745 (sim_callback,
746 "sim: unhandled RedBoot syscall '%d' encountered - ignoring\n",
747 state->Reg[0]);
748 return FALSE;
749
750 default:
751 sim_callback->printf_filtered
752 (sim_callback,
753 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
754 state->Reg[0]);
755 return FALSE;
756 }
757 break;
758 }
759
760 default:
761 unhandled = TRUE;
762 }
763
764 if (unhandled)
765 {
766 if (SWI_vector_installed)
767 {
768 ARMword cpsr;
769 ARMword i_size;
770
771 cpsr = ARMul_GetCPSR (state);
772 i_size = INSN_SIZE;
773
774 ARMul_SetSPSR (state, SVC32MODE, cpsr);
775
776 cpsr &= ~0xbf;
777 cpsr |= SVC32MODE | 0x80;
778 ARMul_SetCPSR (state, cpsr);
779
780 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
781 state->NextInstr = RESUME;
782 state->Reg[15] = state->pc = ARMSWIV;
783 FLUSHPIPE;
784 }
785 else
786 {
787 sim_callback->printf_filtered
788 (sim_callback,
789 "sim: unknown SWI encountered - %x - ignoring\n",
790 number);
791 return FALSE;
792 }
793 }
794
795 return TRUE;
796 }
797
798 #ifndef NOOS
799 #ifndef ASIM
800
801 /* The emulator calls this routine when an Exception occurs. The second
802 parameter is the address of the relevant exception vector. Returning
803 FALSE from this routine causes the trap to be taken, TRUE causes it to
804 be ignored (so set state->Emulate to FALSE!). */
805
806 unsigned
807 ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
808 ARMword vector ATTRIBUTE_UNUSED,
809 ARMword pc ATTRIBUTE_UNUSED)
810 {
811 return FALSE;
812 }
813
814 #endif
815 #endif /* NOOS */
This page took 0.046945 seconds and 4 git commands to generate.