1 /* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
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 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
17 /* This file contains a model of Demon, ARM Ltd's Debug Monitor,
18 including all the SWI's required to support the C library. The code in
19 it is not really for the faint-hearted (especially the abort handling
20 code), but it is a complete example. Defining NOOS will disable all the
21 fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
22 0x11 to halt the emulator. */
31 #include "targ-vals.h"
33 #ifndef TARGET_O_BINARY
34 #define TARGET_O_BINARY 0
38 #include <unistd.h> /* For SEEK_SET etc. */
42 extern int _fisatty (FILE *);
43 #define isatty_(f) _fisatty(f)
47 #define isatty_(f) isatty((f)->_file)
51 #define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
53 #define isatty_(f) isatty (fileno (f))
70 /* For RDIError_BreakpointReached. */
73 #include "gdb/callback.h"
74 extern host_callback
*sim_callback
;
76 extern unsigned ARMul_OSInit (ARMul_State
*);
77 extern void ARMul_OSExit (ARMul_State
*);
78 extern unsigned ARMul_OSHandleSWI (ARMul_State
*, ARMword
);
79 extern unsigned ARMul_OSException (ARMul_State
*, ARMword
, ARMword
);
80 extern ARMword
ARMul_OSLastErrorP (ARMul_State
*);
81 extern ARMword
ARMul_Debug (ARMul_State
*, ARMword
, ARMword
);
83 #define BUFFERSIZE 4096
87 #define UNIQUETEMPS 256
92 /* OS private Information. */
99 FILE *FileTable
[FOPEN_MAX
];
100 char FileFlags
[FOPEN_MAX
];
101 char *tempnames
[UNIQUETEMPS
];
110 #define FIXCRLF(t,c) ((t & BINARY) ? \
112 ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
115 #define FIXCRLF(t,c) c
118 /* Bit mask of enabled SWI implementations. */
119 unsigned int swi_mask
= -1;
122 static ARMword softvectorcode
[] =
124 /* Installed instructions:
125 swi tidyexception + event;
128 swi generateexception + event. */
129 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
130 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
131 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
132 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
133 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
134 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
135 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
136 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
137 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
138 0xe1a0f00e /* Default handler */
141 /* Time for the Operating System to initialise itself. */
144 ARMul_OSInit (ARMul_State
* state
)
149 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
151 if (state
->OSptr
== NULL
)
153 state
->OSptr
= (unsigned char *) malloc (sizeof (struct OSblock
));
154 if (state
->OSptr
== NULL
)
156 perror ("OS Memory");
161 OSptr
= (struct OSblock
*) state
->OSptr
;
163 state
->Reg
[13] = ADDRSUPERSTACK
; /* Set up a stack for the current mode... */
164 ARMul_SetReg (state
, SVC32MODE
, 13, ADDRSUPERSTACK
);/* ...and for supervisor mode... */
165 ARMul_SetReg (state
, ABORT32MODE
, 13, ADDRSUPERSTACK
);/* ...and for abort 32 mode... */
166 ARMul_SetReg (state
, UNDEF32MODE
, 13, ADDRSUPERSTACK
);/* ...and for undef 32 mode... */
167 ARMul_SetReg (state
, SYSTEMMODE
, 13, ADDRSUPERSTACK
);/* ...and for system mode. */
168 instr
= 0xe59ff000 | (ADDRSOFTVECTORS
- 8); /* Load pc from soft vector */
170 for (i
= ARMul_ResetV
; i
<= ARMFIQV
; i
+= 4)
171 /* Write hardware vectors. */
172 ARMul_WriteWord (state
, i
, instr
);
174 SWI_vector_installed
= 0;
176 for (i
= ARMul_ResetV
; i
<= ARMFIQV
+ 4; i
+= 4)
178 ARMul_WriteWord (state
, ADDRSOFTVECTORS
+ i
, SOFTVECTORCODE
+ i
* 4);
179 ARMul_WriteWord (state
, ADDRSOFHANDLERS
+ 2 * i
+ 4L,
180 SOFTVECTORCODE
+ sizeof (softvectorcode
) - 4L);
183 for (i
= 0; i
< sizeof (softvectorcode
); i
+= 4)
184 ARMul_WriteWord (state
, SOFTVECTORCODE
+ i
, softvectorcode
[i
/ 4]);
186 for (i
= 0; i
< FOPEN_MAX
; i
++)
187 OSptr
->FileTable
[i
] = NULL
;
189 for (i
= 0; i
< UNIQUETEMPS
; i
++)
190 OSptr
->tempnames
[i
] = NULL
;
192 ARMul_ConsolePrint (state
, ", Demon 1.01");
197 for (i
= 0; i
< fpesize
; i
+= 4)
199 ARMul_WriteWord (state
, FPESTART
+ i
, fpecode
[i
>> 2]);
201 /* Scan backwards from the end of the code. */
202 for (i
= FPESTART
+ fpesize
;; i
-= 4)
204 /* When we reach the marker value, break out of
205 the loop, leaving i pointing at the maker. */
206 if ((j
= ARMul_ReadWord (state
, i
)) == 0xffffffff)
209 /* If necessary, reverse the error strings. */
210 if (state
->bigendSig
&& j
< 0x80000000)
212 /* It's part of the string so swap it. */
213 j
= ((j
>> 0x18) & 0x000000ff) |
214 ((j
>> 0x08) & 0x0000ff00) |
215 ((j
<< 0x08) & 0x00ff0000) | ((j
<< 0x18) & 0xff000000);
216 ARMul_WriteWord (state
, i
, j
);
220 /* Copy old illegal instr vector. */
221 ARMul_WriteWord (state
, FPEOLDVECT
, ARMul_ReadWord (state
, ARMUndefinedInstrV
));
222 /* Install new vector. */
223 ARMul_WriteWord (state
, ARMUndefinedInstrV
, FPENEWVECT (ARMul_ReadWord (state
, i
- 4)));
224 ARMul_ConsolePrint (state
, ", FPE");
227 #endif /* VALIDATE */
230 /* Intel do not want DEMON SWI support. */
231 if (state
->is_XScale
)
232 swi_mask
= SWI_MASK_ANGEL
;
238 ARMul_OSExit (ARMul_State
* state
)
240 free ((char *) state
->OSptr
);
244 /* Return the last Operating System Error. */
246 ARMword
ARMul_OSLastErrorP (ARMul_State
* state
)
248 return ((struct OSblock
*) state
->OSptr
)->ErrorP
;
251 static int translate_open_mode
[] =
253 TARGET_O_RDONLY
, /* "r" */
254 TARGET_O_RDONLY
+ TARGET_O_BINARY
, /* "rb" */
255 TARGET_O_RDWR
, /* "r+" */
256 TARGET_O_RDWR
+ TARGET_O_BINARY
, /* "r+b" */
257 TARGET_O_WRONLY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w" */
258 TARGET_O_WRONLY
+ TARGET_O_BINARY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "wb" */
259 TARGET_O_RDWR
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w+" */
260 TARGET_O_RDWR
+ TARGET_O_BINARY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w+b" */
261 TARGET_O_WRONLY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "a" */
262 TARGET_O_WRONLY
+ TARGET_O_BINARY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "ab" */
263 TARGET_O_RDWR
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "a+" */
264 TARGET_O_RDWR
+ TARGET_O_BINARY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
/* "a+b" */
268 SWIWrite0 (ARMul_State
* state
, ARMword addr
)
271 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
273 while ((temp
= ARMul_SafeReadByte (state
, addr
++)) != 0)
276 /* Note - we cannot just cast 'temp' to a (char *) here,
277 since on a big-endian host the byte value will end
278 up in the wrong place and a nul character will be printed. */
279 (void) sim_callback
->write_stdout (sim_callback
, & buffer
, 1);
282 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
286 WriteCommandLineTo (ARMul_State
* state
, ARMword addr
)
289 char *cptr
= state
->CommandLine
;
295 temp
= (ARMword
) * cptr
++;
296 ARMul_SafeWriteByte (state
, addr
++, temp
);
302 ReadFileName (ARMul_State
* state
, char *buf
, ARMword src
, size_t n
)
304 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
308 if ((*p
++ = ARMul_SafeReadByte (state
, src
++)) == '\0')
310 OSptr
->ErrorNo
= cb_host_to_target_errno (sim_callback
, ENAMETOOLONG
);
316 SWIopen (ARMul_State
* state
, ARMword name
, ARMword SWIflags
)
318 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
322 if (ReadFileName (state
, buf
, name
, sizeof buf
) == -1)
325 /* Now we need to decode the Demon open mode. */
326 flags
= translate_open_mode
[SWIflags
];
328 /* Filename ":tt" is special: it denotes stdin/out. */
329 if (strcmp (buf
, ":tt") == 0)
331 if (flags
== TARGET_O_RDONLY
) /* opening tty "r" */
332 state
->Reg
[0] = 0; /* stdin */
334 state
->Reg
[0] = 1; /* stdout */
338 state
->Reg
[0] = sim_callback
->open (sim_callback
, buf
, flags
);
339 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
344 SWIread (ARMul_State
* state
, ARMword f
, ARMword ptr
, ARMword len
)
346 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
349 char *local
= malloc (len
);
353 sim_callback
->printf_filtered
355 "sim: Unable to read 0x%ulx bytes - out of memory\n",
360 res
= sim_callback
->read (sim_callback
, f
, local
, len
);
362 for (i
= 0; i
< res
; i
++)
363 ARMul_SafeWriteByte (state
, ptr
+ i
, local
[i
]);
366 state
->Reg
[0] = res
== -1 ? -1 : len
- res
;
367 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
371 SWIwrite (ARMul_State
* state
, ARMword f
, ARMword ptr
, ARMword len
)
373 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
376 char *local
= malloc (len
);
380 sim_callback
->printf_filtered
382 "sim: Unable to write 0x%lx bytes - out of memory\n",
387 for (i
= 0; i
< len
; i
++)
388 local
[i
] = ARMul_SafeReadByte (state
, ptr
+ i
);
390 res
= sim_callback
->write (sim_callback
, f
, local
, len
);
391 state
->Reg
[0] = res
== -1 ? -1 : len
- res
;
394 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
398 SWIflen (ARMul_State
* state
, ARMword fh
)
400 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
405 OSptr
->ErrorNo
= EBADF
;
410 addr
= sim_callback
->lseek (sim_callback
, fh
, 0, SEEK_CUR
);
412 state
->Reg
[0] = sim_callback
->lseek (sim_callback
, fh
, 0L, SEEK_END
);
413 (void) sim_callback
->lseek (sim_callback
, fh
, addr
, SEEK_SET
);
415 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
419 SWIremove (ARMul_State
* state
, ARMword path
)
423 if (ReadFileName (state
, buf
, path
, sizeof buf
) != -1)
425 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
426 state
->Reg
[0] = sim_callback
->unlink (sim_callback
, buf
);
427 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
432 SWIrename (ARMul_State
* state
, ARMword old
, ARMword
new)
434 char oldbuf
[PATH_MAX
], newbuf
[PATH_MAX
];
436 if (ReadFileName (state
, oldbuf
, old
, sizeof oldbuf
) != -1
437 && ReadFileName (state
, newbuf
, new, sizeof newbuf
) != -1)
439 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
440 state
->Reg
[0] = sim_callback
->rename (sim_callback
, oldbuf
, newbuf
);
441 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
445 /* The emulator calls this routine when a SWI instruction is encuntered.
446 The parameter passed is the SWI number (lower 24 bits of the instruction). */
449 ARMul_OSHandleSWI (ARMul_State
* state
, ARMword number
)
451 struct OSblock
* OSptr
= (struct OSblock
*) state
->OSptr
;
452 int unhandled
= FALSE
;
457 if (swi_mask
& SWI_MASK_DEMON
)
458 SWIread (state
, state
->Reg
[0], state
->Reg
[1], state
->Reg
[2]);
464 if (swi_mask
& SWI_MASK_DEMON
)
465 SWIwrite (state
, state
->Reg
[0], state
->Reg
[1], state
->Reg
[2]);
471 if (swi_mask
& SWI_MASK_DEMON
)
472 SWIopen (state
, state
->Reg
[0], state
->Reg
[1]);
478 if (swi_mask
& SWI_MASK_DEMON
)
480 /* Return number of centi-seconds. */
482 #ifdef CLOCKS_PER_SEC
483 (CLOCKS_PER_SEC
>= 100)
484 ? (ARMword
) (clock () / (CLOCKS_PER_SEC
/ 100))
485 : (ARMword
) ((clock () * 100) / CLOCKS_PER_SEC
);
487 /* Presume unix... clock() returns microseconds. */
488 (ARMword
) (clock () / 10000);
490 OSptr
->ErrorNo
= errno
;
497 if (swi_mask
& SWI_MASK_DEMON
)
499 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
, NULL
);
500 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
507 if (swi_mask
& SWI_MASK_DEMON
)
509 state
->Reg
[0] = sim_callback
->close (sim_callback
, state
->Reg
[0]);
510 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
517 if (swi_mask
& SWI_MASK_DEMON
)
518 SWIflen (state
, state
->Reg
[0]);
524 if (swi_mask
& SWI_MASK_DEMON
)
525 state
->Emulate
= FALSE
;
531 if (swi_mask
& SWI_MASK_DEMON
)
533 /* We must return non-zero for failure. */
534 state
->Reg
[0] = -1 >= sim_callback
->lseek (sim_callback
, state
->Reg
[0], state
->Reg
[1], SEEK_SET
);
535 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
542 if (swi_mask
& SWI_MASK_DEMON
)
544 char tmp
= state
->Reg
[0];
545 (void) sim_callback
->write_stdout (sim_callback
, &tmp
, 1);
546 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
553 if (swi_mask
& SWI_MASK_DEMON
)
554 SWIWrite0 (state
, state
->Reg
[0]);
560 if (swi_mask
& SWI_MASK_DEMON
)
561 state
->Reg
[0] = OSptr
->ErrorNo
;
567 if (swi_mask
& SWI_MASK_DEMON
)
569 state
->Reg
[0] = ADDRCMDLINE
;
571 state
->Reg
[1] = state
->MemSize
;
573 state
->Reg
[1] = ADDRUSERSTACK
;
575 WriteCommandLineTo (state
, state
->Reg
[0]);
582 state
->EndCondition
= RDIError_BreakpointReached
;
583 state
->Emulate
= FALSE
;
587 if (swi_mask
& SWI_MASK_DEMON
)
588 SWIremove (state
, state
->Reg
[0]);
594 if (swi_mask
& SWI_MASK_DEMON
)
595 SWIrename (state
, state
->Reg
[0], state
->Reg
[1]);
601 if (swi_mask
& SWI_MASK_DEMON
)
603 state
->Reg
[0] = sim_callback
->isatty (sim_callback
, state
->Reg
[0]);
604 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
610 /* Handle Angel SWIs as well as Demon ones. */
613 if (swi_mask
& SWI_MASK_ANGEL
)
618 /* R1 is almost always a parameter block. */
619 addr
= state
->Reg
[1];
620 /* R0 is a reason code. */
621 switch (state
->Reg
[0])
624 /* This can happen when a SWI is interrupted (eg receiving a
625 ctrl-C whilst processing SWIRead()). The SWI will complete
626 returning -1 in r0 to the caller. If GDB is then used to
627 resume the system call the reason code will now be -1. */
630 /* Unimplemented reason codes. */
631 case AngelSWI_Reason_ReadC
:
632 case AngelSWI_Reason_TmpNam
:
633 case AngelSWI_Reason_System
:
634 case AngelSWI_Reason_EnterSVC
:
636 state
->Emulate
= FALSE
;
639 case AngelSWI_Reason_Clock
:
640 /* Return number of centi-seconds. */
642 #ifdef CLOCKS_PER_SEC
643 (CLOCKS_PER_SEC
>= 100)
644 ? (ARMword
) (clock () / (CLOCKS_PER_SEC
/ 100))
645 : (ARMword
) ((clock () * 100) / CLOCKS_PER_SEC
);
647 /* Presume unix... clock() returns microseconds. */
648 (ARMword
) (clock () / 10000);
650 OSptr
->ErrorNo
= errno
;
653 case AngelSWI_Reason_Time
:
654 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
, NULL
);
655 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
658 case AngelSWI_Reason_WriteC
:
660 char tmp
= ARMul_SafeReadByte (state
, addr
);
661 (void) sim_callback
->write_stdout (sim_callback
, &tmp
, 1);
662 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
666 case AngelSWI_Reason_Write0
:
667 SWIWrite0 (state
, addr
);
670 case AngelSWI_Reason_Close
:
671 state
->Reg
[0] = sim_callback
->close (sim_callback
, ARMul_ReadWord (state
, addr
));
672 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
675 case AngelSWI_Reason_Seek
:
676 state
->Reg
[0] = -1 >= sim_callback
->lseek (sim_callback
, ARMul_ReadWord (state
, addr
),
677 ARMul_ReadWord (state
, addr
+ 4),
679 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
682 case AngelSWI_Reason_FLen
:
683 SWIflen (state
, ARMul_ReadWord (state
, addr
));
686 case AngelSWI_Reason_GetCmdLine
:
687 WriteCommandLineTo (state
, ARMul_ReadWord (state
, addr
));
690 case AngelSWI_Reason_HeapInfo
:
691 /* R1 is a pointer to a pointer. */
692 addr
= ARMul_ReadWord (state
, addr
);
694 /* Pick up the right memory limit. */
696 temp
= state
->MemSize
;
698 temp
= ADDRUSERSTACK
;
700 ARMul_WriteWord (state
, addr
, 0); /* Heap base. */
701 ARMul_WriteWord (state
, addr
+ 4, temp
); /* Heap limit. */
702 ARMul_WriteWord (state
, addr
+ 8, temp
); /* Stack base. */
703 ARMul_WriteWord (state
, addr
+ 12, temp
); /* Stack limit. */
706 case AngelSWI_Reason_ReportException
:
707 if (state
->Reg
[1] == ADP_Stopped_ApplicationExit
)
711 state
->Emulate
= FALSE
;
714 case ADP_Stopped_ApplicationExit
:
716 state
->Emulate
= FALSE
;
719 case ADP_Stopped_RunTimeError
:
721 state
->Emulate
= FALSE
;
724 case AngelSWI_Reason_Errno
:
725 state
->Reg
[0] = OSptr
->ErrorNo
;
728 case AngelSWI_Reason_Open
:
730 ARMul_ReadWord (state
, addr
),
731 ARMul_ReadWord (state
, addr
+ 4));
734 case AngelSWI_Reason_Read
:
736 ARMul_ReadWord (state
, addr
),
737 ARMul_ReadWord (state
, addr
+ 4),
738 ARMul_ReadWord (state
, addr
+ 8));
741 case AngelSWI_Reason_Write
:
743 ARMul_ReadWord (state
, addr
),
744 ARMul_ReadWord (state
, addr
+ 4),
745 ARMul_ReadWord (state
, addr
+ 8));
748 case AngelSWI_Reason_IsTTY
:
749 state
->Reg
[0] = sim_callback
->isatty (sim_callback
,
750 ARMul_ReadWord (state
, addr
));
751 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
754 case AngelSWI_Reason_Remove
:
756 ARMul_ReadWord (state
, addr
));
758 case AngelSWI_Reason_Rename
:
760 ARMul_ReadWord (state
, addr
),
761 ARMul_ReadWord (state
, addr
+ 4));
768 /* The following SWIs are generated by the softvectorcode[]
769 installed by default by the simulator. */
770 case 0x91: /* Undefined Instruction. */
772 ARMword addr
= state
->RegBank
[UNDEFBANK
][14] - 4;
774 sim_callback
->printf_filtered
775 (sim_callback
, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x. Stopping.\n",
776 ARMul_ReadWord (state
, addr
), addr
);
777 state
->EndCondition
= RDIError_SoftwareInterrupt
;
778 state
->Emulate
= FALSE
;
782 case 0x90: /* Reset. */
783 case 0x92: /* SWI. */
784 /* These two can be safely ignored. */
787 case 0x93: /* Prefetch Abort. */
788 case 0x94: /* Data Abort. */
789 case 0x95: /* Address Exception. */
790 case 0x96: /* IRQ. */
791 case 0x97: /* FIQ. */
792 case 0x98: /* Error. */
797 /* This can happen when a SWI is interrupted (eg receiving a
798 ctrl-C whilst processing SWIRead()). The SWI will complete
799 returning -1 in r0 to the caller. If GDB is then used to
800 resume the system call the reason code will now be -1. */
803 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
804 if (swi_mask
& SWI_MASK_REDBOOT
)
806 switch (state
->Reg
[0])
808 /* These numbers are defined in libgloss/syscall.h
809 but the simulator should not be dependend upon
810 libgloss being installed. */
812 state
->Emulate
= FALSE
;
813 /* Copy exit code into r0. */
814 state
->Reg
[0] = state
->Reg
[1];
818 SWIopen (state
, state
->Reg
[1], state
->Reg
[2]);
822 state
->Reg
[0] = sim_callback
->close (sim_callback
, state
->Reg
[1]);
823 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
827 SWIread (state
, state
->Reg
[1], state
->Reg
[2], state
->Reg
[3]);
831 SWIwrite (state
, state
->Reg
[1], state
->Reg
[2], state
->Reg
[3]);
835 state
->Reg
[0] = sim_callback
->lseek (sim_callback
,
839 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
842 case 17: /* Utime. */
843 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
,
844 (long *) state
->Reg
[1]);
845 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
848 case 7: /* Unlink. */
849 case 8: /* Getpid. */
851 case 10: /* Fstat. */
853 case 12: /* Argvlen. */
855 case 14: /* ChDir. */
857 case 16: /* Chmod. */
859 sim_callback
->printf_filtered
861 "sim: unhandled RedBoot syscall `%d' encountered - "
862 "returning ENOSYS\n",
865 OSptr
->ErrorNo
= cb_host_to_target_errno
866 (sim_callback
, ENOSYS
);
868 case 1001: /* Meminfo. */
870 ARMword totmem
= state
->Reg
[1],
871 topmem
= state
->Reg
[2];
872 ARMword stack
= state
->MemSize
> 0
873 ? state
->MemSize
: ADDRUSERSTACK
;
875 ARMul_WriteWord (state
, totmem
, stack
);
877 ARMul_WriteWord (state
, topmem
, stack
);
883 sim_callback
->printf_filtered
885 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
898 if (SWI_vector_installed
)
903 cpsr
= ARMul_GetCPSR (state
);
906 ARMul_SetSPSR (state
, SVC32MODE
, cpsr
);
909 cpsr
|= SVC32MODE
| 0x80;
910 ARMul_SetCPSR (state
, cpsr
);
912 state
->RegBank
[SVCBANK
][14] = state
->Reg
[14] = state
->Reg
[15] - i_size
;
913 state
->NextInstr
= RESUME
;
914 state
->Reg
[15] = state
->pc
= ARMSWIV
;
919 sim_callback
->printf_filtered
921 "sim: unknown SWI encountered - %x - ignoring\n",
933 /* The emulator calls this routine when an Exception occurs. The second
934 parameter is the address of the relevant exception vector. Returning
935 FALSE from this routine causes the trap to be taken, TRUE causes it to
936 be ignored (so set state->Emulate to FALSE!). */
939 ARMul_OSException (ARMul_State
* state ATTRIBUTE_UNUSED
,
940 ARMword vector ATTRIBUTE_UNUSED
,
941 ARMword pc ATTRIBUTE_UNUSED
)