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 "targ-vals.h"
36 #ifndef TARGET_O_BINARY
37 #define TARGET_O_BINARY 0
41 #include <unistd.h> /* For SEEK_SET etc. */
56 /* For RDIError_BreakpointReached. */
59 #include "sim/callback.h"
60 extern host_callback
*sim_callback
;
62 extern unsigned ARMul_OSInit (ARMul_State
*);
63 extern unsigned ARMul_OSHandleSWI (ARMul_State
*, ARMword
);
72 /* OS private Information. */
79 /* Bit mask of enabled SWI implementations. */
80 unsigned int swi_mask
= -1;
83 static ARMword softvectorcode
[] =
85 /* Installed instructions:
86 swi tidyexception + event;
89 swi generateexception + event. */
90 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
91 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
92 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
93 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
94 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
95 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
96 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
97 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
98 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
99 0xe1a0f00e /* Default handler */
102 /* Time for the Operating System to initialise itself. */
105 ARMul_OSInit (ARMul_State
* state
)
110 struct OSblock
*OSptr
= (struct OSblock
*) state
->OSptr
;
112 if (state
->OSptr
== NULL
)
114 state
->OSptr
= (unsigned char *) malloc (sizeof (struct OSblock
));
115 if (state
->OSptr
== NULL
)
117 perror ("OS Memory");
122 OSptr
= (struct OSblock
*) state
->OSptr
;
123 state
->Reg
[13] = ADDRSUPERSTACK
; /* Set up a stack for the current mode... */
124 ARMul_SetReg (state
, SVC32MODE
, 13, ADDRSUPERSTACK
);/* ...and for supervisor mode... */
125 ARMul_SetReg (state
, ABORT32MODE
, 13, ADDRSUPERSTACK
);/* ...and for abort 32 mode... */
126 ARMul_SetReg (state
, UNDEF32MODE
, 13, ADDRSUPERSTACK
);/* ...and for undef 32 mode... */
127 ARMul_SetReg (state
, SYSTEMMODE
, 13, ADDRSUPERSTACK
);/* ...and for system mode. */
128 instr
= 0xe59ff000 | (ADDRSOFTVECTORS
- 8); /* Load pc from soft vector */
130 for (i
= ARMul_ResetV
; i
<= ARMFIQV
; i
+= 4)
131 /* Write hardware vectors. */
132 ARMul_WriteWord (state
, i
, instr
);
134 SWI_vector_installed
= 0;
136 for (i
= ARMul_ResetV
; i
<= ARMFIQV
+ 4; i
+= 4)
138 ARMul_WriteWord (state
, ADDRSOFTVECTORS
+ i
, SOFTVECTORCODE
+ i
* 4);
139 ARMul_WriteWord (state
, ADDRSOFHANDLERS
+ 2 * i
+ 4L,
140 SOFTVECTORCODE
+ sizeof (softvectorcode
) - 4L);
143 for (i
= 0; i
< sizeof (softvectorcode
); i
+= 4)
144 ARMul_WriteWord (state
, SOFTVECTORCODE
+ i
, softvectorcode
[i
/ 4]);
146 ARMul_ConsolePrint (state
, ", Demon 1.01");
151 for (i
= 0; i
< fpesize
; i
+= 4)
153 ARMul_WriteWord (state
, FPESTART
+ i
, fpecode
[i
>> 2]);
155 /* Scan backwards from the end of the code. */
156 for (i
= FPESTART
+ fpesize
;; i
-= 4)
158 /* When we reach the marker value, break out of
159 the loop, leaving i pointing at the maker. */
160 if ((j
= ARMul_ReadWord (state
, i
)) == 0xffffffff)
163 /* If necessary, reverse the error strings. */
164 if (state
->bigendSig
&& j
< 0x80000000)
166 /* It's part of the string so swap it. */
167 j
= ((j
>> 0x18) & 0x000000ff) |
168 ((j
>> 0x08) & 0x0000ff00) |
169 ((j
<< 0x08) & 0x00ff0000) | ((j
<< 0x18) & 0xff000000);
170 ARMul_WriteWord (state
, i
, j
);
174 /* Copy old illegal instr vector. */
175 ARMul_WriteWord (state
, FPEOLDVECT
, ARMul_ReadWord (state
, ARMUndefinedInstrV
));
176 /* Install new vector. */
177 ARMul_WriteWord (state
, ARMUndefinedInstrV
, FPENEWVECT (ARMul_ReadWord (state
, i
- 4)));
178 ARMul_ConsolePrint (state
, ", FPE");
181 #endif /* VALIDATE */
184 /* Intel do not want DEMON SWI support. */
185 if (state
->is_XScale
)
186 swi_mask
= SWI_MASK_ANGEL
;
191 static 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
));
701 case AngelSWI_Reason_Rename
:
703 ARMul_ReadWord (state
, addr
),
704 ARMul_ReadWord (state
, addr
+ 4));
711 /* The following SWIs are generated by the softvectorcode[]
712 installed by default by the simulator. */
713 case 0x91: /* Undefined Instruction. */
715 ARMword addr
= state
->RegBank
[UNDEFBANK
][14] - 4;
717 sim_callback
->printf_filtered
718 (sim_callback
, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x. Stopping.\n",
719 ARMul_ReadWord (state
, addr
), addr
);
720 state
->EndCondition
= RDIError_SoftwareInterrupt
;
721 state
->Emulate
= FALSE
;
725 case 0x90: /* Reset. */
726 case 0x92: /* SWI. */
727 /* These two can be safely ignored. */
730 case 0x93: /* Prefetch Abort. */
731 case 0x94: /* Data Abort. */
732 case 0x95: /* Address Exception. */
733 case 0x96: /* IRQ. */
734 case 0x97: /* FIQ. */
735 case 0x98: /* Error. */
740 /* This can happen when a SWI is interrupted (eg receiving a
741 ctrl-C whilst processing SWIRead()). The SWI will complete
742 returning -1 in r0 to the caller. If GDB is then used to
743 resume the system call the reason code will now be -1. */
746 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
747 if (swi_mask
& SWI_MASK_REDBOOT
)
749 switch (state
->Reg
[0])
751 /* These numbers are defined in libgloss/syscall.h
752 but the simulator should not be dependend upon
753 libgloss being installed. */
755 state
->Emulate
= FALSE
;
756 /* Copy exit code into r0. */
757 state
->Reg
[0] = state
->Reg
[1];
761 SWIopen (state
, state
->Reg
[1], state
->Reg
[2]);
765 state
->Reg
[0] = sim_callback
->close (sim_callback
, state
->Reg
[1]);
766 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
770 SWIread (state
, state
->Reg
[1], state
->Reg
[2], state
->Reg
[3]);
774 SWIwrite (state
, state
->Reg
[1], state
->Reg
[2], state
->Reg
[3]);
778 state
->Reg
[0] = sim_callback
->lseek (sim_callback
,
782 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
785 case 17: /* Utime. */
786 state
->Reg
[0] = state
->Reg
[1] = (ARMword
) sim_callback
->time (sim_callback
);
787 OSptr
->ErrorNo
= sim_callback
->get_errno (sim_callback
);
790 case 7: /* Unlink. */
791 case 8: /* Getpid. */
793 case 10: /* Fstat. */
795 case 12: /* Argvlen. */
797 case 14: /* ChDir. */
799 case 16: /* Chmod. */
801 sim_callback
->printf_filtered
803 "sim: unhandled RedBoot syscall `%d' encountered - "
804 "returning ENOSYS\n",
807 OSptr
->ErrorNo
= cb_host_to_target_errno
808 (sim_callback
, ENOSYS
);
810 case 1001: /* Meminfo. */
812 ARMword totmem
= state
->Reg
[1],
813 topmem
= state
->Reg
[2];
814 ARMword stack
= state
->MemSize
> 0
815 ? state
->MemSize
: ADDRUSERSTACK
;
817 ARMul_WriteWord (state
, totmem
, stack
);
819 ARMul_WriteWord (state
, topmem
, stack
);
825 sim_callback
->printf_filtered
827 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
840 if (SWI_vector_installed
)
845 cpsr
= ARMul_GetCPSR (state
);
848 ARMul_SetSPSR (state
, SVC32MODE
, cpsr
);
851 cpsr
|= SVC32MODE
| 0x80;
852 ARMul_SetCPSR (state
, cpsr
);
854 state
->RegBank
[SVCBANK
][14] = state
->Reg
[14] = state
->Reg
[15] - i_size
;
855 state
->NextInstr
= RESUME
;
856 state
->Reg
[15] = state
->pc
= ARMSWIV
;
861 sim_callback
->printf_filtered
863 "sim: unknown SWI encountered - %x - ignoring\n",