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