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
)
103 if (state
->OSptr
== NULL
)
105 state
->OSptr
= (unsigned char *) malloc (sizeof (struct OSblock
));
106 if (state
->OSptr
== NULL
)
108 perror ("OS Memory");
113 state
->Reg
[13] = ADDRSUPERSTACK
; /* Set up a stack for the current mode... */
114 ARMul_SetReg (state
, SVC32MODE
, 13, ADDRSUPERSTACK
);/* ...and for supervisor mode... */
115 ARMul_SetReg (state
, ABORT32MODE
, 13, ADDRSUPERSTACK
);/* ...and for abort 32 mode... */
116 ARMul_SetReg (state
, UNDEF32MODE
, 13, ADDRSUPERSTACK
);/* ...and for undef 32 mode... */
117 ARMul_SetReg (state
, SYSTEMMODE
, 13, ADDRSUPERSTACK
);/* ...and for system mode. */
118 instr
= 0xe59ff000 | (ADDRSOFTVECTORS
- 8); /* Load pc from soft vector */
120 for (i
= ARMul_ResetV
; i
<= ARMFIQV
; i
+= 4)
121 /* Write hardware vectors. */
122 ARMul_WriteWord (state
, i
, instr
);
124 SWI_vector_installed
= 0;
126 for (i
= ARMul_ResetV
; i
<= ARMFIQV
+ 4; i
+= 4)
128 ARMul_WriteWord (state
, ADDRSOFTVECTORS
+ i
, SOFTVECTORCODE
+ i
* 4);
129 ARMul_WriteWord (state
, ADDRSOFHANDLERS
+ 2 * i
+ 4L,
130 SOFTVECTORCODE
+ sizeof (softvectorcode
) - 4L);
133 for (i
= 0; i
< sizeof (softvectorcode
); i
+= 4)
134 ARMul_WriteWord (state
, SOFTVECTORCODE
+ i
, softvectorcode
[i
/ 4]);
136 ARMul_ConsolePrint (state
, ", Demon 1.01");
141 for (i
= 0; i
< fpesize
; i
+= 4)
143 ARMul_WriteWord (state
, FPESTART
+ i
, fpecode
[i
>> 2]);
145 /* Scan backwards from the end of the code. */
146 for (i
= FPESTART
+ fpesize
;; i
-= 4)
148 /* When we reach the marker value, break out of
149 the loop, leaving i pointing at the maker. */
150 if ((j
= ARMul_ReadWord (state
, i
)) == 0xffffffff)
153 /* If necessary, reverse the error strings. */
154 if (state
->bigendSig
&& j
< 0x80000000)
156 /* It's part of the string so swap it. */
157 j
= ((j
>> 0x18) & 0x000000ff) |
158 ((j
>> 0x08) & 0x0000ff00) |
159 ((j
<< 0x08) & 0x00ff0000) | ((j
<< 0x18) & 0xff000000);
160 ARMul_WriteWord (state
, i
, j
);
164 /* Copy old illegal instr vector. */
165 ARMul_WriteWord (state
, FPEOLDVECT
, ARMul_ReadWord (state
, ARMUndefinedInstrV
));
166 /* Install new vector. */
167 ARMul_WriteWord (state
, ARMUndefinedInstrV
, FPENEWVECT (ARMul_ReadWord (state
, i
- 4)));
168 ARMul_ConsolePrint (state
, ", FPE");
171 #endif /* VALIDATE */
174 /* Intel do not want DEMON SWI support. */
175 if (state
->is_XScale
)
176 swi_mask
= SWI_MASK_ANGEL
;
181 /* These are libgloss defines, but seem to be common across all supported ARM
182 targets at the moment. These should get moved to the callback open_map. */
183 #define TARGET_O_BINARY 0
184 #define TARGET_O_APPEND 0x8
185 #define TARGET_O_CREAT 0x200
186 #define TARGET_O_RDONLY 0x0
187 #define TARGET_O_RDWR 0x2
188 #define TARGET_O_TRUNC 0x400
189 #define TARGET_O_WRONLY 0x1
191 static const int translate_open_mode
[] =
193 TARGET_O_RDONLY
, /* "r" */
194 TARGET_O_RDONLY
+ TARGET_O_BINARY
, /* "rb" */
195 TARGET_O_RDWR
, /* "r+" */
196 TARGET_O_RDWR
+ TARGET_O_BINARY
, /* "r+b" */
197 TARGET_O_WRONLY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w" */
198 TARGET_O_WRONLY
+ TARGET_O_BINARY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "wb" */
199 TARGET_O_RDWR
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w+" */
200 TARGET_O_RDWR
+ TARGET_O_BINARY
+ TARGET_O_CREAT
+ TARGET_O_TRUNC
, /* "w+b" */
201 TARGET_O_WRONLY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "a" */
202 TARGET_O_WRONLY
+ TARGET_O_BINARY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "ab" */
203 TARGET_O_RDWR
+ TARGET_O_APPEND
+ TARGET_O_CREAT
, /* "a+" */
204 TARGET_O_RDWR
+ TARGET_O_BINARY
+ TARGET_O_APPEND
+ TARGET_O_CREAT
/* "a+b" */
208 SWIWrite0 (ARMul_State
* state
, ARMword addr
)
211 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
213 while ((temp
= ARMul_SafeReadByte (state
, addr
++)) != 0)
216 /* Note - we cannot just cast 'temp' to a (char *) here,
217 since on a big-endian host the byte value will end
218 up in the wrong place and a nul character will be printed. */
219 (void) sim_callback
->write_stdout (sim_callback
, & buffer
, 1);
222 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
226 WriteCommandLineTo (ARMul_State
* state
, ARMword addr
)
229 char *cptr
= state
->CommandLine
;
235 temp
= (ARMword
) * cptr
++;
236 ARMul_SafeWriteByte (state
, addr
++, temp
);
242 ReadFileName (ARMul_State
* state
, char *buf
, ARMword src
, size_t n
)
244 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
248 if ((*p
++ = ARMul_SafeReadByte (state
, src
++)) == '\0')
250 OSptr
->ErrorNo
= cb_host_to_target_errno (sim_callback
, ENAMETOOLONG
);
256 SWIopen (ARMul_State
* state
, ARMword name
, ARMword SWIflags
)
258 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
262 if (ReadFileName (state
, buf
, name
, sizeof buf
) == -1)
265 /* Now we need to decode the Demon open mode. */
266 if (SWIflags
>= ARRAY_SIZE (translate_open_mode
))
269 flags
= translate_open_mode
[SWIflags
];
271 /* Filename ":tt" is special: it denotes stdin/out. */
272 if (strcmp (buf
, ":tt") == 0)
274 if (flags
== TARGET_O_RDONLY
) /* opening tty "r" */
275 state
->Reg
[0] = 0; /* stdin */
277 state
->Reg
[0] = 1; /* stdout */
281 state
->Reg
[0] = sim_callback
->open (sim_callback
, buf
, flags
);
282 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
287 SWIread (ARMul_State
* state
, ARMword f
, ARMword ptr
, ARMword len
)
289 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
292 char *local
= malloc (len
);
296 sim_callback
->printf_filtered
298 "sim: Unable to read 0x%lx bytes - out of memory\n",
303 res
= sim_callback
->read (sim_callback
, f
, local
, len
);
305 for (i
= 0; i
< res
; i
++)
306 ARMul_SafeWriteByte (state
, ptr
+ i
, local
[i
]);
309 state
->Reg
[0] = res
== -1 ? -1 : len
- res
;
310 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
314 SWIwrite (ARMul_State
* state
, ARMword f
, ARMword ptr
, ARMword len
)
316 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
319 char *local
= malloc (len
);
323 sim_callback
->printf_filtered
325 "sim: Unable to write 0x%lx bytes - out of memory\n",
330 for (i
= 0; i
< len
; i
++)
331 local
[i
] = ARMul_SafeReadByte (state
, ptr
+ i
);
333 res
= sim_callback
->write (sim_callback
, f
, local
, len
);
334 state
->Reg
[0] = res
== -1 ? -1 : len
- res
;
337 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
341 SWIflen (ARMul_State
* state
, ARMword fh
)
343 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
348 OSptr
->ErrorNo
= EBADF
;
353 addr
= sim_callback
->lseek (sim_callback
, fh
, 0, SEEK_CUR
);
355 state
->Reg
[0] = sim_callback
->lseek (sim_callback
, fh
, 0L, SEEK_END
);
356 (void) sim_callback
->lseek (sim_callback
, fh
, addr
, SEEK_SET
);
358 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
362 SWIremove (ARMul_State
* state
, ARMword path
)
366 if (ReadFileName (state
, buf
, path
, sizeof buf
) != -1)
368 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
369 state
->Reg
[0] = sim_callback
->unlink (sim_callback
, buf
);
370 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
375 SWIrename (ARMul_State
* state
, ARMword old
, ARMword
new)
377 char oldbuf
[PATH_MAX
], newbuf
[PATH_MAX
];
379 if (ReadFileName (state
, oldbuf
, old
, sizeof oldbuf
) != -1
380 && ReadFileName (state
, newbuf
, new, sizeof newbuf
) != -1)
382 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
383 state
->Reg
[0] = sim_callback
->rename (sim_callback
, oldbuf
, newbuf
);
384 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
388 /* The emulator calls this routine when a SWI instruction is encuntered.
389 The parameter passed is the SWI number (lower 24 bits of the instruction). */
392 ARMul_OSHandleSWI (ARMul_State
* state
, ARMword number
)
394 struct OSblock
* OSptr
= (struct OSblock
*) state
->OSptr
;
395 int unhandled
= FALSE
;
400 if (swi_mask
& SWI_MASK_DEMON
)
401 SWIread (state
, state
->Reg
[0], state
->Reg
[1], state
->Reg
[2]);
407 if (swi_mask
& SWI_MASK_DEMON
)
408 SWIwrite (state
, state
->Reg
[0], state
->Reg
[1], state
->Reg
[2]);
414 if (swi_mask
& SWI_MASK_DEMON
)
415 SWIopen (state
, state
->Reg
[0], state
->Reg
[1]);
421 if (swi_mask
& SWI_MASK_DEMON
)
423 /* Return number of centi-seconds. */
425 #ifdef CLOCKS_PER_SEC
426 (CLOCKS_PER_SEC
>= 100)
427 ? (ARMword
) (clock () / (CLOCKS_PER_SEC
/ 100))
428 : (ARMword
) ((clock () * 100) / CLOCKS_PER_SEC
);
430 /* Presume unix... clock() returns microseconds. */
431 (ARMword
) (clock () / 10000);
433 OSptr
->ErrorNo
= errno
;
440 if (swi_mask
& SWI_MASK_DEMON
)
442 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
);
443 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
450 if (swi_mask
& SWI_MASK_DEMON
)
452 state
->Reg
[0] = sim_callback
->close (sim_callback
, state
->Reg
[0]);
453 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
460 if (swi_mask
& SWI_MASK_DEMON
)
461 SWIflen (state
, state
->Reg
[0]);
467 if (swi_mask
& SWI_MASK_DEMON
)
468 state
->Emulate
= FALSE
;
474 if (swi_mask
& SWI_MASK_DEMON
)
476 /* We must return non-zero for failure. */
477 state
->Reg
[0] = -1 >= sim_callback
->lseek (sim_callback
, state
->Reg
[0], state
->Reg
[1], SEEK_SET
);
478 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
485 if (swi_mask
& SWI_MASK_DEMON
)
487 char tmp
= state
->Reg
[0];
488 (void) sim_callback
->write_stdout (sim_callback
, &tmp
, 1);
489 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
496 if (swi_mask
& SWI_MASK_DEMON
)
497 SWIWrite0 (state
, state
->Reg
[0]);
503 if (swi_mask
& SWI_MASK_DEMON
)
504 state
->Reg
[0] = OSptr
->ErrorNo
;
510 if (swi_mask
& SWI_MASK_DEMON
)
512 state
->Reg
[0] = ADDRCMDLINE
;
514 state
->Reg
[1] = state
->MemSize
;
516 state
->Reg
[1] = ADDRUSERSTACK
;
518 WriteCommandLineTo (state
, state
->Reg
[0]);
525 state
->EndCondition
= RDIError_BreakpointReached
;
526 state
->Emulate
= FALSE
;
530 if (swi_mask
& SWI_MASK_DEMON
)
531 SWIremove (state
, state
->Reg
[0]);
537 if (swi_mask
& SWI_MASK_DEMON
)
538 SWIrename (state
, state
->Reg
[0], state
->Reg
[1]);
544 if (swi_mask
& SWI_MASK_DEMON
)
546 state
->Reg
[0] = sim_callback
->isatty (sim_callback
, state
->Reg
[0]);
547 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
553 /* Handle Angel SWIs as well as Demon ones. */
556 if (swi_mask
& SWI_MASK_ANGEL
)
561 /* R1 is almost always a parameter block. */
562 addr
= state
->Reg
[1];
563 /* R0 is a reason code. */
564 switch (state
->Reg
[0])
567 /* This can happen when a SWI is interrupted (eg receiving a
568 ctrl-C whilst processing SWIRead()). The SWI will complete
569 returning -1 in r0 to the caller. If GDB is then used to
570 resume the system call the reason code will now be -1. */
573 /* Unimplemented reason codes. */
574 case AngelSWI_Reason_ReadC
:
575 case AngelSWI_Reason_TmpNam
:
576 case AngelSWI_Reason_System
:
577 case AngelSWI_Reason_EnterSVC
:
579 state
->Emulate
= FALSE
;
582 case AngelSWI_Reason_Clock
:
583 /* Return number of centi-seconds. */
585 #ifdef CLOCKS_PER_SEC
586 (CLOCKS_PER_SEC
>= 100)
587 ? (ARMword
) (clock () / (CLOCKS_PER_SEC
/ 100))
588 : (ARMword
) ((clock () * 100) / CLOCKS_PER_SEC
);
590 /* Presume unix... clock() returns microseconds. */
591 (ARMword
) (clock () / 10000);
593 OSptr
->ErrorNo
= errno
;
596 case AngelSWI_Reason_Time
:
597 state
->Reg
[0] = (ARMword
) sim_callback
->time (sim_callback
);
598 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
601 case AngelSWI_Reason_WriteC
:
603 char tmp
= ARMul_SafeReadByte (state
, addr
);
604 (void) sim_callback
->write_stdout (sim_callback
, &tmp
, 1);
605 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
609 case AngelSWI_Reason_Write0
:
610 SWIWrite0 (state
, addr
);
613 case AngelSWI_Reason_Close
:
614 state
->Reg
[0] = sim_callback
->close (sim_callback
, ARMul_ReadWord (state
, addr
));
615 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
618 case AngelSWI_Reason_Seek
:
619 state
->Reg
[0] = -1 >= sim_callback
->lseek (sim_callback
, ARMul_ReadWord (state
, addr
),
620 ARMul_ReadWord (state
, addr
+ 4),
622 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
625 case AngelSWI_Reason_FLen
:
626 SWIflen (state
, ARMul_ReadWord (state
, addr
));
629 case AngelSWI_Reason_GetCmdLine
:
630 WriteCommandLineTo (state
, ARMul_ReadWord (state
, addr
));
633 case AngelSWI_Reason_HeapInfo
:
634 /* R1 is a pointer to a pointer. */
635 addr
= ARMul_ReadWord (state
, addr
);
637 /* Pick up the right memory limit. */
639 temp
= state
->MemSize
;
641 temp
= ADDRUSERSTACK
;
643 ARMul_WriteWord (state
, addr
, 0); /* Heap base. */
644 ARMul_WriteWord (state
, addr
+ 4, temp
); /* Heap limit. */
645 ARMul_WriteWord (state
, addr
+ 8, temp
); /* Stack base. */
646 ARMul_WriteWord (state
, addr
+ 12, temp
); /* Stack limit. */
649 case AngelSWI_Reason_ReportException
:
650 if (state
->Reg
[1] == ADP_Stopped_ApplicationExit
)
654 state
->Emulate
= FALSE
;
657 case ADP_Stopped_ApplicationExit
:
659 state
->Emulate
= FALSE
;
662 case ADP_Stopped_RunTimeError
:
664 state
->Emulate
= FALSE
;
667 case AngelSWI_Reason_Errno
:
668 state
->Reg
[0] = OSptr
->ErrorNo
;
671 case AngelSWI_Reason_Open
:
673 ARMul_ReadWord (state
, addr
),
674 ARMul_ReadWord (state
, addr
+ 4));
677 case AngelSWI_Reason_Read
:
679 ARMul_ReadWord (state
, addr
),
680 ARMul_ReadWord (state
, addr
+ 4),
681 ARMul_ReadWord (state
, addr
+ 8));
684 case AngelSWI_Reason_Write
:
686 ARMul_ReadWord (state
, addr
),
687 ARMul_ReadWord (state
, addr
+ 4),
688 ARMul_ReadWord (state
, addr
+ 8));
691 case AngelSWI_Reason_IsTTY
:
692 state
->Reg
[0] = sim_callback
->isatty (sim_callback
,
693 ARMul_ReadWord (state
, addr
));
694 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
697 case AngelSWI_Reason_Remove
:
699 ARMul_ReadWord (state
, addr
));
702 case AngelSWI_Reason_Rename
:
704 ARMul_ReadWord (state
, addr
),
705 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",
835 ATTRIBUTE_FALLTHROUGH
;
843 if (SWI_vector_installed
)
848 cpsr
= ARMul_GetCPSR (state
);
851 ARMul_SetSPSR (state
, SVC32MODE
, cpsr
);
854 cpsr
|= SVC32MODE
| 0x80;
855 ARMul_SetCPSR (state
, cpsr
);
857 state
->RegBank
[SVCBANK
][14] = state
->Reg
[14] = state
->Reg
[15] - i_size
;
858 state
->NextInstr
= RESUME
;
859 state
->Reg
[15] = state
->pc
= ARMSWIV
;
864 sim_callback
->printf_filtered
866 "sim: unknown SWI encountered - %x - ignoring\n",