sim: switch config.h usage to defs.h
[deliverable/binutils-gdb.git] / sim / mips / interp.c
CommitLineData
c906108c
SS
1/*> interp.c <*/
2/* Simulator for the MIPS architecture.
3
4 This file is part of the MIPS sim
5
6 THIS SOFTWARE IS NOT COPYRIGHTED
7
8 Cygnus offers the following for use in the public domain. Cygnus
9 makes no warranty with regard to the software or it's performance
10 and the user accepts the software "AS IS" with all faults.
11
12 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
c906108c
SS
16NOTEs:
17
18The IDT monitor (found on the VR4300 board), seems to lie about
19register contents. It seems to treat the registers as sign-extended
2032-bit values. This cause *REAL* problems when single-stepping 64-bit
21code on the hardware.
22
23*/
24
6df01ab8
MF
25/* This must come before any other includes. */
26#include "defs.h"
27
c906108c
SS
28#include "bfd.h"
29#include "sim-main.h"
30#include "sim-utils.h"
31#include "sim-options.h"
32#include "sim-assert.h"
33#include "sim-hw.h"
34
35#include "itable.h"
36
c906108c
SS
37#include <stdio.h>
38#include <stdarg.h>
39#include <ansidecl.h>
40#include <ctype.h>
41#include <limits.h>
42#include <math.h>
c906108c 43#include <stdlib.h>
c906108c 44#include <string.h>
c906108c
SS
45
46#include "getopt.h"
47#include "libiberty.h"
48#include "bfd.h"
b36d953b 49#include "elf-bfd.h"
df68e12b
MF
50#include "sim/callback.h" /* GDB simulator callback interface */
51#include "sim/sim.h" /* GDB simulator interface */
5c6f091a 52#include "sim-syscall.h" /* Simulator system call support */
c906108c 53
bdca5ee4
TT
54char* pr_addr (SIM_ADDR addr);
55char* pr_uword64 (uword64 addr);
c906108c
SS
56
57
58/* Within interp.c we refer to the sim_state and sim_cpu directly. */
59#define CPU cpu
60#define SD sd
61
62
63/* The following reserved instruction value is used when a simulator
64 trap is required. NOTE: Care must be taken, since this value may be
65 used in later revisions of the MIPS ISA. */
66
8e394ffc 67#define RSVD_INSTRUCTION (0x00000039)
c906108c
SS
68#define RSVD_INSTRUCTION_MASK (0xFC00003F)
69
70#define RSVD_INSTRUCTION_ARG_SHIFT 6
71#define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
72
73
74/* Bits in the Debug register */
75#define Debug_DBD 0x80000000 /* Debug Branch Delay */
76#define Debug_DM 0x40000000 /* Debug Mode */
77#define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
78
79/*---------------------------------------------------------------------------*/
80/*-- GDB simulator interface ------------------------------------------------*/
81/*---------------------------------------------------------------------------*/
82
bdca5ee4 83static void ColdReset (SIM_DESC sd);
c906108c
SS
84
85/*---------------------------------------------------------------------------*/
86
87
88
89#define DELAYSLOT() {\
90 if (STATE & simDELAYSLOT)\
91 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
92 STATE |= simDELAYSLOT;\
93 }
94
95#define JALDELAYSLOT() {\
96 DELAYSLOT ();\
97 STATE |= simJALDELAYSLOT;\
98 }
99
100#define NULLIFY() {\
101 STATE &= ~simDELAYSLOT;\
102 STATE |= simSKIPNEXT;\
103 }
104
105#define CANCELDELAYSLOT() {\
106 DSSTATE = 0;\
107 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
108 }
109
110#define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
111#define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
112
adf40b2e
JM
113/* Note that the monitor code essentially assumes this layout of memory.
114 If you change these, change the monitor code, too. */
14fb6c5a
TS
115/* FIXME Currently addresses are truncated to 32-bits, see
116 mips/sim-main.c:address_translation(). If that changes, then these
117 values will need to be extended, and tested for more carefully. */
c906108c
SS
118#define K0BASE (0x80000000)
119#define K0SIZE (0x20000000)
120#define K1BASE (0xA0000000)
121#define K1SIZE (0x20000000)
adf40b2e
JM
122
123/* Simple run-time monitor support.
124
125 We emulate the monitor by placing magic reserved instructions at
126 the monitor's entry points; when we hit these instructions, instead
127 of raising an exception (as we would normally), we look at the
128 instruction and perform the appropriate monitory operation.
129
130 `*_monitor_base' are the physical addresses at which the corresponding
131 monitor vectors are located. `0' means none. By default,
132 install all three.
133 The RSVD_INSTRUCTION... macros specify the magic instructions we
134 use at the monitor entry points. */
135static int firmware_option_p = 0;
136static SIM_ADDR idt_monitor_base = 0xBFC00000;
137static SIM_ADDR pmon_monitor_base = 0xBFC00500;
138static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
139
140static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
141
c8847145 142#define MEM_SIZE (8 << 20) /* 8 MBytes */
c906108c
SS
143
144
29bc024d 145#if WITH_TRACE_ANY_P
c906108c
SS
146static char *tracefile = "trace.din"; /* default filename for trace log */
147FILE *tracefh = NULL;
bdca5ee4 148static void open_trace (SIM_DESC sd);
29bc024d
MF
149#else
150#define open_trace(sd)
151#endif
c906108c
SS
152
153static const char * get_insn_name (sim_cpu *, int);
154
155/* simulation target board. NULL=canonical */
156static char* board = NULL;
157
158
159static DECLARE_OPTION_HANDLER (mips_option_handler);
160
161enum {
162 OPTION_DINERO_TRACE = OPTION_START,
163 OPTION_DINERO_FILE,
adf40b2e 164 OPTION_FIRMWARE,
2525df03 165 OPTION_INFO_MEMORY,
c906108c
SS
166 OPTION_BOARD
167};
168
2525df03 169static int display_mem_info = 0;
c906108c
SS
170
171static SIM_RC
8ac57fbd
MF
172mips_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
173 int is_command)
c906108c
SS
174{
175 int cpu_nr;
176 switch (opt)
177 {
178 case OPTION_DINERO_TRACE: /* ??? */
29bc024d 179#if WITH_TRACE_ANY_P
c906108c
SS
180 /* Eventually the simTRACE flag could be treated as a toggle, to
181 allow external control of the program points being traced
182 (i.e. only from main onwards, excluding the run-time setup,
183 etc.). */
184 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
185 {
186 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
187 if (arg == NULL)
188 STATE |= simTRACE;
189 else if (strcmp (arg, "yes") == 0)
190 STATE |= simTRACE;
191 else if (strcmp (arg, "no") == 0)
192 STATE &= ~simTRACE;
193 else if (strcmp (arg, "on") == 0)
194 STATE |= simTRACE;
195 else if (strcmp (arg, "off") == 0)
196 STATE &= ~simTRACE;
197 else
198 {
199 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
200 return SIM_RC_FAIL;
201 }
202 }
203 return SIM_RC_OK;
29bc024d 204#else /* !WITH_TRACE_ANY_P */
c906108c
SS
205 fprintf(stderr,"\
206Simulator constructed without dinero tracing support (for performance).\n\
29bc024d 207Re-compile simulator with \"-DWITH_TRACE_ANY_P\" to enable this option.\n");
c906108c 208 return SIM_RC_FAIL;
29bc024d 209#endif /* !WITH_TRACE_ANY_P */
c906108c
SS
210
211 case OPTION_DINERO_FILE:
29bc024d 212#if WITH_TRACE_ANY_P
c906108c
SS
213 if (optarg != NULL) {
214 char *tmp;
215 tmp = (char *)malloc(strlen(optarg) + 1);
216 if (tmp == NULL)
217 {
218 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
219 return SIM_RC_FAIL;
220 }
221 else {
222 strcpy(tmp,optarg);
223 tracefile = tmp;
224 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
225 }
226 }
29bc024d 227#endif /* WITH_TRACE_ANY_P */
c906108c
SS
228 return SIM_RC_OK;
229
adf40b2e
JM
230 case OPTION_FIRMWARE:
231 return sim_firmware_command (sd, arg);
232
c906108c
SS
233 case OPTION_BOARD:
234 {
235 if (arg)
236 {
237 board = zalloc(strlen(arg) + 1);
238 strcpy(board, arg);
239 }
240 return SIM_RC_OK;
241 }
2525df03
NC
242
243 case OPTION_INFO_MEMORY:
244 display_mem_info = 1;
245 break;
c906108c
SS
246 }
247
248 return SIM_RC_OK;
249}
250
251
252static const OPTION mips_options[] =
253{
254 { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
255 '\0', "on|off", "Enable dinero tracing",
256 mips_option_handler },
257 { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
258 '\0', "FILE", "Write dinero trace to FILE",
259 mips_option_handler },
adf40b2e
JM
260 { {"firmware", required_argument, NULL, OPTION_FIRMWARE},
261 '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
262 mips_option_handler },
c906108c
SS
263 { {"board", required_argument, NULL, OPTION_BOARD},
264 '\0', "none" /* rely on compile-time string concatenation for other options */
265
266#define BOARD_JMR3904 "jmr3904"
267 "|" BOARD_JMR3904
268#define BOARD_JMR3904_PAL "jmr3904pal"
269 "|" BOARD_JMR3904_PAL
270#define BOARD_JMR3904_DEBUG "jmr3904debug"
271 "|" BOARD_JMR3904_DEBUG
43e526b9
JM
272#define BOARD_BSP "bsp"
273 "|" BOARD_BSP
c906108c
SS
274
275 , "Customize simulation for a particular board.", mips_option_handler },
276
2525df03
NC
277 /* These next two options have the same names as ones found in the
278 memory_options[] array in common/sim-memopt.c. This is because
279 the intention is to provide an alternative handler for those two
280 options. We need an alternative handler because the memory
281 regions are not set up until after the command line arguments
282 have been parsed, and so we cannot display the memory info whilst
283 processing the command line. There is a hack in sim_open to
284 remove these handlers when we want the real --memory-info option
285 to work. */
286 { { "info-memory", no_argument, NULL, OPTION_INFO_MEMORY },
287 '\0', NULL, "List configured memory regions", mips_option_handler },
288 { { "memory-info", no_argument, NULL, OPTION_INFO_MEMORY },
289 '\0', NULL, NULL, mips_option_handler },
290
c906108c
SS
291 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
292};
293
294
295int interrupt_pending;
296
297void
298interrupt_event (SIM_DESC sd, void *data)
299{
300 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
034685f9 301 address_word cia = CPU_PC_GET (cpu);
c906108c
SS
302 if (SR & status_IE)
303 {
304 interrupt_pending = 0;
305 SignalExceptionInterrupt (1); /* interrupt "1" */
306 }
307 else if (!interrupt_pending)
308 sim_events_schedule (sd, 1, interrupt_event, data);
309}
310
311
312/*---------------------------------------------------------------------------*/
313/*-- Device registration hook -----------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315static void device_init(SIM_DESC sd) {
316#ifdef DEVICE_INIT
317 extern void register_devices(SIM_DESC);
318 register_devices(sd);
319#endif
320}
321
322/*---------------------------------------------------------------------------*/
323/*-- GDB simulator interface ------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
7bebb329
MF
326static sim_cia
327mips_pc_get (sim_cpu *cpu)
328{
329 return PC;
330}
331
332static void
333mips_pc_set (sim_cpu *cpu, sim_cia pc)
334{
335 PC = pc;
336}
337
e1211e55
MF
338static int mips_reg_fetch (SIM_CPU *, int, unsigned char *, int);
339static int mips_reg_store (SIM_CPU *, int, unsigned char *, int);
340
c906108c 341SIM_DESC
2e3d4f4d
MF
342sim_open (SIM_OPEN_KIND kind, host_callback *cb,
343 struct bfd *abfd, char * const *argv)
c906108c 344{
7bebb329 345 int i;
c906108c 346 SIM_DESC sd = sim_state_alloc (kind, cb);
7bebb329 347 sim_cpu *cpu;
c906108c
SS
348
349 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
350
7bebb329 351 /* The cpu data is kept in a separately allocated chunk of memory. */
d5a71b11 352 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
7bebb329
MF
353 return 0;
354
355 cpu = STATE_CPU (sd, 0); /* FIXME */
356
c906108c 357 /* FIXME: watchpoints code shouldn't need this */
c906108c
SS
358 STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
359
360 /* Initialize the mechanism for doing insn profiling. */
361 CPU_INSN_NAME (cpu) = get_insn_name;
362 CPU_MAX_INSNS (cpu) = nr_itable_entries;
363
364 STATE = 0;
365
366 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
367 return 0;
368 sim_add_option_table (sd, NULL, mips_options);
369
370
77cf2ef5 371 /* The parser will print an error message for us, so we silently return. */
c906108c
SS
372 if (sim_parse_args (sd, argv) != SIM_RC_OK)
373 {
374 /* Uninstall the modules to avoid memory leaks,
375 file descriptor leaks, etc. */
376 sim_module_uninstall (sd);
377 return 0;
378 }
379
380 /* handle board-specific memory maps */
381 if (board == NULL)
382 {
383 /* Allocate core managed memory */
14fb6c5a
TS
384 sim_memopt *entry, *match = NULL;
385 address_word mem_size = 0;
386 int mapped = 0;
adf40b2e 387
c906108c
SS
388 /* For compatibility with the old code - under this (at level one)
389 are the kernel spaces K0 & K1. Both of these map to a single
390 smaller sub region */
391 sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
14fb6c5a
TS
392
393 /* Look for largest memory region defined on command-line at
394 phys address 0. */
14fb6c5a
TS
395 for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
396 {
397 /* If we find an entry at address 0, then we will end up
398 allocating a new buffer in the "memory alias" command
399 below. The region at address 0 will be deleted. */
400 address_word size = (entry->modulo != 0
401 ? entry->modulo : entry->nr_bytes);
402 if (entry->addr == 0
403 && (!match || entry->level < match->level))
404 match = entry;
405 else if (entry->addr == K0BASE || entry->addr == K1BASE)
406 mapped = 1;
407 else
408 {
409 sim_memopt *alias;
410 for (alias = entry->alias; alias != NULL; alias = alias->next)
411 {
412 if (alias->addr == 0
413 && (!match || entry->level < match->level))
414 match = entry;
415 else if (alias->addr == K0BASE || alias->addr == K1BASE)
416 mapped = 1;
417 }
418 }
419 }
420
421 if (!mapped)
422 {
423 if (match)
424 {
425 /* Get existing memory region size. */
426 mem_size = (match->modulo != 0
427 ? match->modulo : match->nr_bytes);
428 /* Delete old region. */
429 sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
430 match->space, match->addr, match->level);
431 }
432 else if (mem_size == 0)
433 mem_size = MEM_SIZE;
434 /* Limit to KSEG1 size (512MB) */
435 if (mem_size > K1SIZE)
436 mem_size = K1SIZE;
437 /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
438 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
439 K1BASE, K1SIZE, (long)mem_size, K0BASE);
440 }
441
c906108c
SS
442 device_init(sd);
443 }
43e526b9
JM
444 else if (board != NULL
445 && (strcmp(board, BOARD_BSP) == 0))
446 {
447 int i;
448
449 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
450
451 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
452 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
453 0x9FC00000,
454 4 * 1024 * 1024, /* 4 MB */
455 0xBFC00000);
456
457 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
458 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
459 0x80000000,
460 4 * 1024 * 1024, /* 4 MB */
461 0xA0000000);
462
463 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
464 for (i=0; i<8; i++) /* 32 MB total */
465 {
466 unsigned size = 4 * 1024 * 1024; /* 4 MB */
467 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
468 0x88000000 + (i * size),
469 size,
470 0xA8000000 + (i * size));
471 }
472 }
c906108c 473#if (WITH_HW)
43e526b9
JM
474 else if (board != NULL
475 && (strcmp(board, BOARD_JMR3904) == 0 ||
476 strcmp(board, BOARD_JMR3904_PAL) == 0 ||
477 strcmp(board, BOARD_JMR3904_DEBUG) == 0))
c906108c
SS
478 {
479 /* match VIRTUAL memory layout of JMR-TX3904 board */
480 int i;
481
adf40b2e
JM
482 /* --- disable monitor unless forced on by user --- */
483
484 if (! firmware_option_p)
485 {
486 idt_monitor_base = 0;
487 pmon_monitor_base = 0;
488 lsipmon_monitor_base = 0;
489 }
490
c906108c
SS
491 /* --- environment --- */
492
493 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
494
495 /* --- memory --- */
496
497 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
498 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
499 0x9FC00000,
500 4 * 1024 * 1024, /* 4 MB */
501 0xBFC00000);
502
503 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
504 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
505 0x80000000,
506 4 * 1024 * 1024, /* 4 MB */
507 0xA0000000);
508
509 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
510 for (i=0; i<8; i++) /* 32 MB total */
511 {
512 unsigned size = 4 * 1024 * 1024; /* 4 MB */
513 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
514 0x88000000 + (i * size),
515 size,
516 0xA8000000 + (i * size));
517 }
518
cb7450ea 519 /* Dummy memory regions for unsimulated devices - sorted by address */
c906108c 520
d4f3574e 521 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
c2d11a7d
JM
522 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
523 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
d4f3574e
SS
524 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
525 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
cb7450ea
FCE
526 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
527 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
528 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
529 sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
530
c906108c
SS
531
532 /* --- simulated devices --- */
533 sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
534 sim_hw_parse (sd, "/tx3904cpu");
535 sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
536 sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
537 sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
538 sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
539 {
540 /* FIXME: poking at dv-sockser internals, use tcp backend if
541 --sockser_addr option was given.*/
542 extern char* sockser_addr;
543 if(sockser_addr == NULL)
544 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
545 else
546 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
547 }
548 sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
549 sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
550
551 /* -- device connections --- */
552 sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
553 sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
554 sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
555 sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
556 sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
557 sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
558
559 /* add PAL timer & I/O module */
560 if(! strcmp(board, BOARD_JMR3904_PAL))
561 {
562 /* the device */
563 sim_hw_parse (sd, "/pal@0xffff0000");
564 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
565
566 /* wire up interrupt ports to irc */
567 sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
568 sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
569 sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
570 }
571
572 if(! strcmp(board, BOARD_JMR3904_DEBUG))
573 {
574 /* -- DEBUG: glue interrupt generators --- */
575 sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
576 sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
577 sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
578 sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
579 sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
580 sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
581 sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
582 sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
583 sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
584 sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
585 sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
586 sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
587 sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
588 sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
589 sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
590 sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
591 sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
592 sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
593 sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
594 }
595
596 device_init(sd);
597 }
598#endif
599
2525df03
NC
600 if (display_mem_info)
601 {
602 struct option_list * ol;
603 struct option_list * prev;
604
605 /* This is a hack. We want to execute the real --memory-info command
606 line switch which is handled in common/sim-memopts.c, not the
607 override we have defined in this file. So we remove the
608 mips_options array from the state options list. This is safe
609 because we have now processed all of the command line. */
610 for (ol = STATE_OPTIONS (sd), prev = NULL;
611 ol != NULL;
612 prev = ol, ol = ol->next)
613 if (ol->options == mips_options)
614 break;
615
616 SIM_ASSERT (ol != NULL);
617
618 if (prev == NULL)
619 STATE_OPTIONS (sd) = ol->next;
620 else
621 prev->next = ol->next;
622
623 sim_do_commandf (sd, "memory-info");
624 }
c906108c
SS
625
626 /* check for/establish the a reference program image */
627 if (sim_analyze_program (sd,
628 (STATE_PROG_ARGV (sd) != NULL
629 ? *STATE_PROG_ARGV (sd)
630 : NULL),
631 abfd) != SIM_RC_OK)
632 {
633 sim_module_uninstall (sd);
634 return 0;
635 }
636
637 /* Configure/verify the target byte order and other runtime
638 configuration options */
639 if (sim_config (sd) != SIM_RC_OK)
640 {
641 sim_module_uninstall (sd);
642 return 0;
643 }
644
645 if (sim_post_argv_init (sd) != SIM_RC_OK)
646 {
647 /* Uninstall the modules to avoid memory leaks,
648 file descriptor leaks, etc. */
649 sim_module_uninstall (sd);
650 return 0;
651 }
652
653 /* verify assumptions the simulator made about the host type system.
654 This macro does not return if there is a problem */
655 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
656 SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
657
658 /* This is NASTY, in that we are assuming the size of specific
659 registers: */
660 {
661 int rn;
662 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
663 {
664 if (rn < 32)
665 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
ee7254b0 666 else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
c906108c
SS
667 cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
668 else if ((rn >= 33) && (rn <= 37))
669 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
670 else if ((rn == SRIDX)
671 || (rn == FCR0IDX)
672 || (rn == FCR31IDX)
673 || ((rn >= 72) && (rn <= 89)))
674 cpu->register_widths[rn] = 32;
675 else
676 cpu->register_widths[rn] = 0;
677 }
678
679
680 }
681
c906108c
SS
682 if (STATE & simTRACE)
683 open_trace(sd);
c906108c 684
adf40b2e
JM
685 /*
686 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
687 idt_monitor_base,
688 pmon_monitor_base,
689 lsipmon_monitor_base);
690 */
c906108c
SS
691
692 /* Write the monitor trap address handlers into the monitor (eeprom)
693 address space. This can only be done once the target endianness
694 has been determined. */
adf40b2e
JM
695 if (idt_monitor_base != 0)
696 {
697 unsigned loop;
698 unsigned idt_monitor_size = 1 << 11;
699
700 /* the default monitor region */
701 sim_do_commandf (sd, "memory region 0x%x,0x%x",
702 idt_monitor_base, idt_monitor_size);
703
704 /* Entry into the IDT monitor is via fixed address vectors, and
705 not using machine instructions. To avoid clashing with use of
706 the MIPS TRAP system, we place our own (simulator specific)
707 "undefined" instructions into the relevant vector slots. */
708 for (loop = 0; (loop < idt_monitor_size); loop += 4)
709 {
710 address_word vaddr = (idt_monitor_base + loop);
711 unsigned32 insn = (RSVD_INSTRUCTION |
712 (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
713 << RSVD_INSTRUCTION_ARG_SHIFT));
714 H2T (insn);
8ac57fbd 715 sim_write (sd, vaddr, (unsigned char *)&insn, sizeof (insn));
adf40b2e
JM
716 }
717 }
718
719 if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
720 {
c906108c
SS
721 /* The PMON monitor uses the same address space, but rather than
722 branching into it the address of a routine is loaded. We can
723 cheat for the moment, and direct the PMON routine to IDT style
724 instructions within the monitor space. This relies on the IDT
725 monitor not using the locations from 0xBFC00500 onwards as its
726 entry points.*/
adf40b2e
JM
727 unsigned loop;
728 for (loop = 0; (loop < 24); loop++)
729 {
730 unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
731 switch (loop)
732 {
c906108c
SS
733 case 0: /* read */
734 value = 7;
735 break;
736 case 1: /* write */
737 value = 8;
738 break;
739 case 2: /* open */
740 value = 6;
741 break;
742 case 3: /* close */
743 value = 10;
744 break;
745 case 5: /* printf */
746 value = ((0x500 - 16) / 8); /* not an IDT reason code */
747 break;
748 case 8: /* cliexit */
749 value = 17;
750 break;
751 case 11: /* flush_cache */
752 value = 28;
753 break;
754 }
adf40b2e
JM
755
756 SIM_ASSERT (idt_monitor_base != 0);
757 value = ((unsigned int) idt_monitor_base + (value * 8));
c906108c 758 H2T (value);
c906108c 759
adf40b2e
JM
760 if (pmon_monitor_base != 0)
761 {
762 address_word vaddr = (pmon_monitor_base + (loop * 4));
8ac57fbd 763 sim_write (sd, vaddr, (unsigned char *)&value, sizeof (value));
adf40b2e
JM
764 }
765
766 if (lsipmon_monitor_base != 0)
767 {
768 address_word vaddr = (lsipmon_monitor_base + (loop * 4));
8ac57fbd 769 sim_write (sd, vaddr, (unsigned char *)&value, sizeof (value));
adf40b2e 770 }
c906108c 771 }
adf40b2e
JM
772
773 /* Write an abort sequence into the TRAP (common) exception vector
774 addresses. This is to catch code executing a TRAP (et.al.)
775 instruction without installing a trap handler. */
776 if ((idt_monitor_base != 0) ||
777 (pmon_monitor_base != 0) ||
778 (lsipmon_monitor_base != 0))
779 {
780 unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
781 HALT_INSTRUCTION /* BREAK */ };
782 H2T (halt[0]);
783 H2T (halt[1]);
8ac57fbd
MF
784 sim_write (sd, 0x80000000, (unsigned char *) halt, sizeof (halt));
785 sim_write (sd, 0x80000180, (unsigned char *) halt, sizeof (halt));
786 sim_write (sd, 0x80000200, (unsigned char *) halt, sizeof (halt));
adf40b2e 787 /* XXX: Write here unconditionally? */
8ac57fbd
MF
788 sim_write (sd, 0xBFC00200, (unsigned char *) halt, sizeof (halt));
789 sim_write (sd, 0xBFC00380, (unsigned char *) halt, sizeof (halt));
790 sim_write (sd, 0xBFC00400, (unsigned char *) halt, sizeof (halt));
adf40b2e 791 }
c906108c
SS
792 }
793
7bebb329
MF
794 /* CPU specific initialization. */
795 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
796 {
797 SIM_CPU *cpu = STATE_CPU (sd, i);
c906108c 798
e1211e55
MF
799 CPU_REG_FETCH (cpu) = mips_reg_fetch;
800 CPU_REG_STORE (cpu) = mips_reg_store;
7bebb329
MF
801 CPU_PC_FETCH (cpu) = mips_pc_get;
802 CPU_PC_STORE (cpu) = mips_pc_set;
803 }
c906108c
SS
804
805 return sd;
806}
807
29bc024d 808#if WITH_TRACE_ANY_P
c906108c 809static void
8ac57fbd 810open_trace (SIM_DESC sd)
c906108c
SS
811{
812 tracefh = fopen(tracefile,"wb+");
813 if (tracefh == NULL)
814 {
815 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
816 tracefh = stderr;
817 }
818}
29bc024d 819#endif
c906108c
SS
820
821/* Return name of an insn, used by insn profiling. */
822static const char *
823get_insn_name (sim_cpu *cpu, int i)
824{
825 return itable[i].name;
826}
827
828void
6e4f085c 829mips_sim_close (SIM_DESC sd, int quitting)
c906108c 830{
29bc024d 831#if WITH_TRACE_ANY_P
c906108c
SS
832 if (tracefh != NULL && tracefh != stderr)
833 fclose(tracefh);
834 tracefh = NULL;
29bc024d 835#endif
c906108c
SS
836}
837
e1211e55
MF
838static int
839mips_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 840{
c906108c
SS
841 /* NOTE: gdb (the client) stores registers in target byte order
842 while the simulator uses host byte order */
c906108c
SS
843
844 /* Unfortunately this suffers from the same problem as the register
845 numbering one. We need to know what the width of each logical
846 register number is for the architecture being simulated. */
847
848 if (cpu->register_widths[rn] == 0)
849 {
e1211e55 850 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
c906108c
SS
851 return 0;
852 }
853
ee7254b0 854 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
c906108c 855 {
ee7254b0 856 cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
c906108c
SS
857 if (cpu->register_widths[rn] == 32)
858 {
a0b3c4fd
JM
859 if (length == 8)
860 {
ee7254b0 861 cpu->fgr[rn - FGR_BASE] =
a0b3c4fd
JM
862 (unsigned32) T2H_8 (*(unsigned64*)memory);
863 return 8;
864 }
865 else
866 {
ee7254b0 867 cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
a0b3c4fd
JM
868 return 4;
869 }
c906108c
SS
870 }
871 else
872 {
14fb6c5a
TS
873 if (length == 8)
874 {
875 cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
876 return 8;
877 }
878 else
879 {
880 cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
881 return 4;
882 }
c906108c
SS
883 }
884 }
885
886 if (cpu->register_widths[rn] == 32)
887 {
a0b3c4fd
JM
888 if (length == 8)
889 {
890 cpu->registers[rn] =
891 (unsigned32) T2H_8 (*(unsigned64*)memory);
892 return 8;
893 }
894 else
895 {
896 cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
897 return 4;
898 }
c906108c
SS
899 }
900 else
901 {
14fb6c5a
TS
902 if (length == 8)
903 {
904 cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
905 return 8;
906 }
907 else
908 {
909 cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
910 return 4;
911 }
c906108c
SS
912 }
913
914 return 0;
915}
916
e1211e55
MF
917static int
918mips_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c 919{
c906108c
SS
920 /* NOTE: gdb (the client) stores registers in target byte order
921 while the simulator uses host byte order */
c906108c
SS
922
923 if (cpu->register_widths[rn] == 0)
924 {
e1211e55 925 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
c906108c
SS
926 return 0;
927 }
928
c906108c 929 /* Any floating point register */
ee7254b0 930 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
c906108c
SS
931 {
932 if (cpu->register_widths[rn] == 32)
933 {
a0b3c4fd
JM
934 if (length == 8)
935 {
936 *(unsigned64*)memory =
ee7254b0 937 H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE]));
a0b3c4fd
JM
938 return 8;
939 }
940 else
941 {
ee7254b0 942 *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]);
a0b3c4fd
JM
943 return 4;
944 }
c906108c
SS
945 }
946 else
947 {
14fb6c5a
TS
948 if (length == 8)
949 {
950 *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
951 return 8;
952 }
953 else
954 {
955 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
956 return 4;
957 }
c906108c
SS
958 }
959 }
960
961 if (cpu->register_widths[rn] == 32)
962 {
a0b3c4fd
JM
963 if (length == 8)
964 {
965 *(unsigned64*)memory =
966 H2T_8 ((unsigned32) (cpu->registers[rn]));
967 return 8;
968 }
969 else
970 {
971 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
972 return 4;
973 }
c906108c
SS
974 }
975 else
976 {
14fb6c5a
TS
977 if (length == 8)
978 {
979 *(unsigned64*)memory =
980 H2T_8 ((unsigned64) (cpu->registers[rn]));
981 return 8;
982 }
983 else
984 {
985 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
986 return 4;
987 }
c906108c
SS
988 }
989
990 return 0;
991}
992
c906108c 993SIM_RC
2e3d4f4d
MF
994sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
995 char * const *argv, char * const *env)
c906108c
SS
996{
997
998#ifdef DEBUG
999#if 0 /* FIXME: doesn't compile */
1000 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1001 pr_addr(PC));
1002#endif
1003#endif /* DEBUG */
1004
1005 ColdReset(sd);
1006
1007 if (abfd != NULL)
1008 {
1009 /* override PC value set by ColdReset () */
1010 int cpu_nr;
1011 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1012 {
1013 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
b36d953b
MF
1014 sim_cia pc = bfd_get_start_address (abfd);
1015
1016 /* We need to undo brain-dead bfd behavior where it sign-extends
1017 addresses that are supposed to be unsigned. See the mips bfd
1018 sign_extend_vma setting. We have to check the ELF data itself
1019 in order to handle o32 & n32 ABIs. */
1020 if (abfd->tdata.elf_obj_data->elf_header->e_ident[EI_CLASS] ==
1021 ELFCLASS32)
1022 pc = (unsigned32) pc;
1023
1024 CPU_PC_SET (cpu, pc);
c906108c
SS
1025 }
1026 }
1027
1028#if 0 /* def DEBUG */
1029 if (argv || env)
1030 {
1031 /* We should really place the argv slot values into the argument
1032 registers, and onto the stack as required. However, this
1033 assumes that we have a stack defined, which is not
1034 necessarily true at the moment. */
1035 char **cptr;
1036 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1037 for (cptr = argv; (cptr && *cptr); cptr++)
1038 printf("DBG: arg \"%s\"\n",*cptr);
1039 }
1040#endif /* DEBUG */
1041
1042 return SIM_RC_OK;
1043}
1044
c906108c
SS
1045/*---------------------------------------------------------------------------*/
1046/*-- Private simulator support interface ------------------------------------*/
1047/*---------------------------------------------------------------------------*/
1048
1049/* Read a null terminated string from memory, return in a buffer */
1050static char *
1051fetch_str (SIM_DESC sd,
1052 address_word addr)
1053{
1054 char *buf;
1055 int nr = 0;
8ac57fbd 1056 unsigned char null;
c906108c
SS
1057 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1058 nr++;
1059 buf = NZALLOC (char, nr + 1);
8ac57fbd 1060 sim_read (sd, addr, (unsigned char *)buf, nr);
c906108c
SS
1061 return buf;
1062}
1063
adf40b2e
JM
1064
1065/* Implements the "sim firmware" command:
1066 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1067 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1068 defaults to the normal address for that monitor.
1069 sim firmware none --- don't emulate any ROM monitor. Useful
1070 if you need a clean address space. */
1071static SIM_RC
1072sim_firmware_command (SIM_DESC sd, char *arg)
1073{
1074 int address_present = 0;
1075 SIM_ADDR address;
1076
1077 /* Signal occurrence of this option. */
1078 firmware_option_p = 1;
1079
1080 /* Parse out the address, if present. */
1081 {
1082 char *p = strchr (arg, '@');
1083 if (p)
1084 {
1085 char *q;
1086 address_present = 1;
1087 p ++; /* skip over @ */
1088
1089 address = strtoul (p, &q, 0);
1090 if (*q != '\0')
1091 {
1092 sim_io_printf (sd, "Invalid address given to the"
1093 "`sim firmware NAME@ADDRESS' command: %s\n",
1094 p);
1095 return SIM_RC_FAIL;
1096 }
1097 }
1098 else
b4b6c939
AC
1099 {
1100 address_present = 0;
1101 address = -1; /* Dummy value. */
1102 }
adf40b2e
JM
1103 }
1104
1105 if (! strncmp (arg, "idt", 3))
1106 {
1107 idt_monitor_base = address_present ? address : 0xBFC00000;
1108 pmon_monitor_base = 0;
1109 lsipmon_monitor_base = 0;
1110 }
1111 else if (! strncmp (arg, "pmon", 4))
1112 {
1113 /* pmon uses indirect calls. Hook into implied idt. */
1114 pmon_monitor_base = address_present ? address : 0xBFC00500;
1115 idt_monitor_base = pmon_monitor_base - 0x500;
1116 lsipmon_monitor_base = 0;
1117 }
1118 else if (! strncmp (arg, "lsipmon", 7))
1119 {
1120 /* lsipmon uses indirect calls. Hook into implied idt. */
1121 pmon_monitor_base = 0;
1122 lsipmon_monitor_base = address_present ? address : 0xBFC00200;
1123 idt_monitor_base = lsipmon_monitor_base - 0x200;
1124 }
1125 else if (! strncmp (arg, "none", 4))
1126 {
1127 if (address_present)
1128 {
1129 sim_io_printf (sd,
1130 "The `sim firmware none' command does "
1131 "not take an `ADDRESS' argument.\n");
1132 return SIM_RC_FAIL;
1133 }
1134 idt_monitor_base = 0;
1135 pmon_monitor_base = 0;
1136 lsipmon_monitor_base = 0;
1137 }
1138 else
1139 {
1140 sim_io_printf (sd, "\
1141Unrecognized name given to the `sim firmware NAME' command: %s\n\
1142Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1143 arg);
1144 return SIM_RC_FAIL;
1145 }
1146
1147 return SIM_RC_OK;
1148}
1149
5c6f091a
FS
1150/* stat structures from MIPS32/64. */
1151static const char stat32_map[] =
1152"st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1153":st_rdev,2:st_size,4:st_atime,4:st_spare1,4:st_mtime,4:st_spare2,4"
1154":st_ctime,4:st_spare3,4:st_blksize,4:st_blocks,4:st_spare4,8";
1155
1156static const char stat64_map[] =
1157"st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1158":st_rdev,2:st_size,8:st_atime,8:st_spare1,8:st_mtime,8:st_spare2,8"
1159":st_ctime,8:st_spare3,8:st_blksize,8:st_blocks,8:st_spare4,16";
1160
1161/* Map for calls using the host struct stat. */
1162static const CB_TARGET_DEFS_MAP CB_stat_map[] =
1163{
1164 { "stat", CB_SYS_stat, 15 },
1165 { 0, -1, -1 }
1166};
adf40b2e
JM
1167
1168
c906108c 1169/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
8030f857 1170int
c906108c
SS
1171sim_monitor (SIM_DESC sd,
1172 sim_cpu *cpu,
1173 address_word cia,
1174 unsigned int reason)
1175{
1176#ifdef DEBUG
1177 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1178#endif /* DEBUG */
1179
1180 /* The IDT monitor actually allows two instructions per vector
1181 slot. However, the simulator currently causes a trap on each
1182 individual instruction. We cheat, and lose the bottom bit. */
1183 reason >>= 1;
1184
1185 /* The following callback functions are available, however the
1186 monitor we are simulating does not make use of them: get_errno,
5c6f091a 1187 isatty, rename, system and time. */
c906108c
SS
1188 switch (reason)
1189 {
1190
1191 case 6: /* int open(char *path,int flags) */
1192 {
1193 char *path = fetch_str (sd, A0);
1194 V0 = sim_io_open (sd, path, (int)A1);
d79fe0d6 1195 free (path);
c906108c
SS
1196 break;
1197 }
1198
1199 case 7: /* int read(int file,char *ptr,int len) */
1200 {
1201 int fd = A0;
1202 int nr = A2;
1203 char *buf = zalloc (nr);
1204 V0 = sim_io_read (sd, fd, buf, nr);
8ac57fbd 1205 sim_write (sd, A1, (unsigned char *)buf, nr);
d79fe0d6 1206 free (buf);
c906108c
SS
1207 }
1208 break;
1209
1210 case 8: /* int write(int file,char *ptr,int len) */
1211 {
1212 int fd = A0;
1213 int nr = A2;
1214 char *buf = zalloc (nr);
8ac57fbd 1215 sim_read (sd, A1, (unsigned char *)buf, nr);
c906108c 1216 V0 = sim_io_write (sd, fd, buf, nr);
f8df4c77
TS
1217 if (fd == 1)
1218 sim_io_flush_stdout (sd);
1219 else if (fd == 2)
1220 sim_io_flush_stderr (sd);
d79fe0d6 1221 free (buf);
c906108c
SS
1222 break;
1223 }
1224
1225 case 10: /* int close(int file) */
1226 {
1227 V0 = sim_io_close (sd, (int)A0);
1228 break;
1229 }
1230
1231 case 2: /* Densan monitor: char inbyte(int waitflag) */
1232 {
1233 if (A0 == 0) /* waitflag == NOWAIT */
1234 V0 = (unsigned_word)-1;
1235 }
1236 /* Drop through to case 11 */
1237
1238 case 11: /* char inbyte(void) */
1239 {
1240 char tmp;
43e526b9
JM
1241 /* ensure that all output has gone... */
1242 sim_io_flush_stdout (sd);
c906108c
SS
1243 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1244 {
1245 sim_io_error(sd,"Invalid return from character read");
1246 V0 = (unsigned_word)-1;
1247 }
1248 else
1249 V0 = (unsigned_word)tmp;
1250 break;
1251 }
1252
1253 case 3: /* Densan monitor: void co(char chr) */
1254 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1255 {
1256 char tmp = (char)(A0 & 0xFF);
1257 sim_io_write_stdout (sd, &tmp, sizeof(char));
1258 break;
1259 }
1260
5c6f091a
FS
1261 case 13: /* int unlink(const char *path) */
1262 {
1263 char *path = fetch_str (sd, A0);
1264 V0 = sim_io_unlink (sd, path);
1265 free (path);
1266 break;
1267 }
1268
1269 case 14: /* int lseek(int fd, int offset, int whence) */
1270 {
1271 V0 = sim_io_lseek (sd, A0, A1, A2);
1272 break;
1273 }
1274
1275 case 15: /* int stat(const char *path, struct stat *buf); */
1276 {
1277 /* As long as the infrastructure doesn't cache anything
1278 related to the stat mapping, this trick gets us a dual
1279 "struct stat"-type mapping in the least error-prone way. */
1280 host_callback *cb = STATE_CALLBACK (sd);
1281 const char *saved_map = cb->stat_map;
1282 CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
1283 bfd *prog_bfd = STATE_PROG_BFD (sd);
1284 int is_elf32bit = (elf_elfheader(prog_bfd)->e_ident[EI_CLASS] ==
1285 ELFCLASS32);
1286 static CB_SYSCALL s;
1287 CB_SYSCALL_INIT (&s);
1288 s.func = 15;
1289 /* Mask out the sign extension part for 64-bit targets because the
1290 MIPS simulator's memory model is still 32-bit. */
1291 s.arg1 = A0 & 0xFFFFFFFF;
1292 s.arg2 = A1 & 0xFFFFFFFF;
1293 s.p1 = (PTR) sd;
1294 s.p2 = (PTR) cpu;
1295 s.read_mem = sim_syscall_read_mem;
1296 s.write_mem = sim_syscall_write_mem;
1297
1298 cb->syscall_map = (CB_TARGET_DEFS_MAP *) CB_stat_map;
1299 cb->stat_map = is_elf32bit ? stat32_map : stat64_map;
1300
1301 if (cb_syscall (cb, &s) != CB_RC_OK)
1302 sim_engine_halt (sd, cpu, NULL, mips_pc_get (cpu),
1303 sim_stopped, SIM_SIGILL);
1304
1305 V0 = s.result;
1306 cb->stat_map = saved_map;
1307 cb->syscall_map = saved_syscall_map;
1308 break;
1309 }
1310
c906108c
SS
1311 case 17: /* void _exit() */
1312 {
1313 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1314 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1315 (unsigned int)(A0 & 0xFFFFFFFF));
1316 break;
1317 }
1318
e80fc152 1319 case 28: /* PMON flush_cache */
c906108c
SS
1320 break;
1321
1322 case 55: /* void get_mem_info(unsigned int *ptr) */
1323 /* in: A0 = pointer to three word memory location */
1324 /* out: [A0 + 0] = size */
1325 /* [A0 + 4] = instruction cache size */
1326 /* [A0 + 8] = data cache size */
1327 {
14fb6c5a 1328 unsigned_4 value;
c906108c 1329 unsigned_4 zero = 0;
14fb6c5a
TS
1330 address_word mem_size;
1331 sim_memopt *entry, *match = NULL;
1332
1333 /* Search for memory region mapped to KSEG0 or KSEG1. */
1334 for (entry = STATE_MEMOPT (sd);
1335 entry != NULL;
1336 entry = entry->next)
1337 {
1338 if ((entry->addr == K0BASE || entry->addr == K1BASE)
1339 && (!match || entry->level < match->level))
1340 match = entry;
1341 else
1342 {
1343 sim_memopt *alias;
1344 for (alias = entry->alias;
1345 alias != NULL;
1346 alias = alias->next)
1347 if ((alias->addr == K0BASE || alias->addr == K1BASE)
1348 && (!match || entry->level < match->level))
1349 match = entry;
1350 }
1351 }
1352
1353 /* Get region size, limit to KSEG1 size (512MB). */
1354 SIM_ASSERT (match != NULL);
1355 mem_size = (match->modulo != 0
1356 ? match->modulo : match->nr_bytes);
1357 if (mem_size > K1SIZE)
1358 mem_size = K1SIZE;
1359
1360 value = mem_size;
c906108c 1361 H2T (value);
8ac57fbd
MF
1362 sim_write (sd, A0 + 0, (unsigned char *)&value, 4);
1363 sim_write (sd, A0 + 4, (unsigned char *)&zero, 4);
1364 sim_write (sd, A0 + 8, (unsigned char *)&zero, 4);
5accf1ff 1365 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
c906108c
SS
1366 break;
1367 }
1368
e80fc152 1369 case 158: /* PMON printf */
c906108c
SS
1370 /* in: A0 = pointer to format string */
1371 /* A1 = optional argument 1 */
1372 /* A2 = optional argument 2 */
1373 /* A3 = optional argument 3 */
1374 /* out: void */
1375 /* The following is based on the PMON printf source */
1376 {
1377 address_word s = A0;
8ac57fbd 1378 unsigned char c;
c906108c
SS
1379 signed_word *ap = &A1; /* 1st argument */
1380 /* This isn't the quickest way, since we call the host print
1381 routine for every character almost. But it does avoid
1382 having to allocate and manage a temporary string buffer. */
1383 /* TODO: Include check that we only use three arguments (A1,
1384 A2 and A3) */
1385 while (sim_read (sd, s++, &c, 1) && c != '\0')
1386 {
1387 if (c == '%')
1388 {
1389 char tmp[40];
1390 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1391 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1392 while (sim_read (sd, s++, &c, 1) && c != '\0')
1393 {
1394 if (strchr ("dobxXulscefg%", c))
1395 break;
1396 else if (c == '-')
1397 fmt = FMT_LJUST;
1398 else if (c == '0')
1399 fmt = FMT_RJUST0;
1400 else if (c == '~')
1401 fmt = FMT_CENTER;
1402 else if (c == '*')
1403 {
1404 if (haddot)
1405 trunc = (int)*ap++;
1406 else
1407 width = (int)*ap++;
1408 }
1409 else if (c >= '1' && c <= '9')
1410 {
1411 address_word t = s;
1412 unsigned int n;
1413 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1414 tmp[s - t] = c;
1415 tmp[s - t] = '\0';
1416 n = (unsigned int)strtol(tmp,NULL,10);
1417 if (haddot)
1418 trunc = n;
1419 else
1420 width = n;
1421 s--;
1422 }
1423 else if (c == '.')
1424 haddot = 1;
1425 }
1426 switch (c)
1427 {
1428 case '%':
1429 sim_io_printf (sd, "%%");
1430 break;
1431 case 's':
1432 if ((int)*ap != 0)
1433 {
1434 address_word p = *ap++;
8ac57fbd 1435 unsigned char ch;
c906108c
SS
1436 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1437 sim_io_printf(sd, "%c", ch);
1438 }
1439 else
1440 sim_io_printf(sd,"(null)");
1441 break;
1442 case 'c':
1443 sim_io_printf (sd, "%c", (int)*ap++);
1444 break;
1445 default:
1446 if (c == 'l')
1447 {
1448 sim_read (sd, s++, &c, 1);
1449 if (c == 'l')
1450 {
1451 longlong = 1;
1452 sim_read (sd, s++, &c, 1);
1453 }
1454 }
1455 if (strchr ("dobxXu", c))
1456 {
1457 word64 lv = (word64) *ap++;
1458 if (c == 'b')
1459 sim_io_printf(sd,"<binary not supported>");
1460 else
1461 {
1462 sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
1463 if (longlong)
1464 sim_io_printf(sd, tmp, lv);
1465 else
1466 sim_io_printf(sd, tmp, (int)lv);
1467 }
1468 }
1469 else if (strchr ("eEfgG", c))
1470 {
1471 double dbl = *(double*)(ap++);
1472 sprintf (tmp, "%%%d.%d%c", width, trunc, c);
1473 sim_io_printf (sd, tmp, dbl);
1474 trunc = 0;
1475 }
1476 }
1477 }
1478 else
1479 sim_io_printf(sd, "%c", c);
1480 }
1481 break;
1482 }
1483
1484 default:
8030f857
BE
1485 /* Unknown reason. */
1486 return 0;
c906108c 1487 }
8030f857 1488 return 1;
c906108c
SS
1489}
1490
1491/* Store a word into memory. */
1492
1493static void
1494store_word (SIM_DESC sd,
1495 sim_cpu *cpu,
1496 address_word cia,
1497 uword64 vaddr,
1498 signed_word val)
1499{
26f8bf63 1500 address_word paddr = vaddr;
c906108c
SS
1501
1502 if ((vaddr & 3) != 0)
1503 SignalExceptionAddressStore ();
1504 else
1505 {
26f8bf63
MF
1506 const uword64 mask = 7;
1507 uword64 memval;
1508 unsigned int byte;
1509
1510 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1511 byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1512 memval = ((uword64) val) << (8 * byte);
1513 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr,
1514 isREAL);
c906108c
SS
1515 }
1516}
1517
1518/* Load a word from memory. */
1519
1520static signed_word
1521load_word (SIM_DESC sd,
1522 sim_cpu *cpu,
1523 address_word cia,
1524 uword64 vaddr)
1525{
1526 if ((vaddr & 3) != 0)
1527 {
1528 SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1529 }
1530 else
1531 {
26f8bf63
MF
1532 address_word paddr = vaddr;
1533 const uword64 mask = 0x7;
1534 const unsigned int reverse = ReverseEndian ? 1 : 0;
1535 const unsigned int bigend = BigEndianCPU ? 1 : 0;
1536 uword64 memval;
1537 unsigned int byte;
1538
1539 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1540 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA,
1541 isREAL);
1542 byte = (vaddr & mask) ^ (bigend << 2);
1543 return EXTEND32 (memval >> (8 * byte));
c906108c
SS
1544 }
1545
1546 return 0;
1547}
1548
1549/* Simulate the mips16 entry and exit pseudo-instructions. These
1550 would normally be handled by the reserved instruction exception
1551 code, but for ease of simulation we just handle them directly. */
1552
1553static void
1554mips16_entry (SIM_DESC sd,
1555 sim_cpu *cpu,
1556 address_word cia,
1557 unsigned int insn)
1558{
1559 int aregs, sregs, rreg;
1560
1561#ifdef DEBUG
1562 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1563#endif /* DEBUG */
1564
1565 aregs = (insn & 0x700) >> 8;
1566 sregs = (insn & 0x0c0) >> 6;
1567 rreg = (insn & 0x020) >> 5;
1568
1569 /* This should be checked by the caller. */
1570 if (sregs == 3)
1571 abort ();
1572
1573 if (aregs < 5)
1574 {
1575 int i;
1576 signed_word tsp;
1577
1578 /* This is the entry pseudo-instruction. */
1579
1580 for (i = 0; i < aregs; i++)
1581 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1582
1583 tsp = SP;
1584 SP -= 32;
1585
1586 if (rreg)
1587 {
1588 tsp -= 4;
1589 store_word (SD, CPU, cia, (uword64) tsp, RA);
1590 }
1591
1592 for (i = 0; i < sregs; i++)
1593 {
1594 tsp -= 4;
1595 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1596 }
1597 }
1598 else
1599 {
1600 int i;
1601 signed_word tsp;
1602
1603 /* This is the exit pseudo-instruction. */
1604
1605 tsp = SP + 32;
1606
1607 if (rreg)
1608 {
1609 tsp -= 4;
1610 RA = load_word (SD, CPU, cia, (uword64) tsp);
1611 }
1612
1613 for (i = 0; i < sregs; i++)
1614 {
1615 tsp -= 4;
1616 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1617 }
1618
1619 SP += 32;
1620
1621 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1622 {
1623 if (aregs == 5)
1624 {
1625 FGR[0] = WORD64LO (GPR[4]);
1626 FPR_STATE[0] = fmt_uninterpreted;
1627 }
1628 else if (aregs == 6)
1629 {
1630 FGR[0] = WORD64LO (GPR[5]);
1631 FGR[1] = WORD64LO (GPR[4]);
1632 FPR_STATE[0] = fmt_uninterpreted;
1633 FPR_STATE[1] = fmt_uninterpreted;
1634 }
1635 }
1636
1637 PC = RA;
1638 }
1639
1640}
1641
1642/*-- trace support ----------------------------------------------------------*/
1643
29bc024d 1644/* The trace support is provided (if required) in the memory accessing
c906108c
SS
1645 routines. Since we are also providing the architecture specific
1646 features, the architecture simulation code can also deal with
29bc024d 1647 notifying the trace world of cache flushes, etc. Similarly we do
c906108c
SS
1648 not need to provide profiling support in the simulator engine,
1649 since we can sample in the instruction fetch control loop. By
29bc024d 1650 defining the trace manifest, we add tracing as a run-time
c906108c
SS
1651 option. */
1652
29bc024d 1653#if WITH_TRACE_ANY_P
c906108c
SS
1654/* Tracing by default produces "din" format (as required by
1655 dineroIII). Each line of such a trace file *MUST* have a din label
1656 and address field. The rest of the line is ignored, so comments can
1657 be included if desired. The first field is the label which must be
1658 one of the following values:
1659
1660 0 read data
1661 1 write data
1662 2 instruction fetch
1663 3 escape record (treated as unknown access type)
1664 4 escape record (causes cache flush)
1665
1666 The address field is a 32bit (lower-case) hexadecimal address
1667 value. The address should *NOT* be preceded by "0x".
1668
1669 The size of the memory transfer is not important when dealing with
1670 cache lines (as long as no more than a cache line can be
1671 transferred in a single operation :-), however more information
1672 could be given following the dineroIII requirement to allow more
1673 complete memory and cache simulators to provide better
1674 results. i.e. the University of Pisa has a cache simulator that can
1675 also take bus size and speed as (variable) inputs to calculate
1676 complete system performance (a much more useful ability when trying
1677 to construct an end product, rather than a processor). They
1678 currently have an ARM version of their tool called ChARM. */
1679
1680
1681void
1682dotrace (SIM_DESC sd,
1683 sim_cpu *cpu,
1684 FILE *tracefh,
1685 int type,
1686 SIM_ADDR address,
1687 int width,
1688 char *comment,...)
1689{
1690 if (STATE & simTRACE) {
1691 va_list ap;
1692 fprintf(tracefh,"%d %s ; width %d ; ",
1693 type,
1694 pr_addr(address),
1695 width);
1696 va_start(ap,comment);
1697 vfprintf(tracefh,comment,ap);
1698 va_end(ap);
1699 fprintf(tracefh,"\n");
1700 }
1701 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1702 we may be generating 64bit ones, we should put the hi-32bits of the
1703 address into the comment field. */
1704
1705 /* TODO: Provide a buffer for the trace lines. We can then avoid
1706 performing writes until the buffer is filled, or the file is
1707 being closed. */
1708
1709 /* NOTE: We could consider adding a comment field to the "din" file
1710 produced using type 3 markers (unknown access). This would then
1711 allow information about the program that the "din" is for, and
1712 the MIPs world that was being simulated, to be placed into the
1713 trace file. */
1714
1715 return;
1716}
29bc024d 1717#endif /* WITH_TRACE_ANY_P */
c906108c
SS
1718
1719/*---------------------------------------------------------------------------*/
1720/*-- simulator engine -------------------------------------------------------*/
1721/*---------------------------------------------------------------------------*/
1722
1723static void
1724ColdReset (SIM_DESC sd)
1725{
1726 int cpu_nr;
1727 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1728 {
1729 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1730 /* RESET: Fixed PC address: */
1731 PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1732 /* The reset vector address is in the unmapped, uncached memory space. */
1733
1734 SR &= ~(status_SR | status_TS | status_RP);
1735 SR |= (status_ERL | status_BEV);
1736
1737 /* Cheat and allow access to the complete register set immediately */
1738 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1739 && WITH_TARGET_WORD_BITSIZE == 64)
1740 SR |= status_FR; /* 64bit registers */
1741
1742 /* Ensure that any instructions with pending register updates are
1743 cleared: */
1744 PENDING_INVALIDATE();
1745
1746 /* Initialise the FPU registers to the unknown state */
1747 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1748 {
1749 int rn;
1750 for (rn = 0; (rn < 32); rn++)
1751 FPR_STATE[rn] = fmt_uninterpreted;
1752 }
1753
07802d98
TS
1754 /* Initialise the Config0 register. */
1755 C0_CONFIG = 0x80000000 /* Config1 present */
1756 | 2; /* KSEG0 uncached */
1757 if (WITH_TARGET_WORD_BITSIZE == 64)
1758 {
1759 /* FIXME Currently mips/sim-main.c:address_translation()
1760 truncates all addresses to 32-bits. */
1761 if (0 && WITH_TARGET_ADDRESS_BITSIZE == 64)
1762 C0_CONFIG |= (2 << 13); /* MIPS64, 64-bit addresses */
1763 else
1764 C0_CONFIG |= (1 << 13); /* MIPS64, 32-bit addresses */
1765 }
1766 if (BigEndianMem)
1767 C0_CONFIG |= 0x00008000; /* Big Endian */
c906108c
SS
1768 }
1769}
1770
1771
1772
1773
1774/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1775/* Signal an exception condition. This will result in an exception
1776 that aborts the instruction. The instruction operation pseudocode
1777 will never see a return from this function call. */
1778
1779void
1780signal_exception (SIM_DESC sd,
1781 sim_cpu *cpu,
1782 address_word cia,
1783 int exception,...)
1784{
1785 /* int vector; */
1786
1787#ifdef DEBUG
1788 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1789#endif /* DEBUG */
1790
1791 /* Ensure that any active atomic read/modify/write operation will fail: */
1792 LLBIT = 0;
1793
1794 /* Save registers before interrupt dispatching */
1795#ifdef SIM_CPU_EXCEPTION_TRIGGER
1796 SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1797#endif
1798
1799 switch (exception) {
1800
e80fc152 1801 case DebugBreakPoint:
c906108c
SS
1802 if (! (Debug & Debug_DM))
1803 {
1804 if (INDELAYSLOT())
1805 {
1806 CANCELDELAYSLOT();
1807
1808 Debug |= Debug_DBD; /* signaled from within in delay slot */
1809 DEPC = cia - 4; /* reference the branch instruction */
1810 }
1811 else
1812 {
1813 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1814 DEPC = cia;
1815 }
1816
1817 Debug |= Debug_DM; /* in debugging mode */
1818 Debug |= Debug_DBp; /* raising a DBp exception */
1819 PC = 0xBFC00200;
1820 sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1821 }
1822 break;
1823
e80fc152 1824 case ReservedInstruction:
c906108c
SS
1825 {
1826 va_list ap;
1827 unsigned int instruction;
1828 va_start(ap,exception);
1829 instruction = va_arg(ap,unsigned int);
1830 va_end(ap);
1831 /* Provide simple monitor support using ReservedInstruction
1832 exceptions. The following code simulates the fixed vector
1833 entry points into the IDT monitor by causing a simulator
1834 trap, performing the monitor operation, and returning to
1835 the address held in the $ra register (standard PCS return
1836 address). This means we only need to pre-load the vector
1837 space with suitable instruction values. For systems were
1838 actual trap instructions are used, we would not need to
1839 perform this magic. */
1840 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1841 {
8030f857
BE
1842 int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK;
1843 if (!sim_monitor (SD, CPU, cia, reason))
1844 sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia));
1845
c906108c
SS
1846 /* NOTE: This assumes that a branch-and-link style
1847 instruction was used to enter the vector (which is the
1848 case with the current IDT monitor). */
1849 sim_engine_restart (SD, CPU, NULL, RA);
1850 }
1851 /* Look for the mips16 entry and exit instructions, and
1852 simulate a handler for them. */
1853 else if ((cia & 1) != 0
1854 && (instruction & 0xf81f) == 0xe809
1855 && (instruction & 0x0c0) != 0x0c0)
1856 {
1857 mips16_entry (SD, CPU, cia, instruction);
1858 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1859 }
1860 /* else fall through to normal exception processing */
1861 sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1862 }
1863
1864 default:
1865 /* Store exception code into current exception id variable (used
1866 by exit code): */
1867
1868 /* TODO: If not simulating exceptions then stop the simulator
1869 execution. At the moment we always stop the simulation. */
1870
1871#ifdef SUBTARGET_R3900
1872 /* update interrupt-related registers */
1873
1874 /* insert exception code in bits 6:2 */
1875 CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1876 /* shift IE/KU history bits left */
1877 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1878
1879 if (STATE & simDELAYSLOT)
1880 {
1881 STATE &= ~simDELAYSLOT;
1882 CAUSE |= cause_BD;
1883 EPC = (cia - 4); /* reference the branch instruction */
1884 }
1885 else
1886 EPC = cia;
1887
1888 if (SR & status_BEV)
1889 PC = (signed)0xBFC00000 + 0x180;
1890 else
1891 PC = (signed)0x80000000 + 0x080;
1892#else
1893 /* See figure 5-17 for an outline of the code below */
1894 if (! (SR & status_EXL))
1895 {
1896 CAUSE = (exception << 2);
1897 if (STATE & simDELAYSLOT)
1898 {
1899 STATE &= ~simDELAYSLOT;
1900 CAUSE |= cause_BD;
1901 EPC = (cia - 4); /* reference the branch instruction */
1902 }
1903 else
1904 EPC = cia;
1905 /* FIXME: TLB et.al. */
1906 /* vector = 0x180; */
1907 }
1908 else
1909 {
1910 CAUSE = (exception << 2);
1911 /* vector = 0x180; */
1912 }
1913 SR |= status_EXL;
1914 /* Store exception code into current exception id variable (used
1915 by exit code): */
1916
1917 if (SR & status_BEV)
1918 PC = (signed)0xBFC00200 + 0x180;
1919 else
1920 PC = (signed)0x80000000 + 0x180;
1921#endif
1922
1923 switch ((CAUSE >> 2) & 0x1F)
1924 {
1925 case Interrupt:
1926 /* Interrupts arrive during event processing, no need to
1927 restart */
1928 return;
1929
1930 case NMIReset:
1931 /* Ditto */
1932#ifdef SUBTARGET_3900
1933 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1934 PC = (signed)0xBFC00000;
0d3e762b 1935#endif /* SUBTARGET_3900 */
c906108c
SS
1936 return;
1937
1938 case TLBModification:
1939 case TLBLoad:
1940 case TLBStore:
1941 case AddressLoad:
1942 case AddressStore:
1943 case InstructionFetch:
1944 case DataReference:
1945 /* The following is so that the simulator will continue from the
1946 exception handler address. */
1947 sim_engine_halt (SD, CPU, NULL, PC,
1948 sim_stopped, SIM_SIGBUS);
1949
1950 case ReservedInstruction:
1951 case CoProcessorUnusable:
1952 PC = EPC;
1953 sim_engine_halt (SD, CPU, NULL, PC,
1954 sim_stopped, SIM_SIGILL);
1955
1956 case IntegerOverflow:
1957 case FPE:
1958 sim_engine_halt (SD, CPU, NULL, PC,
1959 sim_stopped, SIM_SIGFPE);
1960
1961 case BreakPoint:
1962 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
1963 break;
1964
1965 case SystemCall:
1966 case Trap:
1967 sim_engine_restart (SD, CPU, NULL, PC);
1968 break;
1969
1970 case Watch:
1971 PC = EPC;
1972 sim_engine_halt (SD, CPU, NULL, PC,
1973 sim_stopped, SIM_SIGTRAP);
1974
e80fc152 1975 default: /* Unknown internal exception */
c906108c
SS
1976 PC = EPC;
1977 sim_engine_halt (SD, CPU, NULL, PC,
1978 sim_stopped, SIM_SIGABRT);
1979
1980 }
1981
1982 case SimulatorFault:
1983 {
1984 va_list ap;
1985 char *msg;
1986 va_start(ap,exception);
1987 msg = va_arg(ap,char *);
1988 va_end(ap);
1989 sim_engine_abort (SD, CPU, NULL_CIA,
1990 "FATAL: Simulator error \"%s\"\n",msg);
1991 }
1992 }
1993
1994 return;
1995}
1996
1997
1998
402586aa
CD
1999/* This function implements what the MIPS32 and MIPS64 ISAs define as
2000 "UNPREDICTABLE" behaviour.
2001
2002 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2003 may vary from processor implementation to processor implementation,
2004 instruction to instruction, or as a function of time on the same
2005 implementation or instruction. Software can never depend on results
2006 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
2007 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
2008 0.95, page 2.)
2009
2010 For UNPREDICTABLE behaviour, we print a message, if possible print
2011 the offending instructions mips.igen instruction name (provided by
2012 the caller), and stop the simulator.
2013
2014 XXX FIXME: eventually, stopping the simulator should be made conditional
2015 on a command-line option. */
2016void
2017unpredictable_action(sim_cpu *cpu, address_word cia)
c906108c 2018{
402586aa
CD
2019 SIM_DESC sd = CPU_STATE(cpu);
2020
2021 sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia));
2022 sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT);
c906108c 2023}
c906108c 2024
c906108c
SS
2025
2026/*-- co-processor support routines ------------------------------------------*/
2027
2028static int UNUSED
2029CoProcPresent(unsigned int coproc_number)
2030{
2031 /* Return TRUE if simulator provides a model for the given co-processor number */
2032 return(0);
2033}
2034
2035void
2036cop_lw (SIM_DESC sd,
2037 sim_cpu *cpu,
2038 address_word cia,
2039 int coproc_num,
2040 int coproc_reg,
2041 unsigned int memword)
2042{
2043 switch (coproc_num)
2044 {
2045 case 1:
2046 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2047 {
2048#ifdef DEBUG
2049 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2050#endif
14fb6c5a 2051 StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
c906108c
SS
2052 break;
2053 }
2054
2055 default:
2056#if 0 /* this should be controlled by a configuration option */
2057 sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
2058#endif
2059 break;
2060 }
2061
2062 return;
2063}
2064
2065void
2066cop_ld (SIM_DESC sd,
2067 sim_cpu *cpu,
2068 address_word cia,
2069 int coproc_num,
2070 int coproc_reg,
2071 uword64 memword)
2072{
2073
2074#ifdef DEBUG
2075 printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia) );
2076#endif
2077
2078 switch (coproc_num) {
2079 case 1:
2080 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2081 {
14fb6c5a 2082 StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
c906108c
SS
2083 break;
2084 }
2085
2086 default:
2087#if 0 /* this message should be controlled by a configuration option */
2088 sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
2089#endif
2090 break;
2091 }
2092
2093 return;
2094}
2095
2096
2097
2098
2099unsigned int
2100cop_sw (SIM_DESC sd,
2101 sim_cpu *cpu,
2102 address_word cia,
2103 int coproc_num,
2104 int coproc_reg)
2105{
2106 unsigned int value = 0;
2107
2108 switch (coproc_num)
2109 {
2110 case 1:
2111 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2112 {
14fb6c5a 2113 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
c906108c
SS
2114 break;
2115 }
2116
2117 default:
2118#if 0 /* should be controlled by configuration option */
2119 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2120#endif
2121 break;
2122 }
2123
2124 return(value);
2125}
2126
2127uword64
2128cop_sd (SIM_DESC sd,
2129 sim_cpu *cpu,
2130 address_word cia,
2131 int coproc_num,
2132 int coproc_reg)
2133{
2134 uword64 value = 0;
2135 switch (coproc_num)
2136 {
2137 case 1:
2138 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2139 {
14fb6c5a 2140 value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
c906108c
SS
2141 break;
2142 }
2143
2144 default:
2145#if 0 /* should be controlled by configuration option */
2146 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2147#endif
2148 break;
2149 }
2150
2151 return(value);
2152}
2153
2154
2155
2156
2157void
2158decode_coproc (SIM_DESC sd,
2159 sim_cpu *cpu,
2160 address_word cia,
8e394ffc
AB
2161 unsigned int instruction,
2162 int coprocnum,
2163 CP0_operation op,
2164 int rt,
2165 int rd,
2166 int sel)
c906108c 2167{
c906108c
SS
2168 switch (coprocnum)
2169 {
2170 case 0: /* standard CPU control and cache registers */
2171 {
c906108c
SS
2172 /* R4000 Users Manual (second edition) lists the following CP0
2173 instructions:
2174 CODE><-RT><RD-><--TAIL--->
2175 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2176 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2177 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2178 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2179 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2180 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2181 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2182 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2183 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2184 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2185 */
8e394ffc
AB
2186 if (((op == cp0_mfc0) || (op == cp0_mtc0) /* MFC0 / MTC0 */
2187 || (op == cp0_dmfc0) || (op == cp0_dmtc0)) /* DMFC0 / DMTC0 */
2188 && sel == 0)
c906108c 2189 {
c906108c
SS
2190 switch (rd) /* NOTEs: Standard CP0 registers */
2191 {
2192 /* 0 = Index R4000 VR4100 VR4300 */
2193 /* 1 = Random R4000 VR4100 VR4300 */
2194 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
2195 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
2196 /* 4 = Context R4000 VR4100 VR4300 */
2197 /* 5 = PageMask R4000 VR4100 VR4300 */
2198 /* 6 = Wired R4000 VR4100 VR4300 */
2199 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2200 /* 9 = Count R4000 VR4100 VR4300 */
2201 /* 10 = EntryHi R4000 VR4100 VR4300 */
2202 /* 11 = Compare R4000 VR4100 VR4300 */
2203 /* 12 = SR R4000 VR4100 VR4300 */
2204#ifdef SUBTARGET_R3900
2205 case 3:
2206 /* 3 = Config R3900 */
2207 case 7:
2208 /* 7 = Cache R3900 */
2209 case 15:
2210 /* 15 = PRID R3900 */
2211
2212 /* ignore */
2213 break;
2214
2215 case 8:
2216 /* 8 = BadVAddr R4000 VR4100 VR4300 */
8e394ffc 2217 if (op == cp0_mfc0 || op == cp0_dmfc0)
1a27f959 2218 GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
c906108c
SS
2219 else
2220 COP0_BADVADDR = GPR[rt];
2221 break;
2222
2223#endif /* SUBTARGET_R3900 */
2224 case 12:
8e394ffc 2225 if (op == cp0_mfc0 || op == cp0_dmfc0)
c906108c
SS
2226 GPR[rt] = SR;
2227 else
2228 SR = GPR[rt];
2229 break;
2230 /* 13 = Cause R4000 VR4100 VR4300 */
2231 case 13:
8e394ffc 2232 if (op == cp0_mfc0 || op == cp0_dmfc0)
c906108c
SS
2233 GPR[rt] = CAUSE;
2234 else
2235 CAUSE = GPR[rt];
2236 break;
2237 /* 14 = EPC R4000 VR4100 VR4300 */
2238 case 14:
8e394ffc 2239 if (op == cp0_mfc0 || op == cp0_dmfc0)
c906108c
SS
2240 GPR[rt] = (signed_word) (signed_address) EPC;
2241 else
2242 EPC = GPR[rt];
2243 break;
2244 /* 15 = PRId R4000 VR4100 VR4300 */
2245#ifdef SUBTARGET_R3900
2246 /* 16 = Debug */
2247 case 16:
8e394ffc 2248 if (op == cp0_mfc0 || op == cp0_dmfc0)
c906108c
SS
2249 GPR[rt] = Debug;
2250 else
2251 Debug = GPR[rt];
2252 break;
2253#else
2254 /* 16 = Config R4000 VR4100 VR4300 */
2255 case 16:
8e394ffc 2256 if (op == cp0_mfc0 || op == cp0_dmfc0)
07802d98
TS
2257 GPR[rt] = C0_CONFIG;
2258 else
2259 /* only bottom three bits are writable */
2260 C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7);
c906108c
SS
2261 break;
2262#endif
2263#ifdef SUBTARGET_R3900
2264 /* 17 = Debug */
2265 case 17:
8e394ffc 2266 if (op == cp0_mfc0 || op == cp0_dmfc0)
c906108c
SS
2267 GPR[rt] = DEPC;
2268 else
2269 DEPC = GPR[rt];
2270 break;
2271#else
2272 /* 17 = LLAddr R4000 VR4100 VR4300 */
2273#endif
2274 /* 18 = WatchLo R4000 VR4100 VR4300 */
2275 /* 19 = WatchHi R4000 VR4100 VR4300 */
2276 /* 20 = XContext R4000 VR4100 VR4300 */
2277 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2278 /* 27 = CacheErr R4000 VR4100 */
2279 /* 28 = TagLo R4000 VR4100 VR4300 */
2280 /* 29 = TagHi R4000 VR4100 VR4300 */
2281 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
a3027dd7
FCE
2282 if (STATE_VERBOSE_P(SD))
2283 sim_io_eprintf (SD,
e30db738
AC
2284 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2285 (unsigned long)cia);
c906108c
SS
2286 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
2287 /* CPR[0,rd] = GPR[rt]; */
2288 default:
8e394ffc 2289 if (op == cp0_mfc0 || op == cp0_dmfc0)
c906108c
SS
2290 GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
2291 else
2292 COP0_GPR[rd] = GPR[rt];
2293#if 0
2294 if (code == 0x00)
2295 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2296 else
2297 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2298#endif
2299 }
2300 }
8e394ffc 2301 else if ((op == cp0_mfc0 || op == cp0_dmfc0)
07802d98
TS
2302 && rd == 16)
2303 {
2304 /* [D]MFC0 RT,C0_CONFIG,SEL */
2305 signed32 cfg = 0;
8e394ffc 2306 switch (sel)
07802d98
TS
2307 {
2308 case 0:
2309 cfg = C0_CONFIG;
2310 break;
2311 case 1:
2312 /* MIPS32 r/o Config1:
2313 Config2 present */
2314 cfg = 0x80000000;
2315 /* MIPS16 implemented.
2316 XXX How to check configuration? */
2317 cfg |= 0x0000004;
2318 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2319 /* MDMX & FPU implemented */
2320 cfg |= 0x00000021;
2321 break;
2322 case 2:
2323 /* MIPS32 r/o Config2:
2324 Config3 present. */
2325 cfg = 0x80000000;
2326 break;
2327 case 3:
2328 /* MIPS32 r/o Config3:
2329 SmartMIPS implemented. */
2330 cfg = 0x00000002;
2331 break;
2332 }
2333 GPR[rt] = cfg;
2334 }
8e394ffc 2335 else if (op == cp0_eret && sel == 0x18)
c906108c
SS
2336 {
2337 /* ERET */
2338 if (SR & status_ERL)
2339 {
2340 /* Oops, not yet available */
2341 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
2342 PC = EPC;
2343 SR &= ~status_ERL;
2344 }
2345 else
2346 {
2347 PC = EPC;
2348 SR &= ~status_EXL;
2349 }
2350 }
8e394ffc 2351 else if (op == cp0_rfe && sel == 0x10)
c906108c
SS
2352 {
2353 /* RFE */
2354#ifdef SUBTARGET_R3900
2355 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2356
2357 /* shift IE/KU history bits right */
2358 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
2359
2360 /* TODO: CACHE register */
2361#endif /* SUBTARGET_R3900 */
2362 }
8e394ffc 2363 else if (op == cp0_deret && sel == 0x1F)
c906108c
SS
2364 {
2365 /* DERET */
2366 Debug &= ~Debug_DM;
2367 DELAYSLOT();
2368 DSPC = DEPC;
2369 }
2370 else
2371 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
2372 /* TODO: When executing an ERET or RFE instruction we should
2373 clear LLBIT, to ensure that any out-standing atomic
2374 read/modify/write sequence fails. */
2375 }
2376 break;
2377
2378 case 2: /* co-processor 2 */
2379 {
2380 int handle = 0;
2381
2382
2383 if(! handle)
2384 {
2385 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2386 instruction,pr_addr(cia));
2387 }
2388 }
2389 break;
2390
2391 case 1: /* should not occur (FPU co-processor) */
2392 case 3: /* should not occur (FPU co-processor) */
2393 SignalException(ReservedInstruction,instruction);
2394 break;
2395 }
2396
2397 return;
2398}
2399
2400
2401/* This code copied from gdb's utils.c. Would like to share this code,
2402 but don't know of a common place where both could get to it. */
2403
2404/* Temporary storage using circular buffer */
2405#define NUMCELLS 16
2406#define CELLSIZE 32
2407static char*
2408get_cell (void)
2409{
2410 static char buf[NUMCELLS][CELLSIZE];
2411 static int cell=0;
2412 if (++cell>=NUMCELLS) cell=0;
2413 return buf[cell];
2414}
2415
2416/* Print routines to handle variable size regs, etc */
2417
2418/* Eliminate warning from compiler on 32-bit systems */
2419static int thirty_two = 32;
2420
2421char*
8ac57fbd 2422pr_addr (SIM_ADDR addr)
c906108c
SS
2423{
2424 char *paddr_str=get_cell();
2425 switch (sizeof(addr))
2426 {
2427 case 8:
2428 sprintf(paddr_str,"%08lx%08lx",
2429 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
2430 break;
2431 case 4:
2432 sprintf(paddr_str,"%08lx",(unsigned long)addr);
2433 break;
2434 case 2:
2435 sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
2436 break;
2437 default:
2438 sprintf(paddr_str,"%x",addr);
2439 }
2440 return paddr_str;
2441}
2442
2443char*
8ac57fbd 2444pr_uword64 (uword64 addr)
c906108c
SS
2445{
2446 char *paddr_str=get_cell();
2447 sprintf(paddr_str,"%08lx%08lx",
2448 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
2449 return paddr_str;
2450}
2451
2452
2453void
2454mips_core_signal (SIM_DESC sd,
2455 sim_cpu *cpu,
2456 sim_cia cia,
2457 unsigned map,
2458 int nr_bytes,
2459 address_word addr,
2460 transfer_type transfer,
2461 sim_core_signals sig)
2462{
2463 const char *copy = (transfer == read_transfer ? "read" : "write");
2464 address_word ip = CIA_ADDR (cia);
2465
2466 switch (sig)
2467 {
2468 case sim_core_unmapped_signal:
2469 sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2470 nr_bytes, copy,
2471 (unsigned long) addr, (unsigned long) ip);
2472 COP0_BADVADDR = addr;
2473 SignalExceptionDataReference();
2474 break;
2475
2476 case sim_core_unaligned_signal:
2477 sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
2478 nr_bytes, copy,
2479 (unsigned long) addr, (unsigned long) ip);
2480 COP0_BADVADDR = addr;
2481 if(transfer == read_transfer)
2482 SignalExceptionAddressLoad();
2483 else
2484 SignalExceptionAddressStore();
2485 break;
2486
2487 default:
2488 sim_engine_abort (sd, cpu, cia,
2489 "mips_core_signal - internal error - bad switch");
2490 }
2491}
2492
2493
2494void
2495mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
2496{
2497 ASSERT(cpu != NULL);
2498
2499 if(cpu->exc_suspended > 0)
2500 sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended);
2501
2502 PC = cia;
2503 memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
2504 cpu->exc_suspended = 0;
2505}
2506
2507void
2508mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
2509{
2510 ASSERT(cpu != NULL);
2511
2512 if(cpu->exc_suspended > 0)
2513 sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
2514 cpu->exc_suspended, exception);
2515
2516 memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
2517 memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
2518 cpu->exc_suspended = exception;
2519}
2520
2521void
2522mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
2523{
2524 ASSERT(cpu != NULL);
2525
2526 if(exception == 0 && cpu->exc_suspended > 0)
2527 {
2528 /* warn not for breakpoints */
2529 if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
2530 sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
2531 cpu->exc_suspended);
2532 }
2533 else if(exception != 0 && cpu->exc_suspended > 0)
2534 {
2535 if(exception != cpu->exc_suspended)
2536 sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2537 cpu->exc_suspended, exception);
2538
2539 memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));
2540 }
2541 else if(exception != 0 && cpu->exc_suspended == 0)
2542 {
2543 sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
2544 }
2545 cpu->exc_suspended = 0;
2546}
2547
2548
2549/*---------------------------------------------------------------------------*/
2550/*> EOF interp.c <*/
This page took 1.121567 seconds and 4 git commands to generate.