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. */
24 /* This must come before any other includes. */
28 #include "libiberty.h"
34 #include <unistd.h> /* For SEEK_SET etc. */
48 /* For RDIError_BreakpointReached. */
51 #include "sim/callback.h"
52 extern host_callback
*sim_callback
;
54 extern unsigned ARMul_OSInit (ARMul_State
*);
55 extern unsigned ARMul_OSHandleSWI (ARMul_State
*, ARMword
);
64 /* OS private Information. */
71 /* Bit mask of enabled SWI implementations. */
72 unsigned int swi_mask
= -1;
75 static ARMword softvectorcode
[] =
77 /* Installed instructions:
78 swi tidyexception + event;
81 swi generateexception + event. */
82 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
83 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
84 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
85 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
86 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
87 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
88 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
89 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
90 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
91 0xe1a0f00e /* Default handler */
94 /* Time for the Operating System to initialise itself. */
97 ARMul_OSInit (ARMul_State
* state
)
102 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
104 if (state
->OSptr
== NULL
)
106 state
->OSptr
= (unsigned char *) malloc (sizeof (struct OSblock
));
107 if (state
->OSptr
== NULL
)
109 perror ("OS Memory");
114 OSptr
= (struct OSblock
*) state
->OSptr
;
115 state
->Reg
[13] = ADDRSUPERSTACK
; /* Set up a stack for the current mode... */
116 ARMul_SetReg (state
, SVC32MODE
, 13, ADDRSUPERSTACK
);/* ...and for supervisor mode... */
117 ARMul_SetReg (state
, ABORT32MODE
, 13, ADDRSUPERSTACK
);/* ...and for abort 32 mode... */
118 ARMul_SetReg (state
, UNDEF32MODE
, 13, ADDRSUPERSTACK
);/* ...and for undef 32 mode... */
119 ARMul_SetReg (state
, SYSTEMMODE
, 13, ADDRSUPERSTACK
);/* ...and for system mode. */
120 instr
= 0xe59ff000 | (ADDRSOFTVECTORS
- 8); /* Load pc from soft vector */
122 for (i
= ARMul_ResetV
; i
<= ARMFIQV
; i
+= 4)
123 /* Write hardware vectors. */
124 ARMul_WriteWord (state
, i
, instr
);
126 SWI_vector_installed
= 0;
128 for (i
= ARMul_ResetV
; i
<= ARMFIQV
+ 4; i
+= 4)
130 ARMul_WriteWord (state
, ADDRSOFTVECTORS
+ i
, SOFTVECTORCODE
+ i
* 4);
131 ARMul_WriteWord (state
, ADDRSOFHANDLERS
+ 2 * i
+ 4L,
132 SOFTVECTORCODE
+ sizeof (softvectorcode
) - 4L);
135 for (i
= 0; i
< sizeof (softvectorcode
); i
+= 4)
136 ARMul_WriteWord (state
, SOFTVECTORCODE
+ i
, softvectorcode
[i
/ 4]);
138 ARMul_ConsolePrint (state
, ", Demon 1.01");
143 for (i
= 0; i
< fpesize
; i
+= 4)
145 ARMul_WriteWord (state
, FPESTART
+ i
, fpecode
[i
>> 2]);
147 /* Scan backwards from the end of the code. */
148 for (i
= FPESTART
+ fpesize
;; i
-= 4)
150 /* When we reach the marker value, break out of
151 the loop, leaving i pointing at the maker. */
152 if ((j
= ARMul_ReadWord (state
, i
)) == 0xffffffff)
155 /* If necessary, reverse the error strings. */
156 if (state
->bigendSig
&& j
< 0x80000000)
158 /* It's part of the string so swap it. */
159 j
= ((j
>> 0x18) & 0x000000ff) |
160 ((j
>> 0x08) & 0x0000ff00) |
161 ((j
<< 0x08) & 0x00ff0000) | ((j
<< 0x18) & 0xff000000);
162 ARMul_WriteWord (state
, i
, j
);
166 /* Copy old illegal instr vector. */
167 ARMul_WriteWord (state
, FPEOLDVECT
, ARMul_ReadWord (state
, ARMUndefinedInstrV
));
168 /* Install new vector. */
169 ARMul_WriteWord (state
, ARMUndefinedInstrV
, FPENEWVECT (ARMul_ReadWord (state
, i
- 4)));
170 ARMul_ConsolePrint (state
, ", FPE");
173 #endif /* VALIDATE */
176 /* Intel do not want DEMON SWI support. */
177 if (state
->is_XScale
)
178 swi_mask
= SWI_MASK_ANGEL
;
183 /* These are libgloss defines, but seem to be common across all supported ARM
184 targets at the moment. These should get moved to the callback open_map. */
185 #define TARGET_O_BINARY 0
186 #define TARGET_O_APPEND 0x8
187 #define TARGET_O_CREAT 0x200
188 #define TARGET_O_RDONLY 0x0
189 #define TARGET_O_RDWR 0x2
190 #define TARGET_O_TRUNC 0x400
191 #define TARGET_O_WRONLY 0x1
193 static const int translate_open_mode
[] =
195 TARGET_O_RDONLY
, /* "r" */
196 TARGET_O_RDONLY
+ TARGET_O_BINARY
, /* "rb" */
197 TARGET_O_RDWR
, /* "r+" */
198 TARGET_O_RDWR
+ TARGET_O_BINARY
, /* "r+b" */
199 TARGET_O_WRONLY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w" */
200 TARGET_O_WRONLY
+ TARGET_O_BINARY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "wb" */
201 TARGET_O_RDWR
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w+" */
202 TARGET_O_RDWR
+ TARGET_O_BINARY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w+b" */
203 TARGET_O_WRONLY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "a" */
204 TARGET_O_WRONLY
+ TARGET_O_BINARY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "ab" */
205 TARGET_O_RDWR
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "a+" */
206 TARGET_O_RDWR
+ TARGET_O_BINARY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
/* "a+b" */
210 SWIWrite0 (ARMul_State
* state
, ARMword addr
)
213 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
215 while ((temp
= ARMul_SafeReadByte (state
, addr
++)) != 0)
218 /* Note - we cannot just cast 'temp' to a (char *) here,
219 since on a big-endian host the byte value will end
220 up in the wrong place and a nul character will be printed. */
221 (void) sim_callback
->write_stdout (sim_callback
, & buffer
, 1);
224 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
228 WriteCommandLineTo (ARMul_State
* state
, ARMword addr
)
231 char *cptr
= state
->CommandLine
;
237 temp
= (ARMword
) * cptr
++;
238 ARMul_SafeWriteByte (state
, addr
++, temp
);
244 ReadFileName (ARMul_State
* state
, char *buf
, ARMword src
, size_t n
)
246 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
250 if ((*p
++ = ARMul_SafeReadByte (state
, src
++)) == '\0')
252 OSptr
->ErrorNo
= cb_host_to_target_errno (sim_callback
, ENAMETOOLONG
);
258 SWIopen (ARMul_State
* state
, ARMword name
, ARMword SWIflags
)
260 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
264 if (ReadFileName (state
, buf
, name
, sizeof buf
) == -1)
267 /* Now we need to decode the Demon open mode. */
268 if (SWIflags
>= ARRAY_SIZE (translate_open_mode
))
271 flags
= translate_open_mode
[SWIflags
];
273 /* Filename ":tt" is special: it denotes stdin/out. */
274 if (strcmp (buf
, ":tt") == 0)
276 if (flags
== TARGET_O_RDONLY
) /* opening tty "r" */
277 state
->Reg
[0] = 0; /* stdin */
279 state
->Reg
[0] = 1; /* stdout */
283 state
->Reg
[0] = sim_callback
->open (sim_callback
, buf
, flags
);
284 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
289 SWIread (ARMul_State
* state
, ARMword f
, ARMword ptr
, ARMword len
)
291 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
294 char *local
= malloc (len
);
298 sim_callback
->printf_filtered
300 "sim: Unable to read 0x%lx bytes - out of memory\n",
305 res
= sim_callback
->read (sim_callback
, f
, local
, len
);
307 for (i
= 0; i
< res
; i
++)
308 ARMul_SafeWriteByte (state
, ptr
+ i
, local
[i
]);
311 state
->Reg
[0] = res
== -1 ? -1 : len
- res
;
312 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
316 SWIwrite (ARMul_State
* state
, ARMword f
, ARMword ptr
, ARMword len
)
318 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
321 char *local
= malloc (len
);
325 sim_callback
->printf_filtered
327 "sim: Unable to write 0x%lx bytes - out of memory\n",
332 for (i
= 0; i
< len
; i
++)
333 local
[i
] = ARMul_SafeReadByte (state
, ptr
+ i
);
335 res
= sim_callback
->write (sim_callback
, f
, local
, len
);
336 state
->Reg
[0] = res
== -1 ? -1 : len
- res
;
339 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
343 SWIflen (ARMul_State
* state
, ARMword fh
)
345 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
350 OSptr
->ErrorNo
= EBADF
;
355 addr
= sim_callback
->lseek (sim_callback
, fh
, 0, SEEK_CUR
);
357 state
->Reg
[0] = sim_callback
->lseek (sim_callback
, fh
, 0L, SEEK_END
);
358 (void) sim_callback
->lseek (sim_callback
, fh
, addr
, SEEK_SET
);
360 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
364 SWIremove (ARMul_State
* state
, ARMword path
)
368 if (ReadFileName (state
, buf
, path
, sizeof buf
) != -1)
370 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
371 state
->Reg
[0] = sim_callback
->unlink (sim_callback
, buf
);
372 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
377 SWIrename (ARMul_State
* state
, ARMword old
, ARMword
new)
379 char oldbuf
[PATH_MAX
], newbuf
[PATH_MAX
];
381 if (ReadFileName (state
, oldbuf
, old
, sizeof oldbuf
) != -1
382 && ReadFileName (state
, newbuf
, new, sizeof newbuf
) != -1)
384 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
385 state
->Reg
[0] = sim_callback
->rename (sim_callback
, oldbuf
, newbuf
);
386 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
390 /* The emulator calls this routine when a SWI instruction is encuntered.
391 The parameter passed is the SWI number (lower 24 bits of the instruction). */
394 ARMul_OSHandleSWI (ARMul_State
* state
, ARMword number
)
396 struct OSblock
* OSptr
= (struct OSblock
*) state
->OSptr
;
397 int unhandled
= FALSE
;
402 if (swi_mask
& SWI_MASK_DEMON
)
403 SWIread (state
, state
->Reg
[0], state
->Reg
[1], state
->Reg
[2]);
409 if (swi_mask
& SWI_MASK_DEMON
)
410 SWIwrite (state
, state
->Reg
[0], state
->Reg
[1], state
->Reg
[2]);
416 if (swi_mask
& SWI_MASK_DEMON
)
417 SWIopen (state
, state
->Reg
[0], state
->Reg
[1]);
423 if (swi_mask
& SWI_MASK_DEMON
)
425 /* Return number of centi-seconds. */
427 #ifdef CLOCKS_PER_SEC
428 (CLOCKS_PER_SEC
>= 100)
429 ? (ARMword
) (clock () / (CLOCKS_PER_SEC
/ 100))
430 : (ARMword
) ((clock () * 100) / CLOCKS_PER_SEC
);
432 /* Presume unix... clock() returns microseconds. */
433 (ARMword
) (clock () / 10000);
435 OSptr
->ErrorNo
= errno
;
442 if (swi_mask
& SWI_MASK_DEMON
)
444 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
);
445 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
452 if (swi_mask
& SWI_MASK_DEMON
)
454 state
->Reg
[0] = sim_callback
->close (sim_callback
, state
->Reg
[0]);
455 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
462 if (swi_mask
& SWI_MASK_DEMON
)
463 SWIflen (state
, state
->Reg
[0]);
469 if (swi_mask
& SWI_MASK_DEMON
)
470 state
->Emulate
= FALSE
;
476 if (swi_mask
& SWI_MASK_DEMON
)
478 /* We must return non-zero for failure. */
479 state
->Reg
[0] = -1 >= sim_callback
->lseek (sim_callback
, state
->Reg
[0], state
->Reg
[1], SEEK_SET
);
480 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
487 if (swi_mask
& SWI_MASK_DEMON
)
489 char tmp
= state
->Reg
[0];
490 (void) sim_callback
->write_stdout (sim_callback
, &tmp
, 1);
491 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
498 if (swi_mask
& SWI_MASK_DEMON
)
499 SWIWrite0 (state
, state
->Reg
[0]);
505 if (swi_mask
& SWI_MASK_DEMON
)
506 state
->Reg
[0] = OSptr
->ErrorNo
;
512 if (swi_mask
& SWI_MASK_DEMON
)
514 state
->Reg
[0] = ADDRCMDLINE
;
516 state
->Reg
[1] = state
->MemSize
;
518 state
->Reg
[1] = ADDRUSERSTACK
;
520 WriteCommandLineTo (state
, state
->Reg
[0]);
527 state
->EndCondition
= RDIError_BreakpointReached
;
528 state
->Emulate
= FALSE
;
532 if (swi_mask
& SWI_MASK_DEMON
)
533 SWIremove (state
, state
->Reg
[0]);
539 if (swi_mask
& SWI_MASK_DEMON
)
540 SWIrename (state
, state
->Reg
[0], state
->Reg
[1]);
546 if (swi_mask
& SWI_MASK_DEMON
)
548 state
->Reg
[0] = sim_callback
->isatty (sim_callback
, state
->Reg
[0]);
549 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
555 /* Handle Angel SWIs as well as Demon ones. */
558 if (swi_mask
& SWI_MASK_ANGEL
)
563 /* R1 is almost always a parameter block. */
564 addr
= state
->Reg
[1];
565 /* R0 is a reason code. */
566 switch (state
->Reg
[0])
569 /* This can happen when a SWI is interrupted (eg receiving a
570 ctrl-C whilst processing SWIRead()). The SWI will complete
571 returning -1 in r0 to the caller. If GDB is then used to
572 resume the system call the reason code will now be -1. */
575 /* Unimplemented reason codes. */
576 case AngelSWI_Reason_ReadC
:
577 case AngelSWI_Reason_TmpNam
:
578 case AngelSWI_Reason_System
:
579 case AngelSWI_Reason_EnterSVC
:
581 state
->Emulate
= FALSE
;
584 case AngelSWI_Reason_Clock
:
585 /* Return number of centi-seconds. */
587 #ifdef CLOCKS_PER_SEC
588 (CLOCKS_PER_SEC
>= 100)
589 ? (ARMword
) (clock () / (CLOCKS_PER_SEC
/ 100))
590 : (ARMword
) ((clock () * 100) / CLOCKS_PER_SEC
);
592 /* Presume unix... clock() returns microseconds. */
593 (ARMword
) (clock () / 10000);
595 OSptr
->ErrorNo
= errno
;
598 case AngelSWI_Reason_Time
:
599 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
);
600 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
603 case AngelSWI_Reason_WriteC
:
605 char tmp
= ARMul_SafeReadByte (state
, addr
);
606 (void) sim_callback
->write_stdout (sim_callback
, &tmp
, 1);
607 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
611 case AngelSWI_Reason_Write0
:
612 SWIWrite0 (state
, addr
);
615 case AngelSWI_Reason_Close
:
616 state
->Reg
[0] = sim_callback
->close (sim_callback
, ARMul_ReadWord (state
, addr
));
617 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
620 case AngelSWI_Reason_Seek
:
621 state
->Reg
[0] = -1 >= sim_callback
->lseek (sim_callback
, ARMul_ReadWord (state
, addr
),
622 ARMul_ReadWord (state
, addr
+ 4),
624 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
627 case AngelSWI_Reason_FLen
:
628 SWIflen (state
, ARMul_ReadWord (state
, addr
));
631 case AngelSWI_Reason_GetCmdLine
:
632 WriteCommandLineTo (state
, ARMul_ReadWord (state
, addr
));
635 case AngelSWI_Reason_HeapInfo
:
636 /* R1 is a pointer to a pointer. */
637 addr
= ARMul_ReadWord (state
, addr
);
639 /* Pick up the right memory limit. */
641 temp
= state
->MemSize
;
643 temp
= ADDRUSERSTACK
;
645 ARMul_WriteWord (state
, addr
, 0); /* Heap base. */
646 ARMul_WriteWord (state
, addr
+ 4, temp
); /* Heap limit. */
647 ARMul_WriteWord (state
, addr
+ 8, temp
); /* Stack base. */
648 ARMul_WriteWord (state
, addr
+ 12, temp
); /* Stack limit. */
651 case AngelSWI_Reason_ReportException
:
652 if (state
->Reg
[1] == ADP_Stopped_ApplicationExit
)
656 state
->Emulate
= FALSE
;
659 case ADP_Stopped_ApplicationExit
:
661 state
->Emulate
= FALSE
;
664 case ADP_Stopped_RunTimeError
:
666 state
->Emulate
= FALSE
;
669 case AngelSWI_Reason_Errno
:
670 state
->Reg
[0] = OSptr
->ErrorNo
;
673 case AngelSWI_Reason_Open
:
675 ARMul_ReadWord (state
, addr
),
676 ARMul_ReadWord (state
, addr
+ 4));
679 case AngelSWI_Reason_Read
:
681 ARMul_ReadWord (state
, addr
),
682 ARMul_ReadWord (state
, addr
+ 4),
683 ARMul_ReadWord (state
, addr
+ 8));
686 case AngelSWI_Reason_Write
:
688 ARMul_ReadWord (state
, addr
),
689 ARMul_ReadWord (state
, addr
+ 4),
690 ARMul_ReadWord (state
, addr
+ 8));
693 case AngelSWI_Reason_IsTTY
:
694 state
->Reg
[0] = sim_callback
->isatty (sim_callback
,
695 ARMul_ReadWord (state
, addr
));
696 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
699 case AngelSWI_Reason_Remove
:
701 ARMul_ReadWord (state
, addr
));
703 case AngelSWI_Reason_Rename
:
705 ARMul_ReadWord (state
, addr
),
706 ARMul_ReadWord (state
, addr
+ 4));
713 /* The following SWIs are generated by the softvectorcode[]
714 installed by default by the simulator. */
715 case 0x91: /* Undefined Instruction. */
717 ARMword addr
= state
->RegBank
[UNDEFBANK
][14] - 4;
719 sim_callback
->printf_filtered
720 (sim_callback
, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x. Stopping.\n",
721 ARMul_ReadWord (state
, addr
), addr
);
722 state
->EndCondition
= RDIError_SoftwareInterrupt
;
723 state
->Emulate
= FALSE
;
727 case 0x90: /* Reset. */
728 case 0x92: /* SWI. */
729 /* These two can be safely ignored. */
732 case 0x93: /* Prefetch Abort. */
733 case 0x94: /* Data Abort. */
734 case 0x95: /* Address Exception. */
735 case 0x96: /* IRQ. */
736 case 0x97: /* FIQ. */
737 case 0x98: /* Error. */
742 /* This can happen when a SWI is interrupted (eg receiving a
743 ctrl-C whilst processing SWIRead()). The SWI will complete
744 returning -1 in r0 to the caller. If GDB is then used to
745 resume the system call the reason code will now be -1. */
748 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
749 if (swi_mask
& SWI_MASK_REDBOOT
)
751 switch (state
->Reg
[0])
753 /* These numbers are defined in libgloss/syscall.h
754 but the simulator should not be dependend upon
755 libgloss being installed. */
757 state
->Emulate
= FALSE
;
758 /* Copy exit code into r0. */
759 state
->Reg
[0] = state
->Reg
[1];
763 SWIopen (state
, state
->Reg
[1], state
->Reg
[2]);
767 state
->Reg
[0] = sim_callback
->close (sim_callback
, state
->Reg
[1]);
768 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
772 SWIread (state
, state
->Reg
[1], state
->Reg
[2], state
->Reg
[3]);
776 SWIwrite (state
, state
->Reg
[1], state
->Reg
[2], state
->Reg
[3]);
780 state
->Reg
[0] = sim_callback
->lseek (sim_callback
,
784 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
787 case 17: /* Utime. */
788 state
->Reg
[0] = state
->Reg
[1] = (ARMword
) sim_callback
->time (sim_callback
);
789 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
792 case 7: /* Unlink. */
793 case 8: /* Getpid. */
795 case 10: /* Fstat. */
797 case 12: /* Argvlen. */
799 case 14: /* ChDir. */
801 case 16: /* Chmod. */
803 sim_callback
->printf_filtered
805 "sim: unhandled RedBoot syscall `%d' encountered - "
806 "returning ENOSYS\n",
809 OSptr
->ErrorNo
= cb_host_to_target_errno
810 (sim_callback
, ENOSYS
);
812 case 1001: /* Meminfo. */
814 ARMword totmem
= state
->Reg
[1],
815 topmem
= state
->Reg
[2];
816 ARMword stack
= state
->MemSize
> 0
817 ? state
->MemSize
: ADDRUSERSTACK
;
819 ARMul_WriteWord (state
, totmem
, stack
);
821 ARMul_WriteWord (state
, topmem
, stack
);
827 sim_callback
->printf_filtered
829 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
842 if (SWI_vector_installed
)
847 cpsr
= ARMul_GetCPSR (state
);
850 ARMul_SetSPSR (state
, SVC32MODE
, cpsr
);
853 cpsr
|= SVC32MODE
| 0x80;
854 ARMul_SetCPSR (state
, cpsr
);
856 state
->RegBank
[SVCBANK
][14] = state
->Reg
[14] = state
->Reg
[15] - i_size
;
857 state
->NextInstr
= RESUME
;
858 state
->Reg
[15] = state
->pc
= ARMSWIV
;
863 sim_callback
->printf_filtered
865 "sim: unknown SWI encountered - %x - ignoring\n",