Linux: Use kill_lwp/tkill instead of kill when killing a process
[deliverable/binutils-gdb.git] / sim / arm / armos.c
CommitLineData
c906108c
SS
1/* armos.c -- ARMulator OS interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
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
3fd725ef 6 the Free Software Foundation; either version 3 of the License, or
c906108c
SS
7 (at your option) any later version.
8
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.
13
14 You should have received a copy of the GNU General Public License
51b318de 15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
16
17/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
7f53bc35
NC
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. */
c906108c
SS
23
24#include "config.h"
6d358e86 25#include "ansidecl.h"
c906108c
SS
26
27#include <time.h>
28#include <errno.h>
2be701a3 29#include <limits.h>
c906108c 30#include <string.h>
a4c9740c 31#include "targ-vals.h"
c906108c 32
a4c9740c
MM
33#ifndef TARGET_O_BINARY
34#define TARGET_O_BINARY 0
c906108c
SS
35#endif
36
c906108c 37#ifdef HAVE_UNISTD_H
d8512e6a 38#include <unistd.h> /* For SEEK_SET etc. */
c906108c
SS
39#endif
40
41#ifdef __riscos
dfcd3bfb 42extern int _fisatty (FILE *);
c906108c
SS
43#define isatty_(f) _fisatty(f)
44#else
45#ifdef __ZTC__
46#include <io.h>
47#define isatty_(f) isatty((f)->_file)
48#else
49#ifdef macintosh
50#include <ioctl.h>
51#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
52#else
53#define isatty_(f) isatty (fileno (f))
54#endif
55#endif
56#endif
57
58#include "armdefs.h"
59#include "armos.h"
f1129fb8
NC
60#include "armemu.h"
61
c906108c
SS
62#ifndef NOOS
63#ifndef VALIDATE
64/* #ifndef ASIM */
65#include "armfpe.h"
66/* #endif */
67#endif
68#endif
69
70/* For RDIError_BreakpointReached. */
71#include "dbg_rdi.h"
72
3c25f8c7 73#include "gdb/callback.h"
b3ba81f8
KS
74extern host_callback *sim_callback;
75
d8512e6a
NC
76extern unsigned ARMul_OSInit (ARMul_State *);
77extern void ARMul_OSExit (ARMul_State *);
78extern unsigned ARMul_OSHandleSWI (ARMul_State *, ARMword);
79extern unsigned ARMul_OSException (ARMul_State *, ARMword, ARMword);
80extern ARMword ARMul_OSLastErrorP (ARMul_State *);
81extern ARMword ARMul_Debug (ARMul_State *, ARMword, ARMword);
c906108c
SS
82
83#define BUFFERSIZE 4096
84#ifndef FOPEN_MAX
85#define FOPEN_MAX 64
86#endif
87#define UNIQUETEMPS 256
2be701a3
DJ
88#ifndef PATH_MAX
89#define PATH_MAX 1024
90#endif
c906108c 91
7f53bc35 92/* OS private Information. */
c906108c 93
dfcd3bfb
JM
94struct OSblock
95{
96 ARMword Time0;
97 ARMword ErrorP;
98 ARMword ErrorNo;
99 FILE *FileTable[FOPEN_MAX];
100 char FileFlags[FOPEN_MAX];
101 char *tempnames[UNIQUETEMPS];
102};
c906108c
SS
103
104#define NOOP 0
105#define BINARY 1
106#define READOP 2
107#define WRITEOP 4
108
109#ifdef macintosh
110#define FIXCRLF(t,c) ((t & BINARY) ? \
111 c : \
112 ((c == '\n' || c == '\r' ) ? (c ^ 7) : c) \
113 )
dfcd3bfb
JM
114#else
115#define FIXCRLF(t,c) c
c906108c
SS
116#endif
117
de4112fa
NC
118/* Bit mask of enabled SWI implementations. */
119unsigned int swi_mask = -1;
120
121
6d358e86 122static ARMword softvectorcode[] =
7f53bc35 123{
0f026fd0
NC
124 /* Installed instructions:
125 swi tidyexception + event;
126 mov lr, pc;
127 ldmia fp, {fp, pc};
128 swi generateexception + event. */
7f53bc35
NC
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 */
c906108c
SS
139};
140
7f53bc35 141/* Time for the Operating System to initialise itself. */
c906108c 142
dfcd3bfb
JM
143unsigned
144ARMul_OSInit (ARMul_State * state)
c906108c
SS
145{
146#ifndef NOOS
147#ifndef VALIDATE
dfcd3bfb
JM
148 ARMword instr, i, j;
149 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
150
151 if (state->OSptr == NULL)
152 {
153 state->OSptr = (unsigned char *) malloc (sizeof (struct OSblock));
154 if (state->OSptr == NULL)
155 {
156 perror ("OS Memory");
157 exit (15);
158 }
c906108c 159 }
7f53bc35 160
dfcd3bfb
JM
161 OSptr = (struct OSblock *) state->OSptr;
162 OSptr->ErrorP = 0;
d8512e6a
NC
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 */
7f53bc35 169
dfcd3bfb 170 for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
ace4f296
NC
171 /* Write hardware vectors. */
172 ARMul_WriteWord (state, i, instr);
7f53bc35 173
88694af3
NC
174 SWI_vector_installed = 0;
175
dfcd3bfb
JM
176 for (i = ARMul_ResetV; i <= ARMFIQV + 4; i += 4)
177 {
178 ARMul_WriteWord (state, ADDRSOFTVECTORS + i, SOFTVECTORCODE + i * 4);
179 ARMul_WriteWord (state, ADDRSOFHANDLERS + 2 * i + 4L,
180 SOFTVECTORCODE + sizeof (softvectorcode) - 4L);
c906108c 181 }
7f53bc35 182
dfcd3bfb
JM
183 for (i = 0; i < sizeof (softvectorcode); i += 4)
184 ARMul_WriteWord (state, SOFTVECTORCODE + i, softvectorcode[i / 4]);
7f53bc35 185
dfcd3bfb
JM
186 for (i = 0; i < FOPEN_MAX; i++)
187 OSptr->FileTable[i] = NULL;
7f53bc35 188
dfcd3bfb
JM
189 for (i = 0; i < UNIQUETEMPS; i++)
190 OSptr->tempnames[i] = NULL;
7f53bc35 191
dfcd3bfb 192 ARMul_ConsolePrint (state, ", Demon 1.01");
c906108c
SS
193
194/* #ifndef ASIM */
195
d8512e6a
NC
196 /* Install FPE. */
197 for (i = 0; i < fpesize; i += 4)
198 /* Copy the code. */
dfcd3bfb 199 ARMul_WriteWord (state, FPESTART + i, fpecode[i >> 2]);
7f53bc35 200
0f026fd0 201 /* Scan backwards from the end of the code. */
dfcd3bfb 202 for (i = FPESTART + fpesize;; i -= 4)
d8512e6a 203 {
0f026fd0
NC
204 /* When we reach the marker value, break out of
205 the loop, leaving i pointing at the maker. */
dfcd3bfb
JM
206 if ((j = ARMul_ReadWord (state, i)) == 0xffffffff)
207 break;
0f026fd0
NC
208
209 /* If necessary, reverse the error strings. */
dfcd3bfb 210 if (state->bigendSig && j < 0x80000000)
d8512e6a
NC
211 {
212 /* It's part of the string so swap it. */
dfcd3bfb
JM
213 j = ((j >> 0x18) & 0x000000ff) |
214 ((j >> 0x08) & 0x0000ff00) |
215 ((j << 0x08) & 0x00ff0000) | ((j << 0x18) & 0xff000000);
216 ARMul_WriteWord (state, i, j);
217 }
c906108c 218 }
7f53bc35 219
d8512e6a 220 /* Copy old illegal instr vector. */
0f026fd0 221 ARMul_WriteWord (state, FPEOLDVECT, ARMul_ReadWord (state, ARMUndefinedInstrV));
d8512e6a 222 /* Install new vector. */
0f026fd0 223 ARMul_WriteWord (state, ARMUndefinedInstrV, FPENEWVECT (ARMul_ReadWord (state, i - 4)));
dfcd3bfb 224 ARMul_ConsolePrint (state, ", FPE");
c906108c 225
6d358e86 226/* #endif ASIM */
c906108c
SS
227#endif /* VALIDATE */
228#endif /* NOOS */
229
de4112fa
NC
230 /* Intel do not want DEMON SWI support. */
231 if (state->is_XScale)
232 swi_mask = SWI_MASK_ANGEL;
10b57fcb
NC
233
234 return TRUE;
c906108c
SS
235}
236
dfcd3bfb
JM
237void
238ARMul_OSExit (ARMul_State * state)
c906108c 239{
dfcd3bfb 240 free ((char *) state->OSptr);
c906108c
SS
241}
242
243
7f53bc35 244/* Return the last Operating System Error. */
c906108c 245
dfcd3bfb 246ARMword ARMul_OSLastErrorP (ARMul_State * state)
c906108c 247{
dfcd3bfb 248 return ((struct OSblock *) state->OSptr)->ErrorP;
c906108c
SS
249}
250
7f53bc35
NC
251static int translate_open_mode[] =
252{
a4c9740c
MM
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" */
c906108c
SS
265};
266
dfcd3bfb
JM
267static void
268SWIWrite0 (ARMul_State * state, ARMword addr)
c906108c
SS
269{
270 ARMword temp;
dfcd3bfb 271 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c 272
917bca4f 273 while ((temp = ARMul_SafeReadByte (state, addr++)) != 0)
0d9fd8f1
NC
274 {
275 char buffer = temp;
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);
280 }
c906108c 281
b3ba81f8 282 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
283}
284
dfcd3bfb
JM
285static void
286WriteCommandLineTo (ARMul_State * state, ARMword addr)
c906108c
SS
287{
288 ARMword temp;
289 char *cptr = state->CommandLine;
7f53bc35 290
c906108c
SS
291 if (cptr == NULL)
292 cptr = "\0";
dfcd3bfb
JM
293 do
294 {
295 temp = (ARMword) * cptr++;
917bca4f 296 ARMul_SafeWriteByte (state, addr++, temp);
dfcd3bfb
JM
297 }
298 while (temp != 0);
c906108c
SS
299}
300
2be701a3
DJ
301static int
302ReadFileName (ARMul_State * state, char *buf, ARMword src, size_t n)
303{
304 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
305 char *p = buf;
306
307 while (n--)
308 if ((*p++ = ARMul_SafeReadByte (state, src++)) == '\0')
309 return 0;
310 OSptr->ErrorNo = cb_host_to_target_errno (sim_callback, ENAMETOOLONG);
311 state->Reg[0] = -1;
312 return -1;
313}
314
dfcd3bfb
JM
315static void
316SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
c906108c 317{
dfcd3bfb 318 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
2be701a3 319 char buf[PATH_MAX];
c906108c 320 int flags;
c906108c 321
2be701a3
DJ
322 if (ReadFileName (state, buf, name, sizeof buf) == -1)
323 return;
c906108c 324
7f53bc35 325 /* Now we need to decode the Demon open mode. */
c906108c
SS
326 flags = translate_open_mode[SWIflags];
327
7f53bc35 328 /* Filename ":tt" is special: it denotes stdin/out. */
2be701a3 329 if (strcmp (buf, ":tt") == 0)
c906108c 330 {
a4c9740c 331 if (flags == TARGET_O_RDONLY) /* opening tty "r" */
dfcd3bfb
JM
332 state->Reg[0] = 0; /* stdin */
333 else
334 state->Reg[0] = 1; /* stdout */
c906108c
SS
335 }
336 else
337 {
2be701a3 338 state->Reg[0] = sim_callback->open (sim_callback, buf, flags);
b3ba81f8 339 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
340 }
341}
342
dfcd3bfb
JM
343static void
344SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 345{
dfcd3bfb 346 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
347 int res;
348 int i;
349 char *local = malloc (len);
350
c2d11a7d
JM
351 if (local == NULL)
352 {
d8512e6a
NC
353 sim_callback->printf_filtered
354 (sim_callback,
355 "sim: Unable to read 0x%ulx bytes - out of memory\n",
356 len);
c2d11a7d
JM
357 return;
358 }
dfcd3bfb 359
b3ba81f8 360 res = sim_callback->read (sim_callback, f, local, len);
c906108c 361 if (res > 0)
dfcd3bfb 362 for (i = 0; i < res; i++)
917bca4f 363 ARMul_SafeWriteByte (state, ptr + i, local[i]);
7f53bc35 364
c906108c
SS
365 free (local);
366 state->Reg[0] = res == -1 ? -1 : len - res;
b3ba81f8 367 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
368}
369
dfcd3bfb
JM
370static void
371SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
c906108c 372{
dfcd3bfb 373 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c 374 int res;
6d358e86 375 ARMword i;
c906108c
SS
376 char *local = malloc (len);
377
c2d11a7d 378 if (local == NULL)
c906108c 379 {
d8512e6a
NC
380 sim_callback->printf_filtered
381 (sim_callback,
382 "sim: Unable to write 0x%lx bytes - out of memory\n",
383 (long) len);
c2d11a7d 384 return;
c906108c 385 }
dfcd3bfb
JM
386
387 for (i = 0; i < len; i++)
917bca4f 388 local[i] = ARMul_SafeReadByte (state, ptr + i);
c2d11a7d 389
b3ba81f8 390 res = sim_callback->write (sim_callback, f, local, len);
c906108c
SS
391 state->Reg[0] = res == -1 ? -1 : len - res;
392 free (local);
7f53bc35 393
b3ba81f8 394 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
395}
396
dfcd3bfb
JM
397static void
398SWIflen (ARMul_State * state, ARMword fh)
c906108c 399{
dfcd3bfb 400 struct OSblock *OSptr = (struct OSblock *) state->OSptr;
c906108c
SS
401 ARMword addr;
402
e1c9b6f1 403 if (fh > FOPEN_MAX)
c906108c
SS
404 {
405 OSptr->ErrorNo = EBADF;
406 state->Reg[0] = -1L;
407 return;
408 }
409
b3ba81f8 410 addr = sim_callback->lseek (sim_callback, fh, 0, SEEK_CUR);
6d358e86 411
b3ba81f8
KS
412 state->Reg[0] = sim_callback->lseek (sim_callback, fh, 0L, SEEK_END);
413 (void) sim_callback->lseek (sim_callback, fh, addr, SEEK_SET);
c906108c 414
b3ba81f8 415 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
c906108c
SS
416}
417
2be701a3
DJ
418static void
419SWIremove (ARMul_State * state, ARMword path)
420{
421 char buf[PATH_MAX];
422
423 if (ReadFileName (state, buf, path, sizeof buf) != -1)
424 {
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);
428 }
429}
430
431static void
432SWIrename (ARMul_State * state, ARMword old, ARMword new)
433{
434 char oldbuf[PATH_MAX], newbuf[PATH_MAX];
435
436 if (ReadFileName (state, oldbuf, old, sizeof oldbuf) != -1
437 && ReadFileName (state, newbuf, new, sizeof newbuf) != -1)
438 {
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);
442 }
443}
444
7f53bc35
NC
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). */
c906108c 447
dfcd3bfb
JM
448unsigned
449ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
c906108c 450{
1e5d4e46 451 struct OSblock * OSptr = (struct OSblock *) state->OSptr;
de4112fa
NC
452 int unhandled = FALSE;
453
c906108c
SS
454 switch (number)
455 {
456 case SWI_Read:
de4112fa
NC
457 if (swi_mask & SWI_MASK_DEMON)
458 SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
459 else
460 unhandled = TRUE;
1e5d4e46 461 break;
c906108c
SS
462
463 case SWI_Write:
de4112fa
NC
464 if (swi_mask & SWI_MASK_DEMON)
465 SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
466 else
467 unhandled = TRUE;
1e5d4e46 468 break;
c906108c
SS
469
470 case SWI_Open:
de4112fa
NC
471 if (swi_mask & SWI_MASK_DEMON)
472 SWIopen (state, state->Reg[0], state->Reg[1]);
473 else
474 unhandled = TRUE;
1e5d4e46 475 break;
c906108c 476
dfcd3bfb 477 case SWI_Clock:
de4112fa
NC
478 if (swi_mask & SWI_MASK_DEMON)
479 {
480 /* Return number of centi-seconds. */
481 state->Reg[0] =
c906108c 482#ifdef CLOCKS_PER_SEC
de4112fa
NC
483 (CLOCKS_PER_SEC >= 100)
484 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
485 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 486#else
de4112fa
NC
487 /* Presume unix... clock() returns microseconds. */
488 (ARMword) (clock () / 10000);
c906108c 489#endif
de4112fa
NC
490 OSptr->ErrorNo = errno;
491 }
492 else
493 unhandled = TRUE;
1e5d4e46 494 break;
dfcd3bfb
JM
495
496 case SWI_Time:
de4112fa
NC
497 if (swi_mask & SWI_MASK_DEMON)
498 {
499 state->Reg[0] = (ARMword) sim_callback->time (sim_callback, NULL);
500 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
501 }
502 else
503 unhandled = TRUE;
1e5d4e46 504 break;
dfcd3bfb 505
c906108c 506 case SWI_Close:
de4112fa
NC
507 if (swi_mask & SWI_MASK_DEMON)
508 {
509 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[0]);
510 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
511 }
512 else
513 unhandled = TRUE;
1e5d4e46 514 break;
c906108c 515
dfcd3bfb 516 case SWI_Flen:
de4112fa
NC
517 if (swi_mask & SWI_MASK_DEMON)
518 SWIflen (state, state->Reg[0]);
519 else
520 unhandled = TRUE;
1e5d4e46 521 break;
c906108c
SS
522
523 case SWI_Exit:
de4112fa
NC
524 if (swi_mask & SWI_MASK_DEMON)
525 state->Emulate = FALSE;
526 else
527 unhandled = TRUE;
1e5d4e46 528 break;
c906108c
SS
529
530 case SWI_Seek:
de4112fa
NC
531 if (swi_mask & SWI_MASK_DEMON)
532 {
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);
536 }
537 else
538 unhandled = TRUE;
1e5d4e46 539 break;
c906108c 540
dfcd3bfb 541 case SWI_WriteC:
de4112fa
NC
542 if (swi_mask & SWI_MASK_DEMON)
543 {
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);
547 }
548 else
549 unhandled = TRUE;
1e5d4e46 550 break;
c906108c 551
dfcd3bfb 552 case SWI_Write0:
de4112fa
NC
553 if (swi_mask & SWI_MASK_DEMON)
554 SWIWrite0 (state, state->Reg[0]);
555 else
556 unhandled = TRUE;
1e5d4e46 557 break;
c906108c 558
dfcd3bfb 559 case SWI_GetErrno:
de4112fa
NC
560 if (swi_mask & SWI_MASK_DEMON)
561 state->Reg[0] = OSptr->ErrorNo;
562 else
563 unhandled = TRUE;
1e5d4e46 564 break;
c906108c 565
dfcd3bfb 566 case SWI_GetEnv:
de4112fa
NC
567 if (swi_mask & SWI_MASK_DEMON)
568 {
569 state->Reg[0] = ADDRCMDLINE;
570 if (state->MemSize)
571 state->Reg[1] = state->MemSize;
572 else
573 state->Reg[1] = ADDRUSERSTACK;
c906108c 574
de4112fa
NC
575 WriteCommandLineTo (state, state->Reg[0]);
576 }
577 else
578 unhandled = TRUE;
1e5d4e46 579 break;
7f53bc35 580
f1129fb8
NC
581 case SWI_Breakpoint:
582 state->EndCondition = RDIError_BreakpointReached;
583 state->Emulate = FALSE;
1e5d4e46 584 break;
c906108c 585
2be701a3
DJ
586 case SWI_Remove:
587 if (swi_mask & SWI_MASK_DEMON)
588 SWIremove (state, state->Reg[0]);
589 else
590 unhandled = TRUE;
591 break;
592
593 case SWI_Rename:
594 if (swi_mask & SWI_MASK_DEMON)
595 SWIrename (state, state->Reg[0], state->Reg[1]);
596 else
597 unhandled = TRUE;
598 break;
599
600 case SWI_IsTTY:
601 if (swi_mask & SWI_MASK_DEMON)
602 {
603 state->Reg[0] = sim_callback->isatty (sim_callback, state->Reg[0]);
604 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
605 }
606 else
607 unhandled = TRUE;
608 break;
609
7f53bc35 610 /* Handle Angel SWIs as well as Demon ones. */
c906108c
SS
611 case AngelSWI_ARM:
612 case AngelSWI_Thumb:
de4112fa 613 if (swi_mask & SWI_MASK_ANGEL)
c906108c 614 {
de4112fa
NC
615 ARMword addr;
616 ARMword temp;
617
618 /* R1 is almost always a parameter block. */
619 addr = state->Reg[1];
620 /* R0 is a reason code. */
621 switch (state->Reg[0])
622 {
c7a7b500
NC
623 case -1:
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. */
2ec3c90a 628 return TRUE;
c7a7b500 629
de4112fa
NC
630 /* Unimplemented reason codes. */
631 case AngelSWI_Reason_ReadC:
de4112fa 632 case AngelSWI_Reason_TmpNam:
de4112fa
NC
633 case AngelSWI_Reason_System:
634 case AngelSWI_Reason_EnterSVC:
635 default:
636 state->Emulate = FALSE;
637 return FALSE;
638
639 case AngelSWI_Reason_Clock:
640 /* Return number of centi-seconds. */
641 state->Reg[0] =
c906108c 642#ifdef CLOCKS_PER_SEC
de4112fa
NC
643 (CLOCKS_PER_SEC >= 100)
644 ? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
645 : (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
c906108c 646#else
de4112fa
NC
647 /* Presume unix... clock() returns microseconds. */
648 (ARMword) (clock () / 10000);
c906108c 649#endif
de4112fa
NC
650 OSptr->ErrorNo = errno;
651 break;
652
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);
656 break;
657
658 case AngelSWI_Reason_WriteC:
659 {
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);
663 break;
664 }
665
666 case AngelSWI_Reason_Write0:
667 SWIWrite0 (state, addr);
668 break;
669
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);
673 break;
674
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),
678 SEEK_SET);
679 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
680 break;
681
682 case AngelSWI_Reason_FLen:
683 SWIflen (state, ARMul_ReadWord (state, addr));
684 break;
685
686 case AngelSWI_Reason_GetCmdLine:
687 WriteCommandLineTo (state, ARMul_ReadWord (state, addr));
688 break;
689
690 case AngelSWI_Reason_HeapInfo:
691 /* R1 is a pointer to a pointer. */
692 addr = ARMul_ReadWord (state, addr);
693
694 /* Pick up the right memory limit. */
695 if (state->MemSize)
696 temp = state->MemSize;
697 else
698 temp = ADDRUSERSTACK;
699
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. */
704 break;
705
706 case AngelSWI_Reason_ReportException:
707 if (state->Reg[1] == ADP_Stopped_ApplicationExit)
708 state->Reg[0] = 0;
709 else
710 state->Reg[0] = -1;
711 state->Emulate = FALSE;
712 break;
713
714 case ADP_Stopped_ApplicationExit:
715 state->Reg[0] = 0;
716 state->Emulate = FALSE;
717 break;
718
719 case ADP_Stopped_RunTimeError:
720 state->Reg[0] = -1;
721 state->Emulate = FALSE;
722 break;
723
724 case AngelSWI_Reason_Errno:
725 state->Reg[0] = OSptr->ErrorNo;
726 break;
727
728 case AngelSWI_Reason_Open:
729 SWIopen (state,
730 ARMul_ReadWord (state, addr),
731 ARMul_ReadWord (state, addr + 4));
732 break;
733
734 case AngelSWI_Reason_Read:
735 SWIread (state,
736 ARMul_ReadWord (state, addr),
737 ARMul_ReadWord (state, addr + 4),
738 ARMul_ReadWord (state, addr + 8));
739 break;
740
741 case AngelSWI_Reason_Write:
742 SWIwrite (state,
743 ARMul_ReadWord (state, addr),
744 ARMul_ReadWord (state, addr + 4),
745 ARMul_ReadWord (state, addr + 8));
746 break;
2be701a3
DJ
747
748 case AngelSWI_Reason_IsTTY:
4b1d9c58
PB
749 state->Reg[0] = sim_callback->isatty (sim_callback,
750 ARMul_ReadWord (state, addr));
2be701a3
DJ
751 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
752 break;
753
754 case AngelSWI_Reason_Remove:
755 SWIremove (state,
756 ARMul_ReadWord (state, addr));
757
758 case AngelSWI_Reason_Rename:
759 SWIrename (state,
760 ARMul_ReadWord (state, addr),
761 ARMul_ReadWord (state, addr + 4));
de4112fa 762 }
c906108c 763 }
de4112fa
NC
764 else
765 unhandled = TRUE;
766 break;
c906108c 767
0f026fd0
NC
768 /* The following SWIs are generated by the softvectorcode[]
769 installed by default by the simulator. */
770 case 0x91: /* Undefined Instruction. */
771 {
772 ARMword addr = state->RegBank[UNDEFBANK][14] - 4;
773
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;
779 return FALSE;
780 }
781
782 case 0x90: /* Reset. */
783 case 0x92: /* SWI. */
784 /* These two can be safely ignored. */
785 break;
786
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. */
793 unhandled = TRUE;
1e5d4e46 794 break;
0f026fd0 795
c7a7b500
NC
796 case -1:
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. */
2ec3c90a 801 return TRUE;
c7a7b500 802
d8512e6a 803 case 0x180001: /* RedBoot's Syscall SWI in ARM mode. */
de4112fa 804 if (swi_mask & SWI_MASK_REDBOOT)
d8512e6a 805 {
de4112fa
NC
806 switch (state->Reg[0])
807 {
808 /* These numbers are defined in libgloss/syscall.h
809 but the simulator should not be dependend upon
810 libgloss being installed. */
811 case 1: /* Exit. */
812 state->Emulate = FALSE;
813 /* Copy exit code into r0. */
814 state->Reg[0] = state->Reg[1];
815 break;
816
817 case 2: /* Open. */
818 SWIopen (state, state->Reg[1], state->Reg[2]);
819 break;
820
821 case 3: /* Close. */
822 state->Reg[0] = sim_callback->close (sim_callback, state->Reg[1]);
823 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
824 break;
825
826 case 4: /* Read. */
827 SWIread (state, state->Reg[1], state->Reg[2], state->Reg[3]);
828 break;
829
830 case 5: /* Write. */
831 SWIwrite (state, state->Reg[1], state->Reg[2], state->Reg[3]);
832 break;
833
834 case 6: /* Lseek. */
835 state->Reg[0] = sim_callback->lseek (sim_callback,
836 state->Reg[1],
837 state->Reg[2],
838 state->Reg[3]);
839 OSptr->ErrorNo = sim_callback->get_errno (sim_callback);
840 break;
841
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);
846 break;
847
848 case 7: /* Unlink. */
849 case 8: /* Getpid. */
850 case 9: /* Kill. */
851 case 10: /* Fstat. */
852 case 11: /* Sbrk. */
853 case 12: /* Argvlen. */
854 case 13: /* Argv. */
855 case 14: /* ChDir. */
856 case 15: /* Stat. */
857 case 16: /* Chmod. */
858 case 18: /* Time. */
859 sim_callback->printf_filtered
860 (sim_callback,
eeea4660
DJ
861 "sim: unhandled RedBoot syscall `%d' encountered - "
862 "returning ENOSYS\n",
de4112fa 863 state->Reg[0]);
eeea4660
DJ
864 state->Reg[0] = -1;
865 OSptr->ErrorNo = cb_host_to_target_errno
866 (sim_callback, ENOSYS);
867 break;
868 case 1001: /* Meminfo. */
869 {
870 ARMword totmem = state->Reg[1],
871 topmem = state->Reg[2];
872 ARMword stack = state->MemSize > 0
873 ? state->MemSize : ADDRUSERSTACK;
874 if (totmem != 0)
875 ARMul_WriteWord (state, totmem, stack);
876 if (topmem != 0)
877 ARMul_WriteWord (state, topmem, stack);
878 state->Reg[0] = 0;
879 break;
880 }
de4112fa
NC
881
882 default:
883 sim_callback->printf_filtered
884 (sim_callback,
885 "sim: unknown RedBoot syscall '%d' encountered - ignoring\n",
886 state->Reg[0]);
887 return FALSE;
888 }
889 break;
d8512e6a 890 }
d8512e6a 891
dfcd3bfb 892 default:
de4112fa
NC
893 unhandled = TRUE;
894 }
895
896 if (unhandled)
897 {
898 if (SWI_vector_installed)
1e5d4e46
NC
899 {
900 ARMword cpsr;
901 ARMword i_size;
94ab9d7b 902
1e5d4e46
NC
903 cpsr = ARMul_GetCPSR (state);
904 i_size = INSN_SIZE;
94ab9d7b 905
1e5d4e46 906 ARMul_SetSPSR (state, SVC32MODE, cpsr);
94ab9d7b 907
1e5d4e46
NC
908 cpsr &= ~0xbf;
909 cpsr |= SVC32MODE | 0x80;
910 ARMul_SetCPSR (state, cpsr);
94ab9d7b 911
1e5d4e46
NC
912 state->RegBank[SVCBANK][14] = state->Reg[14] = state->Reg[15] - i_size;
913 state->NextInstr = RESUME;
914 state->Reg[15] = state->pc = ARMSWIV;
915 FLUSHPIPE;
916 }
917 else
918 {
d8512e6a
NC
919 sim_callback->printf_filtered
920 (sim_callback,
921 "sim: unknown SWI encountered - %x - ignoring\n",
922 number);
1e5d4e46
NC
923 return FALSE;
924 }
c906108c 925 }
1e5d4e46 926
1e5d4e46 927 return TRUE;
c906108c
SS
928}
929
c906108c
SS
930#ifndef NOOS
931#ifndef ASIM
932
f1129fb8
NC
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!). */
c906108c 937
dfcd3bfb 938unsigned
7f53bc35 939ARMul_OSException (ARMul_State * state ATTRIBUTE_UNUSED,
f1129fb8
NC
940 ARMword vector ATTRIBUTE_UNUSED,
941 ARMword pc ATTRIBUTE_UNUSED)
942{
917bca4f 943 return FALSE;
c906108c
SS
944}
945
946#endif
c906108c 947#endif /* NOOS */
This page took 0.651908 seconds and 4 git commands to generate.