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 2 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, write to the Free Software
16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
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. */
32 #include "targ-vals.h"
34 #ifndef TARGET_O_BINARY
35 #define TARGET_O_BINARY 0
39 #include <unistd.h> /* For SEEK_SET etc. */
43 extern int _fisatty (FILE *);
44 #define isatty_(f) _fisatty(f)
48 #define isatty_(f) isatty((f)->_file)
52 #define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
54 #define isatty_(f) isatty (fileno (f))
71 /* For RDIError_BreakpointReached. */
74 #include "gdb/callback.h"
75 extern host_callback *sim_callback;
77 extern unsigned ARMul_OSInit (ARMul_State *);
78 extern void ARMul_OSExit (ARMul_State *);
79 extern unsigned ARMul_OSHandleSWI (ARMul_State *, ARMword);
80 extern unsigned ARMul_OSException (ARMul_State *, ARMword, ARMword);
81 extern ARMword ARMul_OSLastErrorP (ARMul_State *);
82 extern ARMword ARMul_Debug (ARMul_State *, ARMword, ARMword);
84 #define BUFFERSIZE 4096
88 #define UNIQUETEMPS 256
93 /* OS private Information. */
100 FILE *FileTable[FOPEN_MAX];
101 char FileFlags[FOPEN_MAX];
102 char *tempnames[UNIQUETEMPS];
111 #define FIXCRLF(t,c) ((t & BINARY) ? \
113 ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
116 #define FIXCRLF(t,c) c
119 /* Bit mask of enabled SWI implementations. */
120 unsigned int swi_mask = -1;
123 static ARMword softvectorcode[] =
125 /* Installed instructions:
126 swi tidyexception + event;
129 swi generateexception + event. */
130 0xef000090, 0xe1a0e00f, 0xe89b8800, 0xef000080, /* Reset */
131 0xef000091, 0xe1a0e00f, 0xe89b8800, 0xef000081, /* Undef */
132 0xef000092, 0xe1a0e00f, 0xe89b8800, 0xef000082, /* SWI */
133 0xef000093, 0xe1a0e00f, 0xe89b8800, 0xef000083, /* Prefetch abort */
134 0xef000094, 0xe1a0e00f, 0xe89b8800, 0xef000084, /* Data abort */
135 0xef000095, 0xe1a0e00f, 0xe89b8800, 0xef000085, /* Address exception */
136 0xef000096, 0xe1a0e00f, 0xe89b8800, 0xef000086, /* IRQ */
137 0xef000097, 0xe1a0e00f, 0xe89b8800, 0xef000087, /* FIQ */
138 0xef000098, 0xe1a0e00f, 0xe89b8800, 0xef000088, /* Error */
139 0xe1a0f00e /* Default handler */
142 /* Time for the Operating System to initialise itself. */
145 ARMul_OSInit (ARMul_State * state)
150 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
152 if (state->OSptr == NULL)
154 state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
155 if (state->OSptr == NULL)
157 perror ("OS Memory");
162 OSptr = (struct OSblock *) state->OSptr;
164 state->Reg[13] = ADDRSUPERSTACK; /* Set up a stack for the current mode... */
165 ARMul_SetReg (state, SVC32MODE, 13, ADDRSUPERSTACK);/* ...and for supervisor mode... */
166 ARMul_SetReg (state, ABORT32MODE, 13, ADDRSUPERSTACK);/* ...and for abort 32 mode... */
167 ARMul_SetReg (state, UNDEF32MODE, 13, ADDRSUPERSTACK);/* ...and for undef 32 mode... */
168 ARMul_SetReg (state, SYSTEMMODE, 13, ADDRSUPERSTACK);/* ...and for system mode. */
169 instr = 0xe59ff000 | (ADDRSOFTVECTORS - 8); /* Load pc from soft vector */
171 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
172 /* Write hardware vectors. */
173 ARMul_WriteWord (state, i, instr);
175 SWI_vector_installed = 0;
177 for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
179 ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
180 ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
181 SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
184 for (i = 0; i < sizeof (softvectorcode); i += 4)
185 ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
187 for (i = 0; i < FOPEN_MAX; i++)
188 OSptr->FileTable[i] = NULL;
190 for (i = 0; i < UNIQUETEMPS; i++)
191 OSptr->tempnames[i] = NULL;
193 ARMul_ConsolePrint (state, ", Demon 1.01");
198 for (i = 0; i < fpesize; i += 4)
200 ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
202 /* Scan backwards from the end of the code. */
203 for (i = FPESTART + fpesize;; i -= 4)
205 /* When we reach the marker value, break out of
206 the loop, leaving i pointing at the maker. */
207 if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
210 /* If necessary, reverse the error strings. */
211 if (state->bigendSig && j < 0x80000000)
213 /* It's part of the string so swap it. */
214 j = ((j >> 0x18) & 0x000000ff) |
215 ((j >> 0x08) & 0x0000ff00) |
216 ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
217 ARMul_WriteWord (state, i, j);
221 /* Copy old illegal instr vector. */
222 ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, ARMUndefinedInstrV));
223 /* Install new vector. */
224 ARMul_WriteWord (state, ARMUndefinedInstrV, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
225 ARMul_ConsolePrint (state, ", FPE");
228 #endif /* VALIDATE */
231 /* Intel do not want DEMON SWI support. */
232 if (state->is_XScale)
233 swi_mask = SWI_MASK_ANGEL;
239 ARMul_OSExit (ARMul_State * state)
241 free ((char *) state->OSptr);
245 /* Return the last Operating System Error. */
247 ARMword ARMul_OSLastErrorP (ARMul_State * state)
249 return ((struct OSblock *) state->OSptr)->ErrorP;
252 static int translate_open_mode[] =
254 TARGET_O_RDONLY, /* "r" */
255 TARGET_O_RDONLY + TARGET_O_BINARY, /* "rb" */
256 TARGET_O_RDWR, /* "r+" */
257 TARGET_O_RDWR + TARGET_O_BINARY, /* "r+b" */
258 TARGET_O_WRONLY + TARGET_O_CREAT + TARGET_O_TRUNC, /* "w" */
259 TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC, /* "wb" */
260 TARGET_O_RDWR + TARGET_O_CREAT + TARGET_O_TRUNC, /* "w+" */
261 TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_CREAT + TARGET_O_TRUNC, /* "w+b" */
262 TARGET_O_WRONLY + TARGET_O_APPEND + TARGET_O_CREAT, /* "a" */
263 TARGET_O_WRONLY + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT, /* "ab" */
264 TARGET_O_RDWR + TARGET_O_APPEND + TARGET_O_CREAT, /* "a+" */
265 TARGET_O_RDWR + TARGET_O_BINARY + TARGET_O_APPEND + TARGET_O_CREAT /* "a+b" */
269 SWIWrite0 (ARMul_State * state, ARMword addr)
272 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
274 while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
277 /* Note - we cannot just cast 'temp' to a (char *) here,
278 since on a big-endian host the byte value will end
279 up in the wrong place and a nul character will be printed. */
280 (void) sim_callback->write_stdout (sim_callback, & buffer, 1);
283 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
287 WriteCommandLineTo (ARMul_State * state, ARMword addr)
290 char *cptr = state->CommandLine;
296 temp = (ARMword) * cptr++;
297 ARMul_SafeWriteByte (state, addr++, temp);
303 ReadFileName (ARMul_State * state, char *buf, ARMword src, size_t n)
305 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
309 if ((*p++ = ARMul_SafeReadByte (state, src++)) == '\0')
311 OSptr->ErrorNo = cb_host_to_target_errno (sim_callback, ENAMETOOLONG);
317 SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
319 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
323 if (ReadFileName (state, buf, name, sizeof buf) == -1)
326 /* Now we need to decode the Demon open mode. */
327 flags = translate_open_mode[SWIflags];
329 /* Filename ":tt" is special: it denotes stdin/out. */
330 if (strcmp (buf, ":tt") == 0)
332 if (flags == TARGET_O_RDONLY) /* opening tty "r" */
333 state->Reg[0] = 0; /* stdin */
335 state->Reg[0] = 1; /* stdout */
339 state->Reg[0] = sim_callback->open (sim_callback, buf, flags);
340 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
345 SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
347 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
350 char *local = malloc (len);
354 sim_callback->printf_filtered
356 "sim: Unable to read 0x%ulx bytes - out of memory\n",
361 res = sim_callback->read (sim_callback, f, local, len);
363 for (i = 0; i < res; i++)
364 ARMul_SafeWriteByte (state, ptr + i, local[i]);
367 state->Reg[0] = res == -1 ? -1 : len - res;
368 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
372 SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
374 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
377 char *local = malloc (len);
381 sim_callback->printf_filtered
383 "sim: Unable to write 0x%lx bytes - out of memory\n",
388 for (i = 0; i < len; i++)
389 local[i] = ARMul_SafeReadByte (state, ptr + i);
391 res = sim_callback->write (sim_callback, f, local, len);
392 state->Reg[0] = res == -1 ? -1 : len - res;
395 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
399 SWIflen (ARMul_State * state, ARMword fh)
401 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
406 OSptr->ErrorNo = EBADF;
411 addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
413 state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
414 (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
416 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
420 SWIremove (ARMul_State * state, ARMword path)
424 if (ReadFileName (state, buf, path, sizeof buf) != -1)
426 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
427 state->Reg[0] = sim_callback->unlink (sim_callback, buf);
428 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
433 SWIrename (ARMul_State * state, ARMword old, ARMword new)
435 char oldbuf[PATH_MAX], newbuf[PATH_MAX];
437 if (ReadFileName (state, oldbuf, old, sizeof oldbuf) != -1
438 && ReadFileName (state, newbuf, new, sizeof newbuf) != -1)
440 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
441 state->Reg[0] = sim_callback->rename (sim_callback, oldbuf, newbuf);
442 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
446 /* The emulator calls this routine when a SWI instruction is encuntered.
447 The parameter passed is the SWI number (lower 24 bits of the instruction). */
450 ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
452 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
453 int unhandled = FALSE;
458 if (swi_mask & SWI_MASK_DEMON)
459 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
465 if (swi_mask & SWI_MASK_DEMON)
466 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
472 if (swi_mask & SWI_MASK_DEMON)
473 SWIopen (state, state->Reg[0], state->Reg[1]);
479 if (swi_mask & SWI_MASK_DEMON)
481 /* Return number of centi-seconds. */
483 #ifdef CLOCKS_PER_SEC
484 (CLOCKS_PER_SEC >= 100)
485 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
486 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
488 /* Presume unix... clock() returns microseconds. */
489 (ARMword) (clock () / 10000);
491 OSptr->ErrorNo = errno;
498 if (swi_mask & SWI_MASK_DEMON)
500 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
501 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
508 if (swi_mask & SWI_MASK_DEMON)
510 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
511 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
518 if (swi_mask & SWI_MASK_DEMON)
519 SWIflen (state, state->Reg[0]);
525 if (swi_mask & SWI_MASK_DEMON)
526 state->Emulate = FALSE;
532 if (swi_mask & SWI_MASK_DEMON)
534 /* We must return non-zero for failure. */
535 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, state->Reg[0], state->Reg[1], SEEK_SET);
536 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
543 if (swi_mask & SWI_MASK_DEMON)
545 char tmp = state->Reg[0];
546 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
547 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
554 if (swi_mask & SWI_MASK_DEMON)
555 SWIWrite0 (state, state->Reg[0]);
561 if (swi_mask & SWI_MASK_DEMON)
562 state->Reg[0] = OSptr->ErrorNo;
568 if (swi_mask & SWI_MASK_DEMON)
570 state->Reg[0] = ADDRCMDLINE;
572 state->Reg[1] = state->MemSize;
574 state->Reg[1] = ADDRUSERSTACK;
576 WriteCommandLineTo (state, state->Reg[0]);
583 state->EndCondition = RDIError_BreakpointReached;
584 state->Emulate = FALSE;
588 if (swi_mask & SWI_MASK_DEMON)
589 SWIremove (state, state->Reg[0]);
595 if (swi_mask & SWI_MASK_DEMON)
596 SWIrename (state, state->Reg[0], state->Reg[1]);
602 if (swi_mask & SWI_MASK_DEMON)
604 state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]);
605 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
611 /* Handle Angel SWIs as well as Demon ones. */
614 if (swi_mask & SWI_MASK_ANGEL)
619 /* R1 is almost always a parameter block. */
620 addr = state->Reg[1];
621 /* R0 is a reason code. */
622 switch (state->Reg[0])
625 /* This can happen when a SWI is interrupted (eg receiving a
626 ctrl-C whilst processing SWIRead()). The SWI will complete
627 returning -1 in r0 to the caller. If GDB is then used to
628 resume the system call the reason code will now be -1. */
631 /* Unimplemented reason codes. */
632 case AngelSWI_Reason_ReadC:
633 case AngelSWI_Reason_TmpNam:
634 case AngelSWI_Reason_System:
635 case AngelSWI_Reason_EnterSVC:
637 state->Emulate = FALSE;
640 case AngelSWI_Reason_Clock:
641 /* Return number of centi-seconds. */
643 #ifdef CLOCKS_PER_SEC
644 (CLOCKS_PER_SEC >= 100)
645 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
646 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
648 /* Presume unix... clock() returns microseconds. */
649 (ARMword) (clock () / 10000);
651 OSptr->ErrorNo = errno;
654 case AngelSWI_Reason_Time:
655 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
656 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
659 case AngelSWI_Reason_WriteC:
661 char tmp = ARMul_SafeReadByte (state, addr);
662 (void) sim_callback->write_stdout (sim_callback, &tmp, 1);
663 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
667 case AngelSWI_Reason_Write0:
668 SWIWrite0 (state, addr);
671 case AngelSWI_Reason_Close:
672 state->Reg[0] = sim_callback->close (sim_callback, ARMul_ReadWord (state, addr));
673 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
676 case AngelSWI_Reason_Seek:
677 state->Reg[0] = -1 >= sim_callback->lseek (sim_callback, ARMul_ReadWord (state, addr),
678 ARMul_ReadWord (state, addr + 4),
680 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
683 case AngelSWI_Reason_FLen:
684 SWIflen (state, ARMul_ReadWord (state, addr));
687 case AngelSWI_Reason_GetCmdLine:
688 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
691 case AngelSWI_Reason_HeapInfo:
692 /* R1 is a pointer to a pointer. */
693 addr = ARMul_ReadWord (state, addr);
695 /* Pick up the right memory limit. */
697 temp = state->MemSize;
699 temp = ADDRUSERSTACK;
701 ARMul_WriteWord (state, addr, 0); /* Heap base. */
702 ARMul_WriteWord (state, addr + 4, temp); /* Heap limit. */
703 ARMul_WriteWord (state, addr + 8, temp); /* Stack base. */
704 ARMul_WriteWord (state, addr + 12, temp); /* Stack limit. */
707 case AngelSWI_Reason_ReportException:
708 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
712 state->Emulate = FALSE;
715 case ADP_Stopped_ApplicationExit:
717 state->Emulate = FALSE;
720 case ADP_Stopped_RunTimeError:
722 state->Emulate = FALSE;
725 case AngelSWI_Reason_Errno:
726 state->Reg[0] = OSptr->ErrorNo;
729 case AngelSWI_Reason_Open:
731 ARMul_ReadWord (state, addr),
732 ARMul_ReadWord (state, addr + 4));
735 case AngelSWI_Reason_Read:
737 ARMul_ReadWord (state, addr),
738 ARMul_ReadWord (state, addr + 4),
739 ARMul_ReadWord (state, addr + 8));
742 case AngelSWI_Reason_Write:
744 ARMul_ReadWord (state, addr),
745 ARMul_ReadWord (state, addr + 4),
746 ARMul_ReadWord (state, addr + 8));
749 case AngelSWI_Reason_IsTTY:
750 state->Reg[0] = sim_callback->isatty (sim_callback,
751 ARMul_ReadWord (state, addr));
752 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
755 case AngelSWI_Reason_Remove:
757 ARMul_ReadWord (state, addr));
759 case AngelSWI_Reason_Rename:
761 ARMul_ReadWord (state, addr),
762 ARMul_ReadWord (state, addr + 4));
769 /* The following SWIs are generated by the softvectorcode[]
770 installed by default by the simulator. */
771 case 0x91: /* Undefined Instruction. */
773 ARMword addr = state->RegBank[UNDEFBANK][14] - 4;
775 sim_callback->printf_filtered
776 (sim_callback, "sim: exception: Unhandled Instruction '0x%08x' at 0x%08x. Stopping.\n",
777 ARMul_ReadWord (state, addr), addr);
778 state->EndCondition = RDIError_SoftwareInterrupt;
779 state->Emulate = FALSE;
783 case 0x90: /* Reset. */
784 case 0x92: /* SWI. */
785 /* These two can be safely ignored. */
788 case 0x93: /* Prefetch Abort. */
789 case 0x94: /* Data Abort. */
790 case 0x95: /* Address Exception. */
791 case 0x96: /* IRQ. */
792 case 0x97: /* FIQ. */
793 case 0x98: /* Error. */
798 /* This can happen when a SWI is interrupted (eg receiving a
799 ctrl-C whilst processing SWIRead()). The SWI will complete
800 returning -1 in r0 to the caller. If GDB is then used to
801 resume the system call the reason code will now be -1. */
804 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
805 if (swi_mask & SWI_MASK_REDBOOT)
807 switch (state->Reg[0])
809 /* These numbers are defined in libgloss/syscall.h
810 but the simulator should not be dependend upon
811 libgloss being installed. */
813 state->Emulate = FALSE;
814 /* Copy exit code into r0. */
815 state->Reg[0] = state->Reg[1];
819 SWIopen (state, state->Reg[1], state->Reg[2]);
823 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
824 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
828 SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
832 SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
836 state->Reg[0] = sim_callback->lseek (sim_callback,
840 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
843 case 17: /* Utime. */
844 state->Reg[0] = (ARMword) sim_callback->time (sim_callback,
845 (long *) state->Reg[1]);
846 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
849 case 7: /* Unlink. */
850 case 8: /* Getpid. */
852 case 10: /* Fstat. */
854 case 12: /* Argvlen. */
856 case 14: /* ChDir. */
858 case 16: /* Chmod. */
860 sim_callback->printf_filtered
862 "sim: unhandled RedBoot syscall `%d' encountered - "
863 "returning ENOSYS\n",
866 OSptr->ErrorNo = cb_host_to_target_errno
867 (sim_callback, ENOSYS);
869 case 1001: /* Meminfo. */
871 ARMword totmem = state->Reg[1],
872 topmem = state->Reg[2];
873 ARMword stack = state->MemSize > 0
874 ? state->MemSize : ADDRUSERSTACK;
876 ARMul_WriteWord (state, totmem, stack);
878 ARMul_WriteWord (state, topmem, stack);
884 sim_callback->printf_filtered
886 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
899 if (SWI_vector_installed)
904 cpsr = ARMul_GetCPSR (state);
907 ARMul_SetSPSR (state, SVC32MODE, cpsr);
910 cpsr |= SVC32MODE | 0x80;
911 ARMul_SetCPSR (state, cpsr);
913 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
914 state->NextInstr = RESUME;
915 state->Reg[15] = state->pc = ARMSWIV;
920 sim_callback->printf_filtered
922 "sim: unknown SWI encountered - %x - ignoring\n",
934 /* The emulator calls this routine when an Exception occurs. The second
935 parameter is the address of the relevant exception vector. Returning
936 FALSE from this routine causes the trap to be taken, TRUE causes it to
937 be ignored (so set state->Emulate to FALSE!). */
940 ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
941 ARMword vector ATTRIBUTE_UNUSED,
942 ARMword pc ATTRIBUTE_UNUSED)